aboutsummaryrefslogtreecommitdiff
path: root/src/rest-plugins
diff options
context:
space:
mode:
authorSchanzenbach, Martin <mschanzenbach@posteo.de>2018-09-27 19:31:50 +0200
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2018-09-27 19:31:50 +0200
commita31198a7231bc072f428eccb57a45db5dfc65105 (patch)
treeed67807b24d8fadfe04fa8a341884c95a3d7b72c /src/rest-plugins
parent592e117242e4cd5f5cd05a687062e7d61e2f8d22 (diff)
downloadgnunet-a31198a7231bc072f428eccb57a45db5dfc65105.tar.gz
gnunet-a31198a7231bc072f428eccb57a45db5dfc65105.zip
bye bye jsonapi
Diffstat (limited to 'src/rest-plugins')
-rw-r--r--src/rest-plugins/Makefile.am21
-rw-r--r--src/rest-plugins/json_reclaim.c242
-rw-r--r--src/rest-plugins/json_reclaim.h46
-rw-r--r--src/rest-plugins/plugin_rest_reclaim.c1097
4 files changed, 1402 insertions, 4 deletions
diff --git a/src/rest-plugins/Makefile.am b/src/rest-plugins/Makefile.am
index 484dceaba..61cd7955d 100644
--- a/src/rest-plugins/Makefile.am
+++ b/src/rest-plugins/Makefile.am
@@ -25,9 +25,25 @@ plugin_LTLIBRARIES = \
25 libgnunet_plugin_rest_gns.la \ 25 libgnunet_plugin_rest_gns.la \
26 libgnunet_plugin_rest_credential.la 26 libgnunet_plugin_rest_credential.la
27if HAVE_ABE 27if HAVE_ABE
28plugin_LTLIBRARIES += libgnunet_plugin_rest_openid_connect.la 28plugin_LTLIBRARIES += libgnunet_plugin_rest_openid_connect.la \
29 libgnunet_plugin_rest_reclaim.la
29endif 30endif
30 31
32libgnunet_plugin_rest_reclaim_la_SOURCES = \
33 plugin_rest_reclaim.c \
34 json_reclaim.c
35libgnunet_plugin_rest_reclaim_la_LIBADD = \
36 $(top_builddir)/src/identity/libgnunetidentity.la \
37 $(top_builddir)/src/reclaim/libgnunetreclaim.la \
38 $(top_builddir)/src/rest/libgnunetrest.la \
39 $(top_builddir)/src/reclaim-attribute/libgnunetreclaimattribute.la \
40 $(top_builddir)/src/namestore/libgnunetnamestore.la \
41 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
42 $(LTLIBINTL) -ljansson -lmicrohttpd
43libgnunet_plugin_rest_reclaim_la_LDFLAGS = \
44 i$(GN_PLUGIN_LDFLAGS)
45
46
31libgnunet_plugin_rest_credential_la_SOURCES = \ 47libgnunet_plugin_rest_credential_la_SOURCES = \
32 plugin_rest_credential.c 48 plugin_rest_credential.c
33libgnunet_plugin_rest_credential_la_LIBADD = \ 49libgnunet_plugin_rest_credential_la_LIBADD = \
@@ -41,9 +57,6 @@ libgnunet_plugin_rest_credential_la_LIBADD = \
41libgnunet_plugin_rest_credential_la_LDFLAGS = \ 57libgnunet_plugin_rest_credential_la_LDFLAGS = \
42 $(GN_PLUGIN_LDFLAGS) 58 $(GN_PLUGIN_LDFLAGS)
43 59
44
45
46
47libgnunet_plugin_rest_copying_la_SOURCES = \ 60libgnunet_plugin_rest_copying_la_SOURCES = \
48 plugin_rest_copying.c 61 plugin_rest_copying.c
49libgnunet_plugin_rest_copying_la_LIBADD = \ 62libgnunet_plugin_rest_copying_la_LIBADD = \
diff --git a/src/rest-plugins/json_reclaim.c b/src/rest-plugins/json_reclaim.c
new file mode 100644
index 000000000..c0cce3be5
--- /dev/null
+++ b/src/rest-plugins/json_reclaim.c
@@ -0,0 +1,242 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2018 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
19/**
20 * @file rest-plugins/json_reclaim.c
21 * @brief JSON handling of reclaim data
22 * @author Martin Schanzenbach
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26#include "gnunet_json_lib.h"
27#include "gnunet_reclaim_service.h"
28#include "gnunet_reclaim_attribute_lib.h"
29
30/**
31 * Parse given JSON object to a claim
32 *
33 * @param cls closure, NULL
34 * @param root the json object representing data
35 * @param spec where to write the data
36 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
37 */
38static int
39parse_attr (void *cls,
40 json_t *root,
41 struct GNUNET_JSON_Specification *spec)
42{
43 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
44 const char* name_str;
45 const char* val_str;
46 const char* type_str;
47 const char* exp_str;
48 char *data;
49 int unpack_state;
50 uint32_t type;
51 size_t data_size;
52
53 GNUNET_assert(NULL != root);
54
55 if(!json_is_object(root))
56 {
57 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
58 "Error json is not array nor object!\n");
59 return GNUNET_SYSERR;
60 }
61 //interpret single attribute
62 unpack_state = json_unpack(root,
63 "{s:s, s:s, s:s, s:s!}",
64 "name", &name_str,
65 "type", &type_str,
66 "value", &val_str,
67 "exp", &exp_str);
68 if (0 != unpack_state)
69 {
70 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
71 "Error json object has a wrong format!\n");
72 return GNUNET_SYSERR;
73 }
74 type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str);
75 if (GNUNET_SYSERR == (GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,
76 val_str,
77 (void**)&data,
78 &data_size)))
79 {
80 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
81 "Attribute value invalid!\n");
82 return GNUNET_SYSERR;
83 }
84 attr = GNUNET_RECLAIM_ATTRIBUTE_claim_new (name_str,
85 type,
86 data,
87 data_size);
88 *(struct GNUNET_RECLAIM_ATTRIBUTE_Claim **) spec->ptr = attr;
89 return GNUNET_OK;
90}
91
92/**
93 * Cleanup data left from parsing RSA public key.
94 *
95 * @param cls closure, NULL
96 * @param[out] spec where to free the data
97 */
98static void
99clean_attr (void *cls, struct GNUNET_JSON_Specification *spec)
100{
101 struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr;
102 attr = (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **) spec->ptr;
103 if (NULL != *attr)
104 {
105 GNUNET_free(*attr);
106 *attr = NULL;
107 }
108}
109
110/**
111 * JSON Specification for Reclaim claims.
112 *
113 * @param ticket struct of GNUNET_RECLAIM_ATTRIBUTE_Claim to fill
114 * @return JSON Specification
115 */
116struct GNUNET_JSON_Specification
117GNUNET_RECLAIM_JSON_spec_claim (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr)
118{
119 struct GNUNET_JSON_Specification ret = {
120 .parser = &parse_attr,
121 .cleaner = &clean_attr,
122 .cls = NULL,
123 .field = NULL,
124 .ptr = attr,
125 .ptr_size = 0,
126 .size_ptr = NULL
127 };
128 *attr = NULL;
129 return ret;
130}
131/**
132 * Parse given JSON object to a ticket
133 *
134 * @param cls closure, NULL
135 * @param root the json object representing data
136 * @param spec where to write the data
137 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
138 */
139static int
140parse_ticket (void *cls,
141 json_t *root,
142 struct GNUNET_JSON_Specification *spec)
143{
144 struct GNUNET_RECLAIM_Ticket *ticket;
145 const char* rnd_str;
146 const char* aud_str;
147 const char* id_str;
148 int unpack_state;
149
150 GNUNET_assert(NULL != root);
151
152 if(!json_is_object(root))
153 {
154 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
155 "Error json is not array nor object!\n");
156 return GNUNET_SYSERR;
157 }
158 //interpret single ticket
159 unpack_state = json_unpack(root,
160 "{s:s, s:s, s:s!}",
161 "rnd", &rnd_str,
162 "audience", &aud_str,
163 "identity", &id_str);
164 if (0 != unpack_state)
165 {
166 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
167 "Error json object has a wrong format!\n");
168 return GNUNET_SYSERR;
169 }
170 ticket = GNUNET_new (struct GNUNET_RECLAIM_Ticket);
171 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (rnd_str,
172 strlen (rnd_str),
173 &ticket->rnd,
174 sizeof (uint64_t)))
175 {
176 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Rnd invalid\n");
177 GNUNET_free(ticket);
178 return GNUNET_SYSERR;
179 }
180 GNUNET_STRINGS_string_to_data (id_str,
181 strlen (id_str),
182 &ticket->identity,
183 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
184 {
185 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Identity invalid\n");
186 GNUNET_free(ticket);
187 return GNUNET_SYSERR;
188 }
189
190 GNUNET_STRINGS_string_to_data (aud_str,
191 strlen (aud_str),
192 &ticket->audience,
193 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
194 {
195 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Audience invalid\n");
196 GNUNET_free(ticket);
197 return GNUNET_SYSERR;
198 }
199
200 *(struct GNUNET_RECLAIM_Ticket **) spec->ptr = ticket;
201 return GNUNET_OK;
202}
203
204/**
205 * Cleanup data left from parsing RSA public key.
206 *
207 * @param cls closure, NULL
208 * @param[out] spec where to free the data
209 */
210static void
211clean_ticket (void *cls, struct GNUNET_JSON_Specification *spec)
212{
213 struct GNUNET_RECLAIM_Ticket **ticket;
214 ticket = (struct GNUNET_RECLAIM_Ticket **) spec->ptr;
215 if (NULL != *ticket)
216 {
217 GNUNET_free(*ticket);
218 *ticket = NULL;
219 }
220}
221
222/**
223 * JSON Specification for Reclaim tickets.
224 *
225 * @param ticket struct of GNUNET_RECLAIM_Ticket to fill
226 * @return JSON Specification
227 */
228struct GNUNET_JSON_Specification
229GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket)
230{
231 struct GNUNET_JSON_Specification ret = {
232 .parser = &parse_ticket,
233 .cleaner = &clean_ticket,
234 .cls = NULL,
235 .field = NULL,
236 .ptr = ticket,
237 .ptr_size = 0,
238 .size_ptr = NULL
239 };
240 *ticket = NULL;
241 return ret;
242}
diff --git a/src/rest-plugins/json_reclaim.h b/src/rest-plugins/json_reclaim.h
new file mode 100644
index 000000000..49674a173
--- /dev/null
+++ b/src/rest-plugins/json_reclaim.h
@@ -0,0 +1,46 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2018 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
19/**
20 * @file rest-plugins/json_reclaim.h
21 * @brief JSON handling of reclaim data
22 * @author Martin Schanzenbach
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26#include "gnunet_json_lib.h"
27#include "gnunet_reclaim_service.h"
28#include "gnunet_reclaim_attribute_lib.h"
29
30/**
31 * JSON Specification for Reclaim claims.
32 *
33 * @param ticket struct of GNUNET_RECLAIM_ATTRIBUTE_Claim to fill
34 * @return JSON Specification
35 */
36struct GNUNET_JSON_Specification
37GNUNET_RECLAIM_JSON_spec_claim (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr);
38
39/**
40 * JSON Specification for Reclaim tickets.
41 *
42 * @param ticket struct of GNUNET_RECLAIM_Ticket to fill
43 * @return JSON Specification
44 */
45struct GNUNET_JSON_Specification
46GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket);
diff --git a/src/rest-plugins/plugin_rest_reclaim.c b/src/rest-plugins/plugin_rest_reclaim.c
new file mode 100644
index 000000000..9115a9449
--- /dev/null
+++ b/src/rest-plugins/plugin_rest_reclaim.c
@@ -0,0 +1,1097 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012-2015 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/**
19 * @author Martin Schanzenbach
20 * @author Philippe Buschmann
21 * @file reclaim/plugin_rest_reclaim.c
22 * @brief GNUnet reclaim REST plugin
23 *
24 */
25
26#include "platform.h"
27#include "gnunet_rest_plugin.h"
28#include "gnunet_identity_service.h"
29#include "gnunet_gns_service.h"
30#include "gnunet_gnsrecord_lib.h"
31#include "gnunet_namestore_service.h"
32#include "gnunet_rest_lib.h"
33#include "gnunet_jsonapi_lib.h"
34#include "gnunet_jsonapi_util.h"
35#include "microhttpd.h"
36#include <jansson.h>
37#include <inttypes.h>
38#include "gnunet_signatures.h"
39#include "gnunet_reclaim_attribute_lib.h"
40#include "gnunet_reclaim_service.h"
41#include "json_reclaim.h"
42
43/**
44 * REST root namespace
45 */
46#define GNUNET_REST_API_NS_RECLAIM "/reclaim"
47
48/**
49 * Attribute namespace
50 */
51#define GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES "/reclaim/attributes"
52
53/**
54 * Ticket namespace
55 */
56#define GNUNET_REST_API_NS_IDENTITY_TICKETS "/reclaim/tickets"
57
58/**
59 * Revoke namespace
60 */
61#define GNUNET_REST_API_NS_IDENTITY_REVOKE "/reclaim/revoke"
62
63/**
64 * Revoke namespace
65 */
66#define GNUNET_REST_API_NS_IDENTITY_CONSUME "/reclaim/consume"
67
68/**
69 * State while collecting all egos
70 */
71#define ID_REST_STATE_INIT 0
72
73/**
74 * Done collecting egos
75 */
76#define ID_REST_STATE_POST_INIT 1
77
78/**
79 * The configuration handle
80 */
81const struct GNUNET_CONFIGURATION_Handle *cfg;
82
83/**
84 * HTTP methods allows for this plugin
85 */
86static char* allow_methods;
87
88/**
89 * @brief struct returned by the initialization function of the plugin
90 */
91struct Plugin
92{
93 const struct GNUNET_CONFIGURATION_Handle *cfg;
94};
95
96/**
97 * The ego list
98 */
99struct EgoEntry
100{
101 /**
102 * DLL
103 */
104 struct EgoEntry *next;
105
106 /**
107 * DLL
108 */
109 struct EgoEntry *prev;
110
111 /**
112 * Ego Identifier
113 */
114 char *identifier;
115
116 /**
117 * Public key string
118 */
119 char *keystring;
120
121 /**
122 * The Ego
123 */
124 struct GNUNET_IDENTITY_Ego *ego;
125};
126
127
128struct RequestHandle
129{
130 /**
131 * Ego list
132 */
133 struct EgoEntry *ego_head;
134
135 /**
136 * Ego list
137 */
138 struct EgoEntry *ego_tail;
139
140 /**
141 * Selected ego
142 */
143 struct EgoEntry *ego_entry;
144
145 /**
146 * Pointer to ego private key
147 */
148 struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key;
149
150 /**
151 * The processing state
152 */
153 int state;
154
155 /**
156 * Handle to Identity service.
157 */
158 struct GNUNET_IDENTITY_Handle *identity_handle;
159
160 /**
161 * Rest connection
162 */
163 struct GNUNET_REST_RequestHandle *rest_handle;
164
165 /**
166 * Handle to NAMESTORE
167 */
168 struct GNUNET_NAMESTORE_Handle *namestore_handle;
169
170 /**
171 * Iterator for NAMESTORE
172 */
173 struct GNUNET_NAMESTORE_ZoneIterator *namestore_handle_it;
174
175 /**
176 * Attribute claim list
177 */
178 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attr_list;
179
180 /**
181 * IDENTITY Operation
182 */
183 struct GNUNET_IDENTITY_Operation *op;
184
185 /**
186 * Identity Provider
187 */
188 struct GNUNET_RECLAIM_Handle *idp;
189
190 /**
191 * Idp Operation
192 */
193 struct GNUNET_RECLAIM_Operation *idp_op;
194
195 /**
196 * Attribute iterator
197 */
198 struct GNUNET_RECLAIM_AttributeIterator *attr_it;
199
200 /**
201 * Ticket iterator
202 */
203 struct GNUNET_RECLAIM_TicketIterator *ticket_it;
204
205 /**
206 * A ticket
207 */
208 struct GNUNET_RECLAIM_Ticket ticket;
209
210 /**
211 * Desired timeout for the lookup (default is no timeout).
212 */
213 struct GNUNET_TIME_Relative timeout;
214
215 /**
216 * ID of a task associated with the resolution process.
217 */
218 struct GNUNET_SCHEDULER_Task *timeout_task;
219
220 /**
221 * The plugin result processor
222 */
223 GNUNET_REST_ResultProcessor proc;
224
225 /**
226 * The closure of the result processor
227 */
228 void *proc_cls;
229
230 /**
231 * The url
232 */
233 char *url;
234
235 /**
236 * Error response message
237 */
238 char *emsg;
239
240 /**
241 * Reponse code
242 */
243 int response_code;
244
245 /**
246 * Response object
247 */
248 json_t *resp_object;
249
250};
251
252/**
253 * Cleanup lookup handle
254 * @param handle Handle to clean up
255 */
256static void
257cleanup_handle (struct RequestHandle *handle)
258{
259 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_entry;
260 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_tmp;
261 struct EgoEntry *ego_entry;
262 struct EgoEntry *ego_tmp;
263 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
264 "Cleaning up\n");
265 if (NULL != handle->resp_object)
266 json_decref (handle->resp_object);
267 if (NULL != handle->timeout_task)
268 GNUNET_SCHEDULER_cancel (handle->timeout_task);
269 if (NULL != handle->identity_handle)
270 GNUNET_IDENTITY_disconnect (handle->identity_handle);
271 if (NULL != handle->attr_it)
272 GNUNET_RECLAIM_get_attributes_stop (handle->attr_it);
273 if (NULL != handle->ticket_it)
274 GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it);
275 if (NULL != handle->idp)
276 GNUNET_RECLAIM_disconnect (handle->idp);
277 if (NULL != handle->url)
278 GNUNET_free (handle->url);
279 if (NULL != handle->emsg)
280 GNUNET_free (handle->emsg);
281 if (NULL != handle->namestore_handle)
282 GNUNET_NAMESTORE_disconnect (handle->namestore_handle);
283 if ( NULL != handle->attr_list )
284 {
285 for (claim_entry = handle->attr_list->list_head;
286 NULL != claim_entry;)
287 {
288 claim_tmp = claim_entry;
289 claim_entry = claim_entry->next;
290 GNUNET_free(claim_tmp->claim);
291 GNUNET_free(claim_tmp);
292 }
293 GNUNET_free (handle->attr_list);
294 }
295 for (ego_entry = handle->ego_head;
296 NULL != ego_entry;)
297 {
298 ego_tmp = ego_entry;
299 ego_entry = ego_entry->next;
300 GNUNET_free (ego_tmp->identifier);
301 GNUNET_free (ego_tmp->keystring);
302 GNUNET_free (ego_tmp);
303 }
304 if (NULL != handle->attr_it)
305 {
306 GNUNET_free(handle->attr_it);
307 }
308 GNUNET_free (handle);
309}
310
311static void
312cleanup_handle_delayed (void *cls)
313{
314 cleanup_handle (cls);
315}
316
317
318/**
319 * Task run on error, sends error message. Cleans up everything.
320 *
321 * @param cls the `struct RequestHandle`
322 */
323static void
324do_error (void *cls)
325{
326 struct RequestHandle *handle = cls;
327 struct MHD_Response *resp;
328 char *json_error;
329
330 GNUNET_asprintf (&json_error, "{ \"error\" : \"%s\" }",
331 handle->emsg);
332 if ( 0 == handle->response_code )
333 {
334 handle->response_code = MHD_HTTP_BAD_REQUEST;
335 }
336 resp = GNUNET_REST_create_response (json_error);
337 MHD_add_response_header (resp, "Content-Type", "application/json");
338 handle->proc (handle->proc_cls, resp, handle->response_code);
339 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
340 GNUNET_free (json_error);
341}
342
343
344/**
345 * Task run on timeout, sends error message. Cleans up everything.
346 *
347 * @param cls the `struct RequestHandle`
348 */
349static void
350do_timeout (void *cls)
351{
352 struct RequestHandle *handle = cls;
353
354 handle->timeout_task = NULL;
355 do_error (handle);
356}
357
358
359static void
360collect_error_cb (void *cls)
361{
362 struct RequestHandle *handle = cls;
363
364 do_error (handle);
365}
366
367static void
368finished_cont (void *cls,
369 int32_t success,
370 const char *emsg)
371{
372 struct RequestHandle *handle = cls;
373 struct MHD_Response *resp;
374
375 resp = GNUNET_REST_create_response (emsg);
376 if (GNUNET_OK != success)
377 {
378 GNUNET_SCHEDULER_add_now (&do_error, handle);
379 return;
380 }
381 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
382 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
383}
384
385
386/**
387 * Return attributes for identity
388 *
389 * @param cls the request handle
390 */
391static void
392return_response (void *cls)
393{
394 char* result_str;
395 struct RequestHandle *handle = cls;
396 struct MHD_Response *resp;
397
398 result_str = json_dumps (handle->resp_object, 0);
399 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
400 resp = GNUNET_REST_create_response (result_str);
401 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
402 GNUNET_free (result_str);
403 cleanup_handle (handle);
404}
405
406static void
407collect_finished_cb (void *cls)
408{
409 struct RequestHandle *handle = cls;
410 //Done
411 handle->attr_it = NULL;
412 handle->ticket_it = NULL;
413 GNUNET_SCHEDULER_add_now (&return_response, handle);
414}
415
416
417/**
418 * Collect all attributes for an ego
419 *
420 */
421static void
422ticket_collect (void *cls,
423 const struct GNUNET_RECLAIM_Ticket *ticket)
424{
425 json_t *json_resource;
426 struct RequestHandle *handle = cls;
427 json_t *value;
428 char* tmp;
429
430 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding ticket\n");
431 tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
432 sizeof (uint64_t));
433 json_resource = json_object ();
434 GNUNET_free (tmp);
435 json_array_append (handle->resp_object,
436 json_resource);
437
438 tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->identity,
439 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
440 value = json_string (tmp);
441 json_object_set_new (json_resource,
442 "issuer",
443 value);
444 GNUNET_free (tmp);
445 json_decref (value);
446 tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->audience,
447 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
448 value = json_string (tmp);
449 json_object_set_new (json_resource,
450 "audience",
451 value);
452 GNUNET_free (tmp);
453 json_decref (value);
454 tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
455 sizeof (uint64_t));
456 value = json_string (tmp);
457 json_object_set_new (json_resource,
458 "rnd",
459 value);
460 GNUNET_free (tmp);
461 json_decref (value);
462 GNUNET_RECLAIM_ticket_iteration_next (handle->ticket_it);
463}
464
465
466
467/**
468 * List tickets for identity request
469 *
470 * @param con_handle the connection handle
471 * @param url the url
472 * @param cls the RequestHandle
473 */
474static void
475list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle,
476 const char* url,
477 void *cls)
478{
479 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
480 struct RequestHandle *handle = cls;
481 struct EgoEntry *ego_entry;
482 char *identity;
483
484 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting tickets for %s.\n",
485 handle->url);
486 if ( strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) >=
487 strlen (handle->url))
488 {
489 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
490 GNUNET_SCHEDULER_add_now (&do_error, handle);
491 return;
492 }
493 identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1;
494
495 for (ego_entry = handle->ego_head;
496 NULL != ego_entry;
497 ego_entry = ego_entry->next)
498 if (0 == strcmp (identity, ego_entry->identifier))
499 break;
500 handle->resp_object = json_array ();
501
502 if (NULL == ego_entry)
503 {
504 //Done
505 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n",
506 identity);
507 GNUNET_SCHEDULER_add_now (&return_response, handle);
508 return;
509 }
510 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
511 handle->idp = GNUNET_RECLAIM_connect (cfg);
512 handle->ticket_it = GNUNET_RECLAIM_ticket_iteration_start (handle->idp,
513 priv_key,
514 &collect_error_cb,
515 handle,
516 &ticket_collect,
517 handle,
518 &collect_finished_cb,
519 handle);
520}
521
522
523static void
524add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
525 const char* url,
526 void *cls)
527{
528 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
529 const char* identity;
530 struct RequestHandle *handle = cls;
531 struct EgoEntry *ego_entry;
532 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attribute;
533 struct GNUNET_TIME_Relative exp;
534 char term_data[handle->rest_handle->data_size+1];
535 json_t *data_json;
536 json_error_t err;
537 struct GNUNET_JSON_Specification attrspec[] = {
538 GNUNET_RECLAIM_JSON_spec_claim (&attribute),
539 GNUNET_JSON_spec_end()
540 };
541
542 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding an attribute for %s.\n",
543 handle->url);
544 if ( strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >=
545 strlen (handle->url))
546 {
547 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
548 GNUNET_SCHEDULER_add_now (&do_error, handle);
549 return;
550 }
551 identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
552
553 for (ego_entry = handle->ego_head;
554 NULL != ego_entry;
555 ego_entry = ego_entry->next)
556 if (0 == strcmp (identity, ego_entry->identifier))
557 break;
558
559 if (NULL == ego_entry)
560 {
561 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
562 "Identity unknown (%s)\n", identity);
563 return;
564 }
565 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
566
567 if (0 >= handle->rest_handle->data_size)
568 {
569 GNUNET_SCHEDULER_add_now (&do_error, handle);
570 return;
571 }
572
573 term_data[handle->rest_handle->data_size] = '\0';
574 GNUNET_memcpy (term_data,
575 handle->rest_handle->data,
576 handle->rest_handle->data_size);
577 data_json = json_loads (term_data,
578 JSON_DECODE_ANY,
579 &err);
580 GNUNET_assert (GNUNET_OK ==
581 GNUNET_JSON_parse (data_json, attrspec,
582 NULL, NULL));
583 json_decref (data_json);
584 if (NULL == attribute)
585 {
586 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
587 "Unable to parse attribute from %s\n",
588 term_data);
589 GNUNET_SCHEDULER_add_now (&do_error, handle);
590 return;
591 }
592 handle->idp = GNUNET_RECLAIM_connect (cfg);
593 handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp,
594 identity_priv,
595 attribute,
596 &exp,
597 &finished_cont,
598 handle);
599 GNUNET_JSON_parse_free (attrspec);
600}
601
602
603
604/**
605 * Collect all attributes for an ego
606 *
607 */
608static void
609attr_collect (void *cls,
610 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
611 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
612{
613 struct RequestHandle *handle = cls;
614 json_t *value;
615 char* tmp_value;
616
617 if ((NULL == attr->name) || (NULL == attr->data))
618 {
619 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
620 return;
621 }
622
623 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n",
624 attr->name);
625
626 tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
627 attr->data,
628 attr->data_size);
629
630 value = json_string (tmp_value);
631
632 json_object_set_new (handle->resp_object,
633 attr->name,
634 value);
635 json_decref (value);
636 GNUNET_free(tmp_value);
637 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
638}
639
640
641
642/**
643 * List attributes for identity request
644 *
645 * @param con_handle the connection handle
646 * @param url the url
647 * @param cls the RequestHandle
648 */
649static void
650list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
651 const char* url,
652 void *cls)
653{
654 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
655 struct RequestHandle *handle = cls;
656 struct EgoEntry *ego_entry;
657 char *identity;
658
659 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting attributes for %s.\n",
660 handle->url);
661 if ( strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >=
662 strlen (handle->url))
663 {
664 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
665 GNUNET_SCHEDULER_add_now (&do_error, handle);
666 return;
667 }
668 identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
669
670 for (ego_entry = handle->ego_head;
671 NULL != ego_entry;
672 ego_entry = ego_entry->next)
673 if (0 == strcmp (identity, ego_entry->identifier))
674 break;
675 handle->resp_object = json_object ();
676
677
678 if (NULL == ego_entry)
679 {
680 //Done
681 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n",
682 identity);
683 GNUNET_SCHEDULER_add_now (&return_response, handle);
684 return;
685 }
686 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
687 handle->idp = GNUNET_RECLAIM_connect (cfg);
688 handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp,
689 priv_key,
690 &collect_error_cb,
691 handle,
692 &attr_collect,
693 handle,
694 &collect_finished_cb,
695 handle);
696}
697
698
699static void
700revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
701 const char* url,
702 void *cls)
703{
704 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
705 struct RequestHandle *handle = cls;
706 struct EgoEntry *ego_entry;
707 struct GNUNET_RECLAIM_Ticket *ticket;
708 struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk;
709 char term_data[handle->rest_handle->data_size+1];
710 json_t *data_json;
711 json_error_t err;
712 struct GNUNET_JSON_Specification tktspec[] = {
713 GNUNET_RECLAIM_JSON_spec_ticket (&ticket),
714 GNUNET_JSON_spec_end()
715 };
716
717 if (0 >= handle->rest_handle->data_size)
718 {
719 GNUNET_SCHEDULER_add_now (&do_error, handle);
720 return;
721 }
722
723 term_data[handle->rest_handle->data_size] = '\0';
724 GNUNET_memcpy (term_data,
725 handle->rest_handle->data,
726 handle->rest_handle->data_size);
727 data_json = json_loads (term_data,
728 JSON_DECODE_ANY,
729 &err);
730 GNUNET_assert (GNUNET_OK ==
731 GNUNET_JSON_parse (data_json, tktspec,
732 NULL, NULL));
733 json_decref (data_json);
734 if (NULL == ticket)
735 {
736 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
737 "Unable to parse ticket from %s\n",
738 term_data);
739 GNUNET_SCHEDULER_add_now (&do_error, handle);
740 return;
741 }
742 if (GNUNET_OK != GNUNET_JSON_parse (data_json,
743 tktspec,
744 NULL, NULL))
745 {
746 handle->emsg = GNUNET_strdup ("Not a ticket!\n");
747 GNUNET_SCHEDULER_add_now (&do_error, handle);
748 GNUNET_JSON_parse_free (tktspec);
749 json_decref (data_json);
750 return;
751 }
752
753 for (ego_entry = handle->ego_head;
754 NULL != ego_entry;
755 ego_entry = ego_entry->next)
756 {
757 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego,
758 &tmp_pk);
759 if (0 == memcmp (&ticket->identity,
760 &tmp_pk,
761 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
762 break;
763 }
764 if (NULL == ego_entry)
765 {
766 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
767 "Identity unknown\n");
768 GNUNET_JSON_parse_free (tktspec);
769 return;
770 }
771 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
772
773 handle->idp = GNUNET_RECLAIM_connect (cfg);
774 handle->idp_op = GNUNET_RECLAIM_ticket_revoke (handle->idp,
775 identity_priv,
776 ticket,
777 &finished_cont,
778 handle);
779 GNUNET_JSON_parse_free (tktspec);
780}
781
782static void
783consume_cont (void *cls,
784 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
785 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
786{
787 struct RequestHandle *handle = cls;
788 char *val_str;
789 json_t *value;
790
791 if (NULL == identity)
792 {
793 GNUNET_SCHEDULER_add_now (&return_response, handle);
794 return;
795 }
796
797 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n",
798 attr->name);
799 val_str = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
800 attr->data,
801 attr->data_size);
802 if (NULL == val_str)
803 {
804 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to parse value for: %s\n",
805 attr->name);
806 return;
807 }
808 value = json_string(val_str);
809 json_object_set_new (handle->resp_object,
810 attr->name,
811 value);
812 json_decref (value);
813 GNUNET_free (val_str);
814}
815
816static void
817consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
818 const char* url,
819 void *cls)
820{
821 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
822 struct RequestHandle *handle = cls;
823 struct EgoEntry *ego_entry;
824 struct GNUNET_RECLAIM_Ticket *ticket;
825 struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk;
826 char term_data[handle->rest_handle->data_size+1];
827 json_t *data_json;
828 json_error_t err;
829 struct GNUNET_JSON_Specification tktspec[] = {
830 GNUNET_RECLAIM_JSON_spec_ticket (&ticket),
831 GNUNET_JSON_spec_end ()
832 };
833
834 if (0 >= handle->rest_handle->data_size)
835 {
836 GNUNET_SCHEDULER_add_now (&do_error, handle);
837 return;
838 }
839
840 term_data[handle->rest_handle->data_size] = '\0';
841 GNUNET_memcpy (term_data,
842 handle->rest_handle->data,
843 handle->rest_handle->data_size);
844 data_json = json_loads (term_data,
845 JSON_DECODE_ANY,
846 &err);
847 if (NULL == data_json)
848 {
849 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
850 "Unable to parse JSON Object from %s\n",
851 term_data);
852 GNUNET_SCHEDULER_add_now (&do_error, handle);
853 return;
854 }
855 if (GNUNET_OK != GNUNET_JSON_parse (data_json,
856 tktspec,
857 NULL, NULL))
858 {
859 handle->emsg = GNUNET_strdup ("Not a ticket!\n");
860 GNUNET_SCHEDULER_add_now (&do_error, handle);
861 GNUNET_JSON_parse_free(tktspec);
862 json_decref (data_json);
863 return;
864 }
865 for (ego_entry = handle->ego_head;
866 NULL != ego_entry;
867 ego_entry = ego_entry->next)
868 {
869 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego,
870 &tmp_pk);
871 if (0 == memcmp (&ticket->audience,
872 &tmp_pk,
873 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
874 break;
875 }
876 if (NULL == ego_entry)
877 {
878 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
879 "Identity unknown\n");
880 GNUNET_JSON_parse_free (tktspec);
881 return;
882 }
883 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
884 handle->resp_object = json_object ();
885 handle->idp = GNUNET_RECLAIM_connect (cfg);
886 handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp,
887 identity_priv,
888 ticket,
889 &consume_cont,
890 handle);
891 GNUNET_JSON_parse_free (tktspec);
892}
893
894
895
896/**
897 * Respond to OPTIONS request
898 *
899 * @param con_handle the connection handle
900 * @param url the url
901 * @param cls the RequestHandle
902 */
903static void
904options_cont (struct GNUNET_REST_RequestHandle *con_handle,
905 const char* url,
906 void *cls)
907{
908 struct MHD_Response *resp;
909 struct RequestHandle *handle = cls;
910
911 //For now, independent of path return all options
912 resp = GNUNET_REST_create_response (NULL);
913 MHD_add_response_header (resp,
914 "Access-Control-Allow-Methods",
915 allow_methods);
916 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
917 cleanup_handle (handle);
918 return;
919}
920
921/**
922 * Handle rest request
923 *
924 * @param handle the request handle
925 */
926static void
927init_cont (struct RequestHandle *handle)
928{
929 struct GNUNET_REST_RequestHandlerError err;
930 static const struct GNUNET_REST_RequestHandler handlers[] = {
931 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &list_attribute_cont},
932 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &add_attribute_cont},
933 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont},
934 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont},
935 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont},
936 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM,
937 &options_cont},
938 GNUNET_REST_HANDLER_END
939 };
940
941 if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle,
942 handlers,
943 &err,
944 handle))
945 {
946 handle->response_code = err.error_code;
947 GNUNET_SCHEDULER_add_now (&do_error, handle);
948 }
949}
950
951/**
952 * If listing is enabled, prints information about the egos.
953 *
954 * This function is initially called for all egos and then again
955 * whenever a ego's identifier changes or if it is deleted. At the
956 * end of the initial pass over all egos, the function is once called
957 * with 'NULL' for 'ego'. That does NOT mean that the callback won't
958 * be invoked in the future or that there was an error.
959 *
960 * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get',
961 * this function is only called ONCE, and 'NULL' being passed in
962 * 'ego' does indicate an error (i.e. name is taken or no default
963 * value is known). If 'ego' is non-NULL and if '*ctx'
964 * is set in those callbacks, the value WILL be passed to a subsequent
965 * call to the identity callback of 'GNUNET_IDENTITY_connect' (if
966 * that one was not NULL).
967 *
968 * When an identity is renamed, this function is called with the
969 * (known) ego but the NEW identifier.
970 *
971 * When an identity is deleted, this function is called with the
972 * (known) ego and "NULL" for the 'identifier'. In this case,
973 * the 'ego' is henceforth invalid (and the 'ctx' should also be
974 * cleaned up).
975 *
976 * @param cls closure
977 * @param ego ego handle
978 * @param ctx context for application to store data for this ego
979 * (during the lifetime of this process, initially NULL)
980 * @param identifier identifier assigned by the user for this ego,
981 * NULL if the user just deleted the ego and it
982 * must thus no longer be used
983 */
984static void
985list_ego (void *cls,
986 struct GNUNET_IDENTITY_Ego *ego,
987 void **ctx,
988 const char *identifier)
989{
990 struct RequestHandle *handle = cls;
991 struct EgoEntry *ego_entry;
992 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
993
994 if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
995 {
996 handle->state = ID_REST_STATE_POST_INIT;
997 init_cont (handle);
998 return;
999 }
1000 if (ID_REST_STATE_INIT == handle->state) {
1001 ego_entry = GNUNET_new (struct EgoEntry);
1002 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
1003 ego_entry->keystring =
1004 GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
1005 ego_entry->ego = ego;
1006 ego_entry->identifier = GNUNET_strdup (identifier);
1007 GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,handle->ego_tail, ego_entry);
1008 }
1009
1010}
1011
1012static void
1013rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle,
1014 GNUNET_REST_ResultProcessor proc,
1015 void *proc_cls)
1016{
1017 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1018 handle->response_code = 0;
1019 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1020 handle->proc_cls = proc_cls;
1021 handle->proc = proc;
1022 handle->state = ID_REST_STATE_INIT;
1023 handle->rest_handle = rest_handle;
1024
1025 handle->url = GNUNET_strdup (rest_handle->url);
1026 if (handle->url[strlen (handle->url)-1] == '/')
1027 handle->url[strlen (handle->url)-1] = '\0';
1028 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1029 "Connecting...\n");
1030 handle->identity_handle = GNUNET_IDENTITY_connect (cfg,
1031 &list_ego,
1032 handle);
1033 handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg);
1034 handle->timeout_task =
1035 GNUNET_SCHEDULER_add_delayed (handle->timeout,
1036 &do_timeout,
1037 handle);
1038 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1039 "Connected\n");
1040}
1041
1042/**
1043 * Entry point for the plugin.
1044 *
1045 * @param cls Config info
1046 * @return NULL on error, otherwise the plugin context
1047 */
1048void *
1049libgnunet_plugin_rest_reclaim_init (void *cls)
1050{
1051 static struct Plugin plugin;
1052 struct GNUNET_REST_Plugin *api;
1053
1054 cfg = cls;
1055 if (NULL != plugin.cfg)
1056 return NULL; /* can only initialize once! */
1057 memset (&plugin, 0, sizeof (struct Plugin));
1058 plugin.cfg = cfg;
1059 api = GNUNET_new (struct GNUNET_REST_Plugin);
1060 api->cls = &plugin;
1061 api->name = GNUNET_REST_API_NS_RECLAIM;
1062 api->process_request = &rest_identity_process_request;
1063 GNUNET_asprintf (&allow_methods,
1064 "%s, %s, %s, %s, %s",
1065 MHD_HTTP_METHOD_GET,
1066 MHD_HTTP_METHOD_POST,
1067 MHD_HTTP_METHOD_PUT,
1068 MHD_HTTP_METHOD_DELETE,
1069 MHD_HTTP_METHOD_OPTIONS);
1070
1071 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1072 _("Identity Provider REST API initialized\n"));
1073 return api;
1074}
1075
1076
1077/**
1078 * Exit point from the plugin.
1079 *
1080 * @param cls the plugin context (as returned by "init")
1081 * @return always NULL
1082 */
1083void *
1084libgnunet_plugin_rest_reclaim_done (void *cls)
1085{
1086 struct GNUNET_REST_Plugin *api = cls;
1087 struct Plugin *plugin = api->cls;
1088 plugin->cfg = NULL;
1089
1090 GNUNET_free_non_null (allow_methods);
1091 GNUNET_free (api);
1092 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1093 "Identity Provider REST plugin is finished\n");
1094 return NULL;
1095}
1096
1097/* end of plugin_rest_reclaim.c */