diff options
author | jospaeth <spaethj@in.tum.de> | 2020-09-06 15:04:50 +0200 |
---|---|---|
committer | jospaeth <spaethj@in.tum.de> | 2020-09-06 15:04:50 +0200 |
commit | 03b7dd8d216b6d14cf0abd66b23f01b2ea94fab1 (patch) | |
tree | 1df4db57e573ba300add2d5af8f804c444342268 | |
parent | f05dbd1b35316d10629247f7c0398f8ec2c70d93 (diff) | |
download | gnunet-03b7dd8d216b6d14cf0abd66b23f01b2ea94fab1.tar.gz gnunet-03b7dd8d216b6d14cf0abd66b23f01b2ea94fab1.zip |
add escrow REST plugin
-rw-r--r-- | src/escrow/Makefile.am | 17 | ||||
-rw-r--r-- | src/escrow/escrow.h | 2 | ||||
-rw-r--r-- | src/escrow/gnunet-escrow.c | 2 | ||||
-rw-r--r-- | src/escrow/plugin_escrow_gns.c | 2 | ||||
-rw-r--r-- | src/escrow/plugin_escrow_plaintext.c | 2 | ||||
-rw-r--r-- | src/escrow/plugin_rest_escrow.c | 1252 | ||||
-rw-r--r-- | src/include/gnunet_escrow_lib.h | 4 |
7 files changed, 1274 insertions, 7 deletions
diff --git a/src/escrow/Makefile.am b/src/escrow/Makefile.am index 70dbfc2e9..36bb027ab 100644 --- a/src/escrow/Makefile.am +++ b/src/escrow/Makefile.am | |||
@@ -26,11 +26,26 @@ plugin_LTLIBRARIES = \ | |||
26 | libgnunet_plugin_escrow_plaintext.la \ | 26 | libgnunet_plugin_escrow_plaintext.la \ |
27 | libgnunet_plugin_escrow_gns.la \ | 27 | libgnunet_plugin_escrow_gns.la \ |
28 | libgnunet_plugin_escrow_anastasis.la \ | 28 | libgnunet_plugin_escrow_anastasis.la \ |
29 | libgnunet_plugin_gnsrecord_escrow.la | 29 | libgnunet_plugin_gnsrecord_escrow.la \ |
30 | libgnunet_plugin_rest_escrow.la | ||
30 | 31 | ||
31 | bin_PROGRAMS = \ | 32 | bin_PROGRAMS = \ |
32 | gnunet-escrow | 33 | gnunet-escrow |
33 | 34 | ||
35 | |||
36 | libgnunet_plugin_rest_escrow_la_SOURCES = \ | ||
37 | plugin_rest_escrow.c | ||
38 | libgnunet_plugin_rest_escrow_la_LIBADD = \ | ||
39 | libgnunetescrow.la \ | ||
40 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
41 | $(top_builddir)/src/rest/libgnunetrest.la \ | ||
42 | $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ | ||
43 | $(LTLIBINTL) -ljansson $(MHD_LIBS) | ||
44 | libgnunet_plugin_rest_escrow_la_LDFLAGS = \ | ||
45 | $(GN_PLUGIN_LDFLAGS) | ||
46 | libgnunet_plugin_rest_escrow_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS) | ||
47 | |||
48 | |||
34 | libgnunetescrow_la_SOURCES = \ | 49 | libgnunetescrow_la_SOURCES = \ |
35 | escrow_api.c \ | 50 | escrow_api.c \ |
36 | escrow.h | 51 | escrow.h |
diff --git a/src/escrow/escrow.h b/src/escrow/escrow.h index a9e6e99e1..8fc9123c1 100644 --- a/src/escrow/escrow.h +++ b/src/escrow/escrow.h | |||
@@ -203,7 +203,7 @@ struct ESCROW_Plugin_EgoContinuationWrapper | |||
203 | /** | 203 | /** |
204 | * The restored ego | 204 | * The restored ego |
205 | */ | 205 | */ |
206 | const struct GNUNET_IDENTITY_Ego *ego; | 206 | struct GNUNET_IDENTITY_Ego *ego; |
207 | 207 | ||
208 | /** | 208 | /** |
209 | * The unique ID of the respective ESCROW_Operation | 209 | * The unique ID of the respective ESCROW_Operation |
diff --git a/src/escrow/gnunet-escrow.c b/src/escrow/gnunet-escrow.c index 9fa219d2f..c3ca3aa9e 100644 --- a/src/escrow/gnunet-escrow.c +++ b/src/escrow/gnunet-escrow.c | |||
@@ -235,7 +235,7 @@ verify_cb (void *cls, | |||
235 | 235 | ||
236 | static void | 236 | static void |
237 | get_cb (void *cls, | 237 | get_cb (void *cls, |
238 | const struct GNUNET_IDENTITY_Ego *ego, | 238 | struct GNUNET_IDENTITY_Ego *ego, |
239 | const char *emsg) | 239 | const char *emsg) |
240 | { | 240 | { |
241 | escrow_op = NULL; | 241 | escrow_op = NULL; |
diff --git a/src/escrow/plugin_escrow_gns.c b/src/escrow/plugin_escrow_gns.c index 96a7252ec..908c7bb44 100644 --- a/src/escrow/plugin_escrow_gns.c +++ b/src/escrow/plugin_escrow_gns.c | |||
@@ -1507,7 +1507,7 @@ verify_gns_key_escrow (struct GNUNET_ESCROW_Handle *h, | |||
1507 | 1507 | ||
1508 | 1508 | ||
1509 | void | 1509 | void |
1510 | ego_created (const struct GNUNET_IDENTITY_Ego *ego) | 1510 | ego_created (struct GNUNET_IDENTITY_Ego *ego) |
1511 | { | 1511 | { |
1512 | struct ESCROW_PluginOperationWrapper *curr; | 1512 | struct ESCROW_PluginOperationWrapper *curr; |
1513 | struct ESCROW_GnsPluginOperation *curr_p_op; | 1513 | struct ESCROW_GnsPluginOperation *curr_p_op; |
diff --git a/src/escrow/plugin_escrow_plaintext.c b/src/escrow/plugin_escrow_plaintext.c index 41523a906..39f605262 100644 --- a/src/escrow/plugin_escrow_plaintext.c +++ b/src/escrow/plugin_escrow_plaintext.c | |||
@@ -291,7 +291,7 @@ verify_plaintext_key_escrow (struct GNUNET_ESCROW_Handle *h, | |||
291 | 291 | ||
292 | 292 | ||
293 | static void | 293 | static void |
294 | ego_created (const struct GNUNET_IDENTITY_Ego *ego) | 294 | ego_created (struct GNUNET_IDENTITY_Ego *ego) |
295 | { | 295 | { |
296 | struct ESCROW_PluginOperationWrapper *curr; | 296 | struct ESCROW_PluginOperationWrapper *curr; |
297 | struct ESCROW_PlaintextPluginOperation *curr_p_op; | 297 | struct ESCROW_PlaintextPluginOperation *curr_p_op; |
diff --git a/src/escrow/plugin_rest_escrow.c b/src/escrow/plugin_rest_escrow.c new file mode 100644 index 000000000..12d48faf5 --- /dev/null +++ b/src/escrow/plugin_rest_escrow.c | |||
@@ -0,0 +1,1252 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your 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 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | /** | ||
21 | * @author Johannes Späth | ||
22 | * @file escrow/plugin_rest_escrow.c | ||
23 | * @brief GNUnet Escrow REST plugin | ||
24 | */ | ||
25 | |||
26 | #include "platform.h" | ||
27 | #include "gnunet_rest_plugin.h" | ||
28 | #include "gnunet_escrow_lib.h" | ||
29 | #include "gnunet_identity_service.h" | ||
30 | #include "gnunet_rest_lib.h" | ||
31 | #include "microhttpd.h" | ||
32 | #include <jansson.h> | ||
33 | |||
34 | /** | ||
35 | * Escrow Namespace | ||
36 | */ | ||
37 | #define GNUNET_REST_API_NS_ESCROW "/escrow" | ||
38 | |||
39 | /** | ||
40 | * Escrow Put Namespace | ||
41 | */ | ||
42 | #define GNUNET_REST_API_NS_ESCROW_PUT "/escrow/put" | ||
43 | |||
44 | /** | ||
45 | * Escrow Get Namespace | ||
46 | */ | ||
47 | #define GNUNET_REST_API_NS_ESCROW_GET "/escrow/get" | ||
48 | |||
49 | /** | ||
50 | * Escrow Verify Namespace | ||
51 | */ | ||
52 | #define GNUNET_REST_API_NS_ESCROW_VERIFY "/escrow/verify" | ||
53 | |||
54 | /** | ||
55 | * Escrow Status Namespace | ||
56 | */ | ||
57 | #define GNUNET_REST_API_NS_ESCROW_STATUS "/escrow/status" | ||
58 | |||
59 | /** | ||
60 | * Error message Unknown Error | ||
61 | */ | ||
62 | #define GNUNET_REST_ESCROW_ERROR_UNKNOWN "Unknown Error" | ||
63 | |||
64 | /** | ||
65 | * Error message Missing identity name | ||
66 | */ | ||
67 | #define GNUNET_REST_ESCROW_MISSING_NAME "Missing identity name" | ||
68 | |||
69 | /** | ||
70 | * Error message Missing escrow anchor | ||
71 | */ | ||
72 | #define GNUNET_REST_ESCROW_MISSING_ANCHOR "Missing escrow anchor" | ||
73 | |||
74 | /** | ||
75 | * Error message Identity not found | ||
76 | */ | ||
77 | #define GNUNET_REST_ESCROW_ID_NOT_FOUND "Identity not found" | ||
78 | |||
79 | /** | ||
80 | * Error message Method not found | ||
81 | */ | ||
82 | #define GNUNET_REST_ESCROW_METHOD_NOT_FOUND "Method not found" | ||
83 | |||
84 | /** | ||
85 | * Error message Escrow failed | ||
86 | */ | ||
87 | #define GNUNET_REST_ESCROW_ESCROW_FAILED "Escrow failed" | ||
88 | |||
89 | /** | ||
90 | * Error message Restoration failed | ||
91 | */ | ||
92 | #define GNUNET_REST_ESCROW_RESTORE_FAILED "Restoration failed" | ||
93 | |||
94 | /** | ||
95 | * Error message Got invalid status | ||
96 | */ | ||
97 | #define GNUNET_REST_ESCROW_INVALID_STATUS "Got invalid status" | ||
98 | |||
99 | /** | ||
100 | * Error message No data | ||
101 | */ | ||
102 | #define GNUNET_REST_ERROR_NO_DATA "No data" | ||
103 | |||
104 | /** | ||
105 | * Error message Data invalid | ||
106 | */ | ||
107 | #define GNUNET_REST_ERROR_DATA_INVALID "Data invalid" | ||
108 | |||
109 | /** | ||
110 | * Error message Failed to parse anchor | ||
111 | */ | ||
112 | #define GNUNET_REST_ESCROW_ANCHOR_ERROR "Failed to parse anchor" | ||
113 | |||
114 | /** | ||
115 | * Parameter anchor | ||
116 | */ | ||
117 | #define GNUNET_REST_ESCROW_PARAM_ANCHOR "anchor" | ||
118 | |||
119 | /** | ||
120 | * Parameter user-secret | ||
121 | */ | ||
122 | #define GNUNET_REST_ESCROW_PARAM_USER_SECRET "user-secret" | ||
123 | |||
124 | /** | ||
125 | * Parameter pubkey | ||
126 | */ | ||
127 | #define GNUNET_REST_ESCROW_PARAM_PUBKEY "pubkey" | ||
128 | |||
129 | /** | ||
130 | * Parameter name | ||
131 | */ | ||
132 | #define GNUNET_REST_ESCROW_PARAM_NAME "name" | ||
133 | |||
134 | /** | ||
135 | * Parameter verification-result | ||
136 | */ | ||
137 | #define GNUNET_REST_ESCROW_PARAM_VERIFICATION_RESULT "verification-result" | ||
138 | |||
139 | /** | ||
140 | * Parameter last-method | ||
141 | */ | ||
142 | #define GNUNET_REST_ESCROW_PARAM_LAST_METHOD "last-method" | ||
143 | |||
144 | /** | ||
145 | * Parameter last-successful-verification | ||
146 | */ | ||
147 | #define GNUNET_REST_ESCROW_PARAM_LAST_VERIF "last-successful-verification" | ||
148 | |||
149 | /** | ||
150 | * Parameter next-recommended-verification | ||
151 | */ | ||
152 | #define GNUNET_REST_ESCROW_PARAM_NEXT_VERIF "next-recommended-verification" | ||
153 | |||
154 | /** | ||
155 | * State while collecting all egos | ||
156 | */ | ||
157 | #define ID_REST_STATE_INIT 0 | ||
158 | |||
159 | /** | ||
160 | * Done collecting egos | ||
161 | */ | ||
162 | #define ID_REST_STATE_POST_INIT 1 | ||
163 | |||
164 | /** | ||
165 | * The configuration handle | ||
166 | */ | ||
167 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
168 | |||
169 | /** | ||
170 | * HTTP methods allows for this plugin | ||
171 | */ | ||
172 | static char *allow_methods; | ||
173 | |||
174 | /** | ||
175 | * Ego list | ||
176 | */ | ||
177 | static struct EgoEntry *ego_head; | ||
178 | |||
179 | /** | ||
180 | * Ego list | ||
181 | */ | ||
182 | static struct EgoEntry *ego_tail; | ||
183 | |||
184 | /** | ||
185 | * The processing state | ||
186 | */ | ||
187 | static int state; | ||
188 | |||
189 | /** | ||
190 | * Handle to the identity service | ||
191 | */ | ||
192 | static struct GNUNET_IDENTITY_Handle *identity_handle; | ||
193 | |||
194 | /** | ||
195 | * Handle to the escrow component | ||
196 | */ | ||
197 | static struct GNUNET_ESCROW_Handle *escrow_handle; | ||
198 | |||
199 | /** | ||
200 | * @brief struct returned by the initialization function of the plugin | ||
201 | */ | ||
202 | struct Plugin | ||
203 | { | ||
204 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
205 | }; | ||
206 | |||
207 | /** | ||
208 | * The ego list | ||
209 | */ | ||
210 | struct EgoEntry | ||
211 | { | ||
212 | /** | ||
213 | * DLL | ||
214 | */ | ||
215 | struct EgoEntry *next; | ||
216 | |||
217 | /** | ||
218 | * DLL | ||
219 | */ | ||
220 | struct EgoEntry *prev; | ||
221 | |||
222 | /** | ||
223 | * Ego Identifier | ||
224 | */ | ||
225 | char *identifier; | ||
226 | |||
227 | /** | ||
228 | * Public key string | ||
229 | */ | ||
230 | char *keystring; | ||
231 | |||
232 | /** | ||
233 | * The Ego | ||
234 | */ | ||
235 | struct GNUNET_IDENTITY_Ego *ego; | ||
236 | }; | ||
237 | |||
238 | /** | ||
239 | * The request handle | ||
240 | */ | ||
241 | struct RequestHandle | ||
242 | { | ||
243 | /** | ||
244 | * DLL | ||
245 | */ | ||
246 | struct RequestHandle *next; | ||
247 | |||
248 | /** | ||
249 | * DLL | ||
250 | */ | ||
251 | struct RequestHandle *prev; | ||
252 | |||
253 | /** | ||
254 | * The data from the REST request | ||
255 | */ | ||
256 | const char *data; | ||
257 | |||
258 | /** | ||
259 | * The name to look up | ||
260 | */ | ||
261 | char *name; | ||
262 | |||
263 | /** | ||
264 | * the length of the REST data | ||
265 | */ | ||
266 | size_t data_size; | ||
267 | |||
268 | /** | ||
269 | * ESCROW Operation | ||
270 | */ | ||
271 | struct GNUNET_ESCROW_Operation *op; | ||
272 | |||
273 | /** | ||
274 | * Rest connection | ||
275 | */ | ||
276 | struct GNUNET_REST_RequestHandle *rest_handle; | ||
277 | |||
278 | /** | ||
279 | * Desired timeout for the lookup (default is no timeout). | ||
280 | */ | ||
281 | struct GNUNET_TIME_Relative timeout; | ||
282 | |||
283 | /** | ||
284 | * ID of a task associated with the resolution process. | ||
285 | */ | ||
286 | struct GNUNET_SCHEDULER_Task *timeout_task; | ||
287 | |||
288 | /** | ||
289 | * The plugin result processor | ||
290 | */ | ||
291 | GNUNET_REST_ResultProcessor proc; | ||
292 | |||
293 | /** | ||
294 | * The closure of the result processor | ||
295 | */ | ||
296 | void *proc_cls; | ||
297 | |||
298 | /** | ||
299 | * The url | ||
300 | */ | ||
301 | char *url; | ||
302 | |||
303 | /** | ||
304 | * Error response message | ||
305 | */ | ||
306 | char *emsg; | ||
307 | |||
308 | /** | ||
309 | * Response code | ||
310 | */ | ||
311 | int response_code; | ||
312 | |||
313 | /** | ||
314 | * Response object | ||
315 | */ | ||
316 | json_t *resp_object; | ||
317 | }; | ||
318 | |||
319 | /** | ||
320 | * DLL | ||
321 | */ | ||
322 | static struct RequestHandle *requests_head; | ||
323 | |||
324 | /** | ||
325 | * DLL | ||
326 | */ | ||
327 | static struct RequestHandle *requests_tail; | ||
328 | |||
329 | /** | ||
330 | * Cleanup lookup handle | ||
331 | * @param handle Handle to clean up | ||
332 | */ | ||
333 | static void | ||
334 | cleanup_handle (void *cls) | ||
335 | { | ||
336 | struct RequestHandle *handle = cls; | ||
337 | |||
338 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); | ||
339 | if (NULL != handle->timeout_task) | ||
340 | { | ||
341 | GNUNET_SCHEDULER_cancel (handle->timeout_task); | ||
342 | handle->timeout_task = NULL; | ||
343 | } | ||
344 | |||
345 | if (NULL != handle->url) | ||
346 | GNUNET_free (handle->url); | ||
347 | if (NULL != handle->emsg) | ||
348 | GNUNET_free (handle->emsg); | ||
349 | if (NULL != handle->name) | ||
350 | GNUNET_free (handle->name); | ||
351 | GNUNET_CONTAINER_DLL_remove (requests_head, | ||
352 | requests_tail, | ||
353 | handle); | ||
354 | GNUNET_free (handle); | ||
355 | } | ||
356 | |||
357 | |||
358 | /** | ||
359 | * Task run on errors. Reports an error and cleans up everything. | ||
360 | * | ||
361 | * @param cls the `struct RequestHandle` | ||
362 | */ | ||
363 | static void | ||
364 | do_error (void *cls) | ||
365 | { | ||
366 | struct RequestHandle *handle = cls; | ||
367 | struct MHD_Response *resp; | ||
368 | json_t *json_error = json_object (); | ||
369 | char *response; | ||
370 | |||
371 | if (NULL == handle->emsg) | ||
372 | handle->emsg = GNUNET_strdup (GNUNET_REST_ESCROW_ERROR_UNKNOWN); | ||
373 | |||
374 | json_object_set_new (json_error, "error", json_string (handle->emsg)); | ||
375 | |||
376 | if (0 == handle->response_code) | ||
377 | handle->response_code = MHD_HTTP_OK; | ||
378 | response = json_dumps (json_error, 0); | ||
379 | resp = GNUNET_REST_create_response (response); | ||
380 | MHD_add_response_header (resp, "Content-Type", "application/json"); | ||
381 | handle->proc (handle->proc_cls, resp, handle->response_code); | ||
382 | json_decref (json_error); | ||
383 | GNUNET_free (response); | ||
384 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
385 | } | ||
386 | |||
387 | |||
388 | static enum GNUNET_ESCROW_Key_Escrow_Method | ||
389 | determine_escrow_method (struct GNUNET_CONTAINER_MultiHashMap *url_param_map) | ||
390 | { | ||
391 | struct GNUNET_HashCode method_key; | ||
392 | char *method_string; | ||
393 | enum GNUNET_ESCROW_Key_Escrow_Method method; | ||
394 | |||
395 | GNUNET_CRYPTO_hash ("method", strlen ("method"), &method_key); | ||
396 | method_string = GNUNET_CONTAINER_multihashmap_get (url_param_map, | ||
397 | &method_key); | ||
398 | // default method is plaintext | ||
399 | if (NULL == method_string) | ||
400 | method = GNUNET_ESCROW_KEY_PLAINTEXT; | ||
401 | else | ||
402 | method = GNUNET_ESCROW_method_string_to_number (method_string); | ||
403 | |||
404 | return method; | ||
405 | } | ||
406 | |||
407 | |||
408 | static char * | ||
409 | get_user_secret_from_payload (struct RequestHandle *handle) | ||
410 | { | ||
411 | json_t *json_data; | ||
412 | json_error_t err; | ||
413 | char *user_secret, *user_secret_cpy; | ||
414 | int json_unpack_state; | ||
415 | char term_data[handle->data_size + 1]; | ||
416 | |||
417 | if (0 >= handle->data_size) | ||
418 | { | ||
419 | handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA); | ||
420 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
421 | return NULL; | ||
422 | } | ||
423 | |||
424 | term_data[handle->data_size] = '\0'; | ||
425 | GNUNET_memcpy (term_data, handle->data, handle->data_size); | ||
426 | json_data = json_loads (term_data, JSON_DECODE_ANY, &err); | ||
427 | if (NULL == json_data) | ||
428 | { | ||
429 | handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA); | ||
430 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
431 | json_decref (json_data); | ||
432 | return NULL; | ||
433 | } | ||
434 | |||
435 | json_unpack_state = 0; | ||
436 | json_unpack_state = | ||
437 | json_unpack (json_data, "{s:s}", | ||
438 | GNUNET_REST_ESCROW_PARAM_USER_SECRET, &user_secret); | ||
439 | if (0 != json_unpack_state) | ||
440 | { | ||
441 | handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_DATA_INVALID); | ||
442 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
443 | json_decref (json_data); | ||
444 | return NULL; | ||
445 | } | ||
446 | |||
447 | if (NULL == user_secret) | ||
448 | { | ||
449 | handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_DATA_INVALID); | ||
450 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
451 | json_decref (json_data); | ||
452 | return NULL; | ||
453 | } | ||
454 | if (0 >= strlen (user_secret)) | ||
455 | { | ||
456 | json_decref (json_data); | ||
457 | handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_DATA_INVALID); | ||
458 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
459 | return NULL; | ||
460 | } | ||
461 | |||
462 | user_secret_cpy = GNUNET_strdup (user_secret); | ||
463 | json_decref (json_data); | ||
464 | |||
465 | return user_secret_cpy; | ||
466 | } | ||
467 | |||
468 | |||
469 | static void | ||
470 | escrow_finished (void *cls, | ||
471 | struct GNUNET_ESCROW_Anchor *anchor, | ||
472 | const char *emsg) | ||
473 | { | ||
474 | struct RequestHandle *handle = cls; | ||
475 | struct MHD_Response *resp; | ||
476 | json_t *json_anchor; | ||
477 | char *anchor_string, *result_string; | ||
478 | |||
479 | if (NULL == anchor) | ||
480 | { | ||
481 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
482 | "Failed to escrow ego.\n"); | ||
483 | handle->response_code = MHD_HTTP_NO_CONTENT; | ||
484 | handle->emsg = GNUNET_strdup (GNUNET_REST_ESCROW_ESCROW_FAILED); | ||
485 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
486 | return; | ||
487 | } | ||
488 | |||
489 | anchor_string = GNUNET_ESCROW_anchor_data_to_string (anchor); | ||
490 | json_anchor = json_object (); | ||
491 | json_object_set_new (json_anchor, | ||
492 | GNUNET_REST_ESCROW_PARAM_ANCHOR, | ||
493 | json_string (anchor_string)); | ||
494 | |||
495 | result_string = json_dumps (json_anchor, 0); | ||
496 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_string); | ||
497 | resp = GNUNET_REST_create_response (result_string); | ||
498 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
499 | MHD_add_response_header (resp, "Content-Type", "application/json"); | ||
500 | |||
501 | json_decref (json_anchor); | ||
502 | GNUNET_free (result_string); | ||
503 | GNUNET_free (anchor_string); | ||
504 | |||
505 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
506 | } | ||
507 | |||
508 | |||
509 | /** | ||
510 | * Respond to PUT (start_escrow) request | ||
511 | * | ||
512 | * @param con_handle the connection handle | ||
513 | * @param url the url | ||
514 | * @param cls the RequestHandle | ||
515 | */ | ||
516 | static void | ||
517 | escrow_identity (struct GNUNET_REST_RequestHandle *con_handle, | ||
518 | const char *url, | ||
519 | void *cls) | ||
520 | { | ||
521 | struct RequestHandle *handle = cls; | ||
522 | struct EgoEntry *ego_entry; | ||
523 | char *identity, *userSecret; | ||
524 | enum GNUNET_ESCROW_Key_Escrow_Method method; | ||
525 | |||
526 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
527 | "Putting %s into escrow.\n", | ||
528 | handle->url); | ||
529 | |||
530 | if (strlen (GNUNET_REST_API_NS_ESCROW_PUT) >= strlen (handle->url)) | ||
531 | { | ||
532 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n"); | ||
533 | handle->response_code = MHD_HTTP_NOT_FOUND; | ||
534 | handle->emsg = GNUNET_strdup (GNUNET_REST_ESCROW_MISSING_NAME); | ||
535 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
536 | return; | ||
537 | } | ||
538 | identity = handle->url + strlen (GNUNET_REST_API_NS_ESCROW_PUT) + 1; | ||
539 | |||
540 | for (ego_entry = ego_head; NULL != ego_entry; | ||
541 | ego_entry = ego_entry->next) | ||
542 | if (0 == strcmp (identity, ego_entry->identifier)) | ||
543 | break; | ||
544 | |||
545 | if (NULL == ego_entry) | ||
546 | { | ||
547 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
548 | "Identity %s not found.\n", | ||
549 | identity); | ||
550 | handle->response_code = MHD_HTTP_NOT_FOUND; | ||
551 | handle->emsg = GNUNET_strdup (GNUNET_REST_ESCROW_ID_NOT_FOUND); | ||
552 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
553 | return; | ||
554 | } | ||
555 | |||
556 | /* determine method */ | ||
557 | method = determine_escrow_method (handle->rest_handle->url_param_map); | ||
558 | if (GNUNET_ESCROW_KEY_NONE == method) | ||
559 | { | ||
560 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
561 | "Method not found.\n"); | ||
562 | handle->response_code = MHD_HTTP_NOT_FOUND; | ||
563 | handle->emsg = GNUNET_strdup (GNUNET_REST_ESCROW_METHOD_NOT_FOUND); | ||
564 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
565 | return; | ||
566 | } | ||
567 | |||
568 | /* get user secret */ | ||
569 | if (GNUNET_ESCROW_KEY_PLAINTEXT != method) | ||
570 | { | ||
571 | userSecret = get_user_secret_from_payload (handle); | ||
572 | if (NULL == userSecret) | ||
573 | // get_user_secret_from_payload () already cleaned up | ||
574 | return; | ||
575 | } | ||
576 | else | ||
577 | userSecret = NULL; | ||
578 | |||
579 | handle->op = GNUNET_ESCROW_put (escrow_handle, | ||
580 | ego_entry->ego, | ||
581 | userSecret, | ||
582 | method, | ||
583 | &escrow_finished, | ||
584 | handle); | ||
585 | |||
586 | if (NULL != userSecret) | ||
587 | GNUNET_free (userSecret); | ||
588 | } | ||
589 | |||
590 | |||
591 | static struct GNUNET_ESCROW_Anchor * | ||
592 | get_anchor_from_payload (struct RequestHandle *handle) | ||
593 | { | ||
594 | json_t *json_data; | ||
595 | json_error_t err; | ||
596 | char *anchor_string; | ||
597 | int json_unpack_state; | ||
598 | char term_data[handle->data_size + 1]; | ||
599 | struct GNUNET_ESCROW_Anchor *anchor; | ||
600 | |||
601 | if (0 >= handle->data_size) | ||
602 | { | ||
603 | handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA); | ||
604 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
605 | return NULL; | ||
606 | } | ||
607 | |||
608 | term_data[handle->data_size] = '\0'; | ||
609 | GNUNET_memcpy (term_data, handle->data, handle->data_size); | ||
610 | json_data = json_loads (term_data, JSON_DECODE_ANY, &err); | ||
611 | if (NULL == json_data) | ||
612 | { | ||
613 | handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA); | ||
614 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
615 | json_decref (json_data); | ||
616 | return NULL; | ||
617 | } | ||
618 | |||
619 | json_unpack_state = 0; | ||
620 | json_unpack_state = | ||
621 | json_unpack (json_data, "{s:s}", | ||
622 | GNUNET_REST_ESCROW_PARAM_ANCHOR, &anchor_string); | ||
623 | if (0 != json_unpack_state) | ||
624 | { | ||
625 | handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_DATA_INVALID); | ||
626 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
627 | json_decref (json_data); | ||
628 | return NULL; | ||
629 | } | ||
630 | |||
631 | if (NULL == anchor_string) | ||
632 | { | ||
633 | handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_DATA_INVALID); | ||
634 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
635 | json_decref (json_data); | ||
636 | return NULL; | ||
637 | } | ||
638 | if (0 >= strlen (anchor_string)) | ||
639 | { | ||
640 | json_decref (json_data); | ||
641 | handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_DATA_INVALID); | ||
642 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
643 | return NULL; | ||
644 | } | ||
645 | |||
646 | json_decref (json_data); | ||
647 | |||
648 | anchor = GNUNET_ESCROW_anchor_string_to_data (anchor_string); | ||
649 | if (NULL == anchor) | ||
650 | { | ||
651 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
652 | "Failed to parse anchor: %s.\n", anchor_string); | ||
653 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
654 | handle->emsg = GNUNET_strdup (GNUNET_REST_ESCROW_ANCHOR_ERROR); | ||
655 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
656 | return NULL; | ||
657 | } | ||
658 | |||
659 | return anchor; | ||
660 | } | ||
661 | |||
662 | |||
663 | static void | ||
664 | restore_finished (void *cls, | ||
665 | struct GNUNET_IDENTITY_Ego *ego, | ||
666 | const char *emsg) | ||
667 | { | ||
668 | struct RequestHandle *handle = cls; | ||
669 | struct EgoEntry *ego_entry; | ||
670 | struct MHD_Response *resp; | ||
671 | struct GNUNET_CRYPTO_EcdsaPublicKey ego_pub; | ||
672 | json_t *json_ego; | ||
673 | char *keystring, *result_string; | ||
674 | |||
675 | if (NULL == ego) | ||
676 | { | ||
677 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
678 | "Failed to restore ego.\n"); | ||
679 | handle->response_code = MHD_HTTP_NO_CONTENT; | ||
680 | handle->emsg = GNUNET_strdup (GNUNET_REST_ESCROW_RESTORE_FAILED); | ||
681 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
682 | return; | ||
683 | } | ||
684 | |||
685 | GNUNET_IDENTITY_ego_get_public_key (ego, &ego_pub); | ||
686 | keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&ego_pub); | ||
687 | |||
688 | for (ego_entry = ego_head; NULL != ego_entry; | ||
689 | ego_entry = ego_entry->next) | ||
690 | if (0 == strcmp (keystring, ego_entry->keystring)) | ||
691 | break; | ||
692 | |||
693 | if (NULL == ego_entry) | ||
694 | { | ||
695 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
696 | "Identity not found despite successful restoration.\n"); | ||
697 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
698 | handle->emsg = GNUNET_strdup (GNUNET_REST_ESCROW_ID_NOT_FOUND); | ||
699 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
700 | GNUNET_free (keystring); | ||
701 | return; | ||
702 | } | ||
703 | |||
704 | json_ego = json_object (); | ||
705 | json_object_set_new (json_ego, | ||
706 | GNUNET_REST_ESCROW_PARAM_NAME, | ||
707 | json_string (ego_entry->identifier)); | ||
708 | json_object_set_new (json_ego, | ||
709 | GNUNET_REST_ESCROW_PARAM_PUBKEY, | ||
710 | json_string (ego_entry->keystring)); | ||
711 | |||
712 | result_string = json_dumps (json_ego, 0); | ||
713 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_string); | ||
714 | resp = GNUNET_REST_create_response (result_string); | ||
715 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
716 | MHD_add_response_header (resp, "Content-Type", "application/json"); | ||
717 | |||
718 | json_decref (json_ego); | ||
719 | GNUNET_free (result_string); | ||
720 | GNUNET_free (keystring); | ||
721 | |||
722 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
723 | } | ||
724 | |||
725 | |||
726 | /** | ||
727 | * Respond to GET (restore) request | ||
728 | * | ||
729 | * @param con_handle the connection handle | ||
730 | * @param url the url | ||
731 | * @param cls the RequestHandle | ||
732 | */ | ||
733 | static void | ||
734 | get_escrowed_identity (struct GNUNET_REST_RequestHandle *con_handle, | ||
735 | const char *url, | ||
736 | void *cls) | ||
737 | { | ||
738 | struct RequestHandle *handle = cls; | ||
739 | struct GNUNET_ESCROW_Anchor *anchor; | ||
740 | |||
741 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
742 | "Getting %s from escrow.\n", | ||
743 | handle->url); | ||
744 | |||
745 | /* get anchor */ | ||
746 | anchor = get_anchor_from_payload (handle); | ||
747 | if (NULL == anchor) | ||
748 | // get_anchor_from_payload () already cleaned up | ||
749 | return; | ||
750 | |||
751 | handle->op = GNUNET_ESCROW_get (escrow_handle, | ||
752 | anchor, | ||
753 | &restore_finished, | ||
754 | handle); | ||
755 | } | ||
756 | |||
757 | |||
758 | static void | ||
759 | verify_finished (void *cls, | ||
760 | int verificationResult, | ||
761 | const char *emsg) | ||
762 | { | ||
763 | struct RequestHandle *handle = cls; | ||
764 | struct MHD_Response *resp; | ||
765 | json_t *json_verif; | ||
766 | const char *verif_string; | ||
767 | char *result_string; | ||
768 | |||
769 | switch (verificationResult) | ||
770 | { | ||
771 | case GNUNET_ESCROW_VALID: | ||
772 | verif_string = "valid"; | ||
773 | break; | ||
774 | case GNUNET_ESCROW_INVALID: | ||
775 | verif_string = "invalid"; | ||
776 | break; | ||
777 | case GNUNET_ESCROW_SHARES_MISSING: | ||
778 | verif_string = "shares_missing"; | ||
779 | break; | ||
780 | default: | ||
781 | verif_string = "unknown"; | ||
782 | } | ||
783 | |||
784 | json_verif = json_object (); | ||
785 | json_object_set_new (json_verif, | ||
786 | GNUNET_REST_ESCROW_PARAM_VERIFICATION_RESULT, | ||
787 | json_string (verif_string)); | ||
788 | |||
789 | result_string = json_dumps (json_verif, 0); | ||
790 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_string); | ||
791 | resp = GNUNET_REST_create_response (result_string); | ||
792 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
793 | MHD_add_response_header (resp, "Content-Type", "application/json"); | ||
794 | |||
795 | json_decref (json_verif); | ||
796 | GNUNET_free (result_string); | ||
797 | |||
798 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
799 | } | ||
800 | |||
801 | |||
802 | /** | ||
803 | * Respond to VERIFY request | ||
804 | * | ||
805 | * @param con_handle the connection handle | ||
806 | * @param url the url | ||
807 | * @param cls the RequestHandle | ||
808 | */ | ||
809 | static void | ||
810 | verify_escrow (struct GNUNET_REST_RequestHandle *con_handle, | ||
811 | const char *url, | ||
812 | void *cls) | ||
813 | { | ||
814 | struct RequestHandle *handle = cls; | ||
815 | struct EgoEntry *ego_entry; | ||
816 | struct GNUNET_ESCROW_Anchor *anchor; | ||
817 | char *identity; | ||
818 | enum GNUNET_ESCROW_Key_Escrow_Method method; | ||
819 | |||
820 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
821 | "Verifying escrow of %s.\n", | ||
822 | handle->url); | ||
823 | |||
824 | if (strlen (GNUNET_REST_API_NS_ESCROW_VERIFY) >= strlen (handle->url)) | ||
825 | { | ||
826 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n"); | ||
827 | handle->response_code = MHD_HTTP_NOT_FOUND; | ||
828 | handle->emsg = GNUNET_strdup (GNUNET_REST_ESCROW_MISSING_NAME); | ||
829 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
830 | return; | ||
831 | } | ||
832 | identity = handle->url + strlen (GNUNET_REST_API_NS_ESCROW_VERIFY) + 1; | ||
833 | |||
834 | for (ego_entry = ego_head; NULL != ego_entry; | ||
835 | ego_entry = ego_entry->next) | ||
836 | if (0 == strcmp (identity, ego_entry->identifier)) | ||
837 | break; | ||
838 | |||
839 | if (NULL == ego_entry) | ||
840 | { | ||
841 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
842 | "Identity %s not found.\n", | ||
843 | identity); | ||
844 | handle->response_code = MHD_HTTP_NOT_FOUND; | ||
845 | handle->emsg = GNUNET_strdup (GNUNET_REST_ESCROW_ID_NOT_FOUND); | ||
846 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
847 | return; | ||
848 | } | ||
849 | |||
850 | /* determine method */ | ||
851 | method = determine_escrow_method (handle->rest_handle->url_param_map); | ||
852 | if (GNUNET_ESCROW_KEY_NONE == method) | ||
853 | { | ||
854 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
855 | "Method not found.\n"); | ||
856 | handle->response_code = MHD_HTTP_NOT_FOUND; | ||
857 | handle->emsg = GNUNET_strdup (GNUNET_REST_ESCROW_METHOD_NOT_FOUND); | ||
858 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
859 | return; | ||
860 | } | ||
861 | |||
862 | /* get anchor */ | ||
863 | anchor = get_anchor_from_payload (handle); | ||
864 | if (NULL == anchor) | ||
865 | // get_anchor_from_payload () already cleaned up | ||
866 | return; | ||
867 | |||
868 | handle->op = GNUNET_ESCROW_verify (escrow_handle, | ||
869 | ego_entry->ego, | ||
870 | anchor, | ||
871 | method, | ||
872 | &verify_finished, | ||
873 | handle); | ||
874 | } | ||
875 | |||
876 | |||
877 | /** | ||
878 | * Respond to STATUS request | ||
879 | * | ||
880 | * @param con_handle the connection handle | ||
881 | * @param url the url | ||
882 | * @param cls the RequestHandle | ||
883 | */ | ||
884 | static void | ||
885 | get_escrow_status (struct GNUNET_REST_RequestHandle *con_handle, | ||
886 | const char *url, | ||
887 | void *cls) | ||
888 | { | ||
889 | struct RequestHandle *handle = cls; | ||
890 | struct EgoEntry *ego_entry; | ||
891 | struct GNUNET_ESCROW_Status *status; | ||
892 | struct MHD_Response *resp; | ||
893 | char *identity; | ||
894 | enum GNUNET_ESCROW_Key_Escrow_Method method; | ||
895 | json_t *json_status; | ||
896 | char *result_string; | ||
897 | |||
898 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
899 | "Getting escrow status of %s.\n", | ||
900 | handle->url); | ||
901 | |||
902 | if (strlen (GNUNET_REST_API_NS_ESCROW_STATUS) >= strlen (handle->url)) | ||
903 | { | ||
904 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n"); | ||
905 | handle->response_code = MHD_HTTP_NOT_FOUND; | ||
906 | handle->emsg = GNUNET_strdup (GNUNET_REST_ESCROW_MISSING_NAME); | ||
907 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
908 | return; | ||
909 | } | ||
910 | identity = handle->url + strlen (GNUNET_REST_API_NS_ESCROW_STATUS) + 1; | ||
911 | |||
912 | for (ego_entry = ego_head; NULL != ego_entry; | ||
913 | ego_entry = ego_entry->next) | ||
914 | if (0 == strcmp (identity, ego_entry->identifier)) | ||
915 | break; | ||
916 | |||
917 | if (NULL == ego_entry) | ||
918 | { | ||
919 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
920 | "Identity %s not found.\n", | ||
921 | identity); | ||
922 | handle->response_code = MHD_HTTP_NOT_FOUND; | ||
923 | handle->emsg = GNUNET_strdup (GNUNET_REST_ESCROW_ID_NOT_FOUND); | ||
924 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
925 | return; | ||
926 | } | ||
927 | |||
928 | /* determine method */ | ||
929 | method = determine_escrow_method (handle->rest_handle->url_param_map); | ||
930 | if (GNUNET_ESCROW_KEY_NONE == method) | ||
931 | { | ||
932 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
933 | "Method not found.\n"); | ||
934 | handle->response_code = MHD_HTTP_NOT_FOUND; | ||
935 | handle->emsg = GNUNET_strdup (GNUNET_REST_ESCROW_METHOD_NOT_FOUND); | ||
936 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
937 | return; | ||
938 | } | ||
939 | |||
940 | status = GNUNET_ESCROW_get_status (escrow_handle, | ||
941 | ego_entry->ego, | ||
942 | method); | ||
943 | |||
944 | if (NULL == status) | ||
945 | { | ||
946 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
947 | "Got invalid status.\n"); | ||
948 | handle->response_code = MHD_HTTP_NO_CONTENT; | ||
949 | handle->emsg = GNUNET_strdup (GNUNET_REST_ESCROW_INVALID_STATUS); | ||
950 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
951 | return; | ||
952 | } | ||
953 | |||
954 | /* create and send response */ | ||
955 | json_status = json_object (); | ||
956 | if (GNUNET_ESCROW_KEY_NONE == status->last_method) | ||
957 | json_object_set_new (json_status, | ||
958 | GNUNET_REST_ESCROW_PARAM_LAST_METHOD, | ||
959 | json_string ("none")); | ||
960 | else | ||
961 | { | ||
962 | json_object_set_new (json_status, | ||
963 | GNUNET_REST_ESCROW_PARAM_LAST_METHOD, | ||
964 | json_string ( | ||
965 | GNUNET_ESCROW_method_number_to_string (status->last_method))); | ||
966 | json_object_set_new (json_status, | ||
967 | GNUNET_REST_ESCROW_PARAM_LAST_VERIF, | ||
968 | json_string ( | ||
969 | GNUNET_STRINGS_absolute_time_to_string ( | ||
970 | status->last_successful_verification_time))); | ||
971 | json_object_set_new (json_status, | ||
972 | GNUNET_REST_ESCROW_PARAM_NEXT_VERIF, | ||
973 | json_string ( | ||
974 | GNUNET_STRINGS_absolute_time_to_string ( | ||
975 | status->next_recommended_verification_time))); | ||
976 | } | ||
977 | |||
978 | result_string = json_dumps (json_status, 0); | ||
979 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_string); | ||
980 | resp = GNUNET_REST_create_response (result_string); | ||
981 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
982 | MHD_add_response_header (resp, "Content-Type", "application/json"); | ||
983 | |||
984 | json_decref (json_status); | ||
985 | GNUNET_free (result_string); | ||
986 | |||
987 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
988 | } | ||
989 | |||
990 | |||
991 | /** | ||
992 | * Respond to OPTIONS request | ||
993 | * | ||
994 | * @param con_handle the connection handle | ||
995 | * @param url the url | ||
996 | * @param cls the RequestHandle | ||
997 | */ | ||
998 | static void | ||
999 | options_cont (struct GNUNET_REST_RequestHandle *con_handle, | ||
1000 | const char *url, | ||
1001 | void *cls) | ||
1002 | { | ||
1003 | struct MHD_Response *resp; | ||
1004 | struct RequestHandle *handle = cls; | ||
1005 | |||
1006 | // For now, independent of path return all options | ||
1007 | resp = GNUNET_REST_create_response (NULL); | ||
1008 | MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods); | ||
1009 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
1010 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
1011 | return; | ||
1012 | } | ||
1013 | |||
1014 | |||
1015 | /** | ||
1016 | * If listing is enabled, prints information about the egos. | ||
1017 | * | ||
1018 | * This function is initially called for all egos and then again | ||
1019 | * whenever a ego's identifier changes or if it is deleted. At the | ||
1020 | * end of the initial pass over all egos, the function is once called | ||
1021 | * with 'NULL' for 'ego'. That does NOT mean that the callback won't | ||
1022 | * be invoked in the future or that there was an error. | ||
1023 | * | ||
1024 | * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get', | ||
1025 | * this function is only called ONCE, and 'NULL' being passed in | ||
1026 | * 'ego' does indicate an error (i.e. name is taken or no default | ||
1027 | * value is known). If 'ego' is non-NULL and if '*ctx' | ||
1028 | * is set in those callbacks, the value WILL be passed to a subsequent | ||
1029 | * call to the identity callback of 'GNUNET_IDENTITY_connect' (if | ||
1030 | * that one was not NULL). | ||
1031 | * | ||
1032 | * When an identity is renamed, this function is called with the | ||
1033 | * (known) ego but the NEW identifier. | ||
1034 | * | ||
1035 | * When an identity is deleted, this function is called with the | ||
1036 | * (known) ego and "NULL" for the 'identifier'. In this case, | ||
1037 | * the 'ego' is henceforth invalid (and the 'ctx' should also be | ||
1038 | * cleaned up). | ||
1039 | * | ||
1040 | * @param cls closure | ||
1041 | * @param ego ego handle | ||
1042 | * @param ctx context for application to store data for this ego | ||
1043 | * (during the lifetime of this process, initially NULL) | ||
1044 | * @param identifier identifier assigned by the user for this ego, | ||
1045 | * NULL if the user just deleted the ego and it | ||
1046 | * must thus no longer be used | ||
1047 | */ | ||
1048 | static void | ||
1049 | list_ego (void *cls, | ||
1050 | struct GNUNET_IDENTITY_Ego *ego, | ||
1051 | void **ctx, | ||
1052 | const char *identifier) | ||
1053 | { | ||
1054 | struct EgoEntry *ego_entry; | ||
1055 | struct GNUNET_CRYPTO_EcdsaPublicKey pk; | ||
1056 | |||
1057 | if ((NULL == ego) && (ID_REST_STATE_INIT == state)) | ||
1058 | { | ||
1059 | state = ID_REST_STATE_POST_INIT; | ||
1060 | return; | ||
1061 | } | ||
1062 | if (ID_REST_STATE_INIT == state) | ||
1063 | { | ||
1064 | ego_entry = GNUNET_new (struct EgoEntry); | ||
1065 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); | ||
1066 | ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); | ||
1067 | ego_entry->ego = ego; | ||
1068 | ego_entry->identifier = GNUNET_strdup (identifier); | ||
1069 | GNUNET_CONTAINER_DLL_insert_tail (ego_head, | ||
1070 | ego_tail, | ||
1071 | ego_entry); | ||
1072 | } | ||
1073 | /* Ego renamed or added */ | ||
1074 | if (identifier != NULL) | ||
1075 | { | ||
1076 | for (ego_entry = ego_head; NULL != ego_entry; | ||
1077 | ego_entry = ego_entry->next) | ||
1078 | { | ||
1079 | if (ego_entry->ego == ego) | ||
1080 | { | ||
1081 | /* Rename */ | ||
1082 | GNUNET_free (ego_entry->identifier); | ||
1083 | ego_entry->identifier = GNUNET_strdup (identifier); | ||
1084 | break; | ||
1085 | } | ||
1086 | } | ||
1087 | if (NULL == ego_entry) | ||
1088 | { | ||
1089 | /* Add */ | ||
1090 | ego_entry = GNUNET_new (struct EgoEntry); | ||
1091 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); | ||
1092 | ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); | ||
1093 | ego_entry->ego = ego; | ||
1094 | ego_entry->identifier = GNUNET_strdup (identifier); | ||
1095 | GNUNET_CONTAINER_DLL_insert_tail (ego_head, | ||
1096 | ego_tail, | ||
1097 | ego_entry); | ||
1098 | } | ||
1099 | } | ||
1100 | else | ||
1101 | { | ||
1102 | /* Delete */ | ||
1103 | for (ego_entry = ego_head; NULL != ego_entry; | ||
1104 | ego_entry = ego_entry->next) | ||
1105 | { | ||
1106 | if (ego_entry->ego == ego) | ||
1107 | break; | ||
1108 | } | ||
1109 | if (NULL == ego_entry) | ||
1110 | return; /* Not found */ | ||
1111 | |||
1112 | GNUNET_CONTAINER_DLL_remove (ego_head, | ||
1113 | ego_tail, | ||
1114 | ego_entry); | ||
1115 | GNUNET_free (ego_entry->identifier); | ||
1116 | GNUNET_free (ego_entry->keystring); | ||
1117 | GNUNET_free (ego_entry); | ||
1118 | return; | ||
1119 | } | ||
1120 | |||
1121 | } | ||
1122 | |||
1123 | |||
1124 | /** | ||
1125 | * Function processing the REST call | ||
1126 | * | ||
1127 | * @param method HTTP method | ||
1128 | * @param url URL of the HTTP request | ||
1129 | * @param data body of the HTTP request (optional) | ||
1130 | * @param data_size length of the body | ||
1131 | * @param proc callback function for the result | ||
1132 | * @param proc_cls closure for callback function | ||
1133 | * @return GNUNET_OK if request accepted | ||
1134 | */ | ||
1135 | static enum GNUNET_GenericReturnValue | ||
1136 | rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, | ||
1137 | GNUNET_REST_ResultProcessor proc, | ||
1138 | void *proc_cls) | ||
1139 | { | ||
1140 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); | ||
1141 | struct GNUNET_REST_RequestHandlerError err; | ||
1142 | static const struct GNUNET_REST_RequestHandler handlers[] = | ||
1143 | { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_ESCROW_VERIFY, &verify_escrow }, | ||
1144 | { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_ESCROW_STATUS, &get_escrow_status }, | ||
1145 | { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_ESCROW_GET, &get_escrowed_identity }, | ||
1146 | { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_ESCROW_PUT, &escrow_identity }, | ||
1147 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_ESCROW, &options_cont }, | ||
1148 | GNUNET_REST_HANDLER_END }; | ||
1149 | |||
1150 | |||
1151 | handle->response_code = 0; | ||
1152 | handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; | ||
1153 | handle->proc_cls = proc_cls; | ||
1154 | handle->proc = proc; | ||
1155 | handle->rest_handle = rest_handle; | ||
1156 | handle->data = rest_handle->data; | ||
1157 | handle->data_size = rest_handle->data_size; | ||
1158 | |||
1159 | handle->url = GNUNET_strdup (rest_handle->url); | ||
1160 | if (handle->url[strlen (handle->url) - 1] == '/') | ||
1161 | handle->url[strlen (handle->url) - 1] = '\0'; | ||
1162 | handle->timeout_task = | ||
1163 | GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle); | ||
1164 | GNUNET_CONTAINER_DLL_insert (requests_head, | ||
1165 | requests_tail, | ||
1166 | handle); | ||
1167 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); | ||
1168 | if (GNUNET_NO == | ||
1169 | GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) | ||
1170 | { | ||
1171 | cleanup_handle (handle); | ||
1172 | return GNUNET_NO; | ||
1173 | } | ||
1174 | |||
1175 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); | ||
1176 | return GNUNET_YES; | ||
1177 | } | ||
1178 | |||
1179 | |||
1180 | /** | ||
1181 | * Entry point for the plugin. | ||
1182 | * | ||
1183 | * @param cls Config info | ||
1184 | * @return NULL on error, otherwise the plugin context | ||
1185 | */ | ||
1186 | void * | ||
1187 | libgnunet_plugin_rest_escrow_init (void *cls) | ||
1188 | { | ||
1189 | static struct Plugin plugin; | ||
1190 | struct GNUNET_REST_Plugin *api; | ||
1191 | |||
1192 | cfg = cls; | ||
1193 | if (NULL != plugin.cfg) | ||
1194 | return NULL; /* can only initialize once! */ | ||
1195 | memset (&plugin, 0, sizeof(struct Plugin)); | ||
1196 | plugin.cfg = cfg; | ||
1197 | api = GNUNET_new (struct GNUNET_REST_Plugin); | ||
1198 | api->cls = &plugin; | ||
1199 | api->name = GNUNET_REST_API_NS_ESCROW; | ||
1200 | api->process_request = &rest_process_request; | ||
1201 | GNUNET_asprintf (&allow_methods, | ||
1202 | "%s, %s, %s", | ||
1203 | MHD_HTTP_METHOD_GET, | ||
1204 | MHD_HTTP_METHOD_POST, | ||
1205 | MHD_HTTP_METHOD_OPTIONS); | ||
1206 | state = ID_REST_STATE_INIT; | ||
1207 | identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL); | ||
1208 | escrow_handle = GNUNET_ESCROW_init (cfg); | ||
1209 | |||
1210 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Escrow REST API initialized\n")); | ||
1211 | return api; | ||
1212 | } | ||
1213 | |||
1214 | |||
1215 | /** | ||
1216 | * Exit point from the plugin. | ||
1217 | * | ||
1218 | * @param cls the plugin context (as returned by "init") | ||
1219 | * @return always NULL | ||
1220 | */ | ||
1221 | void * | ||
1222 | libgnunet_plugin_rest_escrow_done (void *cls) | ||
1223 | { | ||
1224 | struct GNUNET_REST_Plugin *api = cls; | ||
1225 | struct Plugin *plugin = api->cls; | ||
1226 | struct EgoEntry *ego_entry; | ||
1227 | struct EgoEntry *ego_tmp; | ||
1228 | |||
1229 | plugin->cfg = NULL; | ||
1230 | while (NULL != requests_head) | ||
1231 | cleanup_handle (requests_head); | ||
1232 | if (NULL != escrow_handle) | ||
1233 | GNUNET_ESCROW_fini (escrow_handle); | ||
1234 | if (NULL != identity_handle) | ||
1235 | GNUNET_IDENTITY_disconnect (identity_handle); | ||
1236 | for (ego_entry = ego_head; NULL != ego_entry;) | ||
1237 | { | ||
1238 | ego_tmp = ego_entry; | ||
1239 | ego_entry = ego_entry->next; | ||
1240 | GNUNET_free (ego_tmp->identifier); | ||
1241 | GNUNET_free (ego_tmp->keystring); | ||
1242 | GNUNET_free (ego_tmp); | ||
1243 | } | ||
1244 | |||
1245 | GNUNET_free (allow_methods); | ||
1246 | GNUNET_free (api); | ||
1247 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Escrow REST plugin is finished\n"); | ||
1248 | return NULL; | ||
1249 | } | ||
1250 | |||
1251 | |||
1252 | /* end of plugin_rest_escrow.c */ | ||
diff --git a/src/include/gnunet_escrow_lib.h b/src/include/gnunet_escrow_lib.h index 864d6356d..546fdfeb9 100644 --- a/src/include/gnunet_escrow_lib.h +++ b/src/include/gnunet_escrow_lib.h | |||
@@ -120,7 +120,7 @@ typedef void (*GNUNET_ESCROW_IdentityInitContinuation) (); | |||
120 | * because of an escrow GET operation. | 120 | * because of an escrow GET operation. |
121 | */ | 121 | */ |
122 | typedef void (*GNUNET_ESCROW_EgoCreateContinuation) ( | 122 | typedef void (*GNUNET_ESCROW_EgoCreateContinuation) ( |
123 | const struct GNUNET_IDENTITY_Ego *ego); | 123 | struct GNUNET_IDENTITY_Ego *ego); |
124 | 124 | ||
125 | /** | 125 | /** |
126 | * Continuation for PUT operations. | 126 | * Continuation for PUT operations. |
@@ -143,7 +143,7 @@ typedef void (*GNUNET_ESCROW_AnchorContinuation) ( | |||
143 | */ | 143 | */ |
144 | typedef void (*GNUNET_ESCROW_EgoContinuation) ( | 144 | typedef void (*GNUNET_ESCROW_EgoContinuation) ( |
145 | void *cls, | 145 | void *cls, |
146 | const struct GNUNET_IDENTITY_Ego *ego, | 146 | struct GNUNET_IDENTITY_Ego *ego, |
147 | const char *emsg); | 147 | const char *emsg); |
148 | 148 | ||
149 | /** | 149 | /** |