chiark / gitweb /
build-sys: make gcc shut up
[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         size_t sz, align;
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                 size_t sz, align, rindex;
1594
1595                 align = bus_type_get_alignment(type);
1596                 sz = bus_type_get_size(type);
1597
1598                 rindex = m->rindex;
1599                 r = message_peek_body(m, &rindex, align, sz, &q);
1600                 if (r <= 0)
1601                         return r;
1602
1603                 switch (type) {
1604
1605                 case SD_BUS_TYPE_BYTE:
1606                         *(uint8_t*) p = *(uint8_t*) q;
1607                         break;
1608
1609                 case SD_BUS_TYPE_BOOLEAN:
1610                         *(int*) p = !!*(uint32_t*) q;
1611                         break;
1612
1613                 case SD_BUS_TYPE_INT16:
1614                 case SD_BUS_TYPE_UINT16:
1615                         *(uint16_t*) p = BUS_MESSAGE_BSWAP16(m, *(uint16_t*) q);
1616                         break;
1617
1618                 case SD_BUS_TYPE_INT32:
1619                 case SD_BUS_TYPE_UINT32:
1620                         *(uint32_t*) p = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1621                         break;
1622
1623                 case SD_BUS_TYPE_INT64:
1624                 case SD_BUS_TYPE_UINT64:
1625                 case SD_BUS_TYPE_DOUBLE:
1626                         *(uint64_t*) p = BUS_MESSAGE_BSWAP64(m, *(uint64_t*) q);
1627                         break;
1628
1629                 case SD_BUS_TYPE_UNIX_FD: {
1630                         int copy;
1631                         uint32_t j;
1632
1633                         j = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
1634                         if (j >= m->n_fds)
1635                                 return -EBADMSG;
1636
1637                         copy = fcntl(m->fds[j], F_DUPFD_CLOEXEC, 3);
1638                         if (copy < 0)
1639                                 return -errno;
1640
1641                         *(int*) p = copy;
1642                         break;
1643                 }
1644
1645                 default:
1646                         assert_not_reached("Unknown basic type...");
1647                 }
1648
1649                         m->rindex = rindex;
1650
1651                 break;
1652         }
1653         }
1654
1655         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1656                 c->index++;
1657
1658         return 1;
1659 }
1660
1661 static int bus_message_enter_array(
1662                 sd_bus_message *m,
1663                 struct bus_container *c,
1664                 const char *contents,
1665                 uint32_t **array_size) {
1666
1667         size_t rindex;
1668         void *q;
1669         int r, alignment;
1670
1671         assert(m);
1672         assert(c);
1673         assert(contents);
1674         assert(array_size);
1675
1676         if (!signature_is_single(contents))
1677                 return -EINVAL;
1678
1679         alignment = bus_type_get_alignment(contents[0]);
1680         if (alignment < 0)
1681                 return alignment;
1682
1683         if (!c->signature || c->signature[c->index] == 0)
1684                 return 0;
1685
1686         if (c->signature[c->index] != SD_BUS_TYPE_ARRAY)
1687                 return -ENXIO;
1688
1689         if (!startswith(c->signature + c->index + 1, contents))
1690                 return -ENXIO;
1691
1692         rindex = m->rindex;
1693         r = message_peek_body(m, &rindex, 4, 4, &q);
1694         if (r <= 0)
1695                 return r;
1696
1697         if (BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q) > BUS_ARRAY_MAX_SIZE)
1698                 return -EBADMSG;
1699
1700         r = message_peek_body(m, &rindex, alignment, 0, NULL);
1701         if (r < 0)
1702                 return r;
1703         if (r == 0)
1704                 return -EBADMSG;
1705
1706         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1707                 c->index += 1 + strlen(contents);
1708
1709         m->rindex = rindex;
1710
1711         *array_size = (uint32_t*) q;
1712
1713         return 1;
1714 }
1715
1716 static int bus_message_enter_variant(
1717                 sd_bus_message *m,
1718                 struct bus_container *c,
1719                 const char *contents) {
1720
1721         size_t rindex;
1722         uint8_t l;
1723         void *q;
1724         int r;
1725
1726         assert(m);
1727         assert(c);
1728         assert(contents);
1729
1730         if (!signature_is_single(contents))
1731                 return -EINVAL;
1732
1733         if (*contents == SD_BUS_TYPE_DICT_ENTRY_BEGIN)
1734                 return -EINVAL;
1735
1736         if (!c->signature || c->signature[c->index] == 0)
1737                 return 0;
1738
1739         if (c->signature[c->index] != SD_BUS_TYPE_VARIANT)
1740                 return -ENXIO;
1741
1742         rindex = m->rindex;
1743         r = message_peek_body(m, &rindex, 1, 1, &q);
1744         if (r <= 0)
1745                 return r;
1746
1747         l = *(uint8_t*) q;
1748         r = message_peek_body(m, &rindex, 1, l+1, &q);
1749         if (r < 0)
1750                 return r;
1751         if (r == 0)
1752                 return -EBADMSG;
1753
1754         if (!validate_signature(q, l))
1755                 return -EBADMSG;
1756
1757         if (!streq(q, contents))
1758                 return -ENXIO;
1759
1760         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1761                 c->index++;
1762
1763         m->rindex = rindex;
1764
1765         return 1;
1766 }
1767
1768 static int bus_message_enter_struct(
1769                 sd_bus_message *m,
1770                 struct bus_container *c,
1771                 const char *contents) {
1772
1773         size_t l;
1774         int r;
1775
1776         assert(m);
1777         assert(c);
1778         assert(contents);
1779
1780         if (!signature_is_valid(contents, false))
1781                 return -EINVAL;
1782
1783         if (!c->signature || c->signature[c->index] == 0)
1784                 return 0;
1785
1786         l = strlen(contents);
1787
1788         if (c->signature[c->index] != SD_BUS_TYPE_STRUCT_BEGIN ||
1789             !startswith(c->signature + c->index + 1, contents) ||
1790             c->signature[c->index + 1 + l] != SD_BUS_TYPE_STRUCT_END)
1791                 return -ENXIO;
1792
1793         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1794         if (r <= 0)
1795                 return r;
1796
1797         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1798                 c->index += 1 + l + 1;
1799
1800         return 1;
1801 }
1802
1803 static int bus_message_enter_dict_entry(
1804                 sd_bus_message *m,
1805                 struct bus_container *c,
1806                 const char *contents) {
1807
1808         size_t l;
1809         int r;
1810
1811         assert(m);
1812         assert(c);
1813         assert(contents);
1814
1815         if (!signature_is_pair(contents))
1816                 return -EINVAL;
1817
1818         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1819                 return -ENXIO;
1820
1821         if (!c->signature || c->signature[c->index] == 0)
1822                 return 0;
1823
1824         l = strlen(contents);
1825
1826         if (c->signature[c->index] != SD_BUS_TYPE_DICT_ENTRY_BEGIN ||
1827             !startswith(c->signature + c->index + 1, contents) ||
1828             c->signature[c->index + 1 + l] != SD_BUS_TYPE_DICT_ENTRY_END)
1829                 return -ENXIO;
1830
1831         r = message_peek_body(m, &m->rindex, 8, 0, NULL);
1832         if (r <= 0)
1833                 return r;
1834
1835         if (c->enclosing != SD_BUS_TYPE_ARRAY)
1836                 c->index += 1 + l + 1;
1837
1838         return 1;
1839 }
1840
1841 int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents) {
1842         struct bus_container *c, *w;
1843         uint32_t *array_size = NULL;
1844         char *signature;
1845         int r;
1846
1847         if (!m)
1848                 return -EINVAL;
1849         if (!m->sealed)
1850                 return -EPERM;
1851         if (!contents)
1852                 return -EINVAL;
1853
1854         /*
1855          * We enforce a global limit on container depth, that is much
1856          * higher than the 32 structs and 32 arrays the specification
1857          * mandates. This is simpler to implement for us, and we need
1858          * this only to ensure our container array doesn't grow
1859          * without bounds. We are happy to return any data from a
1860          * message as long as the data itself is valid, even if the
1861          * overall message might be not.
1862          *
1863          * Note that the message signature is validated when
1864          * parsing the headers, and that validation does check the
1865          * 32/32 limit.
1866          *
1867          * Note that the specification defines no limits on the depth
1868          * of stacked variants, but we do.
1869          */
1870         if (m->n_containers >= BUS_CONTAINER_DEPTH)
1871                 return -EBADMSG;
1872
1873         w = realloc(m->containers, sizeof(struct bus_container) * (m->n_containers + 1));
1874         if (!w)
1875                 return -ENOMEM;
1876         m->containers = w;
1877
1878         c = message_get_container(m);
1879
1880         if (!c->signature || c->signature[c->index] == 0)
1881                 return 0;
1882
1883         signature = strdup(contents);
1884         if (!signature)
1885                 return -ENOMEM;
1886
1887         if (type == SD_BUS_TYPE_ARRAY)
1888                 r = bus_message_enter_array(m, c, contents, &array_size);
1889         else if (type == SD_BUS_TYPE_VARIANT)
1890                 r = bus_message_enter_variant(m, c, contents);
1891         else if (type == SD_BUS_TYPE_STRUCT)
1892                 r = bus_message_enter_struct(m, c, contents);
1893         else if (type == SD_BUS_TYPE_DICT_ENTRY)
1894                 r = bus_message_enter_dict_entry(m, c, contents);
1895         else
1896                 r = -EINVAL;
1897
1898         if (r <= 0) {
1899                 free(signature);
1900                 return r;
1901         }
1902
1903         /* OK, let's fill it in */
1904         w += m->n_containers++;
1905         w->enclosing = type;
1906         w->signature = signature;
1907         w->index = 0;
1908         w->array_size = array_size;
1909         w->begin = m->rindex;
1910
1911         return 1;
1912 }
1913
1914 int sd_bus_message_exit_container(sd_bus_message *m) {
1915         struct bus_container *c;
1916
1917         if (!m)
1918                 return -EINVAL;
1919         if (!m->sealed)
1920                 return -EPERM;
1921         if (m->n_containers <= 0)
1922                 return -EINVAL;
1923
1924         c = message_get_container(m);
1925         if (c->enclosing == SD_BUS_TYPE_ARRAY) {
1926                 uint32_t l;
1927
1928                 l = BUS_MESSAGE_BSWAP32(m, *c->array_size);
1929                 if (c->begin + l != m->rindex)
1930                         return -EBUSY;
1931
1932         } else {
1933                 if (c->signature && c->signature[c->index] != 0)
1934                         return -EINVAL;
1935         }
1936
1937         free(c->signature);
1938         m->n_containers--;
1939
1940         return 1;
1941 }
1942
1943 int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents) {
1944         struct bus_container *c;
1945         int r;
1946
1947         if (!m)
1948                 return -EINVAL;
1949         if (!m->sealed)
1950                 return -EPERM;
1951
1952         c = message_get_container(m);
1953
1954         if (!c->signature || c->signature[c->index] == 0)
1955                 goto eof;
1956
1957         if (message_end_of_array(m, m->rindex))
1958                 goto eof;
1959
1960         if (bus_type_is_basic(c->signature[c->index])) {
1961                 if (contents)
1962                         *contents = NULL;
1963                 if (type)
1964                         *type = c->signature[c->index];
1965                 return 1;
1966         }
1967
1968         if (c->signature[c->index] == SD_BUS_TYPE_ARRAY) {
1969
1970                 if (contents) {
1971                         size_t l;
1972                         char *sig;
1973
1974                         r = signature_element_length(c->signature+c->index+1, &l);
1975                         if (r < 0)
1976                                 return r;
1977
1978                         assert(l >= 1);
1979
1980                         sig = strndup(c->signature + c->index + 1, l);
1981                         if (!sig)
1982                                 return -ENOMEM;
1983
1984                         free(m->peeked_signature);
1985                         m->peeked_signature = sig;
1986
1987                         *contents = sig;
1988                 }
1989
1990                 if (type)
1991                         *type = SD_BUS_TYPE_ARRAY;
1992
1993                 return 1;
1994         }
1995
1996         if (c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ||
1997             c->signature[c->index] == SD_BUS_TYPE_DICT_ENTRY_BEGIN) {
1998
1999                 if (contents) {
2000                         size_t l;
2001                         char *sig;
2002
2003                         r = signature_element_length(c->signature+c->index, &l);
2004                         if (r < 0)
2005                                 return r;
2006
2007                         assert(l >= 2);
2008                         sig = strndup(c->signature + c->index + 1, l - 2);
2009                         if (!sig)
2010                                 return -ENOMEM;
2011
2012                         free(m->peeked_signature);
2013                         m->peeked_signature = sig;
2014
2015                         *contents = sig;
2016                 }
2017
2018                 if (type)
2019                         *type = c->signature[c->index] == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY;
2020
2021                 return 1;
2022         }
2023
2024         if (c->signature[c->index] == SD_BUS_TYPE_VARIANT) {
2025                 if (contents) {
2026                         size_t rindex, l;
2027                         void *q;
2028
2029                         rindex = m->rindex;
2030                         r = message_peek_body(m, &rindex, 1, 1, &q);
2031                         if (r < 0)
2032                                 return r;
2033                         if (r == 0)
2034                                 goto eof;
2035
2036                         l = *(uint8_t*) q;
2037                         r = message_peek_body(m, &rindex, 1, l+1, &q);
2038                         if (r < 0)
2039                                 return r;
2040                         if (r == 0)
2041                                 return -EBADMSG;
2042
2043                         if (!validate_signature(q, l))
2044                                 return -EBADMSG;
2045
2046                         *contents = q;
2047                 }
2048
2049                 if (type)
2050                         *type = SD_BUS_TYPE_VARIANT;
2051
2052                 return 1;
2053         }
2054
2055         return -EINVAL;
2056
2057 eof:
2058         if (type)
2059                 *type = c->enclosing;
2060         if (contents)
2061                 *contents = NULL;
2062         return 0;
2063 }
2064
2065 int sd_bus_message_rewind(sd_bus_message *m, int complete) {
2066         struct bus_container *c;
2067
2068         if (!m)
2069                 return -EINVAL;
2070         if (!m->sealed)
2071                 return -EPERM;
2072
2073         if (complete) {
2074                 reset_containers(m);
2075                 m->rindex = 0;
2076                 m->root_container.index = 0;
2077
2078                 c = message_get_container(m);
2079         } else {
2080                 c = message_get_container(m);
2081
2082                 c->index = 0;
2083                 m->rindex = c->begin;
2084         }
2085
2086         return !isempty(c->signature);
2087 }
2088
2089 static int message_read_ap(sd_bus_message *m, const char *types, va_list ap) {
2090         const char *t;
2091         int r;
2092
2093         assert(m);
2094         assert(types);
2095
2096         for (t = types; *t; t++) {
2097                 switch (*t) {
2098
2099                 case SD_BUS_TYPE_BYTE:
2100                 case SD_BUS_TYPE_BOOLEAN:
2101                 case SD_BUS_TYPE_INT16:
2102                 case SD_BUS_TYPE_UINT16:
2103                 case SD_BUS_TYPE_INT32:
2104                 case SD_BUS_TYPE_UINT32:
2105                 case SD_BUS_TYPE_INT64:
2106                 case SD_BUS_TYPE_UINT64:
2107                 case SD_BUS_TYPE_DOUBLE:
2108                 case SD_BUS_TYPE_STRING:
2109                 case SD_BUS_TYPE_OBJECT_PATH:
2110                 case SD_BUS_TYPE_SIGNATURE:
2111                 case SD_BUS_TYPE_UNIX_FD: {
2112                         void *p;
2113
2114                         p = va_arg(ap, void*);
2115                         r = sd_bus_message_read_basic(m, *t, p);
2116                         break;
2117                 }
2118
2119                 case SD_BUS_TYPE_ARRAY: {
2120                         size_t k;
2121
2122                         r = signature_element_length(t + 1, &k);
2123                         if (r < 0)
2124                                 return r;
2125
2126                         {
2127                                 unsigned i, n;
2128                                 char s[k + 1];
2129
2130                                 memcpy(s, t + 1, k);
2131                                 s[k] = 0;
2132                                 t += k;
2133
2134                                 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, s);
2135                                 if (r < 0)
2136                                         return r;
2137                                 if (r == 0)
2138                                         return -ENXIO;
2139
2140                                 n = va_arg(ap, unsigned);
2141                                 for (i = 0; i < n; i++) {
2142                                         r = message_read_ap(m, s, ap);
2143                                         if (r < 0)
2144                                                 return r;
2145                                 }
2146
2147                                 r = sd_bus_message_exit_container(m);
2148                         }
2149
2150                         break;
2151                 }
2152
2153                 case SD_BUS_TYPE_VARIANT: {
2154                         const char *s;
2155
2156                         s = va_arg(ap, const char *);
2157                         if (!s)
2158                                 return -EINVAL;
2159
2160                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, s);
2161                         if (r < 0)
2162                                 return r;
2163                         if (r == 0)
2164                                 return -ENXIO;
2165
2166                         r = message_read_ap(m, s, ap);
2167                         if (r < 0)
2168                                 return r;
2169                         if (r == 0)
2170                                 return -ENXIO;
2171
2172                         r = sd_bus_message_exit_container(m);
2173                         break;
2174                 }
2175
2176                 case SD_BUS_TYPE_STRUCT_BEGIN:
2177                 case SD_BUS_TYPE_DICT_ENTRY_BEGIN: {
2178                         size_t k;
2179
2180                         r = signature_element_length(t, &k);
2181                         if (r < 0)
2182                                 return r;
2183
2184                         {
2185                                 char s[k - 1];
2186                                 memcpy(s, t + 1, k - 2);
2187                                 s[k - 2] = 0;
2188
2189                                 r = sd_bus_message_enter_container(m, *t == SD_BUS_TYPE_STRUCT_BEGIN ? SD_BUS_TYPE_STRUCT : SD_BUS_TYPE_DICT_ENTRY, s);
2190                                 if (r < 0)
2191                                         return r;
2192                                 if (r == 0)
2193                                         return -ENXIO;
2194
2195                                 t += k - 1;
2196
2197                                 r = message_read_ap(m, s, ap);
2198                                 if (r < 0)
2199                                         return r;
2200                                 if (r == 0)
2201                                         return -ENXIO;
2202
2203                                 r = sd_bus_message_exit_container(m);
2204                         }
2205
2206                         break;
2207                 }
2208
2209                 default:
2210                         r = -EINVAL;
2211                 }
2212
2213                 if (r < 0)
2214                         return r;
2215                 if (r == 0)
2216                         return -ENXIO;
2217         }
2218
2219         return 1;
2220 }
2221
2222 int sd_bus_message_read(sd_bus_message *m, const char *types, ...) {
2223         va_list ap;
2224         int r;
2225
2226         if (!m)
2227                 return -EINVAL;
2228         if (!m->sealed)
2229                 return -EPERM;
2230         if (!types)
2231                 return -EINVAL;
2232
2233         va_start(ap, types);
2234         r = message_read_ap(m, types, ap);
2235         va_end(ap);
2236
2237         return r;
2238 }
2239
2240 static int message_peek_fields(
2241                 sd_bus_message *m,
2242                 size_t *rindex,
2243                 size_t align,
2244                 size_t nbytes,
2245                 void **ret) {
2246
2247         assert(m);
2248         assert(rindex);
2249         assert(align > 0);
2250
2251         return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
2252 }
2253
2254 static int message_peek_field_uint32(
2255                 sd_bus_message *m,
2256                 size_t *ri,
2257                 uint32_t *ret) {
2258
2259         int r;
2260         void *q;
2261
2262         assert(m);
2263         assert(ri);
2264
2265         r = message_peek_fields(m, ri, 4, 4, &q);
2266         if (r < 0)
2267                 return r;
2268
2269         if (ret)
2270                 *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
2271
2272         return 0;
2273 }
2274
2275 static int message_peek_field_string(
2276                 sd_bus_message *m,
2277                 bool (*validate)(const char *p),
2278                 size_t *ri,
2279                 const char **ret) {
2280
2281         uint32_t l;
2282         int r;
2283         void *q;
2284
2285         assert(m);
2286         assert(ri);
2287
2288         r = message_peek_field_uint32(m, ri, &l);
2289         if (r < 0)
2290                 return r;
2291
2292         r = message_peek_fields(m, ri, 1, l+1, &q);
2293         if (r < 0)
2294                 return r;
2295
2296         if (validate) {
2297                 if (!validate_nul(q, l))
2298                         return -EBADMSG;
2299
2300                 if (!validate(q))
2301                         return -EBADMSG;
2302         } else {
2303                 if (!validate_string(q, l))
2304                         return -EBADMSG;
2305         }
2306
2307         if (ret)
2308                 *ret = q;
2309
2310         return 0;
2311 }
2312
2313 static int message_peek_field_signature(
2314                 sd_bus_message *m,
2315                 size_t *ri,
2316                 const char **ret) {
2317
2318         size_t l;
2319         int r;
2320         void *q;
2321
2322         assert(m);
2323         assert(ri);
2324
2325         r = message_peek_fields(m, ri, 1, 1, &q);
2326         if (r < 0)
2327                 return r;
2328
2329         l = *(uint8_t*) q;
2330         r = message_peek_fields(m, ri, 1, l+1, &q);
2331         if (r < 0)
2332                 return r;
2333
2334         if (!validate_signature(q, l))
2335                 return -EBADMSG;
2336
2337         if (ret)
2338                 *ret = q;
2339
2340         return 0;
2341 }
2342
2343 static int message_skip_fields(
2344                 sd_bus_message *m,
2345                 size_t *ri,
2346                 uint32_t array_size,
2347                 const char **signature) {
2348
2349         size_t original_index;
2350         int r;
2351
2352         assert(m);
2353         assert(ri);
2354         assert(signature);
2355
2356         original_index = *ri;
2357
2358         for (;;) {
2359                 char t;
2360                 size_t l;
2361
2362                 if (array_size != (uint32_t) -1 &&
2363                     array_size <= *ri - original_index)
2364                         return 0;
2365
2366                 t = **signature;
2367                 if (!t)
2368                         return 0;
2369
2370                 if (t == SD_BUS_TYPE_STRING) {
2371
2372                         r = message_peek_field_string(m, NULL, ri, NULL);
2373                         if (r < 0)
2374                                 return r;
2375
2376                         (*signature)++;
2377
2378                 } else if (t == SD_BUS_TYPE_OBJECT_PATH) {
2379
2380                         r = message_peek_field_string(m, object_path_is_valid, ri, NULL);
2381                         if (r < 0)
2382                                 return r;
2383
2384                         (*signature)++;
2385
2386                 } else if (t == SD_BUS_TYPE_SIGNATURE) {
2387
2388                         r = message_peek_field_signature(m, ri, NULL);
2389                         if (r < 0)
2390                                 return r;
2391
2392                         (*signature)++;
2393
2394                 } else if (bus_type_is_basic(t)) {
2395                         size_t align, k;
2396
2397                         align = bus_type_get_alignment(t);
2398                         k = bus_type_get_size(t);
2399
2400                         r = message_peek_fields(m, ri, align, k, NULL);
2401                         if (r < 0)
2402                                 return r;
2403
2404                         (*signature)++;
2405
2406                 } else if (t == SD_BUS_TYPE_ARRAY) {
2407
2408                         r = signature_element_length(*signature+1, &l);
2409                         if (r < 0)
2410                                 return r;
2411
2412                         assert(l >= 1);
2413                         {
2414                                 char sig[l-1], *s;
2415                                 uint32_t nas;
2416                                 int alignment;
2417
2418                                 strncpy(sig, *signature + 1, l-1);
2419                                 s = sig;
2420
2421                                 alignment = bus_type_get_alignment(sig[0]);
2422                                 if (alignment < 0)
2423                                         return alignment;
2424
2425                                 r = message_peek_field_uint32(m, ri, &nas);
2426                                 if (r < 0)
2427                                         return r;
2428                                 if (nas > BUS_ARRAY_MAX_SIZE)
2429                                         return -EBADMSG;
2430
2431                                 r = message_peek_fields(m, ri, alignment, 0, NULL);
2432                                 if (r < 0)
2433                                         return r;
2434
2435                                 r = message_skip_fields(m, ri, nas, (const char**) &s);
2436                                 if (r < 0)
2437                                         return r;
2438                         }
2439
2440                         (*signature) += 1 + l;
2441
2442                 } else if (t == SD_BUS_TYPE_VARIANT) {
2443                         const char *s;
2444
2445                         r = message_peek_field_signature(m, ri, &s);
2446                         if (r < 0)
2447                                 return r;
2448
2449                         r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2450                         if (r < 0)
2451                                 return r;
2452
2453                         (*signature)++;
2454
2455                 } else if (t == SD_BUS_TYPE_STRUCT ||
2456                            t == SD_BUS_TYPE_DICT_ENTRY) {
2457
2458                         r = signature_element_length(*signature, &l);
2459                         if (r < 0)
2460                                 return r;
2461
2462                         assert(l >= 2);
2463                         {
2464                                 char sig[l-1], *s;
2465                                 strncpy(sig, *signature + 1, l-1);
2466                                 s = sig;
2467
2468                                 r = message_skip_fields(m, ri, (uint32_t) -1, (const char**) &s);
2469                                 if (r < 0)
2470                                         return r;
2471                         }
2472
2473                         *signature += l;
2474                 } else
2475                         return -EINVAL;
2476         }
2477 }
2478
2479 static int message_parse_fields(sd_bus_message *m) {
2480         size_t ri;
2481         int r;
2482         uint32_t unix_fds = 0;
2483
2484         assert(m);
2485
2486         for (ri = 0; ri < BUS_MESSAGE_FIELDS_SIZE(m); ) {
2487                 const char *signature;
2488                 uint8_t *header;
2489
2490                 r = message_peek_fields(m, &ri, 8, 1, (void**) &header);
2491                 if (r < 0)
2492                         return r;
2493
2494                 r = message_peek_field_signature(m, &ri, &signature);
2495                 if (r < 0)
2496                         return r;
2497
2498                 switch (*header) {
2499                 case _SD_BUS_MESSAGE_HEADER_INVALID:
2500                         return -EBADMSG;
2501
2502                 case SD_BUS_MESSAGE_HEADER_PATH:
2503
2504                         if (m->path)
2505                                 return -EBADMSG;
2506
2507                         if (!streq(signature, "o"))
2508                                 return -EBADMSG;
2509
2510                         r = message_peek_field_string(m, object_path_is_valid, &ri, &m->path);
2511                         break;
2512
2513                 case SD_BUS_MESSAGE_HEADER_INTERFACE:
2514
2515                         if (m->interface)
2516                                 return -EBADMSG;
2517
2518                         if (!streq(signature, "s"))
2519                                 return -EBADMSG;
2520
2521                         r = message_peek_field_string(m, interface_name_is_valid, &ri, &m->interface);
2522                         break;
2523
2524                 case SD_BUS_MESSAGE_HEADER_MEMBER:
2525
2526                         if (m->member)
2527                                 return -EBADMSG;
2528
2529                         if (!streq(signature, "s"))
2530                                 return -EBADMSG;
2531
2532                         r = message_peek_field_string(m, member_name_is_valid, &ri, &m->member);
2533                         break;
2534
2535                 case SD_BUS_MESSAGE_HEADER_ERROR_NAME:
2536
2537                         if (m->error.name)
2538                                 return -EBADMSG;
2539
2540                         if (!streq(signature, "s"))
2541                                 return -EBADMSG;
2542
2543                         r = message_peek_field_string(m, error_name_is_valid, &ri, &m->error.name);
2544                         break;
2545
2546                 case SD_BUS_MESSAGE_HEADER_DESTINATION:
2547
2548                         if (m->destination)
2549                                 return -EBADMSG;
2550
2551                         if (!streq(signature, "s"))
2552                                 return -EBADMSG;
2553
2554                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->destination);
2555                         break;
2556
2557                 case SD_BUS_MESSAGE_HEADER_SENDER:
2558
2559                         if (m->sender)
2560                                 return -EBADMSG;
2561
2562                         if (!streq(signature, "s"))
2563                                 return -EBADMSG;
2564
2565                         r = message_peek_field_string(m, service_name_is_valid, &ri, &m->sender);
2566                         break;
2567
2568
2569                 case SD_BUS_MESSAGE_HEADER_SIGNATURE: {
2570                         const char *s;
2571                         char *c;
2572
2573                         if (m->root_container.signature)
2574                                 return -EBADMSG;
2575
2576                         if (!streq(signature, "g"))
2577                                 return -EBADMSG;
2578
2579                         r = message_peek_field_signature(m, &ri, &s);
2580                         if (r < 0)
2581                                 return r;
2582
2583                         c = strdup(s);
2584                         if (!c)
2585                                 return -ENOMEM;
2586
2587                         free(m->root_container.signature);
2588                         m->root_container.signature = c;
2589                         break;
2590                 }
2591
2592                 case SD_BUS_MESSAGE_HEADER_REPLY_SERIAL:
2593                         if (m->reply_serial != 0)
2594                                 return -EBADMSG;
2595
2596                         if (!streq(signature, "u"))
2597                                 return -EBADMSG;
2598
2599                         r = message_peek_field_uint32(m, &ri, &m->reply_serial);
2600                         if (r < 0)
2601                                 return r;
2602
2603                         if (m->reply_serial == 0)
2604                                 return -EBADMSG;
2605
2606                         break;
2607
2608                 case SD_BUS_MESSAGE_HEADER_UNIX_FDS:
2609                         if (unix_fds != 0)
2610                                 return -EBADMSG;
2611
2612                         if (!streq(signature, "u"))
2613                                 return -EBADMSG;
2614
2615                         r = message_peek_field_uint32(m, &ri, &unix_fds);
2616                         if (r < 0)
2617                                 return -EBADMSG;
2618
2619                         if (unix_fds == 0)
2620                                 return -EBADMSG;
2621
2622                         break;
2623
2624                 default:
2625                         r = message_skip_fields(m, &ri, (uint32_t) -1, (const char **) &signature);
2626                 }
2627
2628                 if (r < 0)
2629                         return r;
2630         }
2631
2632         if (m->n_fds != unix_fds)
2633                 return -EBADMSG;
2634
2635         if (isempty(m->root_container.signature) != (BUS_MESSAGE_BODY_SIZE(m) == 0))
2636                 return -EBADMSG;
2637
2638         switch (m->header->type) {
2639
2640         case SD_BUS_MESSAGE_TYPE_SIGNAL:
2641                 if (!m->path || !m->interface || !m->member)
2642                         return -EBADMSG;
2643                 break;
2644
2645         case SD_BUS_MESSAGE_TYPE_METHOD_CALL:
2646
2647                 if (!m->path || !m->member)
2648                         return -EBADMSG;
2649
2650                 break;
2651
2652         case SD_BUS_MESSAGE_TYPE_METHOD_RETURN:
2653
2654                 if (m->reply_serial == 0)
2655                         return -EBADMSG;
2656                 break;
2657
2658         case SD_BUS_MESSAGE_TYPE_METHOD_ERROR:
2659
2660                 if (m->reply_serial == 0 || !m->error.name)
2661                         return -EBADMSG;
2662                 break;
2663         }
2664
2665         /* Try to read the error message, but if we can't it's a non-issue */
2666         if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR)
2667                 sd_bus_message_read(m, "s", &m->error.message);
2668
2669         return 0;
2670 }
2671
2672 static void setup_iovec(sd_bus_message *m) {
2673         assert(m);
2674         assert(m->sealed);
2675
2676         m->n_iovec = 0;
2677         m->size = 0;
2678
2679         m->iovec[m->n_iovec].iov_base = m->header;
2680         m->iovec[m->n_iovec].iov_len = sizeof(*m->header);
2681         m->size += m->iovec[m->n_iovec].iov_len;
2682         m->n_iovec++;
2683
2684         if (m->fields) {
2685                 m->iovec[m->n_iovec].iov_base = m->fields;
2686                 m->iovec[m->n_iovec].iov_len = m->header->fields_size;
2687                 m->size += m->iovec[m->n_iovec].iov_len;
2688                 m->n_iovec++;
2689
2690                 if (m->header->fields_size % 8 != 0) {
2691                         static const uint8_t padding[7] = { 0, 0, 0, 0, 0, 0, 0 };
2692
2693                         m->iovec[m->n_iovec].iov_base = (void*) padding;
2694                         m->iovec[m->n_iovec].iov_len = 8 - m->header->fields_size % 8;
2695                         m->size += m->iovec[m->n_iovec].iov_len;
2696                         m->n_iovec++;
2697                 }
2698         }
2699
2700         if (m->body) {
2701                 m->iovec[m->n_iovec].iov_base = m->body;
2702                 m->iovec[m->n_iovec].iov_len = m->header->body_size;
2703                 m->size += m->iovec[m->n_iovec].iov_len;
2704                 m->n_iovec++;
2705         }
2706 }
2707
2708 int bus_message_seal(sd_bus_message *m, uint64_t serial) {
2709         int r;
2710
2711         assert(m);
2712
2713         if (m->sealed)
2714                 return -EPERM;
2715
2716         if (m->n_containers > 0)
2717                 return -EBADMSG;
2718
2719         /* If there's a non-trivial signature set, then add it in here */
2720         if (!isempty(m->root_container.signature)) {
2721                 r = message_append_field_signature(m, SD_BUS_MESSAGE_HEADER_SIGNATURE, m->root_container.signature, NULL);
2722                 if (r < 0)
2723                         return r;
2724         }
2725
2726         if (m->n_fds > 0) {
2727                 r = message_append_field_uint32(m, SD_BUS_MESSAGE_HEADER_UNIX_FDS, m->n_fds);
2728                 if (r < 0)
2729                         return r;
2730         }
2731
2732         m->header->serial = serial;
2733         m->sealed = true;
2734
2735         setup_iovec(m);
2736
2737         return 0;
2738 }
2739
2740 int sd_bus_message_set_destination(sd_bus_message *m, const char *destination) {
2741         if (!m)
2742                 return -EINVAL;
2743         if (!destination)
2744                 return -EINVAL;
2745         if (m->sealed)
2746                 return -EPERM;
2747         if (m->destination)
2748                 return -EEXIST;
2749
2750         return message_append_field_string(m, SD_BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, destination, &m->destination);
2751 }
2752
2753 int bus_message_dump(sd_bus_message *m) {
2754         unsigned level = 1;
2755         int r;
2756
2757         assert(m);
2758
2759         printf("Message %p\n"
2760                "\tn_ref=%u\n"
2761                "\tendian=%c\n"
2762                "\ttype=%i\n"
2763                "\tflags=%u\n"
2764                "\tversion=%u\n"
2765                "\tserial=%u\n"
2766                "\tfields_size=%u\n"
2767                "\tbody_size=%u\n"
2768                "\tpath=%s\n"
2769                "\tinterface=%s\n"
2770                "\tmember=%s\n"
2771                "\tdestination=%s\n"
2772                "\tsender=%s\n"
2773                "\tsignature=%s\n"
2774                "\treply_serial=%u\n"
2775                "\terror.name=%s\n"
2776                "\terror.message=%s\n"
2777                "\tsealed=%s\n",
2778                m,
2779                m->n_ref,
2780                m->header->endian,
2781                m->header->type,
2782                m->header->flags,
2783                m->header->version,
2784                BUS_MESSAGE_SERIAL(m),
2785                BUS_MESSAGE_FIELDS_SIZE(m),
2786                BUS_MESSAGE_BODY_SIZE(m),
2787                strna(m->path),
2788                strna(m->interface),
2789                strna(m->member),
2790                strna(m->destination),
2791                strna(m->sender),
2792                strna(m->root_container.signature),
2793                m->reply_serial,
2794                strna(m->error.name),
2795                strna(m->error.message),
2796                yes_no(m->sealed));
2797
2798         r = sd_bus_message_rewind(m, true);
2799         if (r < 0) {
2800                 log_error("Failed to rewind: %s", strerror(-r));
2801                 return r;
2802         }
2803
2804         printf("BEGIN_MESSAGE \"%s\" {\n", strempty(m->root_container.signature));
2805
2806         for(;;) {
2807                 _cleanup_free_ char *prefix = NULL;
2808                 const char *contents = NULL;
2809                 char type;
2810                 union {
2811                         uint8_t u8;
2812                         uint16_t u16;
2813                         int16_t s16;
2814                         uint32_t u32;
2815                         int32_t s32;
2816                         uint64_t u64;
2817                         int64_t s64;
2818                         double d64;
2819                         const char *string;
2820                         int i;
2821                 } basic;
2822
2823                 r = sd_bus_message_peek_type(m, &type, &contents);
2824                 if (r < 0) {
2825                         log_error("Failed to peek type: %s", strerror(-r));
2826                         return r;
2827                 }
2828                 if (r == 0) {
2829                         if (level <= 1)
2830                                 break;
2831
2832                         r = sd_bus_message_exit_container(m);
2833                         if (r < 0) {
2834                                 log_error("Failed to exit container: %s", strerror(-r));
2835                                 return r;
2836                         }
2837
2838                         level--;
2839
2840                         prefix = strrep("\t", level);
2841                         if (!prefix)
2842                                 return log_oom();
2843
2844                         if (type == SD_BUS_TYPE_ARRAY)
2845                                 printf("%s} END_ARRAY \n", prefix);
2846                         else if (type == SD_BUS_TYPE_VARIANT)
2847                                 printf("%s} END_VARIANT\n", prefix);
2848                         else if (type == SD_BUS_TYPE_STRUCT)
2849                                 printf("%s} END_STRUCT\n", prefix);
2850                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2851                                 printf("%s} END_DICT_ENTRY\n", prefix);
2852
2853                         continue;
2854                 }
2855
2856                 prefix = strrep("\t", level);
2857                 if (!prefix)
2858                         return log_oom();
2859
2860                 if (bus_type_is_container(type) > 0) {
2861                         r = sd_bus_message_enter_container(m, type, contents);
2862                         if (r < 0) {
2863                                 log_error("Failed to enter container: %s", strerror(-r));
2864                                 return r;
2865                         }
2866
2867                         if (type == SD_BUS_TYPE_ARRAY)
2868                                 printf("%sBEGIN_ARRAY \"%s\" {\n", prefix, contents);
2869                         else if (type == SD_BUS_TYPE_VARIANT)
2870                                 printf("%sBEGIN_VARIANT \"%s\" {\n", prefix, contents);
2871                         else if (type == SD_BUS_TYPE_STRUCT)
2872                                 printf("%sBEGIN_STRUCT \"%s\" {\n", prefix, contents);
2873                         else if (type == SD_BUS_TYPE_DICT_ENTRY)
2874                                 printf("%sBEGIN_DICT_ENTRY \"%s\" {\n", prefix, contents);
2875
2876                         level ++;
2877
2878                         continue;
2879                 }
2880
2881                 r = sd_bus_message_read_basic(m, type, &basic);
2882                 if (r < 0) {
2883                         log_error("Failed to get basic: %s", strerror(-r));
2884                         return r;
2885                 }
2886
2887                 switch (type) {
2888
2889                 case SD_BUS_TYPE_BYTE:
2890                         printf("%sBYTE: %u\n", prefix, basic.u8);
2891                         break;
2892
2893                 case SD_BUS_TYPE_BOOLEAN:
2894                         printf("%sBOOLEAN: %s\n", prefix, yes_no(basic.i));
2895                         break;
2896
2897                 case SD_BUS_TYPE_INT16:
2898                         printf("%sINT16: %i\n", prefix, basic.s16);
2899                         break;
2900
2901                 case SD_BUS_TYPE_UINT16:
2902                         printf("%sUINT16: %u\n", prefix, basic.u16);
2903                         break;
2904
2905                 case SD_BUS_TYPE_INT32:
2906                         printf("%sINT32: %i\n", prefix, basic.s32);
2907                         break;
2908
2909                 case SD_BUS_TYPE_UINT32:
2910                         printf("%sUINT32: %u\n", prefix, basic.u32);
2911                         break;
2912
2913                 case SD_BUS_TYPE_INT64:
2914                         printf("%sINT64: %lli\n", prefix, (long long) basic.s64);
2915                         break;
2916
2917                 case SD_BUS_TYPE_UINT64:
2918                         printf("%sUINT64: %llu\n", prefix, (unsigned long long) basic.u64);
2919                         break;
2920
2921                 case SD_BUS_TYPE_DOUBLE:
2922                         printf("%sDOUBLE: %g\n", prefix, basic.d64);
2923                         break;
2924
2925                 case SD_BUS_TYPE_STRING:
2926                         printf("%sSTRING: \"%s\"\n", prefix, basic.string);
2927                         break;
2928
2929                 case SD_BUS_TYPE_OBJECT_PATH:
2930                         printf("%sOBJECT_PATH: \"%s\"\n", prefix, basic.string);
2931                         break;
2932
2933                 case SD_BUS_TYPE_SIGNATURE:
2934                         printf("%sSIGNATURE: \"%s\"\n", prefix, basic.string);
2935                         break;
2936
2937                 case SD_BUS_TYPE_UNIX_FD:
2938                         printf("%sUNIX_FD: %i\n", prefix, basic.i);
2939                         break;
2940
2941                 default:
2942                         assert_not_reached("Unknown basic type.");
2943                 }
2944         }
2945
2946         printf("} END_MESSAGE\n");
2947         return 0;
2948 }
2949
2950 int bus_message_get_blob(sd_bus_message *m, void **buffer, size_t *sz) {
2951         size_t total;
2952         unsigned i;
2953         void *p, *e;
2954
2955         assert(m);
2956         assert(buffer);
2957         assert(sz);
2958
2959         for (i = 0, total = 0; i < m->n_iovec; i++)
2960                 total += m->iovec[i].iov_len;
2961
2962         p = malloc(total);
2963         if (!p)
2964                 return -ENOMEM;
2965
2966         for (i = 0, e = p; i < m->n_iovec; i++)
2967                 e = mempcpy(e, m->iovec[i].iov_base, m->iovec[i].iov_len);
2968
2969         *buffer = p;
2970         *sz = total;
2971
2972         return 0;
2973 }
2974
2975 int bus_message_read_strv_extend(sd_bus_message *m, char ***l) {
2976         int r;
2977
2978         assert(m);
2979         assert(l);
2980
2981         r = sd_bus_message_enter_container(m, 'a', "s");
2982         if (r < 0)
2983                 return r;
2984
2985         for (;;) {
2986                 const char *s;
2987
2988                 r = sd_bus_message_read_basic(m, 's', &s);
2989                 if (r < 0)
2990                         return r;
2991                 if (r == 0)
2992                         break;
2993
2994                 r = strv_extend(l, s);
2995                 if (r < 0)
2996                         return r;
2997         }
2998
2999         r = sd_bus_message_exit_container(m);
3000         if (r < 0)
3001                 return r;
3002
3003         return 0;
3004 }