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