chiark / gitweb /
2d051e8aeb97fafeabf63f3e18ec11a689df7552
[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 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
2095         const char *t;
2096         int r;
2097
2098         assert(m);
2099         assert(types);
2100
2101         for (t = types; *t; t++) {
2102                 switch (*t) {
2103
2104                 case SD_BUS_TYPE_BYTE:
2105                 case SD_BUS_TYPE_BOOLEAN:
2106                 case SD_BUS_TYPE_INT16:
2107                 case SD_BUS_TYPE_UINT16:
2108                 case SD_BUS_TYPE_INT32:
2109                 case SD_BUS_TYPE_UINT32:
2110                 case SD_BUS_TYPE_INT64:
2111                 case SD_BUS_TYPE_UINT64:
2112                 case SD_BUS_TYPE_DOUBLE:
2113                 case SD_BUS_TYPE_STRING:
2114                 case SD_BUS_TYPE_OBJECT_PATH:
2115                 case SD_BUS_TYPE_SIGNATURE:
2116                 case SD_BUS_TYPE_UNIX_FD: {
2117                         void *p;
2118
2119                         p = va_arg(ap, void*);
2120                         r = sd_bus_message_read_basic(m, *t, p);
2121                         break;
2122                 }
2123
2124                 case SD_BUS_TYPE_ARRAY: {
2125                         size_t k;
2126
2127                         r = signature_element_length(t + 1, &k);
2128                         if (r < 0)
2129                                 return r;
2130
2131                         {
2132                                 unsigned i, n;
2133                                 char s[k + 1];
2134
2135                                 memcpy(s, t + 1, k);
2136                                 s[k] = 0;
2137                                 t += k;
2138
2139                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2140                                 if (r < 0)
2141                                         return r;
2142                                 if (r == 0)
2143                                         return -ENXIO;
2144
2145                                 n = va_arg(ap, unsigned);
2146                                 for (i = 0; i < n; i++) {
2147                                         r = message_read_ap(m, s, ap);
2148                                         if (r < 0)
2149                                                 return r;
2150                                 }
2151
2152                                 r = sd_bus_message_exit_container(m);
2153                         }
2154
2155                         break;
2156                 }
2157
2158                 case SD_BUS_TYPE_VARIANT: {
2159                         const char *s;
2160
2161                         s = va_arg(ap, const char *);
2162                         if (!s)
2163                                 return -EINVAL;
2164
2165                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2166                         if (r < 0)
2167                                 return r;
2168                         if (r == 0)
2169                                 return -ENXIO;
2170
2171                         r = message_read_ap(m, s, ap);
2172                         if (r < 0)
2173                                 return r;
2174                         if (r == 0)
2175                                 return -ENXIO;
2176
2177                         r = sd_bus_message_exit_container(m);
2178                         break;
2179                 }
2180
2181                 case SD_BUS_TYPE_STRUCT_BEGIN:
2182                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2183                         size_t k;
2184
2185                         r = signature_element_length(t, &k);
2186                         if (r < 0)
2187                                 return r;
2188
2189                         {
2190                                 char s[k - 1];
2191                                 memcpy(s, t + 1, k - 2);
2192                                 s[k - 2] = 0;
2193
2194                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2195                                 if (r < 0)
2196                                         return r;
2197                                 if (r == 0)
2198                                         return -ENXIO;
2199
2200                                 t += k - 1;
2201
2202                                 r = message_read_ap(m, s, ap);
2203                                 if (r < 0)
2204                                         return r;
2205                                 if (r == 0)
2206                                         return -ENXIO;
2207
2208                                 r = sd_bus_message_exit_container(m);
2209                         }
2210
2211                         break;
2212                 }
2213
2214                 default:
2215                         r = -EINVAL;
2216                 }
2217
2218                 if (r < 0)
2219                         return r;
2220                 if (r == 0)
2221                         return -ENXIO;
2222         }
2223
2224         return 1;
2225 }
2226
2227 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2228         va_list ap;
2229         int r;
2230
2231         if (!m)
2232                 return -EINVAL;
2233         if (!m->sealed)
2234                 return -EPERM;
2235         if (!types)
2236                 return -EINVAL;
2237
2238         va_start(ap, types);
2239         r = message_read_ap(m, types, ap);
2240         va_end(ap);
2241
2242         return r;
2243 }
2244
2245 static int message_peek_fields(
2246                 sd_bus_message *m,
2247                 size_t *rindex,
2248                 size_t align,
2249                 size_t nbytes,
2250                 void **ret) {
2251
2252         assert(m);
2253         assert(rindex);
2254         assert(align > 0);
2255
2256         return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2257 }
2258
2259 static int message_peek_field_uint32(
2260                 sd_bus_message *m,
2261                 size_t *ri,
2262                 uint32_t *ret) {
2263
2264         int r;
2265         void *q;
2266
2267         assert(m);
2268         assert(ri);
2269
2270         r = message_peek_fields(m, ri, 4, 4, &q);
2271         if (r < 0)
2272                 return r;
2273
2274         if (ret)
2275                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2276
2277         return 0;
2278 }
2279
2280 static int message_peek_field_string(
2281                 sd_bus_message *m,
2282                 bool (*validate)(const char *p),
2283                 size_t *ri,
2284                 const char **ret) {
2285
2286         uint32_t l;
2287         int r;
2288         void *q;
2289
2290         assert(m);
2291         assert(ri);
2292
2293         r = message_peek_field_uint32(m, ri, &l);
2294         if (r < 0)
2295                 return r;
2296
2297         r = message_peek_fields(m, ri, 1, l+1, &q);
2298         if (r < 0)
2299                 return r;
2300
2301         if (validate) {
2302                 if (!validate_nul(q, l))
2303                         return -EBADMSG;
2304
2305                 if (!validate(q))
2306                         return -EBADMSG;
2307         } else {
2308                 if (!validate_string(q, l))
2309                         return -EBADMSG;
2310         }
2311
2312         if (ret)
2313                 *ret = q;
2314
2315         return 0;
2316 }
2317
2318 static int message_peek_field_signature(
2319                 sd_bus_message *m,
2320                 size_t *ri,
2321                 const char **ret) {
2322
2323         size_t l;
2324         int r;
2325         void *q;
2326
2327         assert(m);
2328         assert(ri);
2329
2330         r = message_peek_fields(m, ri, 1, 1, &q);
2331         if (r < 0)
2332                 return r;
2333
2334         l = *(uint8_t*) q;
2335         r = message_peek_fields(m, ri, 1, l+1, &q);
2336         if (r < 0)
2337                 return r;
2338
2339         if (!validate_signature(q, l))
2340                 return -EBADMSG;
2341
2342         if (ret)
2343                 *ret = q;
2344
2345         return 0;
2346 }
2347
2348 static int message_skip_fields(
2349                 sd_bus_message *m,
2350                 size_t *ri,
2351                 uint32_t array_size,
2352                 const char **signature) {
2353
2354         size_t original_index;
2355         int r;
2356
2357         assert(m);
2358         assert(ri);
2359         assert(signature);
2360
2361         original_index = *ri;
2362
2363         for (;;) {
2364                 char t;
2365                 size_t l;
2366
2367                 if (array_size != (uint32_t) -1 &&
2368                     array_size <= *ri - original_index)
2369                         return 0;
2370
2371                 t = **signature;
2372                 if (!t)
2373                         return 0;
2374
2375                 if (t == SD_BUS_TYPE_STRING) {
2376
2377                         r = message_peek_field_string(m, NULL, ri, NULL);
2378                         if (r < 0)
2379                                 return r;
2380
2381                         (*signature)++;
2382
2383                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2384
2385                         r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2386                         if (r < 0)
2387                                 return r;
2388
2389                         (*signature)++;
2390
2391                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2392
2393                         r = message_peek_field_signature(m, ri, NULL);
2394                         if (r < 0)
2395                                 return r;
2396
2397                         (*signature)++;
2398
2399                 } else if (bus_type_is_basic(t)) {
2400                         ssize_t align, k;
2401
2402                         align = bus_type_get_alignment(t);
2403                         k = bus_type_get_size(t);
2404                         assert(align > 0 && k > 0);
2405
2406                         r = message_peek_fields(m, ri, align, k, NULL);
2407                         if (r < 0)
2408                                 return r;
2409
2410                         (*signature)++;
2411
2412                 } else if (t == SD_BUS_TYPE_ARRAY) {
2413
2414                         r = signature_element_length(*signature+1, &l);
2415                         if (r < 0)
2416                                 return r;
2417
2418                         assert(l >= 1);
2419                         {
2420                                 char sig[l-1], *s;
2421                                 uint32_t nas;
2422                                 int alignment;
2423
2424                                 strncpy(sig, *signature + 1, l-1);
2425                                 s = sig;
2426
2427                                 alignment = bus_type_get_alignment(sig[0]);
2428                                 if (alignment < 0)
2429                                         return alignment;
2430
2431                                 r = message_peek_field_uint32(m, ri, &nas);
2432                                 if (r < 0)
2433                                         return r;
2434                                 if (nas > BUS_ARRAY_MAX_SIZE)
2435                                         return -EBADMSG;
2436
2437                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
2438                                 if (r < 0)
2439                                         return r;
2440
2441                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
2442                                 if (r < 0)
2443                                         return r;
2444                         }
2445
2446                         (*signature) += 1 + l;
2447
2448                 } else if (t == SD_BUS_TYPE_VARIANT) {
2449                         const char *s;
2450
2451                         r = message_peek_field_signature(m, ri, &s);
2452                         if (r < 0)
2453                                 return r;
2454
2455                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2456                         if (r < 0)
2457                                 return r;
2458
2459                         (*signature)++;
2460
2461                 } else if (t == SD_BUS_TYPE_STRUCT ||
2462                            t == SD_BUS_TYPE_DICT_ENTRY) {
2463
2464                         r = signature_element_length(*signature, &l);
2465                         if (r < 0)
2466                                 return r;
2467
2468                         assert(l >= 2);
2469                         {
2470                                 char sig[l-1], *s;
2471                                 strncpy(sig, *signature + 1, l-1);
2472                                 s = sig;
2473
2474                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2475                                 if (r < 0)
2476                                         return r;
2477                         }
2478
2479                         *signature += l;
2480                 } else
2481                         return -EINVAL;
2482         }
2483 }
2484
2485 static int message_parse_fields(sd_bus_message *m) {
2486         size_t ri;
2487         int r;
2488         uint32_t unix_fds = 0;
2489
2490         assert(m);
2491
2492         for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2493                 const char *signature;
2494                 uint8_t *header;
2495
2496                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2497                 if (r < 0)
2498                         return r;
2499
2500                 r = message_peek_field_signature(m, &ri, &signature);
2501                 if (r < 0)
2502                         return r;
2503
2504                 switch (*header) {
2505                 case _SD_BUS_MESSAGE_HEADER_INVALID:
2506                         return -EBADMSG;
2507
2508                 case SD_BUS_MESSAGE_HEADER_PATH:
2509
2510                         if (m->path)
2511                                 return -EBADMSG;
2512
2513                         if (!streq(signature, "o"))
2514                                 return -EBADMSG;
2515
2516                         r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2517                         break;
2518
2519                 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2520
2521                         if (m->interface)
2522                                 return -EBADMSG;
2523
2524                         if (!streq(signature, "s"))
2525                                 return -EBADMSG;
2526
2527                         r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2528                         break;
2529
2530                 case SD_BUS_MESSAGE_HEADER_MEMBER:
2531
2532                         if (m->member)
2533                                 return -EBADMSG;
2534
2535                         if (!streq(signature, "s"))
2536                                 return -EBADMSG;
2537
2538                         r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2539                         break;
2540
2541                 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2542
2543                         if (m->error.name)
2544                                 return -EBADMSG;
2545
2546                         if (!streq(signature, "s"))
2547                                 return -EBADMSG;
2548
2549                         r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2550                         break;
2551
2552                 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2553
2554                         if (m->destination)
2555                                 return -EBADMSG;
2556
2557                         if (!streq(signature, "s"))
2558                                 return -EBADMSG;
2559
2560                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2561                         break;
2562
2563                 case SD_BUS_MESSAGE_HEADER_SENDER:
2564
2565                         if (m->sender)
2566                                 return -EBADMSG;
2567
2568                         if (!streq(signature, "s"))
2569                                 return -EBADMSG;
2570
2571                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2572                         break;
2573
2574
2575                 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2576                         const char *s;
2577                         char *c;
2578
2579                         if (m->root_container.signature)
2580                                 return -EBADMSG;
2581
2582                         if (!streq(signature, "g"))
2583                                 return -EBADMSG;
2584
2585                         r = message_peek_field_signature(m, &ri, &s);
2586                         if (r < 0)
2587                                 return r;
2588
2589                         c = strdup(s);
2590                         if (!c)
2591                                 return -ENOMEM;
2592
2593                         free(m->root_container.signature);
2594                         m->root_container.signature = c;
2595                         break;
2596                 }
2597
2598                 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2599                         if (m->reply_serial != 0)
2600                                 return -EBADMSG;
2601
2602                         if (!streq(signature, "u"))
2603                                 return -EBADMSG;
2604
2605                         r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2606                         if (r < 0)
2607                                 return r;
2608
2609                         if (m->reply_serial == 0)
2610                                 return -EBADMSG;
2611
2612                         break;
2613
2614                 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2615                         if (unix_fds != 0)
2616                                 return -EBADMSG;
2617
2618                         if (!streq(signature, "u"))
2619                                 return -EBADMSG;
2620
2621                         r = message_peek_field_uint32(m, &ri, &unix_fds);
2622                         if (r < 0)
2623                                 return -EBADMSG;
2624
2625                         if (unix_fds == 0)
2626                                 return -EBADMSG;
2627
2628                         break;
2629
2630                 default:
2631                         r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2632                 }
2633
2634                 if (r < 0)
2635                         return r;
2636         }
2637
2638         if (m->n_fds != unix_fds)
2639                 return -EBADMSG;
2640
2641         if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2642                 return -EBADMSG;
2643
2644         switch (m->header->type) {
2645
2646         case SD_BUS_MESSAGE_TYPE_SIGNAL:
2647                 if (!m->path || !m->interface || !m->member)
2648                         return -EBADMSG;
2649                 break;
2650
2651         case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2652
2653                 if (!m->path || !m->member)
2654                         return -EBADMSG;
2655
2656                 break;
2657
2658         case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2659
2660                 if (m->reply_serial == 0)
2661                         return -EBADMSG;
2662                 break;
2663
2664         case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2665
2666                 if (m->reply_serial == 0 || !m->error.name)
2667                         return -EBADMSG;
2668                 break;
2669         }
2670
2671         /* Try to read the error message, but if we can't it's a non-issue */
2672         if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2673                 sd_bus_message_read(m, "s", &m->error.message);
2674
2675         return 0;
2676 }
2677
2678 static void setup_iovec(sd_bus_message *m) {
2679         assert(m);
2680         assert(m->sealed);
2681
2682         m->n_iovec = 0;
2683         m->size = 0;
2684
2685         m->iovec[m->n_iovec].iov_base = m->header;
2686         m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2687         m->size += m->iovec[m->n_iovec].iov_len;
2688         m->n_iovec++;
2689
2690         if (m->fields) {
2691                 m->iovec[m->n_iovec].iov_base = m->fields;
2692                 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2693                 m->size += m->iovec[m->n_iovec].iov_len;
2694                 m->n_iovec++;
2695
2696                 if (m->header->fields_size % 8 != 0) {
2697                         static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2698
2699                         m->iovec[m->n_iovec].iov_base = (void*) padding;
2700                         m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2701                         m->size += m->iovec[m->n_iovec].iov_len;
2702                         m->n_iovec++;
2703                 }
2704         }
2705
2706         if (m->body) {
2707                 m->iovec[m->n_iovec].iov_base = m->body;
2708                 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2709                 m->size += m->iovec[m->n_iovec].iov_len;
2710                 m->n_iovec++;
2711         }
2712 }
2713
2714 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2715         int r;
2716
2717         assert(m);
2718
2719         if (m->sealed)
2720                 return -EPERM;
2721
2722         if (m->n_containers > 0)
2723                 return -EBADMSG;
2724
2725         /* If there's a non-trivial signature set, then add it in here */
2726         if (!isempty(m->root_container.signature)) {
2727                 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2728                 if (r < 0)
2729                         return r;
2730         }
2731
2732         if (m->n_fds > 0) {
2733                 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2734                 if (r < 0)
2735                         return r;
2736         }
2737
2738         m->header->serial = serial;
2739         m->sealed = true;
2740
2741         setup_iovec(m);
2742
2743         return 0;
2744 }
2745
2746 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2747         if (!m)
2748                 return -EINVAL;
2749         if (!destination)
2750                 return -EINVAL;
2751         if (m->sealed)
2752                 return -EPERM;
2753         if (m->destination)
2754                 return -EEXIST;
2755
2756         return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2757 }
2758
2759 int bus_message_dump(sd_bus_message *m) {
2760         unsigned level = 1;
2761         int r;
2762
2763         assert(m);
2764
2765         printf("Message %p\n"
2766                "\tn_ref=%u\n"
2767                "\tendian=%c\n"
2768                "\ttype=%i\n"
2769                "\tflags=%u\n"
2770                "\tversion=%u\n"
2771                "\tserial=%u\n"
2772                "\tfields_size=%u\n"
2773                "\tbody_size=%u\n"
2774                "\tpath=%s\n"
2775                "\tinterface=%s\n"
2776                "\tmember=%s\n"
2777                "\tdestination=%s\n"
2778                "\tsender=%s\n"
2779                "\tsignature=%s\n"
2780                "\treply_serial=%u\n"
2781                "\terror.name=%s\n"
2782                "\terror.message=%s\n"
2783                "\tsealed=%s\n",
2784                m,
2785                m->n_ref,
2786                m->header->endian,
2787                m->header->type,
2788                m->header->flags,
2789                m->header->version,
2790                BUS_MESSAGE_SERIAL(m),
2791                BUS_MESSAGE_FIELDS_SIZE(m),
2792                BUS_MESSAGE_BODY_SIZE(m),
2793                strna(m->path),
2794                strna(m->interface),
2795                strna(m->member),
2796                strna(m->destination),
2797                strna(m->sender),
2798                strna(m->root_container.signature),
2799                m->reply_serial,
2800                strna(m->error.name),
2801                strna(m->error.message),
2802                yes_no(m->sealed));
2803
2804         r = sd_bus_message_rewind(m, true);
2805         if (r < 0) {
2806                 log_error("Failed to rewind: %s", strerror(-r));
2807                 return r;
2808         }
2809
2810         printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2811
2812         for(;;) {
2813                 _cleanup_free_ char *prefix = NULL;
2814                 const char *contents = NULL;
2815                 char type;
2816                 union {
2817                         uint8_t u8;
2818                         uint16_t u16;
2819                         int16_t s16;
2820                         uint32_t u32;
2821                         int32_t s32;
2822                         uint64_t u64;
2823                         int64_t s64;
2824                         double d64;
2825                         const char *string;
2826                         int i;
2827                 } basic;
2828
2829                 r = sd_bus_message_peek_type(m, &type, &contents);
2830                 if (r < 0) {
2831                         log_error("Failed to peek type: %s", strerror(-r));
2832                         return r;
2833                 }
2834                 if (r == 0) {
2835                         if (level <= 1)
2836                                 break;
2837
2838                         r = sd_bus_message_exit_container(m);
2839                         if (r < 0) {
2840                                 log_error("Failed to exit container: %s", strerror(-r));
2841                                 return r;
2842                         }
2843
2844                         level--;
2845
2846                         prefix = strrep("\t", level);
2847                         if (!prefix)
2848                                 return log_oom();
2849
2850                         if (type == SD_BUS_TYPE_ARRAY)
2851                                 printf("%s} END_ARRAY \n", prefix);
2852                         else if (type == SD_BUS_TYPE_VARIANT)
2853                                 printf("%s} END_VARIANT\n", prefix);
2854                         else if (type == SD_BUS_TYPE_STRUCT)
2855                                 printf("%s} END_STRUCT\n", prefix);
2856                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2857                                 printf("%s} END_DICT_ENTRY\n", prefix);
2858
2859                         continue;
2860                 }
2861
2862                 prefix = strrep("\t", level);
2863                 if (!prefix)
2864                         return log_oom();
2865
2866                 if (bus_type_is_container(type) > 0) {
2867                         r = sd_bus_message_enter_container(m, type, contents);
2868                         if (r < 0) {
2869                                 log_error("Failed to enter container: %s", strerror(-r));
2870                                 return r;
2871                         }
2872
2873                         if (type == SD_BUS_TYPE_ARRAY)
2874                                 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2875                         else if (type == SD_BUS_TYPE_VARIANT)
2876                                 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2877                         else if (type == SD_BUS_TYPE_STRUCT)
2878                                 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2879                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2880                                 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2881
2882                         level ++;
2883
2884                         continue;
2885                 }
2886
2887                 r = sd_bus_message_read_basic(m, type, &basic);
2888                 if (r < 0) {
2889                         log_error("Failed to get basic: %s", strerror(-r));
2890                         return r;
2891                 }
2892
2893                 switch (type) {
2894
2895                 case SD_BUS_TYPE_BYTE:
2896                         printf("%sBYTE: %u\n", prefix, basic.u8);
2897                         break;
2898
2899                 case SD_BUS_TYPE_BOOLEAN:
2900                         printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2901                         break;
2902
2903                 case SD_BUS_TYPE_INT16:
2904                         printf("%sINT16: %i\n", prefix, basic.s16);
2905                         break;
2906
2907                 case SD_BUS_TYPE_UINT16:
2908                         printf("%sUINT16: %u\n", prefix, basic.u16);
2909                         break;
2910
2911                 case SD_BUS_TYPE_INT32:
2912                         printf("%sINT32: %i\n", prefix, basic.s32);
2913                         break;
2914
2915                 case SD_BUS_TYPE_UINT32:
2916                         printf("%sUINT32: %u\n", prefix, basic.u32);
2917                         break;
2918
2919                 case SD_BUS_TYPE_INT64:
2920                         printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2921                         break;
2922
2923                 case SD_BUS_TYPE_UINT64:
2924                         printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2925                         break;
2926
2927                 case SD_BUS_TYPE_DOUBLE:
2928                         printf("%sDOUBLE: %g\n", prefix, basic.d64);
2929                         break;
2930
2931                 case SD_BUS_TYPE_STRING:
2932                         printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2933                         break;
2934
2935                 case SD_BUS_TYPE_OBJECT_PATH:
2936                         printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2937                         break;
2938
2939                 case SD_BUS_TYPE_SIGNATURE:
2940                         printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2941                         break;
2942
2943                 case SD_BUS_TYPE_UNIX_FD:
2944                         printf("%sUNIX_FD: %i\n", prefix, basic.i);
2945                         break;
2946
2947                 default:
2948                         assert_not_reached("Unknown basic type.");
2949                 }
2950         }
2951
2952         printf("} END_MESSAGE\n");
2953         return 0;
2954 }
2955
2956 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2957         size_t total;
2958         unsigned i;
2959         void *p, *e;
2960
2961         assert(m);
2962         assert(buffer);
2963         assert(sz);
2964
2965         for (i = 0, total = 0; i < m->n_iovec; i++)
2966                 total += m->iovec[i].iov_len;
2967
2968         p = malloc(total);
2969         if (!p)
2970                 return -ENOMEM;
2971
2972         for (i = 0, e = p; i < m->n_iovec; i++)
2973                 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
2974
2975         *buffer = p;
2976         *sz = total;
2977
2978         return 0;
2979 }
2980
2981 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
2982         int r;
2983
2984         assert(m);
2985         assert(l);
2986
2987         r = sd_bus_message_enter_container(m, 'a', "s");
2988         if (r < 0)
2989                 return r;
2990
2991         for (;;) {
2992                 const char *s;
2993
2994                 r = sd_bus_message_read_basic(m, 's', &s);
2995                 if (r < 0)
2996                         return r;
2997                 if (r == 0)
2998                         break;
2999
3000                 r = strv_extend(l, s);
3001                 if (r < 0)
3002                         return r;
3003         }
3004
3005         r = sd_bus_message_exit_container(m);
3006         if (r < 0)
3007                 return r;
3008
3009         return 0;
3010 }
3011
3012 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3013         int r;
3014         const char *t;
3015         char type;
3016
3017         assert(m);
3018
3019         r = sd_bus_message_rewind(m, true);
3020         if (r < 0)
3021                 return NULL;
3022
3023         while (i > 0) {
3024                 r = sd_bus_message_peek_type(m, &type, NULL);
3025                 if (r < 0)
3026                         return NULL;
3027
3028                 if (type != SD_BUS_TYPE_STRING &&
3029                     type != SD_BUS_TYPE_OBJECT_PATH &&
3030                     type != SD_BUS_TYPE_SIGNATURE)
3031                         return NULL;
3032
3033                 r = sd_bus_message_read_basic(m, type, &t);
3034                 if (r < 0)
3035                         return NULL;
3036
3037                 i--;
3038         }
3039
3040         r = sd_bus_message_rewind(m, true);
3041         if (r < 0)
3042                 return NULL;
3043
3044         return t;
3045 }