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