chiark / gitweb /
aac49f486e51cdb5b56c9a4ec553210f92071ada
[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_label(sd_bus_message *m) {
706         if (!m)
707                 return NULL;
708
709         return m->label;
710 }
711
712 int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member) {
713         if (!m)
714                 return -EINVAL;
715
716         if (m->header->type != SD_BUS_MESSAGE_TYPE_SIGNAL)
717                 return 0;
718
719         if (interface && (!m->interface || !streq(m->interface, interface)))
720                 return 0;
721
722         if (member &&  (!m->member || !streq(m->member, member)))
723                 return 0;
724
725         return 1;
726 }
727
728 int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member) {
729         if (!m)
730                 return -EINVAL;
731
732         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
733                 return 0;
734
735         if (interface && (!m->interface || !streq(m->interface, interface)))
736                 return 0;
737
738         if (member &&  (!m->member || !streq(m->member, member)))
739                 return 0;
740
741         return 1;
742 }
743
744 int sd_bus_message_is_method_error(sd_bus_message *m, const char *name) {
745         if (!m)
746                 return -EINVAL;
747
748         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
749                 return 0;
750
751         if (name && (!m->error.name || !streq(m->error.name, name)))
752                 return 0;
753
754         return 1;
755 }
756
757 int sd_bus_message_set_no_reply(sd_bus_message *m, int b) {
758         if (!m)
759                 return -EINVAL;
760         if (m->sealed)
761                 return -EPERM;
762         if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
763                 return -EPERM;
764
765         if (b)
766                 m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
767         else
768                 m->header->flags &= ~SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
769
770         return 0;
771 }
772
773 static struct bus_container *message_get_container(sd_bus_message *m) {
774         assert(m);
775
776         if (m->n_containers == 0)
777                 return &m->root_container;
778
779         assert(m->containers);
780         return m->containers + m->n_containers - 1;
781 }
782
783 static void *message_extend_body(sd_bus_message *m, size_t align, size_t sz) {
784         void *p, *o;
785         size_t added;
786         struct bus_container *c;
787
788         assert(m);
789         assert(align > 0);
790
791         o = m->body;
792         added = m->header->body_size;
793
794         p = buffer_extend(&m->body, &m->header->body_size, align, sz);
795         if (!p)
796                 return NULL;
797
798         added = m->header->body_size - added;
799
800         for (c = m->containers; c < m->containers + m->n_containers; c++)
801                 if (c->array_size) {
802                         c->array_size = (uint32_t*) ((uint8_t*) m->body + ((uint8_t*) c->array_size - (uint8_t*) o));
803                         *c->array_size += added;
804                 }
805
806         if (o != m->body) {
807                 if (m->error.message)
808                         m->error.message = (const char*) m->body + (m->error.message - (const char*) o);
809         }
810
811         m->free_body = true;
812
813         return p;
814 }
815
816 int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored) {
817         struct bus_container *c;
818         ssize_t align, sz;
819         uint32_t k;
820         void *a;
821         char *e = NULL;
822         int fd = -1;
823         uint32_t fdi = 0;
824         int r;
825
826         if (!m)
827                 return -EINVAL;
828         if (!p)
829                 return -EINVAL;
830         if (m->sealed)
831                 return -EPERM;
832         if (!bus_type_is_basic(type))
833                 return -EINVAL;
834
835         c = message_get_container(m);
836
837         if (c->signature && c->signature[c->index]) {
838                 /* Container signature is already set */
839
840                 if (c->signature[c->index] != type)
841                         return -ENXIO;
842         } else {
843                 /* Maybe we can append to the signature? But only if this is the top-level container*/
844                 if (c->enclosing != 0)
845                         return -ENXIO;
846
847                 e = strextend(&c->signature, CHAR_TO_STR(type), NULL);
848                 if (!e)
849                         return -ENOMEM;
850         }
851
852         switch (type) {
853
854         case SD_BUS_TYPE_STRING:
855         case SD_BUS_TYPE_OBJECT_PATH:
856
857                 align = 4;
858                 sz = 4 + strlen(p) + 1;
859                 break;
860
861         case SD_BUS_TYPE_SIGNATURE:
862
863                 align = 1;
864                 sz = 1 + strlen(p) + 1;
865                 break;
866
867         case SD_BUS_TYPE_BOOLEAN:
868                 align = sz = 4;
869
870                 assert_cc(sizeof(int) == sizeof(uint32_t));
871                 memcpy(&k, p, 4);
872                 k = !!k;
873                 p = &k;
874                 break;
875
876         case SD_BUS_TYPE_UNIX_FD: {
877                 int z, *f;
878
879                 if (!m->allow_fds) {
880                         r = -ENOTSUP;
881                         goto fail;
882                 }
883
884                 align = sz = 4;
885
886                 z = *(int*) p;
887                 if (z < 0) {
888                         r = -EINVAL;
889                         goto fail;
890                 }
891
892                 fd = fcntl(z, F_DUPFD_CLOEXEC, 3);
893                 if (fd < 0) {
894                         r = -errno;
895                         goto fail;
896                 }
897
898                 f = realloc(m->fds, sizeof(int) * (m->n_fds + 1));
899                 if (!f) {
900                         r = -ENOMEM;
901                         goto fail;
902                 }
903
904                 fdi = m->n_fds;
905                 f[fdi] = fd;
906                 m->fds = f;
907                 m->free_fds = true;
908                 break;
909         }
910
911         default:
912                 align = bus_type_get_alignment(type);
913                 sz = bus_type_get_size(type);
914                 break;
915         }
916
917         assert(align > 0);
918         assert(sz > 0);
919
920         a = message_extend_body(m, align, sz);
921         if (!a) {
922                 r = -ENOMEM;
923                 goto fail;
924         }
925
926         if (type == SD_BUS_TYPE_STRING || type == SD_BUS_TYPE_OBJECT_PATH) {
927                 *(uint32_t*) a = sz - 5;
928                 memcpy((uint8_t*) a + 4, p, sz - 4);
929
930                 if (stored)
931                         *stored = (const uint8_t*) a + 4;
932
933         } else if (type == SD_BUS_TYPE_SIGNATURE) {
934                 *(uint8_t*) a = sz - 1;
935                 memcpy((uint8_t*) a + 1, p, sz - 1);
936
937                 if (stored)
938                         *stored = (const uint8_t*) a + 1;
939         } else if (type == SD_BUS_TYPE_UNIX_FD) {
940                 *(uint32_t*) a = fdi;
941
942                 if (stored)
943                         *stored = a;
944
945                 m->n_fds ++;
946
947         } else {
948                 memcpy(a, p, sz);
949
950                 if (stored)
951                         *stored = a;
952         }
953
954         if (c->enclosing != SD_BUS_TYPE_ARRAY)
955                 c->index++;
956
957         return 0;
958
959 fail:
960         /* Truncate extended signature again */
961         if (e)
962                 c->signature[c->index] = 0;
963
964         if (fd >= 0)
965                 close_nointr_nofail(fd);
966
967         return r;
968 }
969
970 int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p) {
971         return message_append_basic(m, type, p, NULL);
972 }
973
974 static int bus_message_open_array(
975                 sd_bus_message *m,
976                 struct bus_container *c,
977                 const char *contents,
978                 uint32_t **array_size) {
979
980         unsigned nindex;
981         char *e = NULL;
982         void *a, *b;
983         int alignment;
984         size_t saved;
985
986         assert(m);
987         assert(c);
988         assert(contents);
989         assert(array_size);
990
991         if (!signature_is_single(contents))
992                 return -EINVAL;
993
994         alignment = bus_type_get_alignment(contents[0]);
995         if (alignment < 0)
996                 return alignment;
997
998         if (c->signature && c->signature[c->index]) {
999
1000                 /* Verify the existing signature */
1001
1002                 if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1003                         return -ENXIO;
1004
1005                 if (!startswith(c->signature + c->index + 1, contents))
1006                         return -ENXIO;
1007
1008                 nindex = c->index + 1 + strlen(contents);
1009         } else {
1010                 if (c->enclosing != 0)
1011                         return -ENXIO;
1012
1013                 /* Extend the existing signature */
1014
1015                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_ARRAY), contents, NULL);
1016                 if (!e)
1017                         return -ENOMEM;
1018
1019                 nindex = e - c->signature;
1020         }
1021
1022         saved = m->header->body_size;
1023         a = message_extend_body(m, 4, 4);
1024         if (!a) {
1025                 /* Truncate extended signature again */
1026                 if (e)
1027                         c->signature[c->index] = 0;
1028
1029                 return -ENOMEM;
1030         }
1031         b = m->body;
1032
1033         if (!message_extend_body(m, alignment, 0)) {
1034                 /* Add alignment between size and first element */
1035                 if (e)
1036                         c->signature[c->index] = 0;
1037
1038                 m->header->body_size = saved;
1039                 return -ENOMEM;
1040         }
1041
1042         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1043                 c->index = nindex;
1044
1045         /* m->body might have changed so let's readjust a */
1046         a = (uint8_t*) m->body + ((uint8_t*) a - (uint8_t*) b);
1047         *(uint32_t*) a = 0;
1048
1049         *array_size = a;
1050         return 0;
1051 }
1052
1053 static int bus_message_open_variant(
1054                 sd_bus_message *m,
1055                 struct bus_container *c,
1056                 const char *contents) {
1057
1058         char *e = NULL;
1059         size_t l;
1060         void *a;
1061
1062         assert(m);
1063         assert(c);
1064         assert(contents);
1065
1066         if (!signature_is_single(contents))
1067                 return -EINVAL;
1068
1069         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1070                 return -EINVAL;
1071
1072         if (c->signature && c->signature[c->index]) {
1073
1074                 if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1075                         return -ENXIO;
1076
1077         } else {
1078                 if (c->enclosing != 0)
1079                         return -ENXIO;
1080
1081                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_VARIANT), NULL);
1082                 if (!e)
1083                         return -ENOMEM;
1084         }
1085
1086         l = strlen(contents);
1087         a = message_extend_body(m, 1, 1 + l + 1);
1088         if (!a) {
1089                 /* Truncate extended signature again */
1090                 if (e)
1091                         c->signature[c->index] = 0;
1092
1093                 return -ENOMEM;
1094         }
1095
1096         *(uint8_t*) a = l;
1097         memcpy((uint8_t*) a + 1, contents, l + 1);
1098
1099         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1100                 c->index++;
1101
1102         return 0;
1103 }
1104
1105 static int bus_message_open_struct(
1106                 sd_bus_message *m,
1107                 struct bus_container *c,
1108                 const char *contents) {
1109
1110         size_t nindex;
1111         char *e = NULL;
1112
1113         assert(m);
1114         assert(c);
1115         assert(contents);
1116
1117         if (!signature_is_valid(contents, false))
1118                 return -EINVAL;
1119
1120         if (c->signature && c->signature[c->index]) {
1121                 size_t l;
1122
1123                 l = strlen(contents);
1124
1125                 if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1126                     !startswith(c->signature + c->index + 1, contents) ||
1127                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1128                         return -ENXIO;
1129
1130                 nindex = c->index + 1 + l + 1;
1131         } else {
1132                 if (c->enclosing != 0)
1133                         return -ENXIO;
1134
1135                 e = strextend(&c->signature, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_BEGIN), contents, CHAR_TO_STR(SD_BUS_TYPE_STRUCT_END), NULL);
1136                 if (!e)
1137                         return -ENOMEM;
1138
1139                 nindex = e - c->signature;
1140         }
1141
1142         /* Align contents to 8 byte boundary */
1143         if (!message_extend_body(m, 8, 0)) {
1144                 if (e)
1145                         c->signature[c->index] = 0;
1146
1147                 return -ENOMEM;
1148         }
1149
1150         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1151                 c->index = nindex;
1152
1153         return 0;
1154 }
1155
1156 static int bus_message_open_dict_entry(
1157                 sd_bus_message *m,
1158                 struct bus_container *c,
1159                 const char *contents) {
1160
1161         size_t nindex;
1162
1163         assert(m);
1164         assert(c);
1165         assert(contents);
1166
1167         if (!signature_is_pair(contents))
1168                 return -EINVAL;
1169
1170         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1171                 return -ENXIO;
1172
1173         if (c->signature && c->signature[c->index]) {
1174                 size_t l;
1175
1176                 l = strlen(contents);
1177
1178                 if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1179                     !startswith(c->signature + c->index + 1, contents) ||
1180                     c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1181                         return -ENXIO;
1182
1183                 nindex = c->index + 1 + l + 1;
1184         } else
1185                 return -ENXIO;
1186
1187         /* Align contents to 8 byte boundary */
1188         if (!message_extend_body(m, 8, 0))
1189                 return -ENOMEM;
1190
1191         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1192                 c->index = nindex;
1193
1194         return 0;
1195 }
1196
1197 int sd_bus_message_open_container(
1198                 sd_bus_message *m,
1199                 char type,
1200                 const char *contents) {
1201
1202         struct bus_container *c, *w;
1203         uint32_t *array_size = NULL;
1204         char *signature;
1205         int r;
1206
1207         if (!m)
1208                 return -EINVAL;
1209         if (m->sealed)
1210                 return -EPERM;
1211         if (!contents)
1212                 return -EINVAL;
1213
1214         /* Make sure we have space for one more container */
1215         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1216         if (!w)
1217                 return -ENOMEM;
1218         m->containers = w;
1219
1220         c = message_get_container(m);
1221
1222         signature = strdup(contents);
1223         if (!signature)
1224                 return -ENOMEM;
1225
1226         if (type == SD_BUS_TYPE_ARRAY)
1227                 r = bus_message_open_array(m, c, contents, &array_size);
1228         else if (type == SD_BUS_TYPE_VARIANT)
1229                 r = bus_message_open_variant(m, c, contents);
1230         else if (type == SD_BUS_TYPE_STRUCT)
1231                 r = bus_message_open_struct(m, c, contents);
1232         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1233                 r = bus_message_open_dict_entry(m, c, contents);
1234         else
1235                 r = -EINVAL;
1236
1237         if (r < 0) {
1238                 free(signature);
1239                 return r;
1240         }
1241
1242         /* OK, let's fill it in */
1243         w += m->n_containers++;
1244         w->enclosing = type;
1245         w->signature = signature;
1246         w->index = 0;
1247         w->array_size = array_size;
1248         w->begin = 0;
1249
1250         return 0;
1251 }
1252
1253 int sd_bus_message_close_container(sd_bus_message *m) {
1254         struct bus_container *c;
1255
1256         if (!m)
1257                 return -EINVAL;
1258         if (m->sealed)
1259                 return -EPERM;
1260         if (m->n_containers <= 0)
1261                 return -EINVAL;
1262
1263         c = message_get_container(m);
1264         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1265                 if (c->signature && c->signature[c->index] != 0)
1266                         return -EINVAL;
1267
1268         free(c->signature);
1269         m->n_containers--;
1270
1271         return 0;
1272 }
1273
1274
1275 typedef struct {
1276         const char *types;
1277         unsigned n_struct;
1278         unsigned n_array;
1279 } TypeStack;
1280
1281 static int type_stack_push(TypeStack *stack, unsigned max, unsigned *i, const char *types, unsigned n_struct, unsigned n_array) {
1282         assert(stack);
1283         assert(max > 0);
1284
1285         if (*i >= max)
1286                 return -EINVAL;
1287
1288         stack[*i].types = types;
1289         stack[*i].n_struct = n_struct;
1290         stack[*i].n_array = n_array;
1291         (*i)++;
1292
1293         return 0;
1294 }
1295
1296 static int type_stack_pop(TypeStack *stack, unsigned max, unsigned *i, const char **types, unsigned *n_struct, unsigned *n_array) {
1297         assert(stack);
1298         assert(max > 0);
1299         assert(types);
1300         assert(n_struct);
1301         assert(n_array);
1302
1303         if (*i <= 0)
1304                 return 0;
1305
1306         (*i)--;
1307         *types = stack[*i].types;
1308         *n_struct = stack[*i].n_struct;
1309         *n_array = stack[*i].n_array;
1310
1311         return 1;
1312 }
1313
1314 int bus_message_append_ap(
1315                 sd_bus_message *m,
1316                 const char *types,
1317                 va_list ap) {
1318
1319         unsigned n_array, n_struct;
1320         TypeStack stack[BUS_CONTAINER_DEPTH];
1321         unsigned stack_ptr = 0;
1322         int r;
1323
1324         assert(m);
1325
1326         if (!types)
1327                 return 0;
1328
1329         n_array = (unsigned) -1;
1330         n_struct = strlen(types);
1331
1332         for (;;) {
1333                 const char *t;
1334
1335                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
1336                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
1337                         if (r < 0)
1338                                 return r;
1339                         if (r == 0)
1340                                 break;
1341
1342                         r = sd_bus_message_close_container(m);
1343                         if (r < 0)
1344                                 return r;
1345
1346                         continue;
1347                 }
1348
1349                 t = types;
1350                 if (n_array != (unsigned) -1)
1351                         n_array --;
1352                 else {
1353                         types ++;
1354                         n_struct--;
1355                 }
1356
1357                 switch (*t) {
1358
1359                 case SD_BUS_TYPE_BYTE: {
1360                         uint8_t x;
1361
1362                         x = (uint8_t) va_arg(ap, int);
1363                         r = sd_bus_message_append_basic(m, *t, &x);
1364                         break;
1365                 }
1366
1367                 case SD_BUS_TYPE_BOOLEAN:
1368                 case SD_BUS_TYPE_INT32:
1369                 case SD_BUS_TYPE_UINT32:
1370                 case SD_BUS_TYPE_UNIX_FD: {
1371                         uint32_t x;
1372
1373                         /* We assume a boolean is the same as int32_t */
1374                         assert_cc(sizeof(int32_t) == sizeof(int));
1375
1376                         x = va_arg(ap, uint32_t);
1377                         r = sd_bus_message_append_basic(m, *t, &x);
1378                         break;
1379                 }
1380
1381                 case SD_BUS_TYPE_INT16:
1382                 case SD_BUS_TYPE_UINT16: {
1383                         uint16_t x;
1384
1385                         x = (uint16_t) va_arg(ap, int);
1386                         r = sd_bus_message_append_basic(m, *t, &x);
1387                         break;
1388                 }
1389
1390                 case SD_BUS_TYPE_INT64:
1391                 case SD_BUS_TYPE_UINT64:
1392                 case SD_BUS_TYPE_DOUBLE: {
1393                         uint64_t x;
1394
1395                         x = va_arg(ap, uint64_t);
1396                         r = sd_bus_message_append_basic(m, *t, &x);
1397                         break;
1398                 }
1399
1400                 case SD_BUS_TYPE_STRING:
1401                 case SD_BUS_TYPE_OBJECT_PATH:
1402                 case SD_BUS_TYPE_SIGNATURE: {
1403                         const char *x;
1404
1405                         x = va_arg(ap, const char*);
1406                         r = sd_bus_message_append_basic(m, *t, x);
1407                         break;
1408                 }
1409
1410                 case SD_BUS_TYPE_ARRAY: {
1411                         size_t k;
1412
1413                         r = signature_element_length(t + 1, &k);
1414                         if (r < 0)
1415                                 return r;
1416
1417                         {
1418                                 char s[k + 1];
1419                                 memcpy(s, t + 1, k);
1420                                 s[k] = 0;
1421
1422                                 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, s);
1423                                 if (r < 0)
1424                                         return r;
1425                         }
1426
1427                         if (n_array == (unsigned) -1) {
1428                                 types += k;
1429                                 n_struct -= k;
1430                         }
1431
1432                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1433                         if (r < 0)
1434                                 return r;
1435
1436                         types = t + 1;
1437                         n_struct = k;
1438                         n_array = va_arg(ap, unsigned);
1439
1440                         break;
1441                 }
1442
1443                 case SD_BUS_TYPE_VARIANT: {
1444                         const char *s;
1445
1446                         s = va_arg(ap, const char*);
1447                         if (!s)
1448                                 return -EINVAL;
1449
1450                         r = sd_bus_message_open_container(m, SD_BUS_TYPE_VARIANT, s);
1451                         if (r < 0)
1452                                 return r;
1453
1454                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1455                         if (r < 0)
1456                                 return r;
1457
1458                         types = s;
1459                         n_struct = strlen(s);
1460                         n_array = (unsigned) -1;
1461
1462                         break;
1463                 }
1464
1465                 case SD_BUS_TYPE_STRUCT_BEGIN:
1466                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
1467                         size_t k;
1468
1469                         r = signature_element_length(t, &k);
1470                         if (r < 0)
1471                                 return r;
1472
1473                         {
1474                                 char s[k - 1];
1475
1476                                 memcpy(s, t + 1, k - 2);
1477                                 s[k - 2] = 0;
1478
1479                                 r = sd_bus_message_open_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
1480                                 if (r < 0)
1481                                         return r;
1482                         }
1483
1484                         if (n_array == (unsigned) -1) {
1485                                 types += k - 1;
1486                                 n_struct -= k - 1;
1487                         }
1488
1489                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
1490                         if (r < 0)
1491                                 return r;
1492
1493                         types = t + 1;
1494                         n_struct = k - 2;
1495                         n_array = (unsigned) -1;
1496
1497                         break;
1498                 }
1499
1500                 default:
1501                         r = -EINVAL;
1502                 }
1503
1504                 if (r < 0)
1505                         return r;
1506         }
1507
1508         return 0;
1509 }
1510
1511 int sd_bus_message_append(sd_bus_message *m, const char *types, ...) {
1512         va_list ap;
1513         int r;
1514
1515         if (!m)
1516                 return -EINVAL;
1517         if (m->sealed)
1518                 return -EPERM;
1519         if (!types)
1520                 return 0;
1521
1522         va_start(ap, types);
1523         r = bus_message_append_ap(m, types, ap);
1524         va_end(ap);
1525
1526         return r;
1527 }
1528
1529 static int buffer_peek(const void *p, uint32_t sz, size_t *rindex, size_t align, size_t nbytes, void **r) {
1530         size_t k, start, n;
1531
1532         assert(rindex);
1533         assert(align > 0);
1534
1535         start = ALIGN_TO((size_t) *rindex, align);
1536         n = start + nbytes;
1537
1538         if (n > sz)
1539                 return -EBADMSG;
1540
1541         /* Verify that padding is 0 */
1542         for (k = *rindex; k < start; k++)
1543                 if (((const uint8_t*) p)[k] != 0)
1544                         return -EBADMSG;
1545
1546         if (r)
1547                 *r = (uint8_t*) p + start;
1548
1549         *rindex = n;
1550
1551         return 1;
1552 }
1553
1554 static bool message_end_of_array(sd_bus_message *m, size_t index) {
1555         struct bus_container *c;
1556
1557         assert(m);
1558
1559         c = message_get_container(m);
1560         if (!c->array_size)
1561                 return false;
1562
1563         return index >= c->begin + BUS_MESSAGE_BSWAP32(m, *c->array_size);
1564 }
1565
1566 static int message_peek_body(sd_bus_message *m, size_t *rindex, size_t align, size_t nbytes, void **ret) {
1567         assert(m);
1568         assert(rindex);
1569         assert(align > 0);
1570
1571         if (message_end_of_array(m, *rindex))
1572                 return 0;
1573
1574         return buffer_peek(m->body, BUS_MESSAGE_BODY_SIZE(m), rindex, align, nbytes, ret);
1575 }
1576
1577 static bool validate_nul(const char *s, size_t l) {
1578
1579         /* Check for NUL chars in the string */
1580         if (memchr(s, 0, l))
1581                 return false;
1582
1583         /* Check for NUL termination */
1584         if (s[l] != 0)
1585                 return false;
1586
1587         return true;
1588 }
1589
1590 static bool validate_string(const char *s, size_t l) {
1591
1592         if (!validate_nul(s, l))
1593                 return false;
1594
1595         /* Check if valid UTF8 */
1596         if (!utf8_is_valid(s))
1597                 return false;
1598
1599         return true;
1600 }
1601
1602 static bool validate_signature(const char *s, size_t l) {
1603
1604         if (!validate_nul(s, l))
1605                 return false;
1606
1607         /* Check if valid signature */
1608         if (!signature_is_valid(s, true))
1609                 return false;
1610
1611         return true;
1612 }
1613
1614 static bool validate_object_path(const char *s, size_t l) {
1615
1616         if (!validate_nul(s, l))
1617                 return false;
1618
1619         if (!object_path_is_valid(s))
1620                 return false;
1621
1622         return true;
1623 }
1624
1625 int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p) {
1626         struct bus_container *c;
1627         int r;
1628         void *q;
1629
1630         if (!m)
1631                 return -EINVAL;
1632         if (!m->sealed)
1633                 return -EPERM;
1634         if (!bus_type_is_basic(type))
1635                 return -EINVAL;
1636         if (!p)
1637                 return -EINVAL;
1638
1639         c = message_get_container(m);
1640
1641         if (!c->signature || c->signature[c->index] == 0)
1642                 return 0;
1643
1644         if (c->signature[c->index] != type)
1645                 return -ENXIO;
1646
1647         switch (type) {
1648
1649         case SD_BUS_TYPE_STRING:
1650         case SD_BUS_TYPE_OBJECT_PATH: {
1651                 uint32_t l;
1652                 size_t rindex;
1653
1654                 rindex = m->rindex;
1655                 r = message_peek_body(m, &rindex, 4, 4, &q);
1656                 if (r <= 0)
1657                         return r;
1658
1659                 l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1660                 r = message_peek_body(m, &rindex, 1, l+1, &q);
1661                 if (r < 0)
1662                         return r;
1663                 if (r == 0)
1664                         return -EBADMSG;
1665
1666                 if (type == SD_BUS_TYPE_OBJECT_PATH) {
1667                         if (!validate_object_path(q, l))
1668                                 return -EBADMSG;
1669                 } else {
1670                         if (!validate_string(q, l))
1671                                 return -EBADMSG;
1672                 }
1673
1674                 m->rindex = rindex;
1675                 *(const char**) p = q;
1676                 break;
1677         }
1678
1679         case SD_BUS_TYPE_SIGNATURE: {
1680                 uint8_t l;
1681                 size_t rindex;
1682
1683                 rindex = m->rindex;
1684                 r = message_peek_body(m, &rindex, 1, 1, &q);
1685                 if (r <= 0)
1686                         return r;
1687
1688                 l = *(uint8_t*) q;
1689                 r = message_peek_body(m, &rindex, 1, l+1, &q);
1690                 if (r < 0)
1691                         return r;
1692                 if (r == 0)
1693                         return -EBADMSG;
1694
1695                 if (!validate_signature(q, l))
1696                         return -EBADMSG;
1697
1698                 m->rindex = rindex;
1699                 *(const char**) p = q;
1700                 break;
1701         }
1702
1703         default: {
1704                 ssize_t sz, align;
1705                 size_t rindex;
1706
1707                 align = bus_type_get_alignment(type);
1708                 sz = bus_type_get_size(type);
1709                 assert(align > 0 && sz > 0);
1710
1711                 rindex = m->rindex;
1712                 r = message_peek_body(m, &rindex, align, sz, &q);
1713                 if (r <= 0)
1714                         return r;
1715
1716                 switch (type) {
1717
1718                 case SD_BUS_TYPE_BYTE:
1719                         *(uint8_t*) p = *(uint8_t*) q;
1720                         break;
1721
1722                 case SD_BUS_TYPE_BOOLEAN:
1723                         *(int*) p = !!*(uint32_t*) q;
1724                         break;
1725
1726                 case SD_BUS_TYPE_INT16:
1727                 case SD_BUS_TYPE_UINT16:
1728                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1729                         break;
1730
1731                 case SD_BUS_TYPE_INT32:
1732                 case SD_BUS_TYPE_UINT32:
1733                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1734                         break;
1735
1736                 case SD_BUS_TYPE_INT64:
1737                 case SD_BUS_TYPE_UINT64:
1738                 case SD_BUS_TYPE_DOUBLE:
1739                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1740                         break;
1741
1742                 case SD_BUS_TYPE_UNIX_FD: {
1743                         uint32_t j;
1744
1745                         j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1746                         if (j >= m->n_fds)
1747                                 return -EBADMSG;
1748
1749                         *(int*) p = m->fds[j];
1750                         break;
1751                 }
1752
1753                 default:
1754                         assert_not_reached("Unknown basic type...");
1755                 }
1756
1757                         m->rindex = rindex;
1758
1759                 break;
1760         }
1761         }
1762
1763         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1764                 c->index++;
1765
1766         return 1;
1767 }
1768
1769 static int bus_message_enter_array(
1770                 sd_bus_message *m,
1771                 struct bus_container *c,
1772                 const char *contents,
1773                 uint32_t **array_size) {
1774
1775         size_t rindex;
1776         void *q;
1777         int r, alignment;
1778
1779         assert(m);
1780         assert(c);
1781         assert(contents);
1782         assert(array_size);
1783
1784         if (!signature_is_single(contents))
1785                 return -EINVAL;
1786
1787         alignment = bus_type_get_alignment(contents[0]);
1788         if (alignment < 0)
1789                 return alignment;
1790
1791         if (!c->signature || c->signature[c->index] == 0)
1792                 return 0;
1793
1794         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1795                 return -ENXIO;
1796
1797         if (!startswith(c->signature + c->index + 1, contents))
1798                 return -ENXIO;
1799
1800         rindex = m->rindex;
1801         r = message_peek_body(m, &rindex, 4, 4, &q);
1802         if (r <= 0)
1803                 return r;
1804
1805         if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1806                 return -EBADMSG;
1807
1808         r = message_peek_body(m, &rindex, alignment, 0, NULL);
1809         if (r < 0)
1810                 return r;
1811         if (r == 0)
1812                 return -EBADMSG;
1813
1814         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1815                 c->index += 1 + strlen(contents);
1816
1817         m->rindex = rindex;
1818
1819         *array_size = (uint32_t*) q;
1820
1821         return 1;
1822 }
1823
1824 static int bus_message_enter_variant(
1825                 sd_bus_message *m,
1826                 struct bus_container *c,
1827                 const char *contents) {
1828
1829         size_t rindex;
1830         uint8_t l;
1831         void *q;
1832         int r;
1833
1834         assert(m);
1835         assert(c);
1836         assert(contents);
1837
1838         if (!signature_is_single(contents))
1839                 return -EINVAL;
1840
1841         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1842                 return -EINVAL;
1843
1844         if (!c->signature || c->signature[c->index] == 0)
1845                 return 0;
1846
1847         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1848                 return -ENXIO;
1849
1850         rindex = m->rindex;
1851         r = message_peek_body(m, &rindex, 1, 1, &q);
1852         if (r <= 0)
1853                 return r;
1854
1855         l = *(uint8_t*) q;
1856         r = message_peek_body(m, &rindex, 1, l+1, &q);
1857         if (r < 0)
1858                 return r;
1859         if (r == 0)
1860                 return -EBADMSG;
1861
1862         if (!validate_signature(q, l))
1863                 return -EBADMSG;
1864
1865         if (!streq(q, contents))
1866                 return -ENXIO;
1867
1868         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1869                 c->index++;
1870
1871         m->rindex = rindex;
1872
1873         return 1;
1874 }
1875
1876 static int bus_message_enter_struct(
1877                 sd_bus_message *m,
1878                 struct bus_container *c,
1879                 const char *contents) {
1880
1881         size_t l;
1882         int r;
1883
1884         assert(m);
1885         assert(c);
1886         assert(contents);
1887
1888         if (!signature_is_valid(contents, false))
1889                 return -EINVAL;
1890
1891         if (!c->signature || c->signature[c->index] == 0)
1892                 return 0;
1893
1894         l = strlen(contents);
1895
1896         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1897             !startswith(c->signature + c->index + 1, contents) ||
1898             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1899                 return -ENXIO;
1900
1901         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1902         if (r <= 0)
1903                 return r;
1904
1905         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1906                 c->index += 1 + l + 1;
1907
1908         return 1;
1909 }
1910
1911 static int bus_message_enter_dict_entry(
1912                 sd_bus_message *m,
1913                 struct bus_container *c,
1914                 const char *contents) {
1915
1916         size_t l;
1917         int r;
1918
1919         assert(m);
1920         assert(c);
1921         assert(contents);
1922
1923         if (!signature_is_pair(contents))
1924                 return -EINVAL;
1925
1926         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1927                 return -ENXIO;
1928
1929         if (!c->signature || c->signature[c->index] == 0)
1930                 return 0;
1931
1932         l = strlen(contents);
1933
1934         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1935             !startswith(c->signature + c->index + 1, contents) ||
1936             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1937                 return -ENXIO;
1938
1939         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1940         if (r <= 0)
1941                 return r;
1942
1943         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1944                 c->index += 1 + l + 1;
1945
1946         return 1;
1947 }
1948
1949 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1950         struct bus_container *c, *w;
1951         uint32_t *array_size = NULL;
1952         char *signature;
1953         int r;
1954
1955         if (!m)
1956                 return -EINVAL;
1957         if (!m->sealed)
1958                 return -EPERM;
1959         if (!contents)
1960                 return -EINVAL;
1961
1962         /*
1963          * We enforce a global limit on container depth, that is much
1964          * higher than the 32 structs and 32 arrays the specification
1965          * mandates. This is simpler to implement for us, and we need
1966          * this only to ensure our container array doesn't grow
1967          * without bounds. We are happy to return any data from a
1968          * message as long as the data itself is valid, even if the
1969          * overall message might be not.
1970          *
1971          * Note that the message signature is validated when
1972          * parsing the headers, and that validation does check the
1973          * 32/32 limit.
1974          *
1975          * Note that the specification defines no limits on the depth
1976          * of stacked variants, but we do.
1977          */
1978         if (m->n_containers >= BUS_CONTAINER_DEPTH)
1979                 return -EBADMSG;
1980
1981         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1982         if (!w)
1983                 return -ENOMEM;
1984         m->containers = w;
1985
1986         c = message_get_container(m);
1987
1988         if (!c->signature || c->signature[c->index] == 0)
1989                 return 0;
1990
1991         signature = strdup(contents);
1992         if (!signature)
1993                 return -ENOMEM;
1994
1995         if (type == SD_BUS_TYPE_ARRAY)
1996                 r = bus_message_enter_array(m, c, contents, &array_size);
1997         else if (type == SD_BUS_TYPE_VARIANT)
1998                 r = bus_message_enter_variant(m, c, contents);
1999         else if (type == SD_BUS_TYPE_STRUCT)
2000                 r = bus_message_enter_struct(m, c, contents);
2001         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2002                 r = bus_message_enter_dict_entry(m, c, contents);
2003         else
2004                 r = -EINVAL;
2005
2006         if (r <= 0) {
2007                 free(signature);
2008                 return r;
2009         }
2010
2011         /* OK, let's fill it in */
2012         w += m->n_containers++;
2013         w->enclosing = type;
2014         w->signature = signature;
2015         w->index = 0;
2016         w->array_size = array_size;
2017         w->begin = m->rindex;
2018
2019         return 1;
2020 }
2021
2022 int sd_bus_message_exit_container(sd_bus_message *m) {
2023         struct bus_container *c;
2024
2025         if (!m)
2026                 return -EINVAL;
2027         if (!m->sealed)
2028                 return -EPERM;
2029         if (m->n_containers <= 0)
2030                 return -EINVAL;
2031
2032         c = message_get_container(m);
2033         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
2034                 uint32_t l;
2035
2036                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
2037                 if (c->begin + l != m->rindex)
2038                         return -EBUSY;
2039
2040         } else {
2041                 if (c->signature && c->signature[c->index] != 0)
2042                         return -EINVAL;
2043         }
2044
2045         free(c->signature);
2046         m->n_containers--;
2047
2048         return 1;
2049 }
2050
2051 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
2052         struct bus_container *c;
2053         int r;
2054
2055         if (!m)
2056                 return -EINVAL;
2057         if (!m->sealed)
2058                 return -EPERM;
2059
2060         c = message_get_container(m);
2061
2062         if (!c->signature || c->signature[c->index] == 0)
2063                 goto eof;
2064
2065         if (message_end_of_array(m, m->rindex))
2066                 goto eof;
2067
2068         if (bus_type_is_basic(c->signature[c->index])) {
2069                 if (contents)
2070                         *contents = NULL;
2071                 if (type)
2072                         *type = c->signature[c->index];
2073                 return 1;
2074         }
2075
2076         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
2077
2078                 if (contents) {
2079                         size_t l;
2080                         char *sig;
2081
2082                         r = signature_element_length(c->signature+c->index+1, &l);
2083                         if (r < 0)
2084                                 return r;
2085
2086                         assert(l >= 1);
2087
2088                         sig = strndup(c->signature + c->index + 1, l);
2089                         if (!sig)
2090                                 return -ENOMEM;
2091
2092                         free(m->peeked_signature);
2093                         m->peeked_signature = sig;
2094
2095                         *contents = sig;
2096                 }
2097
2098                 if (type)
2099                         *type = SD_BUS_TYPE_ARRAY;
2100
2101                 return 1;
2102         }
2103
2104         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
2105             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
2106
2107                 if (contents) {
2108                         size_t l;
2109                         char *sig;
2110
2111                         r = signature_element_length(c->signature+c->index, &l);
2112                         if (r < 0)
2113                                 return r;
2114
2115                         assert(l >= 2);
2116                         sig = strndup(c->signature + c->index + 1, l - 2);
2117                         if (!sig)
2118                                 return -ENOMEM;
2119
2120                         free(m->peeked_signature);
2121                         m->peeked_signature = sig;
2122
2123                         *contents = sig;
2124                 }
2125
2126                 if (type)
2127                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2128
2129                 return 1;
2130         }
2131
2132         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2133                 if (contents) {
2134                         size_t rindex, l;
2135                         void *q;
2136
2137                         rindex = m->rindex;
2138                         r = message_peek_body(m, &rindex, 1, 1, &q);
2139                         if (r < 0)
2140                                 return r;
2141                         if (r == 0)
2142                                 goto eof;
2143
2144                         l = *(uint8_t*) q;
2145                         r = message_peek_body(m, &rindex, 1, l+1, &q);
2146                         if (r < 0)
2147                                 return r;
2148                         if (r == 0)
2149                                 return -EBADMSG;
2150
2151                         if (!validate_signature(q, l))
2152                                 return -EBADMSG;
2153
2154                         *contents = q;
2155                 }
2156
2157                 if (type)
2158                         *type = SD_BUS_TYPE_VARIANT;
2159
2160                 return 1;
2161         }
2162
2163         return -EINVAL;
2164
2165 eof:
2166         if (type)
2167                 *type = c->enclosing;
2168         if (contents)
2169                 *contents = NULL;
2170         return 0;
2171 }
2172
2173 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2174         struct bus_container *c;
2175
2176         if (!m)
2177                 return -EINVAL;
2178         if (!m->sealed)
2179                 return -EPERM;
2180
2181         if (complete) {
2182                 reset_containers(m);
2183                 m->rindex = 0;
2184                 m->root_container.index = 0;
2185
2186                 c = message_get_container(m);
2187         } else {
2188                 c = message_get_container(m);
2189
2190                 c->index = 0;
2191                 m->rindex = c->begin;
2192         }
2193
2194         return !isempty(c->signature);
2195 }
2196 static int message_read_ap(
2197                 sd_bus_message *m,
2198                 const char *types,
2199                 va_list ap) {
2200
2201         unsigned n_array, n_struct;
2202         TypeStack stack[BUS_CONTAINER_DEPTH];
2203         unsigned stack_ptr = 0;
2204         int r;
2205
2206         assert(m);
2207
2208         if (!types)
2209                 return 0;
2210
2211         /* Ideally, we'd just call ourselves recursively on every
2212          * complex type. However, the state of a va_list that is
2213          * passed to a function is undefined after that function
2214          * returns. This means we need to docode the va_list linearly
2215          * in a single stackframe. We hence implement our own
2216          * home-grown stack in an array. */
2217
2218         n_array = (unsigned) -1;
2219         n_struct = strlen(types);
2220
2221         for (;;) {
2222                 const char *t;
2223
2224                 if (n_array == 0 || (n_array == (unsigned) -1 && n_struct == 0)) {
2225                         r = type_stack_pop(stack, ELEMENTSOF(stack), &stack_ptr, &types, &n_struct, &n_array);
2226                         if (r < 0)
2227                                 return r;
2228                         if (r == 0)
2229                                 break;
2230
2231                         r = sd_bus_message_exit_container(m);
2232                         if (r < 0)
2233                                 return r;
2234
2235                         continue;
2236                 }
2237
2238                 t = types;
2239                 if (n_array != (unsigned) -1)
2240                         n_array --;
2241                 else {
2242                         types ++;
2243                         n_struct--;
2244                 }
2245
2246                 switch (*t) {
2247
2248                 case SD_BUS_TYPE_BYTE:
2249                 case SD_BUS_TYPE_BOOLEAN:
2250                 case SD_BUS_TYPE_INT16:
2251                 case SD_BUS_TYPE_UINT16:
2252                 case SD_BUS_TYPE_INT32:
2253                 case SD_BUS_TYPE_UINT32:
2254                 case SD_BUS_TYPE_INT64:
2255                 case SD_BUS_TYPE_UINT64:
2256                 case SD_BUS_TYPE_DOUBLE:
2257                 case SD_BUS_TYPE_STRING:
2258                 case SD_BUS_TYPE_OBJECT_PATH:
2259                 case SD_BUS_TYPE_SIGNATURE:
2260                 case SD_BUS_TYPE_UNIX_FD: {
2261                         void *p;
2262
2263                         p = va_arg(ap, void*);
2264                         r = sd_bus_message_read_basic(m, *t, p);
2265                         if (r < 0)
2266                                 return r;
2267                         if (r == 0)
2268                                 return -ENXIO;
2269
2270                         break;
2271                 }
2272
2273                 case SD_BUS_TYPE_ARRAY: {
2274                         size_t k;
2275
2276                         r = signature_element_length(t + 1, &k);
2277                         if (r < 0)
2278                                 return r;
2279
2280                         {
2281                                 char s[k + 1];
2282                                 memcpy(s, t + 1, k);
2283                                 s[k] = 0;
2284
2285                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2286                                 if (r < 0)
2287                                         return r;
2288                                 if (r == 0)
2289                                         return -ENXIO;
2290                         }
2291
2292                         if (n_array == (unsigned) -1) {
2293                                 types += k;
2294                                 n_struct -= k;
2295                         }
2296
2297                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2298                         if (r < 0)
2299                                 return r;
2300
2301                         types = t + 1;
2302                         n_struct = k;
2303                         n_array = va_arg(ap, unsigned);
2304
2305                         break;
2306                 }
2307
2308                 case SD_BUS_TYPE_VARIANT: {
2309                         const char *s;
2310
2311                         s = va_arg(ap, const char *);
2312                         if (!s)
2313                                 return -EINVAL;
2314
2315                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2316                         if (r < 0)
2317                                 return r;
2318                         if (r == 0)
2319                                 return -ENXIO;
2320
2321                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2322                         if (r < 0)
2323                                 return r;
2324
2325                         types = s;
2326                         n_struct = strlen(s);
2327                         n_array = (unsigned) -1;
2328
2329                         break;
2330                 }
2331
2332                 case SD_BUS_TYPE_STRUCT_BEGIN:
2333                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2334                         size_t k;
2335
2336                         r = signature_element_length(t, &k);
2337                         if (r < 0)
2338                                 return r;
2339
2340                         {
2341                                 char s[k - 1];
2342                                 memcpy(s, t + 1, k - 2);
2343                                 s[k - 2] = 0;
2344
2345                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2346                                 if (r < 0)
2347                                         return r;
2348                                 if (r == 0)
2349                                         return -ENXIO;
2350                         }
2351
2352                         if (n_array == (unsigned) -1) {
2353                                 types += k - 1;
2354                                 n_struct -= k - 1;
2355                         }
2356
2357                         r = type_stack_push(stack, ELEMENTSOF(stack), &stack_ptr, types, n_struct, n_array);
2358                         if (r < 0)
2359                                 return r;
2360
2361                         types = t + 1;
2362                         n_struct = k - 2;
2363                         n_array = (unsigned) -1;
2364
2365                         break;
2366                 }
2367
2368                 default:
2369                         return -EINVAL;
2370                 }
2371         }
2372
2373         return 1;
2374 }
2375
2376 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2377         va_list ap;
2378         int r;
2379
2380         if (!m)
2381                 return -EINVAL;
2382         if (!m->sealed)
2383                 return -EPERM;
2384         if (!types)
2385                 return -EINVAL;
2386
2387         va_start(ap, types);
2388         r = message_read_ap(m, types, ap);
2389         va_end(ap);
2390
2391         return r;
2392 }
2393
2394 static int message_peek_fields(
2395                 sd_bus_message *m,
2396                 size_t *rindex,
2397                 size_t align,
2398                 size_t nbytes,
2399                 void **ret) {
2400
2401         assert(m);
2402         assert(rindex);
2403         assert(align > 0);
2404
2405         return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2406 }
2407
2408 static int message_peek_field_uint32(
2409                 sd_bus_message *m,
2410                 size_t *ri,
2411                 uint32_t *ret) {
2412
2413         int r;
2414         void *q;
2415
2416         assert(m);
2417         assert(ri);
2418
2419         r = message_peek_fields(m, ri, 4, 4, &q);
2420         if (r < 0)
2421                 return r;
2422
2423         if (ret)
2424                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2425
2426         return 0;
2427 }
2428
2429 static int message_peek_field_string(
2430                 sd_bus_message *m,
2431                 bool (*validate)(const char *p),
2432                 size_t *ri,
2433                 const char **ret) {
2434
2435         uint32_t l;
2436         int r;
2437         void *q;
2438
2439         assert(m);
2440         assert(ri);
2441
2442         r = message_peek_field_uint32(m, ri, &l);
2443         if (r < 0)
2444                 return r;
2445
2446         r = message_peek_fields(m, ri, 1, l+1, &q);
2447         if (r < 0)
2448                 return r;
2449
2450         if (validate) {
2451                 if (!validate_nul(q, l))
2452                         return -EBADMSG;
2453
2454                 if (!validate(q))
2455                         return -EBADMSG;
2456         } else {
2457                 if (!validate_string(q, l))
2458                         return -EBADMSG;
2459         }
2460
2461         if (ret)
2462                 *ret = q;
2463
2464         return 0;
2465 }
2466
2467 static int message_peek_field_signature(
2468                 sd_bus_message *m,
2469                 size_t *ri,
2470                 const char **ret) {
2471
2472         size_t l;
2473         int r;
2474         void *q;
2475
2476         assert(m);
2477         assert(ri);
2478
2479         r = message_peek_fields(m, ri, 1, 1, &q);
2480         if (r < 0)
2481                 return r;
2482
2483         l = *(uint8_t*) q;
2484         r = message_peek_fields(m, ri, 1, l+1, &q);
2485         if (r < 0)
2486                 return r;
2487
2488         if (!validate_signature(q, l))
2489                 return -EBADMSG;
2490
2491         if (ret)
2492                 *ret = q;
2493
2494         return 0;
2495 }
2496
2497 static int message_skip_fields(
2498                 sd_bus_message *m,
2499                 size_t *ri,
2500                 uint32_t array_size,
2501                 const char **signature) {
2502
2503         size_t original_index;
2504         int r;
2505
2506         assert(m);
2507         assert(ri);
2508         assert(signature);
2509
2510         original_index = *ri;
2511
2512         for (;;) {
2513                 char t;
2514                 size_t l;
2515
2516                 if (array_size != (uint32_t) -1 &&
2517                     array_size <= *ri - original_index)
2518                         return 0;
2519
2520                 t = **signature;
2521                 if (!t)
2522                         return 0;
2523
2524                 if (t == SD_BUS_TYPE_STRING) {
2525
2526                         r = message_peek_field_string(m, NULL, ri, NULL);
2527                         if (r < 0)
2528                                 return r;
2529
2530                         (*signature)++;
2531
2532                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2533
2534                         r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2535                         if (r < 0)
2536                                 return r;
2537
2538                         (*signature)++;
2539
2540                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2541
2542                         r = message_peek_field_signature(m, ri, NULL);
2543                         if (r < 0)
2544                                 return r;
2545
2546                         (*signature)++;
2547
2548                 } else if (bus_type_is_basic(t)) {
2549                         ssize_t align, k;
2550
2551                         align = bus_type_get_alignment(t);
2552                         k = bus_type_get_size(t);
2553                         assert(align > 0 && k > 0);
2554
2555                         r = message_peek_fields(m, ri, align, k, NULL);
2556                         if (r < 0)
2557                                 return r;
2558
2559                         (*signature)++;
2560
2561                 } else if (t == SD_BUS_TYPE_ARRAY) {
2562
2563                         r = signature_element_length(*signature+1, &l);
2564                         if (r < 0)
2565                                 return r;
2566
2567                         assert(l >= 1);
2568                         {
2569                                 char sig[l-1], *s;
2570                                 uint32_t nas;
2571                                 int alignment;
2572
2573                                 strncpy(sig, *signature + 1, l-1);
2574                                 s = sig;
2575
2576                                 alignment = bus_type_get_alignment(sig[0]);
2577                                 if (alignment < 0)
2578                                         return alignment;
2579
2580                                 r = message_peek_field_uint32(m, ri, &nas);
2581                                 if (r < 0)
2582                                         return r;
2583                                 if (nas > BUS_ARRAY_MAX_SIZE)
2584                                         return -EBADMSG;
2585
2586                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
2587                                 if (r < 0)
2588                                         return r;
2589
2590                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
2591                                 if (r < 0)
2592                                         return r;
2593                         }
2594
2595                         (*signature) += 1 + l;
2596
2597                 } else if (t == SD_BUS_TYPE_VARIANT) {
2598                         const char *s;
2599
2600                         r = message_peek_field_signature(m, ri, &s);
2601                         if (r < 0)
2602                                 return r;
2603
2604                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2605                         if (r < 0)
2606                                 return r;
2607
2608                         (*signature)++;
2609
2610                 } else if (t == SD_BUS_TYPE_STRUCT ||
2611                            t == SD_BUS_TYPE_DICT_ENTRY) {
2612
2613                         r = signature_element_length(*signature, &l);
2614                         if (r < 0)
2615                                 return r;
2616
2617                         assert(l >= 2);
2618                         {
2619                                 char sig[l-1], *s;
2620                                 strncpy(sig, *signature + 1, l-1);
2621                                 s = sig;
2622
2623                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2624                                 if (r < 0)
2625                                         return r;
2626                         }
2627
2628                         *signature += l;
2629                 } else
2630                         return -EINVAL;
2631         }
2632 }
2633
2634 int bus_message_parse_fields(sd_bus_message *m) {
2635         size_t ri;
2636         int r;
2637         uint32_t unix_fds = 0;
2638
2639         assert(m);
2640
2641         for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2642                 const char *signature;
2643                 uint8_t *header;
2644
2645                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2646                 if (r < 0)
2647                         return r;
2648
2649                 r = message_peek_field_signature(m, &ri, &signature);
2650                 if (r < 0)
2651                         return r;
2652
2653                 switch (*header) {
2654                 case _SD_BUS_MESSAGE_HEADER_INVALID:
2655                         return -EBADMSG;
2656
2657                 case SD_BUS_MESSAGE_HEADER_PATH:
2658
2659                         if (m->path)
2660                                 return -EBADMSG;
2661
2662                         if (!streq(signature, "o"))
2663                                 return -EBADMSG;
2664
2665                         r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2666                         break;
2667
2668                 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2669
2670                         if (m->interface)
2671                                 return -EBADMSG;
2672
2673                         if (!streq(signature, "s"))
2674                                 return -EBADMSG;
2675
2676                         r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2677                         break;
2678
2679                 case SD_BUS_MESSAGE_HEADER_MEMBER:
2680
2681                         if (m->member)
2682                                 return -EBADMSG;
2683
2684                         if (!streq(signature, "s"))
2685                                 return -EBADMSG;
2686
2687                         r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2688                         break;
2689
2690                 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2691
2692                         if (m->error.name)
2693                                 return -EBADMSG;
2694
2695                         if (!streq(signature, "s"))
2696                                 return -EBADMSG;
2697
2698                         r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2699                         break;
2700
2701                 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2702
2703                         if (m->destination)
2704                                 return -EBADMSG;
2705
2706                         if (!streq(signature, "s"))
2707                                 return -EBADMSG;
2708
2709                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2710                         break;
2711
2712                 case SD_BUS_MESSAGE_HEADER_SENDER:
2713
2714                         if (m->sender)
2715                                 return -EBADMSG;
2716
2717                         if (!streq(signature, "s"))
2718                                 return -EBADMSG;
2719
2720                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2721                         break;
2722
2723
2724                 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2725                         const char *s;
2726                         char *c;
2727
2728                         if (m->root_container.signature)
2729                                 return -EBADMSG;
2730
2731                         if (!streq(signature, "g"))
2732                                 return -EBADMSG;
2733
2734                         r = message_peek_field_signature(m, &ri, &s);
2735                         if (r < 0)
2736                                 return r;
2737
2738                         c = strdup(s);
2739                         if (!c)
2740                                 return -ENOMEM;
2741
2742                         free(m->root_container.signature);
2743                         m->root_container.signature = c;
2744                         break;
2745                 }
2746
2747                 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2748                         if (m->reply_serial != 0)
2749                                 return -EBADMSG;
2750
2751                         if (!streq(signature, "u"))
2752                                 return -EBADMSG;
2753
2754                         r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2755                         if (r < 0)
2756                                 return r;
2757
2758                         if (m->reply_serial == 0)
2759                                 return -EBADMSG;
2760
2761                         break;
2762
2763                 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2764                         if (unix_fds != 0)
2765                                 return -EBADMSG;
2766
2767                         if (!streq(signature, "u"))
2768                                 return -EBADMSG;
2769
2770                         r = message_peek_field_uint32(m, &ri, &unix_fds);
2771                         if (r < 0)
2772                                 return -EBADMSG;
2773
2774                         if (unix_fds == 0)
2775                                 return -EBADMSG;
2776
2777                         break;
2778
2779                 default:
2780                         r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2781                 }
2782
2783                 if (r < 0)
2784                         return r;
2785         }
2786
2787         if (m->n_fds != unix_fds)
2788                 return -EBADMSG;
2789
2790         if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2791                 return -EBADMSG;
2792
2793         switch (m->header->type) {
2794
2795         case SD_BUS_MESSAGE_TYPE_SIGNAL:
2796                 if (!m->path || !m->interface || !m->member)
2797                         return -EBADMSG;
2798                 break;
2799
2800         case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2801
2802                 if (!m->path || !m->member)
2803                         return -EBADMSG;
2804
2805                 break;
2806
2807         case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2808
2809                 if (m->reply_serial == 0)
2810                         return -EBADMSG;
2811                 break;
2812
2813         case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2814
2815                 if (m->reply_serial == 0 || !m->error.name)
2816                         return -EBADMSG;
2817                 break;
2818         }
2819
2820         /* Try to read the error message, but if we can't it's a non-issue */
2821         if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2822                 sd_bus_message_read(m, "s", &m->error.message);
2823
2824         return 0;
2825 }
2826
2827 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2828         int r;
2829
2830         assert(m);
2831
2832         if (m->sealed)
2833                 return -EPERM;
2834
2835         if (m->n_containers > 0)
2836                 return -EBADMSG;
2837
2838         /* If there's a non-trivial signature set, then add it in here */
2839         if (!isempty(m->root_container.signature)) {
2840                 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2841                 if (r < 0)
2842                         return r;
2843         }
2844
2845         if (m->n_fds > 0) {
2846                 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2847                 if (r < 0)
2848                         return r;
2849         }
2850
2851         m->header->serial = serial;
2852         m->sealed = true;
2853
2854         return 0;
2855 }
2856
2857 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2858         if (!m)
2859                 return -EINVAL;
2860         if (!destination)
2861                 return -EINVAL;
2862         if (m->sealed)
2863                 return -EPERM;
2864         if (m->destination)
2865                 return -EEXIST;
2866
2867         return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2868 }
2869
2870 int bus_message_dump(sd_bus_message *m) {
2871         unsigned level = 1;
2872         int r;
2873
2874         assert(m);
2875
2876         printf("Message %p\n"
2877                "\tn_ref=%u\n"
2878                "\tendian=%c\n"
2879                "\ttype=%i\n"
2880                "\tflags=%u\n"
2881                "\tversion=%u\n"
2882                "\tserial=%u\n"
2883                "\tfields_size=%u\n"
2884                "\tbody_size=%u\n"
2885                "\tpath=%s\n"
2886                "\tinterface=%s\n"
2887                "\tmember=%s\n"
2888                "\tdestination=%s\n"
2889                "\tsender=%s\n"
2890                "\tsignature=%s\n"
2891                "\treply_serial=%u\n"
2892                "\terror.name=%s\n"
2893                "\terror.message=%s\n"
2894                "\tsealed=%s\n",
2895                m,
2896                m->n_ref,
2897                m->header->endian,
2898                m->header->type,
2899                m->header->flags,
2900                m->header->version,
2901                BUS_MESSAGE_SERIAL(m),
2902                BUS_MESSAGE_FIELDS_SIZE(m),
2903                BUS_MESSAGE_BODY_SIZE(m),
2904                strna(m->path),
2905                strna(m->interface),
2906                strna(m->member),
2907                strna(m->destination),
2908                strna(m->sender),
2909                strna(m->root_container.signature),
2910                m->reply_serial,
2911                strna(m->error.name),
2912                strna(m->error.message),
2913                yes_no(m->sealed));
2914
2915         if (m->pid != 0)
2916                 printf("\tpid=%lu\n", (unsigned long) m->pid);
2917         if (m->tid != 0)
2918                 printf("\ttid=%lu\n", (unsigned long) m->tid);
2919         if (m->uid_valid)
2920                 printf("\tuid=%lu\n", (unsigned long) m->uid);
2921         if (m->gid_valid)
2922                 printf("\tgid=%lu\n", (unsigned long) m->gid);
2923         if (m->pid_starttime != 0)
2924                 printf("\tpid_starttime=%llu\n", (unsigned long long) m->pid_starttime);
2925
2926         r = sd_bus_message_rewind(m, true);
2927         if (r < 0) {
2928                 log_error("Failed to rewind: %s", strerror(-r));
2929                 return r;
2930         }
2931
2932         printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2933
2934         for(;;) {
2935                 _cleanup_free_ char *prefix = NULL;
2936                 const char *contents = NULL;
2937                 char type;
2938                 union {
2939                         uint8_t u8;
2940                         uint16_t u16;
2941                         int16_t s16;
2942                         uint32_t u32;
2943                         int32_t s32;
2944                         uint64_t u64;
2945                         int64_t s64;
2946                         double d64;
2947                         const char *string;
2948                         int i;
2949                 } basic;
2950
2951                 r = sd_bus_message_peek_type(m, &type, &contents);
2952                 if (r < 0) {
2953                         log_error("Failed to peek type: %s", strerror(-r));
2954                         return r;
2955                 }
2956                 if (r == 0) {
2957                         if (level <= 1)
2958                                 break;
2959
2960                         r = sd_bus_message_exit_container(m);
2961                         if (r < 0) {
2962                                 log_error("Failed to exit container: %s", strerror(-r));
2963                                 return r;
2964                         }
2965
2966                         level--;
2967
2968                         prefix = strrep("\t", level);
2969                         if (!prefix)
2970                                 return log_oom();
2971
2972                         if (type == SD_BUS_TYPE_ARRAY)
2973                                 printf("%s} END_ARRAY \n", prefix);
2974                         else if (type == SD_BUS_TYPE_VARIANT)
2975                                 printf("%s} END_VARIANT\n", prefix);
2976                         else if (type == SD_BUS_TYPE_STRUCT)
2977                                 printf("%s} END_STRUCT\n", prefix);
2978                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2979                                 printf("%s} END_DICT_ENTRY\n", prefix);
2980
2981                         continue;
2982                 }
2983
2984                 prefix = strrep("\t", level);
2985                 if (!prefix)
2986                         return log_oom();
2987
2988                 if (bus_type_is_container(type) > 0) {
2989                         r = sd_bus_message_enter_container(m, type, contents);
2990                         if (r < 0) {
2991                                 log_error("Failed to enter container: %s", strerror(-r));
2992                                 return r;
2993                         }
2994
2995                         if (type == SD_BUS_TYPE_ARRAY)
2996                                 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2997                         else if (type == SD_BUS_TYPE_VARIANT)
2998                                 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2999                         else if (type == SD_BUS_TYPE_STRUCT)
3000                                 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
3001                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
3002                                 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
3003
3004                         level ++;
3005
3006                         continue;
3007                 }
3008
3009                 r = sd_bus_message_read_basic(m, type, &basic);
3010                 if (r < 0) {
3011                         log_error("Failed to get basic: %s", strerror(-r));
3012                         return r;
3013                 }
3014
3015                 switch (type) {
3016
3017                 case SD_BUS_TYPE_BYTE:
3018                         printf("%sBYTE: %u\n", prefix, basic.u8);
3019                         break;
3020
3021                 case SD_BUS_TYPE_BOOLEAN:
3022                         printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
3023                         break;
3024
3025                 case SD_BUS_TYPE_INT16:
3026                         printf("%sINT16: %i\n", prefix, basic.s16);
3027                         break;
3028
3029                 case SD_BUS_TYPE_UINT16:
3030                         printf("%sUINT16: %u\n", prefix, basic.u16);
3031                         break;
3032
3033                 case SD_BUS_TYPE_INT32:
3034                         printf("%sINT32: %i\n", prefix, basic.s32);
3035                         break;
3036
3037                 case SD_BUS_TYPE_UINT32:
3038                         printf("%sUINT32: %u\n", prefix, basic.u32);
3039                         break;
3040
3041                 case SD_BUS_TYPE_INT64:
3042                         printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
3043                         break;
3044
3045                 case SD_BUS_TYPE_UINT64:
3046                         printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
3047                         break;
3048
3049                 case SD_BUS_TYPE_DOUBLE:
3050                         printf("%sDOUBLE: %g\n", prefix, basic.d64);
3051                         break;
3052
3053                 case SD_BUS_TYPE_STRING:
3054                         printf("%sSTRING: \"%s\"\n", prefix, basic.string);
3055                         break;
3056
3057                 case SD_BUS_TYPE_OBJECT_PATH:
3058                         printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
3059                         break;
3060
3061                 case SD_BUS_TYPE_SIGNATURE:
3062                         printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
3063                         break;
3064
3065                 case SD_BUS_TYPE_UNIX_FD:
3066                         printf("%sUNIX_FD: %i\n", prefix, basic.i);
3067                         break;
3068
3069                 default:
3070                         assert_not_reached("Unknown basic type.");
3071                 }
3072         }
3073
3074         printf("} END_MESSAGE\n");
3075         return 0;
3076 }
3077
3078 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
3079         size_t total;
3080         void *p, *e;
3081
3082         assert(m);
3083         assert(buffer);
3084         assert(sz);
3085
3086         total = BUS_MESSAGE_SIZE(m);
3087
3088         p = malloc(total);
3089         if (!p)
3090                 return -ENOMEM;
3091
3092         e = mempcpy(p, m->header, sizeof(*m->header));
3093
3094         if (m->fields) {
3095                 e = mempcpy(e, m->fields, m->header->fields_size);
3096
3097                 if (m->header->fields_size % 8 != 0)
3098                         e = mempset(e, 0, 8 - (m->header->fields_size % 8));
3099         }
3100
3101         if (m->body)
3102                 e = mempcpy(e, m->body, m->header->body_size);
3103
3104         assert(total == (size_t) ((uint8_t*) e - (uint8_t*) p));
3105
3106         *buffer = p;
3107         *sz = total;
3108
3109         return 0;
3110 }
3111
3112 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
3113         int r;
3114
3115         assert(m);
3116         assert(l);
3117
3118         r = sd_bus_message_enter_container(m, 'a', "s");
3119         if (r < 0)
3120                 return r;
3121
3122         for (;;) {
3123                 const char *s;
3124
3125                 r = sd_bus_message_read_basic(m, 's', &s);
3126                 if (r < 0)
3127                         return r;
3128                 if (r == 0)
3129                         break;
3130
3131                 r = strv_extend(l, s);
3132                 if (r < 0)
3133                         return r;
3134         }
3135
3136         r = sd_bus_message_exit_container(m);
3137         if (r < 0)
3138                 return r;
3139
3140         return 0;
3141 }
3142
3143 const char* bus_message_get_arg(sd_bus_message *m, unsigned i) {
3144         int r;
3145         const char *t;
3146         char type;
3147
3148         assert(m);
3149
3150         r = sd_bus_message_rewind(m, true);
3151         if (r < 0)
3152                 return NULL;
3153
3154         while (i > 0) {
3155                 r = sd_bus_message_peek_type(m, &type, NULL);
3156                 if (r < 0)
3157                         return NULL;
3158
3159                 if (type != SD_BUS_TYPE_STRING &&
3160                     type != SD_BUS_TYPE_OBJECT_PATH &&
3161                     type != SD_BUS_TYPE_SIGNATURE)
3162                         return NULL;
3163
3164                 r = sd_bus_message_read_basic(m, type, &t);
3165                 if (r < 0)
3166                         return NULL;
3167
3168                 i--;
3169         }
3170
3171         r = sd_bus_message_rewind(m, true);
3172         if (r < 0)
3173                 return NULL;
3174
3175         return t;
3176 }
3177
3178 int bus_header_size(struct bus_header *h, size_t *sum) {
3179         size_t fs, bs;
3180
3181         assert(h);
3182         assert(sum);
3183
3184         if (h->endian == SD_BUS_NATIVE_ENDIAN) {
3185                 fs = h->fields_size;
3186                 bs = h->body_size;
3187         } else if (h->endian == SD_BUS_REVERSE_ENDIAN) {
3188                 fs = bswap_32(h->fields_size);
3189                 bs = bswap_32(h->body_size);
3190         } else
3191                 return -EBADMSG;
3192
3193         *sum = sizeof(struct bus_header) + ALIGN8(fs) + bs;
3194         return 0;
3195 }