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