aboutsummaryrefslogtreecommitdiff
path: root/src/credential/credential_api.c
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2016-11-10 20:35:04 +0100
committerMartin Schanzenbach <mschanzenbach@posteo.de>2016-11-10 20:45:55 +0100
commit39981eee3163a1795026e8670ac5b669426f268b (patch)
tree8807df6deb2ed969ec951f77927b1b27d139d17f /src/credential/credential_api.c
parent60585eacf2735c86b40effaed8614eff2643d6f9 (diff)
downloadgnunet-39981eee3163a1795026e8670ac5b669426f268b.tar.gz
gnunet-39981eee3163a1795026e8670ac5b669426f268b.zip
add credential
Diffstat (limited to 'src/credential/credential_api.c')
-rw-r--r--src/credential/credential_api.c410
1 files changed, 410 insertions, 0 deletions
diff --git a/src/credential/credential_api.c b/src/credential/credential_api.c
new file mode 100644
index 000000000..1efe2d089
--- /dev/null
+++ b/src/credential/credential_api.c
@@ -0,0 +1,410 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013, 2016 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file credential/credential_api.c
22 * @brief library to access the CREDENTIAL service
23 * @author Adnan Husain
24 */
25#include "platform.h"
26#include "gnunet_util_lib.h"
27#include "gnunet_constants.h"
28#include "gnunet_arm_service.h"
29#include "gnunet_hello_lib.h"
30#include "gnunet_protocols.h"
31#include "credential.h"
32#include "gnunet_credential_service.h"
33#include "gnunet_identity_service.h"
34
35
36#define LOG(kind,...) GNUNET_log_from (kind, "credential-api",__VA_ARGS__)
37
38/**
39 * Handle to a lookup request
40 */
41struct GNUNET_CREDENTIAL_LookupRequest
42{
43
44 /**
45 * DLL
46 */
47 struct GNUNET_CREDENTIAL_LookupRequest *next;
48
49 /**
50 * DLL
51 */
52 struct GNUNET_CREDENTIAL_LookupRequest *prev;
53
54 /**
55 * handle to credential service
56 */
57 struct GNUNET_CREDENTIAL_Handle *credential_handle;
58
59 /**
60 * processor to call on lookup result
61 */
62 GNUNET_CREDENTIAL_LookupResultProcessor lookup_proc;
63
64 /**
65 * @e lookup_proc closure
66 */
67 void *proc_cls;
68
69 /**
70 * Envelope with the message for this queue entry.
71 */
72 struct GNUNET_MQ_Envelope *env;
73
74 /**
75 * request id
76 */
77 uint32_t r_id;
78
79};
80
81
82/**
83 * Connection to the CREDENTIAL service.
84 */
85struct GNUNET_CREDENTIAL_Handle
86{
87
88 /**
89 * Configuration to use.
90 */
91 const struct GNUNET_CONFIGURATION_Handle *cfg;
92
93 /**
94 * Connection to service (if available).
95 */
96 struct GNUNET_MQ_Handle *mq;
97
98 /**
99 * Head of linked list of active lookup requests.
100 */
101 struct GNUNET_CREDENTIAL_LookupRequest *lookup_head;
102
103 /**
104 * Tail of linked list of active lookup requests.
105 */
106 struct GNUNET_CREDENTIAL_LookupRequest *lookup_tail;
107
108 /**
109 * Reconnect task
110 */
111 struct GNUNET_SCHEDULER_Task *reconnect_task;
112
113 /**
114 * How long do we wait until we try to reconnect?
115 */
116 struct GNUNET_TIME_Relative reconnect_backoff;
117
118 /**
119 * Request Id generator. Incremented by one for each request.
120 */
121 uint32_t r_id_gen;
122
123};
124
125
126/**
127 * Reconnect to CREDENTIAL service.
128 *
129 * @param handle the handle to the CREDENTIAL service
130 */
131static void
132reconnect (struct GNUNET_CREDENTIAL_Handle *handle);
133
134
135/**
136 * Reconnect to CREDENTIAL
137 *
138 * @param cls the handle
139 */
140static void
141reconnect_task (void *cls)
142{
143 struct GNUNET_CREDENTIAL_Handle *handle = cls;
144
145 handle->reconnect_task = NULL;
146 reconnect (handle);
147}
148
149
150/**
151 * Disconnect from service and then reconnect.
152 *
153 * @param handle our handle
154 */
155static void
156force_reconnect (struct GNUNET_CREDENTIAL_Handle *handle)
157{
158 GNUNET_MQ_destroy (handle->mq);
159 handle->mq = NULL;
160 handle->reconnect_backoff
161 = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
162 handle->reconnect_task
163 = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
164 &reconnect_task,
165 handle);
166}
167
168
169/**
170 * Generic error handler, called with the appropriate error code and
171 * the same closure specified at the creation of the message queue.
172 * Not every message queue implementation supports an error handler.
173 *
174 * @param cls closure with the `struct GNUNET_CREDENTIAL_Handle *`
175 * @param error error code
176 */
177static void
178mq_error_handler (void *cls,
179 enum GNUNET_MQ_Error error)
180{
181 struct GNUNET_CREDENTIAL_Handle *handle = cls;
182
183 force_reconnect (handle);
184}
185
186
187/**
188 * Check validity of message received from the CREDENTIAL service
189 *
190 * @param cls the `struct GNUNET_CREDENTIAL_Handle *`
191 * @param loookup_msg the incoming message
192 */
193static int
194check_result (void *cls,
195 const struct LookupResultMessage *lookup_msg)
196{
197 //TODO
198 return GNUNET_OK;
199}
200
201
202/**
203 * Handler for messages received from the CREDENTIAL service
204 *
205 * @param cls the `struct GNUNET_CREDENTIAL_Handle *`
206 * @param loookup_msg the incoming message
207 */
208static void
209handle_result (void *cls,
210 const struct LookupResultMessage *lookup_msg)
211{
212 struct GNUNET_CREDENTIAL_Handle *handle = cls;
213 uint32_t cd_count = ntohl (lookup_msg->cd_count);
214 struct GNUNET_CREDENTIAL_RecordData cd[cd_count];
215 uint32_t r_id = ntohl (lookup_msg->id);
216 struct GNUNET_CREDENTIAL_LookupRequest *lr;
217 GNUNET_CREDENTIAL_LookupResultProcessor proc;
218 void *proc_cls;
219
220 LOG (GNUNET_ERROR_TYPE_DEBUG,
221 "Received lookup reply from CREDENTIAL service (%u credentials)\n",
222 (unsigned int) cd_count);
223 for (lr = handle->lookup_head; NULL != lr; lr = lr->next)
224 if (lr->r_id == r_id)
225 break;
226 if (NULL == lr)
227 return;
228 proc = lr->lookup_proc;
229 proc_cls = lr->proc_cls;
230 GNUNET_CONTAINER_DLL_remove (handle->lookup_head,
231 handle->lookup_tail,
232 lr);
233 GNUNET_free (lr);
234 /**
235 GNUNET_assert (GNUNET_OK ==
236 GNUNET_CREDENTIAL_records_deserialize (mlen,
237 (const char*) &lookup_msg[1],
238 rd_count,
239 rd));
240 */
241 proc (proc_cls,
242 NULL,
243 cd_count,
244 cd); // TODO
245}
246
247
248/**
249 * Reconnect to CREDENTIAL service.
250 *
251 * @param handle the handle to the CREDENTIAL service
252 */
253static void
254reconnect (struct GNUNET_CREDENTIAL_Handle *handle)
255{
256 struct GNUNET_MQ_MessageHandler handlers[] = {
257 GNUNET_MQ_hd_var_size (result,
258 GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP_RESULT,
259 struct LookupResultMessage,
260 NULL),
261 GNUNET_MQ_handler_end ()
262 };
263 struct GNUNET_CREDENTIAL_LookupRequest *lh;
264
265 GNUNET_assert (NULL == handle->mq);
266 LOG (GNUNET_ERROR_TYPE_DEBUG,
267 "Trying to connect to CREDENTIAL\n");
268 handle->mq = GNUNET_CLIENT_connecT (handle->cfg,
269 "credential",
270 handlers,
271 &mq_error_handler,
272 handle);
273 if (NULL == handle->mq)
274 return;
275 for (lh = handle->lookup_head; NULL != lh; lh = lh->next)
276 GNUNET_MQ_send_copy (handle->mq,
277 lh->env);
278}
279
280
281/**
282 * Initialize the connection with the CREDENTIAL service.
283 *
284 * @param cfg configuration to use
285 * @return handle to the CREDENTIAL service, or NULL on error
286 */
287struct GNUNET_CREDENTIAL_Handle *
288GNUNET_CREDENTIAL_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
289{
290 struct GNUNET_CREDENTIAL_Handle *handle;
291
292 handle = GNUNET_new (struct GNUNET_CREDENTIAL_Handle);
293 handle->cfg = cfg;
294 reconnect (handle);
295 if (NULL == handle->mq)
296 {
297 GNUNET_free (handle);
298 return NULL;
299 }
300 return handle;
301}
302
303
304/**
305 * Shutdown connection with the CREDENTIAL service.
306 *
307 * @param handle handle of the CREDENTIAL connection to stop
308 */
309void
310GNUNET_CREDENTIAL_disconnect (struct GNUNET_CREDENTIAL_Handle *handle)
311{
312 if (NULL != handle->mq)
313 {
314 GNUNET_MQ_destroy (handle->mq);
315 handle->mq = NULL;
316 }
317 if (NULL != handle->reconnect_task)
318 {
319 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
320 handle->reconnect_task = NULL;
321 }
322 GNUNET_assert (NULL == handle->lookup_head);
323 GNUNET_free (handle);
324}
325
326
327/**
328 * Cancel pending lookup request
329 *
330 * @param lr the lookup request to cancel
331 */
332void
333GNUNET_CREDENTIAL_lookup_cancel (struct GNUNET_CREDENTIAL_LookupRequest *lr)
334{
335 struct GNUNET_CREDENTIAL_Handle *handle = lr->credential_handle;
336
337 GNUNET_CONTAINER_DLL_remove (handle->lookup_head,
338 handle->lookup_tail,
339 lr);
340 GNUNET_MQ_discard (lr->env);
341 GNUNET_free (lr);
342}
343
344
345/**
346 * Perform an asynchronous lookup operation for a credential.
347 *
348 * @param handle handle to the Credential service
349 * @param credential the credential to look up
350 * @param subject Ego to check the credential for
351 * @param proc function to call on result
352 * @param proc_cls closure for processor
353 * @return handle to the queued request
354 */
355struct GNUNET_CREDENTIAL_LookupRequest*
356GNUNET_CREDENTIAL_lookup (struct GNUNET_CREDENTIAL_Handle *handle,
357 const char *credential,
358 const struct GNUNET_IDENTITY_Ego *subject,
359 const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key,
360 const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key,
361 uint32_t credential_flags,
362 uint32_t max_delegation_depth,
363 GNUNET_CREDENTIAL_LookupResultProcessor proc,
364 void *proc_cls)
365{
366 /* IPC to shorten credential names, return shorten_handle */
367 struct LookupMessage *lookup_msg;
368 struct GNUNET_CREDENTIAL_LookupRequest *lr;
369 size_t nlen;
370
371 if (NULL == credential)
372 {
373 GNUNET_break (0);
374 return NULL;
375 }
376 //DEBUG LOG
377 LOG (GNUNET_ERROR_TYPE_DEBUG,
378 "Trying to lookup `%s' in CREDENTIAL\n",
379 credential);
380 nlen = strlen (credential) + 1;
381 if (nlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*lr))
382 {
383 GNUNET_break (0);
384 return NULL;
385 }
386 lr = GNUNET_new (struct GNUNET_CREDENTIAL_LookupRequest);
387 lr->credential_handle = handle;
388 lr->lookup_proc = proc;
389 lr->proc_cls = proc_cls;
390 lr->r_id = handle->r_id_gen++;
391 lr->env = GNUNET_MQ_msg_extra (lookup_msg,
392 nlen,
393 GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP);
394 lookup_msg->id = htonl (lr->r_id);
395 lookup_msg->subject_key = *subject_key;
396 lookup_msg->issuer_key = *issuer_key;
397 GNUNET_memcpy (&lookup_msg[1],
398 credential,
399 nlen);
400 GNUNET_CONTAINER_DLL_insert (handle->lookup_head,
401 handle->lookup_tail,
402 lr);
403 if (NULL != handle->mq)
404 GNUNET_MQ_send_copy (handle->mq,
405 lr->env);
406 return lr;
407}
408
409
410/* end of credential_api.c */