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