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