aboutsummaryrefslogtreecommitdiff
path: root/src/lib/common/gnunet_dbus_lib_pop.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/common/gnunet_dbus_lib_pop.c')
-rw-r--r--src/lib/common/gnunet_dbus_lib_pop.c733
1 files changed, 733 insertions, 0 deletions
diff --git a/src/lib/common/gnunet_dbus_lib_pop.c b/src/lib/common/gnunet_dbus_lib_pop.c
new file mode 100644
index 0000000..dd945e4
--- /dev/null
+++ b/src/lib/common/gnunet_dbus_lib_pop.c
@@ -0,0 +1,733 @@
1#include "config.h"
2
3#include <gnunet/platform.h>
4#include <gnunet/gnunet_common.h>
5#include <gnunet/gnunet_strings_lib.h>
6
7#include "gnunet_dbus_lib.h"
8#include "gnunet_crypto_dbus_lib.h"
9
10#define LOG(kind, ...) GNUNET_log_from (kind, "dbus-pop", __VA_ARGS__)
11
12static DBusMessage *
13pop_basic (
14 DBusMessage *message,
15 DBusMessageIter *iter,
16 const char *arg_name,
17 int expected_type,
18 void *value)
19{
20 int arg_type = dbus_message_iter_get_arg_type (iter);
21 if (expected_type != arg_type)
22 {
23 return dbus_message_new_error_printf (
24 message,
25 DBUS_ERROR_INVALID_ARGS,
26 "Bad argument for '%s'. Expected %s. Got %s",
27 arg_name,
28 GNUNET_DBUS_signature_typecode_to_string (expected_type),
29 GNUNET_DBUS_signature_typecode_to_string (arg_type));
30 };
31 dbus_message_iter_get_basic (iter, value);
32 dbus_message_iter_next (iter);
33
34 return NULL;
35};
36
37DBusMessage *
38GNUNET_DBUS_pop_byte (
39 DBusMessage *message,
40 DBusMessageIter *iter,
41 const char *arg_name,
42 unsigned char *value)
43{
44 return pop_basic (
45 message,
46 iter,
47 arg_name,
48 DBUS_TYPE_BYTE,
49 (void *)value);
50};
51
52DBusMessage *
53GNUNET_DBUS_pop_boolean (
54 DBusMessage *message,
55 DBusMessageIter *iter,
56 const char *arg_name,
57 dbus_bool_t *value)
58{
59 return pop_basic (
60 message,
61 iter,
62 arg_name,
63 DBUS_TYPE_BOOLEAN,
64 (void *)value);
65};
66
67DBusMessage *
68GNUNET_DBUS_pop_int16 (
69 DBusMessage *message,
70 DBusMessageIter *iter,
71 const char *arg_name,
72 dbus_int16_t *value)
73{
74 return pop_basic (
75 message,
76 iter,
77 arg_name,
78 DBUS_TYPE_INT16,
79 (void *)value);
80};
81
82DBusMessage *
83GNUNET_DBUS_pop_uint16 (
84 DBusMessage *message,
85 DBusMessageIter *iter,
86 const char *arg_name,
87 dbus_uint16_t *value)
88{
89 return pop_basic (
90 message,
91 iter,
92 arg_name,
93 DBUS_TYPE_UINT16,
94 (void *)value);
95};
96
97DBusMessage *
98GNUNET_DBUS_pop_int32 (
99 DBusMessage *message,
100 DBusMessageIter *iter,
101 const char *arg_name,
102 dbus_int32_t *value)
103{
104 return pop_basic (
105 message,
106 iter,
107 arg_name,
108 DBUS_TYPE_INT32,
109 (void *)value);
110};
111
112DBusMessage *
113GNUNET_DBUS_pop_uint32 (
114 DBusMessage *message,
115 DBusMessageIter *iter,
116 const char *arg_name,
117 dbus_uint32_t *value)
118{
119 return pop_basic (
120 message,
121 iter,
122 arg_name,
123 DBUS_TYPE_UINT32,
124 (void *)value);
125};
126
127DBusMessage *
128GNUNET_DBUS_pop_int64 (
129 DBusMessage *message,
130 DBusMessageIter *iter,
131 const char *arg_name,
132 dbus_int64_t *value)
133{
134 return pop_basic (
135 message,
136 iter,
137 arg_name,
138 DBUS_TYPE_INT64,
139 (void *)value);
140};
141
142DBusMessage *
143GNUNET_DBUS_pop_uint64 (
144 DBusMessage *message,
145 DBusMessageIter *iter,
146 const char *arg_name,
147 dbus_uint64_t *value)
148{
149 return pop_basic (
150 message,
151 iter,
152 arg_name,
153 DBUS_TYPE_UINT64,
154 (void *)value);
155};
156
157DBusMessage *
158GNUNET_DBUS_pop_double (
159 DBusMessage *message,
160 DBusMessageIter *iter,
161 const char *arg_name,
162 double *value)
163{
164 return pop_basic (
165 message,
166 iter,
167 arg_name,
168 DBUS_TYPE_DOUBLE,
169 (void *)value);
170};
171
172DBusMessage *
173GNUNET_DBUS_pop_string (
174 DBusMessage *message,
175 DBusMessageIter *iter,
176 const char *arg_name,
177 const char **value)
178{
179 return pop_basic (
180 message,
181 iter,
182 arg_name,
183 DBUS_TYPE_STRING,
184 (void *)value);
185};
186
187DBusMessage *
188GNUNET_DBUS_pop_object_path (
189 DBusMessage *message,
190 DBusMessageIter *iter,
191 const char *arg_name,
192 const char **value)
193{
194 return pop_basic (
195 message,
196 iter,
197 arg_name,
198 DBUS_TYPE_OBJECT_PATH,
199 (void *)value);
200};
201
202DBusMessage *
203GNUNET_DBUS_pop_signature (
204 DBusMessage *message,
205 DBusMessageIter *iter,
206 const char *arg_name,
207 const char **value)
208{
209 return pop_basic (
210 message,
211 iter,
212 arg_name,
213 DBUS_TYPE_SIGNATURE,
214 (void *)value);
215};
216
217DBusMessage *
218GNUNET_DBUS_pop_unix_fd (
219 DBusMessage *message,
220 DBusMessageIter *iter,
221 const char *arg_name,
222 int *value)
223{
224 return pop_basic (
225 message,
226 iter,
227 arg_name,
228 DBUS_TYPE_UNIX_FD,
229 (void *)value);
230};
231
232static DBusMessage *
233pop_enter_container (
234 DBusMessage *message,
235 DBusMessageIter *iter,
236 DBusMessageIter *iter_sub,
237 int type,
238 const char *arg_name)
239{
240 int arg_type = dbus_message_iter_get_arg_type (iter);
241 if (type != arg_type)
242 {
243 return dbus_message_new_error_printf (
244 message,
245 DBUS_ERROR_INVALID_ARGS,
246 "Bad argument for '%s'. Expected %s. Got %s",
247 arg_name,
248 GNUNET_DBUS_signature_typecode_to_string (type),
249 GNUNET_DBUS_signature_typecode_to_string (arg_type));
250 }
251 dbus_message_iter_recurse (iter, iter_sub);
252 dbus_message_iter_next (iter);
253 return NULL;
254};
255
256DBusMessage *
257GNUNET_DBUS_pop_enter_array (
258 DBusMessage *message,
259 DBusMessageIter *iter,
260 DBusMessageIter *iter_sub,
261 const char *arg_name,
262 size_t *len)
263{
264 if (len && dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY)
265 {
266 DBusMessageIter iter_calc_len;
267 dbus_message_iter_recurse (iter, &iter_calc_len);
268 *len = 0;
269 while (dbus_message_iter_get_arg_type (&iter_calc_len) != DBUS_TYPE_INVALID)
270 {
271 ++*len;
272 dbus_message_iter_next (&iter_calc_len);
273 };
274 };
275 return pop_enter_container (message, iter, iter_sub, DBUS_TYPE_ARRAY, arg_name);
276}
277
278DBusMessage *
279GNUNET_DBUS_pop_enter_struct (
280 DBusMessage *message,
281 DBusMessageIter *iter,
282 DBusMessageIter *iter_sub,
283 const char *arg_name)
284{
285 return pop_enter_container (message, iter, iter_sub, DBUS_TYPE_STRUCT, arg_name);
286}
287
288DBusMessage *
289GNUNET_DBUS_pop_enter_variant (
290 DBusMessage *message,
291 DBusMessageIter *iter,
292 DBusMessageIter *iter_sub,
293 const char *arg_name)
294{
295 return pop_enter_container (message, iter, iter_sub, DBUS_TYPE_VARIANT, arg_name);
296}
297
298DBusMessage *
299GNUNET_DBUS_pop_enter_dict_entry (
300 DBusMessage *message,
301 DBusMessageIter *iter,
302 DBusMessageIter *iter_sub,
303 const char *arg_name)
304{
305 return pop_enter_container (message, iter, iter_sub, DBUS_TYPE_DICT_ENTRY, arg_name);
306}
307
308static DBusMessage *
309pop_fixed_array (
310 DBusMessage *message,
311 DBusMessageIter *iter,
312 const char *arg_name,
313 int expected_type,
314 void *value,
315 int *n_elements)
316{
317 int arg_type = dbus_message_iter_get_arg_type (iter);
318 if (DBUS_TYPE_ARRAY != arg_type)
319 {
320 return dbus_message_new_error_printf (
321 message,
322 DBUS_ERROR_INVALID_ARGS,
323 "Bad argument for '%s'. Expected array of %s. Got %s.",
324 arg_name,
325 GNUNET_DBUS_signature_typecode_to_string (expected_type),
326 GNUNET_DBUS_signature_typecode_to_string (arg_type));
327 };
328
329 int element_type = dbus_message_iter_get_element_type (iter);
330 if (expected_type != element_type)
331 {
332 return dbus_message_new_error_printf (
333 message,
334 DBUS_ERROR_INVALID_ARGS,
335 "Bad argument for '%s'. Expected array of %s. Got array of %s",
336 arg_name,
337 GNUNET_DBUS_signature_typecode_to_string (expected_type),
338 GNUNET_DBUS_signature_typecode_to_string (element_type));
339 };
340
341 DBusMessageIter iter_sub;
342 dbus_message_iter_recurse (iter, &iter_sub);
343 dbus_message_iter_get_fixed_array (&iter_sub, value, n_elements);
344 dbus_message_iter_next (iter);
345
346 return NULL;
347};
348
349DBusMessage *
350GNUNET_DBUS_pop_byte_array (
351 DBusMessage *message,
352 DBusMessageIter *iter,
353 const char *arg_name,
354 const unsigned char **value,
355 int *n_elements)
356{
357 return pop_fixed_array (
358 message,
359 iter,
360 arg_name,
361 DBUS_TYPE_BYTE,
362 (void *)value,
363 n_elements);
364};
365
366DBusMessage *
367GNUNET_DBUS_pop_boolean_array (
368 DBusMessage *message,
369 DBusMessageIter *iter,
370 const char *arg_name,
371 const dbus_bool_t **value,
372 int *n_elements)
373{
374 return pop_fixed_array (
375 message,
376 iter,
377 arg_name,
378 DBUS_TYPE_BOOLEAN,
379 (void *)value,
380 n_elements);
381};
382
383DBusMessage *
384GNUNET_DBUS_pop_int16_array (
385 DBusMessage *message,
386 DBusMessageIter *iter,
387 const char *arg_name,
388 const int16_t **value,
389 int *n_elements)
390{
391 return pop_fixed_array (
392 message,
393 iter,
394 arg_name,
395 DBUS_TYPE_INT16,
396 (void *)value,
397 n_elements);
398};
399
400DBusMessage *
401GNUNET_DBUS_pop_uint16_array (
402 DBusMessage *message,
403 DBusMessageIter *iter,
404 const char *arg_name,
405 const uint16_t **value,
406 int *n_elements)
407{
408 return pop_fixed_array (
409 message,
410 iter,
411 arg_name,
412 DBUS_TYPE_UINT16,
413 (void *)value,
414 n_elements);
415};
416
417DBusMessage *
418GNUNET_DBUS_pop_int32_array (
419 DBusMessage *message,
420 DBusMessageIter *iter,
421 const char *arg_name,
422 const int32_t **value,
423 int *n_elements)
424{
425 return pop_fixed_array (
426 message,
427 iter,
428 arg_name,
429 DBUS_TYPE_INT32,
430 (void *)value,
431 n_elements);
432};
433
434DBusMessage *
435GNUNET_DBUS_pop_uint32_array (
436 DBusMessage *message,
437 DBusMessageIter *iter,
438 const char *arg_name,
439 const uint32_t **value,
440 int *n_elements)
441{
442 return pop_fixed_array (
443 message,
444 iter,
445 arg_name,
446 DBUS_TYPE_UINT32,
447 (void *)value,
448 n_elements);
449};
450
451DBusMessage *
452GNUNET_DBUS_pop_int64_array (
453 DBusMessage *message,
454 DBusMessageIter *iter,
455 const char *arg_name,
456 const int64_t **value,
457 int *n_elements)
458{
459 return pop_fixed_array (
460 message,
461 iter,
462 arg_name,
463 DBUS_TYPE_INT64,
464 (void *)value,
465 n_elements);
466};
467
468DBusMessage *
469GNUNET_DBUS_pop_uint64_array (
470 DBusMessage *message,
471 DBusMessageIter *iter,
472 const char *arg_name,
473 const uint64_t **value,
474 int *n_elements)
475{
476 return pop_fixed_array (
477 message,
478 iter,
479 arg_name,
480 DBUS_TYPE_UINT64,
481 (void *)value,
482 n_elements);
483};
484
485DBusMessage *
486GNUNET_DBUS_pop_double_array (
487 DBusMessage *message,
488 DBusMessageIter *iter,
489 const char *arg_name,
490 const double **value,
491 int *n_elements)
492{
493 return pop_fixed_array (
494 message,
495 iter,
496 arg_name,
497 DBUS_TYPE_DOUBLE,
498 (void *)value,
499 n_elements);
500};
501
502/*
503 * bitfield enums can be sent across the wire in either their integer form (as
504 * an array of bit flags) or as an array of strings. Sending an int is more
505 * efficient and is what libraries built around the DBus API would use, people
506 * using the DBus API directly may want to pass human-readable strings for
507 * convenience.
508 */
509DBusMessage *
510GNUNET_DBUS_pop_bitfield (
511 DBusMessage *message,
512 DBusMessageIter *iter,
513 const char *arg_name,
514 int *value,
515 const struct GNUNET_DBUS_StringEnumPair *fields)
516{
517 DBusMessageIter iter_sub;
518 DBusMessage *ret = GNUNET_DBUS_pop_enter_variant (message, iter, &iter_sub, arg_name);
519 if (ret)
520 return ret;
521
522 int arg_type = dbus_message_iter_get_arg_type (&iter_sub);
523 switch (arg_type)
524 {
525 case DBUS_TYPE_ARRAY: {
526 int element_type = dbus_message_iter_get_element_type (&iter_sub);
527 if (DBUS_TYPE_STRING != element_type)
528 {
529 return dbus_message_new_error_printf (
530 message,
531 DBUS_ERROR_INVALID_ARGS,
532 "Bad argument for '%s'. Variant should contain a uint32 or an array of strings.",
533 arg_name);
534 };
535 DBusMessageIter iter_sub_sub;
536 dbus_message_iter_recurse (&iter_sub, &iter_sub_sub);
537 *value = 0;
538 while (dbus_message_iter_get_arg_type (&iter_sub_sub) != DBUS_TYPE_INVALID)
539 {
540 char *option;
541 dbus_message_iter_get_basic (&iter_sub_sub, &option);
542 const struct GNUNET_DBUS_StringEnumPair *field;
543 for (field = fields; field->name; field++)
544 {
545 if (! strcmp (field->name, option))
546 {
547 *value |= field->value;
548 break;
549 };
550 };
551 if (! field->name)
552 {
553 char *errmsg;
554 GNUNET_asprintf (&errmsg, "Bad argument for '%s'. Unrecognised option '%s'. Valid options are [", arg_name, option);
555 for (field = fields; field->name; field++)
556 {
557 char *errmsg_new;
558 GNUNET_asprintf (&errmsg_new, "%s'%s'%s", errmsg, field->name, (field + 1)->name ? ", " : "].");
559 GNUNET_free (errmsg);
560 errmsg = errmsg_new;
561 };
562 DBusMessage *ret = dbus_message_new_error (
563 message,
564 DBUS_ERROR_INVALID_ARGS,
565 errmsg);
566 GNUNET_free (errmsg);
567 return ret;
568 };
569 dbus_message_iter_next (&iter_sub_sub);
570 };
571 GNUNET_DBUS_message_set_pretty (message, true);
572 return NULL;
573 };
574 case DBUS_TYPE_UINT32: {
575 uint32_t flags;
576 dbus_message_iter_get_basic (&iter_sub, &flags);
577 *value = (int)flags;
578 return NULL;
579 };
580 default:
581 return dbus_message_new_error_printf (
582 message,
583 DBUS_ERROR_INVALID_ARGS,
584 "Bad argument for '%s'. Variant contains a %s. Should contain a uint32 or array of strings.",
585 arg_name);
586 };
587};
588
589DBusMessage *
590GNUNET_DBUS_pop_enum (
591 DBusMessage *message,
592 DBusMessageIter *iter,
593 const char *arg_name,
594 int *value,
595 const struct GNUNET_DBUS_StringEnumPair *names)
596{
597 DBusMessageIter iter_sub;
598 DBusMessage *ret = GNUNET_DBUS_pop_enter_variant (message, iter, &iter_sub, arg_name);
599 if (ret)
600 return ret;
601
602 int arg_type = dbus_message_iter_get_arg_type (&iter_sub);
603 switch (arg_type)
604 {
605 case DBUS_TYPE_STRING: {
606 char *option;
607 dbus_message_iter_get_basic (&iter_sub, &option);
608 const struct GNUNET_DBUS_StringEnumPair *name;
609 for (name = names; name->name; name++)
610 {
611 if (! strcmp (name->name, option))
612 {
613 *value = name->value;
614 return NULL;
615 };
616 };
617 char *errmsg;
618 GNUNET_asprintf (&errmsg, "Bad argument for '%s'. Unrecognised option '%s'. Valid options are [", arg_name, option);
619 for (name = names; name->name; name++)
620 {
621 char *errmsg_new;
622 GNUNET_asprintf (&errmsg_new, "%s'%s'%s", errmsg, name->name, (name + 1)->name ? ", " : "].");
623 GNUNET_free (errmsg);
624 errmsg = errmsg_new;
625 };
626
627 DBusMessage *ret = dbus_message_new_error (
628 message,
629 DBUS_ERROR_INVALID_ARGS,
630 errmsg);
631 GNUNET_free (errmsg);
632 return ret;
633 };
634 case DBUS_TYPE_UINT32: {
635 uint32_t option;
636 dbus_message_iter_get_basic (&iter_sub, &option);
637 *value = (int)option;
638 return NULL;
639 };
640 default:
641 return dbus_message_new_error_printf (
642 message,
643 DBUS_ERROR_INVALID_ARGS,
644 "Bad argument for '%s'. Variant contains a %s. Should contain a uint32 or strings.",
645 arg_name,
646 GNUNET_DBUS_signature_typecode_to_string (arg_type));
647 };
648};
649
650DBusMessage *
651GNUNET_DBUS_pop_hashcode (
652 DBusMessage *message,
653 DBusMessageIter *iter,
654 const char *arg_name,
655 struct GNUNET_HashCode *value)
656{
657 DBusMessageIter iter_sub;
658 DBusMessage *ret = GNUNET_DBUS_pop_enter_variant (message, iter, &iter_sub, arg_name);
659 if (ret)
660 return ret;
661
662 int arg_type = dbus_message_iter_get_arg_type (&iter_sub);
663 switch (arg_type)
664 {
665 case DBUS_TYPE_STRING: {
666 char *encoded;
667 dbus_message_iter_get_basic (&iter_sub, &encoded);
668 int success = GNUNET_CRYPTO_hash_from_string2 (encoded, strlen (encoded), value);
669 if (GNUNET_OK != success)
670 {
671 return dbus_message_new_error_printf (
672 message,
673 DBUS_ERROR_INVALID_ARGS,
674 "Bad argument for '%s'. Malformed hash string. GNUNET_CRYPTO_hash_from_string2 returned %d",
675 arg_name,
676 success);
677 };
678 GNUNET_DBUS_message_set_pretty (message, true);
679 return NULL;
680 }
681 case DBUS_TYPE_ARRAY: {
682 DBusMessageIter iter_sub_sub;
683 unsigned char *data;
684 int n_elements;
685 int element_type = dbus_message_iter_get_element_type (&iter_sub);
686 if (DBUS_TYPE_BYTE != element_type)
687 {
688 return dbus_message_new_error_printf (
689 message,
690 DBUS_ERROR_INVALID_ARGS,
691 "Bad argument for '%s'. Variant contains an array of %s. Should contain a base32 encoded string or array of 64 bytes.",
692 arg_name,
693 GNUNET_DBUS_signature_typecode_to_string (element_type));
694 };
695 dbus_message_iter_recurse (&iter_sub, &iter_sub_sub);
696 dbus_message_iter_get_fixed_array (&iter_sub_sub, &data, &n_elements);
697 if (sizeof (value->bits) != n_elements)
698 {
699 return dbus_message_new_error_printf (
700 message,
701 DBUS_ERROR_INVALID_ARGS,
702 "Bad argument for '%s'. Hash code consists of 64 bytes (512 bits). Array contains %d bytes.",
703 arg_name,
704 n_elements);
705 };
706 memcpy (value->bits, data, n_elements);
707 return NULL;
708 };
709 default:
710 return dbus_message_new_error_printf (
711 message,
712 DBUS_ERROR_INVALID_ARGS,
713 "Bad argument for '%s'. Variant contains a %s. Should contain a base32 encoded string or array of 64 bytes.",
714 arg_name,
715 GNUNET_DBUS_signature_typecode_to_string (arg_type));
716 };
717}
718
719DBusMessage *
720GNUNET_DBUS_pop_peer_identity (
721 DBusMessage *message,
722 DBusMessageIter *iter,
723 const char *arg_name,
724 struct GNUNET_PeerIdentity *value)
725{
726 DBusMessageIter iter_sub;
727 DBusMessage *ret = GNUNET_DBUS_pop_enter_struct (message, iter, &iter_sub, arg_name);
728 if (ret)
729 return ret;
730
731 return GNUNET_CRYPTO_DBUS_pop_eddsa_public_key (message, &iter_sub, "public_key", &value->public_key);
732}
733