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