chiark / gitweb /
bus: validate the entire header more closely
[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         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1745         if (!w)
1746                 return -ENOMEM;
1747         m->containers = w;
1748
1749         c = message_get_container(m);
1750
1751         if (!c->signature || c->signature[c->index] == 0)
1752                 return 0;
1753
1754         signature = strdup(contents);
1755         if (!signature)
1756                 return -ENOMEM;
1757
1758         if (type == SD_BUS_TYPE_ARRAY)
1759                 r = bus_message_enter_array(m, c, contents, &array_size);
1760         else if (type == SD_BUS_TYPE_VARIANT)
1761                 r = bus_message_enter_variant(m, c, contents);
1762         else if (type == SD_BUS_TYPE_STRUCT)
1763                 r = bus_message_enter_struct(m, c, contents);
1764         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1765                 r = bus_message_enter_dict_entry(m, c, contents);
1766         else
1767                 r = -EINVAL;
1768
1769         if (r <= 0) {
1770                 free(signature);
1771                 return r;
1772         }
1773
1774         /* OK, let's fill it in */
1775         w += m->n_containers++;
1776         w->enclosing = type;
1777         w->signature = signature;
1778         w->index = 0;
1779         w->array_size = array_size;
1780         w->begin = m->rindex;
1781
1782         return 1;
1783 }
1784
1785 int sd_bus_message_exit_container(sd_bus_message *m) {
1786         struct bus_container *c;
1787
1788         if (!m)
1789                 return -EINVAL;
1790         if (!m->sealed)
1791                 return -EPERM;
1792         if (m->n_containers <= 0)
1793                 return -EINVAL;
1794
1795         c = message_get_container(m);
1796         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1797                 uint32_t l;
1798
1799                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1800                 if (c->begin + l != m->rindex)
1801                         return -EBUSY;
1802
1803         } else {
1804                 if (c->signature && c->signature[c->index] != 0)
1805                         return -EINVAL;
1806         }
1807
1808         free(c->signature);
1809         m->n_containers--;
1810
1811         return 1;
1812 }
1813
1814 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1815         struct bus_container *c;
1816         int r;
1817
1818         if (!m)
1819                 return -EINVAL;
1820         if (!m->sealed)
1821                 return -EPERM;
1822
1823         c = message_get_container(m);
1824
1825         if (!c->signature || c->signature[c->index] == 0)
1826                 goto eof;
1827
1828         if (message_end_of_array(m, m->rindex))
1829                 goto eof;
1830
1831         if (bus_type_is_basic(c->signature[c->index])) {
1832                 if (contents)
1833                         *contents = NULL;
1834                 if (type)
1835                         *type = c->signature[c->index];
1836                 return 1;
1837         }
1838
1839         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1840
1841                 if (contents) {
1842                         size_t l;
1843                         char *sig;
1844
1845                         r = signature_element_length(c->signature+c->index+1, &l);
1846                         if (r < 0)
1847                                 return r;
1848
1849                         assert(l >= 1);
1850
1851                         sig = strndup(c->signature + c->index + 1, l);
1852                         if (!sig)
1853                                 return -ENOMEM;
1854
1855                         free(m->peeked_signature);
1856                         m->peeked_signature = sig;
1857
1858                         *contents = sig;
1859                 }
1860
1861                 if (type)
1862                         *type = SD_BUS_TYPE_ARRAY;
1863
1864                 return 1;
1865         }
1866
1867         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
1868             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
1869
1870                 if (contents) {
1871                         size_t l;
1872                         char *sig;
1873
1874                         r = signature_element_length(c->signature+c->index, &l);
1875                         if (r < 0)
1876                                 return r;
1877
1878                         assert(l >= 2);
1879                         sig = strndup(c->signature + c->index + 1, l - 2);
1880                         if (!sig)
1881                                 return -ENOMEM;
1882
1883                         free(m->peeked_signature);
1884                         m->peeked_signature = sig;
1885
1886                         *contents = sig;
1887                 }
1888
1889                 if (type)
1890                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
1891
1892                 return 1;
1893         }
1894
1895         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
1896                 if (contents) {
1897                         size_t rindex, l;
1898                         void *q;
1899
1900                         rindex = m->rindex;
1901                         r = message_peek_body(m, &rindex, 1, 1, &q);
1902                         if (r < 0)
1903                                 return r;
1904                         if (r == 0)
1905                                 goto eof;
1906
1907                         l = *(uint8_t*) q;
1908                         r = message_peek_body(m, &rindex, 1, l+1, &q);
1909                         if (r < 0)
1910                                 return r;
1911                         if (r == 0)
1912                                 return -EBADMSG;
1913
1914                         if (!validate_signature(q, l))
1915                                 return -EBADMSG;
1916
1917                         *contents = q;
1918                 }
1919
1920                 if (type)
1921                         *type = SD_BUS_TYPE_VARIANT;
1922
1923                 return 1;
1924         }
1925
1926         return -EINVAL;
1927
1928 eof:
1929         if (type)
1930                 *type = c->enclosing;
1931         if (contents)
1932                 *contents = NULL;
1933         return 0;
1934 }
1935
1936 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
1937         struct bus_container *c;
1938
1939         if (!m)
1940                 return -EINVAL;
1941         if (!m->sealed)
1942                 return -EPERM;
1943
1944         if (complete) {
1945                 reset_containers(m);
1946                 m->rindex = 0;
1947                 m->root_container.index = 0;
1948
1949                 c = message_get_container(m);
1950         } else {
1951                 c = message_get_container(m);
1952
1953                 c->index = 0;
1954                 m->rindex = c->begin;
1955         }
1956
1957         return !isempty(c->signature);
1958 }
1959
1960 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
1961         const char *t;
1962         int r;
1963
1964         assert(m);
1965         assert(types);
1966
1967         for (t = types; *t; t++) {
1968                 switch (*t) {
1969
1970                 case SD_BUS_TYPE_BYTE:
1971                 case SD_BUS_TYPE_BOOLEAN:
1972                 case SD_BUS_TYPE_INT16:
1973                 case SD_BUS_TYPE_UINT16:
1974                 case SD_BUS_TYPE_INT32:
1975                 case SD_BUS_TYPE_UINT32:
1976                 case SD_BUS_TYPE_INT64:
1977                 case SD_BUS_TYPE_UINT64:
1978                 case SD_BUS_TYPE_DOUBLE:
1979                 case SD_BUS_TYPE_STRING:
1980                 case SD_BUS_TYPE_OBJECT_PATH:
1981                 case SD_BUS_TYPE_SIGNATURE: {
1982                         void *p;
1983
1984                         p = va_arg(ap, void*);
1985                         r = sd_bus_message_read_basic(m, *t, p);
1986                         break;
1987                 }
1988
1989                 case SD_BUS_TYPE_ARRAY: {
1990                         size_t k;
1991
1992                         r = signature_element_length(t + 1, &k);
1993                         if (r < 0)
1994                                 return r;
1995
1996                         {
1997                                 unsigned i, n;
1998                                 char s[k + 1];
1999
2000                                 memcpy(s, t + 1, k);
2001                                 s[k] = 0;
2002                                 t += k;
2003
2004                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2005                                 if (r < 0)
2006                                         return r;
2007                                 if (r == 0)
2008                                         return -ENXIO;
2009
2010                                 n = va_arg(ap, unsigned);
2011                                 for (i = 0; i < n; i++) {
2012                                         r = message_read_ap(m, s, ap);
2013                                         if (r < 0)
2014                                                 return r;
2015                                 }
2016
2017                                 r = sd_bus_message_exit_container(m);
2018                         }
2019
2020                         break;
2021                 }
2022
2023                 case SD_BUS_TYPE_VARIANT: {
2024                         const char *s;
2025
2026                         s = va_arg(ap, const char *);
2027                         if (!s)
2028                                 return -EINVAL;
2029
2030                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2031                         if (r < 0)
2032                                 return r;
2033                         if (r == 0)
2034                                 return -ENXIO;
2035
2036                         r = message_read_ap(m, s, ap);
2037                         if (r < 0)
2038                                 return r;
2039                         if (r == 0)
2040                                 return -ENXIO;
2041
2042                         r = sd_bus_message_exit_container(m);
2043                         break;
2044                 }
2045
2046                 case SD_BUS_TYPE_STRUCT_BEGIN:
2047                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2048                         size_t k;
2049
2050                         r = signature_element_length(t, &k);
2051                         if (r < 0)
2052                                 return r;
2053
2054                         {
2055                                 char s[k - 1];
2056                                 memcpy(s, t + 1, k - 2);
2057                                 s[k - 2] = 0;
2058
2059                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2060                                 if (r < 0)
2061                                         return r;
2062                                 if (r == 0)
2063                                         return -ENXIO;
2064
2065                                 t += k - 1;
2066
2067                                 r = message_read_ap(m, s, ap);
2068                                 if (r < 0)
2069                                         return r;
2070                                 if (r == 0)
2071                                         return -ENXIO;
2072
2073                                 r = sd_bus_message_exit_container(m);
2074                         }
2075
2076                         break;
2077                 }
2078
2079                 default:
2080                         r = -EINVAL;
2081                 }
2082
2083                 if (r < 0)
2084                         return r;
2085                 if (r == 0)
2086                         return -ENXIO;
2087         }
2088
2089         return 1;
2090 }
2091
2092 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2093         va_list ap;
2094         int r;
2095
2096         if (!m)
2097                 return -EINVAL;
2098         if (!m->sealed)
2099                 return -EPERM;
2100         if (!types)
2101                 return -EINVAL;
2102
2103         va_start(ap, types);
2104         r = message_read_ap(m, types, ap);
2105         va_end(ap);
2106
2107         return r;
2108 }
2109
2110 static int message_peek_fields(
2111                 sd_bus_message *m,
2112                 size_t *rindex,
2113                 size_t align,
2114                 size_t nbytes,
2115                 void **ret) {
2116
2117         assert(m);
2118         assert(rindex);
2119         assert(align > 0);
2120
2121         return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2122 }
2123
2124 static int message_peek_field_string(
2125                 sd_bus_message *m,
2126                 bool (*validate)(const char *p),
2127                 size_t *ri,
2128                 const char **ret) {
2129
2130         size_t l;
2131         int r;
2132         void *q;
2133
2134         assert(m);
2135         assert(ri);
2136
2137         r = message_peek_fields(m, ri, 4, 4, &q);
2138         if (r < 0)
2139                 return r;
2140
2141         l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2142         r = message_peek_fields(m, ri, 1, l+1, &q);
2143         if (r < 0)
2144                 return r;
2145
2146         if (validate) {
2147                 if (!validate_nul(q, l))
2148                         return -EBADMSG;
2149
2150                 if (!validate(q))
2151                         return -EBADMSG;
2152         } else {
2153                 if (!validate_string(q, l))
2154                         return -EBADMSG;
2155         }
2156
2157         if (ret)
2158                 *ret = q;
2159
2160         return 0;
2161 }
2162
2163 static int message_peek_field_signature(
2164                 sd_bus_message *m,
2165                 size_t *ri,
2166                 const char **ret) {
2167
2168         size_t l;
2169         int r;
2170         void *q;
2171
2172         assert(m);
2173         assert(ri);
2174
2175         r = message_peek_fields(m, ri, 1, 1, &q);
2176         if (r < 0)
2177                 return r;
2178
2179         l = *(uint8_t*) q;
2180         r = message_peek_fields(m, ri, 1, l+1, &q);
2181         if (r < 0)
2182                 return r;
2183
2184         if (!validate_signature(q, l))
2185                 return -EBADMSG;
2186
2187         if (ret)
2188                 *ret = q;
2189
2190         return 0;
2191 }
2192
2193 static int message_peek_field_uint32(
2194                 sd_bus_message *m,
2195                 size_t *ri,
2196                 uint32_t *ret) {
2197
2198         int r;
2199         void *q;
2200
2201         assert(m);
2202         assert(ri);
2203
2204         r = message_peek_fields(m, ri, 4, 4, &q);
2205         if (r < 0)
2206                 return r;
2207
2208         if (ret)
2209                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2210
2211         return 0;
2212 }
2213
2214 static int message_skip_fields(
2215                 sd_bus_message *m,
2216                 size_t *ri,
2217                 uint32_t array_size,
2218                 const char **signature) {
2219
2220         size_t original_index;
2221         int r;
2222
2223         assert(m);
2224         assert(ri);
2225         assert(signature);
2226
2227         original_index = *ri;
2228
2229         for (;;) {
2230                 char t;
2231                 void *q;
2232                 size_t l;
2233
2234                 if (array_size != (uint32_t) -1 &&
2235                     array_size <= *ri - original_index)
2236                         return 0;
2237
2238                 t = **signature;
2239                 if (!t)
2240                         return 0;
2241
2242                 if (t == SD_BUS_TYPE_STRING) {
2243
2244                         r = message_peek_field_string(m, NULL, ri, NULL);
2245                         if (r < 0)
2246                                 return r;
2247
2248                         (*signature)++;
2249
2250                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2251
2252                         r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2253                         if (r < 0)
2254                                 return r;
2255
2256                         (*signature)++;
2257
2258                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2259
2260                         r = message_peek_field_signature(m, ri, NULL);
2261                         if (r < 0)
2262                                 return r;
2263
2264                         (*signature)++;
2265
2266                 } else if (bus_type_is_basic(t)) {
2267                         size_t align, k;
2268
2269                         align = bus_type_get_alignment(t);
2270                         k = bus_type_get_size(t);
2271
2272                         r = message_peek_fields(m, ri, align, k, NULL);
2273                         if (r < 0)
2274                                 return r;
2275
2276                         (*signature)++;
2277
2278                 } else if (t == SD_BUS_TYPE_ARRAY) {
2279
2280                         r = signature_element_length(*signature+1, &l);
2281                         if (r < 0)
2282                                 return r;
2283
2284                         assert(l >= 1);
2285                         {
2286                                 char sig[l-1], *s;
2287                                 size_t nas;
2288                                 int alignment;
2289
2290                                 strncpy(sig, *signature + 1, l-1);
2291                                 s = sig;
2292
2293                                 alignment = bus_type_get_alignment(sig[0]);
2294                                 if (alignment < 0)
2295                                         return alignment;
2296
2297                                 r = message_peek_fields(m, ri, 4, 4, &q);
2298                                 if (r < 0)
2299                                         return r;
2300
2301                                 nas = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2302                                 if (nas > BUS_ARRAY_MAX_SIZE)
2303                                         return -EBADMSG;
2304
2305                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
2306                                 if (r < 0)
2307                                         return r;
2308
2309                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
2310                                 if (r < 0)
2311                                         return r;
2312                         }
2313
2314                         (*signature) += 1 + l;
2315
2316                 } else if (t == SD_BUS_TYPE_VARIANT) {
2317                         const char *s;
2318
2319                         r = message_peek_field_signature(m, ri, &s);
2320                         if (r < 0)
2321                                 return r;
2322
2323                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2324                         if (r < 0)
2325                                 return r;
2326
2327                         (*signature)++;
2328
2329                 } else if (t == SD_BUS_TYPE_STRUCT ||
2330                            t == SD_BUS_TYPE_DICT_ENTRY) {
2331
2332                         r = signature_element_length(*signature, &l);
2333                         if (r < 0)
2334                                 return r;
2335
2336                         assert(l >= 2);
2337                         {
2338                                 char sig[l-1], *s;
2339                                 strncpy(sig, *signature + 1, l-1);
2340                                 s = sig;
2341
2342                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2343                                 if (r < 0)
2344                                         return r;
2345                         }
2346
2347                         *signature += l;
2348                 } else
2349                         return -EINVAL;
2350         }
2351 }
2352
2353 static int message_parse_fields(sd_bus_message *m) {
2354         size_t ri;
2355         int r;
2356
2357         assert(m);
2358
2359         for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2360                 const char *signature;
2361                 uint8_t *header;
2362
2363                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2364                 if (r < 0)
2365                         return r;
2366
2367                 r = message_peek_field_signature(m, &ri, &signature);
2368                 if (r < 0)
2369                         return r;
2370
2371                 switch (*header) {
2372                 case _SD_BUS_MESSAGE_HEADER_INVALID:
2373                         return -EBADMSG;
2374
2375                 case SD_BUS_MESSAGE_HEADER_PATH:
2376                         if (!streq(signature, "o"))
2377                                 return -EBADMSG;
2378
2379                         r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2380                         break;
2381
2382                 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2383                         if (!streq(signature, "s"))
2384                                 return -EBADMSG;
2385
2386                         r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2387                         break;
2388
2389                 case SD_BUS_MESSAGE_HEADER_MEMBER:
2390                         if (!streq(signature, "s"))
2391                                 return -EBADMSG;
2392
2393                         r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2394                         break;
2395
2396                 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2397                         if (!streq(signature, "s"))
2398                                 return -EBADMSG;
2399
2400                         r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2401                         break;
2402
2403                 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2404                         if (!streq(signature, "s"))
2405                                 return -EBADMSG;
2406
2407                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2408                         break;
2409
2410                 case SD_BUS_MESSAGE_HEADER_SENDER:
2411                         if (!streq(signature, "s"))
2412                                 return -EBADMSG;
2413
2414                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2415                         break;
2416
2417
2418                 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2419                         const char *s;
2420                         char *c;
2421
2422                         if (!streq(signature, "g"))
2423                                 return -EBADMSG;
2424
2425                         r = message_peek_field_signature(m, &ri, &s);
2426                         if (r < 0)
2427                                 return r;
2428
2429                         c = strdup(s);
2430                         if (!c)
2431                                 return -ENOMEM;
2432
2433                         free(m->root_container.signature);
2434                         m->root_container.signature = c;
2435
2436                         r = 0;
2437                         break;
2438                 }
2439
2440                 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2441                         if (!streq(signature, "u"))
2442                                 return -EBADMSG;
2443
2444                         r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2445                         if (r < 0)
2446                                 return r;
2447
2448                         if (m->reply_serial == 0)
2449                                 return -EBADMSG;
2450
2451                         break;
2452
2453                 default:
2454                         r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2455                 }
2456
2457                 if (r < 0)
2458                         return r;
2459         }
2460
2461         if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2462                 return -EBADMSG;
2463
2464         switch (m->header->type) {
2465
2466         case SD_BUS_MESSAGE_TYPE_SIGNAL:
2467                 if (!m->path || !m->interface || !m->member)
2468                         return -EBADMSG;
2469                 break;
2470
2471         case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2472
2473                 if (!m->path || !m->member)
2474                         return -EBADMSG;
2475
2476                 break;
2477
2478         case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2479
2480                 if (m->reply_serial == 0)
2481                         return -EBADMSG;
2482                 break;
2483
2484         case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2485
2486                 if (m->reply_serial == 0 || !m->error.name)
2487                         return -EBADMSG;
2488                 break;
2489         }
2490
2491         /* Try to read the error message, but if we can't it's a non-issue */
2492         if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2493                 sd_bus_message_read(m, "s", &m->error.message);
2494
2495         return 0;
2496 }
2497
2498 static void setup_iovec(sd_bus_message *m) {
2499         assert(m);
2500         assert(m->sealed);
2501
2502         m->n_iovec = 0;
2503         m->size = 0;
2504
2505         m->iovec[m->n_iovec].iov_base = m->header;
2506         m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2507         m->size += m->iovec[m->n_iovec].iov_len;
2508         m->n_iovec++;
2509
2510         if (m->fields) {
2511                 m->iovec[m->n_iovec].iov_base = m->fields;
2512                 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2513                 m->size += m->iovec[m->n_iovec].iov_len;
2514                 m->n_iovec++;
2515
2516                 if (m->header->fields_size % 8 != 0) {
2517                         static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2518
2519                         m->iovec[m->n_iovec].iov_base = (void*) padding;
2520                         m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2521                         m->size += m->iovec[m->n_iovec].iov_len;
2522                         m->n_iovec++;
2523                 }
2524         }
2525
2526         if (m->body) {
2527                 m->iovec[m->n_iovec].iov_base = m->body;
2528                 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2529                 m->size += m->iovec[m->n_iovec].iov_len;
2530                 m->n_iovec++;
2531         }
2532 }
2533
2534 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2535         int r;
2536
2537         assert(m);
2538
2539         if (m->sealed)
2540                 return -EPERM;
2541
2542         if (m->n_containers > 0)
2543                 return -EBADMSG;
2544
2545         /* If there's a non-trivial signature set, then add it in here */
2546         if (!isempty(m->root_container.signature)) {
2547                 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2548                 if (r < 0)
2549                         return r;
2550         }
2551
2552         if (m->n_fds > 0) {
2553                 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2554                 if (r < 0)
2555                         return r;
2556         }
2557
2558         m->header->serial = serial;
2559         m->sealed = true;
2560
2561         setup_iovec(m);
2562
2563         return 0;
2564 }
2565
2566 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2567         if (!m)
2568                 return -EINVAL;
2569         if (!destination)
2570                 return -EINVAL;
2571         if (m->sealed)
2572                 return -EPERM;
2573         if (m->destination)
2574                 return -EEXIST;
2575
2576         return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2577 }
2578
2579 int bus_message_dump(sd_bus_message *m) {
2580         unsigned level = 1;
2581         int r;
2582
2583         assert(m);
2584
2585         printf("Message %p\n"
2586                "\tn_ref=%u\n"
2587                "\tendian=%c\n"
2588                "\ttype=%i\n"
2589                "\tflags=%u\n"
2590                "\tversion=%u\n"
2591                "\tserial=%u\n"
2592                "\tfields_size=%u\n"
2593                "\tbody_size=%u\n"
2594                "\tpath=%s\n"
2595                "\tinterface=%s\n"
2596                "\tmember=%s\n"
2597                "\tdestination=%s\n"
2598                "\tsender=%s\n"
2599                "\tsignature=%s\n"
2600                "\treply_serial=%u\n"
2601                "\terror.name=%s\n"
2602                "\terror.message=%s\n"
2603                "\tsealed=%s\n",
2604                m,
2605                m->n_ref,
2606                m->header->endian,
2607                m->header->type,
2608                m->header->flags,
2609                m->header->version,
2610                BUS_MESSAGE_SERIAL(m),
2611                BUS_MESSAGE_FIELDS_SIZE(m),
2612                BUS_MESSAGE_BODY_SIZE(m),
2613                strna(m->path),
2614                strna(m->interface),
2615                strna(m->member),
2616                strna(m->destination),
2617                strna(m->sender),
2618                strna(m->root_container.signature),
2619                m->reply_serial,
2620                strna(m->error.name),
2621                strna(m->error.message),
2622                yes_no(m->sealed));
2623
2624         r = sd_bus_message_rewind(m, true);
2625         if (r < 0) {
2626                 log_error("Failed to rewind: %s", strerror(-r));
2627                 return r;
2628         }
2629
2630         printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2631
2632         for(;;) {
2633                 _cleanup_free_ char *prefix = NULL;
2634                 const char *contents = NULL;
2635                 char type;
2636                 union {
2637                         uint8_t u8;
2638                         uint16_t u16;
2639                         int16_t s16;
2640                         uint32_t u32;
2641                         int32_t s32;
2642                         uint64_t u64;
2643                         int64_t s64;
2644                         double d64;
2645                         const char *string;
2646                         int i;
2647                 } basic;
2648
2649                 r = sd_bus_message_peek_type(m, &type, &contents);
2650                 if (r < 0) {
2651                         log_error("Failed to peek type: %s", strerror(-r));
2652                         return r;
2653                 }
2654                 if (r == 0) {
2655                         if (level <= 1)
2656                                 break;
2657
2658                         r = sd_bus_message_exit_container(m);
2659                         if (r < 0) {
2660                                 log_error("Failed to exit container: %s", strerror(-r));
2661                                 return r;
2662                         }
2663
2664                         level--;
2665
2666                         prefix = strrep("\t", level);
2667                         if (!prefix)
2668                                 return log_oom();
2669
2670                         if (type == SD_BUS_TYPE_ARRAY)
2671                                 printf("%s} END_ARRAY \n", prefix);
2672                         else if (type == SD_BUS_TYPE_VARIANT)
2673                                 printf("%s} END_VARIANT\n", prefix);
2674                         else if (type == SD_BUS_TYPE_STRUCT)
2675                                 printf("%s} END_STRUCT\n", prefix);
2676                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2677                                 printf("%s} END_DICT_ENTRY\n", prefix);
2678
2679                         continue;
2680                 }
2681
2682                 prefix = strrep("\t", level);
2683                 if (!prefix)
2684                         return log_oom();
2685
2686                 if (bus_type_is_container(type) > 0) {
2687                         r = sd_bus_message_enter_container(m, type, contents);
2688                         if (r < 0) {
2689                                 log_error("Failed to enter container: %s", strerror(-r));
2690                                 return r;
2691                         }
2692
2693                         if (type == SD_BUS_TYPE_ARRAY)
2694                                 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2695                         else if (type == SD_BUS_TYPE_VARIANT)
2696                                 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2697                         else if (type == SD_BUS_TYPE_STRUCT)
2698                                 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2699                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2700                                 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2701
2702                         level ++;
2703
2704                         continue;
2705                 }
2706
2707                 r = sd_bus_message_read_basic(m, type, &basic);
2708                 if (r < 0) {
2709                         log_error("Failed to get basic: %s", strerror(-r));
2710                         return r;
2711                 }
2712
2713                 switch (type) {
2714
2715                 case SD_BUS_TYPE_BYTE:
2716                         printf("%sBYTE: %u\n", prefix, basic.u8);
2717                         break;
2718
2719                 case SD_BUS_TYPE_BOOLEAN:
2720                         printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2721                         break;
2722
2723                 case SD_BUS_TYPE_INT16:
2724                         printf("%sINT16: %i\n", prefix, basic.s16);
2725                         break;
2726
2727                 case SD_BUS_TYPE_UINT16:
2728                         printf("%sUINT16: %u\n", prefix, basic.u16);
2729                         break;
2730
2731                 case SD_BUS_TYPE_INT32:
2732                         printf("%sINT32: %i\n", prefix, basic.s32);
2733                         break;
2734
2735                 case SD_BUS_TYPE_UINT32:
2736                         printf("%sUINT32: %u\n", prefix, basic.u32);
2737                         break;
2738
2739                 case SD_BUS_TYPE_INT64:
2740                         printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2741                         break;
2742
2743                 case SD_BUS_TYPE_UINT64:
2744                         printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2745                         break;
2746
2747                 case SD_BUS_TYPE_DOUBLE:
2748                         printf("%sDOUBLE: %g\n", prefix, basic.d64);
2749                         break;
2750
2751                 case SD_BUS_TYPE_STRING:
2752                         printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2753                         break;
2754
2755                 case SD_BUS_TYPE_OBJECT_PATH:
2756                         printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2757                         break;
2758
2759                 case SD_BUS_TYPE_SIGNATURE:
2760                         printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2761                         break;
2762
2763                 case SD_BUS_TYPE_UNIX_FD:
2764                         printf("%sUNIX_FD: %i\n", prefix, basic.i);
2765                         break;
2766
2767                 default:
2768                         assert_not_reached("Unknown basic type.");
2769                 }
2770         }
2771
2772         printf("} END_MESSAGE\n");
2773         return 0;
2774 }
2775
2776 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2777         size_t total;
2778         unsigned i;
2779         void *p, *e;
2780
2781         assert(m);
2782         assert(buffer);
2783         assert(sz);
2784
2785         for (i = 0, total = 0; i < m->n_iovec; i++)
2786                 total += m->iovec[i].iov_len;
2787
2788         p = malloc(total);
2789         if (!p)
2790                 return -ENOMEM;
2791
2792         for (i = 0, e = p; i < m->n_iovec; i++)
2793                 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
2794
2795         *buffer = p;
2796         *sz = total;
2797
2798         return 0;
2799 }
2800
2801 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
2802         int r;
2803
2804         assert(m);
2805         assert(l);
2806
2807         r = sd_bus_message_enter_container(m, 'a', "s");
2808         if (r < 0)
2809                 return r;
2810
2811         for (;;) {
2812                 const char *s;
2813
2814                 r = sd_bus_message_read_basic(m, 's', &s);
2815                 if (r < 0)
2816                         return r;
2817                 if (r == 0)
2818                         break;
2819
2820                 r = strv_extend(l, s);
2821                 if (r < 0)
2822                         return r;
2823         }
2824
2825         r = sd_bus_message_exit_container(m);
2826         if (r < 0)
2827                 return r;
2828
2829         return 0;
2830 }