aboutsummaryrefslogtreecommitdiff
path: root/src/identity-provider/identity_provider_api.c
diff options
context:
space:
mode:
authorSchanzenbach, Martin <mschanzenbach@posteo.de>2017-09-16 22:39:15 +0200
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2017-09-16 22:39:15 +0200
commit67e0d73709ef557b52ba0527291d68c17fd6c60a (patch)
tree57dcf9848b436c01c3fc37e3d878445aaf142a4e /src/identity-provider/identity_provider_api.c
parentd5ec12fdbc288f376ee2ee18aceb00e338191f28 (diff)
downloadgnunet-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.c352
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 */
103struct 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 */
289static void
290free_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 */
517static int
518check_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 */
542static void
543handle_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 *
717struct GNUNET_IDENTITY_PROVIDER_Operation * 905struct GNUNET_IDENTITY_PROVIDER_Operation *
718GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h, 906GNUNET_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 */
952struct GNUNET_IDENTITY_PROVIDER_Attribute *
953GNUNET_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 */
986struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *
987GNUNET_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 */
1034void
1035GNUNET_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 */
1056void
1057GNUNET_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 */