aboutsummaryrefslogtreecommitdiff
path: root/src/service/identity/identity_api_suffix_lookup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service/identity/identity_api_suffix_lookup.c')
-rw-r--r--src/service/identity/identity_api_suffix_lookup.c246
1 files changed, 246 insertions, 0 deletions
diff --git a/src/service/identity/identity_api_suffix_lookup.c b/src/service/identity/identity_api_suffix_lookup.c
new file mode 100644
index 000000000..7bc0d18f3
--- /dev/null
+++ b/src/service/identity/identity_api_suffix_lookup.c
@@ -0,0 +1,246 @@
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 it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file identity/identity_api_suffix_lookup.c
23 * @brief api to lookup an ego
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_identity_service.h"
29#include "identity.h"
30
31#define LOG(kind, ...) GNUNET_log_from (kind, "identity-api", __VA_ARGS__)
32
33
34/**
35 * Handle for ego lookup.
36 */
37struct GNUNET_IDENTITY_EgoSuffixLookup
38{
39 /**
40 * Connection to service.
41 */
42 struct GNUNET_MQ_Handle *mq;
43
44 /**
45 * Suffix we are looking up.
46 */
47 char *suffix;
48
49 /**
50 * Function to call with the result.
51 */
52 GNUNET_IDENTITY_EgoSuffixCallback cb;
53
54 /**
55 * Closure for @e cb
56 */
57 void *cb_cls;
58};
59
60
61/**
62 * We received a result code from the service. Check the message
63 * is well-formed.
64 *
65 * @param cls closure
66 * @param rcm result message received
67 * @return #GNUNET_OK if the message is well-formed
68 */
69static int
70check_identity_result_code (void *cls, const struct ResultCodeMessage *rcm)
71{
72 (void) cls;
73 if (sizeof(*rcm) != htons (rcm->header.size))
74 GNUNET_MQ_check_zero_termination (rcm);
75 return GNUNET_OK;
76}
77
78
79/**
80 * We received a result code from the service.
81 *
82 * @param cls closure
83 * @param rcm result message received
84 */
85static void
86handle_identity_result_code (void *cls, const struct ResultCodeMessage *rcm)
87{
88 struct GNUNET_IDENTITY_EgoSuffixLookup *el = cls;
89
90 (void) rcm;
91 el->cb (el->cb_cls, NULL, NULL);
92 GNUNET_IDENTITY_ego_lookup_by_suffix_cancel (el);
93}
94
95
96/**
97 * Check validity of identity update message.
98 *
99 * @param cls closure
100 * @param um message received
101 * @return #GNUNET_OK if the message is well-formed
102 */
103static int
104check_identity_update (void *cls, const struct UpdateMessage *um)
105{
106 uint16_t size = ntohs (um->header.size);
107 uint16_t name_len = ntohs (um->name_len);
108 const char *str = (const char *) &um[1];
109
110 (void) cls;
111 if ((size < name_len + sizeof(struct UpdateMessage)) ||
112 ((0 != name_len) && ('\0' != str[name_len - 1])))
113 {
114 GNUNET_break (0);
115 return GNUNET_SYSERR;
116 }
117 return GNUNET_OK;
118}
119
120
121/**
122 * Handle identity update message.
123 *
124 * @param cls closure
125 * @param um message received
126 */
127static void
128handle_identity_update (void *cls, const struct UpdateMessage *um)
129{
130 struct GNUNET_IDENTITY_EgoSuffixLookup *el = cls;
131 uint16_t name_len = ntohs (um->name_len);
132 const char *str;
133 size_t key_len;
134 size_t kb_read;
135 struct GNUNET_CRYPTO_PrivateKey private_key;
136 const char *tmp;
137
138 tmp = (const char*) &um[1];
139 str = (0 == name_len) ? NULL : tmp;
140 memset (&private_key, 0, sizeof (private_key));
141 key_len = ntohs (um->header.size) - name_len - sizeof (*um);
142 if (0 < key_len)
143 {
144 GNUNET_assert (GNUNET_SYSERR !=
145 GNUNET_CRYPTO_read_private_key_from_buffer (tmp + name_len,
146 key_len,
147 &private_key,
148 &kb_read));
149 GNUNET_assert (key_len == kb_read);
150 }
151 el->cb (el->cb_cls, &private_key, str);
152 GNUNET_IDENTITY_ego_lookup_by_suffix_cancel (el);
153}
154
155
156/**
157 * Generic error handler, called with the appropriate error code and
158 * the same closure specified at the creation of the message queue.
159 * Not every message queue implementation supports an error handler.
160 *
161 * @param cls closure with the `struct GNUNET_IDENTITY_EgoSuffixLookup *`
162 * @param error error code
163 */
164static void
165mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
166{
167 struct GNUNET_IDENTITY_EgoSuffixLookup *el = cls;
168
169 (void) error;
170 el->cb (el->cb_cls, NULL, NULL);
171 GNUNET_IDENTITY_ego_lookup_by_suffix_cancel (el);
172}
173
174
175/**
176 * Lookup an ego by name.
177 *
178 * @param cfg configuration to use
179 * @param name name to look up
180 * @param cb callback to invoke with the result
181 * @param cb_cls closure for @a cb
182 * @return NULL on error
183 */
184struct GNUNET_IDENTITY_EgoSuffixLookup *
185GNUNET_IDENTITY_ego_lookup_by_suffix (const struct
186 GNUNET_CONFIGURATION_Handle *cfg,
187 const char *suffix,
188 GNUNET_IDENTITY_EgoSuffixCallback cb,
189 void *cb_cls)
190{
191 struct GNUNET_IDENTITY_EgoSuffixLookup *el;
192 struct GNUNET_MQ_Envelope *env;
193 struct GNUNET_MessageHeader *req;
194 size_t nlen;
195
196 GNUNET_assert (NULL != cb);
197 el = GNUNET_new (struct GNUNET_IDENTITY_EgoSuffixLookup);
198 el->cb = cb;
199 el->cb_cls = cb_cls;
200 {
201 struct GNUNET_MQ_MessageHandler handlers[] =
202 { GNUNET_MQ_hd_var_size (identity_result_code,
203 GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE,
204 struct ResultCodeMessage,
205 el),
206 GNUNET_MQ_hd_var_size (identity_update,
207 GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE,
208 struct UpdateMessage,
209 el),
210 GNUNET_MQ_handler_end () };
211
212 el->mq =
213 GNUNET_CLIENT_connect (cfg, "identity", handlers, &mq_error_handler, el);
214 }
215 if (NULL == el->mq)
216 {
217 GNUNET_break (0);
218 GNUNET_free (el);
219 return NULL;
220 }
221 el->suffix = GNUNET_strdup (suffix);
222 nlen = strlen (suffix) + 1;
223 env = GNUNET_MQ_msg_extra (req, nlen,
224 GNUNET_MESSAGE_TYPE_IDENTITY_LOOKUP_BY_SUFFIX);
225 memcpy (&req[1], suffix, nlen);
226 GNUNET_MQ_send (el->mq, env);
227 return el;
228}
229
230
231/**
232 * Abort ego lookup attempt.
233 *
234 * @param el handle for lookup to abort
235 */
236void
237GNUNET_IDENTITY_ego_lookup_by_suffix_cancel (struct
238 GNUNET_IDENTITY_EgoSuffixLookup *el)
239{
240 GNUNET_MQ_destroy (el->mq);
241 GNUNET_free (el->suffix);
242 GNUNET_free (el);
243}
244
245
246/* end of identity_api_suffix_lookup.c */