diff options
Diffstat (limited to 'src/credential')
-rw-r--r-- | src/credential/Makefile.am | 113 | ||||
-rw-r--r-- | src/credential/credential.conf.in | 5 | ||||
-rw-r--r-- | src/credential/credential.h | 91 | ||||
-rw-r--r-- | src/credential/credential_api.c | 410 | ||||
-rw-r--r-- | src/credential/gnunet-credential.c | 382 | ||||
-rw-r--r-- | src/credential/gnunet-service-credential.c | 425 | ||||
-rw-r--r-- | src/credential/plugin_gnsrecord_credential.c | 257 | ||||
-rwxr-xr-x | src/credential/test_credential_lookup.sh | 40 |
8 files changed, 1723 insertions, 0 deletions
diff --git a/src/credential/Makefile.am b/src/credential/Makefile.am new file mode 100644 index 000000000..6469895e3 --- /dev/null +++ b/src/credential/Makefile.am | |||
@@ -0,0 +1,113 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include | ||
3 | |||
4 | EXTRA_DIST = \ | ||
5 | test_credential_defaults.conf \ | ||
6 | test_credential_lookup.conf | ||
7 | # test_gns_nick_shorten.conf \ | ||
8 | #### test_gns_proxy.conf \ | ||
9 | # test_gns_simple_lookup.conf \ | ||
10 | # gns-helper-service-w32.conf \ | ||
11 | # w32nsp.def \ | ||
12 | # gnunet-gns-proxy-setup-ca \ | ||
13 | # zonefiles/J7POEUT41A8PBFS7KVVDRF88GBOU4HK8PSU5QKVLVE3R9T91E99G.zkey \ | ||
14 | # zonefiles/OEFL7A4VEF1B40QLEMTG5D8G1CN6EN16QUSG5R2DT71GRJN34LSG.zkey \ | ||
15 | # zonefiles/test_zonekey \ | ||
16 | # $(check_SCRIPTS) | ||
17 | |||
18 | |||
19 | if USE_COVERAGE | ||
20 | AM_CFLAGS = --coverage -O0 | ||
21 | endif | ||
22 | |||
23 | pkgcfgdir = $(pkgdatadir)/config.d/ | ||
24 | |||
25 | libexecdir= $(pkglibdir)/libexec/ | ||
26 | |||
27 | plugindir = $(libdir)/gnunet | ||
28 | |||
29 | pkgcfg_DATA = \ | ||
30 | credential.conf | ||
31 | |||
32 | |||
33 | # /usr/lib - compiles a layer which can be used to be communicagte with the service | ||
34 | lib_LTLIBRARIES = \ | ||
35 | libgnunetcredential.la | ||
36 | |||
37 | # /usr/lib/gnunet/libexec - Business logic . Separate process | ||
38 | libexec_PROGRAMS = \ | ||
39 | gnunet-service-credential | ||
40 | |||
41 | bin_PROGRAMS = \ | ||
42 | gnunet-credential | ||
43 | |||
44 | plugin_LTLIBRARIES = \ | ||
45 | libgnunet_plugin_gnsrecord_credential.la | ||
46 | |||
47 | |||
48 | #if HAVE_MHD | ||
49 | #if HAVE_JSON | ||
50 | #plugin_LTLIBRARIES += libgnunet_plugin_rest_gns.la | ||
51 | #endif | ||
52 | #endif | ||
53 | |||
54 | |||
55 | gnunet_credential_SOURCES = \ | ||
56 | gnunet-credential.c | ||
57 | gnunet_credential_LDADD = \ | ||
58 | libgnunetcredential.la \ | ||
59 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
60 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
61 | $(GN_LIBINTL) | ||
62 | |||
63 | |||
64 | libgnunet_plugin_gnsrecord_credential_la_SOURCES = \ | ||
65 | plugin_gnsrecord_credential.c | ||
66 | libgnunet_plugin_gnsrecord_credential_la_LIBADD = \ | ||
67 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
68 | $(LTLIBINTL) | ||
69 | libgnunet_plugin_gnsrecord_credential_la_LDFLAGS = \ | ||
70 | $(GN_PLUGIN_LDFLAGS) | ||
71 | |||
72 | |||
73 | |||
74 | gnunet_service_credential_SOURCES = \ | ||
75 | gnunet-service-credential.c | ||
76 | gnunet_service_credential_LDADD = \ | ||
77 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
78 | $(top_builddir)/src/gns/libgnunetgns.la \ | ||
79 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | ||
80 | $(GN_LIBINTL) | ||
81 | |||
82 | |||
83 | libgnunetcredential_la_SOURCES = \ | ||
84 | credential_api.c credential.h | ||
85 | libgnunetcredential_la_LIBADD = \ | ||
86 | $(top_builddir)/src/util/libgnunetutil.la $(XLIB) | ||
87 | libgnunetcredential_la_LDFLAGS = \ | ||
88 | $(GN_LIB_LDFLAGS) | ||
89 | |||
90 | |||
91 | #libgnunet_plugin_rest_gns_la_SOURCES = \ | ||
92 | # plugin_rest_gns.c | ||
93 | #libgnunet_plugin_rest_gns_la_LIBADD = \ | ||
94 | # libgnunetgns.la \ | ||
95 | # $(top_builddir)/src/rest/libgnunetrest.la \ | ||
96 | # $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
97 | # $(top_builddir)/src/jsonapi/libgnunetjsonapi.la \ | ||
98 | # $(top_builddir)/src/jsonapi/libgnunetjsonapiutils.la \ | ||
99 | # $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ | ||
100 | # $(LTLIBINTL) -ljansson -lmicrohttpd | ||
101 | #libgnunet_plugin_rest_gns_la_LDFLAGS = \ | ||
102 | # $(GN_PLUGIN_LDFLAGS) | ||
103 | |||
104 | |||
105 | #check_SCRIPTS = \ | ||
106 | #test_gns_lookup.sh | ||
107 | |||
108 | if ENABLE_TEST_RUN | ||
109 | if HAVE_SQLITE | ||
110 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH; | ||
111 | TESTS = $(check_SCRIPTS) | ||
112 | endif | ||
113 | endif | ||
diff --git a/src/credential/credential.conf.in b/src/credential/credential.conf.in new file mode 100644 index 000000000..71f3066ca --- /dev/null +++ b/src/credential/credential.conf.in | |||
@@ -0,0 +1,5 @@ | |||
1 | [credential] | ||
2 | BINARY = gnunet-service-credential | ||
3 | UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-credential.sock | ||
4 | USER_SERVICE = YES | ||
5 | OPTIONS = -L DEBUG \ No newline at end of file | ||
diff --git a/src/credential/credential.h b/src/credential/credential.h new file mode 100644 index 000000000..597c34a3d --- /dev/null +++ b/src/credential/credential.h | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2012-2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file credential/credential.h | ||
22 | * @brief IPC messages between CREDENTIAL API and CREDENTIAL service | ||
23 | * @author Adnan Husain | ||
24 | */ | ||
25 | #ifndef CREDENTIAL_H | ||
26 | #define CREDENTIAL_H | ||
27 | |||
28 | #include "gnunet_credential_service.h" | ||
29 | |||
30 | GNUNET_NETWORK_STRUCT_BEGIN | ||
31 | |||
32 | /** | ||
33 | * Message from client to Credential service to lookup credentials. | ||
34 | */ | ||
35 | struct LookupMessage | ||
36 | { | ||
37 | /** | ||
38 | * Header of type #GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP | ||
39 | */ | ||
40 | struct GNUNET_MessageHeader header; | ||
41 | |||
42 | /** | ||
43 | * Subject public key | ||
44 | */ | ||
45 | struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; | ||
46 | |||
47 | /** | ||
48 | * Trust anchor | ||
49 | */ | ||
50 | struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; | ||
51 | |||
52 | /** | ||
53 | * Unique identifier for this request (for key collisions). | ||
54 | */ | ||
55 | uint32_t id GNUNET_PACKED; | ||
56 | |||
57 | /* Followed by the zero-terminated credential to look up */ | ||
58 | |||
59 | }; | ||
60 | |||
61 | |||
62 | /** | ||
63 | * Message from CREDENTIAL service to client: new results. | ||
64 | */ | ||
65 | struct LookupResultMessage | ||
66 | { | ||
67 | /** | ||
68 | * Header of type #GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP_RESULT | ||
69 | */ | ||
70 | struct GNUNET_MessageHeader header; | ||
71 | |||
72 | /** | ||
73 | * Unique identifier for this request (for key collisions). | ||
74 | */ | ||
75 | uint32_t id GNUNET_PACKED; | ||
76 | |||
77 | |||
78 | /** | ||
79 | * The number of credentials in the response | ||
80 | */ | ||
81 | uint32_t cd_count GNUNET_PACKED; | ||
82 | |||
83 | /* followed by cd_count GNUNET_CREDENTIAL_RecordData structs*/ | ||
84 | |||
85 | }; | ||
86 | |||
87 | |||
88 | GNUNET_NETWORK_STRUCT_END | ||
89 | |||
90 | #endif | ||
91 | |||
diff --git a/src/credential/credential_api.c b/src/credential/credential_api.c new file mode 100644 index 000000000..1efe2d089 --- /dev/null +++ b/src/credential/credential_api.c | |||
@@ -0,0 +1,410 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2009-2013, 2016 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file credential/credential_api.c | ||
22 | * @brief library to access the CREDENTIAL service | ||
23 | * @author Adnan Husain | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "gnunet_util_lib.h" | ||
27 | #include "gnunet_constants.h" | ||
28 | #include "gnunet_arm_service.h" | ||
29 | #include "gnunet_hello_lib.h" | ||
30 | #include "gnunet_protocols.h" | ||
31 | #include "credential.h" | ||
32 | #include "gnunet_credential_service.h" | ||
33 | #include "gnunet_identity_service.h" | ||
34 | |||
35 | |||
36 | #define LOG(kind,...) GNUNET_log_from (kind, "credential-api",__VA_ARGS__) | ||
37 | |||
38 | /** | ||
39 | * Handle to a lookup request | ||
40 | */ | ||
41 | struct GNUNET_CREDENTIAL_LookupRequest | ||
42 | { | ||
43 | |||
44 | /** | ||
45 | * DLL | ||
46 | */ | ||
47 | struct GNUNET_CREDENTIAL_LookupRequest *next; | ||
48 | |||
49 | /** | ||
50 | * DLL | ||
51 | */ | ||
52 | struct GNUNET_CREDENTIAL_LookupRequest *prev; | ||
53 | |||
54 | /** | ||
55 | * handle to credential service | ||
56 | */ | ||
57 | struct GNUNET_CREDENTIAL_Handle *credential_handle; | ||
58 | |||
59 | /** | ||
60 | * processor to call on lookup result | ||
61 | */ | ||
62 | GNUNET_CREDENTIAL_LookupResultProcessor lookup_proc; | ||
63 | |||
64 | /** | ||
65 | * @e lookup_proc closure | ||
66 | */ | ||
67 | void *proc_cls; | ||
68 | |||
69 | /** | ||
70 | * Envelope with the message for this queue entry. | ||
71 | */ | ||
72 | struct GNUNET_MQ_Envelope *env; | ||
73 | |||
74 | /** | ||
75 | * request id | ||
76 | */ | ||
77 | uint32_t r_id; | ||
78 | |||
79 | }; | ||
80 | |||
81 | |||
82 | /** | ||
83 | * Connection to the CREDENTIAL service. | ||
84 | */ | ||
85 | struct GNUNET_CREDENTIAL_Handle | ||
86 | { | ||
87 | |||
88 | /** | ||
89 | * Configuration to use. | ||
90 | */ | ||
91 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
92 | |||
93 | /** | ||
94 | * Connection to service (if available). | ||
95 | */ | ||
96 | struct GNUNET_MQ_Handle *mq; | ||
97 | |||
98 | /** | ||
99 | * Head of linked list of active lookup requests. | ||
100 | */ | ||
101 | struct GNUNET_CREDENTIAL_LookupRequest *lookup_head; | ||
102 | |||
103 | /** | ||
104 | * Tail of linked list of active lookup requests. | ||
105 | */ | ||
106 | struct GNUNET_CREDENTIAL_LookupRequest *lookup_tail; | ||
107 | |||
108 | /** | ||
109 | * Reconnect task | ||
110 | */ | ||
111 | struct GNUNET_SCHEDULER_Task *reconnect_task; | ||
112 | |||
113 | /** | ||
114 | * How long do we wait until we try to reconnect? | ||
115 | */ | ||
116 | struct GNUNET_TIME_Relative reconnect_backoff; | ||
117 | |||
118 | /** | ||
119 | * Request Id generator. Incremented by one for each request. | ||
120 | */ | ||
121 | uint32_t r_id_gen; | ||
122 | |||
123 | }; | ||
124 | |||
125 | |||
126 | /** | ||
127 | * Reconnect to CREDENTIAL service. | ||
128 | * | ||
129 | * @param handle the handle to the CREDENTIAL service | ||
130 | */ | ||
131 | static void | ||
132 | reconnect (struct GNUNET_CREDENTIAL_Handle *handle); | ||
133 | |||
134 | |||
135 | /** | ||
136 | * Reconnect to CREDENTIAL | ||
137 | * | ||
138 | * @param cls the handle | ||
139 | */ | ||
140 | static void | ||
141 | reconnect_task (void *cls) | ||
142 | { | ||
143 | struct GNUNET_CREDENTIAL_Handle *handle = cls; | ||
144 | |||
145 | handle->reconnect_task = NULL; | ||
146 | reconnect (handle); | ||
147 | } | ||
148 | |||
149 | |||
150 | /** | ||
151 | * Disconnect from service and then reconnect. | ||
152 | * | ||
153 | * @param handle our handle | ||
154 | */ | ||
155 | static void | ||
156 | force_reconnect (struct GNUNET_CREDENTIAL_Handle *handle) | ||
157 | { | ||
158 | GNUNET_MQ_destroy (handle->mq); | ||
159 | handle->mq = NULL; | ||
160 | handle->reconnect_backoff | ||
161 | = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff); | ||
162 | handle->reconnect_task | ||
163 | = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff, | ||
164 | &reconnect_task, | ||
165 | handle); | ||
166 | } | ||
167 | |||
168 | |||
169 | /** | ||
170 | * Generic error handler, called with the appropriate error code and | ||
171 | * the same closure specified at the creation of the message queue. | ||
172 | * Not every message queue implementation supports an error handler. | ||
173 | * | ||
174 | * @param cls closure with the `struct GNUNET_CREDENTIAL_Handle *` | ||
175 | * @param error error code | ||
176 | */ | ||
177 | static void | ||
178 | mq_error_handler (void *cls, | ||
179 | enum GNUNET_MQ_Error error) | ||
180 | { | ||
181 | struct GNUNET_CREDENTIAL_Handle *handle = cls; | ||
182 | |||
183 | force_reconnect (handle); | ||
184 | } | ||
185 | |||
186 | |||
187 | /** | ||
188 | * Check validity of message received from the CREDENTIAL service | ||
189 | * | ||
190 | * @param cls the `struct GNUNET_CREDENTIAL_Handle *` | ||
191 | * @param loookup_msg the incoming message | ||
192 | */ | ||
193 | static int | ||
194 | check_result (void *cls, | ||
195 | const struct LookupResultMessage *lookup_msg) | ||
196 | { | ||
197 | //TODO | ||
198 | return GNUNET_OK; | ||
199 | } | ||
200 | |||
201 | |||
202 | /** | ||
203 | * Handler for messages received from the CREDENTIAL service | ||
204 | * | ||
205 | * @param cls the `struct GNUNET_CREDENTIAL_Handle *` | ||
206 | * @param loookup_msg the incoming message | ||
207 | */ | ||
208 | static void | ||
209 | handle_result (void *cls, | ||
210 | const struct LookupResultMessage *lookup_msg) | ||
211 | { | ||
212 | struct GNUNET_CREDENTIAL_Handle *handle = cls; | ||
213 | uint32_t cd_count = ntohl (lookup_msg->cd_count); | ||
214 | struct GNUNET_CREDENTIAL_RecordData cd[cd_count]; | ||
215 | uint32_t r_id = ntohl (lookup_msg->id); | ||
216 | struct GNUNET_CREDENTIAL_LookupRequest *lr; | ||
217 | GNUNET_CREDENTIAL_LookupResultProcessor proc; | ||
218 | void *proc_cls; | ||
219 | |||
220 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
221 | "Received lookup reply from CREDENTIAL service (%u credentials)\n", | ||
222 | (unsigned int) cd_count); | ||
223 | for (lr = handle->lookup_head; NULL != lr; lr = lr->next) | ||
224 | if (lr->r_id == r_id) | ||
225 | break; | ||
226 | if (NULL == lr) | ||
227 | return; | ||
228 | proc = lr->lookup_proc; | ||
229 | proc_cls = lr->proc_cls; | ||
230 | GNUNET_CONTAINER_DLL_remove (handle->lookup_head, | ||
231 | handle->lookup_tail, | ||
232 | lr); | ||
233 | GNUNET_free (lr); | ||
234 | /** | ||
235 | GNUNET_assert (GNUNET_OK == | ||
236 | GNUNET_CREDENTIAL_records_deserialize (mlen, | ||
237 | (const char*) &lookup_msg[1], | ||
238 | rd_count, | ||
239 | rd)); | ||
240 | */ | ||
241 | proc (proc_cls, | ||
242 | NULL, | ||
243 | cd_count, | ||
244 | cd); // TODO | ||
245 | } | ||
246 | |||
247 | |||
248 | /** | ||
249 | * Reconnect to CREDENTIAL service. | ||
250 | * | ||
251 | * @param handle the handle to the CREDENTIAL service | ||
252 | */ | ||
253 | static void | ||
254 | reconnect (struct GNUNET_CREDENTIAL_Handle *handle) | ||
255 | { | ||
256 | struct GNUNET_MQ_MessageHandler handlers[] = { | ||
257 | GNUNET_MQ_hd_var_size (result, | ||
258 | GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP_RESULT, | ||
259 | struct LookupResultMessage, | ||
260 | NULL), | ||
261 | GNUNET_MQ_handler_end () | ||
262 | }; | ||
263 | struct GNUNET_CREDENTIAL_LookupRequest *lh; | ||
264 | |||
265 | GNUNET_assert (NULL == handle->mq); | ||
266 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
267 | "Trying to connect to CREDENTIAL\n"); | ||
268 | handle->mq = GNUNET_CLIENT_connecT (handle->cfg, | ||
269 | "credential", | ||
270 | handlers, | ||
271 | &mq_error_handler, | ||
272 | handle); | ||
273 | if (NULL == handle->mq) | ||
274 | return; | ||
275 | for (lh = handle->lookup_head; NULL != lh; lh = lh->next) | ||
276 | GNUNET_MQ_send_copy (handle->mq, | ||
277 | lh->env); | ||
278 | } | ||
279 | |||
280 | |||
281 | /** | ||
282 | * Initialize the connection with the CREDENTIAL service. | ||
283 | * | ||
284 | * @param cfg configuration to use | ||
285 | * @return handle to the CREDENTIAL service, or NULL on error | ||
286 | */ | ||
287 | struct GNUNET_CREDENTIAL_Handle * | ||
288 | GNUNET_CREDENTIAL_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
289 | { | ||
290 | struct GNUNET_CREDENTIAL_Handle *handle; | ||
291 | |||
292 | handle = GNUNET_new (struct GNUNET_CREDENTIAL_Handle); | ||
293 | handle->cfg = cfg; | ||
294 | reconnect (handle); | ||
295 | if (NULL == handle->mq) | ||
296 | { | ||
297 | GNUNET_free (handle); | ||
298 | return NULL; | ||
299 | } | ||
300 | return handle; | ||
301 | } | ||
302 | |||
303 | |||
304 | /** | ||
305 | * Shutdown connection with the CREDENTIAL service. | ||
306 | * | ||
307 | * @param handle handle of the CREDENTIAL connection to stop | ||
308 | */ | ||
309 | void | ||
310 | GNUNET_CREDENTIAL_disconnect (struct GNUNET_CREDENTIAL_Handle *handle) | ||
311 | { | ||
312 | if (NULL != handle->mq) | ||
313 | { | ||
314 | GNUNET_MQ_destroy (handle->mq); | ||
315 | handle->mq = NULL; | ||
316 | } | ||
317 | if (NULL != handle->reconnect_task) | ||
318 | { | ||
319 | GNUNET_SCHEDULER_cancel (handle->reconnect_task); | ||
320 | handle->reconnect_task = NULL; | ||
321 | } | ||
322 | GNUNET_assert (NULL == handle->lookup_head); | ||
323 | GNUNET_free (handle); | ||
324 | } | ||
325 | |||
326 | |||
327 | /** | ||
328 | * Cancel pending lookup request | ||
329 | * | ||
330 | * @param lr the lookup request to cancel | ||
331 | */ | ||
332 | void | ||
333 | GNUNET_CREDENTIAL_lookup_cancel (struct GNUNET_CREDENTIAL_LookupRequest *lr) | ||
334 | { | ||
335 | struct GNUNET_CREDENTIAL_Handle *handle = lr->credential_handle; | ||
336 | |||
337 | GNUNET_CONTAINER_DLL_remove (handle->lookup_head, | ||
338 | handle->lookup_tail, | ||
339 | lr); | ||
340 | GNUNET_MQ_discard (lr->env); | ||
341 | GNUNET_free (lr); | ||
342 | } | ||
343 | |||
344 | |||
345 | /** | ||
346 | * Perform an asynchronous lookup operation for a credential. | ||
347 | * | ||
348 | * @param handle handle to the Credential service | ||
349 | * @param credential the credential to look up | ||
350 | * @param subject Ego to check the credential for | ||
351 | * @param proc function to call on result | ||
352 | * @param proc_cls closure for processor | ||
353 | * @return handle to the queued request | ||
354 | */ | ||
355 | struct GNUNET_CREDENTIAL_LookupRequest* | ||
356 | GNUNET_CREDENTIAL_lookup (struct GNUNET_CREDENTIAL_Handle *handle, | ||
357 | const char *credential, | ||
358 | const struct GNUNET_IDENTITY_Ego *subject, | ||
359 | const struct GNUNET_CRYPTO_EcdsaPublicKey *subject_key, | ||
360 | const struct GNUNET_CRYPTO_EcdsaPublicKey *issuer_key, | ||
361 | uint32_t credential_flags, | ||
362 | uint32_t max_delegation_depth, | ||
363 | GNUNET_CREDENTIAL_LookupResultProcessor proc, | ||
364 | void *proc_cls) | ||
365 | { | ||
366 | /* IPC to shorten credential names, return shorten_handle */ | ||
367 | struct LookupMessage *lookup_msg; | ||
368 | struct GNUNET_CREDENTIAL_LookupRequest *lr; | ||
369 | size_t nlen; | ||
370 | |||
371 | if (NULL == credential) | ||
372 | { | ||
373 | GNUNET_break (0); | ||
374 | return NULL; | ||
375 | } | ||
376 | //DEBUG LOG | ||
377 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
378 | "Trying to lookup `%s' in CREDENTIAL\n", | ||
379 | credential); | ||
380 | nlen = strlen (credential) + 1; | ||
381 | if (nlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (*lr)) | ||
382 | { | ||
383 | GNUNET_break (0); | ||
384 | return NULL; | ||
385 | } | ||
386 | lr = GNUNET_new (struct GNUNET_CREDENTIAL_LookupRequest); | ||
387 | lr->credential_handle = handle; | ||
388 | lr->lookup_proc = proc; | ||
389 | lr->proc_cls = proc_cls; | ||
390 | lr->r_id = handle->r_id_gen++; | ||
391 | lr->env = GNUNET_MQ_msg_extra (lookup_msg, | ||
392 | nlen, | ||
393 | GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP); | ||
394 | lookup_msg->id = htonl (lr->r_id); | ||
395 | lookup_msg->subject_key = *subject_key; | ||
396 | lookup_msg->issuer_key = *issuer_key; | ||
397 | GNUNET_memcpy (&lookup_msg[1], | ||
398 | credential, | ||
399 | nlen); | ||
400 | GNUNET_CONTAINER_DLL_insert (handle->lookup_head, | ||
401 | handle->lookup_tail, | ||
402 | lr); | ||
403 | if (NULL != handle->mq) | ||
404 | GNUNET_MQ_send_copy (handle->mq, | ||
405 | lr->env); | ||
406 | return lr; | ||
407 | } | ||
408 | |||
409 | |||
410 | /* end of credential_api.c */ | ||
diff --git a/src/credential/gnunet-credential.c b/src/credential/gnunet-credential.c new file mode 100644 index 000000000..363ed03fc --- /dev/null +++ b/src/credential/gnunet-credential.c | |||
@@ -0,0 +1,382 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2012-2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file gnunet-credential.c | ||
22 | * @brief command line tool to access command line Credential service | ||
23 | * @author Adnan Husain | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include <gnunet_util_lib.h> | ||
27 | #include <gnunet_identity_service.h> | ||
28 | #include <gnunet_credential_service.h> | ||
29 | |||
30 | /** | ||
31 | * Configuration we are using. | ||
32 | */ | ||
33 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
34 | |||
35 | /** | ||
36 | * Handle to Credential service. | ||
37 | */ | ||
38 | static struct GNUNET_CREDENTIAL_Handle *credential; | ||
39 | |||
40 | /** | ||
41 | * Desired timeout for the lookup (default is no timeout). | ||
42 | */ | ||
43 | static struct GNUNET_TIME_Relative timeout; | ||
44 | |||
45 | /** | ||
46 | * Credential to lookup. (-u option) | ||
47 | */ | ||
48 | static char *lookup_credential; | ||
49 | |||
50 | /** | ||
51 | * Handle to lookup request | ||
52 | */ | ||
53 | static struct GNUNET_CREDENTIAL_LookupRequest *lookup_request; | ||
54 | |||
55 | /** | ||
56 | * Lookup an ego with the identity service. | ||
57 | */ | ||
58 | static struct GNUNET_IDENTITY_EgoLookup *el; | ||
59 | |||
60 | /** | ||
61 | * Handle for identity service. | ||
62 | */ | ||
63 | static struct GNUNET_IDENTITY_Handle *identity; | ||
64 | |||
65 | /** | ||
66 | * Active operation on identity service. | ||
67 | */ | ||
68 | static struct GNUNET_IDENTITY_Operation *id_op; | ||
69 | |||
70 | /** | ||
71 | * Task scheduled to handle timeout. | ||
72 | */ | ||
73 | static struct GNUNET_SCHEDULER_Task *tt; | ||
74 | |||
75 | /** | ||
76 | * Subject pubkey string | ||
77 | */ | ||
78 | static char *subject_key; | ||
79 | |||
80 | /** | ||
81 | * Subject pubkey string | ||
82 | */ | ||
83 | static char *issuer_key; | ||
84 | |||
85 | /* | ||
86 | * Credential flags | ||
87 | */ | ||
88 | static int credential_flags; | ||
89 | |||
90 | /* | ||
91 | * Maximum delegation depth | ||
92 | */ | ||
93 | static int max_delegation_depth; | ||
94 | |||
95 | |||
96 | |||
97 | /** | ||
98 | * Identity of the zone to use for the lookup (-z option) | ||
99 | */ | ||
100 | static char *zone_ego_name; | ||
101 | |||
102 | |||
103 | /** | ||
104 | * Task run on shutdown. Cleans up everything. | ||
105 | * | ||
106 | * @param cls unused | ||
107 | */ | ||
108 | static void | ||
109 | do_shutdown (void *cls) | ||
110 | { | ||
111 | if (NULL != el) | ||
112 | { | ||
113 | GNUNET_IDENTITY_ego_lookup_cancel (el); | ||
114 | el = NULL; | ||
115 | } | ||
116 | if (NULL != id_op) | ||
117 | { | ||
118 | GNUNET_IDENTITY_cancel (id_op); | ||
119 | id_op = NULL; | ||
120 | } | ||
121 | if (NULL != lookup_request) | ||
122 | { | ||
123 | GNUNET_CREDENTIAL_lookup_cancel (lookup_request); | ||
124 | lookup_request = NULL; | ||
125 | } | ||
126 | if (NULL != identity) | ||
127 | { | ||
128 | GNUNET_IDENTITY_disconnect (identity); | ||
129 | identity = NULL; | ||
130 | } | ||
131 | if (NULL != credential) | ||
132 | { | ||
133 | GNUNET_CREDENTIAL_disconnect (credential); | ||
134 | credential = NULL; | ||
135 | } | ||
136 | if (NULL != tt) | ||
137 | { | ||
138 | GNUNET_SCHEDULER_cancel (tt); | ||
139 | tt = NULL; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | |||
144 | /** | ||
145 | * Task run on timeout. Triggers shutdown. | ||
146 | * | ||
147 | * @param cls unused | ||
148 | */ | ||
149 | static void | ||
150 | do_timeout (void *cls) | ||
151 | { | ||
152 | tt = NULL; | ||
153 | GNUNET_SCHEDULER_shutdown (); | ||
154 | } | ||
155 | |||
156 | |||
157 | /** | ||
158 | * Function called with the result of a Credential lookup. | ||
159 | * | ||
160 | * @param cls the 'const char *' name that was resolved | ||
161 | * @param cd_count number of records returned | ||
162 | * @param cd array of @a cd_count records with the results | ||
163 | */ | ||
164 | static void | ||
165 | handle_lookup_result (void *cls, | ||
166 | struct GNUNET_IDENTITY_Ego *issuer, | ||
167 | uint16_t issuer_len, | ||
168 | const struct GNUNET_CREDENTIAL_RecordData *data) | ||
169 | { | ||
170 | |||
171 | |||
172 | lookup_request = NULL; | ||
173 | if (0 == issuer_len) | ||
174 | printf ("No results.\n"); | ||
175 | else | ||
176 | printf ("%u\n", | ||
177 | issuer_len); | ||
178 | |||
179 | |||
180 | GNUNET_SCHEDULER_shutdown (); | ||
181 | } | ||
182 | |||
183 | |||
184 | |||
185 | |||
186 | /** | ||
187 | * Perform the actual resolution, with the subject pkey and | ||
188 | * the issuer public key | ||
189 | * | ||
190 | * @param pkey public key to use for the zone, can be NULL | ||
191 | * @param shorten_key private key used for shortening, can be NULL | ||
192 | */ | ||
193 | static void | ||
194 | lookup_credentials (struct GNUNET_IDENTITY_Ego *ego) | ||
195 | { | ||
196 | |||
197 | struct GNUNET_CRYPTO_EcdsaPublicKey subject_pkey; | ||
198 | struct GNUNET_CRYPTO_EcdsaPublicKey issuer_pkey; | ||
199 | |||
200 | if (NULL != subject_key && NULL != issuer_key && NULL != lookup_credential) | ||
201 | { | ||
202 | if (GNUNET_OK != | ||
203 | GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_key, | ||
204 | strlen (subject_key), | ||
205 | &subject_pkey)) | ||
206 | { | ||
207 | fprintf (stderr, | ||
208 | _("Subject public key `%s' is not well-formed\n"), | ||
209 | subject_key); | ||
210 | GNUNET_SCHEDULER_shutdown (); | ||
211 | return; | ||
212 | } | ||
213 | |||
214 | if (GNUNET_OK != | ||
215 | GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key, | ||
216 | strlen (issuer_key), | ||
217 | &issuer_pkey)) | ||
218 | { | ||
219 | fprintf (stderr, | ||
220 | _("Authority public key `%s' is not well-formed\n"), | ||
221 | issuer_key); | ||
222 | GNUNET_SCHEDULER_shutdown (); | ||
223 | return; | ||
224 | } | ||
225 | |||
226 | lookup_request = GNUNET_CREDENTIAL_lookup(credential, | ||
227 | lookup_credential, | ||
228 | ego, | ||
229 | &subject_pkey, | ||
230 | &issuer_pkey, | ||
231 | credential_flags, | ||
232 | max_delegation_depth, | ||
233 | &handle_lookup_result, | ||
234 | NULL); | ||
235 | return; | ||
236 | } | ||
237 | else | ||
238 | { | ||
239 | fprintf (stderr, | ||
240 | _("Please specify name to lookup, subject key and issuer key!\n")); | ||
241 | GNUNET_SCHEDULER_shutdown (); | ||
242 | return; | ||
243 | } | ||
244 | } | ||
245 | |||
246 | |||
247 | /** | ||
248 | * Method called to with the ego we are to use for the lookup, | ||
249 | * when the ego is the one for the default master zone. | ||
250 | * | ||
251 | * @param cls closure (NULL, unused) | ||
252 | * @param ego ego handle, NULL if not found | ||
253 | * @param ctx context for application to store data for this ego | ||
254 | * (during the lifetime of this process, initially NULL) | ||
255 | * @param name name assigned by the user for this ego, | ||
256 | * NULL if the user just deleted the ego and it | ||
257 | * must thus no longer be used | ||
258 | */ | ||
259 | static void | ||
260 | identity_master_cb (void *cls, | ||
261 | struct GNUNET_IDENTITY_Ego *ego, | ||
262 | void **ctx, | ||
263 | const char *name) | ||
264 | { | ||
265 | |||
266 | id_op = NULL; | ||
267 | if (NULL == ego) | ||
268 | { | ||
269 | fprintf (stderr, | ||
270 | _("Ego for `gns-master' not found, cannot perform lookup. Did you run gnunet-gns-import.sh?\n")); | ||
271 | GNUNET_SCHEDULER_shutdown (); | ||
272 | return; | ||
273 | } | ||
274 | |||
275 | lookup_credentials(ego); | ||
276 | |||
277 | |||
278 | } | ||
279 | |||
280 | |||
281 | /** | ||
282 | * Main function that will be run. | ||
283 | * | ||
284 | * @param cls closure | ||
285 | * @param args remaining command-line arguments | ||
286 | * @param cfgfile name of the configuration file used (for saving, can be NULL!) | ||
287 | * @param c configuration | ||
288 | */ | ||
289 | static void | ||
290 | run (void *cls, | ||
291 | char *const *args, | ||
292 | const char *cfgfile, | ||
293 | const struct GNUNET_CONFIGURATION_Handle *c) | ||
294 | { | ||
295 | |||
296 | cfg = c; | ||
297 | credential = GNUNET_CREDENTIAL_connect (cfg); | ||
298 | identity = GNUNET_IDENTITY_connect (cfg, NULL, NULL); | ||
299 | |||
300 | |||
301 | |||
302 | |||
303 | if (NULL == credential) | ||
304 | { | ||
305 | fprintf (stderr, | ||
306 | _("Failed to connect to CREDENTIAL\n")); | ||
307 | return; | ||
308 | } | ||
309 | if (NULL == identity) | ||
310 | { | ||
311 | fprintf (stderr, | ||
312 | _("Failed to connect to IDENTITY\n")); | ||
313 | return; | ||
314 | } | ||
315 | tt = GNUNET_SCHEDULER_add_delayed (timeout, | ||
316 | &do_timeout, NULL); | ||
317 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); | ||
318 | |||
319 | |||
320 | |||
321 | GNUNET_break (NULL == id_op); | ||
322 | id_op = GNUNET_IDENTITY_get (identity, | ||
323 | "gns-master",//# TODO: Create credential-master | ||
324 | &identity_master_cb, | ||
325 | cls); | ||
326 | GNUNET_assert (NULL != id_op); | ||
327 | |||
328 | |||
329 | |||
330 | |||
331 | } | ||
332 | |||
333 | |||
334 | /** | ||
335 | * The main function for gnunet-gns. | ||
336 | * | ||
337 | * @param argc number of arguments from the command line | ||
338 | * @param argv command line arguments | ||
339 | * @return 0 ok, 1 on error | ||
340 | */ | ||
341 | int | ||
342 | main (int argc, char *const *argv) | ||
343 | { | ||
344 | static const struct GNUNET_GETOPT_CommandLineOption options[] = { | ||
345 | {'u', "lookup", "CREDENTIAL", | ||
346 | gettext_noop ("Lookup a record for the given credential"), 1, | ||
347 | &GNUNET_GETOPT_set_string, &lookup_credential}, | ||
348 | /** { 'T', "timeout", "DELAY", | ||
349 | gettext_noop ("Specify timeout for the lookup"), 1, | ||
350 | &GNUNET_GETOPT_set_relative_time, &timeout }, | ||
351 | {'t', "type", "TYPE", | ||
352 | gettext_noop ("Specify the type of the record to lookup"), 1, | ||
353 | &GNUNET_GETOPT_set_string, &lookup_type},**/ | ||
354 | {'z', "zone", "NAME", | ||
355 | gettext_noop ("Specify the name of the ego of the zone to lookup the record in"), 1, | ||
356 | &GNUNET_GETOPT_set_string, &zone_ego_name}, | ||
357 | {'s', "subject", "PKEY", | ||
358 | gettext_noop ("Specify the public key of the subject to lookup the credential for"), 1, | ||
359 | &GNUNET_GETOPT_set_string, &subject_key}, | ||
360 | {'i', "issuer", "PKEY", | ||
361 | gettext_noop ("Specify the public key of the authority to verify the credential against"), 1, | ||
362 | &GNUNET_GETOPT_set_string, &issuer_key}, | ||
363 | GNUNET_GETOPT_OPTION_END | ||
364 | }; | ||
365 | int ret; | ||
366 | |||
367 | timeout = GNUNET_TIME_UNIT_FOREVER_REL; | ||
368 | if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) | ||
369 | return 2; | ||
370 | |||
371 | GNUNET_log_setup ("gnunet-credential", "WARNING", NULL); | ||
372 | ret = | ||
373 | (GNUNET_OK == | ||
374 | GNUNET_PROGRAM_run (argc, argv, "gnunet-credential", | ||
375 | _("GNUnet credential resolver tool"), | ||
376 | options, | ||
377 | &run, NULL)) ? 0 : 1; | ||
378 | GNUNET_free ((void*) argv); | ||
379 | return ret; | ||
380 | } | ||
381 | |||
382 | /* end of gnunet-credential.c */ | ||
diff --git a/src/credential/gnunet-service-credential.c b/src/credential/gnunet-service-credential.c new file mode 100644 index 000000000..de0592637 --- /dev/null +++ b/src/credential/gnunet-service-credential.c | |||
@@ -0,0 +1,425 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2011-2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file gns/gnunet-service-credential.c | ||
22 | * @brief GNU Credential Service (main service) | ||
23 | * @author Adnan Husain | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "gnunet_util_lib.h" | ||
27 | #include "gnunet_credential_service.h" | ||
28 | #include "gnunet_statistics_service.h" | ||
29 | #include "credential.h" | ||
30 | #include "gnunet_protocols.h" | ||
31 | |||
32 | // For Looking up GNS request | ||
33 | #include <gnunet_dnsparser_lib.h> | ||
34 | #include <gnunet_identity_service.h> | ||
35 | #include <gnunet_gnsrecord_lib.h> | ||
36 | #include <gnunet_namestore_service.h> | ||
37 | #include <gnunet_gns_service.h> | ||
38 | #include "gnunet_gns_service.h" | ||
39 | |||
40 | |||
41 | |||
42 | |||
43 | #define GNUNET_CREDENTIAL_MAX_LENGTH 255 | ||
44 | |||
45 | /** | ||
46 | * DLL for record | ||
47 | */ | ||
48 | struct CredentialRecordEntry | ||
49 | { | ||
50 | /** | ||
51 | * DLL | ||
52 | */ | ||
53 | struct CredentialRecordEntry *next; | ||
54 | |||
55 | /** | ||
56 | * DLL | ||
57 | */ | ||
58 | struct CredentialRecordEntry *prev; | ||
59 | |||
60 | |||
61 | /** | ||
62 | * Payload | ||
63 | */ | ||
64 | struct GNUNET_CREDENTIAL_RecordData record_data; | ||
65 | }; | ||
66 | |||
67 | /** | ||
68 | * Handle to a lookup operation from api | ||
69 | */ | ||
70 | struct ClientLookupHandle | ||
71 | { | ||
72 | |||
73 | /** | ||
74 | * We keep these in a DLL. | ||
75 | */ | ||
76 | struct ClientLookupHandle *next; | ||
77 | |||
78 | /** | ||
79 | * We keep these in a DLL. | ||
80 | */ | ||
81 | struct ClientLookupHandle *prev; | ||
82 | |||
83 | /** | ||
84 | * Handle to the requesting client | ||
85 | */ | ||
86 | struct GNUNET_SERVICE_Client *client; | ||
87 | |||
88 | /** | ||
89 | * Handle to GNS lookup | ||
90 | */ | ||
91 | struct GNUNET_GNS_LookupRequest *lookup_request; | ||
92 | |||
93 | /** | ||
94 | * Authority public key | ||
95 | */ | ||
96 | struct GNUNET_CRYPTO_EcdsaPublicKey issuer_key; | ||
97 | |||
98 | /** | ||
99 | * Credential Chain | ||
100 | */ | ||
101 | struct CredentialRecordEntry *cred_chain_head; | ||
102 | |||
103 | /** | ||
104 | * Credential Chain | ||
105 | */ | ||
106 | struct CredentialRecordEntry *cred_chain_tail; | ||
107 | |||
108 | /** | ||
109 | * request id | ||
110 | */ | ||
111 | uint32_t request_id; | ||
112 | |||
113 | }; | ||
114 | |||
115 | |||
116 | /** | ||
117 | * Head of the DLL. | ||
118 | */ | ||
119 | static struct ClientLookupHandle *clh_head; | ||
120 | |||
121 | /** | ||
122 | * Tail of the DLL. | ||
123 | */ | ||
124 | static struct ClientLookupHandle *clh_tail; | ||
125 | |||
126 | /** | ||
127 | * Handle to the statistics service | ||
128 | */ | ||
129 | static struct GNUNET_STATISTICS_Handle *statistics; | ||
130 | |||
131 | |||
132 | |||
133 | /** | ||
134 | * Handle to GNS service. | ||
135 | */ | ||
136 | static struct GNUNET_GNS_Handle *gns; | ||
137 | |||
138 | /** | ||
139 | * Task run during shutdown. | ||
140 | * | ||
141 | * @param cls unused | ||
142 | * @param tc unused | ||
143 | */ | ||
144 | static void | ||
145 | shutdown_task (void *cls) | ||
146 | { | ||
147 | struct ClientLookupHandle *clh; | ||
148 | |||
149 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
150 | "Shutting down!\n"); | ||
151 | while (NULL != (clh = clh_head)) | ||
152 | { | ||
153 | //CREDENTIAL_resolver_lookup_cancel (clh->lookup); | ||
154 | GNUNET_CONTAINER_DLL_remove (clh_head, | ||
155 | clh_tail, | ||
156 | clh); | ||
157 | GNUNET_free (clh); | ||
158 | } | ||
159 | |||
160 | |||
161 | if (NULL != statistics) | ||
162 | { | ||
163 | GNUNET_STATISTICS_destroy (statistics, | ||
164 | GNUNET_NO); | ||
165 | statistics = NULL; | ||
166 | } | ||
167 | |||
168 | } | ||
169 | |||
170 | /** | ||
171 | * Checks a #GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP message | ||
172 | * | ||
173 | * @param cls client sending the message | ||
174 | * @param l_msg message of type `struct LookupMessage` | ||
175 | * @return #GNUNET_OK if @a l_msg is well-formed | ||
176 | */ | ||
177 | static int | ||
178 | check_lookup (void *cls, | ||
179 | const struct LookupMessage *l_msg) | ||
180 | { | ||
181 | size_t msg_size; | ||
182 | const char* cred; | ||
183 | |||
184 | msg_size = ntohs (l_msg->header.size); | ||
185 | if (msg_size < sizeof (struct LookupMessage)) | ||
186 | { | ||
187 | GNUNET_break (0); | ||
188 | return GNUNET_SYSERR; | ||
189 | } | ||
190 | cred = (const char *) &l_msg[1]; | ||
191 | if ( ('\0' != cred[l_msg->header.size - sizeof (struct LookupMessage) - 1]) || | ||
192 | (strlen (cred) > GNUNET_CREDENTIAL_MAX_LENGTH) ) | ||
193 | { | ||
194 | GNUNET_break (0); | ||
195 | return GNUNET_SYSERR; | ||
196 | } | ||
197 | return GNUNET_OK; | ||
198 | } | ||
199 | |||
200 | |||
201 | /** | ||
202 | * Reply to client with the result from our lookup. | ||
203 | * | ||
204 | * @param cls the closure (our client lookup handle) | ||
205 | * @param rd_count the number of records in @a rd | ||
206 | * @param rd the record data | ||
207 | */ | ||
208 | static void | ||
209 | send_lookup_response (void* cls, | ||
210 | uint32_t rd_count, | ||
211 | const struct GNUNET_GNSRECORD_Data *rd) | ||
212 | { | ||
213 | struct ClientLookupHandle *clh = cls; | ||
214 | size_t len; | ||
215 | int i; | ||
216 | int cred_record_count; | ||
217 | struct GNUNET_MQ_Envelope *env; | ||
218 | struct LookupResultMessage *rmsg; | ||
219 | const struct GNUNET_CREDENTIAL_RecordData *crd; | ||
220 | struct CredentialRecordEntry *cr_entry; | ||
221 | |||
222 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
223 | "Sending LOOKUP_RESULT message with %u results\n", | ||
224 | (unsigned int) rd_count); | ||
225 | |||
226 | cred_record_count = 0; | ||
227 | for (i=0; i < rd_count; i++) | ||
228 | { | ||
229 | if (GNUNET_GNSRECORD_TYPE_CREDENTIAL != rd[i].record_type) | ||
230 | continue; | ||
231 | cred_record_count++; | ||
232 | crd = rd[i].data; | ||
233 | /** | ||
234 | * TODO: Check for: | ||
235 | * - First time we come here subject must be subject prvided by client | ||
236 | * - After that is has to be the prev issuer | ||
237 | * - Terminate condition: issuer is clh->authority_key | ||
238 | * | ||
239 | * In any case: | ||
240 | * Append crd to result list of RecordData | ||
241 | */ | ||
242 | cr_entry = GNUNET_new (struct CredentialRecordEntry); | ||
243 | cr_entry->record_data = *crd; | ||
244 | GNUNET_CONTAINER_DLL_insert_tail (clh->cred_chain_head, | ||
245 | clh->cred_chain_tail, | ||
246 | cr_entry); | ||
247 | |||
248 | } | ||
249 | |||
250 | /** | ||
251 | * Get serialized record data size | ||
252 | */ | ||
253 | len = cred_record_count * sizeof (struct GNUNET_CREDENTIAL_RecordData); | ||
254 | |||
255 | /** | ||
256 | * Prepare a lookup result response message for the client | ||
257 | */ | ||
258 | env = GNUNET_MQ_msg_extra (rmsg, | ||
259 | len, | ||
260 | GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP_RESULT); | ||
261 | //Assign id so that client can find associated request | ||
262 | rmsg->id = clh->request_id; | ||
263 | rmsg->cd_count = htonl (cred_record_count); | ||
264 | |||
265 | /** | ||
266 | * Get serialized record data | ||
267 | * Append at the end of rmsg | ||
268 | */ | ||
269 | i = 0; | ||
270 | struct GNUNET_CREDENTIAL_RecordData *tmp_record = (struct GNUNET_CREDENTIAL_RecordData*) &rmsg[1]; | ||
271 | for (cr_entry = clh->cred_chain_head; NULL != cr_entry; cr_entry = cr_entry->next) | ||
272 | { | ||
273 | memcpy (tmp_record, | ||
274 | &cr_entry->record_data, | ||
275 | sizeof (struct GNUNET_CREDENTIAL_RecordData)); | ||
276 | tmp_record++; | ||
277 | } | ||
278 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(clh->client), | ||
279 | env); | ||
280 | |||
281 | GNUNET_CONTAINER_DLL_remove (clh_head, clh_tail, clh); | ||
282 | |||
283 | /** | ||
284 | * TODO: | ||
285 | * - Free DLL | ||
286 | * - Refactor into cleanup_handle() function for this | ||
287 | */ | ||
288 | GNUNET_free (clh); | ||
289 | |||
290 | GNUNET_STATISTICS_update (statistics, | ||
291 | "Completed lookups", 1, | ||
292 | GNUNET_NO); | ||
293 | GNUNET_STATISTICS_update (statistics, | ||
294 | "Records resolved", | ||
295 | rd_count, | ||
296 | GNUNET_NO); | ||
297 | } | ||
298 | |||
299 | /** | ||
300 | * Handle lookup requests from client | ||
301 | * | ||
302 | * @param cls the closure | ||
303 | * @param client the client | ||
304 | * @param message the message | ||
305 | */ | ||
306 | static void | ||
307 | handle_lookup (void *cls, | ||
308 | const struct LookupMessage *l_msg) | ||
309 | { | ||
310 | char credential[GNUNET_CREDENTIAL_MAX_LENGTH + 1]; | ||
311 | struct ClientLookupHandle *clh; | ||
312 | struct GNUNET_SERVICE_Client *client = cls; | ||
313 | char *credentialptr = credential; | ||
314 | const char *utf_in; | ||
315 | |||
316 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
317 | "Received LOOKUP message\n"); | ||
318 | |||
319 | utf_in = (const char *) &l_msg[1]; | ||
320 | GNUNET_STRINGS_utf8_tolower (utf_in, credentialptr); | ||
321 | clh = GNUNET_new (struct ClientLookupHandle); | ||
322 | GNUNET_CONTAINER_DLL_insert (clh_head, clh_tail, clh); | ||
323 | clh->client = client; | ||
324 | clh->request_id = l_msg->id; | ||
325 | clh->issuer_key = l_msg->issuer_key; | ||
326 | |||
327 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
328 | "Sending LOOKUP_RESULT message with >%u results\n", | ||
329 | 0); | ||
330 | |||
331 | if (NULL == credential) | ||
332 | { | ||
333 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
334 | "No credential provided\n"); | ||
335 | send_lookup_response (clh, 0, NULL); | ||
336 | return; | ||
337 | } | ||
338 | clh->lookup_request = GNUNET_GNS_lookup (gns, | ||
339 | credential, | ||
340 | &l_msg->subject_key, //subject_pkey, | ||
341 | GNUNET_GNSRECORD_TYPE_CREDENTIAL, | ||
342 | GNUNET_GNS_LO_DEFAULT, //TODO configurable? credential.conf | ||
343 | NULL, //shorten_key, always NULL | ||
344 | &send_lookup_response, | ||
345 | clh); | ||
346 | } | ||
347 | |||
348 | |||
349 | /** | ||
350 | * One of our clients disconnected, clean up after it. | ||
351 | * | ||
352 | * @param cls NULL | ||
353 | * @param client the client that disconnected | ||
354 | */ | ||
355 | static void | ||
356 | client_disconnect_cb (void *cls, | ||
357 | struct GNUNET_SERVICE_Client *client, | ||
358 | void *app_ctx) | ||
359 | { | ||
360 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
361 | "Client %p disconnected\n", | ||
362 | client); | ||
363 | } | ||
364 | |||
365 | /** | ||
366 | * Add a client to our list of active clients. | ||
367 | * | ||
368 | * @param cls NULL | ||
369 | * @param client client to add | ||
370 | * @param mq message queue for @a client | ||
371 | * @return this client | ||
372 | */ | ||
373 | static void * | ||
374 | client_connect_cb (void *cls, | ||
375 | struct GNUNET_SERVICE_Client *client, | ||
376 | struct GNUNET_MQ_Handle *mq) | ||
377 | { | ||
378 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
379 | "Client %p connected\n", | ||
380 | client); | ||
381 | return client; | ||
382 | } | ||
383 | |||
384 | /** | ||
385 | * Process Credential requests. | ||
386 | * | ||
387 | * @param cls closure | ||
388 | * @param server the initialized server | ||
389 | * @param c configuration to use | ||
390 | */ | ||
391 | static void | ||
392 | run (void *cls, | ||
393 | const struct GNUNET_CONFIGURATION_Handle *c, | ||
394 | struct GNUNET_SERVICE_Handle *handle) | ||
395 | { | ||
396 | |||
397 | gns = GNUNET_GNS_connect (c); | ||
398 | if (NULL == gns) | ||
399 | { | ||
400 | fprintf (stderr, | ||
401 | _("Failed to connect to GNS\n")); | ||
402 | } | ||
403 | |||
404 | statistics = GNUNET_STATISTICS_create ("credential", c); | ||
405 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); | ||
406 | } | ||
407 | |||
408 | |||
409 | /** | ||
410 | * Define "main" method using service macro | ||
411 | */ | ||
412 | GNUNET_SERVICE_MAIN | ||
413 | ("credential", | ||
414 | GNUNET_SERVICE_OPTION_NONE, | ||
415 | &run, | ||
416 | &client_connect_cb, | ||
417 | &client_disconnect_cb, | ||
418 | NULL, | ||
419 | GNUNET_MQ_hd_var_size (lookup, | ||
420 | GNUNET_MESSAGE_TYPE_CREDENTIAL_LOOKUP, | ||
421 | struct LookupMessage, | ||
422 | NULL), | ||
423 | GNUNET_MQ_handler_end()); | ||
424 | |||
425 | /* end of gnunet-service-credential.c */ | ||
diff --git a/src/credential/plugin_gnsrecord_credential.c b/src/credential/plugin_gnsrecord_credential.c new file mode 100644 index 000000000..6ae3b8980 --- /dev/null +++ b/src/credential/plugin_gnsrecord_credential.c | |||
@@ -0,0 +1,257 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file credential/plugin_gnsrecord_credential.c | ||
23 | * @brief gnsrecord plugin to provide the API for CREDENTIAL records | ||
24 | * @author Adnan Husain | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_gnsrecord_lib.h" | ||
30 | #include "gnunet_credential_service.h" | ||
31 | #include "gnunet_gnsrecord_plugin.h" | ||
32 | |||
33 | |||
34 | /** | ||
35 | * Convert the 'value' of a record to a string. | ||
36 | * | ||
37 | * @param cls closure, unused | ||
38 | * @param type type of the record | ||
39 | * @param data value in binary encoding | ||
40 | * @param data_size number of bytes in @a data | ||
41 | * @return NULL on error, otherwise human-readable representation of the value | ||
42 | */ | ||
43 | static char * | ||
44 | credential_value_to_string (void *cls, | ||
45 | uint32_t type, | ||
46 | const void *data, | ||
47 | size_t data_size) | ||
48 | { | ||
49 | |||
50 | const char *cdata; | ||
51 | |||
52 | switch (type) | ||
53 | { | ||
54 | case GNUNET_GNSRECORD_TYPE_CREDENTIAL: | ||
55 | { | ||
56 | struct GNUNET_CREDENTIAL_RecordData cred; | ||
57 | char *cred_str; | ||
58 | char *subject_pkey; | ||
59 | char *issuer_pkey; | ||
60 | uint32_t cf; // Credential flags | ||
61 | uint32_t mdd; // Max delegation depth | ||
62 | if (data_size < sizeof (struct GNUNET_CREDENTIAL_RecordData)) | ||
63 | return NULL; /* malformed */ | ||
64 | memcpy (&cred, | ||
65 | data, | ||
66 | sizeof (cred)); | ||
67 | cdata = data; | ||
68 | subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.subject_key); | ||
69 | issuer_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.issuer_key); | ||
70 | cf = ntohl (cred.credential_flags); | ||
71 | mdd = ntohl (cred.max_delegation_depth); | ||
72 | |||
73 | GNUNET_asprintf (&cred_str, | ||
74 | "%s %s %u %u %s", | ||
75 | subject_pkey, | ||
76 | issuer_pkey, | ||
77 | (unsigned int) cf, | ||
78 | (unsigned int) mdd, | ||
79 | &cdata[sizeof (cred)]); | ||
80 | GNUNET_free (subject_pkey); | ||
81 | GNUNET_free (issuer_pkey); | ||
82 | |||
83 | |||
84 | |||
85 | return cred_str; | ||
86 | } | ||
87 | default: | ||
88 | return NULL; | ||
89 | } | ||
90 | } | ||
91 | |||
92 | |||
93 | /** | ||
94 | * Convert human-readable version of a 'value' of a record to the binary | ||
95 | * representation. | ||
96 | * | ||
97 | * @param cls closure, unused | ||
98 | * @param type type of the record | ||
99 | * @param s human-readable string | ||
100 | * @param data set to value in binary encoding (will be allocated) | ||
101 | * @param data_size set to number of bytes in @a data | ||
102 | * @return #GNUNET_OK on success | ||
103 | */ | ||
104 | static int | ||
105 | credential_string_to_value (void *cls, | ||
106 | uint32_t type, | ||
107 | const char *s, | ||
108 | void **data, | ||
109 | size_t *data_size) | ||
110 | { | ||
111 | if (NULL == s) | ||
112 | return GNUNET_SYSERR; | ||
113 | switch (type) | ||
114 | { | ||
115 | case GNUNET_GNSRECORD_TYPE_CREDENTIAL: | ||
116 | { | ||
117 | struct GNUNET_CREDENTIAL_RecordData *cred; | ||
118 | unsigned int cf; // credential flags | ||
119 | unsigned int mdd; // max delegation depth | ||
120 | |||
121 | size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8; | ||
122 | if (enclen % 5 > 0) | ||
123 | enclen += 5 - enclen % 5; | ||
124 | enclen /= 5; /* 260/5 = 52 */ | ||
125 | char subject_pkey[enclen + 1]; | ||
126 | char issuer_pkey[enclen + 1]; | ||
127 | char name[253 + 1]; | ||
128 | |||
129 | if (5 != SSCANF (s, | ||
130 | "%52s %52s %u %u %253s", | ||
131 | subject_pkey, | ||
132 | issuer_pkey, | ||
133 | &cf, | ||
134 | &mdd, | ||
135 | name)) | ||
136 | { | ||
137 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
138 | _("Unable to parse CRED record string `%s'\n"), | ||
139 | s); | ||
140 | return GNUNET_SYSERR; | ||
141 | } | ||
142 | *data_size = sizeof (struct GNUNET_CREDENTIAL_RecordData) + strlen (name) + 1; | ||
143 | *data = cred = GNUNET_malloc (*data_size); | ||
144 | GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_pkey, | ||
145 | strlen (subject_pkey), | ||
146 | &cred->subject_key); | ||
147 | GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey, | ||
148 | strlen (issuer_pkey), | ||
149 | &cred->issuer_key); | ||
150 | cred->credential_flags = htonl (cf); | ||
151 | cred->max_delegation_depth = htonl (mdd); | ||
152 | GNUNET_memcpy (&cred[1], | ||
153 | name, | ||
154 | strlen (name)); | ||
155 | |||
156 | |||
157 | *data = GNUNET_strdup (s); | ||
158 | *data_size = strlen (s); | ||
159 | return GNUNET_OK; | ||
160 | } | ||
161 | default: | ||
162 | return GNUNET_SYSERR; | ||
163 | } | ||
164 | } | ||
165 | |||
166 | |||
167 | /** | ||
168 | * Mapping of record type numbers to human-readable | ||
169 | * record type names. | ||
170 | */ | ||
171 | static struct { | ||
172 | const char *name; | ||
173 | uint32_t number; | ||
174 | } name_map[] = { | ||
175 | { "CRED", GNUNET_GNSRECORD_TYPE_CREDENTIAL }, | ||
176 | { NULL, UINT32_MAX } | ||
177 | }; | ||
178 | |||
179 | |||
180 | /** | ||
181 | * Convert a type name (i.e. "AAAA") to the corresponding number. | ||
182 | * | ||
183 | * @param cls closure, unused | ||
184 | * @param gns_typename name to convert | ||
185 | * @return corresponding number, UINT32_MAX on error | ||
186 | */ | ||
187 | static uint32_t | ||
188 | credential_typename_to_number (void *cls, | ||
189 | const char *gns_typename) | ||
190 | { | ||
191 | unsigned int i; | ||
192 | |||
193 | i=0; | ||
194 | while ( (name_map[i].name != NULL) && | ||
195 | (0 != strcasecmp (gns_typename, name_map[i].name)) ) | ||
196 | i++; | ||
197 | return name_map[i].number; | ||
198 | } | ||
199 | |||
200 | |||
201 | /** | ||
202 | * Convert a type number (i.e. 1) to the corresponding type string (i.e. "A") | ||
203 | * | ||
204 | * @param cls closure, unused | ||
205 | * @param type number of a type to convert | ||
206 | * @return corresponding typestring, NULL on error | ||
207 | */ | ||
208 | static const char * | ||
209 | credential_number_to_typename (void *cls, | ||
210 | uint32_t type) | ||
211 | { | ||
212 | unsigned int i; | ||
213 | |||
214 | i=0; | ||
215 | while ( (name_map[i].name != NULL) && | ||
216 | (type != name_map[i].number) ) | ||
217 | i++; | ||
218 | return name_map[i].name; | ||
219 | } | ||
220 | |||
221 | |||
222 | /** | ||
223 | * Entry point for the plugin. | ||
224 | * | ||
225 | * @param cls NULL | ||
226 | * @return the exported block API | ||
227 | */ | ||
228 | void * | ||
229 | libgnunet_plugin_gnsrecord_credential_init (void *cls) | ||
230 | { | ||
231 | struct GNUNET_GNSRECORD_PluginFunctions *api; | ||
232 | |||
233 | api = GNUNET_new (struct GNUNET_GNSRECORD_PluginFunctions); | ||
234 | api->value_to_string = &credential_value_to_string; | ||
235 | api->string_to_value = &credential_string_to_value; | ||
236 | api->typename_to_number = &credential_typename_to_number; | ||
237 | api->number_to_typename = &credential_number_to_typename; | ||
238 | return api; | ||
239 | } | ||
240 | |||
241 | |||
242 | /** | ||
243 | * Exit point from the plugin. | ||
244 | * | ||
245 | * @param cls the return value from #libgnunet_plugin_block_test_init | ||
246 | * @return NULL | ||
247 | */ | ||
248 | void * | ||
249 | libgnunet_plugin_gnsrecord_credential_done (void *cls) | ||
250 | { | ||
251 | struct GNUNET_GNSRECORD_PluginFunctions *api = cls; | ||
252 | |||
253 | GNUNET_free (api); | ||
254 | return NULL; | ||
255 | } | ||
256 | |||
257 | /* end of plugin_gnsrecord_credential.c */ | ||
diff --git a/src/credential/test_credential_lookup.sh b/src/credential/test_credential_lookup.sh new file mode 100755 index 000000000..216c281d7 --- /dev/null +++ b/src/credential/test_credential_lookup.sh | |||
@@ -0,0 +1,40 @@ | |||
1 | #!/bin/bash | ||
2 | trap "gnunet-arm -e -c test_credential_lookup.conf" SIGINT | ||
3 | |||
4 | LOCATION=$(which gnunet-config) | ||
5 | if [ -z $LOCATION ] | ||
6 | then | ||
7 | LOCATION="gnunet-config" | ||
8 | fi | ||
9 | $LOCATION --version 1> /dev/null | ||
10 | if test $? != 0 | ||
11 | then | ||
12 | echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX" | ||
13 | exit 77 | ||
14 | fi | ||
15 | |||
16 | rm -rf `gnunet-config -c test_credential_lookup.conf -s PATHS -o GNUNET_HOME -f` | ||
17 | which timeout &> /dev/null && DO_TIMEOUT="timeout 30" | ||
18 | TEST_CREDENTIAL="keySub keyIss credName" | ||
19 | gnunet-arm -s -c test_credential_lookup.conf | ||
20 | gnunet-identity -C testsubject -c test_credential_lookup.conf | ||
21 | |||
22 | #TODO1 Plugin serialization functions see REVERSE in gns/plugin_gnsrecord_gns.c | ||
23 | gnunet-namestore -p -z testsubject -a -n newcred -t CRED -V $TEST_CREDENTIAL -e never -c test_credential_lookup.conf | ||
24 | |||
25 | #TODO2 Add -z swich like in gnunet-gns | ||
26 | RES_IP=`$DO_TIMEOUT gnunet-credential -z testsubject -s testsubject -u credName -c test_credential_lookup.conf` | ||
27 | gnunet-namestore -z testsubject -d -n newcred -t CRED -e never -c test_credential_lookup.conf | ||
28 | gnunet-identity -D testsubject -c test_credential_lookup.conf | ||
29 | gnunet-arm -e -c test_credential_lookup.conf | ||
30 | |||
31 | #TODO3 proper test | ||
32 | exit 0 | ||
33 | |||
34 | #if [ "$RES_IP" == "$TEST_CRED" ] | ||
35 | #then | ||
36 | # exit 0 | ||
37 | #else | ||
38 | # echo "FAIL: Failed to resolve to proper IP, got $RES_IP." | ||
39 | # exit 1 | ||
40 | #fi | ||