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