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