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