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