aboutsummaryrefslogtreecommitdiff
path: root/src/gns
diff options
context:
space:
mode:
authorPhil <phil.buschmann@tum.de>2018-07-26 02:31:30 +0200
committerPhil <phil.buschmann@tum.de>2018-07-26 02:31:30 +0200
commitf7ca27a73e69a8c224d65768be3416ff1388c1d7 (patch)
tree7530a6def74a55885780285162b18b4c2b353380 /src/gns
parentcc577a227d6a5ae8ef75e0fa91ef98ced2d2b743 (diff)
downloadgnunet-f7ca27a73e69a8c224d65768be3416ff1388c1d7.tar.gz
gnunet-f7ca27a73e69a8c224d65768be3416ff1388c1d7.zip
change namestore, json handling; fix identity, gns
Diffstat (limited to 'src/gns')
-rw-r--r--src/gns/plugin_rest_gns.c81
-rw-r--r--src/gns/plugin_rest_gns2.c717
2 files changed, 41 insertions, 757 deletions
diff --git a/src/gns/plugin_rest_gns.c b/src/gns/plugin_rest_gns.c
index 22c908275..aae14153d 100644
--- a/src/gns/plugin_rest_gns.c
+++ b/src/gns/plugin_rest_gns.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012-2015 GNUnet e.V. 3 Copyright (C) 2012-2015 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19 */ 17 */
20/** 18/**
21 * @author Philippe Buschmann 19 * @author Philippe Buschmann
@@ -36,6 +34,7 @@
36#define GNUNET_REST_PARAMETER_GNS_NAME "name" 34#define GNUNET_REST_PARAMETER_GNS_NAME "name"
37 35
38#define GNUNET_REST_PARAMETER_GNS_RECORD_TYPE "record_type" 36#define GNUNET_REST_PARAMETER_GNS_RECORD_TYPE "record_type"
37#define GNUNET_REST_GNS_ERROR_UNKNOWN "Unknown Error"
39 38
40/** 39/**
41 * The configuration handle 40 * The configuration handle
@@ -128,8 +127,9 @@ struct RequestHandle
128 * @param handle Handle to clean up 127 * @param handle Handle to clean up
129 */ 128 */
130static void 129static void
131cleanup_handle (struct RequestHandle *handle) 130cleanup_handle (void *cls)
132{ 131{
132 struct RequestHandle *handle = cls;
133 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 133 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
134 "Cleaning up\n"); 134 "Cleaning up\n");
135 135
@@ -170,20 +170,22 @@ do_error (void *cls)
170{ 170{
171 struct RequestHandle *handle = cls; 171 struct RequestHandle *handle = cls;
172 struct MHD_Response *resp; 172 struct MHD_Response *resp;
173 char *json_error; 173 json_t *json_error = json_object();
174 char *response;
174 175
175 if (NULL == handle->emsg) 176 if (NULL == handle->emsg)
176 handle->emsg = GNUNET_strdup("Unknown Error"); 177 handle->emsg = GNUNET_strdup(GNUNET_REST_GNS_ERROR_UNKNOWN);
178
179 json_object_set_new(json_error,"error", json_string(handle->emsg));
177 180
178 GNUNET_asprintf (&json_error, "{\"error\": \"%s\"}", handle->emsg);
179
180 if (0 == handle->response_code) 181 if (0 == handle->response_code)
181 handle->response_code = MHD_HTTP_OK; 182 handle->response_code = MHD_HTTP_OK;
182 183 response = json_dumps (json_error, 0);
183 resp = GNUNET_REST_create_response (json_error); 184 resp = GNUNET_REST_create_response (response);
184 handle->proc (handle->proc_cls, resp, handle->response_code); 185 handle->proc (handle->proc_cls, resp, handle->response_code);
185 cleanup_handle (handle); 186 json_decref(json_error);
186 GNUNET_free(json_error); 187 GNUNET_free(response);
188 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
187} 189}
188 190
189 191
@@ -201,6 +203,7 @@ handle_gns_response (void *cls,
201 uint32_t rd_count, 203 uint32_t rd_count,
202 const struct GNUNET_GNSRECORD_Data *rd) 204 const struct GNUNET_GNSRECORD_Data *rd)
203{ 205{
206 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "TEST4\n");
204 struct RequestHandle *handle = cls; 207 struct RequestHandle *handle = cls;
205 struct MHD_Response *resp; 208 struct MHD_Response *resp;
206 json_t *result_array; 209 json_t *result_array;
@@ -216,12 +219,6 @@ handle_gns_response (void *cls,
216 GNUNET_SCHEDULER_add_now (&do_error, handle); 219 GNUNET_SCHEDULER_add_now (&do_error, handle);
217 return; 220 return;
218 } 221 }
219 if (0 == rd_count)
220 {
221 handle->emsg = GNUNET_strdup("No result found");
222 GNUNET_SCHEDULER_add_now (&do_error, handle);
223 return;
224 }
225 222
226 result_array = json_array(); 223 result_array = json_array();
227 for (uint32_t i=0;i<rd_count;i++) 224 for (uint32_t i=0;i<rd_count;i++)
@@ -246,7 +243,7 @@ handle_gns_response (void *cls,
246 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 243 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
247 GNUNET_free (result); 244 GNUNET_free (result);
248 json_decref (result_array); 245 json_decref (result_array);
249 cleanup_handle (handle); 246 GNUNET_SCHEDULER_add_now(&cleanup_handle, handle);
250} 247}
251 248
252 249
@@ -264,7 +261,8 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *con_handle,
264{ 261{
265 struct RequestHandle *handle = cls; 262 struct RequestHandle *handle = cls;
266 struct GNUNET_HashCode key; 263 struct GNUNET_HashCode key;
267 int conversion_state; 264 char *record_type;
265 char *name;
268 266
269 GNUNET_CRYPTO_hash (GNUNET_REST_PARAMETER_GNS_NAME, 267 GNUNET_CRYPTO_hash (GNUNET_REST_PARAMETER_GNS_NAME,
270 strlen (GNUNET_REST_PARAMETER_GNS_NAME), 268 strlen (GNUNET_REST_PARAMETER_GNS_NAME),
@@ -277,8 +275,14 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *con_handle,
277 GNUNET_SCHEDULER_add_now (&do_error, handle); 275 GNUNET_SCHEDULER_add_now (&do_error, handle);
278 return; 276 return;
279 } 277 }
280 handle->name = GNUNET_strdup( 278 name = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,&key);
281 GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,&key)); 279 if(0 >= strlen (name))
280 {
281 handle->emsg = GNUNET_strdup("Length of parameter name is zero");
282 GNUNET_SCHEDULER_add_now (&do_error, handle);
283 return;
284 }
285 handle->name = GNUNET_strdup(name);
282 286
283 GNUNET_CRYPTO_hash (GNUNET_REST_PARAMETER_GNS_RECORD_TYPE, 287 GNUNET_CRYPTO_hash (GNUNET_REST_PARAMETER_GNS_RECORD_TYPE,
284 strlen (GNUNET_REST_PARAMETER_GNS_RECORD_TYPE), 288 strlen (GNUNET_REST_PARAMETER_GNS_RECORD_TYPE),
@@ -291,11 +295,13 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *con_handle,
291 GNUNET_SCHEDULER_add_now (&do_error, handle); 295 GNUNET_SCHEDULER_add_now (&do_error, handle);
292 return; 296 return;
293 } 297 }
294 conversion_state = sscanf (
295 GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, &key),"%u",
296 &(handle->record_type));
297 298
298 if((EOF == conversion_state) || (0 == conversion_state)) 299
300 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "TEST1\n");
301
302 record_type = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, &key);
303 handle->record_type = GNUNET_GNSRECORD_typename_to_number(record_type);
304 if(UINT32_MAX == handle->record_type)
299 { 305 {
300 handle->record_type = GNUNET_GNSRECORD_TYPE_ANY; 306 handle->record_type = GNUNET_GNSRECORD_TYPE_ANY;
301 } 307 }
@@ -307,6 +313,7 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *con_handle,
307 GNUNET_SCHEDULER_add_now (&do_error, handle); 313 GNUNET_SCHEDULER_add_now (&do_error, handle);
308 return; 314 return;
309 } 315 }
316 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "TEST2\n");
310 317
311 handle->gns_lookup = GNUNET_GNS_lookup_with_tld (handle->gns, 318 handle->gns_lookup = GNUNET_GNS_lookup_with_tld (handle->gns,
312 handle->name, 319 handle->name,
@@ -314,13 +321,7 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *con_handle,
314 GNUNET_NO, 321 GNUNET_NO,
315 &handle_gns_response, 322 &handle_gns_response,
316 handle); 323 handle);
317 324 return;
318 if (NULL == handle->gns_lookup)
319 {
320 handle->emsg = GNUNET_strdup("GNS lookup failed");
321 GNUNET_SCHEDULER_add_now (&do_error, handle);
322 return;
323 }
324} 325}
325 326
326 327
@@ -346,7 +347,7 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
346 "Access-Control-Allow-Methods", 347 "Access-Control-Allow-Methods",
347 allow_methods); 348 allow_methods);
348 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 349 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
349 cleanup_handle (handle); 350 GNUNET_SCHEDULER_add_now(&cleanup_handle, handle);
350 return; 351 return;
351} 352}
352 353
diff --git a/src/gns/plugin_rest_gns2.c b/src/gns/plugin_rest_gns2.c
deleted file mode 100644
index 82d62744c..000000000
--- a/src/gns/plugin_rest_gns2.c
+++ /dev/null
@@ -1,717 +0,0 @@
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 gns/plugin_rest_gns.c
22 * @brief GNUnet GNS REST plugin
23 *
24 */
25
26#include "platform.h"
27#include "gnunet_rest_plugin.h"
28#include <gnunet_dnsparser_lib.h>
29#include <gnunet_identity_service.h>
30#include <gnunet_gnsrecord_lib.h>
31#include <gnunet_namestore_service.h>
32#include <gnunet_gns_service.h>
33#include <gnunet_rest_lib.h>
34#include <gnunet_jsonapi_lib.h>
35#include <gnunet_jsonapi_util.h>
36#include <jansson.h>
37
38#define GNUNET_REST_API_NS_GNS "/gns"
39
40#define GNUNET_REST_JSONAPI_GNS_RECORD_TYPE "record_type"
41
42#define GNUNET_REST_PARAMETER_GNS_NAME "name"
43
44#define GNUNET_REST_JSONAPI_GNS_TYPEINFO "gns_name"
45
46#define GNUNET_REST_JSONAPI_GNS_RECORD "records"
47
48#define GNUNET_REST_JSONAPI_GNS_EGO "ego"
49
50#define GNUNET_REST_JSONAPI_GNS_PKEY "pkey"
51
52#define GNUNET_REST_JSONAPI_GNS_OPTIONS "options"
53
54/**
55 * @brief struct returned by the initialization function of the plugin
56 */
57struct Plugin
58{
59 const struct GNUNET_CONFIGURATION_Handle *cfg;
60};
61
62const struct GNUNET_CONFIGURATION_Handle *cfg;
63
64struct LookupHandle
65{
66 /**
67 * Handle to GNS service.
68 */
69 struct GNUNET_GNS_Handle *gns;
70
71 /**
72 * Desired timeout for the lookup (default is no timeout).
73 */
74 struct GNUNET_TIME_Relative timeout;
75
76 /**
77 * Handle to lookup request
78 */
79 struct GNUNET_GNS_LookupRequest *lookup_request;
80
81 /**
82 * Handle to rest request
83 */
84 struct GNUNET_REST_RequestHandle *rest_handle;
85
86 /**
87 * Lookup an ego with the identity service.
88 */
89 struct GNUNET_IDENTITY_EgoLookup *el;
90
91 /**
92 * Handle for identity service.
93 */
94 struct GNUNET_IDENTITY_Handle *identity;
95
96 /**
97 * Active operation on identity service.
98 */
99 struct GNUNET_IDENTITY_Operation *id_op;
100
101 /**
102 * ID of a task associated with the resolution process.
103 */
104 struct GNUNET_SCHEDULER_Task * timeout_task;
105
106 /**
107 * The root of the received JSON or NULL
108 */
109 json_t *json_root;
110
111 /**
112 * The plugin result processor
113 */
114 GNUNET_REST_ResultProcessor proc;
115
116 /**
117 * The closure of the result processor
118 */
119 void *proc_cls;
120
121 /**
122 * The name to look up
123 */
124 char *name;
125
126 /**
127 * The ego to use
128 * In string representation from JSON
129 */
130 const char *ego_str;
131
132 /**
133 * The Pkey to use
134 * In string representation from JSON
135 */
136 const char *pkey_str;
137
138 /**
139 * The record type
140 */
141 int type;
142
143 /**
144 * The public key of to use for lookup
145 */
146 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
147
148 /**
149 * The public key to use for lookup
150 */
151 struct GNUNET_CRYPTO_EcdsaPublicKey pkeym;
152
153 /**
154 * The resolver options
155 */
156 enum GNUNET_GNS_LocalOptions options;
157
158 /**
159 * the shorten key
160 */
161 struct GNUNET_CRYPTO_EcdsaPrivateKey shorten_key;
162
163 /**
164 * HTTP response code
165 */
166 int response_code;
167
168 /**
169 * HTTP response code
170 */
171 char* emsg;
172
173};
174
175
176/**
177 * Cleanup lookup handle.
178 *
179 * @param handle Handle to clean up
180 */
181static void
182cleanup_handle (struct LookupHandle *handle)
183{
184 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
185 "Cleaning up\n");
186 if (NULL != handle->json_root)
187 json_decref (handle->json_root);
188
189 if (NULL != handle->name)
190 GNUNET_free (handle->name);
191 if (NULL != handle->emsg)
192 GNUNET_free (handle->emsg);
193 if (NULL != handle->el)
194 {
195 GNUNET_IDENTITY_ego_lookup_cancel (handle->el);
196 handle->el = NULL;
197 }
198 if (NULL != handle->id_op)
199 {
200 GNUNET_IDENTITY_cancel (handle->id_op);
201 handle->id_op = NULL;
202 }
203 if (NULL != handle->lookup_request)
204 {
205 GNUNET_GNS_lookup_cancel (handle->lookup_request);
206 handle->lookup_request = NULL;
207 }
208 if (NULL != handle->identity)
209 {
210 GNUNET_IDENTITY_disconnect (handle->identity);
211 handle->identity = NULL;
212 }
213 if (NULL != handle->gns)
214 {
215 GNUNET_GNS_disconnect (handle->gns);
216 handle->gns = NULL;
217 }
218
219 if (NULL != handle->timeout_task)
220 {
221 GNUNET_SCHEDULER_cancel (handle->timeout_task);
222 }
223 GNUNET_free (handle);
224}
225
226
227/**
228 * Task run on shutdown. Cleans up everything.
229 *
230 * @param cls unused
231 * @param tc scheduler context
232 */
233static void
234do_error (void *cls)
235{
236 struct LookupHandle *handle = cls;
237 struct MHD_Response *resp;
238 char *json_error;
239
240 if (NULL == handle->emsg)
241 handle->emsg = GNUNET_strdup("Unknown Error");
242
243 GNUNET_asprintf (&json_error, "{\"error\": \"%s\"}", handle->emsg);
244 handle->response_code = MHD_HTTP_OK;
245
246 resp = GNUNET_REST_create_response (json_error);
247 handle->proc (handle->proc_cls, resp, handle->response_code);
248 cleanup_handle (handle);
249 GNUNET_free(json_error);
250}
251
252
253/**
254 * Create json representation of a GNSRECORD
255 *
256 * @param rd the GNSRECORD_Data
257 */
258static json_t *
259gnsrecord_to_json (const struct GNUNET_GNSRECORD_Data *rd)
260{
261 const char *typename;
262 char *string_val;
263 const char *exp_str;
264 json_t *record_obj;
265
266 typename = GNUNET_GNSRECORD_number_to_typename (rd->record_type);
267 string_val = GNUNET_GNSRECORD_value_to_string (rd->record_type,
268 rd->data,
269 rd->data_size);
270
271 if (NULL == string_val)
272 {
273 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
274 "Record of type %d malformed, skipping\n",
275 (int) rd->record_type);
276 return NULL;
277 }
278 record_obj = json_object ();
279 json_object_set_new (record_obj, "type", json_string (typename));
280 json_object_set_new (record_obj, "value", json_string (string_val));
281 GNUNET_free (string_val);
282
283 if (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION & rd->flags)
284 {
285 struct GNUNET_TIME_Relative time_rel;
286 time_rel.rel_value_us = rd->expiration_time;
287 exp_str = GNUNET_STRINGS_relative_time_to_string (time_rel, 1);
288 }
289 else
290 {
291 struct GNUNET_TIME_Absolute time_abs;
292 time_abs.abs_value_us = rd->expiration_time;
293 exp_str = GNUNET_STRINGS_absolute_time_to_string (time_abs);
294 }
295 json_object_set_new (record_obj, "expiration_time", json_string (exp_str));
296
297 json_object_set_new (record_obj, "expired",
298 json_boolean (GNUNET_YES == GNUNET_GNSRECORD_is_expired (rd)));
299 return record_obj;
300}
301
302/**
303 * Function called with the result of a GNS lookup.
304 *
305 * @param cls the 'const char *' name that was resolved
306 * @param rd_count number of records returned
307 * @param rd array of @a rd_count records with the results
308 */
309static void
310process_lookup_result (void *cls, uint32_t rd_count,
311 const struct GNUNET_GNSRECORD_Data *rd)
312{
313 struct LookupHandle *handle = cls;
314 struct MHD_Response *resp;
315 uint32_t i;
316 char *result;
317 json_t *result_array;
318 json_t *record_obj;
319
320 result_array = json_array();
321 handle->lookup_request = NULL;
322 for (i=0; i<rd_count; i++)
323 {
324 if ( (rd[i].record_type != handle->type) &&
325 (GNUNET_GNSRECORD_TYPE_ANY != handle->type) )
326 continue;
327 record_obj = gnsrecord_to_json (&(rd[i]));
328 json_array_append (result_array, record_obj);
329 json_decref (record_obj);
330 }
331 result = json_dumps(result_array, 0);
332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result);
333 resp = GNUNET_REST_create_response (result);
334 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
335 GNUNET_free (result);
336 json_decref (result_array);
337 cleanup_handle (handle);
338}
339
340
341/**
342 * Perform the actual resolution, starting with the zone
343 * identified by the given public key and the shorten zone.
344 *
345 * @param pkey public key to use for the zone, can be NULL
346 */
347static void
348lookup_with_public_key (struct LookupHandle *handle)
349{
350 if (UINT32_MAX == handle->type)
351 {
352 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
353 _("Invalid typename specified, assuming `ANY'\n"));
354 handle->type = GNUNET_GNSRECORD_TYPE_ANY;
355 }
356 if (NULL != handle->name)
357 {
358 handle->lookup_request = GNUNET_GNS_lookup (handle->gns,
359 handle->name,
360 &handle->pkey,
361 handle->type,
362 handle->options,
363 &process_lookup_result,
364 handle);
365 }
366 else
367 {
368 handle->emsg = GNUNET_strdup("Parameter name is missing");
369 GNUNET_SCHEDULER_add_now (&do_error, handle);
370 return;
371 }
372}
373
374
375/**
376 * Method called to with the ego we are to use for the lookup,
377 * when the ego is determined by a name.
378 *
379 * @param cls closure (NULL, unused)
380 * @param ego ego handle, NULL if not found
381 */
382static void
383identity_zone_cb (void *cls,
384 const struct GNUNET_IDENTITY_Ego *ego)
385{
386 struct LookupHandle *handle = cls;
387
388 handle->el = NULL;
389 if (NULL == ego)
390 {
391 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
392 _("Ego for not found, cannot perform lookup.\n"));
393 handle->emsg = GNUNET_strdup ("Ego for not found, cannot perform lookup.");
394 GNUNET_SCHEDULER_add_now (&do_error, handle);
395 return;
396 }
397 else
398 {
399 GNUNET_IDENTITY_ego_get_public_key (ego, &handle->pkey);
400 lookup_with_public_key (handle);
401 }
402 json_decref(handle->json_root);
403}
404
405
406/**
407 * Method called to with the ego we are to use for the lookup,
408 * when the ego is the one for the default master zone.
409 *
410 * @param cls closure (NULL, unused)
411 * @param ego ego handle, NULL if not found
412 * @param ctx context for application to store data for this ego
413 * (during the lifetime of this process, initially NULL)
414 * @param name name assigned by the user for this ego,
415 * NULL if the user just deleted the ego and it
416 * must thus no longer be used
417 */
418static void
419identity_master_cb (void *cls,
420 struct GNUNET_IDENTITY_Ego *ego,
421 void **ctx,
422 const char *name)
423{
424 const char *dot;
425 struct LookupHandle *handle = cls;
426
427 handle->id_op = NULL;
428 if (NULL == ego)
429 {
430 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
431 _("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?\n"));
432 handle->emsg = GNUNET_strdup("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?");
433 GNUNET_SCHEDULER_add_now (&do_error, handle);
434 return;
435 }
436 GNUNET_IDENTITY_ego_get_public_key (ego,
437 &handle->pkey);
438 /* main name is our own master zone, do no look for that in the DHT */
439 handle->options = GNUNET_GNS_LO_LOCAL_MASTER;
440 /* if the name is of the form 'label.gnu', never go to the DHT */
441 dot = NULL;
442 if (NULL != handle->name)
443 dot = strchr (handle->name, '.');
444 if ( (NULL != dot) &&
445 (0 == strcasecmp (dot, ".gnu")) )
446 handle->options = GNUNET_GNS_LO_NO_DHT;
447 lookup_with_public_key (handle);
448}
449
450/**
451 * Handle get request
452 *
453 * @param handle the lookup handle
454 */
455static void
456get_gns_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
457 const char* url,
458 void *cls)
459{
460 struct LookupHandle *handle = cls;
461 struct GNUNET_HashCode key;
462 long int enum_test;
463 char *temp_val;
464
465 //check for /gns otherwise 404
466 if (strlen (GNUNET_REST_API_NS_GNS) > strlen (url))
467 {
468 handle->emsg = GNUNET_strdup("Wrong URL");
469 GNUNET_SCHEDULER_add_now (&do_error, handle);
470 return;
471 }
472
473 //connect to gns
474 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
475 handle->gns = GNUNET_GNS_connect (cfg);
476 handle->identity = GNUNET_IDENTITY_connect (cfg, NULL, NULL);
477 handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout,
478 &do_error, handle);
479 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
480 if (NULL == handle->gns)
481 {
482 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Connecting to GNS failed\n");
483 handle->emsg = GNUNET_strdup("Connecting to GNS failed");
484 GNUNET_SCHEDULER_add_now (&do_error, handle);
485 return;
486 }
487
488 //check parameter name -> BAD_REQUEST
489 GNUNET_CRYPTO_hash (GNUNET_REST_PARAMETER_GNS_NAME,
490 strlen (GNUNET_REST_PARAMETER_GNS_NAME),
491 &key);
492 if ( GNUNET_NO
493 == GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
494 &key))
495 {
496 handle->emsg = GNUNET_strdup("Parameter name is missing");
497 GNUNET_SCHEDULER_add_now (&do_error, handle);
498 return;
499 }
500 handle->name = GNUNET_strdup(GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
501 &key));
502
503 //check parameter record_type, optional
504 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_RECORD_TYPE,
505 strlen (GNUNET_REST_JSONAPI_GNS_RECORD_TYPE),
506 &key);
507 if ( GNUNET_YES ==
508 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
509 &key) )
510 {
511 handle->type = GNUNET_GNSRECORD_typename_to_number(
512 GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
513 &key));
514 }
515 else
516 {
517 handle->type = GNUNET_GNSRECORD_TYPE_ANY;
518 }
519
520 //check parameter options, optional
521 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_OPTIONS,
522 strlen (GNUNET_REST_JSONAPI_GNS_OPTIONS),
523 &key);
524 handle->options = GNUNET_GNS_LO_DEFAULT;
525 if ( GNUNET_YES
526 == GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
527 &key))
528 {
529 temp_val = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, &key);
530 if (1 < strlen(temp_val))
531 {
532 handle->options = GNUNET_GNS_LO_DEFAULT;
533 }
534 else
535 {
536 //atoi because no valid conversion is default local option
537 enum_test = atoi(temp_val);
538 if (2 < enum_test)
539 handle->options = GNUNET_GNS_LO_DEFAULT;
540 else
541 handle->options = enum_test;
542 }
543 }
544 else
545 handle->options = GNUNET_GNS_LO_DEFAULT;
546
547 //check parameter pkey, shortcut to lookup
548 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_PKEY,
549 strlen (GNUNET_REST_JSONAPI_GNS_PKEY),
550 &key);
551 if ( GNUNET_YES
552 == GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
553 &key))
554 {
555 handle->pkey_str = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
556 &key);
557 GNUNET_assert(NULL != handle->pkey_str);
558 if (GNUNET_OK
559 != GNUNET_CRYPTO_ecdsa_public_key_from_string (
560 handle->pkey_str, strlen (handle->pkey_str), &(handle->pkey)))
561 {
562 handle->emsg = GNUNET_strdup("Parameter pkey has a wrong format");
563 GNUNET_SCHEDULER_add_now (&do_error, handle);
564 return;
565 }
566 lookup_with_public_key (handle);
567 return;
568 }
569
570 //check parameter ego, lookup public key of ego
571 GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_EGO,
572 strlen (GNUNET_REST_JSONAPI_GNS_EGO),
573 &key);
574 if ( GNUNET_YES ==
575 GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
576 &key) )
577 {
578 handle->ego_str = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
579 &key);
580 handle->el = GNUNET_IDENTITY_ego_lookup (cfg,
581 handle->ego_str,
582 &identity_zone_cb,
583 handle);
584 return;
585 }
586
587 //if name ends with .zkey then get public key
588 if ( (NULL != handle->name) &&
589 (strlen (handle->name) > 4) &&
590 (0 == strcmp (".zkey",
591 &handle->name[strlen (handle->name) - 4])) )
592 {
593 GNUNET_CRYPTO_ecdsa_key_get_public( GNUNET_CRYPTO_ecdsa_key_get_anonymous (),
594 &(handle->pkey));
595 lookup_with_public_key (handle);
596 }
597 else //else use gns-master identity
598 {
599 handle->id_op = GNUNET_IDENTITY_get (handle->identity,
600 "gns-master",
601 &identity_master_cb,
602 handle);
603 }
604}
605
606/**
607 * Handle rest request
608 *
609 * @param handle the lookup handle
610 */
611static void
612options_cont (struct GNUNET_REST_RequestHandle *con_handle,
613 const char* url,
614 void *cls)
615{
616 struct MHD_Response *resp;
617 struct LookupHandle *handle = cls;
618
619 //For GNS, independent of path return all options
620 resp = GNUNET_REST_create_response (NULL);
621 MHD_add_response_header (resp,
622 "Access-Control-Allow-Methods",
623 MHD_HTTP_METHOD_GET);
624 handle->proc (handle->proc_cls,
625 resp,
626 MHD_HTTP_OK);
627 cleanup_handle (handle);
628}
629
630
631/**
632 * Function processing the REST call
633 *
634 * @param method HTTP method
635 * @param url URL of the HTTP request
636 * @param data body of the HTTP request (optional)
637 * @param data_size length of the body
638 * @param proc callback function for the result
639 * @param proc_cls closure for @a proc
640 * @return #GNUNET_OK if request accepted
641 */
642static void
643rest_gns_process_request (struct GNUNET_REST_RequestHandle *conndata_handle,
644 GNUNET_REST_ResultProcessor proc,
645 void *proc_cls)
646{
647 static const struct GNUNET_REST_RequestHandler handlers[] = {
648 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_GNS, &get_gns_cont},
649 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_GNS, &options_cont},
650 GNUNET_REST_HANDLER_END
651 };
652 struct LookupHandle *handle = GNUNET_new (struct LookupHandle);
653 struct GNUNET_REST_RequestHandlerError err;
654
655 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
656 handle->proc_cls = proc_cls;
657 handle->proc = proc;
658 handle->rest_handle = conndata_handle;
659
660 if (GNUNET_NO == GNUNET_REST_handle_request (conndata_handle,
661 handlers,
662 &err,
663 handle))
664 {
665 handle->response_code = err.error_code;
666 GNUNET_SCHEDULER_add_now (&do_error, handle);
667 }
668}
669
670
671/**
672 * Entry point for the plugin.
673 *
674 * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*"
675 * @return NULL on error, otherwise the plugin context
676 */
677void *
678libgnunet_plugin_rest_gns_init (void *cls)
679{
680 static struct Plugin plugin;
681 cfg = cls;
682 struct GNUNET_REST_Plugin *api;
683
684 if (NULL != plugin.cfg)
685 return NULL; /* can only initialize once! */
686 memset (&plugin, 0, sizeof (struct Plugin));
687 plugin.cfg = cfg;
688 api = GNUNET_new (struct GNUNET_REST_Plugin);
689 api->cls = &plugin;
690 api->name = GNUNET_REST_API_NS_GNS;
691 api->process_request = &rest_gns_process_request;
692 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
693 _("GNS REST API initialized\n"));
694 return api;
695}
696
697
698/**
699 * Exit point from the plugin.
700 *
701 * @param cls the plugin context (as returned by "init")
702 * @return always NULL
703 */
704void *
705libgnunet_plugin_rest_gns_done (void *cls)
706{
707 struct GNUNET_REST_Plugin *api = cls;
708 struct Plugin *plugin = api->cls;
709
710 plugin->cfg = NULL;
711 GNUNET_free (api);
712 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
713 "GNS REST plugin is finished\n");
714 return NULL;
715}
716
717/* end of plugin_rest_gns.c */