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