chiark / gitweb /
bus: also remove recursive invocation of message_append_ap()
[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
1245 typedef struct {
1246         const char *types;
1247         unsigned n_struct;
1248         unsigned n_array;
1249 } TypeStack;
1250
1251 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1252         assert(stack);
1253         assert(max > 0);
1254
1255         if (*i >= max)
1256                 return -EINVAL;
1257
1258         stack[*i].types = types;
1259         stack[*i].n_struct = n_struct;
1260         stack[*i].n_array = n_array;
1261         (*i)++;
1262
1263         return 0;
1264 }
1265
1266 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1267         assert(stack);
1268         assert(max > 0);
1269         assert(types);
1270         assert(n_struct);
1271         assert(n_array);
1272
1273         if (*i <= 0)
1274                 return 0;
1275
1276         (*i)--;
1277         *types = stack[*i].types;
1278         *n_struct = stack[*i].n_struct;
1279         *n_array = stack[*i].n_array;
1280
1281         return 1;
1282 }
1283
1284 int bus_message_append_ap(
1285                 sd_bus_message *m,
1286                 const char *types,
1287                 va_list ap) {
1288
1289         unsigned n_array, n_struct;
1290         TypeStack stack[BUS_CONTAINER_DEPTH];
1291         unsigned stack_ptr = 0;
1292         int r;
1293
1294         assert(m);
1295
1296         if (!types)
1297                 return 0;
1298
1299         n_array = (unsigned) -1;
1300         n_struct = strlen(types);
1301
1302         for (;;) {
1303                 const char *t;
1304
1305                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1306                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1307                         if (r < 0)
1308                                 return r;
1309                         if (r == 0)
1310                                 break;
1311
1312                         r = sd_bus_message_close_container(m);
1313                         if (r < 0)
1314                                 return r;
1315
1316                         continue;
1317                 }
1318
1319                 t = types;
1320                 if (n_array != (unsigned) -1)
1321                         n_array --;
1322                 else {
1323                         types ++;
1324                         n_struct--;
1325                 }
1326
1327                 switch (*t) {
1328
1329                 case SD_BUS_TYPE_BYTE: {
1330                         uint8_t x;
1331
1332                         x = (uint8_t) va_arg(ap, int);
1333                         r = sd_bus_message_append_basic(m, *t, &x);
1334                         break;
1335                 }
1336
1337                 case SD_BUS_TYPE_BOOLEAN:
1338                 case SD_BUS_TYPE_INT32:
1339                 case SD_BUS_TYPE_UINT32:
1340                 case SD_BUS_TYPE_UNIX_FD: {
1341                         uint32_t x;
1342
1343                         /* We assume a boolean is the same as int32_t */
1344                         assert_cc(sizeof(int32_t) == sizeof(int));
1345
1346                         x = va_arg(ap, uint32_t);
1347                         r = sd_bus_message_append_basic(m, *t, &x);
1348                         break;
1349                 }
1350
1351                 case SD_BUS_TYPE_INT16:
1352                 case SD_BUS_TYPE_UINT16: {
1353                         uint16_t x;
1354
1355                         x = (uint16_t) va_arg(ap, int);
1356                         r = sd_bus_message_append_basic(m, *t, &x);
1357                         break;
1358                 }
1359
1360                 case SD_BUS_TYPE_INT64:
1361                 case SD_BUS_TYPE_UINT64:
1362                 case SD_BUS_TYPE_DOUBLE: {
1363                         uint64_t x;
1364
1365                         x = va_arg(ap, uint64_t);
1366                         r = sd_bus_message_append_basic(m, *t, &x);
1367                         break;
1368                 }
1369
1370                 case SD_BUS_TYPE_STRING:
1371                 case SD_BUS_TYPE_OBJECT_PATH:
1372                 case SD_BUS_TYPE_SIGNATURE: {
1373                         const char *x;
1374
1375                         x = va_arg(ap, const char*);
1376                         r = sd_bus_message_append_basic(m, *t, x);
1377                         break;
1378                 }
1379
1380                 case SD_BUS_TYPE_ARRAY: {
1381                         size_t k;
1382
1383                         r = signature_element_length(t + 1, &k);
1384                         if (r < 0)
1385                                 return r;
1386
1387                         {
1388                                 char s[k + 1];
1389                                 memcpy(s, t + 1, k);
1390                                 s[k] = 0;
1391
1392                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1393                                 if (r < 0)
1394                                         return r;
1395                         }
1396
1397                         if (n_array == (unsigned) -1) {
1398                                 types += k;
1399                                 n_struct -= k;
1400                         }
1401
1402                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1403                         if (r < 0)
1404                                 return r;
1405
1406                         types = t + 1;
1407                         n_struct = k;
1408                         n_array = va_arg(ap, unsigned);
1409
1410                         break;
1411                 }
1412
1413                 case SD_BUS_TYPE_VARIANT: {
1414                         const char *s;
1415
1416                         s = va_arg(ap, const char*);
1417                         if (!s)
1418                                 return -EINVAL;
1419
1420                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1421                         if (r < 0)
1422                                 return r;
1423
1424                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1425                         if (r < 0)
1426                                 return r;
1427
1428                         types = s;
1429                         n_struct = strlen(s);
1430                         n_array = (unsigned) -1;
1431
1432                         break;
1433                 }
1434
1435                 case SD_BUS_TYPE_STRUCT_BEGIN:
1436                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1437                         size_t k;
1438
1439                         r = signature_element_length(t, &k);
1440                         if (r < 0)
1441                                 return r;
1442
1443                         {
1444                                 char s[k - 1];
1445
1446                                 memcpy(s, t + 1, k - 2);
1447                                 s[k - 2] = 0;
1448
1449                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1450                                 if (r < 0)
1451                                         return r;
1452                         }
1453
1454                         if (n_array == (unsigned) -1) {
1455                                 types += k - 1;
1456                                 n_struct -= k - 1;
1457                         }
1458
1459                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1460                         if (r < 0)
1461                                 return r;
1462
1463                         types = t + 1;
1464                         n_struct = k - 2;
1465                         n_array = (unsigned) -1;
1466
1467                         break;
1468                 }
1469
1470                 default:
1471                         r = -EINVAL;
1472                 }
1473
1474                 if (r < 0)
1475                         return r;
1476         }
1477
1478         return 0;
1479 }
1480
1481 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1482         va_list ap;
1483         int r;
1484
1485         if (!m)
1486                 return -EINVAL;
1487         if (m->sealed)
1488                 return -EPERM;
1489         if (!types)
1490                 return 0;
1491
1492         va_start(ap, types);
1493         r = bus_message_append_ap(m, types, ap);
1494         va_end(ap);
1495
1496         return r;
1497 }
1498
1499 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1500         size_t k, start, n;
1501
1502         assert(rindex);
1503         assert(align > 0);
1504
1505         start = ALIGN_TO((size_t) *rindex, align);
1506         n = start + nbytes;
1507
1508         if (n > sz)
1509                 return -EBADMSG;
1510
1511         /* Verify that padding is 0 */
1512         for (k = *rindex; k < start; k++)
1513                 if (((const uint8_t*) p)[k] != 0)
1514                         return -EBADMSG;
1515
1516         if (r)
1517                 *r = (uint8_t*) p + start;
1518
1519         *rindex = n;
1520
1521         return 1;
1522 }
1523
1524 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1525         struct bus_container *c;
1526
1527         assert(m);
1528
1529         c = message_get_container(m);
1530         if (!c->array_size)
1531                 return false;
1532
1533         return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1534 }
1535
1536 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1537         assert(m);
1538         assert(rindex);
1539         assert(align > 0);
1540
1541         if (message_end_of_array(m, *rindex))
1542                 return 0;
1543
1544         return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1545 }
1546
1547 static bool validate_nul(const char *s, size_t l) {
1548
1549         /* Check for NUL chars in the string */
1550         if (memchr(s, 0, l))
1551                 return false;
1552
1553         /* Check for NUL termination */
1554         if (s[l] != 0)
1555                 return false;
1556
1557         return true;
1558 }
1559
1560 static bool validate_string(const char *s, size_t l) {
1561
1562         if (!validate_nul(s, l))
1563                 return false;
1564
1565         /* Check if valid UTF8 */
1566         if (!utf8_is_valid(s))
1567                 return false;
1568
1569         return true;
1570 }
1571
1572 static bool validate_signature(const char *s, size_t l) {
1573
1574         if (!validate_nul(s, l))
1575                 return false;
1576
1577         /* Check if valid signature */
1578         if (!signature_is_valid(s, true))
1579                 return false;
1580
1581         return true;
1582 }
1583
1584 static bool validate_object_path(const char *s, size_t l) {
1585
1586         if (!validate_nul(s, l))
1587                 return false;
1588
1589         if (!object_path_is_valid(s))
1590                 return false;
1591
1592         return true;
1593 }
1594
1595 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1596         struct bus_container *c;
1597         int r;
1598         void *q;
1599
1600         if (!m)
1601                 return -EINVAL;
1602         if (!m->sealed)
1603                 return -EPERM;
1604         if (!bus_type_is_basic(type))
1605                 return -EINVAL;
1606         if (!p)
1607                 return -EINVAL;
1608
1609         c = message_get_container(m);
1610
1611         if (!c->signature || c->signature[c->index] == 0)
1612                 return 0;
1613
1614         if (c->signature[c->index] != type)
1615                 return -ENXIO;
1616
1617         switch (type) {
1618
1619         case SD_BUS_TYPE_STRING:
1620         case SD_BUS_TYPE_OBJECT_PATH: {
1621                 uint32_t l;
1622                 size_t rindex;
1623
1624                 rindex = m->rindex;
1625                 r = message_peek_body(m, &rindex, 4, 4, &q);
1626                 if (r <= 0)
1627                         return r;
1628
1629                 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1630                 r = message_peek_body(m, &rindex, 1, l+1, &q);
1631                 if (r < 0)
1632                         return r;
1633                 if (r == 0)
1634                         return -EBADMSG;
1635
1636                 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1637                         if (!validate_object_path(q, l))
1638                                 return -EBADMSG;
1639                 } else {
1640                         if (!validate_string(q, l))
1641                                 return -EBADMSG;
1642                 }
1643
1644                 m->rindex = rindex;
1645                 *(const char**) p = q;
1646                 break;
1647         }
1648
1649         case SD_BUS_TYPE_SIGNATURE: {
1650                 uint8_t l;
1651                 size_t rindex;
1652
1653                 rindex = m->rindex;
1654                 r = message_peek_body(m, &rindex, 1, 1, &q);
1655                 if (r <= 0)
1656                         return r;
1657
1658                 l = *(uint8_t*) q;
1659                 r = message_peek_body(m, &rindex, 1, l+1, &q);
1660                 if (r < 0)
1661                         return r;
1662                 if (r == 0)
1663                         return -EBADMSG;
1664
1665                 if (!validate_signature(q, l))
1666                         return -EBADMSG;
1667
1668                 m->rindex = rindex;
1669                 *(const char**) p = q;
1670                 break;
1671         }
1672
1673         default: {
1674                 ssize_t sz, align;
1675                 size_t rindex;
1676
1677                 align = bus_type_get_alignment(type);
1678                 sz = bus_type_get_size(type);
1679                 assert(align > 0 && sz > 0);
1680
1681                 rindex = m->rindex;
1682                 r = message_peek_body(m, &rindex, align, sz, &q);
1683                 if (r <= 0)
1684                         return r;
1685
1686                 switch (type) {
1687
1688                 case SD_BUS_TYPE_BYTE:
1689                         *(uint8_t*) p = *(uint8_t*) q;
1690                         break;
1691
1692                 case SD_BUS_TYPE_BOOLEAN:
1693                         *(int*) p = !!*(uint32_t*) q;
1694                         break;
1695
1696                 case SD_BUS_TYPE_INT16:
1697                 case SD_BUS_TYPE_UINT16:
1698                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1699                         break;
1700
1701                 case SD_BUS_TYPE_INT32:
1702                 case SD_BUS_TYPE_UINT32:
1703                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1704                         break;
1705
1706                 case SD_BUS_TYPE_INT64:
1707                 case SD_BUS_TYPE_UINT64:
1708                 case SD_BUS_TYPE_DOUBLE:
1709                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1710                         break;
1711
1712                 case SD_BUS_TYPE_UNIX_FD: {
1713                         int copy;
1714                         uint32_t j;
1715
1716                         j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1717                         if (j >= m->n_fds)
1718                                 return -EBADMSG;
1719
1720                         copy = fcntl(m->fds[j], F_DUPFD_CLOEXEC, 3);
1721                         if (copy < 0)
1722                                 return -errno;
1723
1724                         *(int*) p = copy;
1725                         break;
1726                 }
1727
1728                 default:
1729                         assert_not_reached("Unknown basic type...");
1730                 }
1731
1732                         m->rindex = rindex;
1733
1734                 break;
1735         }
1736         }
1737
1738         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1739                 c->index++;
1740
1741         return 1;
1742 }
1743
1744 static int bus_message_enter_array(
1745                 sd_bus_message *m,
1746                 struct bus_container *c,
1747                 const char *contents,
1748                 uint32_t **array_size) {
1749
1750         size_t rindex;
1751         void *q;
1752         int r, alignment;
1753
1754         assert(m);
1755         assert(c);
1756         assert(contents);
1757         assert(array_size);
1758
1759         if (!signature_is_single(contents))
1760                 return -EINVAL;
1761
1762         alignment = bus_type_get_alignment(contents[0]);
1763         if (alignment < 0)
1764                 return alignment;
1765
1766         if (!c->signature || c->signature[c->index] == 0)
1767                 return 0;
1768
1769         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1770                 return -ENXIO;
1771
1772         if (!startswith(c->signature + c->index + 1, contents))
1773                 return -ENXIO;
1774
1775         rindex = m->rindex;
1776         r = message_peek_body(m, &rindex, 4, 4, &q);
1777         if (r <= 0)
1778                 return r;
1779
1780         if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1781                 return -EBADMSG;
1782
1783         r = message_peek_body(m, &rindex, alignment, 0, NULL);
1784         if (r < 0)
1785                 return r;
1786         if (r == 0)
1787                 return -EBADMSG;
1788
1789         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1790                 c->index += 1 + strlen(contents);
1791
1792         m->rindex = rindex;
1793
1794         *array_size = (uint32_t*) q;
1795
1796         return 1;
1797 }
1798
1799 static int bus_message_enter_variant(
1800                 sd_bus_message *m,
1801                 struct bus_container *c,
1802                 const char *contents) {
1803
1804         size_t rindex;
1805         uint8_t l;
1806         void *q;
1807         int r;
1808
1809         assert(m);
1810         assert(c);
1811         assert(contents);
1812
1813         if (!signature_is_single(contents))
1814                 return -EINVAL;
1815
1816         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1817                 return -EINVAL;
1818
1819         if (!c->signature || c->signature[c->index] == 0)
1820                 return 0;
1821
1822         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1823                 return -ENXIO;
1824
1825         rindex = m->rindex;
1826         r = message_peek_body(m, &rindex, 1, 1, &q);
1827         if (r <= 0)
1828                 return r;
1829
1830         l = *(uint8_t*) q;
1831         r = message_peek_body(m, &rindex, 1, l+1, &q);
1832         if (r < 0)
1833                 return r;
1834         if (r == 0)
1835                 return -EBADMSG;
1836
1837         if (!validate_signature(q, l))
1838                 return -EBADMSG;
1839
1840         if (!streq(q, contents))
1841                 return -ENXIO;
1842
1843         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1844                 c->index++;
1845
1846         m->rindex = rindex;
1847
1848         return 1;
1849 }
1850
1851 static int bus_message_enter_struct(
1852                 sd_bus_message *m,
1853                 struct bus_container *c,
1854                 const char *contents) {
1855
1856         size_t l;
1857         int r;
1858
1859         assert(m);
1860         assert(c);
1861         assert(contents);
1862
1863         if (!signature_is_valid(contents, false))
1864                 return -EINVAL;
1865
1866         if (!c->signature || c->signature[c->index] == 0)
1867                 return 0;
1868
1869         l = strlen(contents);
1870
1871         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1872             !startswith(c->signature + c->index + 1, contents) ||
1873             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1874                 return -ENXIO;
1875
1876         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1877         if (r <= 0)
1878                 return r;
1879
1880         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1881                 c->index += 1 + l + 1;
1882
1883         return 1;
1884 }
1885
1886 static int bus_message_enter_dict_entry(
1887                 sd_bus_message *m,
1888                 struct bus_container *c,
1889                 const char *contents) {
1890
1891         size_t l;
1892         int r;
1893
1894         assert(m);
1895         assert(c);
1896         assert(contents);
1897
1898         if (!signature_is_pair(contents))
1899                 return -EINVAL;
1900
1901         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1902                 return -ENXIO;
1903
1904         if (!c->signature || c->signature[c->index] == 0)
1905                 return 0;
1906
1907         l = strlen(contents);
1908
1909         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1910             !startswith(c->signature + c->index + 1, contents) ||
1911             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1912                 return -ENXIO;
1913
1914         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1915         if (r <= 0)
1916                 return r;
1917
1918         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1919                 c->index += 1 + l + 1;
1920
1921         return 1;
1922 }
1923
1924 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1925         struct bus_container *c, *w;
1926         uint32_t *array_size = NULL;
1927         char *signature;
1928         int r;
1929
1930         if (!m)
1931                 return -EINVAL;
1932         if (!m->sealed)
1933                 return -EPERM;
1934         if (!contents)
1935                 return -EINVAL;
1936
1937         /*
1938          * We enforce a global limit on container depth, that is much
1939          * higher than the 32 structs and 32 arrays the specification
1940          * mandates. This is simpler to implement for us, and we need
1941          * this only to ensure our container array doesn't grow
1942          * without bounds. We are happy to return any data from a
1943          * message as long as the data itself is valid, even if the
1944          * overall message might be not.
1945          *
1946          * Note that the message signature is validated when
1947          * parsing the headers, and that validation does check the
1948          * 32/32 limit.
1949          *
1950          * Note that the specification defines no limits on the depth
1951          * of stacked variants, but we do.
1952          */
1953         if (m->n_containers >= BUS_CONTAINER_DEPTH)
1954                 return -EBADMSG;
1955
1956         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1957         if (!w)
1958                 return -ENOMEM;
1959         m->containers = w;
1960
1961         c = message_get_container(m);
1962
1963         if (!c->signature || c->signature[c->index] == 0)
1964                 return 0;
1965
1966         signature = strdup(contents);
1967         if (!signature)
1968                 return -ENOMEM;
1969
1970         if (type == SD_BUS_TYPE_ARRAY)
1971                 r = bus_message_enter_array(m, c, contents, &array_size);
1972         else if (type == SD_BUS_TYPE_VARIANT)
1973                 r = bus_message_enter_variant(m, c, contents);
1974         else if (type == SD_BUS_TYPE_STRUCT)
1975                 r = bus_message_enter_struct(m, c, contents);
1976         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1977                 r = bus_message_enter_dict_entry(m, c, contents);
1978         else
1979                 r = -EINVAL;
1980
1981         if (r <= 0) {
1982                 free(signature);
1983                 return r;
1984         }
1985
1986         /* OK, let's fill it in */
1987         w += m->n_containers++;
1988         w->enclosing = type;
1989         w->signature = signature;
1990         w->index = 0;
1991         w->array_size = array_size;
1992         w->begin = m->rindex;
1993
1994         return 1;
1995 }
1996
1997 int sd_bus_message_exit_container(sd_bus_message *m) {
1998         struct bus_container *c;
1999
2000         if (!m)
2001                 return -EINVAL;
2002         if (!m->sealed)
2003                 return -EPERM;
2004         if (m->n_containers <= 0)
2005                 return -EINVAL;
2006
2007         c = message_get_container(m);
2008         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2009                 uint32_t l;
2010
2011                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2012                 if (c->begin + l != m->rindex)
2013                         return -EBUSY;
2014
2015         } else {
2016                 if (c->signature && c->signature[c->index] != 0)
2017                         return -EINVAL;
2018         }
2019
2020         free(c->signature);
2021         m->n_containers--;
2022
2023         return 1;
2024 }
2025
2026 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2027         struct bus_container *c;
2028         int r;
2029
2030         if (!m)
2031                 return -EINVAL;
2032         if (!m->sealed)
2033                 return -EPERM;
2034
2035         c = message_get_container(m);
2036
2037         if (!c->signature || c->signature[c->index] == 0)
2038                 goto eof;
2039
2040         if (message_end_of_array(m, m->rindex))
2041                 goto eof;
2042
2043         if (bus_type_is_basic(c->signature[c->index])) {
2044                 if (contents)
2045                         *contents = NULL;
2046                 if (type)
2047                         *type = c->signature[c->index];
2048                 return 1;
2049         }
2050
2051         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2052
2053                 if (contents) {
2054                         size_t l;
2055                         char *sig;
2056
2057                         r = signature_element_length(c->signature+c->index+1, &l);
2058                         if (r < 0)
2059                                 return r;
2060
2061                         assert(l >= 1);
2062
2063                         sig = strndup(c->signature + c->index + 1, l);
2064                         if (!sig)
2065                                 return -ENOMEM;
2066
2067                         free(m->peeked_signature);
2068                         m->peeked_signature = sig;
2069
2070                         *contents = sig;
2071                 }
2072
2073                 if (type)
2074                         *type = SD_BUS_TYPE_ARRAY;
2075
2076                 return 1;
2077         }
2078
2079         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2080             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2081
2082                 if (contents) {
2083                         size_t l;
2084                         char *sig;
2085
2086                         r = signature_element_length(c->signature+c->index, &l);
2087                         if (r < 0)
2088                                 return r;
2089
2090                         assert(l >= 2);
2091                         sig = strndup(c->signature + c->index + 1, l - 2);
2092                         if (!sig)
2093                                 return -ENOMEM;
2094
2095                         free(m->peeked_signature);
2096                         m->peeked_signature = sig;
2097
2098                         *contents = sig;
2099                 }
2100
2101                 if (type)
2102                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2103
2104                 return 1;
2105         }
2106
2107         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2108                 if (contents) {
2109                         size_t rindex, l;
2110                         void *q;
2111
2112                         rindex = m->rindex;
2113                         r = message_peek_body(m, &rindex, 1, 1, &q);
2114                         if (r < 0)
2115                                 return r;
2116                         if (r == 0)
2117                                 goto eof;
2118
2119                         l = *(uint8_t*) q;
2120                         r = message_peek_body(m, &rindex, 1, l+1, &q);
2121                         if (r < 0)
2122                                 return r;
2123                         if (r == 0)
2124                                 return -EBADMSG;
2125
2126                         if (!validate_signature(q, l))
2127                                 return -EBADMSG;
2128
2129                         *contents = q;
2130                 }
2131
2132                 if (type)
2133                         *type = SD_BUS_TYPE_VARIANT;
2134
2135                 return 1;
2136         }
2137
2138         return -EINVAL;
2139
2140 eof:
2141         if (type)
2142                 *type = c->enclosing;
2143         if (contents)
2144                 *contents = NULL;
2145         return 0;
2146 }
2147
2148 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2149         struct bus_container *c;
2150
2151         if (!m)
2152                 return -EINVAL;
2153         if (!m->sealed)
2154                 return -EPERM;
2155
2156         if (complete) {
2157                 reset_containers(m);
2158                 m->rindex = 0;
2159                 m->root_container.index = 0;
2160
2161                 c = message_get_container(m);
2162         } else {
2163                 c = message_get_container(m);
2164
2165                 c->index = 0;
2166                 m->rindex = c->begin;
2167         }
2168
2169         return !isempty(c->signature);
2170 }
2171 static int message_read_ap(
2172                 sd_bus_message *m,
2173                 const char *types,
2174                 va_list ap) {
2175
2176         unsigned n_array, n_struct;
2177         TypeStack stack[BUS_CONTAINER_DEPTH];
2178         unsigned stack_ptr = 0;
2179         int r;
2180
2181         assert(m);
2182
2183         if (!types)
2184                 return 0;
2185
2186         /* Ideally, we'd just call ourselves recursively on every
2187          * complex type. However, the state of a va_list that is
2188          * passed to a function is undefined after that function
2189          * returns. This means we need to docode the va_list linearly
2190          * in a single stackframe. We hence implement our own
2191          * home-grown stack in an array. */
2192
2193         n_array = (unsigned) -1;
2194         n_struct = strlen(types);
2195
2196         for (;;) {
2197                 const char *t;
2198
2199                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2200                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2201                         if (r < 0)
2202                                 return r;
2203                         if (r == 0)
2204                                 break;
2205
2206                         r = sd_bus_message_exit_container(m);
2207                         if (r < 0)
2208                                 return r;
2209
2210                         continue;
2211                 }
2212
2213                 t = types;
2214                 if (n_array != (unsigned) -1)
2215                         n_array --;
2216                 else {
2217                         types ++;
2218                         n_struct--;
2219                 }
2220
2221                 switch (*t) {
2222
2223                 case SD_BUS_TYPE_BYTE:
2224                 case SD_BUS_TYPE_BOOLEAN:
2225                 case SD_BUS_TYPE_INT16:
2226                 case SD_BUS_TYPE_UINT16:
2227                 case SD_BUS_TYPE_INT32:
2228                 case SD_BUS_TYPE_UINT32:
2229                 case SD_BUS_TYPE_INT64:
2230                 case SD_BUS_TYPE_UINT64:
2231                 case SD_BUS_TYPE_DOUBLE:
2232                 case SD_BUS_TYPE_STRING:
2233                 case SD_BUS_TYPE_OBJECT_PATH:
2234                 case SD_BUS_TYPE_SIGNATURE:
2235                 case SD_BUS_TYPE_UNIX_FD: {
2236                         void *p;
2237
2238                         p = va_arg(ap, void*);
2239                         r = sd_bus_message_read_basic(m, *t, p);
2240                         if (r < 0)
2241                                 return r;
2242                         if (r == 0)
2243                                 return -ENXIO;
2244
2245                         break;
2246                 }
2247
2248                 case SD_BUS_TYPE_ARRAY: {
2249                         size_t k;
2250
2251                         r = signature_element_length(t + 1, &k);
2252                         if (r < 0)
2253                                 return r;
2254
2255                         {
2256                                 char s[k + 1];
2257                                 memcpy(s, t + 1, k);
2258                                 s[k] = 0;
2259
2260                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2261                                 if (r < 0)
2262                                         return r;
2263                                 if (r == 0)
2264                                         return -ENXIO;
2265                         }
2266
2267                         if (n_array == (unsigned) -1) {
2268                                 types += k;
2269                                 n_struct -= k;
2270                         }
2271
2272                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2273                         if (r < 0)
2274                                 return r;
2275
2276                         types = t + 1;
2277                         n_struct = k;
2278                         n_array = va_arg(ap, unsigned);
2279
2280                         break;
2281                 }
2282
2283                 case SD_BUS_TYPE_VARIANT: {
2284                         const char *s;
2285
2286                         s = va_arg(ap, const char *);
2287                         if (!s)
2288                                 return -EINVAL;
2289
2290                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2291                         if (r < 0)
2292                                 return r;
2293                         if (r == 0)
2294                                 return -ENXIO;
2295
2296                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2297                         if (r < 0)
2298                                 return r;
2299
2300                         types = s;
2301                         n_struct = strlen(s);
2302                         n_array = (unsigned) -1;
2303
2304                         break;
2305                 }
2306
2307                 case SD_BUS_TYPE_STRUCT_BEGIN:
2308                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2309                         size_t k;
2310
2311                         r = signature_element_length(t, &k);
2312                         if (r < 0)
2313                                 return r;
2314
2315                         {
2316                                 char s[k - 1];
2317                                 memcpy(s, t + 1, k - 2);
2318                                 s[k - 2] = 0;
2319
2320                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2321                                 if (r < 0)
2322                                         return r;
2323                                 if (r == 0)
2324                                         return -ENXIO;
2325                         }
2326
2327                         if (n_array == (unsigned) -1) {
2328                                 types += k - 1;
2329                                 n_struct -= k - 1;
2330                         }
2331
2332                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2333                         if (r < 0)
2334                                 return r;
2335
2336                         types = t + 1;
2337                         n_struct = k - 2;
2338                         n_array = (unsigned) -1;
2339
2340                         break;
2341                 }
2342
2343                 default:
2344                         return -EINVAL;
2345                 }
2346         }
2347
2348         return 1;
2349 }
2350
2351 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2352         va_list ap;
2353         int r;
2354
2355         if (!m)
2356                 return -EINVAL;
2357         if (!m->sealed)
2358                 return -EPERM;
2359         if (!types)
2360                 return -EINVAL;
2361
2362         va_start(ap, types);
2363         r = message_read_ap(m, types, ap);
2364         va_end(ap);
2365
2366         return r;
2367 }
2368
2369 static int message_peek_fields(
2370                 sd_bus_message *m,
2371                 size_t *rindex,
2372                 size_t align,
2373                 size_t nbytes,
2374                 void **ret) {
2375
2376         assert(m);
2377         assert(rindex);
2378         assert(align > 0);
2379
2380         return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2381 }
2382
2383 static int message_peek_field_uint32(
2384                 sd_bus_message *m,
2385                 size_t *ri,
2386                 uint32_t *ret) {
2387
2388         int r;
2389         void *q;
2390
2391         assert(m);
2392         assert(ri);
2393
2394         r = message_peek_fields(m, ri, 4, 4, &q);
2395         if (r < 0)
2396                 return r;
2397
2398         if (ret)
2399                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2400
2401         return 0;
2402 }
2403
2404 static int message_peek_field_string(
2405                 sd_bus_message *m,
2406                 bool (*validate)(const char *p),
2407                 size_t *ri,
2408                 const char **ret) {
2409
2410         uint32_t l;
2411         int r;
2412         void *q;
2413
2414         assert(m);
2415         assert(ri);
2416
2417         r = message_peek_field_uint32(m, ri, &l);
2418         if (r < 0)
2419                 return r;
2420
2421         r = message_peek_fields(m, ri, 1, l+1, &q);
2422         if (r < 0)
2423                 return r;
2424
2425         if (validate) {
2426                 if (!validate_nul(q, l))
2427                         return -EBADMSG;
2428
2429                 if (!validate(q))
2430                         return -EBADMSG;
2431         } else {
2432                 if (!validate_string(q, l))
2433                         return -EBADMSG;
2434         }
2435
2436         if (ret)
2437                 *ret = q;
2438
2439         return 0;
2440 }
2441
2442 static int message_peek_field_signature(
2443                 sd_bus_message *m,
2444                 size_t *ri,
2445                 const char **ret) {
2446
2447         size_t l;
2448         int r;
2449         void *q;
2450
2451         assert(m);
2452         assert(ri);
2453
2454         r = message_peek_fields(m, ri, 1, 1, &q);
2455         if (r < 0)
2456                 return r;
2457
2458         l = *(uint8_t*) q;
2459         r = message_peek_fields(m, ri, 1, l+1, &q);
2460         if (r < 0)
2461                 return r;
2462
2463         if (!validate_signature(q, l))
2464                 return -EBADMSG;
2465
2466         if (ret)
2467                 *ret = q;
2468
2469         return 0;
2470 }
2471
2472 static int message_skip_fields(
2473                 sd_bus_message *m,
2474                 size_t *ri,
2475                 uint32_t array_size,
2476                 const char **signature) {
2477
2478         size_t original_index;
2479         int r;
2480
2481         assert(m);
2482         assert(ri);
2483         assert(signature);
2484
2485         original_index = *ri;
2486
2487         for (;;) {
2488                 char t;
2489                 size_t l;
2490
2491                 if (array_size != (uint32_t) -1 &&
2492                     array_size <= *ri - original_index)
2493                         return 0;
2494
2495                 t = **signature;
2496                 if (!t)
2497                         return 0;
2498
2499                 if (t == SD_BUS_TYPE_STRING) {
2500
2501                         r = message_peek_field_string(m, NULL, ri, NULL);
2502                         if (r < 0)
2503                                 return r;
2504
2505                         (*signature)++;
2506
2507                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2508
2509                         r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2510                         if (r < 0)
2511                                 return r;
2512
2513                         (*signature)++;
2514
2515                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2516
2517                         r = message_peek_field_signature(m, ri, NULL);
2518                         if (r < 0)
2519                                 return r;
2520
2521                         (*signature)++;
2522
2523                 } else if (bus_type_is_basic(t)) {
2524                         ssize_t align, k;
2525
2526                         align = bus_type_get_alignment(t);
2527                         k = bus_type_get_size(t);
2528                         assert(align > 0 && k > 0);
2529
2530                         r = message_peek_fields(m, ri, align, k, NULL);
2531                         if (r < 0)
2532                                 return r;
2533
2534                         (*signature)++;
2535
2536                 } else if (t == SD_BUS_TYPE_ARRAY) {
2537
2538                         r = signature_element_length(*signature+1, &l);
2539                         if (r < 0)
2540                                 return r;
2541
2542                         assert(l >= 1);
2543                         {
2544                                 char sig[l-1], *s;
2545                                 uint32_t nas;
2546                                 int alignment;
2547
2548                                 strncpy(sig, *signature + 1, l-1);
2549                                 s = sig;
2550
2551                                 alignment = bus_type_get_alignment(sig[0]);
2552                                 if (alignment < 0)
2553                                         return alignment;
2554
2555                                 r = message_peek_field_uint32(m, ri, &nas);
2556                                 if (r < 0)
2557                                         return r;
2558                                 if (nas > BUS_ARRAY_MAX_SIZE)
2559                                         return -EBADMSG;
2560
2561                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
2562                                 if (r < 0)
2563                                         return r;
2564
2565                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
2566                                 if (r < 0)
2567                                         return r;
2568                         }
2569
2570                         (*signature) += 1 + l;
2571
2572                 } else if (t == SD_BUS_TYPE_VARIANT) {
2573                         const char *s;
2574
2575                         r = message_peek_field_signature(m, ri, &s);
2576                         if (r < 0)
2577                                 return r;
2578
2579                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2580                         if (r < 0)
2581                                 return r;
2582
2583                         (*signature)++;
2584
2585                 } else if (t == SD_BUS_TYPE_STRUCT ||
2586                            t == SD_BUS_TYPE_DICT_ENTRY) {
2587
2588                         r = signature_element_length(*signature, &l);
2589                         if (r < 0)
2590                                 return r;
2591
2592                         assert(l >= 2);
2593                         {
2594                                 char sig[l-1], *s;
2595                                 strncpy(sig, *signature + 1, l-1);
2596                                 s = sig;
2597
2598                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2599                                 if (r < 0)
2600                                         return r;
2601                         }
2602
2603                         *signature += l;
2604                 } else
2605                         return -EINVAL;
2606         }
2607 }
2608
2609 static int message_parse_fields(sd_bus_message *m) {
2610         size_t ri;
2611         int r;
2612         uint32_t unix_fds = 0;
2613
2614         assert(m);
2615
2616         for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2617                 const char *signature;
2618                 uint8_t *header;
2619
2620                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2621                 if (r < 0)
2622                         return r;
2623
2624                 r = message_peek_field_signature(m, &ri, &signature);
2625                 if (r < 0)
2626                         return r;
2627
2628                 switch (*header) {
2629                 case _SD_BUS_MESSAGE_HEADER_INVALID:
2630                         return -EBADMSG;
2631
2632                 case SD_BUS_MESSAGE_HEADER_PATH:
2633
2634                         if (m->path)
2635                                 return -EBADMSG;
2636
2637                         if (!streq(signature, "o"))
2638                                 return -EBADMSG;
2639
2640                         r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2641                         break;
2642
2643                 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2644
2645                         if (m->interface)
2646                                 return -EBADMSG;
2647
2648                         if (!streq(signature, "s"))
2649                                 return -EBADMSG;
2650
2651                         r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2652                         break;
2653
2654                 case SD_BUS_MESSAGE_HEADER_MEMBER:
2655
2656                         if (m->member)
2657                                 return -EBADMSG;
2658
2659                         if (!streq(signature, "s"))
2660                                 return -EBADMSG;
2661
2662                         r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2663                         break;
2664
2665                 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2666
2667                         if (m->error.name)
2668                                 return -EBADMSG;
2669
2670                         if (!streq(signature, "s"))
2671                                 return -EBADMSG;
2672
2673                         r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2674                         break;
2675
2676                 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2677
2678                         if (m->destination)
2679                                 return -EBADMSG;
2680
2681                         if (!streq(signature, "s"))
2682                                 return -EBADMSG;
2683
2684                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2685                         break;
2686
2687                 case SD_BUS_MESSAGE_HEADER_SENDER:
2688
2689                         if (m->sender)
2690                                 return -EBADMSG;
2691
2692                         if (!streq(signature, "s"))
2693                                 return -EBADMSG;
2694
2695                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2696                         break;
2697
2698
2699                 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2700                         const char *s;
2701                         char *c;
2702
2703                         if (m->root_container.signature)
2704                                 return -EBADMSG;
2705
2706                         if (!streq(signature, "g"))
2707                                 return -EBADMSG;
2708
2709                         r = message_peek_field_signature(m, &ri, &s);
2710                         if (r < 0)
2711                                 return r;
2712
2713                         c = strdup(s);
2714                         if (!c)
2715                                 return -ENOMEM;
2716
2717                         free(m->root_container.signature);
2718                         m->root_container.signature = c;
2719                         break;
2720                 }
2721
2722                 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2723                         if (m->reply_serial != 0)
2724                                 return -EBADMSG;
2725
2726                         if (!streq(signature, "u"))
2727                                 return -EBADMSG;
2728
2729                         r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2730                         if (r < 0)
2731                                 return r;
2732
2733                         if (m->reply_serial == 0)
2734                                 return -EBADMSG;
2735
2736                         break;
2737
2738                 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2739                         if (unix_fds != 0)
2740                                 return -EBADMSG;
2741
2742                         if (!streq(signature, "u"))
2743                                 return -EBADMSG;
2744
2745                         r = message_peek_field_uint32(m, &ri, &unix_fds);
2746                         if (r < 0)
2747                                 return -EBADMSG;
2748
2749                         if (unix_fds == 0)
2750                                 return -EBADMSG;
2751
2752                         break;
2753
2754                 default:
2755                         r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2756                 }
2757
2758                 if (r < 0)
2759                         return r;
2760         }
2761
2762         if (m->n_fds != unix_fds)
2763                 return -EBADMSG;
2764
2765         if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2766                 return -EBADMSG;
2767
2768         switch (m->header->type) {
2769
2770         case SD_BUS_MESSAGE_TYPE_SIGNAL:
2771                 if (!m->path || !m->interface || !m->member)
2772                         return -EBADMSG;
2773                 break;
2774
2775         case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2776
2777                 if (!m->path || !m->member)
2778                         return -EBADMSG;
2779
2780                 break;
2781
2782         case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2783
2784                 if (m->reply_serial == 0)
2785                         return -EBADMSG;
2786                 break;
2787
2788         case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2789
2790                 if (m->reply_serial == 0 || !m->error.name)
2791                         return -EBADMSG;
2792                 break;
2793         }
2794
2795         /* Try to read the error message, but if we can't it's a non-issue */
2796         if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2797                 sd_bus_message_read(m, "s", &m->error.message);
2798
2799         return 0;
2800 }
2801
2802 static void setup_iovec(sd_bus_message *m) {
2803         assert(m);
2804         assert(m->sealed);
2805
2806         m->n_iovec = 0;
2807         m->size = 0;
2808
2809         m->iovec[m->n_iovec].iov_base = m->header;
2810         m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2811         m->size += m->iovec[m->n_iovec].iov_len;
2812         m->n_iovec++;
2813
2814         if (m->fields) {
2815                 m->iovec[m->n_iovec].iov_base = m->fields;
2816                 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2817                 m->size += m->iovec[m->n_iovec].iov_len;
2818                 m->n_iovec++;
2819
2820                 if (m->header->fields_size % 8 != 0) {
2821                         static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2822
2823                         m->iovec[m->n_iovec].iov_base = (void*) padding;
2824                         m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2825                         m->size += m->iovec[m->n_iovec].iov_len;
2826                         m->n_iovec++;
2827                 }
2828         }
2829
2830         if (m->body) {
2831                 m->iovec[m->n_iovec].iov_base = m->body;
2832                 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2833                 m->size += m->iovec[m->n_iovec].iov_len;
2834                 m->n_iovec++;
2835         }
2836 }
2837
2838 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2839         int r;
2840
2841         assert(m);
2842
2843         if (m->sealed)
2844                 return -EPERM;
2845
2846         if (m->n_containers > 0)
2847                 return -EBADMSG;
2848
2849         /* If there's a non-trivial signature set, then add it in here */
2850         if (!isempty(m->root_container.signature)) {
2851                 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2852                 if (r < 0)
2853                         return r;
2854         }
2855
2856         if (m->n_fds > 0) {
2857                 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2858                 if (r < 0)
2859                         return r;
2860         }
2861
2862         m->header->serial = serial;
2863         m->sealed = true;
2864
2865         setup_iovec(m);
2866
2867         return 0;
2868 }
2869
2870 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2871         if (!m)
2872                 return -EINVAL;
2873         if (!destination)
2874                 return -EINVAL;
2875         if (m->sealed)
2876                 return -EPERM;
2877         if (m->destination)
2878                 return -EEXIST;
2879
2880         return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2881 }
2882
2883 int bus_message_dump(sd_bus_message *m) {
2884         unsigned level = 1;
2885         int r;
2886
2887         assert(m);
2888
2889         printf("Message %p\n"
2890                "\tn_ref=%u\n"
2891                "\tendian=%c\n"
2892                "\ttype=%i\n"
2893                "\tflags=%u\n"
2894                "\tversion=%u\n"
2895                "\tserial=%u\n"
2896                "\tfields_size=%u\n"
2897                "\tbody_size=%u\n"
2898                "\tpath=%s\n"
2899                "\tinterface=%s\n"
2900                "\tmember=%s\n"
2901                "\tdestination=%s\n"
2902                "\tsender=%s\n"
2903                "\tsignature=%s\n"
2904                "\treply_serial=%u\n"
2905                "\terror.name=%s\n"
2906                "\terror.message=%s\n"
2907                "\tsealed=%s\n",
2908                m,
2909                m->n_ref,
2910                m->header->endian,
2911                m->header->type,
2912                m->header->flags,
2913                m->header->version,
2914                BUS_MESSAGE_SERIAL(m),
2915                BUS_MESSAGE_FIELDS_SIZE(m),
2916                BUS_MESSAGE_BODY_SIZE(m),
2917                strna(m->path),
2918                strna(m->interface),
2919                strna(m->member),
2920                strna(m->destination),
2921                strna(m->sender),
2922                strna(m->root_container.signature),
2923                m->reply_serial,
2924                strna(m->error.name),
2925                strna(m->error.message),
2926                yes_no(m->sealed));
2927
2928         r = sd_bus_message_rewind(m, true);
2929         if (r < 0) {
2930                 log_error("Failed to rewind: %s", strerror(-r));
2931                 return r;
2932         }
2933
2934         printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2935
2936         for(;;) {
2937                 _cleanup_free_ char *prefix = NULL;
2938                 const char *contents = NULL;
2939                 char type;
2940                 union {
2941                         uint8_t u8;
2942                         uint16_t u16;
2943                         int16_t s16;
2944                         uint32_t u32;
2945                         int32_t s32;
2946                         uint64_t u64;
2947                         int64_t s64;
2948                         double d64;
2949                         const char *string;
2950                         int i;
2951                 } basic;
2952
2953                 r = sd_bus_message_peek_type(m, &type, &contents);
2954                 if (r < 0) {
2955                         log_error("Failed to peek type: %s", strerror(-r));
2956                         return r;
2957                 }
2958                 if (r == 0) {
2959                         if (level <= 1)
2960                                 break;
2961
2962                         r = sd_bus_message_exit_container(m);
2963                         if (r < 0) {
2964                                 log_error("Failed to exit container: %s", strerror(-r));
2965                                 return r;
2966                         }
2967
2968                         level--;
2969
2970                         prefix = strrep("\t", level);
2971                         if (!prefix)
2972                                 return log_oom();
2973
2974                         if (type == SD_BUS_TYPE_ARRAY)
2975                                 printf("%s} END_ARRAY \n", prefix);
2976                         else if (type == SD_BUS_TYPE_VARIANT)
2977                                 printf("%s} END_VARIANT\n", prefix);
2978                         else if (type == SD_BUS_TYPE_STRUCT)
2979                                 printf("%s} END_STRUCT\n", prefix);
2980                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2981                                 printf("%s} END_DICT_ENTRY\n", prefix);
2982
2983                         continue;
2984                 }
2985
2986                 prefix = strrep("\t", level);
2987                 if (!prefix)
2988                         return log_oom();
2989
2990                 if (bus_type_is_container(type) > 0) {
2991                         r = sd_bus_message_enter_container(m, type, contents);
2992                         if (r < 0) {
2993                                 log_error("Failed to enter container: %s", strerror(-r));
2994                                 return r;
2995                         }
2996
2997                         if (type == SD_BUS_TYPE_ARRAY)
2998                                 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2999                         else if (type == SD_BUS_TYPE_VARIANT)
3000                                 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
3001                         else if (type == SD_BUS_TYPE_STRUCT)
3002                                 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3003                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3004                                 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3005
3006                         level ++;
3007
3008                         continue;
3009                 }
3010
3011                 r = sd_bus_message_read_basic(m, type, &basic);
3012                 if (r < 0) {
3013                         log_error("Failed to get basic: %s", strerror(-r));
3014                         return r;
3015                 }
3016
3017                 switch (type) {
3018
3019                 case SD_BUS_TYPE_BYTE:
3020                         printf("%sBYTE: %u\n", prefix, basic.u8);
3021                         break;
3022
3023                 case SD_BUS_TYPE_BOOLEAN:
3024                         printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3025                         break;
3026
3027                 case SD_BUS_TYPE_INT16:
3028                         printf("%sINT16: %i\n", prefix, basic.s16);
3029                         break;
3030
3031                 case SD_BUS_TYPE_UINT16:
3032                         printf("%sUINT16: %u\n", prefix, basic.u16);
3033                         break;
3034
3035                 case SD_BUS_TYPE_INT32:
3036                         printf("%sINT32: %i\n", prefix, basic.s32);
3037                         break;
3038
3039                 case SD_BUS_TYPE_UINT32:
3040                         printf("%sUINT32: %u\n", prefix, basic.u32);
3041                         break;
3042
3043                 case SD_BUS_TYPE_INT64:
3044                         printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3045                         break;
3046
3047                 case SD_BUS_TYPE_UINT64:
3048                         printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3049                         break;
3050
3051                 case SD_BUS_TYPE_DOUBLE:
3052                         printf("%sDOUBLE: %g\n", prefix, basic.d64);
3053                         break;
3054
3055                 case SD_BUS_TYPE_STRING:
3056                         printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3057                         break;
3058
3059                 case SD_BUS_TYPE_OBJECT_PATH:
3060                         printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3061                         break;
3062
3063                 case SD_BUS_TYPE_SIGNATURE:
3064                         printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3065                         break;
3066
3067                 case SD_BUS_TYPE_UNIX_FD:
3068                         printf("%sUNIX_FD: %i\n", prefix, basic.i);
3069                         break;
3070
3071                 default:
3072                         assert_not_reached("Unknown basic type.");
3073                 }
3074         }
3075
3076         printf("} END_MESSAGE\n");
3077         return 0;
3078 }
3079
3080 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3081         size_t total;
3082         unsigned i;
3083         void *p, *e;
3084
3085         assert(m);
3086         assert(buffer);
3087         assert(sz);
3088
3089         for (i = 0, total = 0; i < m->n_iovec; i++)
3090                 total += m->iovec[i].iov_len;
3091
3092         p = malloc(total);
3093         if (!p)
3094                 return -ENOMEM;
3095
3096         for (i = 0, e = p; i < m->n_iovec; i++)
3097                 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
3098
3099         *buffer = p;
3100         *sz = total;
3101
3102         return 0;
3103 }
3104
3105 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3106         int r;
3107
3108         assert(m);
3109         assert(l);
3110
3111         r = sd_bus_message_enter_container(m, 'a', "s");
3112         if (r < 0)
3113                 return r;
3114
3115         for (;;) {
3116                 const char *s;
3117
3118                 r = sd_bus_message_read_basic(m, 's', &s);
3119                 if (r < 0)
3120                         return r;
3121                 if (r == 0)
3122                         break;
3123
3124                 r = strv_extend(l, s);
3125                 if (r < 0)
3126                         return r;
3127         }
3128
3129         r = sd_bus_message_exit_container(m);
3130         if (r < 0)
3131                 return r;
3132
3133         return 0;
3134 }
3135
3136 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3137         int r;
3138         const char *t;
3139         char type;
3140
3141         assert(m);
3142
3143         r = sd_bus_message_rewind(m, true);
3144         if (r < 0)
3145                 return NULL;
3146
3147         while (i > 0) {
3148                 r = sd_bus_message_peek_type(m, &type, NULL);
3149                 if (r < 0)
3150                         return NULL;
3151
3152                 if (type != SD_BUS_TYPE_STRING &&
3153                     type != SD_BUS_TYPE_OBJECT_PATH &&
3154                     type != SD_BUS_TYPE_SIGNATURE)
3155                         return NULL;
3156
3157                 r = sd_bus_message_read_basic(m, type, &t);
3158                 if (r < 0)
3159                         return NULL;
3160
3161                 i--;
3162         }
3163
3164         r = sd_bus_message_rewind(m, true);
3165         if (r < 0)
3166                 return NULL;
3167
3168         return t;
3169 }