diff options
author | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2017-09-15 18:53:10 +0200 |
---|---|---|
committer | Schanzenbach, Martin <mschanzenbach@posteo.de> | 2017-09-15 18:53:10 +0200 |
commit | 9e6994a55e64aaf7b45fdad7277c27bf30e3c0f3 (patch) | |
tree | a214a625a9fcaeacf219f2a0072fe318b5462009 | |
parent | 41315cebe1d0a074445f28d915d7d038dea80465 (diff) | |
download | gnunet-9e6994a55e64aaf7b45fdad7277c27bf30e3c0f3.tar.gz gnunet-9e6994a55e64aaf7b45fdad7277c27bf30e3c0f3.zip |
- Add attribute store API to IdP service
-rw-r--r-- | src/identity-provider/Makefile.am | 1 | ||||
-rw-r--r-- | src/identity-provider/gnunet-idp.c | 28 | ||||
-rw-r--r-- | src/identity-provider/gnunet-service-identity-provider.c | 325 | ||||
-rw-r--r-- | src/identity-provider/identity_provider.h | 60 | ||||
-rw-r--r-- | src/identity-provider/identity_provider_api.c | 116 | ||||
-rw-r--r-- | src/include/gnunet_identity_provider_service.h | 109 | ||||
-rw-r--r-- | src/include/gnunet_protocols.h | 4 |
7 files changed, 583 insertions, 60 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 = \ | |||
74 | gnunet_idp_LDADD = \ | 74 | gnunet_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; | |||
61 | static struct GNUNET_IDENTITY_Handle *identity_handle; | 62 | static struct GNUNET_IDENTITY_Handle *identity_handle; |
62 | 63 | ||
63 | /** | 64 | /** |
65 | * IdP handle | ||
66 | */ | ||
67 | static struct GNUNET_IDENTITY_PROVIDER_Handle *idp_handle; | ||
68 | |||
69 | /** | ||
70 | * IdP operation | ||
71 | */ | ||
72 | static struct GNUNET_IDENTITY_PROVIDER_Operation *idp_op; | ||
73 | |||
74 | /** | ||
64 | * Namestore handle | 75 | * Namestore handle |
65 | */ | 76 | */ |
66 | static struct GNUNET_NAMESTORE_Handle *namestore_handle; | 77 | static 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 | ||
257 | static void | 280 | static 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 | */ |
130 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 130 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
131 | 131 | ||
132 | struct 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 | |||
132 | struct VerifiedAttributeEntry | 183 | struct VerifiedAttributeEntry |
133 | { | 184 | { |
134 | /** | 185 | /** |
@@ -1175,45 +1226,13 @@ attr_collect_task (void *cls) | |||
1175 | issue_handle); | 1226 | issue_handle); |
1176 | } | 1227 | } |
1177 | 1228 | ||
1178 | void | ||
1179 | store_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 | |||
1194 | void | ||
1195 | store_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 | ||
1214 | void | 1231 | void |
1215 | abe_key_lookup_error (void *cls) | 1232 | abe_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 | ||
1342 | static void | ||
1343 | cleanup_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 | |||
1354 | void | ||
1355 | attr_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 | |||
1383 | void | ||
1384 | attr_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 | |||
1410 | void | ||
1411 | store_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 | |||
1426 | void | ||
1427 | store_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 | |||
1446 | void | ||
1447 | store_cont_abe_error (void *cls) | ||
1448 | { | ||
1449 | GNUNET_SCHEDULER_add_now (&do_shutdown, cls); | ||
1450 | } | ||
1451 | |||
1452 | void | ||
1453 | store_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 | */ | ||
1484 | static int | ||
1485 | check_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 | */ | ||
1516 | static void | ||
1517 | handle_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 | */ | ||
179 | struct 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 | */ | ||
218 | struct 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 | ||
177 | GNUNET_NETWORK_STRUCT_END | 237 | GNUNET_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 | */ | ||
372 | static void | ||
373 | handle_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 | |||
364 | reconnect (struct GNUNET_IDENTITY_PROVIDER_Handle *h) | 416 | reconnect (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 | */ | ||
717 | struct GNUNET_IDENTITY_PROVIDER_Operation * | ||
718 | GNUNET_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 | ||
diff --git a/src/include/gnunet_identity_provider_service.h b/src/include/gnunet_identity_provider_service.h index ba727eb92..2349e7012 100644 --- a/src/include/gnunet_identity_provider_service.h +++ b/src/include/gnunet_identity_provider_service.h | |||
@@ -67,6 +67,53 @@ struct GNUNET_IDENTITY_PROVIDER_Ticket; | |||
67 | struct GNUNET_IDENTITY_PROVIDER_Operation; | 67 | struct GNUNET_IDENTITY_PROVIDER_Operation; |
68 | 68 | ||
69 | /** | 69 | /** |
70 | * Flags that can be set for an attribute. | ||
71 | */ | ||
72 | enum GNUNET_IDENTITY_PROVIDER_AttributeType | ||
73 | { | ||
74 | |||
75 | /** | ||
76 | * No value attribute. | ||
77 | */ | ||
78 | GNUNET_IDENTITY_PROVIDER_AT_NULL = 0, | ||
79 | |||
80 | /** | ||
81 | * String attribute. | ||
82 | */ | ||
83 | GNUNET_IDENTITY_PROVIDER_AT_STRING = 1, | ||
84 | |||
85 | }; | ||
86 | |||
87 | |||
88 | |||
89 | /** | ||
90 | * An attribute. | ||
91 | */ | ||
92 | struct GNUNET_IDENTITY_PROVIDER_Attribute | ||
93 | { | ||
94 | |||
95 | /** | ||
96 | * Binary value stored as attribute value. Note: "data" must never | ||
97 | * be individually 'malloc'ed, but instead always points into some | ||
98 | * existing data area. | ||
99 | */ | ||
100 | const void *data; | ||
101 | |||
102 | /** | ||
103 | * Number of bytes in @e data. | ||
104 | */ | ||
105 | size_t data_size; | ||
106 | |||
107 | /** | ||
108 | * Type of Attribute. | ||
109 | */ | ||
110 | uint32_t attribute_type; | ||
111 | |||
112 | }; | ||
113 | |||
114 | |||
115 | |||
116 | /** | ||
70 | * Method called when a token has been exchanged for a ticket. | 117 | * Method called when a token has been exchanged for a ticket. |
71 | * On success returns a token | 118 | * On success returns a token |
72 | * | 119 | * |
@@ -107,6 +154,44 @@ typedef void | |||
107 | struct GNUNET_IDENTITY_PROVIDER_Handle * | 154 | struct GNUNET_IDENTITY_PROVIDER_Handle * |
108 | GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); | 155 | GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); |
109 | 156 | ||
157 | /** | ||
158 | * Continuation called to notify client about result of the | ||
159 | * operation. | ||
160 | * | ||
161 | * @param cls closure | ||
162 | * @param success #GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate) | ||
163 | * #GNUNET_NO if content was already there or not found | ||
164 | * #GNUNET_YES (or other positive value) on success | ||
165 | * @param emsg NULL on success, otherwise an error message | ||
166 | */ | ||
167 | typedef void | ||
168 | (*GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus) (void *cls, | ||
169 | int32_t success, | ||
170 | const char *emsg); | ||
171 | |||
172 | |||
173 | /** | ||
174 | * Store an attribute. If the attribute is already present, | ||
175 | * it is replaced with the new attribute. | ||
176 | * | ||
177 | * @param h handle to the identity provider | ||
178 | * @param pkey private key of the identity | ||
179 | * @param name the attribute name | ||
180 | * @param value the attribute value | ||
181 | * @param cont continuation to call when done | ||
182 | * @param cont_cls closure for @a cont | ||
183 | * @return handle to abort the request | ||
184 | */ | ||
185 | struct GNUNET_IDENTITY_PROVIDER_Operation * | ||
186 | GNUNET_IDENTITY_PROVIDER_attribute_store (struct GNUNET_IDENTITY_PROVIDER_Handle *h, | ||
187 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey, | ||
188 | const char* name, | ||
189 | const struct GNUNET_IDENTITY_PROVIDER_Attribute *value, | ||
190 | GNUNET_IDENTITY_PROVIDER_ContinuationWithStatus cont, | ||
191 | void *cont_cls); | ||
192 | |||
193 | |||
194 | |||
110 | 195 | ||
111 | /** | 196 | /** |
112 | * Issue a token for a specific audience. | 197 | * Issue a token for a specific audience. |
@@ -123,14 +208,14 @@ GNUNET_IDENTITY_PROVIDER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) | |||
123 | */ | 208 | */ |
124 | struct GNUNET_IDENTITY_PROVIDER_Operation * | 209 | struct GNUNET_IDENTITY_PROVIDER_Operation * |
125 | GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id, | 210 | GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id, |
126 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key, | 211 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss_key, |
127 | const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, | 212 | const struct GNUNET_CRYPTO_EcdsaPublicKey *aud_key, |
128 | const char* scope, | 213 | const char* scope, |
129 | const char* vattr, | 214 | const char* vattr, |
130 | struct GNUNET_TIME_Absolute expiration, | 215 | struct GNUNET_TIME_Absolute expiration, |
131 | uint64_t nonce, | 216 | uint64_t nonce, |
132 | GNUNET_IDENTITY_PROVIDER_IssueCallback cb, | 217 | GNUNET_IDENTITY_PROVIDER_IssueCallback cb, |
133 | void *cb_cls); | 218 | void *cb_cls); |
134 | 219 | ||
135 | 220 | ||
136 | /** | 221 | /** |
@@ -146,10 +231,10 @@ GNUNET_IDENTITY_PROVIDER_issue_token (struct GNUNET_IDENTITY_PROVIDER_Handle *id | |||
146 | */ | 231 | */ |
147 | struct GNUNET_IDENTITY_PROVIDER_Operation * | 232 | struct GNUNET_IDENTITY_PROVIDER_Operation * |
148 | GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_PROVIDER_Handle *id, | 233 | GNUNET_IDENTITY_PROVIDER_exchange_ticket (struct GNUNET_IDENTITY_PROVIDER_Handle *id, |
149 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, | 234 | const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket, |
150 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *aud_privkey, | 235 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *aud_privkey, |
151 | GNUNET_IDENTITY_PROVIDER_ExchangeCallback cont, | 236 | GNUNET_IDENTITY_PROVIDER_ExchangeCallback cont, |
152 | void *cont_cls); | 237 | void *cont_cls); |
153 | 238 | ||
154 | 239 | ||
155 | /** | 240 | /** |
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 455a8292b..5841bd4f8 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -2628,6 +2628,10 @@ extern "C" | |||
2628 | 2628 | ||
2629 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT 964 | 2629 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_EXCHANGE_RESULT 964 |
2630 | 2630 | ||
2631 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE 965 | ||
2632 | |||
2633 | #define GNUNET_MESSAGE_TYPE_IDENTITY_PROVIDER_ATTRIBUTE_STORE_RESPONSE 966 | ||
2634 | |||
2631 | 2635 | ||
2632 | /************************************************** | 2636 | /************************************************** |
2633 | * | 2637 | * |