]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-bus/bus-message.c
bus: when parsing signature strings, accept NULL as empty signature
[thirdparty/systemd.git] / src / libsystemd-bus / bus-message.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <fcntl.h>
24
25 #include "util.h"
26 #include "utf8.h"
27 #include "strv.h"
28
29 #include "sd-bus.h"
30 #include "bus-message.h"
31 #include "bus-internal.h"
32 #include "bus-type.h"
33 #include "bus-signature.h"
34
35 static int message_parse_fields(sd_bus_message *m);
36 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
37
38 static void reset_containers(sd_bus_message *m) {
39 unsigned i;
40
41 assert(m);
42
43 for (i = 0; i < m->n_containers; i++)
44 free(m->containers[i].signature);
45
46 free(m->containers);
47 m->containers = NULL;
48
49 m->n_containers = 0;
50 m->root_container.index = 0;
51 }
52
53 static void message_free(sd_bus_message *m) {
54 assert(m);
55
56 if (m->free_header)
57 free(m->header);
58
59 if (m->free_fields)
60 free(m->fields);
61
62 if (m->free_body)
63 free(m->body);
64
65 if (m->free_fds) {
66 close_many(m->fds, m->n_fds);
67 free(m->fds);
68 }
69
70 reset_containers(m);
71 free(m->root_container.signature);
72
73 free(m->peeked_signature);
74 free(m);
75 }
76
77 static void* buffer_extend(void **p, uint32_t *sz, size_t align, size_t extend) {
78 size_t start, n;
79 void *k;
80
81 assert(p);
82 assert(sz);
83 assert(align > 0);
84
85 start = ALIGN_TO((size_t) *sz, align);
86 n = start + extend;
87
88 if (n == *sz)
89 return (uint8_t*) *p + start;
90
91 if (n > (size_t) ((uint32_t) -1))
92 return NULL;
93
94 k = realloc(*p, n);
95 if (!k)
96 return NULL;
97
98 /* Zero out padding */
99 if (start > *sz)
100 memset((uint8_t*) k + *sz, 0, start - *sz);
101
102 *p = k;
103 *sz = n;
104
105 return (uint8_t*) k + start;
106 }
107
108 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
109 void *p, *o;
110
111 assert(m);
112
113 o = m->fields;
114 p = buffer_extend(&m->fields, &m->header->fields_size, align, sz);
115 if (!p)
116 return NULL;
117
118 if (o != m->fields) {
119 /* Adjust quick access pointers */
120
121 if (m->path)
122 m->path = (const char*) m->fields + (m->path - (const char*) o);
123 if (m->interface)
124 m->interface = (const char*) m->fields + (m->interface - (const char*) o);
125 if (m->member)
126 m->member = (const char*) m->fields + (m->member - (const char*) o);
127 if (m->destination)
128 m->destination = (const char*) m->fields + (m->destination - (const char*) o);
129 if (m->sender)
130 m->sender = (const char*) m->fields + (m->sender - (const char*) o);
131 if (m->error.name)
132 m->error.name = (const char*) m->fields + (m->error.name - (const char*) o);
133 }
134
135 m->free_fields = true;
136
137 return p;
138 }
139
140 static int message_append_field_string(
141 sd_bus_message *m,
142 uint8_t h,
143 char type,
144 const char *s,
145 const char **ret) {
146
147 size_t l;
148 uint8_t *p;
149
150 assert(m);
151
152 l = strlen(s);
153 if (l > (size_t) (uint32_t) -1)
154 return -EINVAL;
155
156 /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
157 p = message_extend_fields(m, 8, 4 + 4 + l + 1);
158 if (!p)
159 return -ENOMEM;
160
161 p[0] = h;
162 p[1] = 1;
163 p[2] = type;
164 p[3] = 0;
165
166 ((uint32_t*) p)[1] = l;
167 memcpy(p + 8, s, l + 1);
168
169 if (ret)
170 *ret = (const char*) p + 8;
171
172 return 0;
173 }
174
175 static int message_append_field_signature(
176 sd_bus_message *m,
177 uint8_t h,
178 const char *s,
179 const char **ret) {
180
181 size_t l;
182 uint8_t *p;
183
184 assert(m);
185
186 l = strlen(s);
187 if (l > 255)
188 return -EINVAL;
189
190 /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
191 p = message_extend_fields(m, 8, 4 + 1 + l + 1);
192 if (!p)
193 return -ENOMEM;
194
195 p[0] = h;
196 p[1] = 1;
197 p[2] = SD_BUS_TYPE_SIGNATURE;
198 p[3] = 0;
199 p[4] = l;
200 memcpy(p + 5, s, l + 1);
201
202 if (ret)
203 *ret = (const char*) p + 5;
204
205 return 0;
206 }
207
208 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
209 uint8_t *p;
210
211 assert(m);
212
213 /* field id byte + signature length + signature 'u' + NUL + value */
214 p = message_extend_fields(m, 8, 4 + 4);
215 if (!p)
216 return -ENOMEM;
217
218 p[0] = h;
219 p[1] = 1;
220 p[2] = SD_BUS_TYPE_UINT32;
221 p[3] = 0;
222
223 ((uint32_t*) p)[1] = x;
224
225 return 0;
226 }
227
228 int bus_message_from_malloc(
229 void *buffer,
230 size_t length,
231 int *fds,
232 unsigned n_fds,
233 const struct ucred *ucred,
234 const char *label,
235 sd_bus_message **ret) {
236
237 sd_bus_message *m;
238 struct bus_header *h;
239 size_t total, fs, bs, label_sz, a;
240 int r;
241
242 assert(buffer || length <= 0);
243 assert(fds || n_fds <= 0);
244 assert(ret);
245
246 if (length < sizeof(struct bus_header))
247 return -EBADMSG;
248
249 h = buffer;
250 if (h->version != 1)
251 return -EBADMSG;
252
253 if (h->serial == 0)
254 return -EBADMSG;
255
256 if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
257 return -EBADMSG;
258
259 if (h->endian == SD_BUS_NATIVE_ENDIAN) {
260 fs = h->fields_size;
261 bs = h->body_size;
262 } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
263 fs = bswap_32(h->fields_size);
264 bs = bswap_32(h->body_size);
265 } else
266 return -EBADMSG;
267
268 total = sizeof(struct bus_header) + ALIGN_TO(fs, 8) + bs;
269 if (length != total)
270 return -EBADMSG;
271
272 if (label) {
273 label_sz = strlen(label);
274 a = ALIGN(sizeof(sd_bus_message)) + label_sz + 1;
275 } else
276 a = sizeof(sd_bus_message);
277
278 m = malloc0(a);
279 if (!m)
280 return -ENOMEM;
281
282 m->n_ref = 1;
283 m->sealed = true;
284 m->header = h;
285 m->fields = (uint8_t*) buffer + sizeof(struct bus_header);
286 m->body = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN_TO(fs, 8);
287 m->fds = fds;
288 m->n_fds = n_fds;
289
290 if (ucred) {
291 m->uid = ucred->uid;
292 m->pid = ucred->pid;
293 m->gid = ucred->gid;
294 m->uid_valid = m->gid_valid = true;
295 }
296
297 if (label) {
298 m->label = (char*) m + ALIGN(sizeof(sd_bus_message));
299 memcpy(m->label, label, label_sz + 1);
300 }
301
302 m->n_iovec = 1;
303 m->iovec[0].iov_base = buffer;
304 m->iovec[0].iov_len = length;
305 m->size = length;
306
307 r = message_parse_fields(m);
308 if (r < 0)
309 goto fail;
310
311 /* We take possession of the memory and fds now */
312 m->free_header = true;
313 m->free_fds = true;
314
315 *ret = m;
316 return 0;
317
318 fail:
319 message_free(m);
320 return r;
321 }
322
323 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
324 sd_bus_message *m;
325
326 m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
327 if (!m)
328 return NULL;
329
330 m->n_ref = 1;
331 m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
332 m->header->endian = SD_BUS_NATIVE_ENDIAN;
333 m->header->type = type;
334 m->header->version = bus ? bus->message_version : 1;
335 m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
336
337 return m;
338 }
339
340 int sd_bus_message_new_signal(
341 sd_bus *bus,
342 const char *path,
343 const char *interface,
344 const char *member,
345 sd_bus_message **m) {
346
347 sd_bus_message *t;
348 int r;
349
350 if (!path)
351 return -EINVAL;
352 if (!interface)
353 return -EINVAL;
354 if (!member)
355 return -EINVAL;
356 if (!m)
357 return -EINVAL;
358 if (bus && bus->state == BUS_UNSET)
359 return -ENOTCONN;
360
361 t = message_new(bus, SD_BUS_MESSAGE_TYPE_SIGNAL);
362 if (!t)
363 return -ENOMEM;
364
365 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
366
367 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
368 if (r < 0)
369 goto fail;
370 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
371 if (r < 0)
372 goto fail;
373 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
374 if (r < 0)
375 goto fail;
376
377 *m = t;
378 return 0;
379
380 fail:
381 sd_bus_message_unref(t);
382 return r;
383 }
384
385 int sd_bus_message_new_method_call(
386 sd_bus *bus,
387 const char *destination,
388 const char *path,
389 const char *interface,
390 const char *member,
391 sd_bus_message **m) {
392
393 sd_bus_message *t;
394 int r;
395
396 if (!path)
397 return -EINVAL;
398 if (!member)
399 return -EINVAL;
400 if (!m)
401 return -EINVAL;
402 if (bus && bus->state == BUS_UNSET)
403 return -ENOTCONN;
404
405 t = message_new(bus, SD_BUS_MESSAGE_TYPE_METHOD_CALL);
406 if (!t)
407 return -ENOMEM;
408
409 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
410 if (r < 0)
411 goto fail;
412 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
413 if (r < 0)
414 goto fail;
415
416 if (interface) {
417 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
418 if (r < 0)
419 goto fail;
420 }
421
422 if (destination) {
423 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
424 if (r < 0)
425 goto fail;
426 }
427
428 *m = t;
429 return 0;
430
431 fail:
432 message_free(t);
433 return r;
434 }
435
436 static int message_new_reply(
437 sd_bus *bus,
438 sd_bus_message *call,
439 uint8_t type,
440 sd_bus_message **m) {
441
442 sd_bus_message *t;
443 int r;
444
445 if (!call)
446 return -EINVAL;
447 if (!call->sealed)
448 return -EPERM;
449 if (call->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
450 return -EINVAL;
451 if (!m)
452 return -EINVAL;
453 if (bus && bus->state == BUS_UNSET)
454 return -ENOTCONN;
455
456 t = message_new(bus, type);
457 if (!t)
458 return -ENOMEM;
459
460 t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
461 t->reply_serial = BUS_MESSAGE_SERIAL(call);
462
463 r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
464 if (r < 0)
465 goto fail;
466
467 if (call->sender) {
468 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->sender);
469 if (r < 0)
470 goto fail;
471 }
472
473 t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
474
475 *m = t;
476 return 0;
477
478 fail:
479 message_free(t);
480 return r;
481 }
482
483 int sd_bus_message_new_method_return(
484 sd_bus *bus,
485 sd_bus_message *call,
486 sd_bus_message **m) {
487
488 return message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_RETURN, m);
489 }
490
491 int sd_bus_message_new_method_error(
492 sd_bus *bus,
493 sd_bus_message *call,
494 const sd_bus_error *e,
495 sd_bus_message **m) {
496
497 sd_bus_message *t;
498 int r;
499
500 if (!sd_bus_error_is_set(e))
501 return -EINVAL;
502 if (!m)
503 return -EINVAL;
504
505 r = message_new_reply(bus, call, SD_BUS_MESSAGE_TYPE_METHOD_ERROR, &t);
506 if (r < 0)
507 return r;
508
509 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
510 if (r < 0)
511 goto fail;
512
513 if (e->message) {
514 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
515 if (r < 0)
516 goto fail;
517 }
518
519 *m = t;
520 return 0;
521
522 fail:
523 message_free(t);
524 return r;
525 }
526
527 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
528 if (!m)
529 return NULL;
530
531 assert(m->n_ref > 0);
532 m->n_ref++;
533
534 return m;
535 }
536
537 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
538 if (!m)
539 return NULL;
540
541 assert(m->n_ref > 0);
542 m->n_ref--;
543
544 if (m->n_ref <= 0)
545 message_free(m);
546
547 return NULL;
548 }
549
550 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
551 if (!m)
552 return -EINVAL;
553 if (!type)
554 return -EINVAL;
555
556 *type = m->header->type;
557 return 0;
558 }
559
560 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
561 if (!m)
562 return -EINVAL;
563 if (!serial)
564 return -EINVAL;
565 if (m->header->serial == 0)
566 return -ENOENT;
567
568 *serial = BUS_MESSAGE_SERIAL(m);
569 return 0;
570 }
571
572 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
573 if (!m)
574 return -EINVAL;
575 if (!serial)
576 return -EINVAL;
577 if (m->reply_serial == 0)
578 return -ENOENT;
579
580 *serial = m->reply_serial;
581 return 0;
582 }
583
584 int sd_bus_message_get_no_reply(sd_bus_message *m) {
585 if (!m)
586 return -EINVAL;
587
588 return m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
589 }
590
591 const char *sd_bus_message_get_path(sd_bus_message *m) {
592 if (!m)
593 return NULL;
594
595 return m->path;
596 }
597
598 const char *sd_bus_message_get_interface(sd_bus_message *m) {
599 if (!m)
600 return NULL;
601
602 return m->interface;
603 }
604
605 const char *sd_bus_message_get_member(sd_bus_message *m) {
606 if (!m)
607 return NULL;
608
609 return m->member;
610 }
611 const char *sd_bus_message_get_destination(sd_bus_message *m) {
612 if (!m)
613 return NULL;
614
615 return m->destination;
616 }
617
618 const char *sd_bus_message_get_sender(sd_bus_message *m) {
619 if (!m)
620 return NULL;
621
622 return m->sender;
623 }
624
625 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
626 if (!m)
627 return NULL;
628
629 if (!sd_bus_error_is_set(&m->error))
630 return NULL;
631
632 return &m->error;
633 }
634
635 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
636 if (!m)
637 return -EINVAL;
638 if (!m->uid_valid)
639 return -ENOENT;
640
641 *uid = m->uid;
642 return 0;
643 }
644
645 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
646 if (!m)
647 return -EINVAL;
648 if (!m->gid_valid)
649 return -ENOENT;
650
651 *gid = m->gid;
652 return 0;
653 }
654
655 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
656 if (!m)
657 return -EINVAL;
658 if (m->pid <= 0)
659 return -ENOENT;
660
661 *pid = m->pid;
662 return 0;
663 }
664
665 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
666 if (!m)
667 return -EINVAL;
668 if (m->tid <= 0)
669 return -ENOENT;
670
671 *tid = m->tid;
672 return 0;
673 }
674
675 const char *sd_bus_message_get_label(sd_bus_message *m) {
676 if (!m)
677 return NULL;
678
679 return m->label;
680 }
681
682 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
683 if (!m)
684 return -EINVAL;
685
686 if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
687 return 0;
688
689 if (interface && (!m->interface || !streq(m->interface, interface)))
690 return 0;
691
692 if (member && (!m->member || !streq(m->member, member)))
693 return 0;
694
695 return 1;
696 }
697
698 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
699 if (!m)
700 return -EINVAL;
701
702 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
703 return 0;
704
705 if (interface && (!m->interface || !streq(m->interface, interface)))
706 return 0;
707
708 if (member && (!m->member || !streq(m->member, member)))
709 return 0;
710
711 return 1;
712 }
713
714 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
715 if (!m)
716 return -EINVAL;
717
718 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
719 return 0;
720
721 if (name && (!m->error.name || !streq(m->error.name, name)))
722 return 0;
723
724 return 1;
725 }
726
727 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
728 if (!m)
729 return -EINVAL;
730 if (m->sealed)
731 return -EPERM;
732 if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
733 return -EPERM;
734
735 if (b)
736 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
737 else
738 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
739
740 return 0;
741 }
742
743 static struct bus_container *message_get_container(sd_bus_message *m) {
744 assert(m);
745
746 if (m->n_containers == 0)
747 return &m->root_container;
748
749 assert(m->containers);
750 return m->containers + m->n_containers - 1;
751 }
752
753 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
754 void *p, *o;
755 size_t added;
756 struct bus_container *c;
757
758 assert(m);
759 assert(align > 0);
760
761 o = m->body;
762 added = m->header->body_size;
763
764 p = buffer_extend(&m->body, &m->header->body_size, align, sz);
765 if (!p)
766 return NULL;
767
768 added = m->header->body_size - added;
769
770 for (c = m->containers; c < m->containers + m->n_containers; c++)
771 if (c->array_size) {
772 c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
773 *c->array_size += added;
774 }
775
776 if (o != m->body) {
777 if (m->error.message)
778 m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
779 }
780
781 m->free_body = true;
782
783 return p;
784 }
785
786 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
787 struct bus_container *c;
788 ssize_t align, sz;
789 uint32_t k;
790 void *a;
791 char *e = NULL;
792 int fd = -1;
793 uint32_t fdi = 0;
794 int r;
795
796 if (!m)
797 return -EINVAL;
798 if (!p)
799 return -EINVAL;
800 if (m->sealed)
801 return -EPERM;
802 if (!bus_type_is_basic(type))
803 return -EINVAL;
804
805 c = message_get_container(m);
806
807 if (c->signature && c->signature[c->index]) {
808 /* Container signature is already set */
809
810 if (c->signature[c->index] != type)
811 return -ENXIO;
812 } else {
813 /* Maybe we can append to the signature? But only if this is the top-level container*/
814 if (c->enclosing != 0)
815 return -ENXIO;
816
817 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
818 if (!e)
819 return -ENOMEM;
820 }
821
822 switch (type) {
823
824 case SD_BUS_TYPE_STRING:
825 case SD_BUS_TYPE_OBJECT_PATH:
826
827 align = 4;
828 sz = 4 + strlen(p) + 1;
829 break;
830
831 case SD_BUS_TYPE_SIGNATURE:
832
833 align = 1;
834 sz = 1 + strlen(p) + 1;
835 break;
836
837 case SD_BUS_TYPE_BOOLEAN:
838 align = sz = 4;
839
840 assert_cc(sizeof(int) == sizeof(uint32_t));
841 memcpy(&k, p, 4);
842 k = !!k;
843 p = &k;
844 break;
845
846 case SD_BUS_TYPE_UNIX_FD: {
847 int z, *f;
848
849 if (!m->allow_fds) {
850 r = -ENOTSUP;
851 goto fail;
852 }
853
854 align = sz = 4;
855
856 z = *(int*) p;
857 if (z < 0) {
858 r = -EINVAL;
859 goto fail;
860 }
861
862 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
863 if (fd < 0) {
864 r = -errno;
865 goto fail;
866 }
867
868 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
869 if (!f) {
870 r = -ENOMEM;
871 goto fail;
872 }
873
874 fdi = m->n_fds;
875 f[fdi] = fd;
876 m->fds = f;
877 m->free_fds = true;
878 break;
879 }
880
881 default:
882 align = bus_type_get_alignment(type);
883 sz = bus_type_get_size(type);
884 break;
885 }
886
887 assert(align > 0);
888 assert(sz > 0);
889
890 a = message_extend_body(m, align, sz);
891 if (!a) {
892 r = -ENOMEM;
893 goto fail;
894 }
895
896 if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
897 *(uint32_t*) a = sz - 5;
898 memcpy((uint8_t*) a + 4, p, sz - 4);
899
900 if (stored)
901 *stored = (const uint8_t*) a + 4;
902
903 } else if (type == SD_BUS_TYPE_SIGNATURE) {
904 *(uint8_t*) a = sz - 1;
905 memcpy((uint8_t*) a + 1, p, sz - 1);
906
907 if (stored)
908 *stored = (const uint8_t*) a + 1;
909 } else if (type == SD_BUS_TYPE_UNIX_FD) {
910 *(uint32_t*) a = fdi;
911
912 if (stored)
913 *stored = a;
914
915 m->n_fds ++;
916
917 } else {
918 memcpy(a, p, sz);
919
920 if (stored)
921 *stored = a;
922 }
923
924 if (c->enclosing != SD_BUS_TYPE_ARRAY)
925 c->index++;
926
927 return 0;
928
929 fail:
930 /* Truncate extended signature again */
931 if (e)
932 c->signature[c->index] = 0;
933
934 if (fd >= 0)
935 close_nointr_nofail(fd);
936
937 return r;
938 }
939
940 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
941 return message_append_basic(m, type, p, NULL);
942 }
943
944 static int bus_message_open_array(
945 sd_bus_message *m,
946 struct bus_container *c,
947 const char *contents,
948 uint32_t **array_size) {
949
950 unsigned nindex;
951 char *e = NULL;
952 void *a, *b;
953 int alignment;
954 size_t saved;
955
956 assert(m);
957 assert(c);
958 assert(contents);
959 assert(array_size);
960
961 if (!signature_is_single(contents))
962 return -EINVAL;
963
964 alignment = bus_type_get_alignment(contents[0]);
965 if (alignment < 0)
966 return alignment;
967
968 if (c->signature && c->signature[c->index]) {
969
970 /* Verify the existing signature */
971
972 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
973 return -ENXIO;
974
975 if (!startswith(c->signature + c->index + 1, contents))
976 return -ENXIO;
977
978 nindex = c->index + 1 + strlen(contents);
979 } else {
980 if (c->enclosing != 0)
981 return -ENXIO;
982
983 /* Extend the existing signature */
984
985 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
986 if (!e)
987 return -ENOMEM;
988
989 nindex = e - c->signature;
990 }
991
992 saved = m->header->body_size;
993 a = message_extend_body(m, 4, 4);
994 if (!a) {
995 /* Truncate extended signature again */
996 if (e)
997 c->signature[c->index] = 0;
998
999 return -ENOMEM;
1000 }
1001 b = m->body;
1002
1003 if (!message_extend_body(m, alignment, 0)) {
1004 /* Add alignment between size and first element */
1005 if (e)
1006 c->signature[c->index] = 0;
1007
1008 m->header->body_size = saved;
1009 return -ENOMEM;
1010 }
1011
1012 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1013 c->index = nindex;
1014
1015 /* m->body might have changed so let's readjust a */
1016 a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1017 *(uint32_t*) a = 0;
1018
1019 *array_size = a;
1020 return 0;
1021 }
1022
1023 static int bus_message_open_variant(
1024 sd_bus_message *m,
1025 struct bus_container *c,
1026 const char *contents) {
1027
1028 char *e = NULL;
1029 size_t l;
1030 void *a;
1031
1032 assert(m);
1033 assert(c);
1034 assert(contents);
1035
1036 if (!signature_is_single(contents))
1037 return -EINVAL;
1038
1039 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1040 return -EINVAL;
1041
1042 if (c->signature && c->signature[c->index]) {
1043
1044 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1045 return -ENXIO;
1046
1047 } else {
1048 if (c->enclosing != 0)
1049 return -ENXIO;
1050
1051 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1052 if (!e)
1053 return -ENOMEM;
1054 }
1055
1056 l = strlen(contents);
1057 a = message_extend_body(m, 1, 1 + l + 1);
1058 if (!a) {
1059 /* Truncate extended signature again */
1060 if (e)
1061 c->signature[c->index] = 0;
1062
1063 return -ENOMEM;
1064 }
1065
1066 *(uint8_t*) a = l;
1067 memcpy((uint8_t*) a + 1, contents, l + 1);
1068
1069 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1070 c->index++;
1071
1072 return 0;
1073 }
1074
1075 static int bus_message_open_struct(
1076 sd_bus_message *m,
1077 struct bus_container *c,
1078 const char *contents) {
1079
1080 size_t nindex;
1081 char *e = NULL;
1082
1083 assert(m);
1084 assert(c);
1085 assert(contents);
1086
1087 if (!signature_is_valid(contents, false))
1088 return -EINVAL;
1089
1090 if (c->signature && c->signature[c->index]) {
1091 size_t l;
1092
1093 l = strlen(contents);
1094
1095 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1096 !startswith(c->signature + c->index + 1, contents) ||
1097 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1098 return -ENXIO;
1099
1100 nindex = c->index + 1 + l + 1;
1101 } else {
1102 if (c->enclosing != 0)
1103 return -ENXIO;
1104
1105 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1106 if (!e)
1107 return -ENOMEM;
1108
1109 nindex = e - c->signature;
1110 }
1111
1112 /* Align contents to 8 byte boundary */
1113 if (!message_extend_body(m, 8, 0)) {
1114 if (e)
1115 c->signature[c->index] = 0;
1116
1117 return -ENOMEM;
1118 }
1119
1120 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1121 c->index = nindex;
1122
1123 return 0;
1124 }
1125
1126 static int bus_message_open_dict_entry(
1127 sd_bus_message *m,
1128 struct bus_container *c,
1129 const char *contents) {
1130
1131 size_t nindex;
1132
1133 assert(m);
1134 assert(c);
1135 assert(contents);
1136
1137 if (!signature_is_pair(contents))
1138 return -EINVAL;
1139
1140 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1141 return -ENXIO;
1142
1143 if (c->signature && c->signature[c->index]) {
1144 size_t l;
1145
1146 l = strlen(contents);
1147
1148 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1149 !startswith(c->signature + c->index + 1, contents) ||
1150 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1151 return -ENXIO;
1152
1153 nindex = c->index + 1 + l + 1;
1154 } else
1155 return -ENXIO;
1156
1157 /* Align contents to 8 byte boundary */
1158 if (!message_extend_body(m, 8, 0))
1159 return -ENOMEM;
1160
1161 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1162 c->index = nindex;
1163
1164 return 0;
1165 }
1166
1167 int sd_bus_message_open_container(
1168 sd_bus_message *m,
1169 char type,
1170 const char *contents) {
1171
1172 struct bus_container *c, *w;
1173 uint32_t *array_size = NULL;
1174 char *signature;
1175 int r;
1176
1177 if (!m)
1178 return -EINVAL;
1179 if (m->sealed)
1180 return -EPERM;
1181 if (!contents)
1182 return -EINVAL;
1183
1184 /* Make sure we have space for one more container */
1185 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1186 if (!w)
1187 return -ENOMEM;
1188 m->containers = w;
1189
1190 c = message_get_container(m);
1191
1192 signature = strdup(contents);
1193 if (!signature)
1194 return -ENOMEM;
1195
1196 if (type == SD_BUS_TYPE_ARRAY)
1197 r = bus_message_open_array(m, c, contents, &array_size);
1198 else if (type == SD_BUS_TYPE_VARIANT)
1199 r = bus_message_open_variant(m, c, contents);
1200 else if (type == SD_BUS_TYPE_STRUCT)
1201 r = bus_message_open_struct(m, c, contents);
1202 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1203 r = bus_message_open_dict_entry(m, c, contents);
1204 else
1205 r = -EINVAL;
1206
1207 if (r < 0) {
1208 free(signature);
1209 return r;
1210 }
1211
1212 /* OK, let's fill it in */
1213 w += m->n_containers++;
1214 w->enclosing = type;
1215 w->signature = signature;
1216 w->index = 0;
1217 w->array_size = array_size;
1218 w->begin = 0;
1219
1220 return 0;
1221 }
1222
1223 int sd_bus_message_close_container(sd_bus_message *m) {
1224 struct bus_container *c;
1225
1226 if (!m)
1227 return -EINVAL;
1228 if (m->sealed)
1229 return -EPERM;
1230 if (m->n_containers <= 0)
1231 return -EINVAL;
1232
1233 c = message_get_container(m);
1234 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1235 if (c->signature && c->signature[c->index] != 0)
1236 return -EINVAL;
1237
1238 free(c->signature);
1239 m->n_containers--;
1240
1241 return 0;
1242 }
1243
1244 int bus_message_append_ap(
1245 sd_bus_message *m,
1246 const char *types,
1247 va_list ap) {
1248
1249 const char *t;
1250 int r;
1251
1252 assert(m);
1253
1254 if (!types)
1255 return 0;
1256
1257 for (t = types; *t; t++) {
1258 switch (*t) {
1259
1260 case SD_BUS_TYPE_BYTE: {
1261 uint8_t x;
1262
1263 x = (uint8_t) va_arg(ap, int);
1264 r = sd_bus_message_append_basic(m, *t, &x);
1265 break;
1266 }
1267
1268 case SD_BUS_TYPE_BOOLEAN:
1269 case SD_BUS_TYPE_INT32:
1270 case SD_BUS_TYPE_UINT32:
1271 case SD_BUS_TYPE_UNIX_FD: {
1272 uint32_t x;
1273
1274 /* We assume a boolean is the same as int32_t */
1275 assert_cc(sizeof(int32_t) == sizeof(int));
1276
1277 x = va_arg(ap, uint32_t);
1278 r = sd_bus_message_append_basic(m, *t, &x);
1279 break;
1280 }
1281
1282 case SD_BUS_TYPE_INT16:
1283 case SD_BUS_TYPE_UINT16: {
1284 uint16_t x;
1285
1286 x = (uint16_t) va_arg(ap, int);
1287 r = sd_bus_message_append_basic(m, *t, &x);
1288 break;
1289 }
1290
1291 case SD_BUS_TYPE_INT64:
1292 case SD_BUS_TYPE_UINT64:
1293 case SD_BUS_TYPE_DOUBLE: {
1294 uint64_t x;
1295
1296 x = va_arg(ap, uint64_t);
1297 r = sd_bus_message_append_basic(m, *t, &x);
1298 break;
1299 }
1300
1301 case SD_BUS_TYPE_STRING:
1302 case SD_BUS_TYPE_OBJECT_PATH:
1303 case SD_BUS_TYPE_SIGNATURE: {
1304 const char *x;
1305
1306 x = va_arg(ap, const char*);
1307 r = sd_bus_message_append_basic(m, *t, x);
1308 break;
1309 }
1310
1311 case SD_BUS_TYPE_ARRAY: {
1312 size_t k;
1313
1314 r = signature_element_length(t + 1, &k);
1315 if (r < 0)
1316 return r;
1317
1318 {
1319 unsigned i, n;
1320 char s[k + 1];
1321
1322 memcpy(s, t + 1, k);
1323 s[k] = 0;
1324 t += k;
1325
1326 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1327 if (r < 0)
1328 return r;
1329
1330 n = va_arg(ap, unsigned);
1331 for (i = 0; i < n; i++) {
1332 r = bus_message_append_ap(m, s, ap);
1333 if (r < 0)
1334 return r;
1335 }
1336
1337 r = sd_bus_message_close_container(m);
1338 }
1339
1340 break;
1341 }
1342
1343 case SD_BUS_TYPE_VARIANT: {
1344 const char *s;
1345
1346 s = va_arg(ap, const char*);
1347 if (!s)
1348 return -EINVAL;
1349
1350 r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1351 if (r < 0)
1352 return r;
1353
1354 r = bus_message_append_ap(m, s, ap);
1355 if (r < 0)
1356 return r;
1357
1358 r = sd_bus_message_close_container(m);
1359 break;
1360 }
1361
1362 case SD_BUS_TYPE_STRUCT_BEGIN:
1363 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1364 size_t k;
1365
1366 r = signature_element_length(t, &k);
1367 if (r < 0)
1368 return r;
1369
1370 {
1371 char s[k - 1];
1372
1373 memcpy(s, t + 1, k - 2);
1374 s[k - 2] = 0;
1375
1376 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1377 if (r < 0)
1378 return r;
1379
1380 t += k - 1;
1381
1382 r = bus_message_append_ap(m, s, ap);
1383 if (r < 0)
1384 return r;
1385
1386 r = sd_bus_message_close_container(m);
1387 }
1388
1389 break;
1390 }
1391
1392 default:
1393 r = -EINVAL;
1394 }
1395
1396 if (r < 0)
1397 return r;
1398 }
1399
1400 return 0;
1401 }
1402
1403 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1404 va_list ap;
1405 int r;
1406
1407 if (!m)
1408 return -EINVAL;
1409 if (m->sealed)
1410 return -EPERM;
1411 if (!types)
1412 return 0;
1413
1414 va_start(ap, types);
1415 r = bus_message_append_ap(m, types, ap);
1416 va_end(ap);
1417
1418 return r;
1419 }
1420
1421 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1422 size_t k, start, n;
1423
1424 assert(rindex);
1425 assert(align > 0);
1426
1427 start = ALIGN_TO((size_t) *rindex, align);
1428 n = start + nbytes;
1429
1430 if (n > sz)
1431 return -EBADMSG;
1432
1433 /* Verify that padding is 0 */
1434 for (k = *rindex; k < start; k++)
1435 if (((const uint8_t*) p)[k] != 0)
1436 return -EBADMSG;
1437
1438 if (r)
1439 *r = (uint8_t*) p + start;
1440
1441 *rindex = n;
1442
1443 return 1;
1444 }
1445
1446 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1447 struct bus_container *c;
1448
1449 assert(m);
1450
1451 c = message_get_container(m);
1452 if (!c->array_size)
1453 return false;
1454
1455 return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1456 }
1457
1458 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1459 assert(m);
1460 assert(rindex);
1461 assert(align > 0);
1462
1463 if (message_end_of_array(m, *rindex))
1464 return 0;
1465
1466 return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1467 }
1468
1469 static bool validate_nul(const char *s, size_t l) {
1470
1471 /* Check for NUL chars in the string */
1472 if (memchr(s, 0, l))
1473 return false;
1474
1475 /* Check for NUL termination */
1476 if (s[l] != 0)
1477 return false;
1478
1479 return true;
1480 }
1481
1482 static bool validate_string(const char *s, size_t l) {
1483
1484 if (!validate_nul(s, l))
1485 return false;
1486
1487 /* Check if valid UTF8 */
1488 if (!utf8_is_valid(s))
1489 return false;
1490
1491 return true;
1492 }
1493
1494 static bool validate_signature(const char *s, size_t l) {
1495
1496 if (!validate_nul(s, l))
1497 return false;
1498
1499 /* Check if valid signature */
1500 if (!signature_is_valid(s, true))
1501 return false;
1502
1503 return true;
1504 }
1505
1506 static bool validate_object_path(const char *s, size_t l) {
1507
1508 if (!validate_nul(s, l))
1509 return false;
1510
1511 if (!object_path_is_valid(s))
1512 return false;
1513
1514 return true;
1515 }
1516
1517 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1518 struct bus_container *c;
1519 int r;
1520 void *q;
1521
1522 if (!m)
1523 return -EINVAL;
1524 if (!m->sealed)
1525 return -EPERM;
1526 if (!bus_type_is_basic(type))
1527 return -EINVAL;
1528 if (!p)
1529 return -EINVAL;
1530
1531 c = message_get_container(m);
1532
1533 if (!c->signature || c->signature[c->index] == 0)
1534 return 0;
1535
1536 if (c->signature[c->index] != type)
1537 return -ENXIO;
1538
1539 switch (type) {
1540
1541 case SD_BUS_TYPE_STRING:
1542 case SD_BUS_TYPE_OBJECT_PATH: {
1543 uint32_t l;
1544 size_t rindex;
1545
1546 rindex = m->rindex;
1547 r = message_peek_body(m, &rindex, 4, 4, &q);
1548 if (r <= 0)
1549 return r;
1550
1551 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1552 r = message_peek_body(m, &rindex, 1, l+1, &q);
1553 if (r < 0)
1554 return r;
1555 if (r == 0)
1556 return -EBADMSG;
1557
1558 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1559 if (!validate_object_path(q, l))
1560 return -EBADMSG;
1561 } else {
1562 if (!validate_string(q, l))
1563 return -EBADMSG;
1564 }
1565
1566 m->rindex = rindex;
1567 *(const char**) p = q;
1568 break;
1569 }
1570
1571 case SD_BUS_TYPE_SIGNATURE: {
1572 uint8_t l;
1573 size_t rindex;
1574
1575 rindex = m->rindex;
1576 r = message_peek_body(m, &rindex, 1, 1, &q);
1577 if (r <= 0)
1578 return r;
1579
1580 l = *(uint8_t*) q;
1581 r = message_peek_body(m, &rindex, 1, l+1, &q);
1582 if (r < 0)
1583 return r;
1584 if (r == 0)
1585 return -EBADMSG;
1586
1587 if (!validate_signature(q, l))
1588 return -EBADMSG;
1589
1590 m->rindex = rindex;
1591 *(const char**) p = q;
1592 break;
1593 }
1594
1595 default: {
1596 ssize_t sz, align;
1597 size_t rindex;
1598
1599 align = bus_type_get_alignment(type);
1600 sz = bus_type_get_size(type);
1601 assert(align > 0 && sz > 0);
1602
1603 rindex = m->rindex;
1604 r = message_peek_body(m, &rindex, align, sz, &q);
1605 if (r <= 0)
1606 return r;
1607
1608 switch (type) {
1609
1610 case SD_BUS_TYPE_BYTE:
1611 *(uint8_t*) p = *(uint8_t*) q;
1612 break;
1613
1614 case SD_BUS_TYPE_BOOLEAN:
1615 *(int*) p = !!*(uint32_t*) q;
1616 break;
1617
1618 case SD_BUS_TYPE_INT16:
1619 case SD_BUS_TYPE_UINT16:
1620 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1621 break;
1622
1623 case SD_BUS_TYPE_INT32:
1624 case SD_BUS_TYPE_UINT32:
1625 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1626 break;
1627
1628 case SD_BUS_TYPE_INT64:
1629 case SD_BUS_TYPE_UINT64:
1630 case SD_BUS_TYPE_DOUBLE:
1631 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1632 break;
1633
1634 case SD_BUS_TYPE_UNIX_FD: {
1635 int copy;
1636 uint32_t j;
1637
1638 j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1639 if (j >= m->n_fds)
1640 return -EBADMSG;
1641
1642 copy = fcntl(m->fds[j], F_DUPFD_CLOEXEC, 3);
1643 if (copy < 0)
1644 return -errno;
1645
1646 *(int*) p = copy;
1647 break;
1648 }
1649
1650 default:
1651 assert_not_reached("Unknown basic type...");
1652 }
1653
1654 m->rindex = rindex;
1655
1656 break;
1657 }
1658 }
1659
1660 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1661 c->index++;
1662
1663 return 1;
1664 }
1665
1666 static int bus_message_enter_array(
1667 sd_bus_message *m,
1668 struct bus_container *c,
1669 const char *contents,
1670 uint32_t **array_size) {
1671
1672 size_t rindex;
1673 void *q;
1674 int r, alignment;
1675
1676 assert(m);
1677 assert(c);
1678 assert(contents);
1679 assert(array_size);
1680
1681 if (!signature_is_single(contents))
1682 return -EINVAL;
1683
1684 alignment = bus_type_get_alignment(contents[0]);
1685 if (alignment < 0)
1686 return alignment;
1687
1688 if (!c->signature || c->signature[c->index] == 0)
1689 return 0;
1690
1691 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1692 return -ENXIO;
1693
1694 if (!startswith(c->signature + c->index + 1, contents))
1695 return -ENXIO;
1696
1697 rindex = m->rindex;
1698 r = message_peek_body(m, &rindex, 4, 4, &q);
1699 if (r <= 0)
1700 return r;
1701
1702 if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1703 return -EBADMSG;
1704
1705 r = message_peek_body(m, &rindex, alignment, 0, NULL);
1706 if (r < 0)
1707 return r;
1708 if (r == 0)
1709 return -EBADMSG;
1710
1711 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1712 c->index += 1 + strlen(contents);
1713
1714 m->rindex = rindex;
1715
1716 *array_size = (uint32_t*) q;
1717
1718 return 1;
1719 }
1720
1721 static int bus_message_enter_variant(
1722 sd_bus_message *m,
1723 struct bus_container *c,
1724 const char *contents) {
1725
1726 size_t rindex;
1727 uint8_t l;
1728 void *q;
1729 int r;
1730
1731 assert(m);
1732 assert(c);
1733 assert(contents);
1734
1735 if (!signature_is_single(contents))
1736 return -EINVAL;
1737
1738 if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1739 return -EINVAL;
1740
1741 if (!c->signature || c->signature[c->index] == 0)
1742 return 0;
1743
1744 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1745 return -ENXIO;
1746
1747 rindex = m->rindex;
1748 r = message_peek_body(m, &rindex, 1, 1, &q);
1749 if (r <= 0)
1750 return r;
1751
1752 l = *(uint8_t*) q;
1753 r = message_peek_body(m, &rindex, 1, l+1, &q);
1754 if (r < 0)
1755 return r;
1756 if (r == 0)
1757 return -EBADMSG;
1758
1759 if (!validate_signature(q, l))
1760 return -EBADMSG;
1761
1762 if (!streq(q, contents))
1763 return -ENXIO;
1764
1765 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1766 c->index++;
1767
1768 m->rindex = rindex;
1769
1770 return 1;
1771 }
1772
1773 static int bus_message_enter_struct(
1774 sd_bus_message *m,
1775 struct bus_container *c,
1776 const char *contents) {
1777
1778 size_t l;
1779 int r;
1780
1781 assert(m);
1782 assert(c);
1783 assert(contents);
1784
1785 if (!signature_is_valid(contents, false))
1786 return -EINVAL;
1787
1788 if (!c->signature || c->signature[c->index] == 0)
1789 return 0;
1790
1791 l = strlen(contents);
1792
1793 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1794 !startswith(c->signature + c->index + 1, contents) ||
1795 c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1796 return -ENXIO;
1797
1798 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1799 if (r <= 0)
1800 return r;
1801
1802 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1803 c->index += 1 + l + 1;
1804
1805 return 1;
1806 }
1807
1808 static int bus_message_enter_dict_entry(
1809 sd_bus_message *m,
1810 struct bus_container *c,
1811 const char *contents) {
1812
1813 size_t l;
1814 int r;
1815
1816 assert(m);
1817 assert(c);
1818 assert(contents);
1819
1820 if (!signature_is_pair(contents))
1821 return -EINVAL;
1822
1823 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1824 return -ENXIO;
1825
1826 if (!c->signature || c->signature[c->index] == 0)
1827 return 0;
1828
1829 l = strlen(contents);
1830
1831 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1832 !startswith(c->signature + c->index + 1, contents) ||
1833 c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1834 return -ENXIO;
1835
1836 r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1837 if (r <= 0)
1838 return r;
1839
1840 if (c->enclosing != SD_BUS_TYPE_ARRAY)
1841 c->index += 1 + l + 1;
1842
1843 return 1;
1844 }
1845
1846 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1847 struct bus_container *c, *w;
1848 uint32_t *array_size = NULL;
1849 char *signature;
1850 int r;
1851
1852 if (!m)
1853 return -EINVAL;
1854 if (!m->sealed)
1855 return -EPERM;
1856 if (!contents)
1857 return -EINVAL;
1858
1859 /*
1860 * We enforce a global limit on container depth, that is much
1861 * higher than the 32 structs and 32 arrays the specification
1862 * mandates. This is simpler to implement for us, and we need
1863 * this only to ensure our container array doesn't grow
1864 * without bounds. We are happy to return any data from a
1865 * message as long as the data itself is valid, even if the
1866 * overall message might be not.
1867 *
1868 * Note that the message signature is validated when
1869 * parsing the headers, and that validation does check the
1870 * 32/32 limit.
1871 *
1872 * Note that the specification defines no limits on the depth
1873 * of stacked variants, but we do.
1874 */
1875 if (m->n_containers >= BUS_CONTAINER_DEPTH)
1876 return -EBADMSG;
1877
1878 w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1879 if (!w)
1880 return -ENOMEM;
1881 m->containers = w;
1882
1883 c = message_get_container(m);
1884
1885 if (!c->signature || c->signature[c->index] == 0)
1886 return 0;
1887
1888 signature = strdup(contents);
1889 if (!signature)
1890 return -ENOMEM;
1891
1892 if (type == SD_BUS_TYPE_ARRAY)
1893 r = bus_message_enter_array(m, c, contents, &array_size);
1894 else if (type == SD_BUS_TYPE_VARIANT)
1895 r = bus_message_enter_variant(m, c, contents);
1896 else if (type == SD_BUS_TYPE_STRUCT)
1897 r = bus_message_enter_struct(m, c, contents);
1898 else if (type == SD_BUS_TYPE_DICT_ENTRY)
1899 r = bus_message_enter_dict_entry(m, c, contents);
1900 else
1901 r = -EINVAL;
1902
1903 if (r <= 0) {
1904 free(signature);
1905 return r;
1906 }
1907
1908 /* OK, let's fill it in */
1909 w += m->n_containers++;
1910 w->enclosing = type;
1911 w->signature = signature;
1912 w->index = 0;
1913 w->array_size = array_size;
1914 w->begin = m->rindex;
1915
1916 return 1;
1917 }
1918
1919 int sd_bus_message_exit_container(sd_bus_message *m) {
1920 struct bus_container *c;
1921
1922 if (!m)
1923 return -EINVAL;
1924 if (!m->sealed)
1925 return -EPERM;
1926 if (m->n_containers <= 0)
1927 return -EINVAL;
1928
1929 c = message_get_container(m);
1930 if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1931 uint32_t l;
1932
1933 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1934 if (c->begin + l != m->rindex)
1935 return -EBUSY;
1936
1937 } else {
1938 if (c->signature && c->signature[c->index] != 0)
1939 return -EINVAL;
1940 }
1941
1942 free(c->signature);
1943 m->n_containers--;
1944
1945 return 1;
1946 }
1947
1948 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1949 struct bus_container *c;
1950 int r;
1951
1952 if (!m)
1953 return -EINVAL;
1954 if (!m->sealed)
1955 return -EPERM;
1956
1957 c = message_get_container(m);
1958
1959 if (!c->signature || c->signature[c->index] == 0)
1960 goto eof;
1961
1962 if (message_end_of_array(m, m->rindex))
1963 goto eof;
1964
1965 if (bus_type_is_basic(c->signature[c->index])) {
1966 if (contents)
1967 *contents = NULL;
1968 if (type)
1969 *type = c->signature[c->index];
1970 return 1;
1971 }
1972
1973 if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1974
1975 if (contents) {
1976 size_t l;
1977 char *sig;
1978
1979 r = signature_element_length(c->signature+c->index+1, &l);
1980 if (r < 0)
1981 return r;
1982
1983 assert(l >= 1);
1984
1985 sig = strndup(c->signature + c->index + 1, l);
1986 if (!sig)
1987 return -ENOMEM;
1988
1989 free(m->peeked_signature);
1990 m->peeked_signature = sig;
1991
1992 *contents = sig;
1993 }
1994
1995 if (type)
1996 *type = SD_BUS_TYPE_ARRAY;
1997
1998 return 1;
1999 }
2000
2001 if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2002 c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2003
2004 if (contents) {
2005 size_t l;
2006 char *sig;
2007
2008 r = signature_element_length(c->signature+c->index, &l);
2009 if (r < 0)
2010 return r;
2011
2012 assert(l >= 2);
2013 sig = strndup(c->signature + c->index + 1, l - 2);
2014 if (!sig)
2015 return -ENOMEM;
2016
2017 free(m->peeked_signature);
2018 m->peeked_signature = sig;
2019
2020 *contents = sig;
2021 }
2022
2023 if (type)
2024 *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2025
2026 return 1;
2027 }
2028
2029 if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2030 if (contents) {
2031 size_t rindex, l;
2032 void *q;
2033
2034 rindex = m->rindex;
2035 r = message_peek_body(m, &rindex, 1, 1, &q);
2036 if (r < 0)
2037 return r;
2038 if (r == 0)
2039 goto eof;
2040
2041 l = *(uint8_t*) q;
2042 r = message_peek_body(m, &rindex, 1, l+1, &q);
2043 if (r < 0)
2044 return r;
2045 if (r == 0)
2046 return -EBADMSG;
2047
2048 if (!validate_signature(q, l))
2049 return -EBADMSG;
2050
2051 *contents = q;
2052 }
2053
2054 if (type)
2055 *type = SD_BUS_TYPE_VARIANT;
2056
2057 return 1;
2058 }
2059
2060 return -EINVAL;
2061
2062 eof:
2063 if (type)
2064 *type = c->enclosing;
2065 if (contents)
2066 *contents = NULL;
2067 return 0;
2068 }
2069
2070 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2071 struct bus_container *c;
2072
2073 if (!m)
2074 return -EINVAL;
2075 if (!m->sealed)
2076 return -EPERM;
2077
2078 if (complete) {
2079 reset_containers(m);
2080 m->rindex = 0;
2081 m->root_container.index = 0;
2082
2083 c = message_get_container(m);
2084 } else {
2085 c = message_get_container(m);
2086
2087 c->index = 0;
2088 m->rindex = c->begin;
2089 }
2090
2091 return !isempty(c->signature);
2092 }
2093
2094 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
2095 const char *t;
2096 int r;
2097
2098 assert(m);
2099 assert(types);
2100
2101 for (t = types; *t; t++) {
2102 switch (*t) {
2103
2104 case SD_BUS_TYPE_BYTE:
2105 case SD_BUS_TYPE_BOOLEAN:
2106 case SD_BUS_TYPE_INT16:
2107 case SD_BUS_TYPE_UINT16:
2108 case SD_BUS_TYPE_INT32:
2109 case SD_BUS_TYPE_UINT32:
2110 case SD_BUS_TYPE_INT64:
2111 case SD_BUS_TYPE_UINT64:
2112 case SD_BUS_TYPE_DOUBLE:
2113 case SD_BUS_TYPE_STRING:
2114 case SD_BUS_TYPE_OBJECT_PATH:
2115 case SD_BUS_TYPE_SIGNATURE:
2116 case SD_BUS_TYPE_UNIX_FD: {
2117 void *p;
2118
2119 p = va_arg(ap, void*);
2120 r = sd_bus_message_read_basic(m, *t, p);
2121 break;
2122 }
2123
2124 case SD_BUS_TYPE_ARRAY: {
2125 size_t k;
2126
2127 r = signature_element_length(t + 1, &k);
2128 if (r < 0)
2129 return r;
2130
2131 {
2132 unsigned i, n;
2133 char s[k + 1];
2134
2135 memcpy(s, t + 1, k);
2136 s[k] = 0;
2137 t += k;
2138
2139 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2140 if (r < 0)
2141 return r;
2142 if (r == 0)
2143 return -ENXIO;
2144
2145 n = va_arg(ap, unsigned);
2146 for (i = 0; i < n; i++) {
2147 r = message_read_ap(m, s, ap);
2148 if (r < 0)
2149 return r;
2150 }
2151
2152 r = sd_bus_message_exit_container(m);
2153 }
2154
2155 break;
2156 }
2157
2158 case SD_BUS_TYPE_VARIANT: {
2159 const char *s;
2160
2161 s = va_arg(ap, const char *);
2162 if (!s)
2163 return -EINVAL;
2164
2165 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2166 if (r < 0)
2167 return r;
2168 if (r == 0)
2169 return -ENXIO;
2170
2171 r = message_read_ap(m, s, ap);
2172 if (r < 0)
2173 return r;
2174 if (r == 0)
2175 return -ENXIO;
2176
2177 r = sd_bus_message_exit_container(m);
2178 break;
2179 }
2180
2181 case SD_BUS_TYPE_STRUCT_BEGIN:
2182 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2183 size_t k;
2184
2185 r = signature_element_length(t, &k);
2186 if (r < 0)
2187 return r;
2188
2189 {
2190 char s[k - 1];
2191 memcpy(s, t + 1, k - 2);
2192 s[k - 2] = 0;
2193
2194 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2195 if (r < 0)
2196 return r;
2197 if (r == 0)
2198 return -ENXIO;
2199
2200 t += k - 1;
2201
2202 r = message_read_ap(m, s, ap);
2203 if (r < 0)
2204 return r;
2205 if (r == 0)
2206 return -ENXIO;
2207
2208 r = sd_bus_message_exit_container(m);
2209 }
2210
2211 break;
2212 }
2213
2214 default:
2215 r = -EINVAL;
2216 }
2217
2218 if (r < 0)
2219 return r;
2220 if (r == 0)
2221 return -ENXIO;
2222 }
2223
2224 return 1;
2225 }
2226
2227 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2228 va_list ap;
2229 int r;
2230
2231 if (!m)
2232 return -EINVAL;
2233 if (!m->sealed)
2234 return -EPERM;
2235 if (!types)
2236 return -EINVAL;
2237
2238 va_start(ap, types);
2239 r = message_read_ap(m, types, ap);
2240 va_end(ap);
2241
2242 return r;
2243 }
2244
2245 static int message_peek_fields(
2246 sd_bus_message *m,
2247 size_t *rindex,
2248 size_t align,
2249 size_t nbytes,
2250 void **ret) {
2251
2252 assert(m);
2253 assert(rindex);
2254 assert(align > 0);
2255
2256 return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2257 }
2258
2259 static int message_peek_field_uint32(
2260 sd_bus_message *m,
2261 size_t *ri,
2262 uint32_t *ret) {
2263
2264 int r;
2265 void *q;
2266
2267 assert(m);
2268 assert(ri);
2269
2270 r = message_peek_fields(m, ri, 4, 4, &q);
2271 if (r < 0)
2272 return r;
2273
2274 if (ret)
2275 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2276
2277 return 0;
2278 }
2279
2280 static int message_peek_field_string(
2281 sd_bus_message *m,
2282 bool (*validate)(const char *p),
2283 size_t *ri,
2284 const char **ret) {
2285
2286 uint32_t l;
2287 int r;
2288 void *q;
2289
2290 assert(m);
2291 assert(ri);
2292
2293 r = message_peek_field_uint32(m, ri, &l);
2294 if (r < 0)
2295 return r;
2296
2297 r = message_peek_fields(m, ri, 1, l+1, &q);
2298 if (r < 0)
2299 return r;
2300
2301 if (validate) {
2302 if (!validate_nul(q, l))
2303 return -EBADMSG;
2304
2305 if (!validate(q))
2306 return -EBADMSG;
2307 } else {
2308 if (!validate_string(q, l))
2309 return -EBADMSG;
2310 }
2311
2312 if (ret)
2313 *ret = q;
2314
2315 return 0;
2316 }
2317
2318 static int message_peek_field_signature(
2319 sd_bus_message *m,
2320 size_t *ri,
2321 const char **ret) {
2322
2323 size_t l;
2324 int r;
2325 void *q;
2326
2327 assert(m);
2328 assert(ri);
2329
2330 r = message_peek_fields(m, ri, 1, 1, &q);
2331 if (r < 0)
2332 return r;
2333
2334 l = *(uint8_t*) q;
2335 r = message_peek_fields(m, ri, 1, l+1, &q);
2336 if (r < 0)
2337 return r;
2338
2339 if (!validate_signature(q, l))
2340 return -EBADMSG;
2341
2342 if (ret)
2343 *ret = q;
2344
2345 return 0;
2346 }
2347
2348 static int message_skip_fields(
2349 sd_bus_message *m,
2350 size_t *ri,
2351 uint32_t array_size,
2352 const char **signature) {
2353
2354 size_t original_index;
2355 int r;
2356
2357 assert(m);
2358 assert(ri);
2359 assert(signature);
2360
2361 original_index = *ri;
2362
2363 for (;;) {
2364 char t;
2365 size_t l;
2366
2367 if (array_size != (uint32_t) -1 &&
2368 array_size <= *ri - original_index)
2369 return 0;
2370
2371 t = **signature;
2372 if (!t)
2373 return 0;
2374
2375 if (t == SD_BUS_TYPE_STRING) {
2376
2377 r = message_peek_field_string(m, NULL, ri, NULL);
2378 if (r < 0)
2379 return r;
2380
2381 (*signature)++;
2382
2383 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2384
2385 r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2386 if (r < 0)
2387 return r;
2388
2389 (*signature)++;
2390
2391 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2392
2393 r = message_peek_field_signature(m, ri, NULL);
2394 if (r < 0)
2395 return r;
2396
2397 (*signature)++;
2398
2399 } else if (bus_type_is_basic(t)) {
2400 ssize_t align, k;
2401
2402 align = bus_type_get_alignment(t);
2403 k = bus_type_get_size(t);
2404 assert(align > 0 && k > 0);
2405
2406 r = message_peek_fields(m, ri, align, k, NULL);
2407 if (r < 0)
2408 return r;
2409
2410 (*signature)++;
2411
2412 } else if (t == SD_BUS_TYPE_ARRAY) {
2413
2414 r = signature_element_length(*signature+1, &l);
2415 if (r < 0)
2416 return r;
2417
2418 assert(l >= 1);
2419 {
2420 char sig[l-1], *s;
2421 uint32_t nas;
2422 int alignment;
2423
2424 strncpy(sig, *signature + 1, l-1);
2425 s = sig;
2426
2427 alignment = bus_type_get_alignment(sig[0]);
2428 if (alignment < 0)
2429 return alignment;
2430
2431 r = message_peek_field_uint32(m, ri, &nas);
2432 if (r < 0)
2433 return r;
2434 if (nas > BUS_ARRAY_MAX_SIZE)
2435 return -EBADMSG;
2436
2437 r = message_peek_fields(m, ri, alignment, 0, NULL);
2438 if (r < 0)
2439 return r;
2440
2441 r = message_skip_fields(m, ri, nas, (const char**) &s);
2442 if (r < 0)
2443 return r;
2444 }
2445
2446 (*signature) += 1 + l;
2447
2448 } else if (t == SD_BUS_TYPE_VARIANT) {
2449 const char *s;
2450
2451 r = message_peek_field_signature(m, ri, &s);
2452 if (r < 0)
2453 return r;
2454
2455 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2456 if (r < 0)
2457 return r;
2458
2459 (*signature)++;
2460
2461 } else if (t == SD_BUS_TYPE_STRUCT ||
2462 t == SD_BUS_TYPE_DICT_ENTRY) {
2463
2464 r = signature_element_length(*signature, &l);
2465 if (r < 0)
2466 return r;
2467
2468 assert(l >= 2);
2469 {
2470 char sig[l-1], *s;
2471 strncpy(sig, *signature + 1, l-1);
2472 s = sig;
2473
2474 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2475 if (r < 0)
2476 return r;
2477 }
2478
2479 *signature += l;
2480 } else
2481 return -EINVAL;
2482 }
2483 }
2484
2485 static int message_parse_fields(sd_bus_message *m) {
2486 size_t ri;
2487 int r;
2488 uint32_t unix_fds = 0;
2489
2490 assert(m);
2491
2492 for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2493 const char *signature;
2494 uint8_t *header;
2495
2496 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2497 if (r < 0)
2498 return r;
2499
2500 r = message_peek_field_signature(m, &ri, &signature);
2501 if (r < 0)
2502 return r;
2503
2504 switch (*header) {
2505 case _SD_BUS_MESSAGE_HEADER_INVALID:
2506 return -EBADMSG;
2507
2508 case SD_BUS_MESSAGE_HEADER_PATH:
2509
2510 if (m->path)
2511 return -EBADMSG;
2512
2513 if (!streq(signature, "o"))
2514 return -EBADMSG;
2515
2516 r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2517 break;
2518
2519 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2520
2521 if (m->interface)
2522 return -EBADMSG;
2523
2524 if (!streq(signature, "s"))
2525 return -EBADMSG;
2526
2527 r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2528 break;
2529
2530 case SD_BUS_MESSAGE_HEADER_MEMBER:
2531
2532 if (m->member)
2533 return -EBADMSG;
2534
2535 if (!streq(signature, "s"))
2536 return -EBADMSG;
2537
2538 r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2539 break;
2540
2541 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2542
2543 if (m->error.name)
2544 return -EBADMSG;
2545
2546 if (!streq(signature, "s"))
2547 return -EBADMSG;
2548
2549 r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2550 break;
2551
2552 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2553
2554 if (m->destination)
2555 return -EBADMSG;
2556
2557 if (!streq(signature, "s"))
2558 return -EBADMSG;
2559
2560 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2561 break;
2562
2563 case SD_BUS_MESSAGE_HEADER_SENDER:
2564
2565 if (m->sender)
2566 return -EBADMSG;
2567
2568 if (!streq(signature, "s"))
2569 return -EBADMSG;
2570
2571 r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2572 break;
2573
2574
2575 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2576 const char *s;
2577 char *c;
2578
2579 if (m->root_container.signature)
2580 return -EBADMSG;
2581
2582 if (!streq(signature, "g"))
2583 return -EBADMSG;
2584
2585 r = message_peek_field_signature(m, &ri, &s);
2586 if (r < 0)
2587 return r;
2588
2589 c = strdup(s);
2590 if (!c)
2591 return -ENOMEM;
2592
2593 free(m->root_container.signature);
2594 m->root_container.signature = c;
2595 break;
2596 }
2597
2598 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2599 if (m->reply_serial != 0)
2600 return -EBADMSG;
2601
2602 if (!streq(signature, "u"))
2603 return -EBADMSG;
2604
2605 r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2606 if (r < 0)
2607 return r;
2608
2609 if (m->reply_serial == 0)
2610 return -EBADMSG;
2611
2612 break;
2613
2614 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2615 if (unix_fds != 0)
2616 return -EBADMSG;
2617
2618 if (!streq(signature, "u"))
2619 return -EBADMSG;
2620
2621 r = message_peek_field_uint32(m, &ri, &unix_fds);
2622 if (r < 0)
2623 return -EBADMSG;
2624
2625 if (unix_fds == 0)
2626 return -EBADMSG;
2627
2628 break;
2629
2630 default:
2631 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2632 }
2633
2634 if (r < 0)
2635 return r;
2636 }
2637
2638 if (m->n_fds != unix_fds)
2639 return -EBADMSG;
2640
2641 if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2642 return -EBADMSG;
2643
2644 switch (m->header->type) {
2645
2646 case SD_BUS_MESSAGE_TYPE_SIGNAL:
2647 if (!m->path || !m->interface || !m->member)
2648 return -EBADMSG;
2649 break;
2650
2651 case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2652
2653 if (!m->path || !m->member)
2654 return -EBADMSG;
2655
2656 break;
2657
2658 case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2659
2660 if (m->reply_serial == 0)
2661 return -EBADMSG;
2662 break;
2663
2664 case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2665
2666 if (m->reply_serial == 0 || !m->error.name)
2667 return -EBADMSG;
2668 break;
2669 }
2670
2671 /* Try to read the error message, but if we can't it's a non-issue */
2672 if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2673 sd_bus_message_read(m, "s", &m->error.message);
2674
2675 return 0;
2676 }
2677
2678 static void setup_iovec(sd_bus_message *m) {
2679 assert(m);
2680 assert(m->sealed);
2681
2682 m->n_iovec = 0;
2683 m->size = 0;
2684
2685 m->iovec[m->n_iovec].iov_base = m->header;
2686 m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2687 m->size += m->iovec[m->n_iovec].iov_len;
2688 m->n_iovec++;
2689
2690 if (m->fields) {
2691 m->iovec[m->n_iovec].iov_base = m->fields;
2692 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2693 m->size += m->iovec[m->n_iovec].iov_len;
2694 m->n_iovec++;
2695
2696 if (m->header->fields_size % 8 != 0) {
2697 static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2698
2699 m->iovec[m->n_iovec].iov_base = (void*) padding;
2700 m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2701 m->size += m->iovec[m->n_iovec].iov_len;
2702 m->n_iovec++;
2703 }
2704 }
2705
2706 if (m->body) {
2707 m->iovec[m->n_iovec].iov_base = m->body;
2708 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2709 m->size += m->iovec[m->n_iovec].iov_len;
2710 m->n_iovec++;
2711 }
2712 }
2713
2714 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2715 int r;
2716
2717 assert(m);
2718
2719 if (m->sealed)
2720 return -EPERM;
2721
2722 if (m->n_containers > 0)
2723 return -EBADMSG;
2724
2725 /* If there's a non-trivial signature set, then add it in here */
2726 if (!isempty(m->root_container.signature)) {
2727 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2728 if (r < 0)
2729 return r;
2730 }
2731
2732 if (m->n_fds > 0) {
2733 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2734 if (r < 0)
2735 return r;
2736 }
2737
2738 m->header->serial = serial;
2739 m->sealed = true;
2740
2741 setup_iovec(m);
2742
2743 return 0;
2744 }
2745
2746 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2747 if (!m)
2748 return -EINVAL;
2749 if (!destination)
2750 return -EINVAL;
2751 if (m->sealed)
2752 return -EPERM;
2753 if (m->destination)
2754 return -EEXIST;
2755
2756 return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2757 }
2758
2759 int bus_message_dump(sd_bus_message *m) {
2760 unsigned level = 1;
2761 int r;
2762
2763 assert(m);
2764
2765 printf("Message %p\n"
2766 "\tn_ref=%u\n"
2767 "\tendian=%c\n"
2768 "\ttype=%i\n"
2769 "\tflags=%u\n"
2770 "\tversion=%u\n"
2771 "\tserial=%u\n"
2772 "\tfields_size=%u\n"
2773 "\tbody_size=%u\n"
2774 "\tpath=%s\n"
2775 "\tinterface=%s\n"
2776 "\tmember=%s\n"
2777 "\tdestination=%s\n"
2778 "\tsender=%s\n"
2779 "\tsignature=%s\n"
2780 "\treply_serial=%u\n"
2781 "\terror.name=%s\n"
2782 "\terror.message=%s\n"
2783 "\tsealed=%s\n",
2784 m,
2785 m->n_ref,
2786 m->header->endian,
2787 m->header->type,
2788 m->header->flags,
2789 m->header->version,
2790 BUS_MESSAGE_SERIAL(m),
2791 BUS_MESSAGE_FIELDS_SIZE(m),
2792 BUS_MESSAGE_BODY_SIZE(m),
2793 strna(m->path),
2794 strna(m->interface),
2795 strna(m->member),
2796 strna(m->destination),
2797 strna(m->sender),
2798 strna(m->root_container.signature),
2799 m->reply_serial,
2800 strna(m->error.name),
2801 strna(m->error.message),
2802 yes_no(m->sealed));
2803
2804 r = sd_bus_message_rewind(m, true);
2805 if (r < 0) {
2806 log_error("Failed to rewind: %s", strerror(-r));
2807 return r;
2808 }
2809
2810 printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2811
2812 for(;;) {
2813 _cleanup_free_ char *prefix = NULL;
2814 const char *contents = NULL;
2815 char type;
2816 union {
2817 uint8_t u8;
2818 uint16_t u16;
2819 int16_t s16;
2820 uint32_t u32;
2821 int32_t s32;
2822 uint64_t u64;
2823 int64_t s64;
2824 double d64;
2825 const char *string;
2826 int i;
2827 } basic;
2828
2829 r = sd_bus_message_peek_type(m, &type, &contents);
2830 if (r < 0) {
2831 log_error("Failed to peek type: %s", strerror(-r));
2832 return r;
2833 }
2834 if (r == 0) {
2835 if (level <= 1)
2836 break;
2837
2838 r = sd_bus_message_exit_container(m);
2839 if (r < 0) {
2840 log_error("Failed to exit container: %s", strerror(-r));
2841 return r;
2842 }
2843
2844 level--;
2845
2846 prefix = strrep("\t", level);
2847 if (!prefix)
2848 return log_oom();
2849
2850 if (type == SD_BUS_TYPE_ARRAY)
2851 printf("%s} END_ARRAY \n", prefix);
2852 else if (type == SD_BUS_TYPE_VARIANT)
2853 printf("%s} END_VARIANT\n", prefix);
2854 else if (type == SD_BUS_TYPE_STRUCT)
2855 printf("%s} END_STRUCT\n", prefix);
2856 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2857 printf("%s} END_DICT_ENTRY\n", prefix);
2858
2859 continue;
2860 }
2861
2862 prefix = strrep("\t", level);
2863 if (!prefix)
2864 return log_oom();
2865
2866 if (bus_type_is_container(type) > 0) {
2867 r = sd_bus_message_enter_container(m, type, contents);
2868 if (r < 0) {
2869 log_error("Failed to enter container: %s", strerror(-r));
2870 return r;
2871 }
2872
2873 if (type == SD_BUS_TYPE_ARRAY)
2874 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2875 else if (type == SD_BUS_TYPE_VARIANT)
2876 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2877 else if (type == SD_BUS_TYPE_STRUCT)
2878 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2879 else if (type == SD_BUS_TYPE_DICT_ENTRY)
2880 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2881
2882 level ++;
2883
2884 continue;
2885 }
2886
2887 r = sd_bus_message_read_basic(m, type, &basic);
2888 if (r < 0) {
2889 log_error("Failed to get basic: %s", strerror(-r));
2890 return r;
2891 }
2892
2893 switch (type) {
2894
2895 case SD_BUS_TYPE_BYTE:
2896 printf("%sBYTE: %u\n", prefix, basic.u8);
2897 break;
2898
2899 case SD_BUS_TYPE_BOOLEAN:
2900 printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2901 break;
2902
2903 case SD_BUS_TYPE_INT16:
2904 printf("%sINT16: %i\n", prefix, basic.s16);
2905 break;
2906
2907 case SD_BUS_TYPE_UINT16:
2908 printf("%sUINT16: %u\n", prefix, basic.u16);
2909 break;
2910
2911 case SD_BUS_TYPE_INT32:
2912 printf("%sINT32: %i\n", prefix, basic.s32);
2913 break;
2914
2915 case SD_BUS_TYPE_UINT32:
2916 printf("%sUINT32: %u\n", prefix, basic.u32);
2917 break;
2918
2919 case SD_BUS_TYPE_INT64:
2920 printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2921 break;
2922
2923 case SD_BUS_TYPE_UINT64:
2924 printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2925 break;
2926
2927 case SD_BUS_TYPE_DOUBLE:
2928 printf("%sDOUBLE: %g\n", prefix, basic.d64);
2929 break;
2930
2931 case SD_BUS_TYPE_STRING:
2932 printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2933 break;
2934
2935 case SD_BUS_TYPE_OBJECT_PATH:
2936 printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2937 break;
2938
2939 case SD_BUS_TYPE_SIGNATURE:
2940 printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2941 break;
2942
2943 case SD_BUS_TYPE_UNIX_FD:
2944 printf("%sUNIX_FD: %i\n", prefix, basic.i);
2945 break;
2946
2947 default:
2948 assert_not_reached("Unknown basic type.");
2949 }
2950 }
2951
2952 printf("} END_MESSAGE\n");
2953 return 0;
2954 }
2955
2956 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2957 size_t total;
2958 unsigned i;
2959 void *p, *e;
2960
2961 assert(m);
2962 assert(buffer);
2963 assert(sz);
2964
2965 for (i = 0, total = 0; i < m->n_iovec; i++)
2966 total += m->iovec[i].iov_len;
2967
2968 p = malloc(total);
2969 if (!p)
2970 return -ENOMEM;
2971
2972 for (i = 0, e = p; i < m->n_iovec; i++)
2973 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
2974
2975 *buffer = p;
2976 *sz = total;
2977
2978 return 0;
2979 }
2980
2981 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
2982 int r;
2983
2984 assert(m);
2985 assert(l);
2986
2987 r = sd_bus_message_enter_container(m, 'a', "s");
2988 if (r < 0)
2989 return r;
2990
2991 for (;;) {
2992 const char *s;
2993
2994 r = sd_bus_message_read_basic(m, 's', &s);
2995 if (r < 0)
2996 return r;
2997 if (r == 0)
2998 break;
2999
3000 r = strv_extend(l, s);
3001 if (r < 0)
3002 return r;
3003 }
3004
3005 r = sd_bus_message_exit_container(m);
3006 if (r < 0)
3007 return r;
3008
3009 return 0;
3010 }
3011
3012 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3013 int r;
3014 const char *t;
3015 char type;
3016
3017 assert(m);
3018
3019 r = sd_bus_message_rewind(m, true);
3020 if (r < 0)
3021 return NULL;
3022
3023 while (i > 0) {
3024 r = sd_bus_message_peek_type(m, &type, NULL);
3025 if (r < 0)
3026 return NULL;
3027
3028 if (type != SD_BUS_TYPE_STRING &&
3029 type != SD_BUS_TYPE_OBJECT_PATH &&
3030 type != SD_BUS_TYPE_SIGNATURE)
3031 return NULL;
3032
3033 r = sd_bus_message_read_basic(m, type, &t);
3034 if (r < 0)
3035 return NULL;
3036
3037 i--;
3038 }
3039
3040 r = sd_bus_message_rewind(m, true);
3041 if (r < 0)
3042 return NULL;
3043
3044 return t;
3045 }