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