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