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