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