chiark / gitweb /
437f6dfd49d89840e1fbe716d7409eb0e7afeac0
[elogind.git] / src / libsystemd-bus / bus-message.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <sys/mman.h>
25
26 #include "util.h"
27 #include "utf8.h"
28 #include "strv.h"
29 #include "time-util.h"
30 #include "cgroup-util.h"
31
32 #include "sd-bus.h"
33 #include "bus-message.h"
34 #include "bus-internal.h"
35 #include "bus-type.h"
36 #include "bus-signature.h"
37
38 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
39
40 static void *adjust_pointer(const void *p, void *old_base, size_t sz, void *new_base) {
41
42         if (p == NULL)
43                 return NULL;
44
45         if (old_base == new_base)
46                 return (void*) p;
47
48         if ((uint8_t*) p < (uint8_t*) old_base)
49                 return (void*) p;
50
51         if ((uint8_t*) p >= (uint8_t*) old_base + sz)
52                 return (void*) p;
53
54         return (uint8_t*) new_base + ((uint8_t*) p - (uint8_t*) old_base);
55 }
56
57 static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
58         assert(m);
59         assert(part);
60
61         if (part->memfd >= 0) {
62                 /* If we can reuse the memfd, try that. For that it
63                  * can't be sealed yet. */
64
65                 if (!part->sealed)
66                         bus_kernel_push_memfd(m->bus, part->memfd, part->data, part->mapped);
67                 else {
68                         if (part->mapped > 0)
69                                 assert_se(munmap(part->data, part->mapped) == 0);
70
71                         close_nointr_nofail(part->memfd);
72                 }
73
74         } else if (part->munmap_this)
75                 munmap(part->data, part->mapped);
76         else if (part->free_this)
77                 free(part->data);
78
79         if (part != &m->body)
80                 free(part);
81 }
82
83 static void message_reset_parts(sd_bus_message *m) {
84         struct bus_body_part *part;
85
86         assert(m);
87
88         part = &m->body;
89         while (m->n_body_parts > 0) {
90                 struct bus_body_part *next = part->next;
91                 message_free_part(m, part);
92                 part = next;
93                 m->n_body_parts--;
94         }
95
96         m->body_end = NULL;
97
98         m->cached_rindex_part = NULL;
99         m->cached_rindex_part_begin = 0;
100 }
101
102 static void message_reset_containers(sd_bus_message *m) {
103         unsigned i;
104
105         assert(m);
106
107         for (i = 0; i < m->n_containers; i++)
108                 free(m->containers[i].signature);
109
110         free(m->containers);
111         m->containers = NULL;
112
113         m->n_containers = 0;
114         m->root_container.index = 0;
115 }
116
117 static void message_free(sd_bus_message *m) {
118         assert(m);
119
120         if (m->free_header)
121                 free(m->header);
122
123         message_reset_parts(m);
124
125         if (m->free_kdbus)
126                 free(m->kdbus);
127
128         if (m->release_kdbus) {
129                 uint64_t off;
130
131                 off = (uint8_t *)m->kdbus - (uint8_t *)m->bus->kdbus_buffer;
132                 ioctl(m->bus->input_fd, KDBUS_CMD_MSG_RELEASE, &off);
133         }
134
135         if (m->bus)
136                 sd_bus_unref(m->bus);
137
138         if (m->free_fds) {
139                 close_many(m->fds, m->n_fds);
140                 free(m->fds);
141         }
142
143         if (m->iovec != m->iovec_fixed)
144                 free(m->iovec);
145
146         free(m->cmdline_array);
147
148         message_reset_containers(m);
149         free(m->root_container.signature);
150
151         free(m->peeked_signature);
152
153         free(m->unit);
154         free(m->user_unit);
155         free(m->session);
156         free(m);
157 }
158
159 static void *message_extend_fields(sd_bus_message *m, size_t align, size_t sz) {
160         void *op, *np;
161         size_t old_size, new_size, start;
162
163         assert(m);
164
165         if (m->poisoned)
166                 return NULL;
167
168         old_size = sizeof(struct bus_header) + m->header->fields_size;
169         start = ALIGN_TO(old_size, align);
170         new_size = start + sz;
171
172         if (old_size == new_size)
173                 return (uint8_t*) m->header + old_size;
174
175         if (new_size > (size_t) ((uint32_t) -1))
176                 goto poison;
177
178         if (m->free_header) {
179                 np = realloc(m->header, ALIGN8(new_size));
180                 if (!np)
181                         goto poison;
182         } else {
183                 /* Initially, the header is allocated as part of of
184                  * the sd_bus_message itself, let's replace it by
185                  * dynamic data */
186
187                 np = malloc(ALIGN8(new_size));
188                 if (!np)
189                         goto poison;
190
191                 memcpy(np, m->header, sizeof(struct bus_header));
192         }
193
194         /* Zero out padding */
195         if (start > old_size)
196                 memset((uint8_t*) np + old_size, 0, start - old_size);
197
198         op = m->header;
199         m->header = np;
200         m->header->fields_size = new_size - sizeof(struct bus_header);
201
202         /* Adjust quick access pointers */
203         m->path = adjust_pointer(m->path, op, old_size, m->header);
204         m->interface = adjust_pointer(m->interface, op, old_size, m->header);
205         m->member = adjust_pointer(m->member, op, old_size, m->header);
206         m->destination = adjust_pointer(m->destination, op, old_size, m->header);
207         m->sender = adjust_pointer(m->sender, op, old_size, m->header);
208         m->error.name = adjust_pointer(m->error.name, op, old_size, m->header);
209
210         m->free_header = true;
211
212         return (uint8_t*) np + start;
213
214 poison:
215         m->poisoned = true;
216         return NULL;
217 }
218
219 static int message_append_field_string(
220                 sd_bus_message *m,
221                 uint8_t h,
222                 char type,
223                 const char *s,
224                 const char **ret) {
225
226         size_t l;
227         uint8_t *p;
228
229         assert(m);
230
231         l = strlen(s);
232         if (l > (size_t) (uint32_t) -1)
233                 return -EINVAL;
234
235         /* field id byte + signature length + signature 's' + NUL + string length + string + NUL */
236         p = message_extend_fields(m, 8, 4 + 4 + l + 1);
237         if (!p)
238                 return -ENOMEM;
239
240         p[0] = h;
241         p[1] = 1;
242         p[2] = type;
243         p[3] = 0;
244
245         ((uint32_t*) p)[1] = l;
246         memcpy(p + 8, s, l + 1);
247
248         if (ret)
249                 *ret = (char*) p + 8;
250
251         return 0;
252 }
253
254 static int message_append_field_signature(
255                 sd_bus_message *m,
256                 uint8_t h,
257                 const char *s,
258                 const char **ret) {
259
260         size_t l;
261         uint8_t *p;
262
263         assert(m);
264
265         l = strlen(s);
266         if (l > 255)
267                 return -EINVAL;
268
269         /* field id byte + signature length + signature 'g' + NUL + string length + string + NUL */
270         p = message_extend_fields(m, 8, 4 + 1 + l + 1);
271         if (!p)
272                 return -ENOMEM;
273
274         p[0] = h;
275         p[1] = 1;
276         p[2] = SD_BUS_TYPE_SIGNATURE;
277         p[3] = 0;
278         p[4] = l;
279         memcpy(p + 5, s, l + 1);
280
281         if (ret)
282                 *ret = (const char*) p + 5;
283
284         return 0;
285 }
286
287 static int message_append_field_uint32(sd_bus_message *m, uint8_t h, uint32_t x) {
288         uint8_t *p;
289
290         assert(m);
291
292         /* field id byte + signature length + signature 'u' + NUL + value */
293         p = message_extend_fields(m, 8, 4 + 4);
294         if (!p)
295                 return -ENOMEM;
296
297         p[0] = h;
298         p[1] = 1;
299         p[2] = SD_BUS_TYPE_UINT32;
300         p[3] = 0;
301
302         ((uint32_t*) p)[1] = x;
303
304         return 0;
305 }
306
307 int bus_message_from_header(
308                 void *buffer,
309                 size_t length,
310                 int *fds,
311                 unsigned n_fds,
312                 const struct ucred *ucred,
313                 const char *label,
314                 size_t extra,
315                 sd_bus_message **ret) {
316
317         sd_bus_message *m;
318         struct bus_header *h;
319         size_t a, label_sz;
320
321         assert(buffer || length <= 0);
322         assert(fds || n_fds <= 0);
323         assert(ret);
324
325         if (length < sizeof(struct bus_header))
326                 return -EBADMSG;
327
328         h = buffer;
329         if (h->version != 1)
330                 return -EBADMSG;
331
332         if (h->serial == 0)
333                 return -EBADMSG;
334
335         if (h->type == _SD_BUS_MESSAGE_TYPE_INVALID)
336                 return -EBADMSG;
337
338         if (h->endian != SD_BUS_LITTLE_ENDIAN &&
339             h->endian != SD_BUS_BIG_ENDIAN)
340                 return -EBADMSG;
341
342         a = ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
343
344         if (label) {
345                 label_sz = strlen(label);
346                 a += label_sz + 1;
347         }
348
349         m = malloc0(a);
350         if (!m)
351                 return -ENOMEM;
352
353         m->n_ref = 1;
354         m->sealed = true;
355         m->header = h;
356         m->fds = fds;
357         m->n_fds = n_fds;
358
359         if (ucred) {
360                 m->uid = ucred->uid;
361                 m->pid = ucred->pid;
362                 m->gid = ucred->gid;
363                 m->uid_valid = m->gid_valid = true;
364         }
365
366         if (label) {
367                 m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
368                 memcpy(m->label, label, label_sz + 1);
369         }
370
371         *ret = m;
372         return 0;
373 }
374
375 int bus_message_from_malloc(
376                 void *buffer,
377                 size_t length,
378                 int *fds,
379                 unsigned n_fds,
380                 const struct ucred *ucred,
381                 const char *label,
382                 sd_bus_message **ret) {
383
384         sd_bus_message *m;
385         int r;
386
387         r = bus_message_from_header(buffer, length, fds, n_fds, ucred, label, 0, &m);
388         if (r < 0)
389                 return r;
390
391         if (length != BUS_MESSAGE_SIZE(m)) {
392                 r = -EBADMSG;
393                 goto fail;
394         }
395
396         m->n_body_parts = 1;
397         m->body.data = (uint8_t*) buffer + sizeof(struct bus_header) + ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
398         m->body.size = length - sizeof(struct bus_header) - ALIGN8(BUS_MESSAGE_FIELDS_SIZE(m));
399         m->body.sealed = true;
400         m->body.memfd = -1;
401
402         m->n_iovec = 1;
403         m->iovec = m->iovec_fixed;
404         m->iovec[0].iov_base = buffer;
405         m->iovec[0].iov_len = length;
406
407         r = bus_message_parse_fields(m);
408         if (r < 0)
409                 goto fail;
410
411         /* We take possession of the memory and fds now */
412         m->free_header = true;
413         m->free_fds = true;
414
415         *ret = m;
416         return 0;
417
418 fail:
419         message_free(m);
420         return r;
421 }
422
423 static sd_bus_message *message_new(sd_bus *bus, uint8_t type) {
424         sd_bus_message *m;
425
426         m = malloc0(ALIGN(sizeof(sd_bus_message)) + sizeof(struct bus_header));
427         if (!m)
428                 return NULL;
429
430         m->n_ref = 1;
431         m->header = (struct bus_header*) ((uint8_t*) m + ALIGN(sizeof(struct sd_bus_message)));
432         m->header->endian = SD_BUS_NATIVE_ENDIAN;
433         m->header->type = type;
434         m->header->version = bus ? bus->message_version : 1;
435         m->allow_fds = !bus || bus->can_fds || (bus->state != BUS_HELLO && bus->state != BUS_RUNNING);
436
437         if (bus)
438                 m->bus = sd_bus_ref(bus);
439
440         return m;
441 }
442
443 int sd_bus_message_new_signal(
444                 sd_bus *bus,
445                 const char *path,
446                 const char *interface,
447                 const char *member,
448                 sd_bus_message **m) {
449
450         sd_bus_message *t;
451         int r;
452
453         assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
454         assert_return(object_path_is_valid(path), -EINVAL);
455         assert_return(interface_name_is_valid(interface), -EINVAL);
456         assert_return(member_name_is_valid(member), -EINVAL);
457         assert_return(m, -EINVAL);
458
459         t = message_new(bus, SD_BUS_MESSAGE_SIGNAL);
460         if (!t)
461                 return -ENOMEM;
462
463         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
464
465         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
466         if (r < 0)
467                 goto fail;
468         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
469         if (r < 0)
470                 goto fail;
471         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
472         if (r < 0)
473                 goto fail;
474
475         *m = t;
476         return 0;
477
478 fail:
479         sd_bus_message_unref(t);
480         return r;
481 }
482
483 int sd_bus_message_new_method_call(
484                 sd_bus *bus,
485                 const char *destination,
486                 const char *path,
487                 const char *interface,
488                 const char *member,
489                 sd_bus_message **m) {
490
491         sd_bus_message *t;
492         int r;
493
494         assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
495         assert_return(!destination || service_name_is_valid(destination), -EINVAL);
496         assert_return(object_path_is_valid(path), -EINVAL);
497         assert_return(!interface || interface_name_is_valid(interface), -EINVAL);
498         assert_return(member_name_is_valid(member), -EINVAL);
499         assert_return(m, -EINVAL);
500
501         t = message_new(bus, SD_BUS_MESSAGE_METHOD_CALL);
502         if (!t)
503                 return -ENOMEM;
504
505         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_PATH, SD_BUS_TYPE_OBJECT_PATH, path, &t->path);
506         if (r < 0)
507                 goto fail;
508         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_MEMBER, SD_BUS_TYPE_STRING, member, &t->member);
509         if (r < 0)
510                 goto fail;
511
512         if (interface) {
513                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_INTERFACE, SD_BUS_TYPE_STRING, interface, &t->interface);
514                 if (r < 0)
515                         goto fail;
516         }
517
518         if (destination) {
519                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &t->destination);
520                 if (r < 0)
521                         goto fail;
522         }
523
524         *m = t;
525         return 0;
526
527 fail:
528         message_free(t);
529         return r;
530 }
531
532 static int message_new_reply(
533                 sd_bus *bus,
534                 sd_bus_message *call,
535                 uint8_t type,
536                 sd_bus_message **m) {
537
538         sd_bus_message *t;
539         int r;
540
541         assert_return(!bus || bus->state != BUS_UNSET, -ENOTCONN);
542         assert_return(call, -EINVAL);
543         assert_return(call->sealed, -EPERM);
544         assert_return(call->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
545         assert_return(m, -EINVAL);
546
547         t = message_new(bus, type);
548         if (!t)
549                 return -ENOMEM;
550
551         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
552         t->reply_serial = BUS_MESSAGE_SERIAL(call);
553
554         r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
555         if (r < 0)
556                 goto fail;
557
558         if (call->sender) {
559                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, call->sender, &t->destination);
560                 if (r < 0)
561                         goto fail;
562         }
563
564         t->dont_send = !!(call->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED);
565
566         *m = t;
567         return 0;
568
569 fail:
570         message_free(t);
571         return r;
572 }
573
574 int sd_bus_message_new_method_return(
575                 sd_bus *bus,
576                 sd_bus_message *call,
577                 sd_bus_message **m) {
578
579         return message_new_reply(bus, call, SD_BUS_MESSAGE_METHOD_RETURN, m);
580 }
581
582 int sd_bus_message_new_method_error(
583                 sd_bus *bus,
584                 sd_bus_message *call,
585                 const sd_bus_error *e,
586                 sd_bus_message **m) {
587
588         sd_bus_message *t;
589         int r;
590
591         assert_return(sd_bus_error_is_set(e), -EINVAL);
592         assert_return(m, -EINVAL);
593
594         r = message_new_reply(bus, call, SD_BUS_MESSAGE_METHOD_ERROR, &t);
595         if (r < 0)
596                 return r;
597
598         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
599         if (r < 0)
600                 goto fail;
601
602         if (e->message) {
603                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
604                 if (r < 0)
605                         goto fail;
606         }
607
608         *m = t;
609         return 0;
610
611 fail:
612         message_free(t);
613         return r;
614 }
615
616 int sd_bus_message_new_method_errorf(
617                 sd_bus *bus,
618                 sd_bus_message *call,
619                 sd_bus_message **m,
620                 const char *name,
621                 const char *format,
622                 ...) {
623
624         _cleanup_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
625         va_list ap;
626         int r;
627
628         assert_return(name, -EINVAL);
629         assert_return(m, -EINVAL);
630
631         va_start(ap, format);
632         r = bus_error_setfv(&error, name, format, ap);
633         va_end(ap);
634
635         if (r < 0)
636                 return r;
637
638         return sd_bus_message_new_method_error(bus, call, &error, m);
639 }
640
641 int sd_bus_message_new_method_errno(
642                 sd_bus *bus,
643                 sd_bus_message *call,
644                 int error,
645                 const sd_bus_error *p,
646                 sd_bus_message **m) {
647
648         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
649
650         if (sd_bus_error_is_set(p))
651                 return sd_bus_message_new_method_error(bus, call, p, m);
652
653         sd_bus_error_set_errno(&berror, error);
654
655         return sd_bus_message_new_method_error(bus, call, &berror, m);
656 }
657
658 int sd_bus_message_new_method_errnof(
659                 sd_bus *bus,
660                 sd_bus_message *call,
661                 sd_bus_message **m,
662                 int error,
663                 const char *format,
664                 ...) {
665
666         _cleanup_free_ sd_bus_error berror = SD_BUS_ERROR_NULL;
667         va_list ap;
668         int r;
669
670         va_start(ap, format);
671         r = bus_error_set_errnofv(&berror, error, format, ap);
672         va_end(ap);
673
674         if (r < 0)
675                 return r;
676
677         return sd_bus_message_new_method_error(bus, call, &berror, m);
678 }
679
680 int bus_message_new_synthetic_error(
681                 sd_bus *bus,
682                 uint64_t serial,
683                 const sd_bus_error *e,
684                 sd_bus_message **m) {
685
686         sd_bus_message *t;
687         int r;
688
689         assert(sd_bus_error_is_set(e));
690         assert(m);
691
692         t = message_new(bus, SD_BUS_MESSAGE_METHOD_ERROR);
693         if (!t)
694                 return -ENOMEM;
695
696         t->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
697         t->reply_serial = serial;
698
699         r = message_append_field_uint32(t, SD_BUS_MESSAGE_HEADER_REPLY_SERIAL, t->reply_serial);
700         if (r < 0)
701                 goto fail;
702
703         if (bus && bus->unique_name) {
704                 r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, bus->unique_name, &t->destination);
705                 if (r < 0)
706                         goto fail;
707         }
708
709         r = message_append_field_string(t, SD_BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, e->name, &t->error.name);
710         if (r < 0)
711                 goto fail;
712
713         if (e->message) {
714                 r = message_append_basic(t, SD_BUS_TYPE_STRING, e->message, (const void**) &t->error.message);
715                 if (r < 0)
716                         goto fail;
717         }
718
719         *m = t;
720         return 0;
721
722 fail:
723         message_free(t);
724         return r;
725 }
726
727 sd_bus_message* sd_bus_message_ref(sd_bus_message *m) {
728         assert_return(m, NULL);
729
730         assert(m->n_ref > 0);
731         m->n_ref++;
732
733         return m;
734 }
735
736 sd_bus_message* sd_bus_message_unref(sd_bus_message *m) {
737         assert_return(m, NULL);
738
739         assert(m->n_ref > 0);
740         m->n_ref--;
741
742         if (m->n_ref <= 0)
743                 message_free(m);
744
745         return NULL;
746 }
747
748 int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type) {
749         assert_return(m, -EINVAL);
750         assert_return(type, -EINVAL);
751
752         *type = m->header->type;
753         return 0;
754 }
755
756 int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial) {
757         assert_return(m, -EINVAL);
758         assert_return(serial, -EINVAL);
759         assert_return(m->header->serial != 0, -ENOENT);
760
761         *serial = BUS_MESSAGE_SERIAL(m);
762         return 0;
763 }
764
765 int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial) {
766         assert_return(m, -EINVAL);
767         assert_return(serial, -EINVAL);
768         assert_return(m->reply_serial != 0, -ENOENT);
769
770         *serial = m->reply_serial;
771         return 0;
772 }
773
774 int sd_bus_message_get_no_reply(sd_bus_message *m) {
775         assert_return(m, -EINVAL);
776
777         return m->header->type == SD_BUS_MESSAGE_METHOD_CALL ? !!(m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED) : 0;
778 }
779
780 const char *sd_bus_message_get_path(sd_bus_message *m) {
781         assert_return(m, NULL);
782
783         return m->path;
784 }
785
786 const char *sd_bus_message_get_interface(sd_bus_message *m) {
787         assert_return(m, NULL);
788
789         return m->interface;
790 }
791
792 const char *sd_bus_message_get_member(sd_bus_message *m) {
793         assert_return(m, NULL);
794
795         return m->member;
796 }
797 const char *sd_bus_message_get_destination(sd_bus_message *m) {
798         assert_return(m, NULL);
799
800         return m->destination;
801 }
802
803 const char *sd_bus_message_get_sender(sd_bus_message *m) {
804         assert_return(m, NULL);
805
806         return m->sender;
807 }
808
809 const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
810         assert_return(m, NULL);
811         assert_return(sd_bus_error_is_set(&m->error), NULL);
812
813         return &m->error;
814 }
815
816 int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
817         assert_return(m, -EINVAL);
818         assert_return(uid, -EINVAL);
819         assert_return(m->uid_valid, -ESRCH);
820
821         *uid = m->uid;
822         return 0;
823 }
824
825 int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
826         assert_return(m, -EINVAL);
827         assert_return(gid, -EINVAL);
828         assert_return(m->gid_valid, -ESRCH);
829
830         *gid = m->gid;
831         return 0;
832 }
833
834 int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
835         assert_return(m, -EINVAL);
836         assert_return(pid, -EINVAL);
837         assert_return(m->pid > 0, -ESRCH);
838
839         *pid = m->pid;
840         return 0;
841 }
842
843 int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
844         assert_return(m, -EINVAL);
845         assert_return(tid, -EINVAL);
846         assert_return(m->tid > 0, -ESRCH);
847
848         *tid = m->tid;
849         return 0;
850 }
851
852 int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
853         assert_return(m, -EINVAL);
854         assert_return(usec, -EINVAL);
855         assert_return(m->pid_starttime > 0, -ESRCH);
856
857         *usec = m->pid_starttime;
858         return 0;
859 }
860
861 int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
862         assert_return(m, -EINVAL);
863         assert_return(m->label, -ESRCH);
864
865         *ret = m->label;
866         return 0;
867 }
868
869 int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
870         assert_return(m, -EINVAL);
871         assert_return(usec, -EINVAL);
872         assert_return(m->monotonic > 0, -ESRCH);
873
874         *usec = m->monotonic;
875         return 0;
876 }
877
878 int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
879         assert_return(m, -EINVAL);
880         assert_return(usec, -EINVAL);
881         assert_return(m->realtime > 0, -ESRCH);
882
883         *usec = m->realtime;
884         return 0;
885 }
886
887 int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
888         assert_return(m, -EINVAL);
889         assert_return(ret, -EINVAL);
890         assert_return(m->comm, -ESRCH);
891
892         *ret = m->comm;
893         return 0;
894 }
895
896 int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
897         assert_return(m, -EINVAL);
898         assert_return(ret, -EINVAL);
899         assert_return(m->tid_comm, -ESRCH);
900
901         *ret = m->tid_comm;
902         return 0;
903 }
904
905 int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
906         assert_return(m, -EINVAL);
907         assert_return(ret, -EINVAL);
908         assert_return(m->exe, -ESRCH);
909
910         *ret = m->exe;
911         return 0;
912 }
913
914 int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
915         assert_return(m, -EINVAL);
916         assert_return(ret, -EINVAL);
917         assert_return(m->cgroup, -ESRCH);
918
919         *ret = m->cgroup;
920         return 0;
921 }
922
923 int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
924         int r;
925
926         assert_return(m, -EINVAL);
927         assert_return(ret, -EINVAL);
928         assert_return(m->cgroup, -ESRCH);
929
930         if (!m->unit) {
931                 r = cg_path_get_unit(m->cgroup, &m->unit);
932                 if (r < 0)
933                         return r;
934         }
935
936         *ret = m->unit;
937         return 0;
938 }
939
940 int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
941         int r;
942
943         assert_return(m, -EINVAL);
944         assert_return(ret, -EINVAL);
945         assert_return(m->cgroup, -ESRCH);
946
947         if (!m->user_unit) {
948                 r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
949                 if (r < 0)
950                         return r;
951         }
952
953         *ret = m->user_unit;
954         return 0;
955 }
956
957 int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
958         int r;
959
960         assert_return(m, -EINVAL);
961         assert_return(ret, -EINVAL);
962         assert_return(m->cgroup, -ESRCH);
963
964         if (!m->session) {
965                 r = cg_path_get_session(m->cgroup, &m->session);
966                 if (r < 0)
967                         return r;
968         }
969
970         *ret = m->session;
971         return 0;
972 }
973
974 int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
975         assert_return(m, -EINVAL);
976         assert_return(uid, -EINVAL);
977         assert_return(m->cgroup, -ESRCH);
978
979         return cg_path_get_owner_uid(m->cgroup, uid);
980 }
981
982 int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
983         size_t n, i;
984         const char *p;
985         bool first;
986
987         assert_return(m, -EINVAL);
988         assert_return(m->cmdline, -ESRCH);
989
990         for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
991                 if (*p == 0)
992                         n++;
993
994         m->cmdline_array = new(char*, n + 1);
995         if (!m->cmdline_array)
996                 return -ENOMEM;
997
998         for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
999                 if (first)
1000                         m->cmdline_array[i++] = (char*) p;
1001
1002                 first = *p == 0;
1003         }
1004
1005         m->cmdline_array[i] = NULL;
1006         *cmdline = m->cmdline_array;
1007
1008         return 0;
1009 }
1010
1011 int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
1012         assert_return(m, -EINVAL);
1013         assert_return(sessionid, -EINVAL);
1014         assert_return(m->audit, -ESRCH);
1015
1016         *sessionid = m->audit->sessionid;
1017         return 0;
1018 }
1019
1020 int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
1021         assert_return(m, -EINVAL);
1022         assert_return(uid, -EINVAL);
1023         assert_return(m->audit, -ESRCH);
1024
1025         *uid = m->audit->loginuid;
1026         return 0;
1027 }
1028
1029 int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
1030         unsigned sz;
1031
1032         assert_return(m, -EINVAL);
1033         assert_return(capability < 0, -EINVAL);
1034         assert_return(!m->capability, -ESRCH);
1035
1036         sz = m->capability_size / 4;
1037         if ((unsigned) capability >= sz*8)
1038                 return 0;
1039
1040         return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
1041 }
1042
1043 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
1044         assert_return(m, -EINVAL);
1045
1046         if (m->header->type != SD_BUS_MESSAGE_SIGNAL)
1047                 return 0;
1048
1049         if (interface && (!m->interface || !streq(m->interface, interface)))
1050                 return 0;
1051
1052         if (member &&  (!m->member || !streq(m->member, member)))
1053                 return 0;
1054
1055         return 1;
1056 }
1057
1058 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
1059         assert_return(m, -EINVAL);
1060
1061         if (m->header->type != SD_BUS_MESSAGE_METHOD_CALL)
1062                 return 0;
1063
1064         if (interface && (!m->interface || !streq(m->interface, interface)))
1065                 return 0;
1066
1067         if (member &&  (!m->member || !streq(m->member, member)))
1068                 return 0;
1069
1070         return 1;
1071 }
1072
1073 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
1074         assert_return(m, -EINVAL);
1075
1076         if (m->header->type != SD_BUS_MESSAGE_METHOD_ERROR)
1077                 return 0;
1078
1079         if (name && (!m->error.name || !streq(m->error.name, name)))
1080                 return 0;
1081
1082         return 1;
1083 }
1084
1085 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
1086         assert_return(m, -EINVAL);
1087         assert_return(!m->sealed, -EPERM);
1088         assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EPERM);
1089
1090         if (b)
1091                 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1092         else
1093                 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
1094
1095         return 0;
1096 }
1097
1098 static struct bus_container *message_get_container(sd_bus_message *m) {
1099         assert(m);
1100
1101         if (m->n_containers == 0)
1102                 return &m->root_container;
1103
1104         assert(m->containers);
1105         return m->containers + m->n_containers - 1;
1106 }
1107
1108 struct bus_body_part *message_append_part(sd_bus_message *m) {
1109         struct bus_body_part *part;
1110
1111         assert(m);
1112
1113         if (m->poisoned)
1114                 return NULL;
1115
1116         if (m->n_body_parts <= 0) {
1117                 part = &m->body;
1118                 zero(*part);
1119         } else {
1120                 assert(m->body_end);
1121
1122                 part = new0(struct bus_body_part, 1);
1123                 if (!part) {
1124                         m->poisoned = true;
1125                         return NULL;
1126                 }
1127
1128                 m->body_end->next = part;
1129         }
1130
1131         part->memfd = -1;
1132         m->body_end = part;
1133         m->n_body_parts ++;
1134
1135         return part;
1136 }
1137
1138 static void part_zero(struct bus_body_part *part, size_t sz) {
1139         assert(part);
1140         assert(sz > 0);
1141         assert(sz < 8);
1142
1143         /* All other fields can be left in their defaults */
1144         assert(!part->data);
1145         assert(part->memfd < 0);
1146
1147         part->size = sz;
1148         part->is_zero = true;
1149         part->sealed = true;
1150 }
1151
1152 static int part_make_space(
1153                 struct sd_bus_message *m,
1154                 struct bus_body_part *part,
1155                 size_t sz,
1156                 void **q) {
1157
1158         void *n;
1159         int r;
1160
1161         assert(m);
1162         assert(part);
1163         assert(!part->sealed);
1164
1165         if (m->poisoned)
1166                 return -ENOMEM;
1167
1168         if (!part->data && part->memfd < 0)
1169                 part->memfd = bus_kernel_pop_memfd(m->bus, &part->data, &part->mapped);
1170
1171         if (part->memfd >= 0) {
1172                 uint64_t u = sz;
1173
1174                 r = ioctl(part->memfd, KDBUS_CMD_MEMFD_SIZE_SET, &u);
1175                 if (r < 0) {
1176                         m->poisoned = true;
1177                         return -errno;
1178                 }
1179
1180                 if (!part->data || sz > part->mapped) {
1181                         size_t psz = PAGE_ALIGN(sz > 0 ? sz : 1);
1182
1183                         if (part->mapped <= 0)
1184                                 n = mmap(NULL, psz, PROT_READ|PROT_WRITE, MAP_SHARED, part->memfd, 0);
1185                         else
1186                                 n = mremap(part->data, part->mapped, psz, MREMAP_MAYMOVE);
1187
1188                         if (n == MAP_FAILED) {
1189                                 m->poisoned = true;
1190                                 return -errno;
1191                         }
1192
1193                         part->mapped = psz;
1194                         part->data = n;
1195                 }
1196
1197                 part->munmap_this = true;
1198         } else {
1199                 n = realloc(part->data, MAX(sz, 1u));
1200                 if (!n) {
1201                         m->poisoned = true;
1202                         return -ENOMEM;
1203                 }
1204
1205                 part->data = n;
1206                 part->free_this = true;
1207         }
1208
1209         if (q)
1210                 *q = part->data ? (uint8_t*) part->data + part->size : NULL;
1211
1212         part->size = sz;
1213         return 0;
1214 }
1215
1216 static void message_extend_containers(sd_bus_message *m, size_t expand) {
1217         struct bus_container *c;
1218
1219         assert(m);
1220
1221         if (expand <= 0)
1222                 return;
1223
1224         /* Update counters */
1225         for (c = m->containers; c < m->containers + m->n_containers; c++)
1226                 if (c->array_size)
1227                         *c->array_size += expand;
1228 }
1229
1230 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
1231         struct bus_body_part *part = NULL;
1232         size_t start_body, end_body, padding, start_part, end_part, added;
1233         bool add_new_part;
1234         void *p;
1235         int r;
1236
1237         assert(m);
1238         assert(align > 0);
1239         assert(!m->sealed);
1240
1241         if (m->poisoned)
1242                 return NULL;
1243
1244         start_body = ALIGN_TO((size_t) m->header->body_size, align);
1245         end_body = start_body + sz;
1246
1247         padding = start_body - m->header->body_size;
1248         added = padding + sz;
1249
1250         /* Check for 32bit overflows */
1251         if (end_body > (size_t) ((uint32_t) -1)) {
1252                 m->poisoned = true;
1253                 return NULL;
1254         }
1255
1256         add_new_part =
1257                 m->n_body_parts <= 0 ||
1258                 m->body_end->sealed ||
1259                 padding != ALIGN_TO(m->body_end->size, align) - m->body_end->size;
1260
1261         if (add_new_part) {
1262                 if (padding > 0) {
1263                         part = message_append_part(m);
1264                         if (!part)
1265                                 return NULL;
1266
1267                         part_zero(part, padding);
1268                 }
1269
1270                 part = message_append_part(m);
1271                 if (!part)
1272                         return NULL;
1273
1274                 r = part_make_space(m, part, sz, &p);
1275                 if (r < 0)
1276                         return NULL;
1277         } else {
1278                 struct bus_container *c;
1279                 void *op;
1280                 size_t os;
1281
1282                 part = m->body_end;
1283                 op = part->data;
1284                 os = part->size;
1285
1286                 start_part = ALIGN_TO(part->size, align);
1287                 end_part = start_part + sz;
1288
1289                 r = part_make_space(m, part, end_part, &p);
1290                 if (r < 0)
1291                         return NULL;
1292
1293                 if (padding > 0) {
1294                         memset(p, 0, padding);
1295                         p = (uint8_t*) p + padding;
1296                 }
1297
1298                 /* Readjust pointers */
1299                 for (c = m->containers; c < m->containers + m->n_containers; c++)
1300                         c->array_size = adjust_pointer(c->array_size, op, os, part->data);
1301
1302                 m->error.message = (const char*) adjust_pointer(m->error.message, op, os, part->data);
1303         }
1304
1305         m->header->body_size = end_body;
1306         message_extend_containers(m, added);
1307
1308         return p;
1309 }
1310
1311 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
1312         struct bus_container *c;
1313         ssize_t align, sz;
1314         uint32_t k;
1315         void *a;
1316         int fd = -1;
1317         uint32_t fdi = 0;
1318         int r;
1319
1320         assert_return(m, -EINVAL);
1321         assert_return(p, -EINVAL);
1322         assert_return(!m->sealed, -EPERM);
1323         assert_return(bus_type_is_basic(type), -EINVAL);
1324         assert_return(!m->poisoned, -ESTALE);
1325
1326         c = message_get_container(m);
1327
1328         if (c->signature && c->signature[c->index]) {
1329                 /* Container signature is already set */
1330
1331                 if (c->signature[c->index] != type)
1332                         return -ENXIO;
1333         } else {
1334                 char *e;
1335
1336                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1337                 if (c->enclosing != 0)
1338                         return -ENXIO;
1339
1340                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
1341                 if (!e) {
1342                         m->poisoned = true;
1343                         return -ENOMEM;
1344                 }
1345         }
1346
1347         switch (type) {
1348
1349         case SD_BUS_TYPE_STRING:
1350                 /* To make things easy we'll serialize a NULL string
1351                  * into the empty string */
1352                 p = strempty(p);
1353
1354                 /* Fall through... */
1355         case SD_BUS_TYPE_OBJECT_PATH:
1356
1357                 if (!p) {
1358                         r = -EINVAL;
1359                         goto fail;
1360                 }
1361
1362                 align = 4;
1363                 sz = 4 + strlen(p) + 1;
1364                 break;
1365
1366         case SD_BUS_TYPE_SIGNATURE:
1367
1368                 if (!p) {
1369                         r = -EINVAL;
1370                         goto fail;
1371                 }
1372
1373                 align = 1;
1374                 sz = 1 + strlen(p) + 1;
1375                 break;
1376
1377         case SD_BUS_TYPE_BOOLEAN:
1378                 align = sz = 4;
1379
1380                 assert_cc(sizeof(int) == sizeof(uint32_t));
1381                 memcpy(&k, p, 4);
1382                 k = !!k;
1383                 p = &k;
1384                 break;
1385
1386         case SD_BUS_TYPE_UNIX_FD: {
1387                 int z, *f;
1388
1389                 if (!m->allow_fds) {
1390                         r = -ENOTSUP;
1391                         goto fail;
1392                 }
1393
1394                 align = sz = 4;
1395
1396                 z = *(int*) p;
1397                 if (z < 0) {
1398                         r = -EINVAL;
1399                         goto fail;
1400                 }
1401
1402                 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
1403                 if (fd < 0) {
1404                         r = -errno;
1405                         goto fail;
1406                 }
1407
1408                 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
1409                 if (!f) {
1410                         m->poisoned = true;
1411                         r = -ENOMEM;
1412                         goto fail;
1413                 }
1414
1415                 fdi = m->n_fds;
1416                 f[fdi] = fd;
1417                 m->fds = f;
1418                 m->free_fds = true;
1419                 break;
1420         }
1421
1422         default:
1423                 align = bus_type_get_alignment(type);
1424                 sz = bus_type_get_size(type);
1425                 break;
1426         }
1427
1428         assert(align > 0);
1429         assert(sz > 0);
1430
1431         a = message_extend_body(m, align, sz);
1432         if (!a) {
1433                 r = -ENOMEM;
1434                 goto fail;
1435         }
1436
1437         if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
1438                 *(uint32_t*) a = sz - 5;
1439                 memcpy((uint8_t*) a + 4, p, sz - 4);
1440
1441                 if (stored)
1442                         *stored = (const uint8_t*) a + 4;
1443
1444         } else if (type == SD_BUS_TYPE_SIGNATURE) {
1445                 *(uint8_t*) a = sz - 1;
1446                 memcpy((uint8_t*) a + 1, p, sz - 1);
1447
1448                 if (stored)
1449                         *stored = (const uint8_t*) a + 1;
1450         } else if (type == SD_BUS_TYPE_UNIX_FD) {
1451                 *(uint32_t*) a = fdi;
1452
1453                 if (stored)
1454                         *stored = a;
1455
1456                 m->n_fds ++;
1457
1458         } else {
1459                 memcpy(a, p, sz);
1460
1461                 if (stored)
1462                         *stored = a;
1463         }
1464
1465         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1466                 c->index++;
1467
1468         return 0;
1469
1470 fail:
1471         if (fd >= 0)
1472                 close_nointr_nofail(fd);
1473
1474         return r;
1475 }
1476
1477 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
1478         return message_append_basic(m, type, p, NULL);
1479 }
1480
1481 int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s) {
1482         struct bus_container *c;
1483         void *a;
1484
1485         assert_return(m, -EINVAL);
1486         assert_return(s, -EINVAL);
1487         assert_return(!m->sealed, -EPERM);
1488         assert_return(!m->poisoned, -ESTALE);
1489
1490         c = message_get_container(m);
1491
1492         if (c->signature && c->signature[c->index]) {
1493                 /* Container signature is already set */
1494
1495                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
1496                         return -ENXIO;
1497         } else {
1498                 char *e;
1499
1500                 /* Maybe we can append to the signature? But only if this is the top-level container*/
1501                 if (c->enclosing != 0)
1502                         return -ENXIO;
1503
1504                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
1505                 if (!e) {
1506                         m->poisoned = true;
1507                         return -ENOMEM;
1508                 }
1509         }
1510
1511         a = message_extend_body(m, 4, 4 + size + 1);
1512         if (!a)
1513                 return -ENOMEM;
1514
1515         *(uint32_t*) a = size;
1516         *s = (char*) a + 4;
1517
1518         (*s)[size] = 0;
1519
1520         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1521                 c->index++;
1522
1523         return 0;
1524 }
1525
1526 static int bus_message_open_array(
1527                 sd_bus_message *m,
1528                 struct bus_container *c,
1529                 const char *contents,
1530                 uint32_t **array_size) {
1531
1532         unsigned nindex;
1533         void *a, *op;
1534         int alignment;
1535         size_t os;
1536         struct bus_body_part *o;
1537
1538         assert(m);
1539         assert(c);
1540         assert(contents);
1541         assert(array_size);
1542
1543         if (!signature_is_single(contents, true))
1544                 return -EINVAL;
1545
1546         alignment = bus_type_get_alignment(contents[0]);
1547         if (alignment < 0)
1548                 return alignment;
1549
1550         if (c->signature && c->signature[c->index]) {
1551
1552                 /* Verify the existing signature */
1553
1554                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1555                         return -ENXIO;
1556
1557                 if (!startswith(c->signature + c->index + 1, contents))
1558                         return -ENXIO;
1559
1560                 nindex = c->index + 1 + strlen(contents);
1561         } else {
1562                 char *e;
1563
1564                 if (c->enclosing != 0)
1565                         return -ENXIO;
1566
1567                 /* Extend the existing signature */
1568
1569                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1570                 if (!e) {
1571                         m->poisoned = true;
1572                         return -ENOMEM;
1573                 }
1574
1575                 nindex = e - c->signature;
1576         }
1577
1578         a = message_extend_body(m, 4, 4);
1579         if (!a)
1580                 return -ENOMEM;
1581
1582         o = m->body_end;
1583         op = m->body_end->data;
1584         os = m->body_end->size;
1585
1586         /* Add alignment between size and first element */
1587         if (!message_extend_body(m, alignment, 0))
1588                 return -ENOMEM;
1589
1590         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1591                 c->index = nindex;
1592
1593         /* location of array size might have changed so let's readjust a */
1594         if (o == m->body_end)
1595                 a = adjust_pointer(a, op, os, m->body_end->data);
1596
1597         *(uint32_t*) a = 0;
1598         *array_size = a;
1599         return 0;
1600 }
1601
1602 static int bus_message_open_variant(
1603                 sd_bus_message *m,
1604                 struct bus_container *c,
1605                 const char *contents) {
1606
1607         size_t l;
1608         void *a;
1609
1610         assert(m);
1611         assert(c);
1612         assert(contents);
1613
1614         if (!signature_is_single(contents, false))
1615                 return -EINVAL;
1616
1617         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1618                 return -EINVAL;
1619
1620         if (c->signature && c->signature[c->index]) {
1621
1622                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1623                         return -ENXIO;
1624
1625         } else {
1626                 char *e;
1627
1628                 if (c->enclosing != 0)
1629                         return -ENXIO;
1630
1631                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1632                 if (!e) {
1633                         m->poisoned = true;
1634                         return -ENOMEM;
1635                 }
1636         }
1637
1638         l = strlen(contents);
1639         a = message_extend_body(m, 1, 1 + l + 1);
1640         if (!a)
1641                 return -ENOMEM;
1642
1643         *(uint8_t*) a = l;
1644         memcpy((uint8_t*) a + 1, contents, l + 1);
1645
1646         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1647                 c->index++;
1648
1649         return 0;
1650 }
1651
1652 static int bus_message_open_struct(
1653                 sd_bus_message *m,
1654                 struct bus_container *c,
1655                 const char *contents) {
1656
1657         size_t nindex;
1658
1659         assert(m);
1660         assert(c);
1661         assert(contents);
1662
1663         if (!signature_is_valid(contents, false))
1664                 return -EINVAL;
1665
1666         if (c->signature && c->signature[c->index]) {
1667                 size_t l;
1668
1669                 l = strlen(contents);
1670
1671                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1672                     !startswith(c->signature + c->index + 1, contents) ||
1673                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1674                         return -ENXIO;
1675
1676                 nindex = c->index + 1 + l + 1;
1677         } else {
1678                 char *e;
1679
1680                 if (c->enclosing != 0)
1681                         return -ENXIO;
1682
1683                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1684                 if (!e) {
1685                         m->poisoned = true;
1686                         return -ENOMEM;
1687                 }
1688
1689                 nindex = e - c->signature;
1690         }
1691
1692         /* Align contents to 8 byte boundary */
1693         if (!message_extend_body(m, 8, 0))
1694                 return -ENOMEM;
1695
1696         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1697                 c->index = nindex;
1698
1699         return 0;
1700 }
1701
1702 static int bus_message_open_dict_entry(
1703                 sd_bus_message *m,
1704                 struct bus_container *c,
1705                 const char *contents) {
1706
1707         size_t nindex;
1708
1709         assert(m);
1710         assert(c);
1711         assert(contents);
1712
1713         if (!signature_is_pair(contents))
1714                 return -EINVAL;
1715
1716         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1717                 return -ENXIO;
1718
1719         if (c->signature && c->signature[c->index]) {
1720                 size_t l;
1721
1722                 l = strlen(contents);
1723
1724                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1725                     !startswith(c->signature + c->index + 1, contents) ||
1726                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1727                         return -ENXIO;
1728
1729                 nindex = c->index + 1 + l + 1;
1730         } else
1731                 return -ENXIO;
1732
1733         /* Align contents to 8 byte boundary */
1734         if (!message_extend_body(m, 8, 0))
1735                 return -ENOMEM;
1736
1737         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1738                 c->index = nindex;
1739
1740         return 0;
1741 }
1742
1743 int sd_bus_message_open_container(
1744                 sd_bus_message *m,
1745                 char type,
1746                 const char *contents) {
1747
1748         struct bus_container *c, *w;
1749         uint32_t *array_size = NULL;
1750         char *signature;
1751         size_t before;
1752         int r;
1753
1754         assert_return(m, -EINVAL);
1755         assert_return(!m->sealed, -EPERM);
1756         assert_return(contents, -EINVAL);
1757         assert_return(!m->poisoned, -ESTALE);
1758
1759         /* Make sure we have space for one more container */
1760         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1761         if (!w) {
1762                 m->poisoned = true;
1763                 return -ENOMEM;
1764         }
1765
1766         m->containers = w;
1767
1768         c = message_get_container(m);
1769
1770         signature = strdup(contents);
1771         if (!signature) {
1772                 m->poisoned = true;
1773                 return -ENOMEM;
1774         }
1775
1776         /* Save old index in the parent container, in case we have to
1777          * abort this container */
1778         c->saved_index = c->index;
1779         before = m->header->body_size;
1780
1781         if (type == SD_BUS_TYPE_ARRAY)
1782                 r = bus_message_open_array(m, c, contents, &array_size);
1783         else if (type == SD_BUS_TYPE_VARIANT)
1784                 r = bus_message_open_variant(m, c, contents);
1785         else if (type == SD_BUS_TYPE_STRUCT)
1786                 r = bus_message_open_struct(m, c, contents);
1787         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1788                 r = bus_message_open_dict_entry(m, c, contents);
1789         else
1790                 r = -EINVAL;
1791
1792         if (r < 0) {
1793                 free(signature);
1794                 return r;
1795         }
1796
1797         /* OK, let's fill it in */
1798         w += m->n_containers++;
1799         w->enclosing = type;
1800         w->signature = signature;
1801         w->index = 0;
1802         w->array_size = array_size;
1803         w->before = before;
1804         w->begin = m->rindex;
1805
1806         return 0;
1807 }
1808
1809 int sd_bus_message_close_container(sd_bus_message *m) {
1810         struct bus_container *c;
1811
1812         assert_return(m, -EINVAL);
1813         assert_return(!m->sealed, -EPERM);
1814         assert_return(m->n_containers > 0, -EINVAL);
1815         assert_return(!m->poisoned, -ESTALE);
1816
1817         c = message_get_container(m);
1818         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1819                 if (c->signature && c->signature[c->index] != 0)
1820                         return -EINVAL;
1821
1822         free(c->signature);
1823         m->n_containers--;
1824
1825         return 0;
1826 }
1827
1828 typedef struct {
1829         const char *types;
1830         unsigned n_struct;
1831         unsigned n_array;
1832 } TypeStack;
1833
1834 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1835         assert(stack);
1836         assert(max > 0);
1837
1838         if (*i >= max)
1839                 return -EINVAL;
1840
1841         stack[*i].types = types;
1842         stack[*i].n_struct = n_struct;
1843         stack[*i].n_array = n_array;
1844         (*i)++;
1845
1846         return 0;
1847 }
1848
1849 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1850         assert(stack);
1851         assert(max > 0);
1852         assert(types);
1853         assert(n_struct);
1854         assert(n_array);
1855
1856         if (*i <= 0)
1857                 return 0;
1858
1859         (*i)--;
1860         *types = stack[*i].types;
1861         *n_struct = stack[*i].n_struct;
1862         *n_array = stack[*i].n_array;
1863
1864         return 1;
1865 }
1866
1867 int bus_message_append_ap(
1868                 sd_bus_message *m,
1869                 const char *types,
1870                 va_list ap) {
1871
1872         unsigned n_array, n_struct;
1873         TypeStack stack[BUS_CONTAINER_DEPTH];
1874         unsigned stack_ptr = 0;
1875         int r;
1876
1877         assert(m);
1878
1879         if (!types)
1880                 return 0;
1881
1882         n_array = (unsigned) -1;
1883         n_struct = strlen(types);
1884
1885         for (;;) {
1886                 const char *t;
1887
1888                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1889                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1890                         if (r < 0)
1891                                 return r;
1892                         if (r == 0)
1893                                 break;
1894
1895                         r = sd_bus_message_close_container(m);
1896                         if (r < 0)
1897                                 return r;
1898
1899                         continue;
1900                 }
1901
1902                 t = types;
1903                 if (n_array != (unsigned) -1)
1904                         n_array --;
1905                 else {
1906                         types ++;
1907                         n_struct--;
1908                 }
1909
1910                 switch (*t) {
1911
1912                 case SD_BUS_TYPE_BYTE: {
1913                         uint8_t x;
1914
1915                         x = (uint8_t) va_arg(ap, int);
1916                         r = sd_bus_message_append_basic(m, *t, &x);
1917                         break;
1918                 }
1919
1920                 case SD_BUS_TYPE_BOOLEAN:
1921                 case SD_BUS_TYPE_INT32:
1922                 case SD_BUS_TYPE_UINT32:
1923                 case SD_BUS_TYPE_UNIX_FD: {
1924                         uint32_t x;
1925
1926                         /* We assume a boolean is the same as int32_t */
1927                         assert_cc(sizeof(int32_t) == sizeof(int));
1928
1929                         x = va_arg(ap, uint32_t);
1930                         r = sd_bus_message_append_basic(m, *t, &x);
1931                         break;
1932                 }
1933
1934                 case SD_BUS_TYPE_INT16:
1935                 case SD_BUS_TYPE_UINT16: {
1936                         uint16_t x;
1937
1938                         x = (uint16_t) va_arg(ap, int);
1939                         r = sd_bus_message_append_basic(m, *t, &x);
1940                         break;
1941                 }
1942
1943                 case SD_BUS_TYPE_INT64:
1944                 case SD_BUS_TYPE_UINT64:
1945                 case SD_BUS_TYPE_DOUBLE: {
1946                         uint64_t x;
1947
1948                         x = va_arg(ap, uint64_t);
1949                         r = sd_bus_message_append_basic(m, *t, &x);
1950                         break;
1951                 }
1952
1953                 case SD_BUS_TYPE_STRING:
1954                 case SD_BUS_TYPE_OBJECT_PATH:
1955                 case SD_BUS_TYPE_SIGNATURE: {
1956                         const char *x;
1957
1958                         x = va_arg(ap, const char*);
1959                         r = sd_bus_message_append_basic(m, *t, x);
1960                         break;
1961                 }
1962
1963                 case SD_BUS_TYPE_ARRAY: {
1964                         size_t k;
1965
1966                         r = signature_element_length(t + 1, &k);
1967                         if (r < 0)
1968                                 return r;
1969
1970                         {
1971                                 char s[k + 1];
1972                                 memcpy(s, t + 1, k);
1973                                 s[k] = 0;
1974
1975                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1976                                 if (r < 0)
1977                                         return r;
1978                         }
1979
1980                         if (n_array == (unsigned) -1) {
1981                                 types += k;
1982                                 n_struct -= k;
1983                         }
1984
1985                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1986                         if (r < 0)
1987                                 return r;
1988
1989                         types = t + 1;
1990                         n_struct = k;
1991                         n_array = va_arg(ap, unsigned);
1992
1993                         break;
1994                 }
1995
1996                 case SD_BUS_TYPE_VARIANT: {
1997                         const char *s;
1998
1999                         s = va_arg(ap, const char*);
2000                         if (!s)
2001                                 return -EINVAL;
2002
2003                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
2004                         if (r < 0)
2005                                 return r;
2006
2007                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2008                         if (r < 0)
2009                                 return r;
2010
2011                         types = s;
2012                         n_struct = strlen(s);
2013                         n_array = (unsigned) -1;
2014
2015                         break;
2016                 }
2017
2018                 case SD_BUS_TYPE_STRUCT_BEGIN:
2019                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2020                         size_t k;
2021
2022                         r = signature_element_length(t, &k);
2023                         if (r < 0)
2024                                 return r;
2025
2026                         {
2027                                 char s[k - 1];
2028
2029                                 memcpy(s, t + 1, k - 2);
2030                                 s[k - 2] = 0;
2031
2032                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2033                                 if (r < 0)
2034                                         return r;
2035                         }
2036
2037                         if (n_array == (unsigned) -1) {
2038                                 types += k - 1;
2039                                 n_struct -= k - 1;
2040                         }
2041
2042                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2043                         if (r < 0)
2044                                 return r;
2045
2046                         types = t + 1;
2047                         n_struct = k - 2;
2048                         n_array = (unsigned) -1;
2049
2050                         break;
2051                 }
2052
2053                 default:
2054                         r = -EINVAL;
2055                 }
2056
2057                 if (r < 0)
2058                         return r;
2059         }
2060
2061         return 0;
2062 }
2063
2064 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
2065         va_list ap;
2066         int r;
2067
2068         assert_return(m, -EINVAL);
2069         assert_return(types, -EINVAL);
2070         assert_return(!m->sealed, -EPERM);
2071         assert_return(!m->poisoned, -ESTALE);
2072
2073         va_start(ap, types);
2074         r = bus_message_append_ap(m, types, ap);
2075         va_end(ap);
2076
2077         return r;
2078 }
2079
2080 int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr) {
2081         ssize_t align, sz;
2082         void *a;
2083         int r;
2084
2085         assert_return(m, -EINVAL);
2086         assert_return(!m->sealed, -EPERM);
2087         assert_return(bus_type_is_trivial(type), -EINVAL);
2088         assert_return(ptr || size == 0, -EINVAL);
2089         assert_return(!m->poisoned, -ESTALE);
2090
2091         align = bus_type_get_alignment(type);
2092         sz = bus_type_get_size(type);
2093
2094         assert_se(align > 0);
2095         assert_se(sz > 0);
2096
2097         if (size % sz != 0)
2098                 return -EINVAL;
2099
2100         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2101         if (r < 0)
2102                 return r;
2103
2104         a = message_extend_body(m, align, size);
2105         if (!a)
2106                 return -ENOMEM;
2107
2108         r = sd_bus_message_close_container(m);
2109         if (r < 0)
2110                 return r;
2111
2112         *ptr = a;
2113         return 0;
2114 }
2115
2116 int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size) {
2117         int r;
2118         void *p;
2119
2120         assert_return(m, -EINVAL);
2121         assert_return(!m->sealed, -EPERM);
2122         assert_return(bus_type_is_trivial(type), -EINVAL);
2123         assert_return(ptr || size == 0, -EINVAL);
2124         assert_return(!m->poisoned, -ESTALE);
2125
2126         r = sd_bus_message_append_array_space(m, type, size, &p);
2127         if (r < 0)
2128                 return r;
2129
2130         if (size > 0)
2131                 memcpy(p, ptr, size);
2132
2133         return 0;
2134 }
2135
2136 int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, sd_memfd *memfd) {
2137         _cleanup_close_ int copy_fd = -1;
2138         struct bus_body_part *part;
2139         ssize_t align, sz;
2140         uint64_t size;
2141         void *a;
2142         int r;
2143
2144         if (!m)
2145                 return -EINVAL;
2146         if (!memfd)
2147                 return -EINVAL;
2148         if (m->sealed)
2149                 return -EPERM;
2150         if (!bus_type_is_trivial(type))
2151                 return -EINVAL;
2152         if (m->poisoned)
2153                 return -ESTALE;
2154
2155         r = sd_memfd_set_sealed(memfd, true);
2156         if (r < 0)
2157                 return r;
2158
2159         copy_fd = sd_memfd_dup_fd(memfd);
2160         if (copy_fd < 0)
2161                 return copy_fd;
2162
2163         r = sd_memfd_get_size(memfd, &size);
2164         if (r < 0)
2165                 return r;
2166
2167         align = bus_type_get_alignment(type);
2168         sz = bus_type_get_size(type);
2169
2170         assert_se(align > 0);
2171         assert_se(sz > 0);
2172
2173         if (size % sz != 0)
2174                 return -EINVAL;
2175
2176         if (size > (uint64_t) (uint32_t) -1)
2177                 return -EINVAL;
2178
2179         r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
2180         if (r < 0)
2181                 return r;
2182
2183         a = message_extend_body(m, align, 0);
2184         if (!a)
2185                 return -ENOMEM;
2186
2187         part = message_append_part(m);
2188         if (!part)
2189                 return -ENOMEM;
2190
2191         part->memfd = copy_fd;
2192         part->sealed = true;
2193         part->size = size;
2194         copy_fd = -1;
2195
2196         message_extend_containers(m, size);
2197         m->header->body_size += size;
2198
2199         return sd_bus_message_close_container(m);
2200 }
2201
2202 int sd_bus_message_append_string_memfd(sd_bus_message *m, sd_memfd *memfd) {
2203         _cleanup_close_ int copy_fd = -1;
2204         struct bus_body_part *part;
2205         struct bus_container *c;
2206         uint64_t size;
2207         void *a;
2208         int r;
2209
2210         assert_return(m, -EINVAL);
2211         assert_return(memfd, -EINVAL);
2212         assert_return(!m->sealed, -EPERM);
2213         assert_return(!m->poisoned, -ESTALE);
2214
2215         r = sd_memfd_set_sealed(memfd, true);
2216         if (r < 0)
2217                 return r;
2218
2219         copy_fd = sd_memfd_dup_fd(memfd);
2220         if (copy_fd < 0)
2221                 return copy_fd;
2222
2223         r = sd_memfd_get_size(memfd, &size);
2224         if (r < 0)
2225                 return r;
2226
2227         /* We require this to be NUL terminated */
2228         if (size == 0)
2229                 return -EINVAL;
2230
2231         if (size > (uint64_t) (uint32_t) -1)
2232                 return -EINVAL;
2233
2234         c = message_get_container(m);
2235         if (c->signature && c->signature[c->index]) {
2236                 /* Container signature is already set */
2237
2238                 if (c->signature[c->index] != SD_BUS_TYPE_STRING)
2239                         return -ENXIO;
2240         } else {
2241                 char *e;
2242
2243                 /* Maybe we can append to the signature? But only if this is the top-level container*/
2244                 if (c->enclosing != 0)
2245                         return -ENXIO;
2246
2247                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRING), NULL);
2248                 if (!e) {
2249                         m->poisoned = true;
2250                         return -ENOMEM;
2251                 }
2252         }
2253
2254         a = message_extend_body(m, 4, 4);
2255         if (!a)
2256                 return -ENOMEM;
2257
2258         *(uint32_t*) a = size - 1;
2259
2260         part = message_append_part(m);
2261         if (!part)
2262                 return -ENOMEM;
2263
2264         part->memfd = copy_fd;
2265         part->sealed = true;
2266         part->size = size;
2267         copy_fd = -1;
2268
2269         message_extend_containers(m, size);
2270         m->header->body_size += size;
2271
2272         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2273                 c->index++;
2274
2275         return 0;
2276 }
2277
2278 int sd_bus_message_append_strv(sd_bus_message *m, char **l) {
2279         char **i;
2280         int r;
2281
2282         assert_return(m, -EINVAL);
2283         assert_return(!m->sealed, -EPERM);
2284         assert_return(!m->poisoned, -ESTALE);
2285
2286         r = sd_bus_message_open_container(m, 'a', "s");
2287         if (r < 0)
2288                 return r;
2289
2290         STRV_FOREACH(i, l) {
2291                 r = sd_bus_message_append_basic(m, 's', *i);
2292                 if (r < 0)
2293                         return r;
2294         }
2295
2296         return sd_bus_message_close_container(m);
2297 }
2298
2299 int bus_body_part_map(struct bus_body_part *part) {
2300         void *p;
2301         size_t psz;
2302
2303         assert_se(part);
2304
2305         if (part->data)
2306                 return 0;
2307
2308         if (part->size <= 0)
2309                 return 0;
2310
2311         /* For smaller zero parts (as used for padding) we don't need to map anything... */
2312         if (part->memfd < 0 && part->is_zero && part->size < 8) {
2313                 static const uint8_t zeroes[7] = { };
2314                 part->data = (void*) zeroes;
2315                 return 0;
2316         }
2317
2318         psz = PAGE_ALIGN(part->size);
2319
2320         if (part->memfd >= 0)
2321                 p = mmap(NULL, psz, PROT_READ, MAP_SHARED, part->memfd, 0);
2322         else if (part->is_zero)
2323                 p = mmap(NULL, psz, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
2324         else
2325                 return -EINVAL;
2326
2327         if (p == MAP_FAILED)
2328                 return -errno;
2329
2330         part->mapped = psz;
2331         part->data = p;
2332         part->munmap_this = true;
2333
2334         return 0;
2335 }
2336
2337 void bus_body_part_unmap(struct bus_body_part *part) {
2338
2339         assert_se(part);
2340
2341         if (part->memfd < 0)
2342                 return;
2343
2344         if (!part->data)
2345                 return;
2346
2347         if (!part->munmap_this)
2348                 return;
2349
2350         assert_se(munmap(part->data, part->mapped) == 0);
2351
2352         part->data = NULL;
2353         part->mapped = 0;
2354         part->munmap_this = false;
2355
2356         return;
2357 }
2358
2359 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
2360         size_t k, start, end;
2361
2362         assert(rindex);
2363         assert(align > 0);
2364
2365         start = ALIGN_TO((size_t) *rindex, align);
2366         end = start + nbytes;
2367
2368         if (end > sz)
2369                 return -EBADMSG;
2370
2371         /* Verify that padding is 0 */
2372         for (k = *rindex; k < start; k++)
2373                 if (((const uint8_t*) p)[k] != 0)
2374                         return -EBADMSG;
2375
2376         if (r)
2377                 *r = (uint8_t*) p + start;
2378
2379         *rindex = end;
2380
2381         return 1;
2382 }
2383
2384 static bool message_end_of_signature(sd_bus_message *m) {
2385         struct bus_container *c;
2386
2387         assert(m);
2388
2389         c = message_get_container(m);
2390         return !c->signature || c->signature[c->index] == 0;
2391 }
2392
2393 static bool message_end_of_array(sd_bus_message *m, size_t index) {
2394         struct bus_container *c;
2395
2396         assert(m);
2397
2398         c = message_get_container(m);
2399         if (!c->array_size)
2400                 return false;
2401
2402         return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
2403 }
2404
2405 int sd_bus_message_at_end(sd_bus_message *m, int complete) {
2406         assert_return(m, -EINVAL);
2407         assert_return(m->sealed, -EPERM);
2408
2409         if (complete && m->n_containers > 0)
2410                 return false;
2411
2412         if (message_end_of_signature(m))
2413                 return true;
2414
2415         if (message_end_of_array(m, m->rindex))
2416                 return true;
2417
2418         return false;
2419 }
2420
2421 static struct bus_body_part* find_part(sd_bus_message *m, size_t index, size_t sz, void **p) {
2422         struct bus_body_part *part;
2423         size_t begin;
2424         int r;
2425
2426         assert(m);
2427
2428         if (m->cached_rindex_part && index >= m->cached_rindex_part_begin) {
2429                 part = m->cached_rindex_part;
2430                 begin = m->cached_rindex_part_begin;
2431         } else {
2432                 part = &m->body;
2433                 begin = 0;
2434         }
2435
2436         while (part) {
2437                 if (index < begin)
2438                         return NULL;
2439
2440                 if (index + sz <= begin + part->size) {
2441
2442                         r = bus_body_part_map(part);
2443                         if (r < 0)
2444                                 return NULL;
2445
2446                         if (p)
2447                                 *p = (uint8_t*) part->data + index - begin;
2448
2449                         m->cached_rindex_part = part;
2450                         m->cached_rindex_part_begin = begin;
2451
2452                         return part;
2453                 }
2454
2455                 begin += part->size;
2456                 part = part->next;
2457         }
2458
2459         return NULL;
2460 }
2461
2462 static int message_peek_body(
2463                 sd_bus_message *m,
2464                 size_t *rindex,
2465                 size_t align,
2466                 size_t nbytes,
2467                 void **ret) {
2468
2469         size_t k, start, end, padding;
2470         struct bus_body_part *part;
2471         uint8_t *q;
2472
2473         assert(m);
2474         assert(rindex);
2475         assert(align > 0);
2476
2477         if (message_end_of_array(m, *rindex))
2478                 return 0;
2479
2480         start = ALIGN_TO((size_t) *rindex, align);
2481         padding = start - *rindex;
2482         end = start + nbytes;
2483
2484         if (end > BUS_MESSAGE_BODY_SIZE(m))
2485                 return -EBADMSG;
2486
2487         part = find_part(m, *rindex, padding, (void**) &q);
2488         if (!part)
2489                 return -EBADMSG;
2490
2491         if (q) {
2492                 /* Verify padding */
2493                 for (k = 0; k < padding; k++)
2494                         if (q[k] != 0)
2495                                 return -EBADMSG;
2496         }
2497
2498         part = find_part(m, start, nbytes, (void**) &q);
2499         if (!part || !q)
2500                 return -EBADMSG;
2501
2502         *rindex = end;
2503
2504         if (ret)
2505                 *ret = q;
2506
2507         return 1;
2508 }
2509
2510 static bool validate_nul(const char *s, size_t l) {
2511
2512         /* Check for NUL chars in the string */
2513         if (memchr(s, 0, l))
2514                 return false;
2515
2516         /* Check for NUL termination */
2517         if (s[l] != 0)
2518                 return false;
2519
2520         return true;
2521 }
2522
2523 static bool validate_string(const char *s, size_t l) {
2524
2525         if (!validate_nul(s, l))
2526                 return false;
2527
2528         /* Check if valid UTF8 */
2529         if (!utf8_is_valid(s))
2530                 return false;
2531
2532         return true;
2533 }
2534
2535 static bool validate_signature(const char *s, size_t l) {
2536
2537         if (!validate_nul(s, l))
2538                 return false;
2539
2540         /* Check if valid signature */
2541         if (!signature_is_valid(s, true))
2542                 return false;
2543
2544         return true;
2545 }
2546
2547 static bool validate_object_path(const char *s, size_t l) {
2548
2549         if (!validate_nul(s, l))
2550                 return false;
2551
2552         if (!object_path_is_valid(s))
2553                 return false;
2554
2555         return true;
2556 }
2557
2558 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
2559         struct bus_container *c;
2560         void *q;
2561         int r;
2562
2563         assert_return(m, -EINVAL);
2564         assert_return(m->sealed, -EPERM);
2565         assert_return(bus_type_is_basic(type), -EINVAL);
2566
2567         if (message_end_of_signature(m))
2568                 return -ENXIO;
2569
2570         if (message_end_of_array(m, m->rindex))
2571                 return 0;
2572
2573         c = message_get_container(m);
2574         if (c->signature[c->index] != type)
2575                 return -ENXIO;
2576
2577         switch (type) {
2578
2579         case SD_BUS_TYPE_STRING:
2580         case SD_BUS_TYPE_OBJECT_PATH: {
2581                 uint32_t l;
2582                 size_t rindex;
2583
2584                 rindex = m->rindex;
2585                 r = message_peek_body(m, &rindex, 4, 4, &q);
2586                 if (r <= 0)
2587                         return r;
2588
2589                 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2590                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2591                 if (r < 0)
2592                         return r;
2593                 if (r == 0)
2594                         return -EBADMSG;
2595
2596                 if (type == SD_BUS_TYPE_OBJECT_PATH) {
2597                         if (!validate_object_path(q, l))
2598                                 return -EBADMSG;
2599                 } else {
2600                         if (!validate_string(q, l))
2601                                 return -EBADMSG;
2602                 }
2603
2604                 m->rindex = rindex;
2605                 if (p)
2606                         *(const char**) p = q;
2607
2608                 break;
2609         }
2610
2611         case SD_BUS_TYPE_SIGNATURE: {
2612                 uint8_t l;
2613                 size_t rindex;
2614
2615                 rindex = m->rindex;
2616                 r = message_peek_body(m, &rindex, 1, 1, &q);
2617                 if (r <= 0)
2618                         return r;
2619
2620                 l = *(uint8_t*) q;
2621                 r = message_peek_body(m, &rindex, 1, l+1, &q);
2622                 if (r < 0)
2623                         return r;
2624                 if (r == 0)
2625                         return -EBADMSG;
2626
2627                 if (!validate_signature(q, l))
2628                         return -EBADMSG;
2629
2630                 m->rindex = rindex;
2631
2632                 if (p)
2633                         *(const char**) p = q;
2634                 break;
2635         }
2636
2637         default: {
2638                 ssize_t sz, align;
2639                 size_t rindex;
2640
2641                 align = bus_type_get_alignment(type);
2642                 sz = bus_type_get_size(type);
2643                 assert(align > 0 && sz > 0);
2644
2645                 rindex = m->rindex;
2646                 r = message_peek_body(m, &rindex, align, sz, &q);
2647                 if (r <= 0)
2648                         return r;
2649
2650                 switch (type) {
2651
2652                 case SD_BUS_TYPE_BYTE:
2653                         if (p)
2654                                 *(uint8_t*) p = *(uint8_t*) q;
2655                         break;
2656
2657                 case SD_BUS_TYPE_BOOLEAN:
2658                         if (p)
2659                                 *(unsigned*) p = !!*(uint32_t*) q;
2660                         break;
2661
2662                 case SD_BUS_TYPE_INT16:
2663                 case SD_BUS_TYPE_UINT16:
2664                         if (p)
2665                                 *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
2666                         break;
2667
2668                 case SD_BUS_TYPE_INT32:
2669                 case SD_BUS_TYPE_UINT32:
2670                         if (p)
2671                                 *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2672                         break;
2673
2674                 case SD_BUS_TYPE_INT64:
2675                 case SD_BUS_TYPE_UINT64:
2676                 case SD_BUS_TYPE_DOUBLE:
2677                         if (p)
2678                                 *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
2679                         break;
2680
2681                 case SD_BUS_TYPE_UNIX_FD: {
2682                         uint32_t j;
2683
2684                         j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2685                         if (j >= m->n_fds)
2686                                 return -EBADMSG;
2687
2688                         if (p)
2689                                 *(int*) p = m->fds[j];
2690                         break;
2691                 }
2692
2693                 default:
2694                         assert_not_reached("Unknown basic type...");
2695                 }
2696
2697                 m->rindex = rindex;
2698
2699                 break;
2700         }
2701         }
2702
2703         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2704                 c->index++;
2705
2706         return 1;
2707 }
2708
2709 static int bus_message_enter_array(
2710                 sd_bus_message *m,
2711                 struct bus_container *c,
2712                 const char *contents,
2713                 uint32_t **array_size) {
2714
2715         size_t rindex;
2716         void *q;
2717         int r, alignment;
2718
2719         assert(m);
2720         assert(c);
2721         assert(contents);
2722         assert(array_size);
2723
2724         if (!signature_is_single(contents, true))
2725                 return -EINVAL;
2726
2727         alignment = bus_type_get_alignment(contents[0]);
2728         if (alignment < 0)
2729                 return alignment;
2730
2731         if (!c->signature || c->signature[c->index] == 0)
2732                 return 0;
2733
2734         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
2735                 return -ENXIO;
2736
2737         if (!startswith(c->signature + c->index + 1, contents))
2738                 return -ENXIO;
2739
2740         rindex = m->rindex;
2741         r = message_peek_body(m, &rindex, 4, 4, &q);
2742         if (r <= 0)
2743                 return r;
2744
2745         if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
2746                 return -EBADMSG;
2747
2748         r = message_peek_body(m, &rindex, alignment, 0, NULL);
2749         if (r < 0)
2750                 return r;
2751         if (r == 0)
2752                 return -EBADMSG;
2753
2754         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2755                 c->index += 1 + strlen(contents);
2756
2757         m->rindex = rindex;
2758
2759         *array_size = (uint32_t*) q;
2760
2761         return 1;
2762 }
2763
2764 static int bus_message_enter_variant(
2765                 sd_bus_message *m,
2766                 struct bus_container *c,
2767                 const char *contents) {
2768
2769         size_t rindex;
2770         uint8_t l;
2771         void *q;
2772         int r;
2773
2774         assert(m);
2775         assert(c);
2776         assert(contents);
2777
2778         if (!signature_is_single(contents, false))
2779                 return -EINVAL;
2780
2781         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
2782                 return -EINVAL;
2783
2784         if (!c->signature || c->signature[c->index] == 0)
2785                 return 0;
2786
2787         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
2788                 return -ENXIO;
2789
2790         rindex = m->rindex;
2791         r = message_peek_body(m, &rindex, 1, 1, &q);
2792         if (r <= 0)
2793                 return r;
2794
2795         l = *(uint8_t*) q;
2796         r = message_peek_body(m, &rindex, 1, l+1, &q);
2797         if (r < 0)
2798                 return r;
2799         if (r == 0)
2800                 return -EBADMSG;
2801
2802         if (!validate_signature(q, l))
2803                 return -EBADMSG;
2804
2805         if (!streq(q, contents))
2806                 return -ENXIO;
2807
2808         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2809                 c->index++;
2810
2811         m->rindex = rindex;
2812
2813         return 1;
2814 }
2815
2816 static int bus_message_enter_struct(
2817                 sd_bus_message *m,
2818                 struct bus_container *c,
2819                 const char *contents) {
2820
2821         size_t l;
2822         int r;
2823
2824         assert(m);
2825         assert(c);
2826         assert(contents);
2827
2828         if (!signature_is_valid(contents, false))
2829                 return -EINVAL;
2830
2831         if (!c->signature || c->signature[c->index] == 0)
2832                 return 0;
2833
2834         l = strlen(contents);
2835
2836         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
2837             !startswith(c->signature + c->index + 1, contents) ||
2838             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
2839                 return -ENXIO;
2840
2841         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2842         if (r <= 0)
2843                 return r;
2844
2845         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2846                 c->index += 1 + l + 1;
2847
2848         return 1;
2849 }
2850
2851 static int bus_message_enter_dict_entry(
2852                 sd_bus_message *m,
2853                 struct bus_container *c,
2854                 const char *contents) {
2855
2856         size_t l;
2857         int r;
2858
2859         assert(m);
2860         assert(c);
2861         assert(contents);
2862
2863         if (!signature_is_pair(contents))
2864                 return -EINVAL;
2865
2866         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2867                 return -ENXIO;
2868
2869         if (!c->signature || c->signature[c->index] == 0)
2870                 return 0;
2871
2872         l = strlen(contents);
2873
2874         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
2875             !startswith(c->signature + c->index + 1, contents) ||
2876             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
2877                 return -ENXIO;
2878
2879         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
2880         if (r <= 0)
2881                 return r;
2882
2883         if (c->enclosing != SD_BUS_TYPE_ARRAY)
2884                 c->index += 1 + l + 1;
2885
2886         return 1;
2887 }
2888
2889 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
2890         struct bus_container *c, *w;
2891         uint32_t *array_size = NULL;
2892         char *signature;
2893         size_t before;
2894         int r;
2895
2896         assert_return(m, -EINVAL);
2897         assert_return(m->sealed, -EPERM);
2898         assert_return(type != 0 || !contents, -EINVAL);
2899
2900         if (type == 0 || !contents) {
2901                 const char *cc;
2902                 char tt;
2903
2904                 /* Allow entering into anonymous containers */
2905                 r = sd_bus_message_peek_type(m, &tt, &cc);
2906                 if (r <= 0)
2907                         return r;
2908
2909                 if (type != 0 && type != tt)
2910                         return -ENXIO;
2911
2912                 if (contents && !streq(contents, cc))
2913                         return -ENXIO;
2914
2915                 type = tt;
2916                 contents = cc;
2917         }
2918
2919         /*
2920          * We enforce a global limit on container depth, that is much
2921          * higher than the 32 structs and 32 arrays the specification
2922          * mandates. This is simpler to implement for us, and we need
2923          * this only to ensure our container array doesn't grow
2924          * without bounds. We are happy to return any data from a
2925          * message as long as the data itself is valid, even if the
2926          * overall message might be not.
2927          *
2928          * Note that the message signature is validated when
2929          * parsing the headers, and that validation does check the
2930          * 32/32 limit.
2931          *
2932          * Note that the specification defines no limits on the depth
2933          * of stacked variants, but we do.
2934          */
2935         if (m->n_containers >= BUS_CONTAINER_DEPTH)
2936                 return -EBADMSG;
2937
2938         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
2939         if (!w)
2940                 return -ENOMEM;
2941         m->containers = w;
2942
2943         if (message_end_of_signature(m))
2944                 return -ENXIO;
2945
2946         if (message_end_of_array(m, m->rindex))
2947                 return 0;
2948
2949         c = message_get_container(m);
2950
2951         signature = strdup(contents);
2952         if (!signature)
2953                 return -ENOMEM;
2954
2955         c->saved_index = c->index;
2956         before = m->rindex;
2957
2958         if (type == SD_BUS_TYPE_ARRAY)
2959                 r = bus_message_enter_array(m, c, contents, &array_size);
2960         else if (type == SD_BUS_TYPE_VARIANT)
2961                 r = bus_message_enter_variant(m, c, contents);
2962         else if (type == SD_BUS_TYPE_STRUCT)
2963                 r = bus_message_enter_struct(m, c, contents);
2964         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2965                 r = bus_message_enter_dict_entry(m, c, contents);
2966         else
2967                 r = -EINVAL;
2968
2969         if (r <= 0) {
2970                 free(signature);
2971                 return r;
2972         }
2973
2974         /* OK, let's fill it in */
2975         w += m->n_containers++;
2976         w->enclosing = type;
2977         w->signature = signature;
2978         w->index = 0;
2979         w->array_size = array_size;
2980         w->before = before;
2981         w->begin = m->rindex;
2982
2983         return 1;
2984 }
2985
2986 int sd_bus_message_exit_container(sd_bus_message *m) {
2987         struct bus_container *c;
2988
2989         assert_return(m, -EINVAL);
2990         assert_return(m->sealed, -EPERM);
2991         assert_return(m->n_containers > 0, -EINVAL);
2992
2993         c = message_get_container(m);
2994         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2995                 uint32_t l;
2996
2997                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2998                 if (c->begin + l != m->rindex)
2999                         return -EBUSY;
3000
3001         } else {
3002                 if (c->signature && c->signature[c->index] != 0)
3003                         return -EINVAL;
3004         }
3005
3006         free(c->signature);
3007         m->n_containers--;
3008
3009         return 1;
3010 }
3011
3012 static void message_quit_container(sd_bus_message *m) {
3013         struct bus_container *c;
3014
3015         assert(m);
3016         assert(m->sealed);
3017         assert(m->n_containers > 0);
3018
3019         c = message_get_container(m);
3020
3021         /* Undo seeks */
3022         assert(m->rindex >= c->before);
3023         m->rindex = c->before;
3024
3025         /* Free container */
3026         free(c->signature);
3027         m->n_containers--;
3028
3029         /* Correct index of new top-level container */
3030         c = message_get_container(m);
3031         c->index = c->saved_index;
3032 }
3033
3034 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
3035         struct bus_container *c;
3036         int r;
3037
3038         assert_return(m, -EINVAL);
3039         assert_return(m->sealed, -EPERM);
3040
3041         if (message_end_of_signature(m))
3042                 goto eof;
3043
3044         if (message_end_of_array(m, m->rindex))
3045                 goto eof;
3046
3047         c = message_get_container(m);
3048
3049         if (bus_type_is_basic(c->signature[c->index])) {
3050                 if (contents)
3051                         *contents = NULL;
3052                 if (type)
3053                         *type = c->signature[c->index];
3054                 return 1;
3055         }
3056
3057         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
3058
3059                 if (contents) {
3060                         size_t l;
3061                         char *sig;
3062
3063                         r = signature_element_length(c->signature+c->index+1, &l);
3064                         if (r < 0)
3065                                 return r;
3066
3067                         assert(l >= 1);
3068
3069                         sig = strndup(c->signature + c->index + 1, l);
3070                         if (!sig)
3071                                 return -ENOMEM;
3072
3073                         free(m->peeked_signature);
3074                         m->peeked_signature = sig;
3075
3076                         *contents = sig;
3077                 }
3078
3079                 if (type)
3080                         *type = SD_BUS_TYPE_ARRAY;
3081
3082                 return 1;
3083         }
3084
3085         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
3086             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
3087
3088                 if (contents) {
3089                         size_t l;
3090                         char *sig;
3091
3092                         r = signature_element_length(c->signature+c->index, &l);
3093                         if (r < 0)
3094                                 return r;
3095
3096                         assert(l >= 2);
3097                         sig = strndup(c->signature + c->index + 1, l - 2);
3098                         if (!sig)
3099                                 return -ENOMEM;
3100
3101                         free(m->peeked_signature);
3102                         m->peeked_signature = sig;
3103
3104                         *contents = sig;
3105                 }
3106
3107                 if (type)
3108                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
3109
3110                 return 1;
3111         }
3112
3113         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
3114                 if (contents) {
3115                         size_t rindex, l;
3116                         void *q;
3117
3118                         rindex = m->rindex;
3119                         r = message_peek_body(m, &rindex, 1, 1, &q);
3120                         if (r < 0)
3121                                 return r;
3122                         if (r == 0)
3123                                 goto eof;
3124
3125                         l = *(uint8_t*) q;
3126                         r = message_peek_body(m, &rindex, 1, l+1, &q);
3127                         if (r < 0)
3128                                 return r;
3129                         if (r == 0)
3130                                 return -EBADMSG;
3131
3132                         if (!validate_signature(q, l))
3133                                 return -EBADMSG;
3134
3135                         *contents = q;
3136                 }
3137
3138                 if (type)
3139                         *type = SD_BUS_TYPE_VARIANT;
3140
3141                 return 1;
3142         }
3143
3144         return -EINVAL;
3145
3146 eof:
3147         if (type)
3148                 *type = 0;
3149         if (contents)
3150                 *contents = NULL;
3151         return 0;
3152 }
3153
3154 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
3155         struct bus_container *c;
3156
3157         assert_return(m, -EINVAL);
3158         assert_return(m->sealed, -EPERM);
3159
3160         if (complete) {
3161                 message_reset_containers(m);
3162                 m->rindex = 0;
3163                 m->root_container.index = 0;
3164
3165                 c = message_get_container(m);
3166         } else {
3167                 c = message_get_container(m);
3168
3169                 c->index = 0;
3170                 m->rindex = c->begin;
3171         }
3172
3173         return !isempty(c->signature);
3174 }
3175 static int message_read_ap(
3176                 sd_bus_message *m,
3177                 const char *types,
3178                 va_list ap) {
3179
3180         unsigned n_array, n_struct;
3181         TypeStack stack[BUS_CONTAINER_DEPTH];
3182         unsigned stack_ptr = 0;
3183         unsigned n_loop = 0;
3184         int r;
3185
3186         assert(m);
3187
3188         if (isempty(types))
3189                 return 0;
3190
3191         /* Ideally, we'd just call ourselves recursively on every
3192          * complex type. However, the state of a va_list that is
3193          * passed to a function is undefined after that function
3194          * returns. This means we need to docode the va_list linearly
3195          * in a single stackframe. We hence implement our own
3196          * home-grown stack in an array. */
3197
3198         n_array = (unsigned) -1; /* lenght of current array entries */
3199         n_struct = strlen(types); /* length of current struct contents signature */
3200
3201         for (;;) {
3202                 const char *t;
3203
3204                 n_loop++;
3205
3206                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
3207                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
3208                         if (r < 0)
3209                                 return r;
3210                         if (r == 0)
3211                                 break;
3212
3213                         r = sd_bus_message_exit_container(m);
3214                         if (r < 0)
3215                                 return r;
3216
3217                         continue;
3218                 }
3219
3220                 t = types;
3221                 if (n_array != (unsigned) -1)
3222                         n_array --;
3223                 else {
3224                         types ++;
3225                         n_struct--;
3226                 }
3227
3228                 switch (*t) {
3229
3230                 case SD_BUS_TYPE_BYTE:
3231                 case SD_BUS_TYPE_BOOLEAN:
3232                 case SD_BUS_TYPE_INT16:
3233                 case SD_BUS_TYPE_UINT16:
3234                 case SD_BUS_TYPE_INT32:
3235                 case SD_BUS_TYPE_UINT32:
3236                 case SD_BUS_TYPE_INT64:
3237                 case SD_BUS_TYPE_UINT64:
3238                 case SD_BUS_TYPE_DOUBLE:
3239                 case SD_BUS_TYPE_STRING:
3240                 case SD_BUS_TYPE_OBJECT_PATH:
3241                 case SD_BUS_TYPE_SIGNATURE:
3242                 case SD_BUS_TYPE_UNIX_FD: {
3243                         void *p;
3244
3245                         p = va_arg(ap, void*);
3246                         r = sd_bus_message_read_basic(m, *t, p);
3247                         if (r < 0)
3248                                 return r;
3249                         if (r == 0) {
3250                                 if (n_loop <= 1)
3251                                         return 0;
3252
3253                                 return -ENXIO;
3254                         }
3255
3256                         break;
3257                 }
3258
3259                 case SD_BUS_TYPE_ARRAY: {
3260                         size_t k;
3261
3262                         r = signature_element_length(t + 1, &k);
3263                         if (r < 0)
3264                                 return r;
3265
3266                         {
3267                                 char s[k + 1];
3268                                 memcpy(s, t + 1, k);
3269                                 s[k] = 0;
3270
3271                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3272                                 if (r < 0)
3273                                         return r;
3274                                 if (r == 0) {
3275                                         if (n_loop <= 1)
3276                                                 return 0;
3277
3278                                         return -ENXIO;
3279                                 }
3280                         }
3281
3282                         if (n_array == (unsigned) -1) {
3283                                 types += k;
3284                                 n_struct -= k;
3285                         }
3286
3287                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3288                         if (r < 0)
3289                                 return r;
3290
3291                         types = t + 1;
3292                         n_struct = k;
3293                         n_array = va_arg(ap, unsigned);
3294
3295                         break;
3296                 }
3297
3298                 case SD_BUS_TYPE_VARIANT: {
3299                         const char *s;
3300
3301                         s = va_arg(ap, const char *);
3302                         if (!s)
3303                                 return -EINVAL;
3304
3305                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
3306                         if (r < 0)
3307                                 return r;
3308                         if (r == 0) {
3309                                 if (n_loop <= 1)
3310                                         return 0;
3311
3312                                 return -ENXIO;
3313                         }
3314
3315                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3316                         if (r < 0)
3317                                 return r;
3318
3319                         types = s;
3320                         n_struct = strlen(s);
3321                         n_array = (unsigned) -1;
3322
3323                         break;
3324                 }
3325
3326                 case SD_BUS_TYPE_STRUCT_BEGIN:
3327                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3328                         size_t k;
3329
3330                         r = signature_element_length(t, &k);
3331                         if (r < 0)
3332                                 return r;
3333
3334                         {
3335                                 char s[k - 1];
3336                                 memcpy(s, t + 1, k - 2);
3337                                 s[k - 2] = 0;
3338
3339                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3340                                 if (r < 0)
3341                                         return r;
3342                                 if (r == 0) {
3343                                         if (n_loop <= 1)
3344                                                 return 0;
3345                                         return -ENXIO;
3346                                 }
3347                         }
3348
3349                         if (n_array == (unsigned) -1) {
3350                                 types += k - 1;
3351                                 n_struct -= k - 1;
3352                         }
3353
3354                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
3355                         if (r < 0)
3356                                 return r;
3357
3358                         types = t + 1;
3359                         n_struct = k - 2;
3360                         n_array = (unsigned) -1;
3361
3362                         break;
3363                 }
3364
3365                 default:
3366                         return -EINVAL;
3367                 }
3368         }
3369
3370         return 1;
3371 }
3372
3373 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
3374         va_list ap;
3375         int r;
3376
3377         assert_return(m, -EINVAL);
3378         assert_return(m->sealed, -EPERM);
3379         assert_return(types, -EINVAL);
3380
3381         va_start(ap, types);
3382         r = message_read_ap(m, types, ap);
3383         va_end(ap);
3384
3385         return r;
3386 }
3387
3388 int sd_bus_message_skip(sd_bus_message *m, const char *types) {
3389         int r;
3390
3391         assert_return(m, -EINVAL);
3392         assert_return(m->sealed, -EPERM);
3393         assert_return(types, -EINVAL);
3394
3395         if (isempty(types))
3396                 return 0;
3397
3398         switch (*types) {
3399
3400         case SD_BUS_TYPE_BYTE:
3401         case SD_BUS_TYPE_BOOLEAN:
3402         case SD_BUS_TYPE_INT16:
3403         case SD_BUS_TYPE_UINT16:
3404         case SD_BUS_TYPE_INT32:
3405         case SD_BUS_TYPE_UINT32:
3406         case SD_BUS_TYPE_INT64:
3407         case SD_BUS_TYPE_UINT64:
3408         case SD_BUS_TYPE_DOUBLE:
3409         case SD_BUS_TYPE_STRING:
3410         case SD_BUS_TYPE_OBJECT_PATH:
3411         case SD_BUS_TYPE_SIGNATURE:
3412         case SD_BUS_TYPE_UNIX_FD:
3413
3414                 r = sd_bus_message_read_basic(m, *types, NULL);
3415                 if (r <= 0)
3416                         return r;
3417
3418                 r = sd_bus_message_skip(m, types + 1);
3419                 if (r < 0)
3420                         return r;
3421
3422                 return 1;
3423
3424         case SD_BUS_TYPE_ARRAY: {
3425                 size_t k;
3426
3427                 r = signature_element_length(types + 1, &k);
3428                 if (r < 0)
3429                         return r;
3430
3431                 {
3432                         char s[k+1];
3433                         memcpy(s, types+1, k);
3434                         s[k] = 0;
3435
3436                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
3437                         if (r <= 0)
3438                                 return r;
3439
3440                         for (;;) {
3441                                 r = sd_bus_message_skip(m, s);
3442                                 if (r < 0)
3443                                         return r;
3444                                 if (r == 0)
3445                                         break;
3446                         }
3447
3448                         r = sd_bus_message_exit_container(m);
3449                         if (r < 0)
3450                                 return r;
3451                 }
3452
3453                 r = sd_bus_message_skip(m, types + 1 + k);
3454                 if (r < 0)
3455                         return r;
3456
3457                 return 1;
3458         }
3459
3460         case SD_BUS_TYPE_VARIANT: {
3461                 const char *contents;
3462                 char x;
3463
3464                 r = sd_bus_message_peek_type(m, &x, &contents);
3465                 if (r <= 0)
3466                         return r;
3467
3468                 if (x != SD_BUS_TYPE_VARIANT)
3469                         return -ENXIO;
3470
3471                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
3472                 if (r <= 0)
3473                         return r;
3474
3475                 r = sd_bus_message_skip(m, contents);
3476                 if (r < 0)
3477                         return r;
3478                 assert(r != 0);
3479
3480                 r = sd_bus_message_exit_container(m);
3481                 if (r < 0)
3482                         return r;
3483
3484                 r = sd_bus_message_skip(m, types + 1);
3485                 if (r < 0)
3486                         return r;
3487
3488                 return 1;
3489         }
3490
3491         case SD_BUS_TYPE_STRUCT_BEGIN:
3492         case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
3493                 size_t k;
3494
3495                 r = signature_element_length(types, &k);
3496                 if (r < 0)
3497                         return r;
3498
3499                 {
3500                         char s[k-1];
3501                         memcpy(s, types+1, k-2);
3502                         s[k-2] = 0;
3503
3504                         r = sd_bus_message_enter_container(m, *types == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
3505                         if (r <= 0)
3506                                 return r;
3507
3508                         r = sd_bus_message_skip(m, s);
3509                         if (r < 0)
3510                                 return r;
3511                         assert(r != 0);
3512
3513                         r = sd_bus_message_exit_container(m);
3514                         if (r < 0)
3515                                 return r;
3516                 }
3517
3518                 r = sd_bus_message_skip(m, types + k);
3519                 if (r < 0)
3520                         return r;
3521
3522                 return 1;
3523         }
3524
3525         default:
3526                 return -EINVAL;
3527         }
3528 }
3529
3530 int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size) {
3531         struct bus_container *c;
3532         void *p;
3533         size_t sz;
3534         ssize_t align;
3535         int r;
3536
3537         assert_return(m, -EINVAL);
3538         assert_return(m->sealed, -EPERM);
3539         assert_return(bus_type_is_trivial(type), -EINVAL);
3540         assert_return(ptr, -EINVAL);
3541         assert_return(size, -EINVAL);
3542         assert_return(!BUS_MESSAGE_NEED_BSWAP(m), -ENOTSUP);
3543
3544         align = bus_type_get_alignment(type);
3545         if (align < 0)
3546                 return align;
3547
3548         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, CHAR_TO_STR(type));
3549         if (r <= 0)
3550                 return r;
3551
3552         c = message_get_container(m);
3553         sz = BUS_MESSAGE_BSWAP32(m, *c->array_size);
3554
3555         r = message_peek_body(m, &m->rindex, align, sz, &p);
3556         if (r < 0)
3557                 goto fail;
3558         if (r == 0) {
3559                 r = -EBADMSG;
3560                 goto fail;
3561         }
3562
3563         r = sd_bus_message_exit_container(m);
3564         if (r < 0)
3565                 goto fail;
3566
3567         *ptr = (const void*) p;
3568         *size = sz;
3569
3570         return 1;
3571
3572 fail:
3573         message_quit_container(m);
3574         return r;
3575 }
3576
3577 static int message_peek_fields(
3578                 sd_bus_message *m,
3579                 size_t *rindex,
3580                 size_t align,
3581                 size_t nbytes,
3582                 void **ret) {
3583
3584         assert(m);
3585         assert(rindex);
3586         assert(align > 0);
3587
3588         return buffer_peek(BUS_MESSAGE_FIELDS(m), BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
3589 }
3590
3591 static int message_peek_field_uint32(
3592                 sd_bus_message *m,
3593                 size_t *ri,
3594                 uint32_t *ret) {
3595
3596         int r;
3597         void *q;
3598
3599         assert(m);
3600         assert(ri);
3601
3602         r = message_peek_fields(m, ri, 4, 4, &q);
3603         if (r < 0)
3604                 return r;
3605
3606         if (ret)
3607                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
3608
3609         return 0;
3610 }
3611
3612 static int message_peek_field_string(
3613                 sd_bus_message *m,
3614                 bool (*validate)(const char *p),
3615                 size_t *ri,
3616                 const char **ret) {
3617
3618         uint32_t l;
3619         int r;
3620         void *q;
3621
3622         assert(m);
3623         assert(ri);
3624
3625         r = message_peek_field_uint32(m, ri, &l);
3626         if (r < 0)
3627                 return r;
3628
3629         r = message_peek_fields(m, ri, 1, l+1, &q);
3630         if (r < 0)
3631                 return r;
3632
3633         if (validate) {
3634                 if (!validate_nul(q, l))
3635                         return -EBADMSG;
3636
3637                 if (!validate(q))
3638                         return -EBADMSG;
3639         } else {
3640                 if (!validate_string(q, l))
3641                         return -EBADMSG;
3642         }
3643
3644         if (ret)
3645                 *ret = q;
3646
3647         return 0;
3648 }
3649
3650 static int message_peek_field_signature(
3651                 sd_bus_message *m,
3652                 size_t *ri,
3653                 const char **ret) {
3654
3655         size_t l;
3656         int r;
3657         void *q;
3658
3659         assert(m);
3660         assert(ri);
3661
3662         r = message_peek_fields(m, ri, 1, 1, &q);
3663         if (r < 0)
3664                 return r;
3665
3666         l = *(uint8_t*) q;
3667         r = message_peek_fields(m, ri, 1, l+1, &q);
3668         if (r < 0)
3669                 return r;
3670
3671         if (!validate_signature(q, l))
3672                 return -EBADMSG;
3673
3674         if (ret)
3675                 *ret = q;
3676
3677         return 0;
3678 }
3679
3680 static int message_skip_fields(
3681                 sd_bus_message *m,
3682                 size_t *ri,
3683                 uint32_t array_size,
3684                 const char **signature) {
3685
3686         size_t original_index;
3687         int r;
3688
3689         assert(m);
3690         assert(ri);
3691         assert(signature);
3692
3693         original_index = *ri;
3694
3695         for (;;) {
3696                 char t;
3697                 size_t l;
3698
3699                 if (array_size != (uint32_t) -1 &&
3700                     array_size <= *ri - original_index)
3701                         return 0;
3702
3703                 t = **signature;
3704                 if (!t)
3705                         return 0;
3706
3707                 if (t == SD_BUS_TYPE_STRING) {
3708
3709                         r = message_peek_field_string(m, NULL, ri, NULL);
3710                         if (r < 0)
3711                                 return r;
3712
3713                         (*signature)++;
3714
3715                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
3716
3717                         r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
3718                         if (r < 0)
3719                                 return r;
3720
3721                         (*signature)++;
3722
3723                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
3724
3725                         r = message_peek_field_signature(m, ri, NULL);
3726                         if (r < 0)
3727                                 return r;
3728
3729                         (*signature)++;
3730
3731                 } else if (bus_type_is_basic(t)) {
3732                         ssize_t align, k;
3733
3734                         align = bus_type_get_alignment(t);
3735                         k = bus_type_get_size(t);
3736                         assert(align > 0 && k > 0);
3737
3738                         r = message_peek_fields(m, ri, align, k, NULL);
3739                         if (r < 0)
3740                                 return r;
3741
3742                         (*signature)++;
3743
3744                 } else if (t == SD_BUS_TYPE_ARRAY) {
3745
3746                         r = signature_element_length(*signature+1, &l);
3747                         if (r < 0)
3748                                 return r;
3749
3750                         assert(l >= 1);
3751                         {
3752                                 char sig[l-1], *s;
3753                                 uint32_t nas;
3754                                 int alignment;
3755
3756                                 strncpy(sig, *signature + 1, l-1);
3757                                 s = sig;
3758
3759                                 alignment = bus_type_get_alignment(sig[0]);
3760                                 if (alignment < 0)
3761                                         return alignment;
3762
3763                                 r = message_peek_field_uint32(m, ri, &nas);
3764                                 if (r < 0)
3765                                         return r;
3766                                 if (nas > BUS_ARRAY_MAX_SIZE)
3767                                         return -EBADMSG;
3768
3769                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
3770                                 if (r < 0)
3771                                         return r;
3772
3773                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
3774                                 if (r < 0)
3775                                         return r;
3776