diff options
author | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2017-09-16 22:39:15 +0200 |
---|---|---|
committer | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2017-09-16 22:39:15 +0200 |
commit | 67e0d73709ef557b52ba0527291d68c17fd6c60a (patch) | |
tree | 57dcf9848b436c01c3fc37e3d878445aaf142a4e /src/identity-provider/identity_provider_api.c | |
parent | d5ec12fdbc288f376ee2ee18aceb00e338191f28 (diff) | |
download | gnunet-67e0d73709ef557b52ba0527291d68c17fd6c60a.tar.gz gnunet-67e0d73709ef557b52ba0527291d68c17fd6c60a.zip |
-various fixes; add attribute list API
Diffstat (limited to 'src/identity-provider/identity_provider_api.c')
-rw-r--r-- | src/identity-provider/identity_provider_api.c | 352 |
1 files changed, 331 insertions, 21 deletions
diff --git a/src/identity-provider/identity_provider_api.c b/src/identity-provider/identity_provider_api.c index bbc2bb70a..c806735f6 100644 --- a/src/identity-provider/identity_provider_api.c +++ b/src/identity-provider/identity_provider_api.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "gnunet_mq_lib.h" | 30 | #include "gnunet_mq_lib.h" |
31 | #include "gnunet_identity_provider_service.h" | 31 | #include "gnunet_identity_provider_service.h" |
32 | #include "identity_provider.h" | 32 | #include "identity_provider.h" |
33 | #include "identity_attribute.h" | ||
33 | 34 | ||
34 | #define LOG(kind,...) GNUNET_log_from (kind, "identity-api",__VA_ARGS__) | 35 | #define LOG(kind,...) GNUNET_log_from (kind, "identity-api",__VA_ARGS__) |
35 | 36 | ||
@@ -96,6 +97,75 @@ struct GNUNET_IDENTITY_PROVIDER_Operation | |||
96 | 97 | ||
97 | }; | 98 | }; |
98 | 99 | ||
100 | /** | ||
101 | * Handle for a attribute iterator operation | ||
102 | */ | ||
103 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator | ||
104 | { | ||
105 | |||
106 | /** | ||
107 | * Kept in a DLL. | ||
108 | */ | ||
109 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *next; | ||
110 | |||
111 | /** | ||
112 | * Kept in a DLL. | ||
113 | */ | ||
114 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *prev; | ||
115 | |||
116 | /** | ||
117 | * Main handle to access the idp. | ||
118 | */ | ||
119 | struct GNUNET_IDENTITY_PROVIDER_Handle *h; | ||
120 | |||
121 | /** | ||
122 | * Function to call on completion. | ||
123 | */ | ||
124 | GNUNET_SCHEDULER_TaskCallback finish_cb; | ||
125 | |||
126 | /** | ||
127 | * Closure for @e error_cb. | ||
128 | */ | ||
129 | void *finish_cb_cls; | ||
130 | |||
131 | /** | ||
132 | * The continuation to call with the results | ||
133 | */ | ||
134 | GNUNET_IDENTITY_PROVIDER_AttributeResult proc; | ||
135 | |||
136 | /** | ||
137 | * Closure for @e proc. | ||
138 | */ | ||
139 | void *proc_cls; | ||
140 | |||
141 | /** | ||
142 | * Function to call on errors. | ||
143 | */ | ||
144 | GNUNET_SCHEDULER_TaskCallback error_cb; | ||
145 | |||
146 | /** | ||
147 | * Closure for @e error_cb. | ||
148 | */ | ||
149 | void *error_cb_cls; | ||
150 | |||
151 | /** | ||
152 | * Envelope of the message to send to the service, if not yet | ||
153 | * sent. | ||
154 | */ | ||
155 | struct GNUNET_MQ_Envelope *env; | ||
156 | |||
157 | /** | ||
158 | * Private key of the zone. | ||
159 | */ | ||
160 | struct GNUNET_CRYPTO_EcdsaPrivateKey identity; | ||
161 | |||
162 | /** | ||
163 | * The operation id this zone iteration operation has | ||
164 | */ | ||
165 | uint32_t r_id; | ||
166 | |||
167 | }; | ||
168 | |||
99 | 169 | ||
100 | /** | 170 | /** |
101 | * Handle for the service. | 171 | * Handle for the service. |
@@ -128,6 +198,16 @@ struct GNUNET_IDENTITY_PROVIDER_Handle | |||
128 | struct GNUNET_IDENTITY_PROVIDER_Operation *op_tail; | 198 | struct GNUNET_IDENTITY_PROVIDER_Operation *op_tail; |
129 | 199 | ||
130 | /** | 200 | /** |
201 | * Head of active iterations | ||
202 | */ | ||
203 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it_head; | ||
204 | |||
205 | /** | ||
206 | * Tail of active iterations | ||
207 | */ | ||
208 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it_tail; | ||
209 | |||
210 | /** | ||
131 | * Currently pending transmission request, or NULL for none. | 211 | * Currently pending transmission request, or NULL for none. |
132 | */ | 212 | */ |
133 | struct GNUNET_CLIENT_TransmitHandle *th; | 213 | struct GNUNET_CLIENT_TransmitHandle *th; |
@@ -202,6 +282,26 @@ force_reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *handle) | |||
202 | } | 282 | } |
203 | 283 | ||
204 | /** | 284 | /** |
285 | * Free @a it. | ||
286 | * | ||
287 | * @param it entry to free | ||
288 | */ | ||
289 | static void | ||
290 | free_it (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it) | ||
291 | { | ||
292 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h; | ||
293 | |||
294 | GNUNET_CONTAINER_DLL_remove (h->it_head, | ||
295 | h->it_tail, | ||
296 | it); | ||
297 | if (NULL != it->env) | ||
298 | GNUNET_MQ_discard (it->env); | ||
299 | GNUNET_free (it); | ||
300 | } | ||
301 | |||
302 | |||
303 | |||
304 | /** | ||
205 | * Generic error handler, called with the appropriate error code and | 305 | * Generic error handler, called with the appropriate error code and |
206 | * the same closure specified at the creation of the message queue. | 306 | * the same closure specified at the creation of the message queue. |
207 | * Not every message queue implementation supports an error handler. | 307 | * Not every message queue implementation supports an error handler. |
@@ -406,6 +506,91 @@ handle_attribute_store_response (void *cls, | |||
406 | 506 | ||
407 | } | 507 | } |
408 | 508 | ||
509 | /** | ||
510 | * Handle an incoming message of type | ||
511 | * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT | ||
512 | * | ||
513 | * @param cls | ||
514 | * @param msg the message we received | ||
515 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on error | ||
516 | */ | ||
517 | static int | ||
518 | check_attribute_result (void *cls, | ||
519 | const struct AttributeResultMessage *msg) | ||
520 | { | ||
521 | size_t msg_len; | ||
522 | size_t attr_len; | ||
523 | |||
524 | msg_len = ntohs (msg->header.size); | ||
525 | attr_len = ntohs (msg->attr_len); | ||
526 | if (msg_len != sizeof (struct AttributeResultMessage) + attr_len) | ||
527 | { | ||
528 | GNUNET_break (0); | ||
529 | return GNUNET_SYSERR; | ||
530 | } | ||
531 | return GNUNET_OK; | ||
532 | } | ||
533 | |||
534 | |||
535 | /** | ||
536 | * Handle an incoming message of type | ||
537 | * #GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT | ||
538 | * | ||
539 | * @param cls | ||
540 | * @param msg the message we received | ||
541 | */ | ||
542 | static void | ||
543 | handle_attribute_result (void *cls, | ||
544 | const struct AttributeResultMessage *msg) | ||
545 | { | ||
546 | static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy; | ||
547 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls; | ||
548 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it; | ||
549 | size_t attr_len; | ||
550 | uint32_t r_id = ntohl (msg->id); | ||
551 | |||
552 | attr_len = ntohs (msg->attr_len); | ||
553 | |||
554 | for (it = h->it_head; NULL != it; it = it->next) | ||
555 | if (it->r_id == r_id) | ||
556 | break; | ||
557 | if (NULL == it) | ||
558 | return; | ||
559 | |||
560 | if ( (0 == (memcmp (&msg->identity, | ||
561 | &identity_dummy, | ||
562 | sizeof (identity_dummy)))) ) | ||
563 | { | ||
564 | if (NULL == it) | ||
565 | { | ||
566 | GNUNET_break (0); | ||
567 | force_reconnect (h); | ||
568 | return; | ||
569 | } | ||
570 | if (NULL != it->finish_cb) | ||
571 | it->finish_cb (it->finish_cb_cls); | ||
572 | free_it (it); | ||
573 | return; | ||
574 | } | ||
575 | |||
576 | { | ||
577 | struct GNUNET_IDENTITY_PROVIDER_Attribute *attr; | ||
578 | attr = attribute_deserialize ((char*)&msg[1], | ||
579 | attr_len); | ||
580 | if (NULL != it) | ||
581 | { | ||
582 | if (NULL != it->proc) | ||
583 | it->proc (it->proc_cls, | ||
584 | &msg->identity, | ||
585 | attr); | ||
586 | GNUNET_free (attr); | ||
587 | return; | ||
588 | } | ||
589 | } | ||
590 | GNUNET_assert (0); | ||
591 | } | ||
592 | |||
593 | |||
409 | 594 | ||
410 | /** | 595 | /** |
411 | * Try again to connect to the service. | 596 | * Try again to connect to the service. |
@@ -428,7 +613,10 @@ reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h) | |||
428 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT, | 613 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT, |
429 | struct ExchangeResultMessage, | 614 | struct ExchangeResultMessage, |
430 | h), | 615 | h), |
431 | 616 | GNUNET_MQ_hd_var_size (attribute_result, | |
617 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_RESULT, | ||
618 | struct AttributeResultMessage, | ||
619 | h), | ||
432 | GNUNET_MQ_handler_end () | 620 | GNUNET_MQ_handler_end () |
433 | }; | 621 | }; |
434 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | 622 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; |
@@ -717,24 +905,14 @@ GNUNET_IDENTITY_PROVIDER_ticket_destroy(struct GNUNET_IDENTITY_PROVIDER_Ticket * | |||
717 | struct GNUNET_IDENTITY_PROVIDER_Operation * | 905 | struct GNUNET_IDENTITY_PROVIDER_Operation * |
718 | GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h, | 906 | GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h, |
719 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, | 907 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, |
720 | const char* name, | 908 | const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr, |
721 | const struct GNUNET_IDENTITY_PROVIDER_Attribute *value, | ||
722 | GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cont, | 909 | GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cont, |
723 | void *cont_cls) | 910 | void *cont_cls) |
724 | { | 911 | { |
725 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; | 912 | struct GNUNET_IDENTITY_PROVIDER_Operation *op; |
726 | struct AttributeStoreMessage *sam; | 913 | struct AttributeStoreMessage *sam; |
727 | size_t name_len; | 914 | size_t attr_len; |
728 | char *name_tmp; | ||
729 | char *attr_ser; | ||
730 | 915 | ||
731 | |||
732 | name_len = strlen (name) + 1; | ||
733 | if (name_len >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct AttributeStoreMessage)) | ||
734 | { | ||
735 | GNUNET_break (0); | ||
736 | return NULL; | ||
737 | } | ||
738 | op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation); | 916 | op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation); |
739 | op->h = h; | 917 | op->h = h; |
740 | op->as_cb = cont; | 918 | op->as_cb = cont; |
@@ -743,17 +921,17 @@ GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle | |||
743 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, | 921 | GNUNET_CONTAINER_DLL_insert_tail (h->op_head, |
744 | h->op_tail, | 922 | h->op_tail, |
745 | op); | 923 | op); |
924 | attr_len = attribute_serialize_get_size (attr); | ||
746 | op->env = GNUNET_MQ_msg_extra (sam, | 925 | op->env = GNUNET_MQ_msg_extra (sam, |
747 | name_len + value->data_size, | 926 | attr_len, |
748 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE); | 927 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE); |
749 | sam->identity = *pkey; | 928 | sam->identity = *pkey; |
750 | sam->id = htonl (op->r_id); | 929 | sam->id = htonl (op->r_id); |
751 | sam->attr_value_len = htons (value->data_size); | 930 | |
752 | sam->name_len = htons (name_len); | 931 | attribute_serialize (attr, |
753 | name_tmp = (char *) &sam[1]; | 932 | (char*)&sam[1]); |
754 | GNUNET_memcpy (name_tmp, name, name_len); | 933 | |
755 | attr_ser = &name_tmp[name_len]; | 934 | sam->attr_len = htons (attr_len); |
756 | GNUNET_memcpy (attr_ser, value->data, value->data_size); | ||
757 | if (NULL != h->mq) | 935 | if (NULL != h->mq) |
758 | GNUNET_MQ_send_copy (h->mq, | 936 | GNUNET_MQ_send_copy (h->mq, |
759 | op->env); | 937 | op->env); |
@@ -762,7 +940,139 @@ GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle | |||
762 | } | 940 | } |
763 | 941 | ||
764 | 942 | ||
943 | /** | ||
944 | * Create a new attribute. | ||
945 | * | ||
946 | * @param name the attribute name | ||
947 | * @param type the attribute type | ||
948 | * @param data the attribute value | ||
949 | * @param data_size the attribute value size | ||
950 | * @return the new attribute | ||
951 | */ | ||
952 | struct GNUNET_IDENTITY_PROVIDER_Attribute * | ||
953 | GNUNET_IDENTITY_PROVIDER_attribute_new (const char* attr_name, | ||
954 | uint32_t attr_type, | ||
955 | const void* data, | ||
956 | size_t data_size) | ||
957 | { | ||
958 | return attribute_new (attr_name, attr_type, data, data_size); | ||
959 | } | ||
960 | |||
961 | /** | ||
962 | * List all attributes for a local identity. | ||
963 | * This MUST lock the `struct GNUNET_IDENTITY_PROVIDER_Handle` | ||
964 | * for any other calls than #GNUNET_IDENTITY_PROVIDER_get_attributes_next() and | ||
965 | * #GNUNET_IDENTITY_PROVIDER_get_attributes_stop. @a proc will be called once | ||
966 | * immediately, and then again after | ||
967 | * #GNUNET_IDENTITY_PROVIDER_get_attributes_next() is invoked. | ||
968 | * | ||
969 | * On error (disconnect), @a error_cb will be invoked. | ||
970 | * On normal completion, @a finish_cb proc will be | ||
971 | * invoked. | ||
972 | * | ||
973 | * @param h handle to the idp | ||
974 | * @param identity identity to access | ||
975 | * @param error_cb function to call on error (i.e. disconnect), | ||
976 | * the handle is afterwards invalid | ||
977 | * @param error_cb_cls closure for @a error_cb | ||
978 | * @param proc function to call on each attribute; it | ||
979 | * will be called repeatedly with a value (if available) | ||
980 | * @param proc_cls closure for @a proc | ||
981 | * @param finish_cb function to call on completion | ||
982 | * the handle is afterwards invalid | ||
983 | * @param finish_cb_cls closure for @a finish_cb | ||
984 | * @return an iterator handle to use for iteration | ||
985 | */ | ||
986 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator * | ||
987 | GNUNET_IDENTITY_PROVIDER_get_attributes_start (struct GNUNET_IDENTITY_PROVIDER_Handle *h, | ||
988 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, | ||
989 | GNUNET_SCHEDULER_TaskCallback error_cb, | ||
990 | void *error_cb_cls, | ||
991 | GNUNET_IDENTITY_PROVIDER_AttributeResult proc, | ||
992 | void *proc_cls, | ||
993 | GNUNET_SCHEDULER_TaskCallback finish_cb, | ||
994 | void *finish_cb_cls) | ||
995 | { | ||
996 | struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it; | ||
997 | struct GNUNET_MQ_Envelope *env; | ||
998 | struct AttributeIterationStartMessage *msg; | ||
999 | uint32_t rid; | ||
1000 | |||
1001 | rid = h->r_id_gen++; | ||
1002 | it = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator); | ||
1003 | it->h = h; | ||
1004 | it->error_cb = error_cb; | ||
1005 | it->error_cb_cls = error_cb_cls; | ||
1006 | it->finish_cb = finish_cb; | ||
1007 | it->finish_cb_cls = finish_cb_cls; | ||
1008 | it->proc = proc; | ||
1009 | it->proc_cls = proc_cls; | ||
1010 | it->r_id = rid; | ||
1011 | it->identity = *identity; | ||
1012 | GNUNET_CONTAINER_DLL_insert_tail (h->it_head, | ||
1013 | h->it_tail, | ||
1014 | it); | ||
1015 | env = GNUNET_MQ_msg (msg, | ||
1016 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_START); | ||
1017 | msg->id = htonl (rid); | ||
1018 | msg->identity = *identity; | ||
1019 | if (NULL == h->mq) | ||
1020 | it->env = env; | ||
1021 | else | ||
1022 | GNUNET_MQ_send (h->mq, | ||
1023 | env); | ||
1024 | return it; | ||
1025 | } | ||
1026 | |||
1027 | |||
1028 | /** | ||
1029 | * Calls the record processor specified in #GNUNET_IDENTITY_PROVIDER_get_attributes_start | ||
1030 | * for the next record. | ||
1031 | * | ||
1032 | * @param it the iterator | ||
1033 | */ | ||
1034 | void | ||
1035 | GNUNET_IDENTITY_PROVIDER_get_attributes_next (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it) | ||
1036 | { | ||
1037 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h; | ||
1038 | struct AttributeIterationNextMessage *msg; | ||
1039 | struct GNUNET_MQ_Envelope *env; | ||
1040 | |||
1041 | env = GNUNET_MQ_msg (msg, | ||
1042 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_NEXT); | ||
1043 | msg->id = htonl (it->r_id); | ||
1044 | GNUNET_MQ_send (h->mq, | ||
1045 | env); | ||
1046 | } | ||
1047 | |||
1048 | |||
1049 | /** | ||
1050 | * Stops iteration and releases the idp handle for further calls. Must | ||
1051 | * be called on any iteration that has not yet completed prior to calling | ||
1052 | * #GNUNET_IDENTITY_PROVIDER_disconnect. | ||
1053 | * | ||
1054 | * @param it the iterator | ||
1055 | */ | ||
1056 | void | ||
1057 | GNUNET_IDENTITY_PROVIDER_get_attributes_stop (struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *it) | ||
1058 | { | ||
1059 | struct GNUNET_IDENTITY_PROVIDER_Handle *h = it->h; | ||
1060 | struct GNUNET_MQ_Envelope *env; | ||
1061 | struct AttributeIterationStopMessage *msg; | ||
1062 | |||
1063 | if (NULL != h->mq) | ||
1064 | { | ||
1065 | env = GNUNET_MQ_msg (msg, | ||
1066 | GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_ITERATION_STOP); | ||
1067 | msg->id = htonl (it->r_id); | ||
1068 | GNUNET_MQ_send (h->mq, | ||
1069 | env); | ||
1070 | } | ||
1071 | free_it (it); | ||
1072 | } | ||
1073 | |||
1074 | |||
765 | 1075 | ||
766 | 1076 | ||
767 | 1077 | ||
768 | /* end of identity_provider_api.c */ | 1078 | /* end of identity_provider_api.c */ |