chiark / gitweb /
bus: fix signature handling when exiting container
[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         return !isempty(c->signature);
4154 }
4155
4156 static int message_read_ap(
4157                 sd_bus_message *m,
4158                 const char *types,
4159                 va_list ap) {
4160
4161         unsigned n_array, n_struct;
4162         TypeStack stack[BUS_CONTAINER_DEPTH];
4163         unsigned stack_ptr = 0;
4164         unsigned n_loop = 0;
4165         int r;
4166
4167         assert(m);
4168
4169         if (isempty(types))
4170                 return 0;
4171
4172         /* Ideally, we'd just call ourselves recursively on every
4173          * complex type. However, the state of a va_list that is
4174          * passed to a function is undefined after that function
4175          * returns. This means we need to docode the va_list linearly
4176          * in a single stackframe. We hence implement our own
4177          * home-grown stack in an array. */
4178
4179         n_array = (unsigned) -1; /* lenght of current array entries */
4180         n_struct = strlen(types); /* length of current struct contents signature */
4181
4182         for (;;) {
4183                 const char *t;
4184
4185                 n_loop++;
4186
4187                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
4188                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
4189                         if (r < 0)
4190                                 return r;
4191                         if (r == 0)
4192                                 break;
4193
4194                         r = sd_bus_message_exit_container(m);
4195                         if (r < 0)
4196                                 return r;
4197
4198                         continue;
4199                 }
4200
4201                 t = types;
4202                 if (n_array != (unsigned) -1)
4203                         n_array --;
4204                 else {
4205                         types ++;
4206                         n_struct--;
4207                 }
4208
4209                 switch (*t) {
4210
4211                 case SD_BUS_TYPE_BYTE:
4212                 case SD_BUS_TYPE_BOOLEAN:
4213                 case SD_BUS_TYPE_INT16:
4214                 case SD_BUS_TYPE_UINT16:
4215                 case SD_BUS_TYPE_INT32:
4216                 case SD_BUS_TYPE_UINT32:
4217                 case SD_BUS_TYPE_INT64:
4218                 case SD_BUS_TYPE_UINT64:
4219                 case SD_BUS_TYPE_DOUBLE:
4220                 case SD_BUS_TYPE_STRING:
4221                 case SD_BUS_TYPE_OBJECT_PATH:
4222                 case SD_BUS_TYPE_SIGNATURE:
4223                 case SD_BUS_TYPE_UNIX_FD: {
4224                         void *p;
4225
4226                         p = va_arg(ap, void*);
4227                         r = sd_bus_message_read_basic(m, *t, p);
4228                         if (r < 0)
4229                                 return r;
4230                         if (r == 0) {
4231                                 if (n_loop <= 1)
4232                                         return 0;
4233
4234                                 return -ENXIO;
4235                         }
4236
4237                         break;
4238                 }
4239
4240                 case SD_BUS_TYPE_ARRAY: {
4241                         size_t k;
4242
4243                         r = signature_element_length(t + 1, &k);
4244                         if (r < 0)
4245                                 return r;
4246
4247                         {
4248                                 char s[k + 1];
4249                                 memcpy(s, t + 1, k);
4250                                 s[k] = 0;
4251
4252                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4253                                 if (r < 0)
4254                                         return r;
4255                                 if (r == 0) {
4256                                         if (n_loop <= 1)
4257                                                 return 0;
4258
4259                                         return -ENXIO;
4260                                 }
4261                         }
4262
4263                         if (n_array == (unsigned) -1) {
4264                                 types += k;
4265                                 n_struct -= k;
4266                         }
4267
4268                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4269                         if (r < 0)
4270                                 return r;
4271
4272                         types = t + 1;
4273                         n_struct = k;
4274                         n_array = va_arg(ap, unsigned);
4275
4276                         break;
4277                 }
4278
4279                 case SD_BUS_TYPE_VARIANT: {
4280                         const char *s;
4281
4282                         s = va_arg(ap, const char *);
4283                         if (!s)
4284                                 return -EINVAL;
4285
4286                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
4287                         if (r < 0)
4288                                 return r;
4289                         if (r == 0) {
4290                                 if (n_loop <= 1)
4291                                         return 0;
4292
4293                                 return -ENXIO;
4294                         }
4295
4296                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4297                         if (r < 0)
4298                                 return r;
4299
4300                         types = s;
4301                         n_struct = strlen(s);
4302                         n_array = (unsigned) -1;
4303
4304                         break;
4305                 }
4306
4307                 case SD_BUS_TYPE_STRUCT_BEGIN:
4308                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4309                         size_t k;
4310
4311                         r = signature_element_length(t, &k);
4312                         if (r < 0)
4313                                 return r;
4314
4315                         {
4316                                 char s[k - 1];
4317                                 memcpy(s, t + 1, k - 2);
4318                                 s[k - 2] = 0;
4319
4320                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4321                                 if (r < 0)
4322                                         return r;
4323                                 if (r == 0) {
4324                                         if (n_loop <= 1)
4325                                                 return 0;
4326                                         return -ENXIO;
4327                                 }
4328                         }
4329
4330                         if (n_array == (unsigned) -1) {
4331                                 types += k - 1;
4332                                 n_struct -= k - 1;
4333                         }
4334
4335                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
4336                         if (r < 0)
4337                                 return r;
4338
4339                         types = t + 1;
4340                         n_struct = k - 2;
4341                         n_array = (unsigned) -1;
4342
4343                         break;
4344                 }
4345
4346                 default:
4347                         return -EINVAL;
4348                 }
4349         }
4350
4351         return 1;
4352 }
4353
4354 _public_ int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
4355         va_list ap;
4356         int r;
4357
4358         assert_return(m, -EINVAL);
4359         assert_return(m->sealed, -EPERM);
4360         assert_return(types, -EINVAL);
4361
4362         va_start(ap, types);
4363         r = message_read_ap(m, types, ap);
4364         va_end(ap);
4365
4366         return r;
4367 }
4368
4369 _public_ int sd_bus_message_skip(sd_bus_message *m, const char *types) {
4370         int r;
4371
4372         assert_return(m, -EINVAL);
4373         assert_return(m->sealed, -EPERM);
4374         assert_return(types, -EINVAL);
4375
4376         if (isempty(types))
4377                 return 0;
4378
4379         switch (*types) {
4380
4381         case SD_BUS_TYPE_BYTE:
4382         case SD_BUS_TYPE_BOOLEAN:
4383         case SD_BUS_TYPE_INT16:
4384         case SD_BUS_TYPE_UINT16:
4385         case SD_BUS_TYPE_INT32:
4386         case SD_BUS_TYPE_UINT32:
4387         case SD_BUS_TYPE_INT64:
4388         case SD_BUS_TYPE_UINT64:
4389         case SD_BUS_TYPE_DOUBLE:
4390         case SD_BUS_TYPE_STRING:
4391         case SD_BUS_TYPE_OBJECT_PATH:
4392         case SD_BUS_TYPE_SIGNATURE:
4393         case SD_BUS_TYPE_UNIX_FD:
4394
4395                 r = sd_bus_message_read_basic(m, *types, NULL);
4396                 if (r <= 0)
4397                         return r;
4398
4399                 r = sd_bus_message_skip(m, types + 1);
4400                 if (r < 0)
4401                         return r;
4402
4403                 return 1;
4404
4405         case SD_BUS_TYPE_ARRAY: {
4406                 size_t k;
4407
4408                 r = signature_element_length(types + 1, &k);
4409                 if (r < 0)
4410                         return r;
4411
4412                 {
4413                         char s[k+1];
4414                         memcpy(s, types+1, k);
4415                         s[k] = 0;
4416
4417                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
4418                         if (r <= 0)
4419                                 return r;
4420
4421                         for (;;) {
4422                                 r = sd_bus_message_skip(m, s);
4423                                 if (r < 0)
4424                                         return r;
4425                                 if (r == 0)
4426                                         break;
4427                         }
4428
4429                         r = sd_bus_message_exit_container(m);
4430                         if (r < 0)
4431                                 return r;
4432                 }
4433
4434                 r = sd_bus_message_skip(m, types + 1 + k);
4435                 if (r < 0)
4436                         return r;
4437
4438                 return 1;
4439         }
4440
4441         case SD_BUS_TYPE_VARIANT: {
4442                 const char *contents;
4443                 char x;
4444
4445                 r = sd_bus_message_peek_type(m, &x, &contents);
4446                 if (r <= 0)
4447                         return r;
4448
4449                 if (x != SD_BUS_TYPE_VARIANT)
4450                         return -ENXIO;
4451
4452                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
4453                 if (r <= 0)
4454                         return r;
4455
4456                 r = sd_bus_message_skip(m, contents);
4457                 if (r < 0)
4458                         return r;
4459                 assert(r != 0);
4460
4461                 r = sd_bus_message_exit_container(m);
4462                 if (r < 0)
4463                         return r;
4464
4465                 r = sd_bus_message_skip(m, types + 1);
4466                 if (r < 0)
4467                         return r;
4468
4469                 return 1;
4470         }
4471
4472         case SD_BUS_TYPE_STRUCT_BEGIN:
4473         case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
4474                 size_t k;
4475
4476                 r = signature_element_length(types, &k);
4477                 if (r < 0)
4478                         return r;
4479
4480                 {
4481                         char s[k-1];
4482                         memcpy(s, types+1, k-2);
4483                         s[k-2] = 0;
4484
4485                         r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
4486                         if (r <= 0)
4487                                 return r;
4488
4489                         r = sd_bus_message_skip(m, s);
4490                         if (r < 0)
4491                                 return r;
4492                         assert(r != 0);
4493
4494                         r = sd_bus_message_exit_container(m);
4495                         if (r < 0)
4496                                 return r;
4497                 }
4498
4499                 r = sd_bus_message_skip(m, types + k);
4500                 if (r < 0)
4501                         return r;
4502
4503                 return 1;
4504         }
4505
4506         default:
4507                 return -EINVAL;
4508         }
4509 }
4510
4511 _public_ int sd_bus_message_read_array(sd_bus_message *m,
4512                                        char type,
4513                                        const void **ptr,
4514                                        size_t *size) {
4515         struct bus_container *c;
4516         void *p;
4517         size_t sz;
4518         ssize_t align;
4519         int r;
4520
4521         assert_return(m, -EINVAL);
4522         assert_return(m->sealed, -EPERM);
4523         assert_return(bus_type_is_trivial(type), -EINVAL);
4524         assert_return(ptr, -EINVAL);
4525         assert_return(size, -EINVAL);
4526         assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
4527
4528         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
4529         if (r <= 0)
4530                 return r;
4531
4532         c = message_get_container(m);
4533
4534         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4535                 align = bus_gvariant_get_alignment(CHAR_TO_STR(type));
4536                 if (align < 0)
4537                         return align;
4538
4539                 sz = c->end - c->begin;
4540         } else {
4541                 align = bus_type_get_alignment(type);
4542                 if (align < 0)
4543                         return align;
4544
4545                 sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
4546         }
4547
4548         if (sz == 0)
4549                 /* Zero length array, let's return some aligned
4550                  * pointer that is not NULL */
4551                 p = (uint8_t*) NULL + align;
4552         else {
4553                 r = message_peek_body(m, &m->rindex, align, sz, &p);
4554                 if (r < 0)
4555                         goto fail;
4556         }
4557
4558         r = sd_bus_message_exit_container(m);
4559         if (r < 0)
4560                 goto fail;
4561
4562         *ptr = (const void*) p;
4563         *size = sz;
4564
4565         return 1;
4566
4567 fail:
4568         message_quit_container(m);
4569         return r;
4570 }
4571
4572 static int message_peek_fields(
4573                 sd_bus_message *m,
4574                 size_t *rindex,
4575                 size_t align,
4576                 size_t nbytes,
4577                 void **ret) {
4578
4579         assert(m);
4580         assert(rindex);
4581         assert(align > 0);
4582
4583         return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
4584 }
4585
4586 static int message_peek_field_uint32(
4587                 sd_bus_message *m,
4588                 size_t *ri,
4589                 size_t item_size,
4590                 uint32_t *ret) {
4591
4592         int r;
4593         void *q;
4594
4595         assert(m);
4596         assert(ri);
4597
4598         if (BUS_MESSAGE_IS_GVARIANT(m) && item_size != 4)
4599                 return -EBADMSG;
4600
4601         /* identical for gvariant and dbus1 */
4602
4603         r = message_peek_fields(m, ri, 4, 4, &q);
4604         if (r < 0)
4605                 return r;
4606
4607         if (ret)
4608                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
4609
4610         return 0;
4611 }
4612
4613 static int message_peek_field_string(
4614                 sd_bus_message *m,
4615                 bool (*validate)(const char *p),
4616                 size_t *ri,
4617                 size_t item_size,
4618                 const char **ret) {
4619
4620         uint32_t l;
4621         int r;
4622         void *q;
4623
4624         assert(m);
4625         assert(ri);
4626
4627         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4628
4629                 if (item_size <= 0)
4630                         return -EBADMSG;
4631
4632                 r = message_peek_fields(m, ri, 1, item_size, &q);
4633                 if (r < 0)
4634                         return r;
4635
4636                 l = item_size - 1;
4637         } else {
4638                 r = message_peek_field_uint32(m, ri, 4, &l);
4639                 if (r < 0)
4640                         return r;
4641
4642                 r = message_peek_fields(m, ri, 1, l+1, &q);
4643                 if (r < 0)
4644                         return r;
4645         }
4646
4647         if (validate) {
4648                 if (!validate_nul(q, l))
4649                         return -EBADMSG;
4650
4651                 if (!validate(q))
4652                         return -EBADMSG;
4653         } else {
4654                 if (!validate_string(q, l))
4655                         return -EBADMSG;
4656         }
4657
4658         if (ret)
4659                 *ret = q;
4660
4661         return 0;
4662 }
4663
4664 static int message_peek_field_signature(
4665                 sd_bus_message *m,
4666                 size_t *ri,
4667                 size_t item_size,
4668                 const char **ret) {
4669
4670         size_t l;
4671         int r;
4672         void *q;
4673
4674         assert(m);
4675         assert(ri);
4676
4677         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4678
4679                 if (item_size <= 0)
4680                         return -EBADMSG;
4681
4682                 r = message_peek_fields(m, ri, 1, item_size, &q);
4683                 if (r < 0)
4684                         return r;
4685
4686                 l = item_size - 1;
4687         } else {
4688                 r = message_peek_fields(m, ri, 1, 1, &q);
4689                 if (r < 0)
4690                         return r;
4691
4692                 l = *(uint8_t*) q;
4693                 r = message_peek_fields(m, ri, 1, l+1, &q);
4694                 if (r < 0)
4695                         return r;
4696         }
4697
4698         if (!validate_signature(q, l))
4699                 return -EBADMSG;
4700
4701         if (ret)
4702                 *ret = q;
4703
4704         return 0;
4705 }
4706
4707 static int message_skip_fields(
4708                 sd_bus_message *m,
4709                 size_t *ri,
4710                 uint32_t array_size,
4711                 const char **signature) {
4712
4713         size_t original_index;
4714         int r;
4715
4716         assert(m);
4717         assert(ri);
4718         assert(signature);
4719         assert(!BUS_MESSAGE_IS_GVARIANT(m));
4720
4721         original_index = *ri;
4722
4723         for (;;) {
4724                 char t;
4725                 size_t l;
4726
4727                 if (array_size != (uint32_t) -1 &&
4728                     array_size <= *ri - original_index)
4729                         return 0;
4730
4731                 t = **signature;
4732                 if (!t)
4733                         return 0;
4734
4735                 if (t == SD_BUS_TYPE_STRING) {
4736
4737                         r = message_peek_field_string(m, NULL, ri, 0, NULL);
4738                         if (r < 0)
4739                                 return r;
4740
4741                         (*signature)++;
4742
4743                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
4744
4745                         r = message_peek_field_string(m, object_path_is_valid, ri, 0, NULL);
4746                         if (r < 0)
4747                                 return r;
4748
4749                         (*signature)++;
4750
4751                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
4752
4753                         r = message_peek_field_signature(m, ri, 0, NULL);
4754                         if (r < 0)
4755                                 return r;
4756
4757                         (*signature)++;
4758
4759                 } else if (bus_type_is_basic(t)) {
4760                         ssize_t align, k;
4761
4762                         align = bus_type_get_alignment(t);
4763                         k = bus_type_get_size(t);
4764                         assert(align > 0 && k > 0);
4765
4766                         r = message_peek_fields(m, ri, align, k, NULL);
4767                         if (r < 0)
4768                                 return r;
4769
4770                         (*signature)++;
4771
4772                 } else if (t == SD_BUS_TYPE_ARRAY) {
4773
4774                         r = signature_element_length(*signature+1, &l);
4775                         if (r < 0)
4776                                 return r;
4777
4778                         assert(l >= 1);
4779                         {
4780                                 char sig[l-1], *s;
4781                                 uint32_t nas;
4782                                 int alignment;
4783
4784                                 strncpy(sig, *signature + 1, l-1);
4785                                 s = sig;
4786
4787                                 alignment = bus_type_get_alignment(sig[0]);
4788                                 if (alignment < 0)
4789                                         return alignment;
4790
4791                                 r = message_peek_field_uint32(m, ri, 0, &nas);
4792                                 if (r < 0)
4793                                         return r;
4794                                 if (nas > BUS_ARRAY_MAX_SIZE)
4795                                         return -EBADMSG;
4796
4797                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
4798                                 if (r < 0)
4799                                         return r;
4800
4801                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
4802                                 if (r < 0)
4803                                         return r;
4804                         }
4805
4806                         (*signature) += 1 + l;
4807
4808                 } else if (t == SD_BUS_TYPE_VARIANT) {
4809                         const char *s;
4810
4811                         r = message_peek_field_signature(m, ri, 0, &s);
4812                         if (r < 0)
4813                                 return r;
4814
4815                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4816                         if (r < 0)
4817                                 return r;
4818
4819                         (*signature)++;
4820
4821                 } else if (t == SD_BUS_TYPE_STRUCT ||
4822                            t == SD_BUS_TYPE_DICT_ENTRY) {
4823
4824                         r = signature_element_length(*signature, &l);
4825                         if (r < 0)
4826                                 return r;
4827
4828                         assert(l >= 2);
4829                         {
4830                                 char sig[l-1], *s;
4831                                 strncpy(sig, *signature + 1, l-1);
4832                                 s = sig;
4833
4834                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
4835                                 if (r < 0)
4836                                         return r;
4837                         }
4838
4839                         *signature += l;
4840                 } else
4841                         return -EINVAL;
4842         }
4843 }
4844
4845 int bus_message_parse_fields(sd_bus_message *m) {
4846         size_t ri;
4847         int r;
4848         uint32_t unix_fds = 0;
4849         void *offsets = NULL;
4850         unsigned n_offsets = 0;
4851         size_t sz;
4852         unsigned i = 0;
4853
4854         assert(m);
4855
4856         if (BUS_MESSAGE_IS_GVARIANT(m)) {
4857                 void *q;
4858
4859                 sz = determine_word_size(BUS_MESSAGE_FIELDS_SIZE(m), 0);
4860                 if (sz > 0) {
4861                         size_t framing;
4862
4863                         ri = BUS_MESSAGE_FIELDS_SIZE(m) - sz;
4864                         r = message_peek_fields(m, &ri, 1, sz, &q);
4865                         if (r < 0)
4866                                 return r;
4867
4868                         framing = read_word_le(q, sz);
4869                         if (framing >= BUS_MESSAGE_FIELDS_SIZE(m) - sz)
4870                                 return -EBADMSG;
4871                         if ((BUS_MESSAGE_FIELDS_SIZE(m) - framing) % sz != 0)
4872                                 return -EBADMSG;
4873
4874                         ri = framing;
4875                         r = message_peek_fields(m, &ri, 1, BUS_MESSAGE_FIELDS_SIZE(m) - framing, &offsets);
4876                         if (r < 0)
4877                                 return r;
4878
4879                         n_offsets = (BUS_MESSAGE_FIELDS_SIZE(m) - framing) / sz;
4880                 }
4881         }
4882
4883         ri = 0;
4884         while (ri < BUS_MESSAGE_FIELDS_SIZE(m)) {
4885                 _cleanup_free_ char *sig = NULL;
4886                 const char *signature;
4887                 uint8_t *header;
4888                 size_t item_size = (size_t) -1;
4889
4890                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4891                         if (i >= n_offsets)
4892                                 break;
4893
4894                         if (i == 0)
4895                                 ri = 0;
4896                         else
4897                                 ri = ALIGN_TO(read_word_le((uint8_t*) offsets + (i-1)*sz, sz), 8);
4898                 }
4899
4900                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
4901                 if (r < 0)
4902                         return r;
4903
4904                 if (BUS_MESSAGE_IS_GVARIANT(m)) {
4905                         size_t where, end;
4906                         char *b;
4907                         void *q;
4908
4909                         end = read_word_le((uint8_t*) offsets + i*sz, sz);
4910
4911                         if (end < ri)
4912                                 return -EBADMSG;
4913
4914                         where = ri = ALIGN_TO(ri, 8);
4915                         item_size = end - ri;
4916                         r = message_peek_fields(m, &where, 1, item_size, &q);
4917                         if (r < 0)
4918                                 return r;
4919
4920                         b = memrchr(q, 0, item_size);
4921                         if (!b)
4922                                 return -EBADMSG;
4923
4924                         sig = strndup(b+1, item_size - (b+1-(char*) q));
4925                         if (!sig)
4926                                 return -ENOMEM;
4927
4928                         signature = sig;
4929                         item_size = b - (char*) q;
4930                 } else {
4931                         r = message_peek_field_signature(m, &ri, 0, &signature);
4932                         if (r < 0)
4933                                 return r;
4934                 }
4935
4936                 switch (*header) {
4937                 case _BUS_MESSAGE_HEADER_INVALID:
4938                         return -EBADMSG;
4939
4940                 case BUS_MESSAGE_HEADER_PATH:
4941
4942                         if (m->path)
4943                                 return -EBADMSG;
4944
4945                         if (!streq(signature, "o"))
4946                                 return -EBADMSG;
4947
4948                         r = message_peek_field_string(m, object_path_is_valid, &ri, item_size, &m->path);
4949                         break;
4950
4951                 case BUS_MESSAGE_HEADER_INTERFACE:
4952
4953                         if (m->interface)
4954                                 return -EBADMSG;
4955
4956                         if (!streq(signature, "s"))
4957                                 return -EBADMSG;
4958
4959                         r = message_peek_field_string(m, interface_name_is_valid, &ri, item_size, &m->interface);
4960                         break;
4961
4962                 case BUS_MESSAGE_HEADER_MEMBER:
4963
4964                         if (m->member)
4965                                 return -EBADMSG;
4966
4967                         if (!streq(signature, "s"))
4968                                 return -EBADMSG;
4969
4970                         r = message_peek_field_string(m, member_name_is_valid, &ri, item_size, &m->member);
4971                         break;
4972
4973                 case BUS_MESSAGE_HEADER_ERROR_NAME:
4974
4975                         if (m->error.name)
4976                                 return -EBADMSG;
4977
4978                         if (!streq(signature, "s"))
4979                                 return -EBADMSG;
4980
4981                         r = message_peek_field_string(m, error_name_is_valid, &ri, item_size, &m->error.name);
4982                         if (r >= 0)
4983                                 m->error._need_free = -1;
4984
4985                         break;
4986
4987                 case BUS_MESSAGE_HEADER_DESTINATION:
4988
4989                         if (m->destination)
4990                                 return -EBADMSG;
4991
4992                         if (!streq(signature, "s"))
4993                                 return -EBADMSG;
4994
4995                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->destination);
4996                         break;
4997
4998                 case BUS_MESSAGE_HEADER_SENDER:
4999
5000                         if (m->sender)
5001                                 return -EBADMSG;
5002
5003                         if (!streq(signature, "s"))
5004                                 return -EBADMSG;
5005
5006                         r = message_peek_field_string(m, service_name_is_valid, &ri, item_size, &m->sender);
5007
5008                         if (r >= 0 && m->sender[0] == ':' && m->bus && m->bus->bus_client && !m->bus->is_kernel) {
5009                                 m->creds.unique_name = (char*) m->sender;
5010                                 m->creds.mask |= SD_BUS_CREDS_UNIQUE_NAME & m->bus->creds_mask;
5011                         }
5012
5013                         break;
5014
5015
5016                 case BUS_MESSAGE_HEADER_SIGNATURE: {
5017                         const char *s;
5018                         char *c;
5019
5020                         if (m->root_container.signature)
5021                                 return -EBADMSG;
5022
5023                         if (!streq(signature, "g"))
5024                                 return -EBADMSG;
5025
5026                         r = message_peek_field_signature(m, &ri, item_size, &s);
5027                         if (r < 0)
5028                                 return r;
5029
5030                         c = strdup(s);
5031                         if (!c)
5032                                 return -ENOMEM;
5033
5034                         free(m->root_container.signature);
5035                         m->root_container.signature = c;
5036                         break;
5037                 }
5038
5039                 case BUS_MESSAGE_HEADER_REPLY_SERIAL:
5040                         if (m->reply_serial != 0)
5041                                 return -EBADMSG;
5042
5043                         if (!streq(signature, "u"))
5044                                 return -EBADMSG;
5045
5046                         r = message_peek_field_uint32(m, &ri, item_size, &m->reply_serial);
5047                         if (r < 0)
5048                                 return r;
5049
5050                         if (m->reply_serial == 0)
5051                                 return -EBADMSG;
5052
5053                         break;
5054
5055                 case BUS_MESSAGE_HEADER_UNIX_FDS:
5056                         if (unix_fds != 0)
5057                                 return -EBADMSG;
5058
5059                         if (!streq(signature, "u"))
5060                                 return -EBADMSG;
5061
5062                         r = message_peek_field_uint32(m, &ri, item_size, &unix_fds);
5063                         if (r < 0)
5064                                 return -EBADMSG;
5065
5066                         if (unix_fds == 0)
5067                                 return -EBADMSG;
5068
5069                         break;
5070
5071                 default:
5072                         if (!BUS_MESSAGE_IS_GVARIANT(m))
5073                                 r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
5074                 }
5075
5076                 if (r < 0)
5077                         return r;
5078
5079                 i++;
5080         }
5081
5082         if (m->n_fds != unix_fds)
5083                 return -EBADMSG;
5084
5085         if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
5086                 return -EBADMSG;
5087
5088         switch (m->header->type) {
5089
5090         case SD_BUS_MESSAGE_SIGNAL:
5091                 if (!m->path || !m->interface || !m->member)
5092                         return -EBADMSG;
5093                 break;
5094
5095         case SD_BUS_MESSAGE_METHOD_CALL:
5096
5097                 if (!m->path || !m->member)
5098                         return -EBADMSG;
5099
5100                 break;
5101
5102         case SD_BUS_MESSAGE_METHOD_RETURN:
5103
5104                 if (m->reply_serial == 0)
5105                         return -EBADMSG;
5106                 break;
5107
5108         case SD_BUS_MESSAGE_METHOD_ERROR:
5109
5110                 if (m->reply_serial == 0 || !m->error.name)
5111                         return -EBADMSG;
5112                 break;
5113         }
5114
5115         m->root_container.end = BUS_MESSAGE_BODY_SIZE(m);
5116
5117         if (BUS_MESSAGE_IS_GVARIANT(m)) {
5118                 r = build_struct_offsets(
5119                                 m,
5120                                 m->root_container.signature,
5121                                 BUS_MESSAGE_BODY_SIZE(m),
5122                                 &m->root_container.item_size,
5123                                 &m->root_container.offsets,
5124                                 &m->root_container.n_offsets);
5125                 if (r < 0)
5126                         return r;
5127         }
5128
5129         /* Try to read the error message, but if we can't it's a non-issue */
5130         if (m->header->type == SD_BUS_MESSAGE_METHOD_ERROR)
5131                 sd_bus_message_read(m, "s", &m->error.message);
5132
5133         return 0;
5134 }
5135
5136 _public_ int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
5137         assert_return(m, -EINVAL);
5138         assert_return(destination, -EINVAL);
5139         assert_return(!m->sealed, -EPERM);
5140         assert_return(!m->destination, -EEXIST);
5141
5142         return message_append_field_string(m, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
5143 }
5144
5145 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
5146         size_t total;
5147         void *p, *e;
5148         unsigned i;
5149         struct bus_body_part *part;
5150
5151         assert(m);
5152         assert(buffer);
5153         assert(sz);
5154
5155         total = BUS_MESSAGE_SIZE(m);
5156
5157         p = malloc(total);
5158         if (!p)
5159                 return -ENOMEM;
5160
5161         e = mempcpy(p, m->header, BUS_MESSAGE_BODY_BEGIN(m));
5162         MESSAGE_FOREACH_PART(part, i, m)
5163                 e = mempcpy(e, part->data, part->size);
5164
5165         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
5166
5167         *buffer = p;
5168         *sz = total;
5169
5170         return 0;
5171 }
5172
5173 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
5174         int r;
5175
5176         assert(m);
5177         assert(l);
5178
5179         r = sd_bus_message_enter_container(m, 'a', "s");
5180         if (r <= 0)
5181                 return r;
5182
5183         for (;;) {
5184                 const char *s;
5185
5186                 r = sd_bus_message_read_basic(m, 's', &s);
5187                 if (r < 0)
5188                         return r;
5189                 if (r == 0)
5190                         break;
5191
5192                 r = strv_extend(l, s);
5193                 if (r < 0)
5194                         return r;
5195         }
5196
5197         r = sd_bus_message_exit_container(m);
5198         if (r < 0)
5199                 return r;
5200
5201         return 1;
5202 }
5203
5204 _public_ int sd_bus_message_read_strv(sd_bus_message *m, char ***l) {
5205         char **strv = NULL;
5206         int r;
5207
5208         assert_return(m, -EINVAL);
5209         assert_return(m->sealed, -EPERM);
5210         assert_return(l, -EINVAL);
5211
5212         r = bus_message_read_strv_extend(m, &strv);
5213         if (r <= 0) {
5214                 strv_free(strv);
5215                 return r;
5216         }
5217
5218         *l = strv;
5219         return 1;
5220 }
5221
5222 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
5223         int r;
5224         const char *t = NULL;
5225         unsigned j;
5226
5227         assert(m);
5228
5229         r = sd_bus_message_rewind(m, true);
5230         if (r < 0)
5231                 return NULL;
5232
5233         for (j = 0; j <= i; j++) {
5234                 char type;
5235
5236                 r = sd_bus_message_peek_type(m, &type, NULL);
5237                 if (r < 0)
5238                         return NULL;
5239
5240                 if (type != SD_BUS_TYPE_STRING &&
5241                     type != SD_BUS_TYPE_OBJECT_PATH &&
5242                     type != SD_BUS_TYPE_SIGNATURE)
5243                         return NULL;
5244
5245                 r = sd_bus_message_read_basic(m, type, &t);
5246                 if (r < 0)
5247                         return NULL;
5248         }
5249
5250         return t;
5251 }
5252
5253 bool bus_header_is_complete(struct bus_header *h, size_t size) {
5254         size_t full;
5255
5256         assert(h);
5257         assert(size);
5258
5259         if (size < sizeof(struct bus_header))
5260                 return false;
5261
5262         full = sizeof(struct bus_header) +
5263                 (h->endian == BUS_NATIVE_ENDIAN ? h->fields_size : bswap_32(h->fields_size));
5264
5265         return size >= full;
5266 }
5267
5268 int bus_header_message_size(struct bus_header *h, size_t *sum) {
5269         size_t fs, bs;
5270
5271         assert(h);
5272         assert(sum);
5273
5274         if (h->endian == BUS_NATIVE_ENDIAN) {
5275                 fs = h->fields_size;
5276                 bs = h->body_size;
5277         } else if (h->endian == BUS_REVERSE_ENDIAN) {
5278                 fs = bswap_32(h->fields_size);
5279                 bs = bswap_32(h->body_size);
5280         } else
5281                 return -EBADMSG;
5282
5283         *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
5284         return 0;
5285 }
5286
5287 _public_ int sd_bus_message_get_errno(sd_bus_message *m) {
5288         assert_return(m, -EINVAL);
5289
5290         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
5291                 return 0;
5292
5293         return sd_bus_error_get_errno(&m->error);
5294 }
5295
5296 _public_ const char* sd_bus_message_get_signature(sd_bus_message *m, int complete) {
5297         struct bus_container *c;
5298
5299         assert_return(m, NULL);
5300
5301         c = complete ? &m->root_container : message_get_container(m);
5302         return strempty(c->signature);
5303 }
5304
5305 _public_ int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all) {
5306         bool done_something = false;
5307         int r;
5308
5309         assert_return(m, -EINVAL);
5310         assert_return(source, -EINVAL);
5311         assert_return(!m->sealed, -EPERM);
5312         assert_return(source->sealed, -EPERM);
5313
5314         do {
5315                 const char *contents;
5316                 char type;
5317                 union {
5318                         uint8_t u8;
5319                         uint16_t u16;
5320                         int16_t s16;
5321                         uint32_t u32;
5322                         int32_t s32;
5323                         uint64_t u64;
5324                         int64_t s64;
5325                         double d64;
5326                         const char *string;
5327                         int i;
5328                 } basic;
5329
5330                 r = sd_bus_message_peek_type(source, &type, &contents);
5331                 if (r < 0)
5332                         return r;
5333                 if (r == 0)
5334                         break;
5335
5336                 done_something = true;
5337
5338                 if (bus_type_is_container(type) > 0) {
5339
5340                         r = sd_bus_message_enter_container(source, type, contents);
5341                         if (r < 0)
5342                                 return r;
5343
5344                         r = sd_bus_message_open_container(m, type, contents);
5345                         if (r < 0)
5346                                 return r;
5347
5348                         r = sd_bus_message_copy(m, source, true);
5349                         if (r < 0)
5350                                 return r;
5351
5352                         r = sd_bus_message_close_container(m);
5353                         if (r < 0)
5354                                 return r;
5355
5356                         r = sd_bus_message_exit_container(source);
5357                         if (r < 0)
5358                                 return r;
5359
5360                         continue;
5361                 }
5362
5363                 r = sd_bus_message_read_basic(source, type, &basic);
5364                 if (r < 0)
5365                         return r;
5366
5367                 assert(r > 0);
5368
5369                 if (type == SD_BUS_TYPE_OBJECT_PATH ||
5370                     type == SD_BUS_TYPE_SIGNATURE ||
5371                     type == SD_BUS_TYPE_STRING)
5372                         r = sd_bus_message_append_basic(m, type, basic.string);
5373                 else
5374                         r = sd_bus_message_append_basic(m, type, &basic);
5375
5376                 if (r < 0)
5377                         return r;
5378
5379         } while (all);
5380
5381         return done_something;
5382 }
5383
5384 _public_ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents) {
5385         const char *c;
5386         char t;
5387         int r;
5388
5389         assert_return(m, -EINVAL);
5390         assert_return(m->sealed, -EPERM);
5391         assert_return(!type || bus_type_is_valid(type), -EINVAL);
5392         assert_return(!contents || signature_is_valid(contents, true), -EINVAL);
5393         assert_return(type || contents, -EINVAL);
5394         assert_return(!contents || !type || bus_type_is_container(type), -EINVAL);
5395
5396         r = sd_bus_message_peek_type(m, &t, &c);
5397         if (r <= 0)
5398                 return r;
5399
5400         if (type != 0 && type != t)
5401                 return 0;
5402
5403         if (contents && !streq_ptr(contents, c))
5404                 return 0;
5405
5406         return 1;
5407 }
5408
5409 _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
5410         assert_return(m, NULL);
5411
5412         return m->bus;
5413 }