]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-bus/bus-message.c
Export sd_bus_message_append_ap. It is renamed to sd_bus_message_appendv to follow...
[thirdparty/systemd.git] / src / libsystemd / sd-bus / bus-message.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2013 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <sys/mman.h>
23
24 #include "sd-bus.h"
25
26 #include "alloc-util.h"
27 #include "bus-gvariant.h"
28 #include "bus-internal.h"
29 #include "bus-message.h"
30 #include "bus-signature.h"
31 #include "bus-type.h"
32 #include "bus-util.h"
33 #include "fd-util.h"
34 #include "io-util.h"
35 #include "memfd-util.h"
36 #include "string-util.h"
37 #include "strv.h"
38 #include "time-util.h"
39 #include "utf8.h"
40 #include "util.h"
41
42 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
43
44 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
45
46 if (p == NULL)
47 return NULL;
48
49 if (old_base == new_base)
50 return (void*) p;
51
52 if ((uint8_t*) p < (uint8_t*) old_base)
53 return (void*) p;
54
55 if ((uint8_t*) p >= (uint8_t*) old_base + sz)
56 return (void*) p;
57
58 return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
59 }
60
61 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
62 assert(m);
63 assert(part);
64
65 if (part->memfd >= 0) {
66 /* If we can reuse the memfd, try that. For that it
67 * can't be sealed yet. */
68
69 if (!part->sealed) {
70 assert(part->memfd_offset == 0);
71 assert(part->data == part->mmap_begin);
72 bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped, part->allocated);
73 } else {
74 if (part->mapped > 0)
75 assert_se(munmap(part->mmap_begin, part->mapped) == 0);
76
77 safe_close(part->memfd);
78 }
79
80 } else if (part->munmap_this)
81 munmap(part->mmap_begin, part->mapped);
82 else if (part->free_this)
83 free(part->data);
84
85 if (part != &m->body)
86 free(part);
87 }
88
89 static void message_reset_parts(sd_bus_message *m) {
90 struct bus_body_part *part;
91
92 assert(m);
93
94 part = &m->body;
95 while (m->n_body_parts > 0) {
96 struct bus_body_part *next = part->next;
97 message_free_part(m, part);
98 part = next;
99 m->n_body_parts--;
100 }
101
102 m->body_end = NULL;
103
104 m->cached_rindex_part = NULL;
105 m->cached_rindex_part_begin = 0;
106 }
107
108 static void message_reset_containers(sd_bus_message *m) {
109 unsigned i;
110
111 assert(m);
112
113 for (i = 0; i < m->n_containers; i++) {
114 free(m->containers[i].signature);
115 free(m->containers[i].offsets);
116 }
117
118 m->containers = mfree(m->containers);
119
120 m->n_containers = m->containers_allocated = 0;
121 m->root_container.index = 0;
122 }
123
124 static void message_free(sd_bus_message *m) {
125 assert(m);
126
127 if (m->free_header)
128 free(m->header);
129
130 message_reset_parts(m);
131
132 if (m->release_kdbus)
133 bus_kernel_cmd_free(m->bus, (uint8_t *) m->kdbus - (uint8_t *) m->bus->kdbus_buffer);
134
135 if (m->free_kdbus)
136 free(m->kdbus);
137
138 sd_bus_unref(m->bus);
139
140 if (m->free_fds) {
141 close_many(m->fds, m->n_fds);
142 free(m->fds);
143 }
144
145 if (m->iovec != m->iovec_fixed)
146 free(m->iovec);
147
148 m->destination_ptr = mfree(m->destination_ptr);
149 message_reset_containers(m);
150 free(m->root_container.signature);
151 free(m->root_container.offsets);
152
153 free(m->root_container.peeked_signature);
154
155 bus_creds_done(&m->creds);
156 free(m);
157 }
158
159 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz, bool add_offset) {
160 void *op, *np;
161 size_t old_size, new_size, start;
162
163 assert(m);
164
165 if (m->poisoned)
166 return NULL;
167
168 old_size = sizeof(struct bus_header) + m->fields_size;
169 start = ALIGN_TO(old_size, align);
170 new_size = start + sz;
171
172 if (new_size < start ||
173 new_size > (size_t) ((uint32_t) -1))
174 goto poison;
175
176 if (old_size == new_size)
177 return (uint8_t*) m->header + old_size;
178
179 if (m->free_header) {
180 np = realloc(m->header, ALIGN8(new_size));
181 if (!np)
182 goto poison;
183 } else {
184 /* Initially, the header is allocated as part of
185 * the sd_bus_message itself, let's replace it by
186 * dynamic data */
187
188 np = malloc(ALIGN8(new_size));
189 if (!np)
190 goto poison;
191
192 memcpy(np, m->header, sizeof(struct bus_header));
193 }
194
195 /* Zero out padding */
196 if (start > old_size)
197 memzero((uint8_t*) np + old_size, start - old_size);
198
199 op = m->header;
200 m->header = np;
201 m->fields_size = new_size - sizeof(struct bus_header);
202
203 /* Adjust quick access pointers */
204 m->path = adjust_pointer(m->path, op, old_size, m->header);
205 m->interface = adjust_pointer(m->interface, op, old_size, m->header);
206 m->member = adjust_pointer(m->member, op, old_size, m->header);
207 m->destination = adjust_pointer(m->destination, op, old_size, m->header);
208 m->sender = adjust_pointer(m->sender, op, old_size, m->header);
209 m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
210
211 m->free_header = true;
212
213 if (add_offset) {
214 if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets))
215 goto poison;
216
217 m->header_offsets[m->n_header_offsets++] = new_size - sizeof(struct bus_header);
218 }
219
220 return (uint8_t*) np + start;
221
222 poison:
223 m->poisoned = true;
224 return NULL;
225 }
226
227 static int message_append_field_string(
228 sd_bus_message *m,
229 uint64_t h,
230 char type,
231 const char *s,
232 const char **ret) {
233
234 size_t l;
235 uint8_t *p;
236
237 assert(m);
238
239 /* dbus1 only allows 8bit header field ids */
240 if (h > 0xFF)
241 return -EINVAL;
242
243 /* dbus1 doesn't allow strings over 32bit, let's enforce this
244 * globally, to not risk convertability */
245 l = strlen(s);
246 if (l > (size_t) (uint32_t) -1)
247 return -EINVAL;
248
249 /* Signature "(yv)" where the variant contains "s" */
250
251 if (BUS_MESSAGE_IS_GVARIANT(m)) {
252
253 /* (field id 64bit, ((string + NUL) + NUL + signature string 's') */
254 p = message_extend_fields(m, 8, 8 + l + 1 + 1 + 1, true);
255 if (!p)
256 return -ENOMEM;
257
258 *((uint64_t*) p) = h;
259 memcpy(p+8, s, l);
260 p[8+l] = 0;
261 p[8+l+1] = 0;
262 p[8+l+2] = type;
263
264 if (ret)
265 *ret = (char*) p + 8;
266
267 } else {
268 /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */
269 p = message_extend_fields(m, 8, 4 + 4 + l + 1, false);
270 if (!p)
271 return -ENOMEM;
272
273 p[0] = (uint8_t) h;
274 p[1] = 1;
275 p[2] = type;
276 p[3] = 0;
277
278 ((uint32_t*) p)[1] = l;
279 memcpy(p + 8, s, l + 1);
280
281 if (ret)
282 *ret = (char*) p + 8;
283 }
284
285 return 0;
286 }
287
288 static int message_append_field_signature(
289 sd_bus_message *m,
290 uint64_t h,
291 const char *s,
292 const char **ret) {
293
294 size_t l;
295 uint8_t *p;
296
297 assert(m);
298
299 /* dbus1 only allows 8bit header field ids */
300 if (h > 0xFF)
301 return -EINVAL;
302
303 /* dbus1 doesn't allow signatures over 8bit, let's enforce
304 * this globally, to not risk convertability */
305 l = strlen(s);
306 if (l > 255)
307 return -EINVAL;
308
309 /* Signature "(yv)" where the variant contains "g" */
310
311 if (BUS_MESSAGE_IS_GVARIANT(m))
312 /* For gvariant the serialization is the same as for normal strings */
313 return message_append_field_string(m, h, 'g', s, ret);
314 else {
315 /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */
316 p = message_extend_fields(m, 8, 4 + 1 + l + 1, false);
317 if (!p)
318 return -ENOMEM;
319
320 p[0] = (uint8_t) h;
321 p[1] = 1;
322 p[2] = SD_BUS_TYPE_SIGNATURE;
323 p[3] = 0;
324 p[4] = l;
325 memcpy(p + 5, s, l + 1);
326
327 if (ret)
328 *ret = (const char*) p + 5;
329 }
330
331 return 0;
332 }
333
334 static int message_append_field_uint32(sd_bus_message *m, uint64_t h, uint32_t x) {
335 uint8_t *p;
336
337 assert(m);
338
339 /* dbus1 only allows 8bit header field ids */
340 if (h > 0xFF)
341 return -EINVAL;
342
343 if (BUS_MESSAGE_IS_GVARIANT(m)) {
344 /* (field id 64bit + ((value + NUL + signature string 'u') */
345
346 p = message_extend_fields(m, 8, 8 + 4 + 1 + 1, true);
347 if (!p)
348 return -ENOMEM;
349
350 *((uint64_t*) p) = h;
351 *((uint32_t*) (p + 8)) = x;
352 p[12] = 0;
353 p[13] = 'u';
354 } else {
355 /* (field id byte + (signature length + signature 'u' + NUL) + value) */
356 p = message_extend_fields(m, 8, 4 + 4, false);
357 if (!p)
358 return -ENOMEM;
359
360 p[0] = (uint8_t) h;
361 p[1] = 1;
362 p[2] = 'u';
363 p[3] = 0;
364
365 ((uint32_t*) p)[1] = x;
366 }
367
368 return 0;
369 }
370
371 static int message_append_field_uint64(sd_bus_message *m, uint64_t h, uint64_t x) {
372 uint8_t *p;
373
374 assert(m);
375
376 /* dbus1 only allows 8bit header field ids */
377 if (h > 0xFF)
378 return -EINVAL;
379
380 if (BUS_MESSAGE_IS_GVARIANT(m)) {
381 /* (field id 64bit + ((value + NUL + signature string 't') */
382
383 p = message_extend_fields(m, 8, 8 + 8 + 1 + 1, true);
384 if (!p)
385 return -ENOMEM;
386
387 *((uint64_t*) p) = h;
388 *((uint64_t*) (p + 8)) = x;
389 p[16] = 0;
390 p[17] = 't';
391 } else {
392 /* (field id byte + (signature length + signature 't' + NUL) + 4 byte padding + value) */
393 p = message_extend_fields(m, 8, 4 + 4 + 8, false);
394 if (!p)
395 return -ENOMEM;
396
397 p[0] = (uint8_t) h;
398 p[1] = 1;
399 p[2] = 't';
400 p[3] = 0;
401 p[4] = 0;
402 p[5] = 0;
403 p[6] = 0;
404 p[7] = 0;
405
406 ((uint64_t*) p)[1] = x;
407 }
408
409 return 0;
410 }
411
412 static int message_append_reply_cookie(sd_bus_message *m, uint64_t cookie) {
413 assert(m);
414
415 if (BUS_MESSAGE_IS_GVARIANT(m))
416 return message_append_field_uint64(m, BUS_MESSAGE_HEADER_REPLY_SERIAL, cookie);
417 else {
418 /* 64bit cookies are not supported on dbus1 */
419 if (cookie > 0xffffffffUL)
420 return -EOPNOTSUPP;
421
422 return message_append_field_uint32(m, BUS_MESSAGE_HEADER_REPLY_SERIAL, (uint32_t) cookie);
423 }
424 }
425
426 int bus_message_from_header(
427 sd_bus *bus,
428 void *header,
429 size_t header_accessible,
430 void *footer,
431 size_t footer_accessible,
432 size_t message_size,
433 int *fds,
434 unsigned n_fds,
435 const char *label,
436 size_t extra,
437 sd_bus_message **ret) {
438
439 _cleanup_free_ sd_bus_message *m = NULL;
440 struct bus_header *h;
441 size_t a, label_sz;
442
443 assert(bus);
444 assert(header || header_accessible <= 0);
445 assert(footer || footer_accessible <= 0);
446 assert(fds || n_fds <= 0);
447 assert(ret);
448
449 if (header_accessible < sizeof(struct bus_header))
450 return -EBADMSG;
451
452 if (header_accessible > message_size)
453 return -EBADMSG;
454 if (footer_accessible > message_size)
455 return -EBADMSG;
456
457 h = header;
458 if (!IN_SET(h->version, 1, 2))
459 return -EBADMSG;
460
461 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
462 return -EBADMSG;
463
464 if (!IN_SET(h->endian, BUS_LITTLE_ENDIAN, BUS_BIG_ENDIAN))
465 return -EBADMSG;
466
467 /* Note that we are happy with unknown flags in the flags header! */
468
469 a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
470
471 if (label) {
472 label_sz = strlen(label);
473 a += label_sz + 1;
474 }
475
476 m = malloc0(a);
477 if (!m)
478 return -ENOMEM;
479
480 m->n_ref = 1;
481 m->sealed = true;
482 m->header = header;
483 m->header_accessible = header_accessible;
484 m->footer = footer;
485 m->footer_accessible = footer_accessible;
486
487 if (BUS_MESSAGE_IS_GVARIANT(m)) {
488 size_t ws;
489
490 if (h->dbus2.cookie == 0)
491 return -EBADMSG;
492
493 /* dbus2 derives the sizes from the message size and
494 the offset table at the end, since it is formatted as
495 gvariant "yyyyuta{tv}v". Since the message itself is a
496 structure with precisely to variable sized entries,
497 there's only one offset in the table, which marks the
498 end of the fields array. */
499
500 ws = bus_gvariant_determine_word_size(message_size, 0);
501 if (footer_accessible < ws)
502 return -EBADMSG;
503
504 m->fields_size = bus_gvariant_read_word_le((uint8_t*) footer + footer_accessible - ws, ws);
505 if (ALIGN8(m->fields_size) > message_size - ws)
506 return -EBADMSG;
507 if (m->fields_size < sizeof(struct bus_header))
508 return -EBADMSG;
509
510 m->fields_size -= sizeof(struct bus_header);
511 m->body_size = message_size - (sizeof(struct bus_header) + ALIGN8(m->fields_size));
512 } else {
513 if (h->dbus1.serial == 0)
514 return -EBADMSG;
515
516 /* dbus1 has the sizes in the header */
517 m->fields_size = BUS_MESSAGE_BSWAP32(m, h->dbus1.fields_size);
518 m->body_size = BUS_MESSAGE_BSWAP32(m, h->dbus1.body_size);
519
520 if (sizeof(struct bus_header) + ALIGN8(m->fields_size) + m->body_size != message_size)
521 return -EBADMSG;
522 }
523
524 m->fds = fds;
525 m->n_fds = n_fds;
526
527 if (label) {
528 m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
529 memcpy(m->creds.label, label, label_sz + 1);
530
531 m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
532 }
533
534 m->bus = sd_bus_ref(bus);
535 *ret = m;
536 m = NULL;
537
538 return 0;
539 }
540
541 int bus_message_from_malloc(
542 sd_bus *bus,
543 void *buffer,
544 size_t length,
545 int *fds,
546 unsigned n_fds,
547 const char *label,
548 sd_bus_message **ret) {
549
550 sd_bus_message *m;
551 size_t sz;
552 int r;
553
554 r = bus_message_from_header(
555 bus,
556 buffer, length, /* in this case the initial bytes and the final bytes are the same */
557 buffer, length,
558 length,
559 fds, n_fds,
560 label,
561 0, &m);
562 if (r < 0)
563 return r;
564
565 sz = length - sizeof(struct bus_header) - ALIGN8(m->fields_size);
566 if (sz > 0) {
567 m->n_body_parts = 1;
568 m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(m->fields_size);
569 m->body.size = sz;
570 m->body.sealed = true;
571 m->body.memfd = -1;
572 }
573
574 m->n_iovec = 1;
575 m->iovec = m->iovec_fixed;
576 m->iovec[0].iov_base = buffer;
577 m->iovec[0].iov_len = length;
578
579 r = bus_message_parse_fields(m);
580 if (r < 0)
581 goto fail;
582
583 /* We take possession of the memory and fds now */
584 m->free_header = true;
585 m->free_fds = true;
586
587 *ret = m;
588 return 0;
589
590 fail:
591 message_free(m);
592 return r;
593 }
594
595 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
596 sd_bus_message *m;
597
598 assert(bus);
599
600 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
601 if (!m)
602 return NULL;
603
604 m->n_ref = 1;
605 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
606 m->header->endian = BUS_NATIVE_ENDIAN;
607 m->header->type = type;
608 m->header->version = bus->message_version;
609 m->allow_fds = bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
610 m->root_container.need_offsets = BUS_MESSAGE_IS_GVARIANT(m);
611 m->bus = sd_bus_ref(bus);
612
613 if (bus->allow_interactive_authorization)
614 m->header->flags |= BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION;
615
616 return m;
617 }
618
619 _public_ int sd_bus_message_new_signal(
620 sd_bus *bus,
621 sd_bus_message **m,
622 const char *path,
623 const char *interface,
624 const char *member) {
625
626 sd_bus_message *t;
627 int r;
628
629 assert_return(bus, -ENOTCONN);
630 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
631 assert_return(object_path_is_valid(path), -EINVAL);
632 assert_return(interface_name_is_valid(interface), -EINVAL);
633 assert_return(member_name_is_valid(member), -EINVAL);
634 assert_return(m, -EINVAL);
635
636 t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
637 if (!t)
638 return -ENOMEM;
639
640 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
641
642 r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
643 if (r < 0)
644 goto fail;
645 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
646 if (r < 0)
647 goto fail;
648 r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
649 if (r < 0)
650 goto fail;
651
652 *m = t;
653 return 0;
654
655 fail:
656 sd_bus_message_unref(t);
657 return r;
658 }
659
660 _public_ int sd_bus_message_new_method_call(
661 sd_bus *bus,
662 sd_bus_message **m,
663 const char *destination,
664 const char *path,
665 const char *interface,
666 const char *member) {
667
668 sd_bus_message *t;
669 int r;
670
671 assert_return(bus, -ENOTCONN);
672 assert_return(bus->state != BUS_UNSET, -ENOTCONN);
673 assert_return(!destination || service_name_is_valid(destination), -EINVAL);
674 assert_return(object_path_is_valid(path), -EINVAL);
675 assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
676 assert_return(member_name_is_valid(member), -EINVAL);
677 assert_return(m, -EINVAL);
678
679 t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
680 if (!t)
681 return -ENOMEM;
682
683 r = message_append_field_string(t, BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
684 if (r < 0)
685 goto fail;
686 r = message_append_field_string(t, BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
687 if (r < 0)
688 goto fail;
689
690 if (interface) {
691 r = message_append_field_string(t, BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
692 if (r < 0)
693 goto fail;
694 }
695
696 if (destination) {
697 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
698 if (r < 0)
699 goto fail;
700 }
701
702 *m = t;
703 return 0;
704
705 fail:
706 message_free(t);
707 return r;
708 }
709
710 static int message_new_reply(
711 sd_bus_message *call,
712 uint8_t type,
713 sd_bus_message **m) {
714
715 sd_bus_message *t;
716 int r;
717
718 assert_return(call, -EINVAL);
719 assert_return(call->sealed, -EPERM);
720 assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
721 assert_return(call->bus->state != BUS_UNSET, -ENOTCONN);
722 assert_return(m, -EINVAL);
723
724 t = message_new(call->bus, type);
725 if (!t)
726 return -ENOMEM;
727
728 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
729 t->reply_cookie = BUS_MESSAGE_COOKIE(call);
730 if (t->reply_cookie == 0)
731 return -EOPNOTSUPP;
732
733 r = message_append_reply_cookie(t, t->reply_cookie);
734 if (r < 0)
735 goto fail;
736
737 if (call->sender) {
738 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
739 if (r < 0)
740 goto fail;
741 }
742
743 t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
744 t->enforced_reply_signature = call->enforced_reply_signature;
745
746 *m = t;
747 return 0;
748
749 fail:
750 message_free(t);
751 return r;
752 }
753
754 _public_ int sd_bus_message_new_method_return(
755 sd_bus_message *call,
756 sd_bus_message **m) {
757
758 return message_new_reply(call, SD_BUS_MESSAGE_METHOD_RETURN, m);
759 }
760
761 _public_ int sd_bus_message_new_method_error(
762 sd_bus_message *call,
763 sd_bus_message **m,
764 const sd_bus_error *e) {
765
766 sd_bus_message *t;
767 int r;
768
769 assert_return(sd_bus_error_is_set(e), -EINVAL);
770 assert_return(m, -EINVAL);
771
772 r = message_new_reply(call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
773 if (r < 0)
774 return r;
775
776 r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
777 if (r < 0)
778 goto fail;
779
780 if (e->message) {
781 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
782 if (r < 0)
783 goto fail;
784 }
785
786 t->error._need_free = -1;
787
788 *m = t;
789 return 0;
790
791 fail:
792 message_free(t);
793 return r;
794 }
795
796 _public_ int sd_bus_message_new_method_errorf(
797 sd_bus_message *call,
798 sd_bus_message **m,
799 const char *name,
800 const char *format,
801 ...) {
802
803 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
804 va_list ap;
805
806 assert_return(name, -EINVAL);
807 assert_return(m, -EINVAL);
808
809 va_start(ap, format);
810 bus_error_setfv(&error, name, format, ap);
811 va_end(ap);
812
813 return sd_bus_message_new_method_error(call, m, &error);
814 }
815
816 _public_ int sd_bus_message_new_method_errno(
817 sd_bus_message *call,
818 sd_bus_message **m,
819 int error,
820 const sd_bus_error *p) {
821
822 _cleanup_(sd_bus_error_free) sd_bus_error berror = SD_BUS_ERROR_NULL;
823
824 if (sd_bus_error_is_set(p))
825 return sd_bus_message_new_method_error(call, m, p);
826
827 sd_bus_error_set_errno(&berror, error);
828
829 return sd_bus_message_new_method_error(call, m, &berror);
830 }
831
832 _public_ int sd_bus_message_new_method_errnof(
833 sd_bus_message *call,
834 sd_bus_message **m,
835 int error,
836 const char *format,
837 ...) {
838
839 _cleanup_(sd_bus_error_free) sd_bus_error berror = SD_BUS_ERROR_NULL;
840 va_list ap;
841
842 va_start(ap, format);
843 sd_bus_error_set_errnofv(&berror, error, format, ap);
844 va_end(ap);
845
846 return sd_bus_message_new_method_error(call, m, &berror);
847 }
848
849 void bus_message_set_sender_local(sd_bus *bus, sd_bus_message *m) {
850 assert(bus);
851 assert(m);
852
853 m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus.Local";
854 m->creds.well_known_names_local = true;
855 m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
856 }
857
858 void bus_message_set_sender_driver(sd_bus *bus, sd_bus_message *m) {
859 assert(bus);
860 assert(m);
861
862 m->sender = m->creds.unique_name = (char*) "org.freedesktop.DBus";
863 m->creds.well_known_names_driver = true;
864 m->creds.mask |= (SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES) & bus->creds_mask;
865 }
866
867 int bus_message_new_synthetic_error(
868 sd_bus *bus,
869 uint64_t cookie,
870 const sd_bus_error *e,
871 sd_bus_message **m) {
872
873 sd_bus_message *t;
874 int r;
875
876 assert(bus);
877 assert(sd_bus_error_is_set(e));
878 assert(m);
879
880 t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
881 if (!t)
882 return -ENOMEM;
883
884 t->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;
885 t->reply_cookie = cookie;
886
887 r = message_append_reply_cookie(t, t->reply_cookie);
888 if (r < 0)
889 goto fail;
890
891 if (bus && bus->unique_name) {
892 r = message_append_field_string(t, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
893 if (r < 0)
894 goto fail;
895 }
896
897 r = message_append_field_string(t, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
898 if (r < 0)
899 goto fail;
900
901 if (e->message) {
902 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
903 if (r < 0)
904 goto fail;
905 }
906
907 t->error._need_free = -1;
908
909 bus_message_set_sender_driver(bus, t);
910
911 *m = t;
912 return 0;
913
914 fail:
915 message_free(t);
916 return r;
917 }
918
919 _public_ sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
920
921 if (!m)
922 return NULL;
923
924 assert(m->n_ref > 0);
925 m->n_ref++;
926
927 return m;
928 }
929
930 _public_ sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
931
932 if (!m)
933 return NULL;
934
935 assert(m->n_ref > 0);
936 m->n_ref--;
937
938 if (m->n_ref > 0)
939 return NULL;
940
941 message_free(m);
942 return NULL;
943 }
944
945 _public_ int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
946 assert_return(m, -EINVAL);
947 assert_return(type, -EINVAL);
948
949 *type = m->header->type;
950 return 0;
951 }
952
953 _public_ int sd_bus_message_get_cookie(sd_bus_message *m, uint64_t *cookie) {
954 uint64_t c;
955
956 assert_return(m, -EINVAL);
957 assert_return(cookie, -EINVAL);
958
959 c = BUS_MESSAGE_COOKIE(m);
960 if (c == 0)
961 return -ENODATA;
962
963 *cookie = BUS_MESSAGE_COOKIE(m);
964 return 0;
965 }
966
967 _public_ int sd_bus_message_get_reply_cookie(sd_bus_message *m, uint64_t *cookie) {
968 assert_return(m, -EINVAL);
969 assert_return(cookie, -EINVAL);
970
971 if (m->reply_cookie == 0)
972 return -ENODATA;
973
974 *cookie = m->reply_cookie;
975 return 0;
976 }
977
978 _public_ int sd_bus_message_get_expect_reply(sd_bus_message *m) {
979 assert_return(m, -EINVAL);
980
981 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
982 !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
983 }
984
985 _public_ int sd_bus_message_get_auto_start(sd_bus_message *m) {
986 assert_return(m, -EINVAL);
987
988 return !(m->header->flags & BUS_MESSAGE_NO_AUTO_START);
989 }
990
991 _public_ int sd_bus_message_get_allow_interactive_authorization(sd_bus_message *m) {
992 assert_return(m, -EINVAL);
993
994 return m->header->type == SD_BUS_MESSAGE_METHOD_CALL &&
995 (m->header->flags & BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION);
996 }
997
998 _public_ const char *sd_bus_message_get_path(sd_bus_message *m) {
999 assert_return(m, NULL);
1000
1001 return m->path;
1002 }
1003
1004 _public_ const char *sd_bus_message_get_interface(sd_bus_message *m) {
1005 assert_return(m, NULL);
1006
1007 return m->interface;
1008 }
1009
1010 _public_ const char *sd_bus_message_get_member(sd_bus_message *m) {
1011 assert_return(m, NULL);
1012
1013 return m->member;
1014 }
1015
1016 _public_ const char *sd_bus_message_get_destination(sd_bus_message *m) {
1017 assert_return(m, NULL);
1018
1019 return m->destination;
1020 }
1021
1022 _public_ const char *sd_bus_message_get_sender(sd_bus_message *m) {
1023 assert_return(m, NULL);
1024
1025 return m->sender;
1026 }
1027
1028 _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
1029 assert_return(m, NULL);
1030
1031 if (!sd_bus_error_is_set(&m->error))
1032 return NULL;
1033
1034 return &m->error;
1035 }
1036
1037 _public_ int sd_bus_message_get_monotonic_usec(sd_bus_message *m, uint64_t *usec) {
1038 assert_return(m, -EINVAL);
1039 assert_return(usec, -EINVAL);
1040
1041 if (m->monotonic <= 0)
1042 return -ENODATA;
1043
1044 *usec = m->monotonic;
1045 return 0;
1046 }
1047
1048 _public_ int sd_bus_message_get_realtime_usec(sd_bus_message *m, uint64_t *usec) {
1049 assert_return(m, -EINVAL);
1050 assert_return(usec, -EINVAL);
1051
1052 if (m->realtime <= 0)
1053 return -ENODATA;
1054
1055 *usec = m->realtime;
1056 return 0;
1057 }
1058
1059 _public_ int sd_bus_message_get_seqnum(sd_bus_message *m, uint64_t *seqnum) {
1060 assert_return(m, -EINVAL);
1061 assert_return(seqnum, -EINVAL);
1062
1063 if (m->seqnum <= 0)
1064 return -ENODATA;
1065
1066 *seqnum = m->seqnum;
1067 return 0;
1068 }
1069
1070 _public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
1071 assert_return(m, NULL);
1072
1073 if (m->creds.mask == 0)
1074 return NULL;
1075
1076 return &m->creds;
1077 }
1078
1079 _public_ int sd_bus_message_is_signal(
1080 sd_bus_message *m,
1081 const char *interface,
1082 const char *member) {
1083
1084 assert_return(m, -EINVAL);
1085
1086 if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
1087 return 0;
1088
1089 if (interface && (!m->interface || !streq(m->interface, interface)))
1090 return 0;
1091
1092 if (member && (!m->member || !streq(m->member, member)))
1093 return 0;
1094
1095 return 1;
1096 }
1097
1098 _public_ int sd_bus_message_is_method_call(
1099 sd_bus_message *m,
1100 const char *interface,
1101 const char *member) {
1102
1103 assert_return(m, -EINVAL);
1104
1105 if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1106 return 0;
1107
1108 if (interface && (!m->interface || !streq(m->interface, interface)))
1109 return 0;
1110
1111 if (member && (!m->member || !streq(m->member, member)))
1112 return 0;
1113
1114 return 1;
1115 }
1116
1117 _public_ int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1118 assert_return(m, -EINVAL);
1119
1120 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
1121 return 0;
1122
1123 if (name && (!m->error.name || !streq(m->error.name, name)))
1124 return 0;
1125
1126 return 1;
1127 }
1128
1129 _public_ int sd_bus_message_set_expect_reply(sd_bus_message *m, int b) {
1130 assert_return(m, -EINVAL);
1131 assert_return(!m->sealed, -EPERM);
1132 assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
1133
1134 SET_FLAG(m->header->flags, BUS_MESSAGE_NO_REPLY_EXPECTED, !b);
1135
1136 return 0;
1137 }
1138
1139 _public_ int sd_bus_message_set_auto_start(sd_bus_message *m, int b) {
1140 assert_return(m, -EINVAL);
1141 assert_return(!m->sealed, -EPERM);
1142
1143 SET_FLAG(m->header->flags, BUS_MESSAGE_NO_AUTO_START, !b);
1144
1145 return 0;
1146 }
1147
1148 _public_ int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *m, int b) {
1149 assert_return(m, -EINVAL);
1150 assert_return(!m->sealed, -EPERM);
1151
1152 SET_FLAG(m->header->flags, BUS_MESSAGE_ALLOW_INTERACTIVE_AUTHORIZATION, b);
1153
1154 return 0;
1155 }
1156
1157 static struct bus_container *message_get_container(sd_bus_message *m) {
1158 assert(m);
1159
1160 if (m->n_containers == 0)
1161 return &m->root_container;
1162
1163 assert(m->containers);
1164 return m->containers + m->n_containers - 1;
1165 }
1166
1167 struct bus_body_part *message_append_part(sd_bus_message *m) {
1168 struct bus_body_part *part;
1169
1170 assert(m);
1171
1172 if (m->poisoned)
1173 return NULL;
1174
1175 if (m->n_body_parts <= 0) {
1176 part = &m->body;
1177 zero(*part);
1178 } else {
1179 assert(m->body_end);
1180
1181 part = new0(struct bus_body_part, 1);
1182 if (!part) {
1183 m->poisoned = true;
1184 return NULL;
1185 }
1186
1187 m->body_end->next = part;
1188 }
1189
1190 part->memfd = -1;
1191 m->body_end = part;
1192 m->n_body_parts++;
1193
1194 return part;
1195 }
1196
1197 static void part_zero(struct bus_body_part *part, size_t sz) {
1198 assert(part);
1199 assert(sz > 0);
1200 assert(sz < 8);
1201
1202 /* All other fields can be left in their defaults */
1203 assert(!part->data);
1204 assert(part->memfd < 0);
1205
1206 part->size = sz;
1207 part->is_zero = true;
1208 part->sealed = true;
1209 }
1210
1211 static int part_make_space(
1212 struct sd_bus_message *m,
1213 struct bus_body_part *part,
1214 size_t sz,
1215 void **q) {
1216
1217 void *n;
1218 int r;
1219
1220 assert(m);
1221 assert(part);
1222 assert(!part->sealed);
1223
1224 if (m->poisoned)
1225 return -ENOMEM;
1226
1227 if (!part->data && part->memfd < 0) {
1228 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped, &part->allocated);
1229 part->mmap_begin = part->data;
1230 }
1231
1232 if (part->memfd >= 0) {
1233
1234 if (part->allocated == 0 || sz > part->allocated) {
1235 uint64_t new_allocated;
1236
1237 new_allocated = PAGE_ALIGN(sz > 0 ? 2 * sz : 1);
1238 r = memfd_set_size(part->memfd, new_allocated);
1239 if (r < 0) {
1240 m->poisoned = true;
1241 return r;
1242 }
1243
1244 part->allocated = new_allocated;
1245 }
1246
1247 if (!part->data || sz > part->mapped) {
1248 size_t psz;
1249
1250 psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1251 if (part->mapped <= 0)
1252 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1253 else
1254 n = mremap(part->mmap_begin, part->mapped, psz, MREMAP_MAYMOVE);
1255
1256 if (n == MAP_FAILED) {
1257 m->poisoned = true;
1258 return -errno;
1259 }
1260
1261 part->mmap_begin = part->data = n;
1262 part->mapped = psz;
1263 part->memfd_offset = 0;
1264 }
1265
1266 part->munmap_this = true;
1267 } else {
1268 if (part->allocated == 0 || sz > part->allocated) {
1269 size_t new_allocated;
1270
1271 new_allocated = sz > 0 ? 2 * sz : 64;
1272 n = realloc(part->data, new_allocated);
1273 if (!n) {
1274 m->poisoned = true;
1275 return -ENOMEM;
1276 }
1277
1278 part->data = n;
1279 part->allocated = new_allocated;
1280 part->free_this = true;
1281 }
1282 }
1283
1284 if (q)
1285 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1286
1287 part->size = sz;
1288 return 0;
1289 }
1290
1291 static int message_add_offset(sd_bus_message *m, size_t offset) {
1292 struct bus_container *c;
1293
1294 assert(m);
1295 assert(BUS_MESSAGE_IS_GVARIANT(m));
1296
1297 /* Add offset to current container, unless this is the first
1298 * item in it, which will have the 0 offset, which we can
1299 * ignore. */
1300 c = message_get_container(m);
1301
1302 if (!c->need_offsets)
1303 return 0;
1304
1305 if (!GREEDY_REALLOC(c->offsets, c->offsets_allocated, c->n_offsets + 1))
1306 return -ENOMEM;
1307
1308 c->offsets[c->n_offsets++] = offset;
1309 return 0;
1310 }
1311
1312 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1313 struct bus_container *c;
1314
1315 assert(m);
1316
1317 if (expand <= 0)
1318 return;
1319
1320 /* Update counters */
1321 for (c = m->containers; c < m->containers + m->n_containers; c++) {
1322
1323 if (c->array_size)
1324 *c->array_size += expand;
1325 }
1326 }
1327
1328 static void *message_extend_body(
1329 sd_bus_message *m,
1330 size_t align,
1331 size_t sz,
1332 bool add_offset,
1333 bool force_inline) {
1334
1335 size_t start_body, end_body, padding, added;
1336 void *p;
1337 int r;
1338
1339 assert(m);
1340 assert(align > 0);
1341 assert(!m->sealed);
1342
1343 if (m->poisoned)
1344 return NULL;
1345
1346 start_body = ALIGN_TO((size_t) m->body_size, align);
1347 end_body = start_body + sz;
1348
1349 padding = start_body - m->body_size;
1350 added = padding + sz;
1351
1352 /* Check for 32bit overflows */
1353 if (end_body > (size_t) ((uint32_t) -1) ||
1354 end_body < start_body) {
1355 m->poisoned = true;
1356 return NULL;
1357 }
1358
1359 if (added > 0) {
1360 struct bus_body_part *part = NULL;
1361 bool add_new_part;
1362
1363 add_new_part =
1364 m->n_body_parts <= 0 ||
1365 m->body_end->sealed ||
1366 (padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size) ||
1367 (force_inline && m->body_end->size > MEMFD_MIN_SIZE); /* if this must be an inlined extension, let's create a new part if the previous part is large enough to be inlined */
1368
1369 if (add_new_part) {
1370 if (padding > 0) {
1371 part = message_append_part(m);
1372 if (!part)
1373 return NULL;
1374
1375 part_zero(part, padding);
1376 }
1377
1378 part = message_append_part(m);
1379 if (!part)
1380 return NULL;
1381
1382 r = part_make_space(m, part, sz, &p);
1383 if (r < 0)
1384 return NULL;
1385 } else {
1386 struct bus_container *c;
1387 void *op;
1388 size_t os, start_part, end_part;
1389
1390 part = m->body_end;
1391 op = part->data;
1392 os = part->size;
1393
1394 start_part = ALIGN_TO(part->size, align);
1395 end_part = start_part + sz;
1396
1397 r = part_make_space(m, part, end_part, &p);
1398 if (r < 0)
1399 return NULL;
1400
1401 if (padding > 0) {
1402 memzero(p, padding);
1403 p = (uint8_t*) p + padding;
1404 }
1405
1406 /* Readjust pointers */
1407 for (c = m->containers; c < m->containers + m->n_containers; c++)
1408 c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1409
1410 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1411 }
1412 } else
1413 /* Return something that is not NULL and is aligned */
1414 p = (uint8_t *) NULL + align;
1415
1416 m->body_size = end_body;
1417 message_extend_containers(m, added);
1418
1419 if (add_offset) {
1420 r = message_add_offset(m, end_body);
1421 if (r < 0) {
1422 m->poisoned = true;
1423 return NULL;
1424 }
1425 }
1426
1427 return p;
1428 }
1429
1430 static int message_push_fd(sd_bus_message *m, int fd) {
1431 int *f, copy;
1432
1433 assert(m);
1434
1435 if (fd < 0)
1436 return -EINVAL;
1437
1438 if (!m->allow_fds)
1439 return -EOPNOTSUPP;
1440
1441 copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
1442 if (copy < 0)
1443 return -errno;
1444
1445 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1446 if (!f) {
1447 m->poisoned = true;
1448 safe_close(copy);
1449 return -ENOMEM;
1450 }
1451
1452 m->fds = f;
1453 m->fds[m->n_fds] = copy;
1454 m->free_fds = true;
1455
1456 return copy;
1457 }
1458
1459 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1460 _cleanup_close_ int fd = -1;
1461 struct bus_container *c;
1462 ssize_t align, sz;
1463 void *a;
1464
1465 assert_return(m, -EINVAL);
1466 assert_return(!m->sealed, -EPERM);
1467 assert_return(bus_type_is_basic(type), -EINVAL);
1468 assert_return(!m->poisoned, -ESTALE);
1469
1470 c = message_get_container(m);
1471
1472 if (c->signature && c->signature[c->index]) {
1473 /* Container signature is already set */
1474
1475 if (c->signature[c->index] != type)
1476 return -ENXIO;
1477 } else {
1478 char *e;
1479
1480 /* Maybe we can append to the signature? But only if this is the top-level container */
1481 if (c->enclosing != 0)
1482 return -ENXIO;
1483
1484 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1485 if (!e) {
1486 m->poisoned = true;
1487 return -ENOMEM;
1488 }
1489 }
1490
1491 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1492 uint8_t u8;
1493 uint32_t u32;
1494
1495 switch (type) {
1496
1497 case SD_BUS_TYPE_SIGNATURE:
1498 case SD_BUS_TYPE_STRING:
1499 p = strempty(p);
1500
1501 /* Fall through... */
1502 case SD_BUS_TYPE_OBJECT_PATH:
1503 if (!p)
1504 return -EINVAL;
1505
1506 align = 1;
1507 sz = strlen(p) + 1;
1508 break;
1509
1510 case SD_BUS_TYPE_BOOLEAN:
1511
1512 u8 = p && *(int*) p;
1513 p = &u8;
1514
1515 align = sz = 1;
1516 break;
1517
1518 case SD_BUS_TYPE_UNIX_FD:
1519
1520 if (!p)
1521 return -EINVAL;
1522
1523 fd = message_push_fd(m, *(int*) p);
1524 if (fd < 0)
1525 return fd;
1526
1527 u32 = m->n_fds;
1528 p = &u32;
1529
1530 align = sz = 4;
1531 break;
1532
1533 default:
1534 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
1535 sz = bus_gvariant_get_size(CHAR_TO_STR(type));
1536 break;
1537 }
1538
1539 assert(align > 0);
1540 assert(sz > 0);
1541
1542 a = message_extend_body(m, align, sz, true, false);
1543 if (!a)
1544 return -ENOMEM;
1545
1546 memcpy(a, p, sz);
1547
1548 if (stored)
1549 *stored = (const uint8_t*) a;
1550
1551 } else {
1552 uint32_t u32;
1553
1554 switch (type) {
1555
1556 case SD_BUS_TYPE_STRING:
1557 /* To make things easy we'll serialize a NULL string
1558 * into the empty string */
1559 p = strempty(p);
1560
1561 /* Fall through... */
1562 case SD_BUS_TYPE_OBJECT_PATH:
1563
1564 if (!p)
1565 return -EINVAL;
1566
1567 align = 4;
1568 sz = 4 + strlen(p) + 1;
1569 break;
1570
1571 case SD_BUS_TYPE_SIGNATURE:
1572
1573 p = strempty(p);
1574
1575 align = 1;
1576 sz = 1 + strlen(p) + 1;
1577 break;
1578
1579 case SD_BUS_TYPE_BOOLEAN:
1580
1581 u32 = p && *(int*) p;
1582 p = &u32;
1583
1584 align = sz = 4;
1585 break;
1586
1587 case SD_BUS_TYPE_UNIX_FD:
1588
1589 if (!p)
1590 return -EINVAL;
1591
1592 fd = message_push_fd(m, *(int*) p);
1593 if (fd < 0)
1594 return fd;
1595
1596 u32 = m->n_fds;
1597 p = &u32;
1598
1599 align = sz = 4;
1600 break;
1601
1602 default:
1603 align = bus_type_get_alignment(type);
1604 sz = bus_type_get_size(type);
1605 break;
1606 }
1607
1608 assert(align > 0);
1609 assert(sz > 0);
1610
1611 a = message_extend_body(m, align, sz, false, false);
1612 if (!a)
1613 return -ENOMEM;
1614
1615 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1616 *(uint32_t*) a = sz - 5;
1617 memcpy((uint8_t*) a + 4, p, sz - 4);
1618
1619 if (stored)
1620 *stored = (const uint8_t*) a + 4;
1621
1622 } else if (type == SD_BUS_TYPE_SIGNATURE) {
1623 *(uint8_t*) a = sz - 2;
1624 memcpy((uint8_t*) a + 1, p, sz - 1);
1625
1626 if (stored)
1627 *stored = (const uint8_t*) a + 1;
1628 } else {
1629 memcpy(a, p, sz);
1630
1631 if (stored)
1632 *stored = a;
1633 }
1634 }
1635
1636 if (type == SD_BUS_TYPE_UNIX_FD)
1637 m->n_fds++;
1638
1639 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1640 c->index++;
1641
1642 fd = -1;
1643 return 0;
1644 }
1645
1646 _public_ int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1647 return message_append_basic(m, type, p, NULL);
1648 }
1649
1650 _public_ int sd_bus_message_append_string_space(
1651 sd_bus_message *m,
1652 size_t size,
1653 char **s) {
1654
1655 struct bus_container *c;
1656 void *a;
1657
1658 assert_return(m, -EINVAL);
1659 assert_return(s, -EINVAL);
1660 assert_return(!m->sealed, -EPERM);
1661 assert_return(!m->poisoned, -ESTALE);
1662
1663 c = message_get_container(m);
1664
1665 if (c->signature && c->signature[c->index]) {
1666 /* Container signature is already set */
1667
1668 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1669 return -ENXIO;
1670 } else {
1671 char *e;
1672
1673 /* Maybe we can append to the signature? But only if this is the top-level container */
1674 if (c->enclosing != 0)
1675 return -ENXIO;
1676
1677 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1678 if (!e) {
1679 m->poisoned = true;
1680 return -ENOMEM;
1681 }
1682 }
1683
1684 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1685 a = message_extend_body(m, 1, size + 1, true, false);
1686 if (!a)
1687 return -ENOMEM;
1688
1689 *s = a;
1690 } else {
1691 a = message_extend_body(m, 4, 4 + size + 1, false, false);
1692 if (!a)
1693 return -ENOMEM;
1694
1695 *(uint32_t*) a = size;
1696 *s = (char*) a + 4;
1697 }
1698
1699 (*s)[size] = 0;
1700
1701 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1702 c->index++;
1703
1704 return 0;
1705 }
1706
1707 _public_ int sd_bus_message_append_string_iovec(
1708 sd_bus_message *m,
1709 const struct iovec *iov,
1710 unsigned n) {
1711
1712 size_t size;
1713 unsigned i;
1714 char *p;
1715 int r;
1716
1717 assert_return(m, -EINVAL);
1718 assert_return(!m->sealed, -EPERM);
1719 assert_return(iov || n == 0, -EINVAL);
1720 assert_return(!m->poisoned, -ESTALE);
1721
1722 size = IOVEC_TOTAL_SIZE(iov, n);
1723
1724 r = sd_bus_message_append_string_space(m, size, &p);
1725 if (r < 0)
1726 return r;
1727
1728 for (i = 0; i < n; i++) {
1729
1730 if (iov[i].iov_base)
1731 memcpy(p, iov[i].iov_base, iov[i].iov_len);
1732 else
1733 memset(p, ' ', iov[i].iov_len);
1734
1735 p += iov[i].iov_len;
1736 }
1737
1738 return 0;
1739 }
1740
1741 static int bus_message_open_array(
1742 sd_bus_message *m,
1743 struct bus_container *c,
1744 const char *contents,
1745 uint32_t **array_size,
1746 size_t *begin,
1747 bool *need_offsets) {
1748
1749 unsigned nindex;
1750 int alignment, r;
1751
1752 assert(m);
1753 assert(c);
1754 assert(contents);
1755 assert(array_size);
1756 assert(begin);
1757 assert(need_offsets);
1758
1759 if (!signature_is_single(contents, true))
1760 return -EINVAL;
1761
1762 if (c->signature && c->signature[c->index]) {
1763
1764 /* Verify the existing signature */
1765
1766 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1767 return -ENXIO;
1768
1769 if (!startswith(c->signature + c->index + 1, contents))
1770 return -ENXIO;
1771
1772 nindex = c->index + 1 + strlen(contents);
1773 } else {
1774 char *e;
1775
1776 if (c->enclosing != 0)
1777 return -ENXIO;
1778
1779 /* Extend the existing signature */
1780
1781 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1782 if (!e) {
1783 m->poisoned = true;
1784 return -ENOMEM;
1785 }
1786
1787 nindex = e - c->signature;
1788 }
1789
1790 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1791 alignment = bus_gvariant_get_alignment(contents);
1792 if (alignment < 0)
1793 return alignment;
1794
1795 /* Add alignment padding and add to offset list */
1796 if (!message_extend_body(m, alignment, 0, false, false))
1797 return -ENOMEM;
1798
1799 r = bus_gvariant_is_fixed_size(contents);
1800 if (r < 0)
1801 return r;
1802
1803 *begin = m->body_size;
1804 *need_offsets = r == 0;
1805 } else {
1806 void *a, *op;
1807 size_t os;
1808 struct bus_body_part *o;
1809
1810 alignment = bus_type_get_alignment(contents[0]);
1811 if (alignment < 0)
1812 return alignment;
1813
1814 a = message_extend_body(m, 4, 4, false, false);
1815 if (!a)
1816 return -ENOMEM;
1817
1818 o = m->body_end;
1819 op = m->body_end->data;
1820 os = m->body_end->size;
1821
1822 /* Add alignment between size and first element */
1823 if (!message_extend_body(m, alignment, 0, false, false))
1824 return -ENOMEM;
1825
1826 /* location of array size might have changed so let's readjust a */
1827 if (o == m->body_end)
1828 a = adjust_pointer(a, op, os, m->body_end->data);
1829
1830 *(uint32_t*) a = 0;
1831 *array_size = a;
1832 }
1833
1834 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1835 c->index = nindex;
1836
1837 return 0;
1838 }
1839
1840 static int bus_message_open_variant(
1841 sd_bus_message *m,
1842 struct bus_container *c,
1843 const char *contents) {
1844
1845 assert(m);
1846 assert(c);
1847 assert(contents);
1848
1849 if (!signature_is_single(contents, false))
1850 return -EINVAL;
1851
1852 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1853 return -EINVAL;
1854
1855 if (c->signature && c->signature[c->index]) {
1856
1857 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1858 return -ENXIO;
1859
1860 } else {
1861 char *e;
1862
1863 if (c->enclosing != 0)
1864 return -ENXIO;
1865
1866 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1867 if (!e) {
1868 m->poisoned = true;
1869 return -ENOMEM;
1870 }
1871 }
1872
1873 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1874 /* Variants are always aligned to 8 */
1875
1876 if (!message_extend_body(m, 8, 0, false, false))
1877 return -ENOMEM;
1878
1879 } else {
1880 size_t l;
1881 void *a;
1882
1883 l = strlen(contents);
1884 a = message_extend_body(m, 1, 1 + l + 1, false, false);
1885 if (!a)
1886 return -ENOMEM;
1887
1888 *(uint8_t*) a = l;
1889 memcpy((uint8_t*) a + 1, contents, l + 1);
1890 }
1891
1892 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1893 c->index++;
1894
1895 return 0;
1896 }
1897
1898 static int bus_message_open_struct(
1899 sd_bus_message *m,
1900 struct bus_container *c,
1901 const char *contents,
1902 size_t *begin,
1903 bool *need_offsets) {
1904
1905 size_t nindex;
1906 int r;
1907
1908 assert(m);
1909 assert(c);
1910 assert(contents);
1911 assert(begin);
1912 assert(need_offsets);
1913
1914 if (!signature_is_valid(contents, false))
1915 return -EINVAL;
1916
1917 if (c->signature && c->signature[c->index]) {
1918 size_t l;
1919
1920 l = strlen(contents);
1921
1922 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1923 !startswith(c->signature + c->index + 1, contents) ||
1924 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1925 return -ENXIO;
1926
1927 nindex = c->index + 1 + l + 1;
1928 } else {
1929 char *e;
1930
1931 if (c->enclosing != 0)
1932 return -ENXIO;
1933
1934 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1935 if (!e) {
1936 m->poisoned = true;
1937 return -ENOMEM;
1938 }
1939
1940 nindex = e - c->signature;
1941 }
1942
1943 if (BUS_MESSAGE_IS_GVARIANT(m)) {
1944 int alignment;
1945
1946 alignment = bus_gvariant_get_alignment(contents);
1947 if (alignment < 0)
1948 return alignment;
1949
1950 if (!message_extend_body(m, alignment, 0, false, false))
1951 return -ENOMEM;
1952
1953 r = bus_gvariant_is_fixed_size(contents);
1954 if (r < 0)
1955 return r;
1956
1957 *begin = m->body_size;
1958 *need_offsets = r == 0;
1959 } else {
1960 /* Align contents to 8 byte boundary */
1961 if (!message_extend_body(m, 8, 0, false, false))
1962 return -ENOMEM;
1963 }
1964
1965 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1966 c->index = nindex;
1967
1968 return 0;
1969 }
1970
1971 static int bus_message_open_dict_entry(
1972 sd_bus_message *m,
1973 struct bus_container *c,
1974 const char *contents,
1975 size_t *begin,
1976 bool *need_offsets) {
1977
1978 int r;
1979
1980 assert(m);
1981 assert(c);
1982 assert(contents);
1983 assert(begin);
1984 assert(need_offsets);
1985
1986 if (!signature_is_pair(contents))
1987 return -EINVAL;
1988
1989 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1990 return -ENXIO;
1991
1992 if (c->signature && c->signature[c->index]) {
1993 size_t l;
1994
1995 l = strlen(contents);
1996
1997 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1998 !startswith(c->signature + c->index + 1, contents) ||
1999 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2000 return -ENXIO;
2001 } else
2002 return -ENXIO;
2003
2004 if (BUS_MESSAGE_IS_GVARIANT(m)) {
2005 int alignment;
2006
2007 alignment = bus_gvariant_get_alignment(contents);
2008 if (alignment < 0)
2009 return alignment;
2010
2011 if (!message_extend_body(m, alignment, 0, false, false))
2012 return -ENOMEM;
2013
2014 r = bus_gvariant_is_fixed_size(contents);
2015 if (r < 0)
2016 return r;
2017
2018 *begin = m->body_size;
2019 *need_offsets = r == 0;
2020 } else {
2021 /* Align contents to 8 byte boundary */
2022 if (!message_extend_body(m, 8, 0, false, false))
2023 return -ENOMEM;
2024 }
2025
2026 return 0;
2027 }
2028
2029 _public_ int sd_bus_message_open_container(
2030 sd_bus_message *m,
2031 char type,
2032 const char *contents) {
2033
2034 struct bus_container *c, *w;
2035 uint32_t *array_size = NULL;
2036 char *signature;
2037 size_t before, begin = 0;
2038 bool need_offsets = false;
2039 int r;
2040
2041 assert_return(m, -EINVAL);
2042 assert_return(!m->sealed, -EPERM);
2043 assert_return(contents, -EINVAL);
2044 assert_return(!m->poisoned, -ESTALE);
2045
2046 /* Make sure we have space for one more container */
2047 if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1)) {
2048 m->poisoned = true;
2049 return -ENOMEM;
2050 }
2051
2052 c = message_get_container(m);
2053
2054 signature = strdup(contents);
2055 if (!signature) {
2056 m->poisoned = true;
2057 return -ENOMEM;
2058 }
2059
2060 /* Save old index in the parent container, in case we have to
2061 * abort this container */
2062 c->saved_index = c->index;
2063 before = m->body_size;
2064
2065 if (type == SD_BUS_TYPE_ARRAY)
2066 r = bus_message_open_array(m, c, contents, &array_size, &begin, &need_offsets);
2067 else if (type == SD_BUS_TYPE_VARIANT)
2068 r = bus_message_open_variant(m, c, contents);
2069 else if (type == SD_BUS_TYPE_STRUCT)
2070 r = bus_message_open_struct(m, c, contents, &begin, &need_offsets);
2071 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2072 r = bus_message_open_dict_entry(m, c, contents, &begin, &need_offsets);
2073 else
2074 r = -EINVAL;
2075
2076 if (r < 0) {
2077 free(signature);
2078 return r;
2079 }
2080
2081 /* OK, let's fill it in */
2082 w = m->containers + m->n_containers++;
2083 w->enclosing = type;
2084 w->signature = signature;
2085 w->index = 0;
2086 w->array_size = array_size;
2087 w->before = before;
2088 w->begin = begin;
2089 w->n_offsets = w->offsets_allocated = 0;
2090 w->offsets = NULL;
2091 w->need_offsets = need_offsets;
2092
2093 return 0;
2094 }
2095
2096 static int bus_message_close_array(sd_bus_message *m, struct bus_container *c) {
2097
2098 assert(m);
2099 assert(c);
2100
2101 if (!BUS_MESSAGE_IS_GVARIANT(m))
2102 return 0;
2103
2104 if (c->need_offsets) {
2105 size_t payload, sz, i;
2106 uint8_t *a;
2107
2108 /* Variable-width arrays */
2109
2110 payload = c->n_offsets > 0 ? c->offsets[c->n_offsets-1] - c->begin : 0;
2111 sz = bus_gvariant_determine_word_size(payload, c->n_offsets);
2112
2113 a = message_extend_body(m, 1, sz * c->n_offsets, true, false);
2114 if (!a)
2115 return -ENOMEM;
2116
2117 for (i = 0; i < c->n_offsets; i++)
2118 bus_gvariant_write_word_le(a + sz*i, sz, c->offsets[i] - c->begin);
2119 } else {
2120 void *a;
2121
2122 /* Fixed-width or empty arrays */
2123
2124 a = message_extend_body(m, 1, 0, true, false); /* let's add offset to parent */
2125 if (!a)
2126 return -ENOMEM;
2127 }
2128
2129 return 0;
2130 }
2131
2132 static int bus_message_close_variant(sd_bus_message *m, struct bus_container *c) {
2133 uint8_t *a;
2134 size_t l;
2135
2136 assert(m);
2137 assert(c);
2138 assert(c->signature);
2139
2140 if (!BUS_MESSAGE_IS_GVARIANT(m))
2141 return 0;
2142
2143 l = strlen(c->signature);
2144
2145 a = message_extend_body(m, 1, 1 + l, true, false);
2146 if (!a)
2147 return -ENOMEM;
2148
2149 a[0] = 0;
2150 memcpy(a+1, c->signature, l);
2151
2152 return 0;
2153 }
2154
2155 static int bus_message_close_struct(sd_bus_message *m, struct bus_container *c, bool add_offset) {
2156 bool fixed_size = true;
2157 size_t n_variable = 0;
2158 unsigned i = 0;
2159 const char *p;
2160 uint8_t *a;
2161 int r;
2162
2163 assert(m);
2164 assert(c);
2165
2166 if (!BUS_MESSAGE_IS_GVARIANT(m))
2167 return 0;
2168
2169 p = strempty(c->signature);
2170 while (*p != 0) {
2171 size_t n;
2172
2173 r = signature_element_length(p, &n);
2174 if (r < 0)
2175 return r;
2176 else {
2177 char t[n+1];
2178
2179 memcpy(t, p, n);
2180 t[n] = 0;
2181
2182 r = bus_gvariant_is_fixed_size(t);
2183 if (r < 0)
2184 return r;
2185 }
2186
2187 assert(!c->need_offsets || i <= c->n_offsets);
2188
2189 /* We need to add an offset for each item that has a
2190 * variable size and that is not the last one in the
2191 * list */
2192 if (r == 0)
2193 fixed_size = false;
2194 if (r == 0 && p[n] != 0)
2195 n_variable++;
2196
2197 i++;
2198 p += n;
2199 }
2200
2201 assert(!c->need_offsets || i == c->n_offsets);
2202 assert(c->need_offsets || n_variable == 0);
2203
2204 if (isempty(c->signature)) {
2205 /* The unary type is encoded as fixed 1 byte padding */
2206 a = message_extend_body(m, 1, 1, add_offset, false);
2207 if (!a)
2208 return -ENOMEM;
2209
2210 *a = 0;
2211 } else if (n_variable <= 0) {
2212 int alignment = 1;
2213
2214 /* Structures with fixed-size members only have to be
2215 * fixed-size themselves. But gvariant requires all fixed-size
2216 * elements to be sized a multiple of their alignment. Hence,
2217 * we must *always* add final padding after the last member so
2218 * the overall size of the structure is properly aligned. */
2219 if (fixed_size)
2220 alignment = bus_gvariant_get_alignment(strempty(c->signature));
2221
2222 assert(alignment > 0);
2223
2224 a = message_extend_body(m, alignment, 0, add_offset, false);
2225 if (!a)
2226 return -ENOMEM;
2227 } else {
2228 size_t sz;
2229 unsigned j;
2230
2231 assert(c->offsets[c->n_offsets-1] == m->body_size);
2232
2233 sz = bus_gvariant_determine_word_size(m->body_size - c->begin, n_variable);
2234
2235 a = message_extend_body(m, 1, sz * n_variable, add_offset, false);
2236 if (!a)
2237 return -ENOMEM;
2238
2239 p = strempty(c->signature);
2240 for (i = 0, j = 0; i < c->n_offsets; i++) {
2241 unsigned k;
2242 size_t n;
2243
2244 r = signature_element_length(p, &n);
2245 if (r < 0)
2246 return r;
2247 else {
2248 char t[n+1];
2249
2250 memcpy(t, p, n);
2251 t[n] = 0;
2252
2253 p += n;
2254
2255 r = bus_gvariant_is_fixed_size(t);
2256 if (r < 0)
2257 return r;
2258 if (r > 0 || p[0] == 0)
2259 continue;
2260 }
2261
2262 k = n_variable - 1 - j;
2263
2264 bus_gvariant_write_word_le(a + k * sz, sz, c->offsets[i] - c->begin);
2265
2266 j++;
2267 }
2268 }
2269
2270 return 0;
2271 }
2272
2273 _public_ int sd_bus_message_close_container(sd_bus_message *m) {
2274 struct bus_container *c;
2275 int r;
2276
2277 assert_return(m, -EINVAL);
2278 assert_return(!m->sealed, -EPERM);
2279 assert_return(m->n_containers > 0, -EINVAL);
2280 assert_return(!m->poisoned, -ESTALE);
2281
2282 c = message_get_container(m);
2283
2284 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2285 if (c->signature && c->signature[c->index] != 0)
2286 return -EINVAL;
2287
2288 m->n_containers--;
2289
2290 if (c->enclosing == SD_BUS_TYPE_ARRAY)
2291 r = bus_message_close_array(m, c);
2292 else if (c->enclosing == SD_BUS_TYPE_VARIANT)
2293 r = bus_message_close_variant(m, c);
2294 else if (c->enclosing == SD_BUS_TYPE_STRUCT || c->enclosing == SD_BUS_TYPE_DICT_ENTRY)
2295 r = bus_message_close_struct(m, c, true);
2296 else
2297 assert_not_reached("Unknown container type");
2298
2299 free(c->signature);
2300 free(c->offsets);
2301
2302 return r;
2303 }
2304
2305 typedef struct {
2306 const char *types;
2307 unsigned n_struct;
2308 unsigned n_array;
2309 } TypeStack;
2310
2311 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
2312 assert(stack);
2313 assert(max > 0);
2314
2315 if (*i >= max)
2316 return -EINVAL;
2317
2318 stack[*i].types = types;
2319 stack[*i].n_struct = n_struct;
2320 stack[*i].n_array = n_array;
2321 (*i)++;
2322
2323 return 0;
2324 }
2325
2326 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
2327 assert(stack);
2328 assert(max > 0);
2329 assert(types);
2330 assert(n_struct);
2331 assert(n_array);
2332
2333 if (*i <= 0)
2334 return 0;
2335
2336 (*i)--;
2337 *types = stack[*i].types;
2338 *n_struct = stack[*i].n_struct;
2339 *n_array = stack[*i].n_array;
2340
2341 return 1;
2342 }
2343
2344 _public_ int sd_bus_message_appendv(
2345 sd_bus_message *m,
2346 const char *types,
2347 va_list ap) {
2348
2349 unsigned n_array, n_struct;
2350 TypeStack stack[BUS_CONTAINER_DEPTH];
2351 unsigned stack_ptr = 0;
2352 int r;
2353
2354 assert_return(m, -EINVAL);
2355 assert_return(types, -EINVAL);
2356 assert_return(!m->sealed, -EPERM);
2357 assert_return(!m->poisoned, -ESTALE);
2358
2359 n_array = (unsigned) -1;
2360 n_struct = strlen(types);
2361
2362 for (;;) {
2363 const char *t;
2364
2365 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2366 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2367 if (r < 0)
2368 return r;
2369 if (r == 0)
2370 break;
2371
2372 r = sd_bus_message_close_container(m);
2373 if (r < 0)
2374 return r;
2375
2376 continue;
2377 }
2378
2379 t = types;
2380 if (n_array != (unsigned) -1)
2381 n_array--;
2382 else {
2383 types++;
2384 n_struct--;
2385 }
2386
2387 switch (*t) {
2388
2389 case SD_BUS_TYPE_BYTE: {
2390 uint8_t x;
2391
2392 x = (uint8_t) va_arg(ap, int);
2393 r = sd_bus_message_append_basic(m, *t, &x);
2394 break;
2395 }
2396
2397 case SD_BUS_TYPE_BOOLEAN:
2398 case SD_BUS_TYPE_INT32:
2399 case SD_BUS_TYPE_UINT32:
2400 case SD_BUS_TYPE_UNIX_FD: {
2401 uint32_t x;
2402
2403 /* We assume a boolean is the same as int32_t */
2404 assert_cc(sizeof(int32_t) == sizeof(int));
2405
2406 x = va_arg(ap, uint32_t);
2407 r = sd_bus_message_append_basic(m, *t, &x);
2408 break;
2409 }
2410
2411 case SD_BUS_TYPE_INT16:
2412 case SD_BUS_TYPE_UINT16: {
2413 uint16_t x;
2414
2415 x = (uint16_t) va_arg(ap, int);
2416 r = sd_bus_message_append_basic(m, *t, &x);
2417 break;
2418 }
2419
2420 case SD_BUS_TYPE_INT64:
2421 case SD_BUS_TYPE_UINT64: {
2422 uint64_t x;
2423
2424 x = va_arg(ap, uint64_t);
2425 r = sd_bus_message_append_basic(m, *t, &x);
2426 break;
2427 }
2428
2429 case SD_BUS_TYPE_DOUBLE: {
2430 double x;
2431
2432 x = va_arg(ap, double);
2433 r = sd_bus_message_append_basic(m, *t, &x);
2434 break;
2435 }
2436
2437 case SD_BUS_TYPE_STRING:
2438 case SD_BUS_TYPE_OBJECT_PATH:
2439 case SD_BUS_TYPE_SIGNATURE: {
2440 const char *x;
2441
2442 x = va_arg(ap, const char*);
2443 r = sd_bus_message_append_basic(m, *t, x);
2444 break;
2445 }
2446
2447 case SD_BUS_TYPE_ARRAY: {
2448 size_t k;
2449
2450 r = signature_element_length(t + 1, &k);
2451 if (r < 0)
2452 return r;
2453
2454 {
2455 char s[k + 1];
2456 memcpy(s, t + 1, k);
2457 s[k] = 0;
2458
2459 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
2460 if (r < 0)
2461 return r;
2462 }
2463
2464 if (n_array == (unsigned) -1) {
2465 types += k;
2466 n_struct -= k;
2467 }
2468
2469 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2470 if (r < 0)
2471 return r;
2472
2473 types = t + 1;
2474 n_struct = k;
2475 n_array = va_arg(ap, unsigned);
2476
2477 break;
2478 }
2479
2480 case SD_BUS_TYPE_VARIANT: {
2481 const char *s;
2482
2483 s = va_arg(ap, const char*);
2484 if (!s)
2485 return -EINVAL;
2486
2487 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2488 if (r < 0)
2489 return r;
2490
2491 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2492 if (r < 0)
2493 return r;
2494
2495 types = s;
2496 n_struct = strlen(s);
2497 n_array = (unsigned) -1;
2498
2499 break;
2500 }
2501
2502 case SD_BUS_TYPE_STRUCT_BEGIN:
2503 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2504 size_t k;
2505
2506 r = signature_element_length(t, &k);
2507 if (r < 0)
2508 return r;
2509
2510 {
2511 char s[k - 1];
2512
2513 memcpy(s, t + 1, k - 2);
2514 s[k - 2] = 0;
2515
2516 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2517 if (r < 0)
2518 return r;
2519 }
2520
2521 if (n_array == (unsigned) -1) {
2522 types += k - 1;
2523 n_struct -= k - 1;
2524 }
2525
2526 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2527 if (r < 0)
2528 return r;
2529
2530 types = t + 1;
2531 n_struct = k - 2;
2532 n_array = (unsigned) -1;
2533
2534 break;
2535 }
2536
2537 default:
2538 r = -EINVAL;
2539 }
2540
2541 if (r < 0)
2542 return r;
2543 }
2544
2545 return 1;
2546 }
2547
2548 _public_ int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2549 va_list ap;
2550 int r;
2551
2552 assert_return(m, -EINVAL);
2553 assert_return(types, -EINVAL);
2554 assert_return(!m->sealed, -EPERM);
2555 assert_return(!m->poisoned, -ESTALE);
2556
2557 va_start(ap, types);
2558 r = sd_bus_message_appendv(m, types, ap);
2559 va_end(ap);
2560
2561 return r;
2562 }
2563
2564 _public_ int sd_bus_message_append_array_space(
2565 sd_bus_message *m,
2566 char type,
2567 size_t size,
2568 void **ptr) {
2569
2570 ssize_t align, sz;
2571 void *a;
2572 int r;
2573
2574 assert_return(m, -EINVAL);
2575 assert_return(!m->sealed, -EPERM);
2576 assert_return(bus_type_is_trivial(type) && type != SD_BUS_TYPE_BOOLEAN, -EINVAL);
2577 assert_return(ptr || size == 0, -EINVAL);
2578 assert_return(!m->poisoned, -ESTALE);
2579
2580 /* alignment and size of the trivial types (except bool) is
2581 * identical for gvariant and dbus1 marshalling */
2582 align = bus_type_get_alignment(type);
2583 sz = bus_type_get_size(type);
2584
2585 assert_se(align > 0);
2586 assert_se(sz > 0);
2587
2588 if (size % sz != 0)
2589 return -EINVAL;
2590
2591 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2592 if (r < 0)
2593 return r;
2594
2595 a = message_extend_body(m, align, size, false, false);
2596 if (!a)
2597 return -ENOMEM;
2598
2599 r = sd_bus_message_close_container(m);
2600 if (r < 0)
2601 return r;
2602
2603 *ptr = a;
2604 return 0;
2605 }
2606
2607 _public_ int sd_bus_message_append_array(
2608 sd_bus_message *m,
2609 char type,
2610 const void *ptr,
2611 size_t size) {
2612 int r;
2613 void *p;
2614
2615 assert_return(m, -EINVAL);
2616 assert_return(!m->sealed, -EPERM);
2617 assert_return(bus_type_is_trivial(type), -EINVAL);
2618 assert_return(ptr || size == 0, -EINVAL);
2619 assert_return(!m->poisoned, -ESTALE);
2620
2621 r = sd_bus_message_append_array_space(m, type, size, &p);
2622 if (r < 0)
2623 return r;
2624
2625 memcpy_safe(p, ptr, size);
2626
2627 return 0;
2628 }
2629
2630 _public_ int sd_bus_message_append_array_iovec(
2631 sd_bus_message *m,
2632 char type,
2633 const struct iovec *iov,
2634 unsigned n) {
2635
2636 size_t size;
2637 unsigned i;
2638 void *p;
2639 int r;
2640
2641 assert_return(m, -EINVAL);
2642 assert_return(!m->sealed, -EPERM);
2643 assert_return(bus_type_is_trivial(type), -EINVAL);
2644 assert_return(iov || n == 0, -EINVAL);
2645 assert_return(!m->poisoned, -ESTALE);
2646
2647 size = IOVEC_TOTAL_SIZE(iov, n);
2648
2649 r = sd_bus_message_append_array_space(m, type, size, &p);
2650 if (r < 0)
2651 return r;
2652
2653 for (i = 0; i < n; i++) {
2654
2655 if (iov[i].iov_base)
2656 memcpy(p, iov[i].iov_base, iov[i].iov_len);
2657 else
2658 memzero(p, iov[i].iov_len);
2659
2660 p = (uint8_t*) p + iov[i].iov_len;
2661 }
2662
2663 return 0;
2664 }
2665
2666 _public_ int sd_bus_message_append_array_memfd(
2667 sd_bus_message *m,
2668 char type,
2669 int memfd,
2670 uint64_t offset,
2671 uint64_t size) {
2672
2673 _cleanup_close_ int copy_fd = -1;
2674 struct bus_body_part *part;
2675 ssize_t align, sz;
2676 uint64_t real_size;
2677 void *a;
2678 int r;
2679
2680 assert_return(m, -EINVAL);
2681 assert_return(memfd >= 0, -EBADF);
2682 assert_return(bus_type_is_trivial(type), -EINVAL);
2683 assert_return(size > 0, -EINVAL);
2684 assert_return(!m->sealed, -EPERM);
2685 assert_return(!m->poisoned, -ESTALE);
2686
2687 r = memfd_set_sealed(memfd);
2688 if (r < 0)
2689 return r;
2690
2691 copy_fd = dup(memfd);
2692 if (copy_fd < 0)
2693 return copy_fd;
2694
2695 r = memfd_get_size(memfd, &real_size);
2696 if (r < 0)
2697 return r;
2698
2699 if (offset == 0 && size == (uint64_t) -1)
2700 size = real_size;
2701 else if (offset + size > real_size)
2702 return -EMSGSIZE;
2703
2704 align = bus_type_get_alignment(type);
2705 sz = bus_type_get_size(type);
2706
2707 assert_se(align > 0);
2708 assert_se(sz > 0);
2709
2710 if (offset % align != 0)
2711 return -EINVAL;
2712
2713 if (size % sz != 0)
2714 return -EINVAL;
2715
2716 if (size > (uint64_t) (uint32_t) -1)
2717 return -EINVAL;
2718
2719 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2720 if (r < 0)
2721 return r;
2722
2723 a = message_extend_body(m, align, 0, false, false);
2724 if (!a)
2725 return -ENOMEM;
2726
2727 part = message_append_part(m);
2728 if (!part)
2729 return -ENOMEM;
2730
2731 part->memfd = copy_fd;
2732 part->memfd_offset = offset;
2733 part->sealed = true;
2734 part->size = size;
2735 copy_fd = -1;
2736
2737 m->body_size += size;
2738 message_extend_containers(m, size);
2739
2740 return sd_bus_message_close_container(m);
2741 }
2742
2743 _public_ int sd_bus_message_append_string_memfd(
2744 sd_bus_message *m,
2745 int memfd,
2746 uint64_t offset,
2747 uint64_t size) {
2748
2749 _cleanup_close_ int copy_fd = -1;
2750 struct bus_body_part *part;
2751 struct bus_container *c;
2752 uint64_t real_size;
2753 void *a;
2754 int r;
2755
2756 assert_return(m, -EINVAL);
2757 assert_return(memfd >= 0, -EBADF);
2758 assert_return(size > 0, -EINVAL);
2759 assert_return(!m->sealed, -EPERM);
2760 assert_return(!m->poisoned, -ESTALE);
2761
2762 r = memfd_set_sealed(memfd);
2763 if (r < 0)
2764 return r;
2765
2766 copy_fd = dup(memfd);
2767 if (copy_fd < 0)
2768 return copy_fd;
2769
2770 r = memfd_get_size(memfd, &real_size);
2771 if (r < 0)
2772 return r;
2773
2774 if (offset == 0 && size == (uint64_t) -1)
2775 size = real_size;
2776 else if (offset + size > real_size)
2777 return -EMSGSIZE;
2778
2779 /* We require this to be NUL terminated */
2780 if (size == 0)
2781 return -EINVAL;
2782
2783 if (size > (uint64_t) (uint32_t) -1)
2784 return -EINVAL;
2785
2786 c = message_get_container(m);
2787 if (c->signature && c->signature[c->index]) {
2788 /* Container signature is already set */
2789
2790 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2791 return -ENXIO;
2792 } else {
2793 char *e;
2794
2795 /* Maybe we can append to the signature? But only if this is the top-level container */
2796 if (c->enclosing != 0)
2797 return -ENXIO;
2798
2799 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2800 if (!e) {
2801 m->poisoned = true;
2802 return -ENOMEM;
2803 }
2804 }
2805
2806 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
2807 a = message_extend_body(m, 4, 4, false, false);
2808 if (!a)
2809 return -ENOMEM;
2810
2811 *(uint32_t*) a = size - 1;
2812 }
2813
2814 part = message_append_part(m);
2815 if (!part)
2816 return -ENOMEM;
2817
2818 part->memfd = copy_fd;
2819 part->memfd_offset = offset;
2820 part->sealed = true;
2821 part->size = size;
2822 copy_fd = -1;
2823
2824 m->body_size += size;
2825 message_extend_containers(m, size);
2826
2827 if (BUS_MESSAGE_IS_GVARIANT(m)) {
2828 r = message_add_offset(m, m->body_size);
2829 if (r < 0) {
2830 m->poisoned = true;
2831 return -ENOMEM;
2832 }
2833 }
2834
2835 if (c->enclosing != SD_BUS_TYPE_ARRAY)
2836 c->index++;
2837
2838 return 0;
2839 }
2840
2841 _public_ int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2842 char **i;
2843 int r;
2844
2845 assert_return(m, -EINVAL);
2846 assert_return(!m->sealed, -EPERM);
2847 assert_return(!m->poisoned, -ESTALE);
2848
2849 r = sd_bus_message_open_container(m, 'a', "s");
2850 if (r < 0)
2851 return r;
2852
2853 STRV_FOREACH(i, l) {
2854 r = sd_bus_message_append_basic(m, 's', *i);
2855 if (r < 0)
2856 return r;
2857 }
2858
2859 return sd_bus_message_close_container(m);
2860 }
2861
2862 static int bus_message_close_header(sd_bus_message *m) {
2863
2864 assert(m);
2865
2866 /* The actual user data is finished now, we just complete the
2867 variant and struct now (at least on gvariant). Remember
2868 this position, so that during parsing we know where to
2869 put the outer container end. */
2870 m->user_body_size = m->body_size;
2871
2872 if (BUS_MESSAGE_IS_GVARIANT(m)) {
2873 const char *signature;
2874 size_t sz, l;
2875 void *d;
2876
2877 /* Add offset table to end of fields array */
2878 if (m->n_header_offsets >= 1) {
2879 uint8_t *a;
2880 unsigned i;
2881
2882 assert(m->fields_size == m->header_offsets[m->n_header_offsets-1]);
2883
2884 sz = bus_gvariant_determine_word_size(m->fields_size, m->n_header_offsets);
2885 a = message_extend_fields(m, 1, sz * m->n_header_offsets, false);
2886 if (!a)
2887 return -ENOMEM;
2888
2889 for (i = 0; i < m->n_header_offsets; i++)
2890 bus_gvariant_write_word_le(a + sz*i, sz, m->header_offsets[i]);
2891 }
2892
2893 /* Add gvariant NUL byte plus signature to the end of
2894 * the body, followed by the final offset pointing to
2895 * the end of the fields array */
2896
2897 signature = strempty(m->root_container.signature);
2898 l = strlen(signature);
2899
2900 sz = bus_gvariant_determine_word_size(sizeof(struct bus_header) + ALIGN8(m->fields_size) + m->body_size + 1 + l + 2, 1);
2901 d = message_extend_body(m, 1, 1 + l + 2 + sz, false, true);
2902 if (!d)
2903 return -ENOMEM;
2904
2905 *(uint8_t*) d = 0;
2906 *((uint8_t*) d + 1) = SD_BUS_TYPE_STRUCT_BEGIN;
2907 memcpy((uint8_t*) d + 2, signature, l);
2908 *((uint8_t*) d + 1 + l + 1) = SD_BUS_TYPE_STRUCT_END;
2909
2910 bus_gvariant_write_word_le((uint8_t*) d + 1 + l + 2, sz, sizeof(struct bus_header) + m->fields_size);
2911
2912 m->footer = d;
2913 m->footer_accessible = 1 + l + 2 + sz;
2914 } else {
2915 m->header->dbus1.fields_size = m->fields_size;
2916 m->header->dbus1.body_size = m->body_size;
2917 }
2918
2919 return 0;
2920 }
2921
2922 int bus_message_seal(sd_bus_message *m, uint64_t cookie, usec_t timeout) {
2923 struct bus_body_part *part;
2924 size_t a;
2925 unsigned i;
2926 int r;
2927
2928 assert(m);
2929
2930 if (m->sealed)
2931 return -EPERM;
2932
2933 if (m->n_containers > 0)
2934 return -EBADMSG;
2935
2936 if (m->poisoned)
2937 return -ESTALE;
2938
2939 if (cookie > 0xffffffffULL &&
2940 !BUS_MESSAGE_IS_GVARIANT(m))
2941 return -EOPNOTSUPP;
2942
2943 /* In vtables the return signature of method calls is listed,
2944 * let's check if they match if this is a response */
2945 if (m->header->type == SD_BUS_MESSAGE_METHOD_RETURN &&
2946 m->enforced_reply_signature &&
2947 !streq(strempty(m->root_container.signature), m->enforced_reply_signature))
2948 return -ENOMSG;
2949
2950 /* If gvariant marshalling is used we need to close the body structure */
2951 r = bus_message_close_struct(m, &m->root_container, false);
2952 if (r < 0)
2953 return r;
2954
2955 /* If there's a non-trivial signature set, then add it in
2956 * here, but only on dbus1 */
2957 if (!isempty(m->root_container.signature) && !BUS_MESSAGE_IS_GVARIANT(m)) {
2958 r = message_append_field_signature(m, BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2959 if (r < 0)
2960 return r;
2961 }
2962
2963 if (m->n_fds > 0) {
2964 r = message_append_field_uint32(m, BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2965 if (r < 0)
2966 return r;
2967 }
2968
2969 r = bus_message_close_header(m);
2970 if (r < 0)
2971 return r;
2972
2973 if (BUS_MESSAGE_IS_GVARIANT(m))
2974 m->header->dbus2.cookie = cookie;
2975 else
2976 m->header->dbus1.serial = (uint32_t) cookie;
2977
2978 m->timeout = m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED ? 0 : timeout;
2979
2980 /* Add padding at the end of the fields part, since we know
2981 * the body needs to start at an 8 byte alignment. We made
2982 * sure we allocated enough space for this, so all we need to
2983 * do here is to zero it out. */
2984 a = ALIGN8(m->fields_size) - m->fields_size;
2985 if (a > 0)
2986 memzero((uint8_t*) BUS_MESSAGE_FIELDS(m) + m->fields_size, a);
2987
2988 /* If this is something we can send as memfd, then let's seal
2989 the memfd now. Note that we can send memfds as payload only
2990 for directed messages, and not for broadcasts. */
2991 if (m->destination && m->bus->use_memfd) {
2992 MESSAGE_FOREACH_PART(part, i, m)
2993 if (part->memfd >= 0 &&
2994 !part->sealed &&
2995 (part->size > MEMFD_MIN_SIZE || m->bus->use_memfd < 0) &&
2996 part != m->body_end) { /* The last part may never be sent as memfd */
2997 uint64_t sz;
2998
2999 /* Try to seal it if that makes
3000 * sense. First, unmap our own map to
3001 * make sure we don't keep it busy. */
3002 bus_body_part_unmap(part);
3003
3004 /* Then, sync up real memfd size */
3005 sz = part->size;
3006 r = memfd_set_size(part->memfd, sz);
3007 if (r < 0)
3008 return r;
3009
3010 /* Finally, try to seal */
3011 if (memfd_set_sealed(part->memfd) >= 0)
3012 part->sealed = true;
3013 }
3014 }
3015
3016 m->root_container.end = m->user_body_size;
3017 m->root_container.index = 0;
3018 m->root_container.offset_index = 0;
3019 m->root_container.item_size = m->root_container.n_offsets > 0 ? m->root_container.offsets[0] : 0;
3020
3021 m->sealed = true;
3022
3023 return 0;
3024 }
3025
3026 int bus_body_part_map(struct bus_body_part *part) {
3027 void *p;
3028 size_t psz, shift;
3029
3030 assert_se(part);
3031
3032 if (part->data)
3033 return 0;
3034
3035 if (part->size <= 0)
3036 return 0;
3037
3038 /* For smaller zero parts (as used for padding) we don't need to map anything... */
3039 if (part->memfd < 0 && part->is_zero && part->size < 8) {
3040 static const uint8_t zeroes[7] = { };
3041 part->data = (void*) zeroes;
3042 return 0;
3043 }
3044
3045 shift = part->memfd_offset - ((part->memfd_offset / page_size()) * page_size());
3046 psz = PAGE_ALIGN(part->size + shift);
3047
3048 if (part->memfd >= 0)
3049 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE, part->memfd, part->memfd_offset - shift);
3050 else if (part->is_zero)
3051 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
3052 else
3053 return -EINVAL;
3054
3055 if (p == MAP_FAILED)
3056 return -errno;
3057
3058 part->mapped = psz;
3059 part->mmap_begin = p;
3060 part->data = (uint8_t*) p + shift;
3061 part->munmap_this = true;
3062
3063 return 0;
3064 }
3065
3066 void bus_body_part_unmap(struct bus_body_part *part) {
3067
3068 assert_se(part);
3069
3070 if (part->memfd < 0)
3071 return;
3072
3073 if (!part->mmap_begin)
3074 return;
3075
3076 if (!part->munmap_this)
3077 return;
3078
3079 assert_se(munmap(part->mmap_begin, part->mapped) == 0);
3080
3081 part->mmap_begin = NULL;
3082 part->data = NULL;
3083 part->mapped = 0;
3084 part->munmap_this = false;
3085
3086 return;
3087 }
3088
3089 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
3090 size_t k, start, end;
3091
3092 assert(rindex);
3093 assert(align > 0);
3094
3095 start = ALIGN_TO((size_t) *rindex, align);
3096 end = start + nbytes;
3097
3098 if (end > sz)
3099 return -EBADMSG;
3100
3101 /* Verify that padding is 0 */
3102 for (k = *rindex; k < start; k++)
3103 if (((const uint8_t*) p)[k] != 0)
3104 return -EBADMSG;
3105
3106 if (r)
3107 *r = (uint8_t*) p + start;
3108
3109 *rindex = end;
3110
3111 return 1;
3112 }
3113
3114 static bool message_end_of_signature(sd_bus_message *m) {
3115 struct bus_container *c;
3116
3117 assert(m);
3118
3119 c = message_get_container(m);
3120 return !c->signature || c->signature[c->index] == 0;
3121 }
3122
3123 static bool message_end_of_array(sd_bus_message *m, size_t index) {
3124 struct bus_container *c;
3125
3126 assert(m);
3127
3128 c = message_get_container(m);
3129 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3130 return false;
3131
3132 if (BUS_MESSAGE_IS_GVARIANT(m))
3133 return index >= c->end;
3134 else {
3135 assert(c->array_size);
3136 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
3137 }
3138 }
3139
3140 _public_ int sd_bus_message_at_end(sd_bus_message *m, int complete) {
3141 assert_return(m, -EINVAL);
3142 assert_return(m->sealed, -EPERM);
3143
3144 if (complete && m->n_containers > 0)
3145 return false;
3146
3147 if (message_end_of_signature(m))
3148 return true;
3149
3150 if (message_end_of_array(m, m->rindex))
3151 return true;
3152
3153 return false;
3154 }
3155
3156 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
3157 struct bus_body_part *part;
3158 size_t begin;
3159 int r;
3160
3161 assert(m);
3162
3163 if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
3164 part = m->cached_rindex_part;
3165 begin = m->cached_rindex_part_begin;
3166 } else {
3167 part = &m->body;
3168 begin = 0;
3169 }
3170
3171 while (part) {
3172 if (index < begin)
3173 return NULL;
3174
3175 if (index + sz <= begin + part->size) {
3176
3177 r = bus_body_part_map(part);
3178 if (r < 0)
3179 return NULL;
3180
3181 if (p)
3182 *p = (uint8_t*) part->data + index - begin;
3183
3184 m->cached_rindex_part = part;
3185 m->cached_rindex_part_begin = begin;
3186
3187 return part;
3188 }
3189
3190 begin += part->size;
3191 part = part->next;
3192 }
3193
3194 return NULL;
3195 }
3196
3197 static int container_next_item(sd_bus_message *m, struct bus_container *c, size_t *rindex) {
3198 int r;
3199
3200 assert(m);
3201 assert(c);
3202 assert(rindex);
3203
3204 if (!BUS_MESSAGE_IS_GVARIANT(m))
3205 return 0;
3206
3207 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
3208 int sz;
3209
3210 sz = bus_gvariant_get_size(c->signature);
3211 if (sz < 0) {
3212 int alignment;
3213
3214 if (c->offset_index+1 >= c->n_offsets)
3215 goto end;
3216
3217 /* Variable-size array */
3218
3219 alignment = bus_gvariant_get_alignment(c->signature);
3220 assert(alignment > 0);
3221
3222 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3223 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3224 } else {
3225
3226 if (c->offset_index+1 >= (c->end-c->begin)/sz)
3227 goto end;
3228
3229 /* Fixed-size array */
3230 *rindex = c->begin + (c->offset_index+1) * sz;
3231 c->item_size = sz;
3232 }
3233
3234 c->offset_index++;
3235
3236 } else if (c->enclosing == 0 ||
3237 c->enclosing == SD_BUS_TYPE_STRUCT ||
3238 c->enclosing == SD_BUS_TYPE_DICT_ENTRY) {
3239
3240 int alignment;
3241 size_t n, j;
3242
3243 if (c->offset_index+1 >= c->n_offsets)
3244 goto end;
3245
3246 r = signature_element_length(c->signature + c->index, &n);
3247 if (r < 0)
3248 return r;
3249
3250 r = signature_element_length(c->signature + c->index + n, &j);
3251 if (r < 0)
3252 return r;
3253 else {
3254 char t[j+1];
3255 memcpy(t, c->signature + c->index + n, j);
3256 t[j] = 0;
3257
3258 alignment = bus_gvariant_get_alignment(t);
3259 }
3260
3261 assert(alignment > 0);
3262
3263 *rindex = ALIGN_TO(c->offsets[c->offset_index], alignment);
3264 c->item_size = c->offsets[c->offset_index+1] - *rindex;
3265
3266 c->offset_index++;
3267
3268 } else if (c->enclosing == SD_BUS_TYPE_VARIANT)
3269 goto end;
3270 else
3271 assert_not_reached("Unknown container type");
3272
3273 return 0;
3274
3275 end:
3276 /* Reached the end */
3277 *rindex = c->end;
3278 c->item_size = 0;
3279 return 0;
3280 }
3281
3282
3283 static int message_peek_body(
3284 sd_bus_message *m,
3285 size_t *rindex,
3286 size_t align,
3287 size_t nbytes,
3288 void **ret) {
3289
3290 size_t k, start, end, padding;
3291 struct bus_body_part *part;
3292 uint8_t *q;
3293
3294 assert(m);
3295 assert(rindex);
3296 assert(align > 0);
3297
3298 start = ALIGN_TO((size_t) *rindex, align);
3299 padding = start - *rindex;
3300 end = start + nbytes;
3301
3302 if (end > m->user_body_size)
3303 return -EBADMSG;
3304
3305 part = find_part(m, *rindex, padding, (void**) &q);
3306 if (!part)
3307 return -EBADMSG;
3308
3309 if (q) {
3310 /* Verify padding */
3311 for (k = 0; k < padding; k++)
3312 if (q[k] != 0)
3313 return -EBADMSG;
3314 }
3315
3316 part = find_part(m, start, nbytes, (void**) &q);
3317 if (!part || (nbytes > 0 && !q))
3318 return -EBADMSG;
3319
3320 *rindex = end;
3321
3322 if (ret)
3323 *ret = q;
3324
3325 return 0;
3326 }
3327
3328 static bool validate_nul(const char *s, size_t l) {
3329
3330 /* Check for NUL chars in the string */
3331 if (memchr(s, 0, l))
3332 return false;
3333
3334 /* Check for NUL termination */
3335 if (s[l] != 0)
3336 return false;
3337
3338 return true;
3339 }
3340
3341 static bool validate_string(const char *s, size_t l) {
3342
3343 if (!validate_nul(s, l))
3344 return false;
3345
3346 /* Check if valid UTF8 */
3347 if (!utf8_is_valid(s))
3348 return false;
3349
3350 return true;
3351 }
3352
3353 static bool validate_signature(const char *s, size_t l) {
3354
3355 if (!validate_nul(s, l))
3356 return false;
3357
3358 /* Check if valid signature */
3359 if (!signature_is_valid(s, true))
3360 return false;
3361
3362 return true;
3363 }
3364
3365 static bool validate_object_path(const char *s, size_t l) {
3366
3367 if (!validate_nul(s, l))
3368 return false;
3369
3370 if (!object_path_is_valid(s))
3371 return false;
3372
3373 return true;
3374 }
3375
3376 _public_ int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
3377 struct bus_container *c;
3378 size_t rindex;
3379 void *q;
3380 int r;
3381
3382 assert_return(m, -EINVAL);
3383 assert_return(m->sealed, -EPERM);
3384 assert_return(bus_type_is_basic(type), -EINVAL);
3385
3386 if (message_end_of_signature(m))
3387 return -ENXIO;
3388
3389 if (message_end_of_array(m, m->rindex))
3390 return 0;
3391
3392 c = message_get_container(m);
3393 if (c->signature[c->index] != type)
3394 return -ENXIO;
3395
3396 rindex = m->rindex;
3397
3398 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3399
3400 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE)) {
3401 bool ok;
3402
3403 r = message_peek_body(m, &rindex, 1, c->item_size, &q);
3404 if (r < 0)
3405 return r;
3406
3407 if (type == SD_BUS_TYPE_STRING)
3408 ok = validate_string(q, c->item_size-1);
3409 else if (type == SD_BUS_TYPE_OBJECT_PATH)
3410 ok = validate_object_path(q, c->item_size-1);
3411 else
3412 ok = validate_signature(q, c->item_size-1);
3413
3414 if (!ok)
3415 return -EBADMSG;
3416
3417 if (p)
3418 *(const char**) p = q;
3419 } else {
3420 int sz, align;
3421
3422 sz = bus_gvariant_get_size(CHAR_TO_STR(type));
3423 assert(sz > 0);
3424 if ((size_t) sz != c->item_size)
3425 return -EBADMSG;
3426
3427 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
3428 assert(align > 0);
3429
3430 r = message_peek_body(m, &rindex, align, c->item_size, &q);
3431 if (r < 0)
3432 return r;
3433
3434 switch (type) {
3435
3436 case SD_BUS_TYPE_BYTE:
3437 if (p)
3438 *(uint8_t*) p = *(uint8_t*) q;
3439 break;
3440
3441 case SD_BUS_TYPE_BOOLEAN:
3442 if (p)
3443 *(int*) p = !!*(uint8_t*) q;
3444 break;
3445
3446 case SD_BUS_TYPE_INT16:
3447 case SD_BUS_TYPE_UINT16:
3448 if (p)
3449 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3450 break;
3451
3452 case SD_BUS_TYPE_INT32:
3453 case SD_BUS_TYPE_UINT32:
3454 if (p)
3455 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3456 break;
3457
3458 case SD_BUS_TYPE_INT64:
3459 case SD_BUS_TYPE_UINT64:
3460 case SD_BUS_TYPE_DOUBLE:
3461 if (p)
3462 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3463 break;
3464
3465 case SD_BUS_TYPE_UNIX_FD: {
3466 uint32_t j;
3467
3468 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3469 if (j >= m->n_fds)
3470 return -EBADMSG;
3471
3472 if (p)
3473 *(int*) p = m->fds[j];
3474
3475 break;
3476 }
3477
3478 default:
3479 assert_not_reached("unexpected type");
3480 }
3481 }
3482
3483 r = container_next_item(m, c, &rindex);
3484 if (r < 0)
3485 return r;
3486 } else {
3487
3488 if (IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH)) {
3489 uint32_t l;
3490 bool ok;
3491
3492 r = message_peek_body(m, &rindex, 4, 4, &q);
3493 if (r < 0)
3494 return r;
3495
3496 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3497 r = message_peek_body(m, &rindex, 1, l+1, &q);
3498 if (r < 0)
3499 return r;
3500
3501 if (type == SD_BUS_TYPE_OBJECT_PATH)
3502 ok = validate_object_path(q, l);
3503 else
3504 ok = validate_string(q, l);
3505 if (!ok)
3506 return -EBADMSG;
3507
3508 if (p)
3509 *(const char**) p = q;
3510
3511 } else if (type == SD_BUS_TYPE_SIGNATURE) {
3512 uint8_t l;
3513
3514 r = message_peek_body(m, &rindex, 1, 1, &q);
3515 if (r < 0)
3516 return r;
3517
3518 l = *(uint8_t*) q;
3519 r = message_peek_body(m, &rindex, 1, l+1, &q);
3520 if (r < 0)
3521 return r;
3522
3523 if (!validate_signature(q, l))
3524 return -EBADMSG;
3525
3526 if (p)
3527 *(const char**) p = q;
3528
3529 } else {
3530 ssize_t sz, align;
3531
3532 align = bus_type_get_alignment(type);
3533 assert(align > 0);
3534
3535 sz = bus_type_get_size(type);
3536 assert(sz > 0);
3537
3538 r = message_peek_body(m, &rindex, align, sz, &q);
3539 if (r < 0)
3540 return r;
3541
3542 switch (type) {
3543
3544 case SD_BUS_TYPE_BYTE:
3545 if (p)
3546 *(uint8_t*) p = *(uint8_t*) q;
3547 break;
3548
3549 case SD_BUS_TYPE_BOOLEAN:
3550 if (p)
3551 *(int*) p = !!*(uint32_t*) q;
3552 break;
3553
3554 case SD_BUS_TYPE_INT16:
3555 case SD_BUS_TYPE_UINT16:
3556 if (p)
3557 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
3558 break;
3559
3560 case SD_BUS_TYPE_INT32:
3561 case SD_BUS_TYPE_UINT32:
3562 if (p)
3563 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3564 break;
3565
3566 case SD_BUS_TYPE_INT64:
3567 case SD_BUS_TYPE_UINT64:
3568 case SD_BUS_TYPE_DOUBLE:
3569 if (p)
3570 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
3571 break;
3572
3573 case SD_BUS_TYPE_UNIX_FD: {
3574 uint32_t j;
3575
3576 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3577 if (j >= m->n_fds)
3578 return -EBADMSG;
3579
3580 if (p)
3581 *(int*) p = m->fds[j];
3582 break;
3583 }
3584
3585 default:
3586 assert_not_reached("Unknown basic type...");
3587 }
3588 }
3589 }
3590
3591 m->rindex = rindex;
3592
3593 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3594 c->index++;
3595
3596 return 1;
3597 }
3598
3599 static int bus_message_enter_array(
3600 sd_bus_message *m,
3601 struct bus_container *c,
3602 const char *contents,
3603 uint32_t **array_size,
3604 size_t *item_size,
3605 size_t **offsets,
3606 size_t *n_offsets) {
3607
3608 size_t rindex;
3609 void *q;
3610 int r, alignment;
3611
3612 assert(m);
3613 assert(c);
3614 assert(contents);
3615 assert(array_size);
3616 assert(item_size);
3617 assert(offsets);
3618 assert(n_offsets);
3619
3620 if (!signature_is_single(contents, true))
3621 return -EINVAL;
3622
3623 if (!c->signature || c->signature[c->index] == 0)
3624 return -ENXIO;
3625
3626 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
3627 return -ENXIO;
3628
3629 if (!startswith(c->signature + c->index + 1, contents))
3630 return -ENXIO;
3631
3632 rindex = m->rindex;
3633
3634 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3635 /* dbus1 */
3636
3637 r = message_peek_body(m, &rindex, 4, 4, &q);
3638 if (r < 0)
3639 return r;
3640
3641 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
3642 return -EBADMSG;
3643
3644 alignment = bus_type_get_alignment(contents[0]);
3645 if (alignment < 0)
3646 return alignment;
3647
3648 r = message_peek_body(m, &rindex, alignment, 0, NULL);
3649 if (r < 0)
3650 return r;
3651
3652 *array_size = (uint32_t*) q;
3653
3654 } else if (c->item_size <= 0) {
3655
3656 /* gvariant: empty array */
3657 *item_size = 0;
3658 *offsets = NULL;
3659 *n_offsets = 0;
3660
3661 } else if (bus_gvariant_is_fixed_size(contents)) {
3662
3663 /* gvariant: fixed length array */
3664 *item_size = bus_gvariant_get_size(contents);
3665 *offsets = NULL;
3666 *n_offsets = 0;
3667
3668 } else {
3669 size_t where, p = 0, framing, sz;
3670 unsigned i;
3671
3672 /* gvariant: variable length array */
3673 sz = bus_gvariant_determine_word_size(c->item_size, 0);
3674
3675 where = rindex + c->item_size - sz;
3676 r = message_peek_body(m, &where, 1, sz, &q);
3677 if (r < 0)
3678 return r;
3679
3680 framing = bus_gvariant_read_word_le(q, sz);
3681 if (framing > c->item_size - sz)
3682 return -EBADMSG;
3683 if ((c->item_size - framing) % sz != 0)
3684 return -EBADMSG;
3685
3686 *n_offsets = (c->item_size - framing) / sz;
3687
3688 where = rindex + framing;
3689 r = message_peek_body(m, &where, 1, *n_offsets * sz, &q);
3690 if (r < 0)
3691 return r;
3692
3693 *offsets = new(size_t, *n_offsets);
3694 if (!*offsets)
3695 return -ENOMEM;
3696
3697 for (i = 0; i < *n_offsets; i++) {
3698 size_t x;
3699
3700 x = bus_gvariant_read_word_le((uint8_t*) q + i * sz, sz);
3701 if (x > c->item_size - sz)
3702 return -EBADMSG;
3703 if (x < p)
3704 return -EBADMSG;
3705
3706 (*offsets)[i] = rindex + x;
3707 p = x;
3708 }
3709
3710 *item_size = (*offsets)[0] - rindex;
3711 }
3712
3713 m->rindex = rindex;
3714
3715 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3716 c->index += 1 + strlen(contents);
3717
3718 return 1;
3719 }
3720
3721 static int bus_message_enter_variant(
3722 sd_bus_message *m,
3723 struct bus_container *c,
3724 const char *contents,
3725 size_t *item_size) {
3726
3727 size_t rindex;
3728 uint8_t l;
3729 void *q;
3730 int r;
3731
3732 assert(m);
3733 assert(c);
3734 assert(contents);
3735 assert(item_size);
3736
3737 if (!signature_is_single(contents, false))
3738 return -EINVAL;
3739
3740 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
3741 return -EINVAL;
3742
3743 if (!c->signature || c->signature[c->index] == 0)
3744 return -ENXIO;
3745
3746 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
3747 return -ENXIO;
3748
3749 rindex = m->rindex;
3750
3751 if (BUS_MESSAGE_IS_GVARIANT(m)) {
3752 size_t k, where;
3753
3754 k = strlen(contents);
3755 if (1+k > c->item_size)
3756 return -EBADMSG;
3757
3758 where = rindex + c->item_size - (1+k);
3759 r = message_peek_body(m, &where, 1, 1+k, &q);
3760 if (r < 0)
3761 return r;
3762
3763 if (*(char*) q != 0)
3764 return -EBADMSG;
3765
3766 if (memcmp((uint8_t*) q+1, contents, k))
3767 return -ENXIO;
3768
3769 *item_size = c->item_size - (1+k);
3770
3771 } else {
3772 r = message_peek_body(m, &rindex, 1, 1, &q);
3773 if (r < 0)
3774 return r;
3775
3776 l = *(uint8_t*) q;
3777 r = message_peek_body(m, &rindex, 1, l+1, &q);
3778 if (r < 0)
3779 return r;
3780
3781 if (!validate_signature(q, l))
3782 return -EBADMSG;
3783
3784 if (!streq(q, contents))
3785 return -ENXIO;
3786 }
3787
3788 m->rindex = rindex;
3789
3790 if (c->enclosing != SD_BUS_TYPE_ARRAY)
3791 c->index++;
3792
3793 return 1;
3794 }
3795
3796 static int build_struct_offsets(
3797 sd_bus_message *m,
3798 const char *signature,
3799 size_t size,
3800 size_t *item_size,
3801 size_t **offsets,
3802 size_t *n_offsets) {
3803
3804 unsigned n_variable = 0, n_total = 0, v;
3805 size_t previous = 0, where;
3806 const char *p;
3807 size_t sz;
3808 void *q;
3809 int r;
3810
3811 assert(m);
3812 assert(item_size);
3813 assert(offsets);
3814 assert(n_offsets);
3815
3816 if (isempty(signature)) {
3817 /* Unary type is encoded as *fixed* 1 byte padding */
3818 r = message_peek_body(m, &m->rindex, 1, 1, &q);
3819 if (r < 0)
3820 return r;
3821
3822 if (*(uint8_t *) q != 0)
3823 return -EBADMSG;
3824
3825 *item_size = 0;
3826 *offsets = NULL;
3827 *n_offsets = 0;
3828 return 0;
3829 }
3830
3831 sz = bus_gvariant_determine_word_size(size, 0);
3832 if (sz <= 0)
3833 return -EBADMSG;
3834
3835 /* First, loop over signature and count variable elements and
3836 * elements in general. We use this to know how large the
3837 * offset array is at the end of the structure. Note that
3838 * GVariant only stores offsets for all variable size elements
3839 * that are not the last item. */
3840
3841 p = signature;
3842 while (*p != 0) {
3843 size_t n;
3844
3845 r = signature_element_length(p, &n);
3846 if (r < 0)
3847 return r;
3848 else {
3849 char t[n+1];
3850
3851 memcpy(t, p, n);
3852 t[n] = 0;
3853
3854 r = bus_gvariant_is_fixed_size(t);
3855 }
3856
3857 if (r < 0)
3858 return r;
3859 if (r == 0 && p[n] != 0) /* except the last item */
3860 n_variable++;
3861 n_total++;
3862
3863 p += n;
3864 }
3865
3866 if (size < n_variable * sz)
3867 return -EBADMSG;
3868
3869 where = m->rindex + size - (n_variable * sz);
3870 r = message_peek_body(m, &where, 1, n_variable * sz, &q);
3871 if (r < 0)
3872 return r;
3873
3874 v = n_variable;
3875
3876 *offsets = new(size_t, n_total);
3877 if (!*offsets)
3878 return -ENOMEM;
3879
3880 *n_offsets = 0;
3881
3882 /* Second, loop again and build an offset table */
3883 p = signature;
3884 while (*p != 0) {
3885 size_t n, offset;
3886 int k;
3887
3888 r = signature_element_length(p, &n);
3889 if (r < 0)
3890 return r;
3891 else {
3892 char t[n+1];
3893
3894 memcpy(t, p, n);
3895 t[n] = 0;
3896
3897 k = bus_gvariant_get_size(t);
3898 if (k < 0) {
3899 size_t x;
3900
3901 /* variable size */
3902 if (v > 0) {
3903 v--;
3904
3905 x = bus_gvariant_read_word_le((uint8_t*) q + v*sz, sz);
3906 if (x >= size)
3907 return -EBADMSG;
3908 if (m->rindex + x < previous)
3909 return -EBADMSG;
3910 } else
3911 /* The last item's end
3912 * is determined from
3913 * the start of the
3914 * offset array */
3915 x = size - (n_variable * sz);
3916
3917 offset = m->rindex + x;
3918
3919 } else {
3920 size_t align;
3921
3922 /* fixed size */
3923 align = bus_gvariant_get_alignment(t);
3924 assert(align > 0);
3925
3926 offset = (*n_offsets == 0 ? m->rindex : ALIGN_TO((*offsets)[*n_offsets-1], align)) + k;
3927 }
3928 }
3929
3930 previous = (*offsets)[(*n_offsets)++] = offset;
3931 p += n;
3932 }
3933
3934 assert(v == 0);
3935 assert(*n_offsets == n_total);
3936
3937 *item_size = (*offsets)[0] - m->rindex;
3938 return 0;
3939 }
3940
3941 static int enter_struct_or_dict_entry(
3942 sd_bus_message *m,
3943 struct bus_container *c,
3944 const char *contents,
3945 size_t *item_size,
3946 size_t **offsets,
3947 size_t *n_offsets) {
3948
3949 int r;
3950
3951 assert(m);
3952 assert(c);
3953 assert(contents);
3954 assert(item_size);
3955 assert(offsets);
3956 assert(n_offsets);
3957
3958 if (!BUS_MESSAGE_IS_GVARIANT(m)) {
3959
3960 /* dbus1 */
3961 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
3962 if (r < 0)
3963 return r;
3964
3965 } else
3966 /* gvariant with contents */
3967 return build_struct_offsets(m, contents, c->item_size, item_size, offsets, n_offsets);
3968
3969 return 0;
3970 }
3971
3972 static int bus_message_enter_struct(
3973 sd_bus_message *m,
3974 struct bus_container *c,
3975 const char *contents,
3976 size_t *item_size,
3977 size_t **offsets,
3978 size_t *n_offsets) {
3979
3980 size_t l;
3981 int r;
3982
3983 assert(m);
3984 assert(c);
3985 assert(contents);
3986 assert(item_size);
3987 assert(offsets);
3988 assert(n_offsets);
3989
3990 if (!signature_is_valid(contents, false))
3991 return -EINVAL;
3992
3993 if (!c->signature || c->signature[c->index] == 0)
3994 return -ENXIO;
3995
3996 l = strlen(contents);
3997
3998 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
3999 !startswith(c->signature + c->index + 1, contents) ||
4000 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
4001 return -ENXIO;
4002
4003 r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
4004 if (r < 0)
4005 return r;
4006
4007 if (c->enclosing != SD_BUS_TYPE_ARRAY)
4008 c->index += 1 + l + 1;
4009
4010 return 1;
4011 }
4012
4013 static int bus_message_enter_dict_entry(
4014 sd_bus_message *m,
4015 struct bus_container *c,
4016 const char *contents,
4017 size_t *item_size,
4018 size_t **offsets,
4019 size_t *n_offsets) {
4020
4021 size_t l;
4022 int r;
4023
4024 assert(m);
4025 assert(c);
4026 assert(contents);
4027
4028 if (!signature_is_pair(contents))
4029 return -EINVAL;
4030
4031 if (c->enclosing != SD_BUS_TYPE_ARRAY)
4032 return -ENXIO;
4033
4034 if (!c->signature || c->signature[c->index] == 0)
4035 return 0;
4036
4037 l = strlen(contents);
4038
4039 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
4040 !startswith(c->signature + c->index + 1, contents) ||
4041 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
4042 return -ENXIO;
4043
4044 r = enter_struct_or_dict_entry(m, c, contents, item_size, offsets, n_offsets);
4045 if (r < 0)
4046 return r;
4047
4048 if (c->enclosing != SD_BUS_TYPE_ARRAY)
4049 c->index += 1 + l + 1;
4050
4051 return 1;
4052 }
4053
4054 _public_ int sd_bus_message_enter_container(sd_bus_message *m,
4055 char type,
4056 const char *contents) {
4057 struct bus_container *c, *w;
4058 uint32_t *array_size = NULL;
4059 char *signature;
4060 size_t before;
4061 size_t *offsets = NULL;
4062 size_t n_offsets = 0, item_size = 0;
4063 int r;
4064
4065 assert_return(m, -EINVAL);
4066 assert_return(m->sealed, -EPERM);
4067 assert_return(type != 0 || !contents, -EINVAL);
4068
4069 if (type == 0 || !contents) {
4070 const char *cc;
4071 char tt;
4072
4073 /* Allow entering into anonymous containers */
4074 r = sd_bus_message_peek_type(m, &tt, &cc);
4075 if (r < 0)
4076 return r;
4077
4078 if (type != 0 && type != tt)
4079 return -ENXIO;
4080
4081 if (contents && !streq(contents, cc))
4082 return -ENXIO;
4083
4084 type = tt;
4085 contents = cc;
4086 }
4087
4088 /*
4089 * We enforce a global limit on container depth, that is much
4090 * higher than the 32 structs and 32 arrays the specification
4091 * mandates. This is simpler to implement for us, and we need
4092 * this only to ensure our container array doesn't grow
4093 * without bounds. We are happy to return any data from a
4094 * message as long as the data itself is valid, even if the
4095 * overall message might be not.
4096 *
4097 * Note that the message signature is validated when
4098 * parsing the headers, and that validation does check the
4099 * 32/32 limit.
4100 *
4101 * Note that the specification defines no limits on the depth
4102 * of stacked variants, but we do.
4103 */
4104 if (m->n_containers >= BUS_CONTAINER_DEPTH)
4105 return -EBADMSG;
4106
4107 if (!GREEDY_REALLOC(m->containers, m->containers_allocated, m->n_containers + 1))
4108 return -ENOMEM;
4109
4110 if (message_end_of_signature(m))
4111 return -ENXIO;
4112
4113 if (message_end_of_array(m, m->rindex))
4114 return 0;
4115
4116 c = message_get_container(m);
4117
4118 signature = strdup(contents);
4119 if (!signature)
4120 return -ENOMEM;
4121
4122 c->saved_index = c->index;
4123 before = m->rindex;
4124
4125 if (type == SD_BUS_TYPE_ARRAY)
4126 r = bus_message_enter_array(m, c, contents, &array_size, &item_size, &offsets, &n_offsets);
4127 else if (type == SD_BUS_TYPE_VARIANT)
4128 r = bus_message_enter_variant(m, c, contents, &item_size);
4129 else if (type == SD_BUS_TYPE_STRUCT)
4130 r = bus_message_enter_struct(m, c, contents, &item_size, &offsets, &n_offsets);
4131 else if (type == SD_BUS_TYPE_DICT_ENTRY)
4132 r = bus_message_enter_dict_entry(m, c, contents, &item_size, &offsets, &n_offsets);
4133 else
4134 r = -EINVAL;
4135
4136 if (r <= 0) {
4137 free(signature);
4138 free(offsets);
4139 return r;
4140 }
4141
4142 /* OK, let's fill it in */
4143 w = m->containers + m->n_containers++;
4144 w->enclosing = type;
4145 w->signature = signature;
4146 w->peeked_signature = NULL;
4147 w->index = 0;
4148
4149 w->before = before;
4150 w->begin = m->rindex;
4151
4152 /* Unary type has fixed size of 1, but virtual size of 0 */
4153 if (BUS_MESSAGE_IS_GVARIANT(m) &&
4154 type == SD_BUS_TYPE_STRUCT &&
4155 isempty(signature))
4156 w->end = m->rindex + 0;
4157 else
4158 w->end = m->rindex + c->item_size;
4159
4160 w->array_size = array_size;
4161 w->item_size = item_size;
4162 w->offsets = offsets;
4163 w->n_offsets = n_offsets;
4164 w->offset_index = 0;
4165
4166 return 1;
4167 }
4168
4169 _public_ int sd_bus_message_exit_container(sd_bus_message *m) {
4170 struct bus_container *c;
4171 unsigned saved;
4172 int r;
4173
4174 assert_return(m, -EINVAL);
4175 assert_return(m->sealed, -EPERM);
4176 assert_return(m->n_containers > 0, -ENXIO);
4177
4178 c = message_get_container(m);
4179
4180 if (c->enclosing != SD_BUS_TYPE_ARRAY) {
4181 if (c->signature && c->signature[c->index] != 0)
4182 return -EBUSY;
4183 }
4184
4185 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4186 if (m->rindex < c->end)
4187 return -EBUSY;
4188
4189 } else if (c->enclosing == SD_BUS_TYPE_ARRAY) {
4190 uint32_t l;
4191
4192 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4193 if (c->begin + l != m->rindex)
4194 return -EBUSY;
4195 }
4196
4197 free(c->signature);
4198 free(c->peeked_signature);
4199 free(c->offsets);
4200 m->n_containers--;
4201
4202 c = message_get_container(m);
4203
4204 saved = c->index;
4205 c->index = c->saved_index;
4206 r = container_next_item(m, c, &m->rindex);
4207 c->index = saved;
4208 if (r < 0)
4209 return r;
4210
4211 return 1;
4212 }
4213
4214 static void message_quit_container(sd_bus_message *m) {
4215 struct bus_container *c;
4216
4217 assert(m);
4218 assert(m->sealed);
4219 assert(m->n_containers > 0);
4220
4221 c = message_get_container(m);
4222
4223 /* Undo seeks */
4224 assert(m->rindex >= c->before);
4225 m->rindex = c->before;
4226
4227 /* Free container */
4228 free(c->signature);
4229 free(c->offsets);
4230 m->n_containers--;
4231
4232 /* Correct index of new top-level container */
4233 c = message_get_container(m);
4234 c->index = c->saved_index;
4235 }
4236
4237 _public_ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
4238 struct bus_container *c;
4239 int r;
4240
4241 assert_return(m, -EINVAL);
4242 assert_return(m->sealed, -EPERM);
4243
4244 if (message_end_of_signature(m))
4245 goto eof;
4246
4247 if (message_end_of_array(m, m->rindex))
4248 goto eof;
4249
4250 c = message_get_container(m);
4251
4252 if (bus_type_is_basic(c->signature[c->index])) {
4253 if (contents)
4254 *contents = NULL;
4255 if (type)
4256 *type = c->signature[c->index];
4257 return 1;
4258 }
4259
4260 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
4261
4262 if (contents) {
4263 size_t l;
4264 char *sig;
4265
4266 r = signature_element_length(c->signature+c->index+1, &l);
4267 if (r < 0)
4268 return r;
4269
4270 assert(l >= 1);
4271
4272 sig = strndup(c->signature + c->index + 1, l);
4273 if (!sig)
4274 return -ENOMEM;
4275
4276 free(c->peeked_signature);
4277 *contents = c->peeked_signature = sig;
4278 }
4279
4280 if (type)
4281 *type = SD_BUS_TYPE_ARRAY;
4282
4283 return 1;
4284 }
4285
4286 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
4287 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
4288
4289 if (contents) {
4290 size_t l;
4291 char *sig;
4292
4293 r = signature_element_length(c->signature+c->index, &l);
4294 if (r < 0)
4295 return r;
4296
4297 assert(l >= 2);
4298 sig = strndup(c->signature + c->index + 1, l - 2);
4299 if (!sig)
4300 return -ENOMEM;
4301
4302 free(c->peeked_signature);
4303 *contents = c->peeked_signature = sig;
4304 }
4305
4306 if (type)
4307 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
4308
4309 return 1;
4310 }
4311
4312 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
4313 if (contents) {
4314 void *q;
4315
4316 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4317 size_t k;
4318
4319 if (c->item_size < 2)
4320 return -EBADMSG;
4321
4322 /* Look for the NUL delimiter that
4323 separates the payload from the
4324 signature. Since the body might be
4325 in a different part that then the
4326 signature we map byte by byte. */
4327
4328 for (k = 2; k <= c->item_size; k++) {
4329 size_t where;
4330
4331 where = m->rindex + c->item_size - k;
4332 r = message_peek_body(m, &where, 1, k, &q);
4333 if (r < 0)
4334 return r;
4335
4336 if (*(char*) q == 0)
4337 break;
4338 }
4339
4340 if (k > c->item_size)
4341 return -EBADMSG;
4342
4343 free(c->peeked_signature);
4344 c->peeked_signature = strndup((char*) q + 1, k - 1);
4345 if (!c->peeked_signature)
4346 return -ENOMEM;
4347
4348 if (!signature_is_valid(c->peeked_signature, true))
4349 return -EBADMSG;
4350
4351 *contents = c->peeked_signature;
4352 } else {
4353 size_t rindex, l;
4354
4355 rindex = m->rindex;
4356 r = message_peek_body(m, &rindex, 1, 1, &q);
4357 if (r < 0)
4358 return r;
4359
4360 l = *(uint8_t*) q;
4361 r = message_peek_body(m, &rindex, 1, l+1, &q);
4362 if (r < 0)
4363 return r;
4364
4365 if (!validate_signature(q, l))
4366 return -EBADMSG;
4367
4368 *contents = q;
4369 }
4370 }
4371
4372 if (type)
4373 *type = SD_BUS_TYPE_VARIANT;
4374
4375 return 1;
4376 }
4377
4378 return -EINVAL;
4379
4380 eof:
4381 if (type)
4382 *type = 0;
4383 if (contents)
4384 *contents = NULL;
4385 return 0;
4386 }
4387
4388 _public_ int sd_bus_message_rewind(sd_bus_message *m, int complete) {
4389 struct bus_container *c;
4390
4391 assert_return(m, -EINVAL);
4392 assert_return(m->sealed, -EPERM);
4393
4394 if (complete) {
4395 message_reset_containers(m);
4396 m->rindex = 0;
4397
4398 c = message_get_container(m);
4399 } else {
4400 c = message_get_container(m);
4401
4402 c->offset_index = 0;
4403 c->index = 0;
4404 m->rindex = c->begin;
4405 }
4406
4407 c->offset_index = 0;
4408 c->item_size = (c->n_offsets > 0 ? c->offsets[0] : c->end) - c->begin;
4409
4410 return !isempty(c->signature);
4411 }
4412
4413 static int message_read_ap(
4414 sd_bus_message *m,
4415 const char *types,
4416 va_list ap) {
4417
4418 unsigned n_array, n_struct;
4419 TypeStack stack[BUS_CONTAINER_DEPTH];
4420 unsigned stack_ptr = 0;
4421 unsigned n_loop = 0;
4422 int r;
4423
4424 assert(m);
4425
4426 if (isempty(types))
4427 return 0;
4428
4429 /* Ideally, we'd just call ourselves recursively on every
4430 * complex type. However, the state of a va_list that is
4431 * passed to a function is undefined after that function
4432 * returns. This means we need to docode the va_list linearly
4433 * in a single stackframe. We hence implement our own
4434 * home-grown stack in an array. */
4435
4436 n_array = (unsigned) -1; /* length of current array entries */
4437 n_struct = strlen(types); /* length of current struct contents signature */
4438
4439 for (;;) {
4440 const char *t;
4441
4442 n_loop++;
4443
4444 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
4445 r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
4446 if (r < 0)
4447 return r;
4448 if (r == 0)
4449 break;
4450
4451 r = sd_bus_message_exit_container(m);
4452 if (r < 0)
4453 return r;
4454
4455 continue;
4456 }
4457
4458 t = types;
4459 if (n_array != (unsigned) -1)
4460 n_array--;
4461 else {
4462 types++;
4463 n_struct--;
4464 }
4465
4466 switch (*t) {
4467
4468 case SD_BUS_TYPE_BYTE:
4469 case SD_BUS_TYPE_BOOLEAN:
4470 case SD_BUS_TYPE_INT16:
4471 case SD_BUS_TYPE_UINT16:
4472 case SD_BUS_TYPE_INT32:
4473 case SD_BUS_TYPE_UINT32:
4474 case SD_BUS_TYPE_INT64:
4475 case SD_BUS_TYPE_UINT64:
4476 case SD_BUS_TYPE_DOUBLE:
4477 case SD_BUS_TYPE_STRING:
4478 case SD_BUS_TYPE_OBJECT_PATH:
4479 case SD_BUS_TYPE_SIGNATURE:
4480 case SD_BUS_TYPE_UNIX_FD: {
4481 void *p;
4482
4483 p = va_arg(ap, void*);
4484 r = sd_bus_message_read_basic(m, *t, p);
4485 if (r < 0)
4486 return r;
4487 if (r == 0) {
4488 if (n_loop <= 1)
4489 return 0;
4490
4491 return -ENXIO;
4492 }
4493
4494 break;
4495 }
4496
4497 case SD_BUS_TYPE_ARRAY: {
4498 size_t k;
4499
4500 r = signature_element_length(t + 1, &k);
4501 if (r < 0)
4502 return r;
4503
4504 {
4505 char s[k + 1];
4506 memcpy(s, t + 1, k);
4507 s[k] = 0;
4508
4509 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4510 if (r < 0)
4511 return r;
4512 if (r == 0) {
4513 if (n_loop <= 1)
4514 return 0;
4515
4516 return -ENXIO;
4517 }
4518 }
4519
4520 if (n_array == (unsigned) -1) {
4521 types += k;
4522 n_struct -= k;
4523 }
4524
4525 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4526 if (r < 0)
4527 return r;
4528
4529 types = t + 1;
4530 n_struct = k;
4531 n_array = va_arg(ap, unsigned);
4532
4533 break;
4534 }
4535
4536 case SD_BUS_TYPE_VARIANT: {
4537 const char *s;
4538
4539 s = va_arg(ap, const char *);
4540 if (!s)
4541 return -EINVAL;
4542
4543 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
4544 if (r < 0)
4545 return r;
4546 if (r == 0) {
4547 if (n_loop <= 1)
4548 return 0;
4549
4550 return -ENXIO;
4551 }
4552
4553 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4554 if (r < 0)
4555 return r;
4556
4557 types = s;
4558 n_struct = strlen(s);
4559 n_array = (unsigned) -1;
4560
4561 break;
4562 }
4563
4564 case SD_BUS_TYPE_STRUCT_BEGIN:
4565 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4566 size_t k;
4567
4568 r = signature_element_length(t, &k);
4569 if (r < 0)
4570 return r;
4571
4572 {
4573 char s[k - 1];
4574 memcpy(s, t + 1, k - 2);
4575 s[k - 2] = 0;
4576
4577 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4578 if (r < 0)
4579 return r;
4580 if (r == 0) {
4581 if (n_loop <= 1)
4582 return 0;
4583 return -ENXIO;
4584 }
4585 }
4586
4587 if (n_array == (unsigned) -1) {
4588 types += k - 1;
4589 n_struct -= k - 1;
4590 }
4591
4592 r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4593 if (r < 0)
4594 return r;
4595
4596 types = t + 1;
4597 n_struct = k - 2;
4598 n_array = (unsigned) -1;
4599
4600 break;
4601 }
4602
4603 default:
4604 return -EINVAL;
4605 }
4606 }
4607
4608 return 1;
4609 }
4610
4611 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
4612 va_list ap;
4613 int r;
4614
4615 assert_return(m, -EINVAL);
4616 assert_return(m->sealed, -EPERM);
4617 assert_return(types, -EINVAL);
4618
4619 va_start(ap, types);
4620 r = message_read_ap(m, types, ap);
4621 va_end(ap);
4622
4623 return r;
4624 }
4625
4626 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
4627 int r;
4628
4629 assert_return(m, -EINVAL);
4630 assert_return(m->sealed, -EPERM);
4631
4632 /* If types is NULL, read exactly one element */
4633 if (!types) {
4634 struct bus_container *c;
4635 size_t l;
4636
4637 if (message_end_of_signature(m))
4638 return -ENXIO;
4639
4640 if (message_end_of_array(m, m->rindex))
4641 return 0;
4642
4643 c = message_get_container(m);
4644
4645 r = signature_element_length(c->signature + c->index, &l);
4646 if (r < 0)
4647 return r;
4648
4649 types = strndupa(c->signature + c->index, l);
4650 }
4651
4652 switch (*types) {
4653
4654 case 0: /* Nothing to drop */
4655 return 0;
4656
4657 case SD_BUS_TYPE_BYTE:
4658 case SD_BUS_TYPE_BOOLEAN:
4659 case SD_BUS_TYPE_INT16:
4660 case SD_BUS_TYPE_UINT16:
4661 case SD_BUS_TYPE_INT32:
4662 case SD_BUS_TYPE_UINT32:
4663 case SD_BUS_TYPE_INT64:
4664 case SD_BUS_TYPE_UINT64:
4665 case SD_BUS_TYPE_DOUBLE:
4666 case SD_BUS_TYPE_STRING:
4667 case SD_BUS_TYPE_OBJECT_PATH:
4668 case SD_BUS_TYPE_SIGNATURE:
4669 case SD_BUS_TYPE_UNIX_FD:
4670
4671 r = sd_bus_message_read_basic(m, *types, NULL);
4672 if (r <= 0)
4673 return r;
4674
4675 r = sd_bus_message_skip(m, types + 1);
4676 if (r < 0)
4677 return r;
4678
4679 return 1;
4680
4681 case SD_BUS_TYPE_ARRAY: {
4682 size_t k;
4683
4684 r = signature_element_length(types + 1, &k);
4685 if (r < 0)
4686 return r;
4687
4688 {
4689 char s[k+1];
4690 memcpy(s, types+1, k);
4691 s[k] = 0;
4692
4693 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4694 if (r <= 0)
4695 return r;
4696
4697 for (;;) {
4698 r = sd_bus_message_skip(m, s);
4699 if (r < 0)
4700 return r;
4701 if (r == 0)
4702 break;
4703 }
4704
4705 r = sd_bus_message_exit_container(m);
4706 if (r < 0)
4707 return r;
4708 }
4709
4710 r = sd_bus_message_skip(m, types + 1 + k);
4711 if (r < 0)
4712 return r;
4713
4714 return 1;
4715 }
4716
4717 case SD_BUS_TYPE_VARIANT: {
4718 const char *contents;
4719 char x;
4720
4721 r = sd_bus_message_peek_type(m, &x, &contents);
4722 if (r <= 0)
4723 return r;
4724
4725 if (x != SD_BUS_TYPE_VARIANT)
4726 return -ENXIO;
4727
4728 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
4729 if (r <= 0)
4730 return r;
4731
4732 r = sd_bus_message_skip(m, contents);
4733 if (r < 0)
4734 return r;
4735 assert(r != 0);
4736
4737 r = sd_bus_message_exit_container(m);
4738 if (r < 0)
4739 return r;
4740
4741 r = sd_bus_message_skip(m, types + 1);
4742 if (r < 0)
4743 return r;
4744
4745 return 1;
4746 }
4747
4748 case SD_BUS_TYPE_STRUCT_BEGIN:
4749 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4750 size_t k;
4751
4752 r = signature_element_length(types, &k);
4753 if (r < 0)
4754 return r;
4755
4756 {
4757 char s[k-1];
4758 memcpy(s, types+1, k-2);
4759 s[k-2] = 0;
4760
4761 r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4762 if (r <= 0)
4763 return r;
4764
4765 r = sd_bus_message_skip(m, s);
4766 if (r < 0)
4767 return r;
4768
4769 r = sd_bus_message_exit_container(m);
4770 if (r < 0)
4771 return r;
4772 }
4773
4774 r = sd_bus_message_skip(m, types + k);
4775 if (r < 0)
4776 return r;
4777
4778 return 1;
4779 }
4780
4781 default:
4782 return -EINVAL;
4783 }
4784 }
4785
4786 _public_ int sd_bus_message_read_array(
4787 sd_bus_message *m,
4788 char type,
4789 const void **ptr,
4790 size_t *size) {
4791
4792 struct bus_container *c;
4793 void *p;
4794 size_t sz;
4795 ssize_t align;
4796 int r;
4797
4798 assert_return(m, -EINVAL);
4799 assert_return(m->sealed, -EPERM);
4800 assert_return(bus_type_is_trivial(type), -EINVAL);
4801 assert_return(ptr, -EINVAL);
4802 assert_return(size, -EINVAL);
4803 assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -EOPNOTSUPP);
4804
4805 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
4806 if (r <= 0)
4807 return r;
4808
4809 c = message_get_container(m);
4810
4811 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4812 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
4813 if (align < 0)
4814 return align;
4815
4816 sz = c->end - c->begin;
4817 } else {
4818 align = bus_type_get_alignment(type);
4819 if (align < 0)
4820 return align;
4821
4822 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4823 }
4824
4825 if (sz == 0)
4826 /* Zero length array, let's return some aligned
4827 * pointer that is not NULL */
4828 p = (uint8_t*) NULL + align;
4829 else {
4830 r = message_peek_body(m, &m->rindex, align, sz, &p);
4831 if (r < 0)
4832 goto fail;
4833 }
4834
4835 r = sd_bus_message_exit_container(m);
4836 if (r < 0)
4837 goto fail;
4838
4839 *ptr = (const void*) p;
4840 *size = sz;
4841
4842 return 1;
4843
4844 fail:
4845 message_quit_container(m);
4846 return r;
4847 }
4848
4849 static int message_peek_fields(
4850 sd_bus_message *m,
4851 size_t *rindex,
4852 size_t align,
4853 size_t nbytes,
4854 void **ret) {
4855
4856 assert(m);
4857 assert(rindex);
4858 assert(align > 0);
4859
4860 return buffer_peek(BUS_MESSAGE_FIELDS(m), m->fields_size, rindex, align, nbytes, ret);
4861 }
4862
4863 static int message_peek_field_uint32(
4864 sd_bus_message *m,
4865 size_t *ri,
4866 size_t item_size,
4867 uint32_t *ret) {
4868
4869 int r;
4870 void *q;
4871
4872 assert(m);
4873 assert(ri);
4874
4875 if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 4)
4876 return -EBADMSG;
4877
4878 /* identical for gvariant and dbus1 */
4879
4880 r = message_peek_fields(m, ri, 4, 4, &q);
4881 if (r < 0)
4882 return r;
4883
4884 if (ret)
4885 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
4886
4887 return 0;
4888 }
4889
4890 static int message_peek_field_uint64(
4891 sd_bus_message *m,
4892 size_t *ri,
4893 size_t item_size,
4894 uint64_t *ret) {
4895
4896 int r;
4897 void *q;
4898
4899 assert(m);
4900 assert(ri);
4901
4902 if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 8)
4903 return -EBADMSG;
4904
4905 /* identical for gvariant and dbus1 */
4906
4907 r = message_peek_fields(m, ri, 8, 8, &q);
4908 if (r < 0)
4909 return r;
4910
4911 if (ret)
4912 *ret = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
4913
4914 return 0;
4915 }
4916
4917 static int message_peek_field_string(
4918 sd_bus_message *m,
4919 bool (*validate)(const char *p),
4920 size_t *ri,
4921 size_t item_size,
4922 const char **ret) {
4923
4924 uint32_t l;
4925 int r;
4926 void *q;
4927
4928 assert(m);
4929 assert(ri);
4930
4931 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4932
4933 if (item_size <= 0)
4934 return -EBADMSG;
4935
4936 r = message_peek_fields(m, ri, 1, item_size, &q);
4937 if (r < 0)
4938 return r;
4939
4940 l = item_size - 1;
4941 } else {
4942 r = message_peek_field_uint32(m, ri, 4, &l);
4943 if (r < 0)
4944 return r;
4945
4946 r = message_peek_fields(m, ri, 1, l+1, &q);
4947 if (r < 0)
4948 return r;
4949 }
4950
4951 if (validate) {
4952 if (!validate_nul(q, l))
4953 return -EBADMSG;
4954
4955 if (!validate(q))
4956 return -EBADMSG;
4957 } else {
4958 if (!validate_string(q, l))
4959 return -EBADMSG;
4960 }
4961
4962 if (ret)
4963 *ret = q;
4964
4965 return 0;
4966 }
4967
4968 static int message_peek_field_signature(
4969 sd_bus_message *m,
4970 size_t *ri,
4971 size_t item_size,
4972 const char **ret) {
4973
4974 size_t l;
4975 int r;
4976 void *q;
4977
4978 assert(m);
4979 assert(ri);
4980
4981 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4982
4983 if (item_size <= 0)
4984 return -EBADMSG;
4985
4986 r = message_peek_fields(m, ri, 1, item_size, &q);
4987 if (r < 0)
4988 return r;
4989
4990 l = item_size - 1;
4991 } else {
4992 r = message_peek_fields(m, ri, 1, 1, &q);
4993 if (r < 0)
4994 return r;
4995
4996 l = *(uint8_t*) q;
4997 r = message_peek_fields(m, ri, 1, l+1, &q);
4998 if (r < 0)
4999 return r;
5000 }
5001
5002 if (!validate_signature(q, l))
5003 return -EBADMSG;
5004
5005 if (ret)
5006 *ret = q;
5007
5008 return 0;
5009 }
5010
5011 static int message_skip_fields(
5012 sd_bus_message *m,
5013 size_t *ri,
5014 uint32_t array_size,
5015 const char **signature) {
5016
5017 size_t original_index;
5018 int r;
5019
5020 assert(m);
5021 assert(ri);
5022 assert(signature);
5023 assert(!BUS_MESSAGE_IS_GVARIANT(m));
5024
5025 original_index = *ri;
5026
5027 for (;;) {
5028 char t;
5029 size_t l;
5030
5031 if (array_size != (uint32_t) -1 &&
5032 array_size <= *ri - original_index)
5033 return 0;
5034
5035 t = **signature;
5036 if (!t)
5037 return 0;
5038
5039 if (t == SD_BUS_TYPE_STRING) {
5040
5041 r = message_peek_field_string(m, NULL, ri, 0, NULL);
5042 if (r < 0)
5043 return r;
5044
5045 (*signature)++;
5046
5047 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
5048
5049 r = message_peek_field_string(m, object_path_is_valid, ri, 0, NULL);
5050 if (r < 0)
5051 return r;
5052
5053 (*signature)++;
5054
5055 } else if (t == SD_BUS_TYPE_SIGNATURE) {
5056
5057 r = message_peek_field_signature(m, ri, 0, NULL);
5058 if (r < 0)
5059 return r;
5060
5061 (*signature)++;
5062
5063 } else if (bus_type_is_basic(t)) {
5064 ssize_t align, k;
5065
5066 align = bus_type_get_alignment(t);
5067 k = bus_type_get_size(t);
5068 assert(align > 0 && k > 0);
5069
5070 r = message_peek_fields(m, ri, align, k, NULL);
5071 if (r < 0)
5072 return r;
5073
5074 (*signature)++;
5075
5076 } else if (t == SD_BUS_TYPE_ARRAY) {
5077
5078 r = signature_element_length(*signature+1, &l);
5079 if (r < 0)
5080 return r;
5081
5082 assert(l >= 1);
5083 {
5084 char sig[l-1], *s;
5085 uint32_t nas;
5086 int alignment;
5087
5088 strncpy(sig, *signature + 1, l-1);
5089 s = sig;
5090
5091 alignment = bus_type_get_alignment(sig[0]);
5092 if (alignment < 0)
5093 return alignment;
5094
5095 r = message_peek_field_uint32(m, ri, 0, &nas);
5096 if (r < 0)
5097 return r;
5098 if (nas > BUS_ARRAY_MAX_SIZE)
5099 return -EBADMSG;
5100
5101 r = message_peek_fields(m, ri, alignment, 0, NULL);
5102 if (r < 0)
5103 return r;
5104
5105 r = message_skip_fields(m, ri, nas, (const char**) &s);
5106 if (r < 0)
5107 return r;
5108 }
5109
5110 (*signature) += 1 + l;
5111
5112 } else if (t == SD_BUS_TYPE_VARIANT) {
5113 const char *s;
5114
5115 r = message_peek_field_signature(m, ri, 0, &s);
5116 if (r < 0)
5117 return r;
5118
5119 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
5120 if (r < 0)
5121 return r;
5122
5123 (*signature)++;
5124
5125 } else if (t == SD_BUS_TYPE_STRUCT ||
5126 t == SD_BUS_TYPE_DICT_ENTRY) {
5127
5128 r = signature_element_length(*signature, &l);
5129 if (r < 0)
5130 return r;
5131
5132 assert(l >= 2);
5133 {
5134 char sig[l-1], *s;
5135 strncpy(sig, *signature + 1, l-1);
5136 s = sig;
5137
5138 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
5139 if (r < 0)
5140 return r;
5141 }
5142
5143 *signature += l;
5144 } else
5145 return -EINVAL;
5146 }
5147 }
5148
5149 int bus_message_parse_fields(sd_bus_message *m) {
5150 size_t ri;
5151 int r;
5152 uint32_t unix_fds = 0;
5153 bool unix_fds_set = false;
5154 void *offsets = NULL;
5155 unsigned n_offsets = 0;
5156 size_t sz = 0;
5157 unsigned i = 0;
5158
5159 assert(m);
5160
5161 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5162 char *p;
5163
5164 /* Read the signature from the end of the body variant first */
5165 sz = bus_gvariant_determine_word_size(BUS_MESSAGE_SIZE(m), 0);
5166 if (m->footer_accessible < 1 + sz)
5167 return -EBADMSG;
5168
5169 p = (char*) m->footer + m->footer_accessible - (1 + sz);
5170 for (;;) {
5171 if (p < (char*) m->footer)
5172 return -EBADMSG;
5173
5174 if (*p == 0) {
5175 size_t l;
5176 char *c;
5177
5178 /* We found the beginning of the signature
5179 * string, yay! We require the body to be a
5180 * structure, so verify it and then strip the
5181 * opening/closing brackets. */
5182
5183 l = ((char*) m->footer + m->footer_accessible) - p - (1 + sz);
5184 if (l < 2 ||
5185 p[1] != SD_BUS_TYPE_STRUCT_BEGIN ||
5186 p[1 + l - 1] != SD_BUS_TYPE_STRUCT_END)
5187 return -EBADMSG;
5188
5189 c = strndup(p + 1 + 1, l - 2);
5190 if (!c)
5191 return -ENOMEM;
5192
5193 free(m->root_container.signature);
5194 m->root_container.signature = c;
5195 break;
5196 }
5197
5198 p--;
5199 }
5200
5201 /* Calculate the actual user body size, by removing
5202 * the trailing variant signature and struct offset
5203 * table */
5204 m->user_body_size = m->body_size - ((char*) m->footer + m->footer_accessible - p);
5205
5206 /* Pull out the offset table for the fields array */
5207 sz = bus_gvariant_determine_word_size(m->fields_size, 0);
5208 if (sz > 0) {
5209 size_t framing;
5210 void *q;
5211
5212 ri = m->fields_size - sz;
5213 r = message_peek_fields(m, &ri, 1, sz, &q);
5214 if (r < 0)
5215 return r;
5216
5217 framing = bus_gvariant_read_word_le(q, sz);
5218 if (framing >= m->fields_size - sz)
5219 return -EBADMSG;
5220 if ((m->fields_size - framing) % sz != 0)
5221 return -EBADMSG;
5222
5223 ri = framing;
5224 r = message_peek_fields(m, &ri, 1, m->fields_size - framing, &offsets);
5225 if (r < 0)
5226 return r;
5227
5228 n_offsets = (m->fields_size - framing) / sz;
5229 }
5230 } else
5231 m->user_body_size = m->body_size;
5232
5233 ri = 0;
5234 while (ri < m->fields_size) {
5235 _cleanup_free_ char *sig = NULL;
5236 const char *signature;
5237 uint64_t field_type;
5238 size_t item_size = (size_t) -1;
5239
5240 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5241 uint64_t *u64;
5242
5243 if (i >= n_offsets)
5244 break;
5245
5246 if (i == 0)
5247 ri = 0;
5248 else
5249 ri = ALIGN_TO(bus_gvariant_read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8);
5250
5251 r = message_peek_fields(m, &ri, 8, 8, (void**) &u64);
5252 if (r < 0)
5253 return r;
5254
5255 field_type = BUS_MESSAGE_BSWAP64(m, *u64);
5256 } else {
5257 uint8_t *u8;
5258
5259 r = message_peek_fields(m, &ri, 8, 1, (void**) &u8);
5260 if (r < 0)
5261 return r;
5262
5263 field_type = *u8;
5264 }
5265
5266 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5267 size_t where, end;
5268 char *b;
5269 void *q;
5270
5271 end = bus_gvariant_read_word_le((uint8_t*) offsets + i*sz, sz);
5272
5273 if (end < ri)
5274 return -EBADMSG;
5275
5276 where = ri = ALIGN_TO(ri, 8);
5277 item_size = end - ri;
5278 r = message_peek_fields(m, &where, 1, item_size, &q);
5279 if (r < 0)
5280 return r;
5281
5282 b = memrchr(q, 0, item_size);
5283 if (!b)
5284 return -EBADMSG;
5285
5286 sig = strndup(b+1, item_size - (b+1-(char*) q));
5287 if (!sig)
5288 return -ENOMEM;
5289
5290 signature = sig;
5291 item_size = b - (char*) q;
5292 } else {
5293 r = message_peek_field_signature(m, &ri, 0, &signature);
5294 if (r < 0)
5295 return r;
5296 }
5297
5298 switch (field_type) {
5299
5300 case _BUS_MESSAGE_HEADER_INVALID:
5301 return -EBADMSG;
5302
5303 case BUS_MESSAGE_HEADER_PATH:
5304
5305 if (m->path)
5306 return -EBADMSG;
5307
5308 if (!streq(signature, "o"))
5309 return -EBADMSG;
5310
5311 r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path);
5312 break;
5313
5314 case BUS_MESSAGE_HEADER_INTERFACE:
5315
5316 if (m->interface)
5317 return -EBADMSG;
5318
5319 if (!streq(signature, "s"))
5320 return -EBADMSG;
5321
5322 r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface);
5323 break;
5324
5325 case BUS_MESSAGE_HEADER_MEMBER:
5326
5327 if (m->member)
5328 return -EBADMSG;
5329
5330 if (!streq(signature, "s"))
5331 return -EBADMSG;
5332
5333 r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member);
5334 break;
5335
5336 case BUS_MESSAGE_HEADER_ERROR_NAME:
5337
5338 if (m->error.name)
5339 return -EBADMSG;
5340
5341 if (!streq(signature, "s"))
5342 return -EBADMSG;
5343
5344 r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name);
5345 if (r >= 0)
5346 m->error._need_free = -1;
5347
5348 break;
5349
5350 case BUS_MESSAGE_HEADER_DESTINATION:
5351
5352 if (m->destination)
5353 return -EBADMSG;
5354
5355 if (!streq(signature, "s"))
5356 return -EBADMSG;
5357
5358 r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination);
5359 break;
5360
5361 case BUS_MESSAGE_HEADER_SENDER:
5362
5363 if (m->sender)
5364 return -EBADMSG;
5365
5366 if (!streq(signature, "s"))
5367 return -EBADMSG;
5368
5369 r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
5370
5371 if (r >= 0 && m->sender[0] == ':' && m->bus->bus_client && !m->bus->is_kernel) {
5372 m->creds.unique_name = (char*) m->sender;
5373 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
5374 }
5375
5376 break;
5377
5378
5379 case BUS_MESSAGE_HEADER_SIGNATURE: {
5380 const char *s;
5381 char *c;
5382
5383 if (BUS_MESSAGE_IS_GVARIANT(m)) /* only applies to dbus1 */
5384 return -EBADMSG;
5385
5386 if (m->root_container.signature)
5387 return -EBADMSG;
5388
5389 if (!streq(signature, "g"))
5390 return -EBADMSG;
5391
5392 r = message_peek_field_signature(m, &ri, item_size, &s);
5393 if (r < 0)
5394 return r;
5395
5396 c = strdup(s);
5397 if (!c)
5398 return -ENOMEM;
5399
5400 free(m->root_container.signature);
5401 m->root_container.signature = c;
5402 break;
5403 }
5404
5405 case BUS_MESSAGE_HEADER_REPLY_SERIAL:
5406
5407 if (m->reply_cookie != 0)
5408 return -EBADMSG;
5409
5410 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5411 /* 64bit on dbus2 */
5412
5413 if (!streq(signature, "t"))
5414 return -EBADMSG;
5415
5416 r = message_peek_field_uint64(m, &ri, item_size, &m->reply_cookie);
5417 if (r < 0)
5418 return r;
5419 } else {
5420 /* 32bit on dbus1 */
5421 uint32_t serial;
5422
5423 if (!streq(signature, "u"))
5424 return -EBADMSG;
5425
5426 r = message_peek_field_uint32(m, &ri, item_size, &serial);
5427 if (r < 0)
5428 return r;
5429
5430 m->reply_cookie = serial;
5431 }
5432
5433 if (m->reply_cookie == 0)
5434 return -EBADMSG;
5435
5436 break;
5437
5438 case BUS_MESSAGE_HEADER_UNIX_FDS:
5439 if (unix_fds_set)
5440 return -EBADMSG;
5441
5442 if (!streq(signature, "u"))
5443 return -EBADMSG;
5444
5445 r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
5446 if (r < 0)
5447 return -EBADMSG;
5448
5449 unix_fds_set = true;
5450 break;
5451
5452 default:
5453 if (!BUS_MESSAGE_IS_GVARIANT(m))
5454 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
5455 }
5456
5457 if (r < 0)
5458 return r;
5459
5460 i++;
5461 }
5462
5463 if (m->n_fds != unix_fds)
5464 return -EBADMSG;
5465
5466 switch (m->header->type) {
5467
5468 case SD_BUS_MESSAGE_SIGNAL:
5469 if (!m->path || !m->interface || !m->member)
5470 return -EBADMSG;
5471
5472 if (m->reply_cookie != 0)
5473 return -EBADMSG;
5474
5475 break;
5476
5477 case SD_BUS_MESSAGE_METHOD_CALL:
5478
5479 if (!m->path || !m->member)
5480 return -EBADMSG;
5481
5482 if (m->reply_cookie != 0)
5483 return -EBADMSG;
5484
5485 break;
5486
5487 case SD_BUS_MESSAGE_METHOD_RETURN:
5488
5489 if (m->reply_cookie == 0)
5490 return -EBADMSG;
5491 break;
5492
5493 case SD_BUS_MESSAGE_METHOD_ERROR:
5494
5495 if (m->reply_cookie == 0 || !m->error.name)
5496 return -EBADMSG;
5497 break;
5498 }
5499
5500 /* Refuse non-local messages that claim they are local */
5501 if (streq_ptr(m->path, "/org/freedesktop/DBus/Local"))
5502 return -EBADMSG;
5503 if (streq_ptr(m->interface, "org.freedesktop.DBus.Local"))
5504 return -EBADMSG;
5505 if (streq_ptr(m->sender, "org.freedesktop.DBus.Local"))
5506 return -EBADMSG;
5507
5508 m->root_container.end = m->user_body_size;
5509
5510 if (BUS_MESSAGE_IS_GVARIANT(m)) {
5511 r = build_struct_offsets(
5512 m,
5513 m->root_container.signature,
5514 m->user_body_size,
5515 &m->root_container.item_size,
5516 &m->root_container.offsets,
5517 &m->root_container.n_offsets);
5518 if (r < 0)
5519 return r;
5520 }
5521
5522 /* Try to read the error message, but if we can't it's a non-issue */
5523 if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
5524 (void) sd_bus_message_read(m, "s", &m->error.message);
5525
5526 return 0;
5527 }
5528
5529 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
5530 assert_return(m, -EINVAL);
5531 assert_return(destination, -EINVAL);
5532 assert_return(!m->sealed, -EPERM);
5533 assert_return(!m->destination, -EEXIST);
5534
5535 return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
5536 }
5537
5538 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
5539 size_t total;
5540 void *p, *e;
5541 unsigned i;
5542 struct bus_body_part *part;
5543
5544 assert(m);
5545 assert(buffer);
5546 assert(sz);
5547
5548 total = BUS_MESSAGE_SIZE(m);
5549
5550 p = malloc(total);
5551 if (!p)
5552 return -ENOMEM;
5553
5554 e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
5555 MESSAGE_FOREACH_PART(part, i, m)
5556 e = mempcpy(e, part->data, part->size);
5557
5558 assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
5559
5560 *buffer = p;
5561 *sz = total;
5562
5563 return 0;
5564 }
5565
5566 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
5567 const char *s;
5568 int r;
5569
5570 assert(m);
5571 assert(l);
5572
5573 r = sd_bus_message_enter_container(m, 'a', "s");
5574 if (r <= 0)
5575 return r;
5576
5577 while ((r = sd_bus_message_read_basic(m, 's', &s)) > 0) {
5578 r = strv_extend(l, s);
5579 if (r < 0)
5580 return r;
5581 }
5582 if (r < 0)
5583 return r;
5584
5585 r = sd_bus_message_exit_container(m);
5586 if (r < 0)
5587 return r;
5588
5589 return 1;
5590 }
5591
5592 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
5593 char **strv = NULL;
5594 int r;
5595
5596 assert_return(m, -EINVAL);
5597 assert_return(m->sealed, -EPERM);
5598 assert_return(l, -EINVAL);
5599
5600 r = bus_message_read_strv_extend(m, &strv);
5601 if (r <= 0) {
5602 strv_free(strv);
5603 return r;
5604 }
5605
5606 *l = strv;
5607 return 1;
5608 }
5609
5610 static int bus_message_get_arg_skip(
5611 sd_bus_message *m,
5612 unsigned i,
5613 char *_type,
5614 const char **_contents) {
5615
5616 unsigned j;
5617 int r;
5618
5619 r = sd_bus_message_rewind(m, true);
5620 if (r < 0)
5621 return r;
5622
5623 for (j = 0;; j++) {
5624 const char *contents;
5625 char type;
5626
5627 r = sd_bus_message_peek_type(m, &type, &contents);
5628 if (r < 0)
5629 return r;
5630 if (r == 0)
5631 return -ENXIO;
5632
5633 /* Don't match against arguments after the first one we don't understand */
5634 if (!IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE) &&
5635 !(type == SD_BUS_TYPE_ARRAY && STR_IN_SET(contents, "s", "o", "g")))
5636 return -ENXIO;
5637
5638 if (j >= i) {
5639 if (_contents)
5640 *_contents = contents;
5641 if (_type)
5642 *_type = type;
5643 return 0;
5644 }
5645
5646 r = sd_bus_message_skip(m, NULL);
5647 if (r < 0)
5648 return r;
5649 }
5650
5651 }
5652
5653 int bus_message_get_arg(sd_bus_message *m, unsigned i, const char **str) {
5654 char type;
5655 int r;
5656
5657 assert(m);
5658 assert(str);
5659
5660 r = bus_message_get_arg_skip(m, i, &type, NULL);
5661 if (r < 0)
5662 return r;
5663
5664 if (!IN_SET(type, SD_BUS_TYPE_STRING, SD_BUS_TYPE_OBJECT_PATH, SD_BUS_TYPE_SIGNATURE))
5665 return -ENXIO;
5666
5667 return sd_bus_message_read_basic(m, type, str);
5668 }
5669
5670 int bus_message_get_arg_strv(sd_bus_message *m, unsigned i, char ***strv) {
5671 const char *contents;
5672 char type;
5673 int r;
5674
5675 assert(m);
5676 assert(strv);
5677
5678 r = bus_message_get_arg_skip(m, i, &type, &contents);
5679 if (r < 0)
5680 return r;
5681
5682 if (type != SD_BUS_TYPE_ARRAY)
5683 return -ENXIO;
5684 if (!STR_IN_SET(contents, "s", "o", "g"))
5685 return -ENXIO;
5686
5687 return sd_bus_message_read_strv(m, strv);
5688 }
5689
5690 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
5691 assert_return(m, EINVAL);
5692
5693 if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
5694 return 0;
5695
5696 return sd_bus_error_get_errno(&m->error);
5697 }
5698
5699 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
5700 struct bus_container *c;
5701
5702 assert_return(m, NULL);
5703
5704 c = complete ? &m->root_container : message_get_container(m);
5705 return strempty(c->signature);
5706 }
5707
5708 _public_ int sd_bus_message_is_empty(sd_bus_message *m) {
5709 assert_return(m, -EINVAL);
5710
5711 return isempty(m->root_container.signature);
5712 }
5713
5714 _public_ int sd_bus_message_has_signature(sd_bus_message *m, const char *signature) {
5715 assert_return(m, -EINVAL);
5716
5717 return streq(strempty(m->root_container.signature), strempty(signature));
5718 }
5719
5720 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
5721 bool done_something = false;
5722 int r;
5723
5724 assert_return(m, -EINVAL);
5725 assert_return(source, -EINVAL);
5726 assert_return(!m->sealed, -EPERM);
5727 assert_return(source->sealed, -EPERM);
5728
5729 do {
5730 const char *contents;
5731 char type;
5732 union {
5733 uint8_t u8;
5734 uint16_t u16;
5735 int16_t s16;
5736 uint32_t u32;
5737 int32_t s32;
5738 uint64_t u64;
5739 int64_t s64;
5740 double d64;
5741 const char *string;
5742 int i;
5743 } basic;
5744
5745 r = sd_bus_message_peek_type(source, &type, &contents);
5746 if (r < 0)
5747 return r;
5748 if (r == 0)
5749 break;
5750
5751 done_something = true;
5752
5753 if (bus_type_is_container(type) > 0) {
5754
5755 r = sd_bus_message_enter_container(source, type, contents);
5756 if (r < 0)
5757 return r;
5758
5759 r = sd_bus_message_open_container(m, type, contents);
5760 if (r < 0)
5761 return r;
5762
5763 r = sd_bus_message_copy(m, source, true);
5764 if (r < 0)
5765 return r;
5766
5767 r = sd_bus_message_close_container(m);
5768 if (r < 0)
5769 return r;
5770
5771 r = sd_bus_message_exit_container(source);
5772 if (r < 0)
5773 return r;
5774
5775 continue;
5776 }
5777
5778 r = sd_bus_message_read_basic(source, type, &basic);
5779 if (r < 0)
5780 return r;
5781
5782 assert(r > 0);
5783
5784 if (type == SD_BUS_TYPE_OBJECT_PATH ||
5785 type == SD_BUS_TYPE_SIGNATURE ||
5786 type == SD_BUS_TYPE_STRING)
5787 r = sd_bus_message_append_basic(m, type, basic.string);
5788 else
5789 r = sd_bus_message_append_basic(m, type, &basic);
5790
5791 if (r < 0)
5792 return r;
5793
5794 } while (all);
5795
5796 return done_something;
5797 }
5798
5799 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
5800 const char *c;
5801 char t;
5802 int r;
5803
5804 assert_return(m, -EINVAL);
5805 assert_return(m->sealed, -EPERM);
5806 assert_return(!type || bus_type_is_valid(type), -EINVAL);
5807 assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
5808 assert_return(type || contents, -EINVAL);
5809 assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
5810
5811 r = sd_bus_message_peek_type(m, &t, &c);
5812 if (r <= 0)
5813 return r;
5814
5815 if (type != 0 && type != t)
5816 return 0;
5817
5818 if (contents && !streq_ptr(contents, c))
5819 return 0;
5820
5821 return 1;
5822 }
5823
5824 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
5825 assert_return(m, NULL);
5826
5827 return m->bus;
5828 }
5829
5830 int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
5831 _cleanup_(sd_bus_message_unrefp) sd_bus_message *n = NULL;
5832 usec_t timeout;
5833 int r;
5834
5835 assert(bus);
5836 assert(m);
5837 assert(*m);
5838
5839 switch ((*m)->header->type) {
5840
5841 case SD_BUS_MESSAGE_SIGNAL:
5842 r = sd_bus_message_new_signal(bus, &n, (*m)->path, (*m)->interface, (*m)->member);
5843 if (r < 0)
5844 return r;
5845
5846 break;
5847
5848 case SD_BUS_MESSAGE_METHOD_CALL:
5849 r = sd_bus_message_new_method_call(bus, &n, (*m)->destination, (*m)->path, (*m)->interface, (*m)->member);
5850 if (r < 0)
5851 return r;
5852
5853 break;
5854
5855 case SD_BUS_MESSAGE_METHOD_RETURN:
5856 case SD_BUS_MESSAGE_METHOD_ERROR:
5857
5858 n = message_new(bus, (*m)->header->type);
5859 if (!n)
5860 return -ENOMEM;
5861
5862 n->reply_cookie = (*m)->reply_cookie;
5863
5864 r = message_append_reply_cookie(n, n->reply_cookie);
5865 if (r < 0)
5866 return r;
5867
5868 if ((*m)->header->type == SD_BUS_MESSAGE_METHOD_ERROR && (*m)->error.name) {
5869 r = message_append_field_string(n, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, (*m)->error.name, &n->error.message);
5870 if (r < 0)
5871 return r;
5872
5873 n->error._need_free = -1;
5874 }
5875
5876 break;
5877
5878 default:
5879 return -EINVAL;
5880 }
5881
5882 if ((*m)->destination && !n->destination) {
5883 r = message_append_field_string(n, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, (*m)->destination, &n->destination);
5884 if (r < 0)
5885 return r;
5886 }
5887
5888 if ((*m)->sender && !n->sender) {
5889 r = message_append_field_string(n, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, (*m)->sender, &n->sender);
5890 if (r < 0)
5891 return r;
5892 }
5893
5894 n->header->flags |= (*m)->header->flags & (BUS_MESSAGE_NO_REPLY_EXPECTED|BUS_MESSAGE_NO_AUTO_START);
5895
5896 r = sd_bus_message_copy(n, *m, true);
5897 if (r < 0)
5898 return r;
5899
5900 timeout = (*m)->timeout;
5901 if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
5902 timeout = BUS_DEFAULT_TIMEOUT;
5903
5904 r = bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout);
5905 if (r < 0)
5906 return r;
5907
5908 sd_bus_message_unref(*m);
5909 *m = n;
5910 n = NULL;
5911
5912 return 0;
5913 }
5914
5915 int bus_message_append_sender(sd_bus_message *m, const char *sender) {
5916 assert(m);
5917 assert(sender);
5918
5919 assert_return(!m->sealed, -EPERM);
5920 assert_return(!m->sender, -EPERM);
5921
5922 return message_append_field_string(m, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, sender, &m->sender);
5923 }
5924
5925 _public_ int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority) {
5926 assert_return(m, -EINVAL);
5927 assert_return(priority, -EINVAL);
5928
5929 *priority = m->priority;
5930 return 0;
5931 }
5932
5933 _public_ int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority) {
5934 assert_return(m, -EINVAL);
5935 assert_return(!m->sealed, -EPERM);
5936
5937 m->priority = priority;
5938 return 0;
5939 }