aboutsummaryrefslogtreecommitdiff
path: root/src/identity-provider
diff options
context:
space:
mode:
authorSchanzenbach, Martin <mschanzenbach@posteo.de>2017-09-15 18:53:10 +0200
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2017-09-15 18:53:10 +0200
commit9e6994a55e64aaf7b45fdad7277c27bf30e3c0f3 (patch)
treea214a625a9fcaeacf219f2a0072fe318b5462009 /src/identity-provider
parent41315cebe1d0a074445f28d915d7d038dea80465 (diff)
downloadgnunet-9e6994a55e64aaf7b45fdad7277c27bf30e3c0f3.tar.gz
gnunet-9e6994a55e64aaf7b45fdad7277c27bf30e3c0f3.zip
- Add attribute store API to IdP service
Diffstat (limited to 'src/identity-provider')
-rw-r--r--src/identity-provider/Makefile.am1
-rw-r--r--src/identity-provider/gnunet-idp.c28
-rw-r--r--src/identity-provider/gnunet-service-identity-provider.c325
-rw-r--r--src/identity-provider/identity_provider.h60
-rw-r--r--src/identity-provider/identity_provider_api.c116
5 files changed, 482 insertions, 48 deletions
diff --git a/src/identity-provider/Makefile.am b/src/identity-provider/Makefile.am
index 5355b1221..4f5738692 100644
--- a/src/identity-provider/Makefile.am
+++ b/src/identity-provider/Makefile.am
@@ -74,6 +74,7 @@ gnunet_idp_SOURCES = \
74gnunet_idp_LDADD = \ 74gnunet_idp_LDADD = \
75 $(top_builddir)/src/util/libgnunetutil.la \ 75 $(top_builddir)/src/util/libgnunetutil.la \
76 $(top_builddir)/src/namestore/libgnunetnamestore.la \ 76 $(top_builddir)/src/namestore/libgnunetnamestore.la \
77 $(top_builddir)/src/identity-provider/libgnunetidentityprovider.la \
77 $(top_builddir)/src/identity/libgnunetidentity.la \ 78 $(top_builddir)/src/identity/libgnunetidentity.la \
78 $(GN_LIBINTL) 79 $(GN_LIBINTL)
79 80
diff --git a/src/identity-provider/gnunet-idp.c b/src/identity-provider/gnunet-idp.c
index 6b2bdcc96..b4785580a 100644
--- a/src/identity-provider/gnunet-idp.c
+++ b/src/identity-provider/gnunet-idp.c
@@ -27,6 +27,7 @@
27#include "platform.h" 27#include "platform.h"
28#include "gnunet_util_lib.h" 28#include "gnunet_util_lib.h"
29#include "gnunet_namestore_service.h" 29#include "gnunet_namestore_service.h"
30#include "gnunet_identity_provider_service.h"
30#include "gnunet_identity_service.h" 31#include "gnunet_identity_service.h"
31#include "gnunet_signatures.h" 32#include "gnunet_signatures.h"
32 33
@@ -61,6 +62,16 @@ static char* ego_name;
61static struct GNUNET_IDENTITY_Handle *identity_handle; 62static struct GNUNET_IDENTITY_Handle *identity_handle;
62 63
63/** 64/**
65 * IdP handle
66 */
67static struct GNUNET_IDENTITY_PROVIDER_Handle *idp_handle;
68
69/**
70 * IdP operation
71 */
72static struct GNUNET_IDENTITY_PROVIDER_Operation *idp_op;
73
74/**
64 * Namestore handle 75 * Namestore handle
65 */ 76 */
66static struct GNUNET_NAMESTORE_Handle *namestore_handle; 77static struct GNUNET_NAMESTORE_Handle *namestore_handle;
@@ -235,7 +246,19 @@ abe_lookup_cb (void *cls,
235 return; 246 return;
236 } 247 }
237 248
238 size = GNUNET_CRYPTO_cpabe_encrypt (attr_value, 249 struct GNUNET_IDENTITY_PROVIDER_Attribute *attr;
250 attr = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_PROVIDER_Attribute) + strlen (attr_value) + 1);
251 attr->attribute_type = GNUNET_IDENTITY_PROVIDER_AT_STRING;
252 attr->data = &attr[1];
253 attr->data_size = strlen (attr_value) + 1;
254 idp_op = GNUNET_IDENTITY_PROVIDER_attribute_store (idp_handle,
255 zone,
256 attr_name,
257 attr,
258 &store_attr_cont,
259 NULL);
260
261 /*size = GNUNET_CRYPTO_cpabe_encrypt (attr_value,
239 strlen (attr_value) + 1, 262 strlen (attr_value) + 1,
240 attr_name, 263 attr_name,
241 abe_key, 264 abe_key,
@@ -251,7 +274,7 @@ abe_lookup_cb (void *cls,
251 1, 274 1,
252 &new_record, 275 &new_record,
253 &store_attr_cont, 276 &store_attr_cont,
254 NULL); 277 NULL);*/
255} 278}
256 279
257static void 280static void
@@ -301,6 +324,7 @@ run (void *cls,
301 } 324 }
302 325
303 namestore_handle = GNUNET_NAMESTORE_connect (c); 326 namestore_handle = GNUNET_NAMESTORE_connect (c);
327 idp_handle = GNUNET_IDENTITY_PROVIDER_connect (c);
304 //Get Ego 328 //Get Ego
305 identity_handle = GNUNET_IDENTITY_connect (c, 329 identity_handle = GNUNET_IDENTITY_connect (c,
306 &ego_cb, 330 &ego_cb,
diff --git a/src/identity-provider/gnunet-service-identity-provider.c b/src/identity-provider/gnunet-service-identity-provider.c
index 8746e39f7..5663a7681 100644
--- a/src/identity-provider/gnunet-service-identity-provider.c
+++ b/src/identity-provider/gnunet-service-identity-provider.c
@@ -129,6 +129,57 @@ static struct GNUNET_STATISTICS_Handle *stats;
129 */ 129 */
130static const struct GNUNET_CONFIGURATION_Handle *cfg; 130static const struct GNUNET_CONFIGURATION_Handle *cfg;
131 131
132struct AttributeStoreHandle
133{
134
135 /**
136 * Client connection
137 */
138 struct GNUNET_SERVICE_Client *client;
139
140 /**
141 * Identity
142 */
143 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
144
145 /**
146 * Identity pubkey
147 */
148 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
149
150 /**
151 * The issuer egos ABE master key
152 */
153 struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
154
155 /**
156 * QueueEntry
157 */
158 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
159
160 /**
161 * The attribute name
162 */
163 char *name;
164
165 /**
166 * The attribute value
167 */
168 char *attribute_value;
169
170 /**
171 * Size of the attribute value
172 */
173 size_t attribute_value_len;
174
175 /**
176 * request id
177 */
178 uint32_t r_id;
179};
180
181
182
132struct VerifiedAttributeEntry 183struct VerifiedAttributeEntry
133{ 184{
134 /** 185 /**
@@ -1175,45 +1226,13 @@ attr_collect_task (void *cls)
1175 issue_handle); 1226 issue_handle);
1176} 1227}
1177 1228
1178void
1179store_bootstrap_cont (void *cls,
1180 int32_t success,
1181 const char *emsg)
1182{
1183 if (GNUNET_SYSERR == success)
1184 {
1185 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1186 "Failed to bootstrap ABE master %s\n",
1187 emsg);
1188 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1189 return;
1190 }
1191 GNUNET_SCHEDULER_add_now (&attr_collect_task, cls);
1192}
1193
1194void
1195store_bootstrap_task (void *cls)
1196{
1197 struct IssueHandle *issue_handle = cls;
1198 struct GNUNET_GNSRECORD_Data rd[1];
1199 1229
1200 rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (issue_handle->abe_key,
1201 (void**)&rd[0].data);
1202 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
1203 rd[0].flags = GNUNET_GNSRECORD_RF_NONE | GNUNET_GNSRECORD_RF_PRIVATE;
1204 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1205 issue_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1206 &issue_handle->iss_key,
1207 "+",
1208 1,
1209 rd,
1210 &store_bootstrap_cont,
1211 issue_handle);
1212}
1213 1230
1214void 1231void
1215abe_key_lookup_error (void *cls) 1232abe_key_lookup_error (void *cls)
1216{ 1233{
1234 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1235 "Error looking for ABE master!\n");
1217 GNUNET_SCHEDULER_add_now (&do_shutdown, cls); 1236 GNUNET_SCHEDULER_add_now (&do_shutdown, cls);
1218} 1237}
1219 1238
@@ -1235,10 +1254,10 @@ abe_key_lookup_result (void *cls,
1235 GNUNET_SCHEDULER_add_now (&attr_collect_task, handle); 1254 GNUNET_SCHEDULER_add_now (&attr_collect_task, handle);
1236 return; 1255 return;
1237 } 1256 }
1257 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1258 "No ABE master found!\n");
1259 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1238 1260
1239 //No ABE master found, bootstrapping...
1240 handle->abe_key = GNUNET_CRYPTO_cpabe_create_master_key ();
1241 GNUNET_SCHEDULER_add_now (&store_bootstrap_task, handle);
1242} 1261}
1243 1262
1244/** 1263/**
@@ -1256,15 +1275,13 @@ handle_issue_message (void *cls,
1256 const char *scopes; 1275 const char *scopes;
1257 char *scopes_tmp; 1276 char *scopes_tmp;
1258 char *scope; 1277 char *scope;
1259 const char *v_attrs;
1260 uint64_t rnd_key; 1278 uint64_t rnd_key;
1261 struct GNUNET_HashCode key; 1279 struct GNUNET_HashCode key;
1262 struct IssueHandle *issue_handle; 1280 struct IssueHandle *issue_handle;
1263 struct VerifiedAttributeEntry *vattr_entry;
1264 struct GNUNET_SERVICE_Client *client = cls; 1281 struct GNUNET_SERVICE_Client *client = cls;
1265 1282
1266 scopes = (const char *) &im[1]; 1283 scopes = (const char *) &im[1];
1267 v_attrs = (const char *) &im[1] + ntohl(im->scope_len); 1284 //v_attrs = (const char *) &im[1] + ntohl(im->scope_len);
1268 issue_handle = GNUNET_malloc (sizeof (struct IssueHandle)); 1285 issue_handle = GNUNET_malloc (sizeof (struct IssueHandle));
1269 issue_handle->attr_map = GNUNET_CONTAINER_multihashmap_create (5, 1286 issue_handle->attr_map = GNUNET_CONTAINER_multihashmap_create (5,
1270 GNUNET_NO); 1287 GNUNET_NO);
@@ -1283,15 +1300,15 @@ handle_issue_message (void *cls,
1283 GNUNET_free (scopes_tmp); 1300 GNUNET_free (scopes_tmp);
1284 /*scopes_tmp = GNUNET_strdup (v_attrs); 1301 /*scopes_tmp = GNUNET_strdup (v_attrs);
1285 1302
1286 for (scope = strtok (scopes_tmp, ","); NULL != scope; scope = strtok (NULL, ",")) 1303 for (scope = strtok (scopes_tmp, ","); NULL != scope; scope = strtok (NULL, ","))
1287 { 1304 {
1288 vattr_entry = GNUNET_new (struct VerifiedAttributeEntry); 1305 vattr_entry = GNUNET_new (struct VerifiedAttributeEntry);
1289 vattr_entry->name = GNUNET_strdup (scope); 1306 vattr_entry->name = GNUNET_strdup (scope);
1290 GNUNET_CONTAINER_DLL_insert (issue_handle->v_attr_head, 1307 GNUNET_CONTAINER_DLL_insert (issue_handle->v_attr_head,
1291 issue_handle->v_attr_tail, 1308 issue_handle->v_attr_tail,
1292 vattr_entry); 1309 vattr_entry);
1293 } 1310 }
1294 GNUNET_free (scopes_tmp);*/ 1311 GNUNET_free (scopes_tmp);*/
1295 1312
1296 1313
1297 1314
@@ -1322,6 +1339,218 @@ handle_issue_message (void *cls,
1322 issue_handle); 1339 issue_handle);
1323} 1340}
1324 1341
1342static void
1343cleanup_as_handle (struct AttributeStoreHandle *handle)
1344{
1345 if (NULL != handle->name)
1346 GNUNET_free (handle->name);
1347 if (NULL != handle->attribute_value)
1348 GNUNET_free (handle->attribute_value);
1349 GNUNET_free (handle);
1350}
1351
1352
1353
1354void
1355attr_store_cont (void *cls,
1356 int32_t success,
1357 const char *emsg)
1358{
1359 struct AttributeStoreHandle *as_handle = cls;
1360 struct GNUNET_MQ_Envelope *env;
1361 struct AttributeStoreResponseMessage *acr_msg;
1362
1363 if (GNUNET_SYSERR == success)
1364 {
1365 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1366 "Failed to store attribute %s\n",
1367 emsg);
1368 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1369 return;
1370 }
1371
1372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1373 "Sending ATTRIBUTE_STORE_RESPONSE message\n");
1374 env = GNUNET_MQ_msg (acr_msg,
1375 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE);
1376 acr_msg->id = htonl (as_handle->r_id);
1377 acr_msg->op_result = htonl (GNUNET_OK);
1378 GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(as_handle->client),
1379 env);
1380 cleanup_as_handle (as_handle);
1381}
1382
1383void
1384attr_store_task (void *cls)
1385{
1386 struct AttributeStoreHandle *as_handle = cls;
1387 struct GNUNET_GNSRECORD_Data rd[1];
1388
1389 /**
1390 * Encrypt the attribute value and store in namestore
1391 */
1392 rd[0].data_size = GNUNET_CRYPTO_cpabe_encrypt (as_handle->attribute_value,
1393 as_handle->attribute_value_len,
1394 as_handle->name, //Policy
1395 as_handle->abe_key,
1396 (void**)&rd[0].data);
1397 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ID_ATTR;
1398 rd[0].flags = GNUNET_GNSRECORD_RF_NONE;
1399 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1400 as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1401 &as_handle->identity,
1402 as_handle->name,
1403 1,
1404 rd,
1405 &attr_store_cont,
1406 as_handle);
1407
1408}
1409
1410void
1411store_bootstrap_cont (void *cls,
1412 int32_t success,
1413 const char *emsg)
1414{
1415 if (GNUNET_SYSERR == success)
1416 {
1417 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1418 "Failed to bootstrap ABE master %s\n",
1419 emsg);
1420 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1421 return;
1422 }
1423 GNUNET_SCHEDULER_add_now (&attr_store_task, cls);
1424}
1425
1426void
1427store_bootstrap_task (void *cls)
1428{
1429 struct AttributeStoreHandle *as_handle = cls;
1430 struct GNUNET_GNSRECORD_Data rd[1];
1431
1432 rd[0].data_size = GNUNET_CRYPTO_cpabe_serialize_master_key (as_handle->abe_key,
1433 (void**)&rd[0].data);
1434 rd[0].record_type = GNUNET_GNSRECORD_TYPE_ABE_MASTER;
1435 rd[0].flags = GNUNET_GNSRECORD_RF_NONE | GNUNET_GNSRECORD_RF_PRIVATE;
1436 rd[0].expiration_time = GNUNET_TIME_UNIT_HOURS.rel_value_us; //TODO sane?
1437 as_handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
1438 &as_handle->identity,
1439 "+",
1440 1,
1441 rd,
1442 &store_bootstrap_cont,
1443 as_handle);
1444}
1445
1446void
1447store_cont_abe_error (void *cls)
1448{
1449 GNUNET_SCHEDULER_add_now (&do_shutdown, cls);
1450}
1451
1452void
1453store_cont_abe_result (void *cls,
1454 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1455 const char *label,
1456 unsigned int rd_count,
1457 const struct GNUNET_GNSRECORD_Data *rd)
1458{
1459 struct AttributeStoreHandle *handle = cls;
1460 int i;
1461
1462 for (i=0;i<rd_count;i++) {
1463 if (GNUNET_GNSRECORD_TYPE_ABE_MASTER != rd[i].record_type)
1464 continue;
1465 handle->abe_key = GNUNET_CRYPTO_cpabe_deserialize_master_key ((void**)rd[i].data,
1466 rd[i].data_size);
1467 GNUNET_SCHEDULER_add_now (&attr_collect_task, handle);
1468 return;
1469 }
1470
1471 //No ABE master found, bootstrapping...
1472 handle->abe_key = GNUNET_CRYPTO_cpabe_create_master_key ();
1473 GNUNET_SCHEDULER_add_now (&store_bootstrap_task, handle);
1474}
1475
1476
1477/**
1478 * Checks a store message
1479 *
1480 * @param cls client sending the message
1481 * @param sam message of type `struct AttributeStoreMessage`
1482 * @return #GNUNET_OK if @a im is well-formed
1483 */
1484static int
1485check_attribute_store_message(void *cls,
1486 const struct AttributeStoreMessage *sam)
1487{
1488 uint16_t size;
1489 uint32_t name_len;
1490
1491 size = ntohs (sam->header.size);
1492 if (size <= sizeof (struct AttributeStoreMessage))
1493 {
1494 GNUNET_break (0);
1495 return GNUNET_SYSERR;
1496 }
1497 name_len = ntohs (sam->name_len);
1498 if (0 <= name_len)
1499 {
1500 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1501 "Malformed store message received!\n");
1502 GNUNET_break (0);
1503 return GNUNET_SYSERR;
1504 }
1505 return GNUNET_OK;
1506}
1507
1508/**
1509 *
1510 * Handler for store message
1511 *
1512 * @param cls unused
1513 * @param client who sent the message
1514 * @param message the message
1515 */
1516static void
1517handle_attribute_store_message (void *cls,
1518 const struct AttributeStoreMessage *sam)
1519{
1520 struct AttributeStoreHandle *as_handle;
1521 struct GNUNET_SERVICE_Client *client = cls;
1522 size_t name_len;
1523 size_t data_len;
1524 char *attribute_value;
1525
1526 name_len = ntohs (sam->name_len);
1527 data_len = ntohs (sam->attr_value_len);
1528
1529 as_handle = GNUNET_new (struct AttributeStoreHandle);
1530 as_handle->name = GNUNET_strndup ((char*)&sam[1], name_len);
1531 attribute_value = (char*)&sam[1] + name_len;
1532
1533 as_handle->r_id = sam->id;
1534 as_handle->identity = sam->identity;
1535 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity,
1536 &as_handle->identity_pkey);
1537 as_handle->attribute_value = GNUNET_malloc (data_len);
1538 GNUNET_memcpy (as_handle->attribute_value,
1539 attribute_value,
1540 data_len);
1541 as_handle->attribute_value_len = data_len;
1542
1543 GNUNET_SERVICE_client_continue (client);
1544 as_handle->client = client;
1545 as_handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
1546 &as_handle->identity,
1547 "+",
1548 &store_cont_abe_error,
1549 as_handle,
1550 &store_cont_abe_result,
1551 as_handle);
1552}
1553
1325 1554
1326/** 1555/**
1327 * Main function that will be run 1556 * Main function that will be run
@@ -1435,5 +1664,9 @@ GNUNET_SERVICE_MAIN
1435 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE, 1664 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE,
1436 struct ExchangeMessage, 1665 struct ExchangeMessage,
1437 NULL), 1666 NULL),
1667 GNUNET_MQ_hd_var_size (attribute_store_message,
1668 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE,
1669 struct AttributeStoreMessage,
1670 NULL),
1438 GNUNET_MQ_handler_end()); 1671 GNUNET_MQ_handler_end());
1439/* end of gnunet-service-identity-provider.c */ 1672/* end of gnunet-service-identity-provider.c */
diff --git a/src/identity-provider/identity_provider.h b/src/identity-provider/identity_provider.h
index 9d2675c35..47d3f0945 100644
--- a/src/identity-provider/identity_provider.h
+++ b/src/identity-provider/identity_provider.h
@@ -173,6 +173,66 @@ struct ExchangeMessage
173 173
174}; 174};
175 175
176/**
177 * Use to store an identity attribute
178 */
179struct AttributeStoreMessage
180{
181 /**
182 * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT
183 */
184 struct GNUNET_MessageHeader header;
185
186 /**
187 * Unique identifier for this request (for key collisions).
188 */
189 uint32_t id GNUNET_PACKED;
190
191 /**
192 * The attribute type
193 */
194 uint32_t attribute_type GNUNET_PACKED;
195
196 /**
197 * The length of the attribute name
198 */
199 uint32_t name_len GNUNET_PACKED;
200
201 /**
202 * The length of the attribute value
203 */
204 uint32_t attr_value_len GNUNET_PACKED;
205
206 /**
207 * Identity
208 */
209 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
210
211 /* followed by the name of attribute as string and value data */
212
213};
214
215/**
216 * Attribute store response message
217 */
218struct AttributeStoreResponseMessage
219{
220 /**
221 * Message header
222 */
223 struct GNUNET_MessageHeader header;
224
225 /**
226 * Unique identifier for this request (for key collisions).
227 */
228 uint32_t id GNUNET_PACKED;
229
230 /**
231 * #GNUNET_SYSERR on failure, #GNUNET_OK on success
232 */
233 int32_t op_result GNUNET_PACKED;
234
235};
176 236
177GNUNET_NETWORK_STRUCT_END 237GNUNET_NETWORK_STRUCT_END
178 238
diff --git a/src/identity-provider/identity_provider_api.c b/src/identity-provider/identity_provider_api.c
index 9a3304334..bbc2bb70a 100644
--- a/src/identity-provider/identity_provider_api.c
+++ b/src/identity-provider/identity_provider_api.c
@@ -75,6 +75,11 @@ struct GNUNET_IDENTITY_PROVIDER_Operation
75 GNUNET_IDENTITY_PROVIDER_IssueCallback iss_cb; 75 GNUNET_IDENTITY_PROVIDER_IssueCallback iss_cb;
76 76
77 /** 77 /**
78 * Continuation to invoke after attribute store call
79 */
80 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus as_cb;
81
82 /**
78 * Envelope with the message for this queue entry. 83 * Envelope with the message for this queue entry.
79 */ 84 */
80 struct GNUNET_MQ_Envelope *env; 85 struct GNUNET_MQ_Envelope *env;
@@ -355,6 +360,53 @@ handle_result (void *cls,
355 360
356} 361}
357 362
363
364
365/**
366 * Handle an incoming message of type
367 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
368 *
369 * @param cls
370 * @param msg the message we received
371 */
372static void
373handle_attribute_store_response (void *cls,
374 const struct AttributeStoreResponseMessage *msg)
375{
376 struct GNUNET_IDENTITY_PROVIDER_Handle *h = cls;
377 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
378 uint32_t r_id = ntohl (msg->id);
379 int res;
380 const char *emsg;
381
382 for (op = h->op_head; NULL != op; op = op->next)
383 if (op->r_id == r_id)
384 break;
385 if (NULL == op)
386 return;
387
388 res = ntohl (msg->op_result);
389 LOG (GNUNET_ERROR_TYPE_DEBUG,
390 "Received ATTRIBUTE_STORE_RESPONSE with result %d\n",
391 res);
392
393 /* TODO: add actual error message to response... */
394 if (GNUNET_SYSERR == res)
395 emsg = _("failed to store record\n");
396 else
397 emsg = NULL;
398 if (NULL != op->as_cb)
399 op->as_cb (op->cls,
400 res,
401 emsg);
402 GNUNET_CONTAINER_DLL_remove (h->op_head,
403 h->op_tail,
404 op);
405 GNUNET_free (op);
406
407}
408
409
358/** 410/**
359 * Try again to connect to the service. 411 * Try again to connect to the service.
360 * 412 *
@@ -364,6 +416,10 @@ static void
364reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h) 416reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
365{ 417{
366 struct GNUNET_MQ_MessageHandler handlers[] = { 418 struct GNUNET_MQ_MessageHandler handlers[] = {
419 GNUNET_MQ_hd_fixed_size (attribute_store_response,
420 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE,
421 struct AttributeStoreResponseMessage,
422 h),
367 GNUNET_MQ_hd_var_size (result, 423 GNUNET_MQ_hd_var_size (result,
368 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT, 424 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ISSUE_RESULT,
369 struct IssueResultMessage, 425 struct IssueResultMessage,
@@ -372,6 +428,7 @@ reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h)
372 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT, 428 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT,
373 struct ExchangeResultMessage, 429 struct ExchangeResultMessage,
374 h), 430 h),
431
375 GNUNET_MQ_handler_end () 432 GNUNET_MQ_handler_end ()
376 }; 433 };
377 struct GNUNET_IDENTITY_PROVIDER_Operation *op; 434 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
@@ -645,6 +702,65 @@ GNUNET_IDENTITY_PROVIDER_ticket_destroy(struct GNUNET_IDENTITY_PROVIDER_Ticket *
645 GNUNET_free (ticket); 702 GNUNET_free (ticket);
646} 703}
647 704
705/**
706 * Store an attribute. If the attribute is already present,
707 * it is replaced with the new attribute.
708 *
709 * @param h handle to the identity provider
710 * @param pkey private key of the identity
711 * @param name the attribute name
712 * @param value the attribute value
713 * @param cont continuation to call when done
714 * @param cont_cls closure for @a cont
715 * @return handle to abort the request
716 */
717struct GNUNET_IDENTITY_PROVIDER_Operation *
718GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h,
719 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
720 const char* name,
721 const struct GNUNET_IDENTITY_PROVIDER_Attribute *value,
722 GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cont,
723 void *cont_cls)
724{
725 struct GNUNET_IDENTITY_PROVIDER_Operation *op;
726 struct AttributeStoreMessage *sam;
727 size_t name_len;
728 char *name_tmp;
729 char *attr_ser;
730
731
732 name_len = strlen (name) + 1;
733 if (name_len >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct AttributeStoreMessage))
734 {
735 GNUNET_break (0);
736 return NULL;
737 }
738 op = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_Operation);
739 op->h = h;
740 op->as_cb = cont;
741 op->cls = cont_cls;
742 op->r_id = h->r_id_gen++;
743 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
744 h->op_tail,
745 op);
746 op->env = GNUNET_MQ_msg_extra (sam,
747 name_len + value->data_size,
748 GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE);
749 sam->identity = *pkey;
750 sam->id = htonl (op->r_id);
751 sam->attr_value_len = htons (value->data_size);
752 sam->name_len = htons (name_len);
753 name_tmp = (char *) &sam[1];
754 GNUNET_memcpy (name_tmp, name, name_len);
755 attr_ser = &name_tmp[name_len];
756 GNUNET_memcpy (attr_ser, value->data, value->data_size);
757 if (NULL != h->mq)
758 GNUNET_MQ_send_copy (h->mq,
759 op->env);
760 return op;
761
762}
763
648 764
649 765
650 766