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