reclaim_api.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2016 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file reclaim/reclaim_api.c
  18. * @brief api to interact with the reclaim service
  19. * @author Martin Schanzenbach
  20. */
  21. #include "platform.h"
  22. #include "gnunet_util_lib.h"
  23. #include "gnunet_constants.h"
  24. #include "gnunet_mq_lib.h"
  25. #include "gnunet_protocols.h"
  26. #include "gnunet_reclaim_lib.h"
  27. #include "gnunet_reclaim_service.h"
  28. #include "reclaim.h"
  29. #define LOG(kind, ...) GNUNET_log_from (kind, "reclaim-api", __VA_ARGS__)
  30. /**
  31. * Handle for an operation with the service.
  32. */
  33. struct GNUNET_RECLAIM_Operation
  34. {
  35. /**
  36. * Main handle.
  37. */
  38. struct GNUNET_RECLAIM_Handle *h;
  39. /**
  40. * We keep operations in a DLL.
  41. */
  42. struct GNUNET_RECLAIM_Operation *next;
  43. /**
  44. * We keep operations in a DLL.
  45. */
  46. struct GNUNET_RECLAIM_Operation *prev;
  47. /**
  48. * Message to send to the service.
  49. * Allocated at the end of this struct.
  50. */
  51. const struct GNUNET_MessageHeader *msg;
  52. /**
  53. * Continuation to invoke after attribute store call
  54. */
  55. GNUNET_RECLAIM_ContinuationWithStatus as_cb;
  56. /**
  57. * Attribute result callback
  58. */
  59. GNUNET_RECLAIM_AttributeResult ar_cb;
  60. /**
  61. * Attribute result callback
  62. */
  63. GNUNET_RECLAIM_AttributeTicketResult atr_cb;
  64. /**
  65. * Credential result callback
  66. */
  67. GNUNET_RECLAIM_CredentialResult at_cb;
  68. /**
  69. * Revocation result callback
  70. */
  71. GNUNET_RECLAIM_ContinuationWithStatus rvk_cb;
  72. /**
  73. * Ticket result callback
  74. */
  75. GNUNET_RECLAIM_TicketCallback tr_cb;
  76. /**
  77. * Ticket issue result callback
  78. */
  79. GNUNET_RECLAIM_IssueTicketCallback ti_cb;
  80. /**
  81. * Envelope with the message for this queue entry.
  82. */
  83. struct GNUNET_MQ_Envelope *env;
  84. /**
  85. * request id
  86. */
  87. uint32_t r_id;
  88. /**
  89. * Closure for @e cont or @e cb.
  90. */
  91. void *cls;
  92. };
  93. /**
  94. * Handle for a ticket iterator operation
  95. */
  96. struct GNUNET_RECLAIM_TicketIterator
  97. {
  98. /**
  99. * Kept in a DLL.
  100. */
  101. struct GNUNET_RECLAIM_TicketIterator *next;
  102. /**
  103. * Kept in a DLL.
  104. */
  105. struct GNUNET_RECLAIM_TicketIterator *prev;
  106. /**
  107. * Main handle to access the idp.
  108. */
  109. struct GNUNET_RECLAIM_Handle *h;
  110. /**
  111. * Function to call on completion.
  112. */
  113. GNUNET_SCHEDULER_TaskCallback finish_cb;
  114. /**
  115. * Closure for @e finish_cb.
  116. */
  117. void *finish_cb_cls;
  118. /**
  119. * The continuation to call with the results
  120. */
  121. GNUNET_RECLAIM_TicketCallback tr_cb;
  122. /**
  123. * Closure for @e tr_cb.
  124. */
  125. void *cls;
  126. /**
  127. * Function to call on errors.
  128. */
  129. GNUNET_SCHEDULER_TaskCallback error_cb;
  130. /**
  131. * Closure for @e error_cb.
  132. */
  133. void *error_cb_cls;
  134. /**
  135. * Envelope of the message to send to the service, if not yet
  136. * sent.
  137. */
  138. struct GNUNET_MQ_Envelope *env;
  139. /**
  140. * The operation id this zone iteration operation has
  141. */
  142. uint32_t r_id;
  143. };
  144. /**
  145. * Handle for a attribute iterator operation
  146. */
  147. struct GNUNET_RECLAIM_AttributeIterator
  148. {
  149. /**
  150. * Kept in a DLL.
  151. */
  152. struct GNUNET_RECLAIM_AttributeIterator *next;
  153. /**
  154. * Kept in a DLL.
  155. */
  156. struct GNUNET_RECLAIM_AttributeIterator *prev;
  157. /**
  158. * Main handle to access the service.
  159. */
  160. struct GNUNET_RECLAIM_Handle *h;
  161. /**
  162. * Function to call on completion.
  163. */
  164. GNUNET_SCHEDULER_TaskCallback finish_cb;
  165. /**
  166. * Closure for @e finish_cb.
  167. */
  168. void *finish_cb_cls;
  169. /**
  170. * The continuation to call with the results
  171. */
  172. GNUNET_RECLAIM_AttributeResult proc;
  173. /**
  174. * Closure for @e proc.
  175. */
  176. void *proc_cls;
  177. /**
  178. * Function to call on errors.
  179. */
  180. GNUNET_SCHEDULER_TaskCallback error_cb;
  181. /**
  182. * Closure for @e error_cb.
  183. */
  184. void *error_cb_cls;
  185. /**
  186. * Envelope of the message to send to the service, if not yet
  187. * sent.
  188. */
  189. struct GNUNET_MQ_Envelope *env;
  190. /**
  191. * Private key of the zone.
  192. */
  193. struct GNUNET_IDENTITY_PrivateKey identity;
  194. /**
  195. * The operation id this zone iteration operation has
  196. */
  197. uint32_t r_id;
  198. };
  199. /**
  200. * Handle for a credential iterator operation
  201. */
  202. struct GNUNET_RECLAIM_CredentialIterator
  203. {
  204. /**
  205. * Kept in a DLL.
  206. */
  207. struct GNUNET_RECLAIM_CredentialIterator *next;
  208. /**
  209. * Kept in a DLL.
  210. */
  211. struct GNUNET_RECLAIM_CredentialIterator *prev;
  212. /**
  213. * Main handle to access the service.
  214. */
  215. struct GNUNET_RECLAIM_Handle *h;
  216. /**
  217. * Function to call on completion.
  218. */
  219. GNUNET_SCHEDULER_TaskCallback finish_cb;
  220. /**
  221. * Closure for @e finish_cb.
  222. */
  223. void *finish_cb_cls;
  224. /**
  225. * The continuation to call with the results
  226. */
  227. GNUNET_RECLAIM_CredentialResult proc;
  228. /**
  229. * Closure for @e proc.
  230. */
  231. void *proc_cls;
  232. /**
  233. * Function to call on errors.
  234. */
  235. GNUNET_SCHEDULER_TaskCallback error_cb;
  236. /**
  237. * Closure for @e error_cb.
  238. */
  239. void *error_cb_cls;
  240. /**
  241. * Envelope of the message to send to the service, if not yet
  242. * sent.
  243. */
  244. struct GNUNET_MQ_Envelope *env;
  245. /**
  246. * Private key of the zone.
  247. */
  248. struct GNUNET_IDENTITY_PrivateKey identity;
  249. /**
  250. * The operation id this zone iteration operation has
  251. */
  252. uint32_t r_id;
  253. };
  254. /**
  255. * Handle to the service.
  256. */
  257. struct GNUNET_RECLAIM_Handle
  258. {
  259. /**
  260. * Configuration to use.
  261. */
  262. const struct GNUNET_CONFIGURATION_Handle *cfg;
  263. /**
  264. * Socket (if available).
  265. */
  266. struct GNUNET_CLIENT_Connection *client;
  267. /**
  268. * Closure for 'cb'.
  269. */
  270. void *cb_cls;
  271. /**
  272. * Head of active operations.
  273. */
  274. struct GNUNET_RECLAIM_Operation *op_head;
  275. /**
  276. * Tail of active operations.
  277. */
  278. struct GNUNET_RECLAIM_Operation *op_tail;
  279. /**
  280. * Head of active iterations
  281. */
  282. struct GNUNET_RECLAIM_AttributeIterator *it_head;
  283. /**
  284. * Tail of active iterations
  285. */
  286. struct GNUNET_RECLAIM_AttributeIterator *it_tail;
  287. /**
  288. * Head of active iterations
  289. */
  290. struct GNUNET_RECLAIM_CredentialIterator *ait_head;
  291. /**
  292. * Tail of active iterations
  293. */
  294. struct GNUNET_RECLAIM_CredentialIterator *ait_tail;
  295. /**
  296. * Head of active iterations
  297. */
  298. struct GNUNET_RECLAIM_TicketIterator *ticket_it_head;
  299. /**
  300. * Tail of active iterations
  301. */
  302. struct GNUNET_RECLAIM_TicketIterator *ticket_it_tail;
  303. /**
  304. * Currently pending transmission request, or NULL for none.
  305. */
  306. struct GNUNET_CLIENT_TransmitHandle *th;
  307. /**
  308. * Task doing exponential back-off trying to reconnect.
  309. */
  310. struct GNUNET_SCHEDULER_Task *reconnect_task;
  311. /**
  312. * Time for next connect retry.
  313. */
  314. struct GNUNET_TIME_Relative reconnect_backoff;
  315. /**
  316. * Connection to service (if available).
  317. */
  318. struct GNUNET_MQ_Handle *mq;
  319. /**
  320. * Request Id generator. Incremented by one for each request.
  321. */
  322. uint32_t r_id_gen;
  323. /**
  324. * Are we polling for incoming messages right now?
  325. */
  326. int in_receive;
  327. };
  328. /**
  329. * Try again to connect to the service.
  330. *
  331. * @param h handle to the reclaim service.
  332. */
  333. static void
  334. reconnect (struct GNUNET_RECLAIM_Handle *h);
  335. /**
  336. * Reconnect
  337. *
  338. * @param cls the handle
  339. */
  340. static void
  341. reconnect_task (void *cls)
  342. {
  343. struct GNUNET_RECLAIM_Handle *handle = cls;
  344. handle->reconnect_task = NULL;
  345. reconnect (handle);
  346. }
  347. /**
  348. * Disconnect from service and then reconnect.
  349. *
  350. * @param handle our service
  351. */
  352. static void
  353. force_reconnect (struct GNUNET_RECLAIM_Handle *handle)
  354. {
  355. GNUNET_MQ_destroy (handle->mq);
  356. handle->mq = NULL;
  357. handle->reconnect_backoff =
  358. GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
  359. handle->reconnect_task =
  360. GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
  361. &reconnect_task,
  362. handle);
  363. }
  364. /**
  365. * Free @a it.
  366. *
  367. * @param it entry to free
  368. */
  369. static void
  370. free_it (struct GNUNET_RECLAIM_AttributeIterator *it)
  371. {
  372. struct GNUNET_RECLAIM_Handle *h = it->h;
  373. GNUNET_CONTAINER_DLL_remove (h->it_head, h->it_tail, it);
  374. if (NULL != it->env)
  375. GNUNET_MQ_discard (it->env);
  376. GNUNET_free (it);
  377. }
  378. /**
  379. * Free @a it.
  380. *
  381. * @param ait entry to free
  382. */
  383. static void
  384. free_ait (struct GNUNET_RECLAIM_CredentialIterator *ait)
  385. {
  386. struct GNUNET_RECLAIM_Handle *h = ait->h;
  387. GNUNET_CONTAINER_DLL_remove (h->ait_head, h->ait_tail, ait);
  388. if (NULL != ait->env)
  389. GNUNET_MQ_discard (ait->env);
  390. GNUNET_free (ait);
  391. }
  392. /**
  393. * Free @a op
  394. *
  395. * @param op the operation to free
  396. */
  397. static void
  398. free_op (struct GNUNET_RECLAIM_Operation *op)
  399. {
  400. if (NULL == op)
  401. return;
  402. if (NULL != op->env)
  403. GNUNET_MQ_discard (op->env);
  404. GNUNET_free (op);
  405. }
  406. /**
  407. * Generic error handler, called with the appropriate error code and
  408. * the same closure specified at the creation of the message queue.
  409. * Not every message queue implementation supports an error handler.
  410. *
  411. * @param cls closure with the `struct GNUNET_GNS_Handle *`
  412. * @param error error code
  413. */
  414. static void
  415. mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
  416. {
  417. struct GNUNET_RECLAIM_Handle *handle = cls;
  418. force_reconnect (handle);
  419. }
  420. /**
  421. * Handle an incoming message of type
  422. * #GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE
  423. *
  424. * @param cls
  425. * @param msg the message we received
  426. */
  427. static void
  428. handle_success_response (void *cls, const struct SuccessResultMessage *msg)
  429. {
  430. struct GNUNET_RECLAIM_Handle *h = cls;
  431. struct GNUNET_RECLAIM_Operation *op;
  432. uint32_t r_id = ntohl (msg->id);
  433. int res;
  434. const char *emsg;
  435. for (op = h->op_head; NULL != op; op = op->next)
  436. if (op->r_id == r_id)
  437. break;
  438. if (NULL == op)
  439. return;
  440. res = ntohl (msg->op_result);
  441. LOG (GNUNET_ERROR_TYPE_DEBUG,
  442. "Received SUCCESS_RESPONSE with result %d\n",
  443. res);
  444. /* TODO: add actual error message to response... */
  445. if (GNUNET_SYSERR == res)
  446. emsg = _ ("failed to store record\n");
  447. else
  448. emsg = NULL;
  449. if (NULL != op->as_cb)
  450. op->as_cb (op->cls, res, emsg);
  451. GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
  452. free_op (op);
  453. }
  454. /**
  455. * Handle an incoming message of type
  456. * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
  457. *
  458. * @param cls
  459. * @param msg the message we received
  460. * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  461. */
  462. static int
  463. check_consume_ticket_result (void *cls,
  464. const struct ConsumeTicketResultMessage *msg)
  465. {
  466. size_t msg_len;
  467. size_t attrs_len;
  468. size_t pl_len;
  469. msg_len = ntohs (msg->header.size);
  470. attrs_len = ntohs (msg->attrs_len);
  471. pl_len = ntohs (msg->presentations_len);
  472. if (msg_len !=
  473. sizeof(struct ConsumeTicketResultMessage) + attrs_len + pl_len)
  474. {
  475. GNUNET_break (0);
  476. return GNUNET_SYSERR;
  477. }
  478. return GNUNET_OK;
  479. }
  480. /**
  481. * Handle an incoming message of type
  482. * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
  483. *
  484. * @param cls
  485. * @param msg the message we received
  486. */
  487. static void
  488. handle_consume_ticket_result (void *cls,
  489. const struct ConsumeTicketResultMessage *msg)
  490. {
  491. struct GNUNET_RECLAIM_Handle *h = cls;
  492. struct GNUNET_RECLAIM_Operation *op;
  493. size_t attrs_len;
  494. size_t pl_len;
  495. uint32_t r_id = ntohl (msg->id);
  496. char *read_ptr;
  497. attrs_len = ntohs (msg->attrs_len);
  498. pl_len = ntohs (msg->presentations_len);
  499. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing ticket result.\n");
  500. for (op = h->op_head; NULL != op; op = op->next)
  501. if (op->r_id == r_id)
  502. break;
  503. if (NULL == op)
  504. return;
  505. {
  506. struct GNUNET_RECLAIM_AttributeList *attrs;
  507. struct GNUNET_RECLAIM_AttributeListEntry *le;
  508. struct GNUNET_RECLAIM_PresentationList *pl;
  509. struct GNUNET_RECLAIM_PresentationListEntry *ple;
  510. attrs =
  511. GNUNET_RECLAIM_attribute_list_deserialize ((char *) &msg[1], attrs_len);
  512. read_ptr = ((char *) &msg[1]) + attrs_len;
  513. pl = GNUNET_RECLAIM_presentation_list_deserialize (read_ptr, pl_len);
  514. if (NULL != op->atr_cb)
  515. {
  516. if (NULL == attrs)
  517. {
  518. op->atr_cb (op->cls, &msg->identity, NULL, NULL);
  519. }
  520. else
  521. {
  522. for (le = attrs->list_head; NULL != le; le = le->next)
  523. {
  524. if (GNUNET_NO ==
  525. GNUNET_RECLAIM_id_is_zero (&le->attribute->credential))
  526. {
  527. for (ple = pl->list_head; NULL != ple; ple = ple->next)
  528. {
  529. if (GNUNET_YES ==
  530. GNUNET_RECLAIM_id_is_equal (&le->attribute->credential,
  531. &ple->presentation->credential_id))
  532. {
  533. op->atr_cb (op->cls, &msg->identity,
  534. le->attribute, ple->presentation);
  535. break;
  536. }
  537. }
  538. }
  539. else // No credentials
  540. {
  541. op->atr_cb (op->cls, &msg->identity,
  542. le->attribute, NULL);
  543. }
  544. }
  545. }
  546. op->atr_cb (op->cls, NULL, NULL, NULL);
  547. }
  548. if (NULL != attrs)
  549. GNUNET_RECLAIM_attribute_list_destroy (attrs);
  550. if (NULL != pl)
  551. GNUNET_RECLAIM_presentation_list_destroy (pl);
  552. GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
  553. free_op (op);
  554. return;
  555. }
  556. GNUNET_assert (0);
  557. }
  558. /**
  559. * Handle an incoming message of type
  560. * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
  561. *
  562. * @param cls
  563. * @param msg the message we received
  564. * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  565. */
  566. static int
  567. check_attribute_result (void *cls, const struct AttributeResultMessage *msg)
  568. {
  569. size_t msg_len;
  570. size_t attr_len;
  571. msg_len = ntohs (msg->header.size);
  572. attr_len = ntohs (msg->attr_len);
  573. if (msg_len != sizeof(struct AttributeResultMessage) + attr_len)
  574. {
  575. GNUNET_break (0);
  576. return GNUNET_SYSERR;
  577. }
  578. return GNUNET_OK;
  579. }
  580. /**
  581. * Handle an incoming message of type
  582. * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
  583. *
  584. * @param cls
  585. * @param msg the message we received
  586. */
  587. static void
  588. handle_attribute_result (void *cls, const struct AttributeResultMessage *msg)
  589. {
  590. static struct GNUNET_IDENTITY_PrivateKey identity_dummy;
  591. struct GNUNET_RECLAIM_Handle *h = cls;
  592. struct GNUNET_RECLAIM_AttributeIterator *it;
  593. struct GNUNET_RECLAIM_Operation *op;
  594. size_t attr_len;
  595. uint32_t r_id = ntohl (msg->id);
  596. attr_len = ntohs (msg->attr_len);
  597. LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attribute result.\n");
  598. for (it = h->it_head; NULL != it; it = it->next)
  599. if (it->r_id == r_id)
  600. break;
  601. for (op = h->op_head; NULL != op; op = op->next)
  602. if (op->r_id == r_id)
  603. break;
  604. if ((NULL == it) && (NULL == op))
  605. return;
  606. if ((0 ==
  607. (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
  608. {
  609. if ((NULL == it) && (NULL == op))
  610. {
  611. GNUNET_break (0);
  612. force_reconnect (h);
  613. return;
  614. }
  615. if (NULL != it)
  616. {
  617. if (NULL != it->finish_cb)
  618. it->finish_cb (it->finish_cb_cls);
  619. free_it (it);
  620. }
  621. if (NULL != op)
  622. {
  623. if (NULL != op->ar_cb)
  624. op->ar_cb (op->cls, NULL, NULL);
  625. GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
  626. free_op (op);
  627. }
  628. return;
  629. }
  630. {
  631. struct GNUNET_RECLAIM_Attribute *attr;
  632. GNUNET_RECLAIM_attribute_deserialize ((char *) &msg[1], attr_len,
  633. &attr);
  634. if (NULL != it)
  635. {
  636. if (NULL != it->proc)
  637. it->proc (it->proc_cls, &msg->identity, attr);
  638. }
  639. else if (NULL != op)
  640. {
  641. if (NULL != op->ar_cb)
  642. op->ar_cb (op->cls, &msg->identity, attr);
  643. }
  644. GNUNET_free (attr);
  645. return;
  646. }
  647. GNUNET_assert (0);
  648. }
  649. /**
  650. * Handle an incoming message of type
  651. * #GNUNET_MESSAGE_TYPE_RECLAIM_credential_RESULT
  652. *
  653. * @param cls
  654. * @param msg the message we received
  655. * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  656. */
  657. static int
  658. check_credential_result (void *cls, const struct CredentialResultMessage *msg)
  659. {
  660. size_t msg_len;
  661. size_t cred_len;
  662. msg_len = ntohs (msg->header.size);
  663. cred_len = ntohs (msg->credential_len);
  664. if (msg_len != sizeof(struct CredentialResultMessage) + cred_len)
  665. {
  666. GNUNET_break (0);
  667. return GNUNET_SYSERR;
  668. }
  669. return GNUNET_OK;
  670. }
  671. /**
  672. * Handle an incoming message of type
  673. * #GNUNET_MESSAGE_TYPE_RECLAIM_credential_RESULT
  674. *
  675. * @param cls
  676. * @param msg the message we received
  677. */
  678. static void
  679. handle_credential_result (void *cls, const struct
  680. CredentialResultMessage *msg)
  681. {
  682. static struct GNUNET_IDENTITY_PrivateKey identity_dummy;
  683. struct GNUNET_RECLAIM_Handle *h = cls;
  684. struct GNUNET_RECLAIM_CredentialIterator *it;
  685. struct GNUNET_RECLAIM_Operation *op;
  686. size_t att_len;
  687. uint32_t r_id = ntohl (msg->id);
  688. att_len = ntohs (msg->credential_len);
  689. LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing credential result.\n");
  690. for (it = h->ait_head; NULL != it; it = it->next)
  691. if (it->r_id == r_id)
  692. break;
  693. for (op = h->op_head; NULL != op; op = op->next)
  694. if (op->r_id == r_id)
  695. break;
  696. if ((NULL == it) && (NULL == op))
  697. return;
  698. if ((0 ==
  699. (memcmp (&msg->identity, &identity_dummy, sizeof(identity_dummy)))))
  700. {
  701. if ((NULL == it) && (NULL == op))
  702. {
  703. GNUNET_break (0);
  704. force_reconnect (h);
  705. return;
  706. }
  707. if (NULL != it)
  708. {
  709. if (NULL != it->finish_cb)
  710. it->finish_cb (it->finish_cb_cls);
  711. free_ait (it);
  712. }
  713. if (NULL != op)
  714. {
  715. if (NULL != op->at_cb)
  716. op->at_cb (op->cls, NULL, NULL);
  717. GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
  718. free_op (op);
  719. }
  720. return;
  721. }
  722. {
  723. struct GNUNET_RECLAIM_Credential *att;
  724. att = GNUNET_RECLAIM_credential_deserialize ((char *) &msg[1], att_len);
  725. if (NULL != it)
  726. {
  727. if (NULL != it->proc)
  728. it->proc (it->proc_cls, &msg->identity, att);
  729. }
  730. else if (NULL != op)
  731. {
  732. if (NULL != op->at_cb)
  733. op->at_cb (op->cls, &msg->identity, att);
  734. }
  735. GNUNET_free (att);
  736. return;
  737. }
  738. GNUNET_assert (0);
  739. }
  740. /**
  741. * Handle an incoming message of type
  742. * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT
  743. *
  744. * @param cls
  745. * @param msg the message we received
  746. * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  747. */
  748. static int
  749. check_ticket_result (void *cls, const struct TicketResultMessage *msg)
  750. {
  751. size_t msg_len;
  752. size_t pres_len;
  753. msg_len = ntohs (msg->header.size);
  754. pres_len = ntohs (msg->presentations_len);
  755. if (msg_len != sizeof(struct TicketResultMessage) + pres_len)
  756. {
  757. GNUNET_break (0);
  758. return GNUNET_SYSERR;
  759. }
  760. return GNUNET_OK;
  761. }
  762. /**
  763. * Handle an incoming message of type
  764. * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT
  765. *
  766. * @param cls
  767. * @param msg the message we received
  768. */
  769. static void
  770. handle_ticket_result (void *cls, const struct TicketResultMessage *msg)
  771. {
  772. struct GNUNET_RECLAIM_Handle *handle = cls;
  773. struct GNUNET_RECLAIM_Operation *op;
  774. struct GNUNET_RECLAIM_TicketIterator *it;
  775. struct GNUNET_RECLAIM_PresentationList *presentation;
  776. uint32_t r_id = ntohl (msg->id);
  777. static const struct GNUNET_RECLAIM_Ticket ticket;
  778. uint32_t pres_len = ntohs (msg->presentations_len);
  779. for (op = handle->op_head; NULL != op; op = op->next)
  780. if (op->r_id == r_id)
  781. break;
  782. for (it = handle->ticket_it_head; NULL != it; it = it->next)
  783. if (it->r_id == r_id)
  784. break;
  785. if ((NULL == op) && (NULL == it))
  786. return;
  787. if (NULL != op)
  788. {
  789. if (0 < pres_len)
  790. presentation = GNUNET_RECLAIM_presentation_list_deserialize (
  791. (char*) &msg[1],
  792. pres_len);
  793. GNUNET_CONTAINER_DLL_remove (handle->op_head, handle->op_tail, op);
  794. if (0 ==
  795. memcmp (&msg->ticket, &ticket, sizeof(struct GNUNET_RECLAIM_Ticket)))
  796. {
  797. if (NULL != op->ti_cb)
  798. op->ti_cb (op->cls, NULL, NULL);
  799. }
  800. else
  801. {
  802. if (NULL != op->ti_cb)
  803. op->ti_cb (op->cls,
  804. &msg->ticket,
  805. (0 < pres_len) ? presentation : NULL);
  806. }
  807. if (0 < pres_len)
  808. GNUNET_RECLAIM_presentation_list_destroy (presentation);
  809. free_op (op);
  810. return;
  811. }
  812. else if (NULL != it)
  813. {
  814. if (0 ==
  815. memcmp (&msg->ticket, &ticket, sizeof(struct GNUNET_RECLAIM_Ticket)))
  816. {
  817. GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head,
  818. handle->ticket_it_tail,
  819. it);
  820. it->finish_cb (it->finish_cb_cls);
  821. GNUNET_free (it);
  822. }
  823. else
  824. {
  825. if (NULL != it->tr_cb)
  826. it->tr_cb (it->cls, &msg->ticket);
  827. }
  828. return;
  829. }
  830. GNUNET_break (0);
  831. }
  832. /**
  833. * Handle an incoming message of type
  834. * #GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT
  835. *
  836. * @param cls
  837. * @param msg the message we received
  838. */
  839. static void
  840. handle_revoke_ticket_result (void *cls,
  841. const struct RevokeTicketResultMessage *msg)
  842. {
  843. struct GNUNET_RECLAIM_Handle *h = cls;
  844. struct GNUNET_RECLAIM_Operation *op;
  845. uint32_t r_id = ntohl (msg->id);
  846. int32_t success;
  847. LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing revocation result.\n");
  848. for (op = h->op_head; NULL != op; op = op->next)
  849. if (op->r_id == r_id)
  850. break;
  851. if (NULL == op)
  852. return;
  853. success = ntohl (msg->success);
  854. {
  855. if (NULL != op->rvk_cb)
  856. {
  857. op->rvk_cb (op->cls, success, NULL);
  858. }
  859. GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
  860. free_op (op);
  861. return;
  862. }
  863. GNUNET_assert (0);
  864. }
  865. /**
  866. * Try again to connect to the service.
  867. *
  868. * @param h handle to the reclaim service.
  869. */
  870. static void
  871. reconnect (struct GNUNET_RECLAIM_Handle *h)
  872. {
  873. struct GNUNET_MQ_MessageHandler handlers[] =
  874. { GNUNET_MQ_hd_fixed_size (success_response,
  875. GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE,
  876. struct SuccessResultMessage,
  877. h),
  878. GNUNET_MQ_hd_var_size (attribute_result,
  879. GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT,
  880. struct AttributeResultMessage,
  881. h),
  882. GNUNET_MQ_hd_var_size (credential_result,
  883. GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_RESULT,
  884. struct CredentialResultMessage,
  885. h),
  886. GNUNET_MQ_hd_var_size (ticket_result,
  887. GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT,
  888. struct TicketResultMessage,
  889. h),
  890. GNUNET_MQ_hd_var_size (consume_ticket_result,
  891. GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT,
  892. struct ConsumeTicketResultMessage,
  893. h),
  894. GNUNET_MQ_hd_fixed_size (revoke_ticket_result,
  895. GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT,
  896. struct RevokeTicketResultMessage,
  897. h),
  898. GNUNET_MQ_handler_end () };
  899. struct GNUNET_RECLAIM_Operation *op;
  900. GNUNET_assert (NULL == h->mq);
  901. LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to reclaim service.\n");
  902. h->mq =
  903. GNUNET_CLIENT_connect (h->cfg, "reclaim", handlers, &mq_error_handler, h);
  904. if (NULL == h->mq)
  905. return;
  906. for (op = h->op_head; NULL != op; op = op->next)
  907. GNUNET_MQ_send_copy (h->mq, op->env);
  908. }
  909. /**
  910. * Connect to the reclaim service.
  911. *
  912. * @param cfg the configuration to use
  913. * @return handle to use
  914. */
  915. struct GNUNET_RECLAIM_Handle *
  916. GNUNET_RECLAIM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
  917. {
  918. struct GNUNET_RECLAIM_Handle *h;
  919. h = GNUNET_new (struct GNUNET_RECLAIM_Handle);
  920. h->cfg = cfg;
  921. reconnect (h);
  922. if (NULL == h->mq)
  923. {
  924. GNUNET_free (h);
  925. return NULL;
  926. }
  927. return h;
  928. }
  929. /**
  930. * Cancel an operation. Note that the operation MAY still
  931. * be executed; this merely cancels the continuation; if the request
  932. * was already transmitted, the service may still choose to complete
  933. * the operation.
  934. *
  935. * @param op operation to cancel
  936. */
  937. void
  938. GNUNET_RECLAIM_cancel (struct GNUNET_RECLAIM_Operation *op)
  939. {
  940. struct GNUNET_RECLAIM_Handle *h = op->h;
  941. GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
  942. free_op (op);
  943. }
  944. /**
  945. * Disconnect from service
  946. *
  947. * @param h handle to destroy
  948. */
  949. void
  950. GNUNET_RECLAIM_disconnect (struct GNUNET_RECLAIM_Handle *h)
  951. {
  952. GNUNET_assert (NULL != h);
  953. if (NULL != h->mq)
  954. {
  955. GNUNET_MQ_destroy (h->mq);
  956. h->mq = NULL;
  957. }
  958. if (NULL != h->reconnect_task)
  959. {
  960. GNUNET_SCHEDULER_cancel (h->reconnect_task);
  961. h->reconnect_task = NULL;
  962. }
  963. GNUNET_assert (NULL == h->op_head);
  964. GNUNET_free (h);
  965. }
  966. /**
  967. * Store an attribute. If the attribute is already present,
  968. * it is replaced with the new attribute.
  969. *
  970. * @param h handle to the re:claimID service
  971. * @param pkey private key of the identity
  972. * @param attr the attribute value
  973. * @param exp_interval the relative expiration interval for the attribute
  974. * @param cont continuation to call when done
  975. * @param cont_cls closure for @a cont
  976. * @return handle to abort the request
  977. */
  978. struct GNUNET_RECLAIM_Operation *
  979. GNUNET_RECLAIM_attribute_store (
  980. struct GNUNET_RECLAIM_Handle *h,
  981. const struct GNUNET_IDENTITY_PrivateKey *pkey,
  982. const struct GNUNET_RECLAIM_Attribute *attr,
  983. const struct GNUNET_TIME_Relative *exp_interval,
  984. GNUNET_RECLAIM_ContinuationWithStatus cont,
  985. void *cont_cls)
  986. {
  987. struct GNUNET_RECLAIM_Operation *op;
  988. struct AttributeStoreMessage *sam;
  989. size_t attr_len;
  990. op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
  991. op->h = h;
  992. op->as_cb = cont;
  993. op->cls = cont_cls;
  994. op->r_id = h->r_id_gen++;
  995. GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
  996. attr_len = GNUNET_RECLAIM_attribute_serialize_get_size (attr);
  997. op->env = GNUNET_MQ_msg_extra (sam,
  998. attr_len,
  999. GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE);
  1000. sam->identity = *pkey;
  1001. sam->id = htonl (op->r_id);
  1002. sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
  1003. GNUNET_RECLAIM_attribute_serialize (attr, (char *) &sam[1]);
  1004. sam->attr_len = htons (attr_len);
  1005. if (NULL != h->mq)
  1006. GNUNET_MQ_send_copy (h->mq, op->env);
  1007. return op;
  1008. }
  1009. /**
  1010. * Delete an attribute. Tickets used to share this attribute are updated
  1011. * accordingly.
  1012. *
  1013. * @param h handle to the re:claimID service
  1014. * @param pkey Private key of the identity to add an attribute to
  1015. * @param attr The attribute
  1016. * @param cont Continuation to call when done
  1017. * @param cont_cls Closure for @a cont
  1018. * @return handle Used to to abort the request
  1019. */
  1020. struct GNUNET_RECLAIM_Operation *
  1021. GNUNET_RECLAIM_attribute_delete (
  1022. struct GNUNET_RECLAIM_Handle *h,
  1023. const struct GNUNET_IDENTITY_PrivateKey *pkey,
  1024. const struct GNUNET_RECLAIM_Attribute *attr,
  1025. GNUNET_RECLAIM_ContinuationWithStatus cont,
  1026. void *cont_cls)
  1027. {
  1028. struct GNUNET_RECLAIM_Operation *op;
  1029. struct AttributeDeleteMessage *dam;
  1030. size_t attr_len;
  1031. op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
  1032. op->h = h;
  1033. op->as_cb = cont;
  1034. op->cls = cont_cls;
  1035. op->r_id = h->r_id_gen++;
  1036. GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
  1037. attr_len = GNUNET_RECLAIM_attribute_serialize_get_size (attr);
  1038. op->env = GNUNET_MQ_msg_extra (dam,
  1039. attr_len,
  1040. GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE);
  1041. dam->identity = *pkey;
  1042. dam->id = htonl (op->r_id);
  1043. GNUNET_RECLAIM_attribute_serialize (attr, (char *) &dam[1]);
  1044. dam->attr_len = htons (attr_len);
  1045. if (NULL != h->mq)
  1046. GNUNET_MQ_send_copy (h->mq, op->env);
  1047. return op;
  1048. }
  1049. /**
  1050. * Store an credential. If the credential is already present,
  1051. * it is replaced with the new credential.
  1052. *
  1053. * @param h handle to the re:claimID service
  1054. * @param pkey private key of the identity
  1055. * @param attr the credential value
  1056. * @param exp_interval the relative expiration interval for the credential
  1057. * @param cont continuation to call when done
  1058. * @param cont_cls closure for @a cont
  1059. * @return handle to abort the request
  1060. */
  1061. struct GNUNET_RECLAIM_Operation *
  1062. GNUNET_RECLAIM_credential_store (
  1063. struct GNUNET_RECLAIM_Handle *h,
  1064. const struct GNUNET_IDENTITY_PrivateKey *pkey,
  1065. const struct GNUNET_RECLAIM_Credential *attr,
  1066. const struct GNUNET_TIME_Relative *exp_interval,
  1067. GNUNET_RECLAIM_ContinuationWithStatus cont,
  1068. void *cont_cls)
  1069. {
  1070. struct GNUNET_RECLAIM_Operation *op;
  1071. struct AttributeStoreMessage *sam;
  1072. size_t attr_len;
  1073. op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
  1074. op->h = h;
  1075. op->as_cb = cont;
  1076. op->cls = cont_cls;
  1077. op->r_id = h->r_id_gen++;
  1078. GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
  1079. attr_len = GNUNET_RECLAIM_credential_serialize_get_size (attr);
  1080. op->env = GNUNET_MQ_msg_extra (sam,
  1081. attr_len,
  1082. GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_STORE);
  1083. sam->identity = *pkey;
  1084. sam->id = htonl (op->r_id);
  1085. sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
  1086. GNUNET_RECLAIM_credential_serialize (attr, (char *) &sam[1]);
  1087. sam->attr_len = htons (attr_len);
  1088. if (NULL != h->mq)
  1089. GNUNET_MQ_send_copy (h->mq, op->env);
  1090. return op;
  1091. }
  1092. /**
  1093. * Delete an credential. Tickets used to share this credential are updated
  1094. * accordingly.
  1095. *
  1096. * @param h handle to the re:claimID service
  1097. * @param pkey Private key of the identity to add an attribute to
  1098. * @param attr The credential
  1099. * @param cont Continuation to call when done
  1100. * @param cont_cls Closure for @a cont
  1101. * @return handle Used to to abort the request
  1102. */
  1103. struct GNUNET_RECLAIM_Operation *
  1104. GNUNET_RECLAIM_credential_delete (
  1105. struct GNUNET_RECLAIM_Handle *h,
  1106. const struct GNUNET_IDENTITY_PrivateKey *pkey,
  1107. const struct GNUNET_RECLAIM_Credential *attr,
  1108. GNUNET_RECLAIM_ContinuationWithStatus cont,
  1109. void *cont_cls)
  1110. {
  1111. struct GNUNET_RECLAIM_Operation *op;
  1112. struct AttributeDeleteMessage *dam;
  1113. size_t attr_len;
  1114. op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
  1115. op->h = h;
  1116. op->as_cb = cont;
  1117. op->cls = cont_cls;
  1118. op->r_id = h->r_id_gen++;
  1119. GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
  1120. attr_len = GNUNET_RECLAIM_credential_serialize_get_size (attr);
  1121. op->env = GNUNET_MQ_msg_extra (dam,
  1122. attr_len,
  1123. GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_DELETE);
  1124. dam->identity = *pkey;
  1125. dam->id = htonl (op->r_id);
  1126. GNUNET_RECLAIM_credential_serialize (attr, (char *) &dam[1]);
  1127. dam->attr_len = htons (attr_len);
  1128. if (NULL != h->mq)
  1129. GNUNET_MQ_send_copy (h->mq, op->env);
  1130. return op;
  1131. }
  1132. /**
  1133. * List all attributes for a local identity.
  1134. * This MUST lock the `struct GNUNET_RECLAIM_Handle`
  1135. * for any other calls than #GNUNET_RECLAIM_get_attributes_next() and
  1136. * #GNUNET_RECLAIM_get_attributes_stop. @a proc will be called once
  1137. * immediately, and then again after
  1138. * #GNUNET_RECLAIM_get_attributes_next() is invoked.
  1139. *
  1140. * On error (disconnect), @a error_cb will be invoked.
  1141. * On normal completion, @a finish_cb proc will be
  1142. * invoked.
  1143. *
  1144. * @param h Handle to the re:claimID service
  1145. * @param identity Identity to iterate over
  1146. * @param error_cb Function to call on error (i.e. disconnect),
  1147. * the handle is afterwards invalid
  1148. * @param error_cb_cls Closure for @a error_cb
  1149. * @param proc Function to call on each attribute
  1150. * @param proc_cls Closure for @a proc
  1151. * @param finish_cb Function to call on completion
  1152. * the handle is afterwards invalid
  1153. * @param finish_cb_cls Closure for @a finish_cb
  1154. * @return an iterator Handle to use for iteration
  1155. */
  1156. struct GNUNET_RECLAIM_AttributeIterator *
  1157. GNUNET_RECLAIM_get_attributes_start (
  1158. struct GNUNET_RECLAIM_Handle *h,
  1159. const struct GNUNET_IDENTITY_PrivateKey *identity,
  1160. GNUNET_SCHEDULER_TaskCallback error_cb,
  1161. void *error_cb_cls,
  1162. GNUNET_RECLAIM_AttributeResult proc,
  1163. void *proc_cls,
  1164. GNUNET_SCHEDULER_TaskCallback finish_cb,
  1165. void *finish_cb_cls)
  1166. {
  1167. struct GNUNET_RECLAIM_AttributeIterator *it;
  1168. struct GNUNET_MQ_Envelope *env;
  1169. struct AttributeIterationStartMessage *msg;
  1170. uint32_t rid;
  1171. rid = h->r_id_gen++;
  1172. it = GNUNET_new (struct GNUNET_RECLAIM_AttributeIterator);
  1173. it->h = h;
  1174. it->error_cb = error_cb;
  1175. it->error_cb_cls = error_cb_cls;
  1176. it->finish_cb = finish_cb;
  1177. it->finish_cb_cls = finish_cb_cls;
  1178. it->proc = proc;
  1179. it->proc_cls = proc_cls;
  1180. it->r_id = rid;
  1181. it->identity = *identity;
  1182. GNUNET_CONTAINER_DLL_insert_tail (h->it_head, h->it_tail, it);
  1183. env =
  1184. GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START);
  1185. msg->id = htonl (rid);
  1186. msg->identity = *identity;
  1187. if (NULL == h->mq)
  1188. it->env = env;
  1189. else
  1190. GNUNET_MQ_send (h->mq, env);
  1191. return it;
  1192. }
  1193. /**
  1194. * Calls the record processor specified in #GNUNET_RECLAIM_get_attributes_start
  1195. * for the next record.
  1196. *
  1197. * @param it the iterator
  1198. */
  1199. void
  1200. GNUNET_RECLAIM_get_attributes_next (struct GNUNET_RECLAIM_AttributeIterator *it)
  1201. {
  1202. struct GNUNET_RECLAIM_Handle *h = it->h;
  1203. struct AttributeIterationNextMessage *msg;
  1204. struct GNUNET_MQ_Envelope *env;
  1205. env =
  1206. GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT);
  1207. msg->id = htonl (it->r_id);
  1208. GNUNET_MQ_send (h->mq, env);
  1209. }
  1210. /**
  1211. * Stops iteration and releases the handle for further calls. Must
  1212. * be called on any iteration that has not yet completed prior to calling
  1213. * #GNUNET_RECLAIM_disconnect.
  1214. *
  1215. * @param it the iterator
  1216. */
  1217. void
  1218. GNUNET_RECLAIM_get_attributes_stop (struct GNUNET_RECLAIM_AttributeIterator *it)
  1219. {
  1220. struct GNUNET_RECLAIM_Handle *h = it->h;
  1221. struct GNUNET_MQ_Envelope *env;
  1222. struct AttributeIterationStopMessage *msg;
  1223. if (NULL != h->mq)
  1224. {
  1225. env =
  1226. GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP);
  1227. msg->id = htonl (it->r_id);
  1228. GNUNET_MQ_send (h->mq, env);
  1229. }
  1230. free_it (it);
  1231. }
  1232. /**
  1233. * List all credentials for a local identity.
  1234. * This MUST lock the `struct GNUNET_RECLAIM_Handle`
  1235. * for any other calls than #GNUNET_RECLAIM_get_credentials_next() and
  1236. * #GNUNET_RECLAIM_get_credentials_stop. @a proc will be called once
  1237. * immediately, and then again after
  1238. * #GNUNET_RECLAIM_get_credentials_next() is invoked.
  1239. *
  1240. * On error (disconnect), @a error_cb will be invoked.
  1241. * On normal completion, @a finish_cb proc will be
  1242. * invoked.
  1243. *
  1244. * @param h Handle to the re:claimID service
  1245. * @param identity Identity to iterate over
  1246. * @param error_cb Function to call on error (i.e. disconnect),
  1247. * the handle is afterwards invalid
  1248. * @param error_cb_cls Closure for @a error_cb
  1249. * @param proc Function to call on each credential
  1250. * @param proc_cls Closure for @a proc
  1251. * @param finish_cb Function to call on completion
  1252. * the handle is afterwards invalid
  1253. * @param finish_cb_cls Closure for @a finish_cb
  1254. * @return an iterator Handle to use for iteration
  1255. */
  1256. struct GNUNET_RECLAIM_CredentialIterator *
  1257. GNUNET_RECLAIM_get_credentials_start (
  1258. struct GNUNET_RECLAIM_Handle *h,
  1259. const struct GNUNET_IDENTITY_PrivateKey *identity,
  1260. GNUNET_SCHEDULER_TaskCallback error_cb,
  1261. void *error_cb_cls,
  1262. GNUNET_RECLAIM_CredentialResult proc,
  1263. void *proc_cls,
  1264. GNUNET_SCHEDULER_TaskCallback finish_cb,
  1265. void *finish_cb_cls)
  1266. {
  1267. struct GNUNET_RECLAIM_CredentialIterator *ait;
  1268. struct GNUNET_MQ_Envelope *env;
  1269. struct CredentialIterationStartMessage *msg;
  1270. uint32_t rid;
  1271. rid = h->r_id_gen++;
  1272. ait = GNUNET_new (struct GNUNET_RECLAIM_CredentialIterator);
  1273. ait->h = h;
  1274. ait->error_cb = error_cb;
  1275. ait->error_cb_cls = error_cb_cls;
  1276. ait->finish_cb = finish_cb;
  1277. ait->finish_cb_cls = finish_cb_cls;
  1278. ait->proc = proc;
  1279. ait->proc_cls = proc_cls;
  1280. ait->r_id = rid;
  1281. ait->identity = *identity;
  1282. GNUNET_CONTAINER_DLL_insert_tail (h->ait_head, h->ait_tail, ait);
  1283. env =
  1284. GNUNET_MQ_msg (msg,
  1285. GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_START);
  1286. msg->id = htonl (rid);
  1287. msg->identity = *identity;
  1288. if (NULL == h->mq)
  1289. ait->env = env;
  1290. else
  1291. GNUNET_MQ_send (h->mq, env);
  1292. return ait;
  1293. }
  1294. /**
  1295. * Calls the record processor specified in #GNUNET_RECLAIM_get_credential_start
  1296. * for the next record.
  1297. *
  1298. * @param it the iterator
  1299. */
  1300. void
  1301. GNUNET_RECLAIM_get_credentials_next (struct
  1302. GNUNET_RECLAIM_CredentialIterator *ait)
  1303. {
  1304. struct GNUNET_RECLAIM_Handle *h = ait->h;
  1305. struct CredentialIterationNextMessage *msg;
  1306. struct GNUNET_MQ_Envelope *env;
  1307. env =
  1308. GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_NEXT);
  1309. msg->id = htonl (ait->r_id);
  1310. GNUNET_MQ_send (h->mq, env);
  1311. }
  1312. /**
  1313. * Stops iteration and releases the handle for further calls. Must
  1314. * be called on any iteration that has not yet completed prior to calling
  1315. * #GNUNET_RECLAIM_disconnect.
  1316. *
  1317. * @param it the iterator
  1318. */
  1319. void
  1320. GNUNET_RECLAIM_get_credentials_stop (struct
  1321. GNUNET_RECLAIM_CredentialIterator *ait)
  1322. {
  1323. struct GNUNET_RECLAIM_Handle *h = ait->h;
  1324. struct GNUNET_MQ_Envelope *env;
  1325. struct CredentialIterationStopMessage *msg;
  1326. if (NULL != h->mq)
  1327. {
  1328. env =
  1329. GNUNET_MQ_msg (msg,
  1330. GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_STOP);
  1331. msg->id = htonl (ait->r_id);
  1332. GNUNET_MQ_send (h->mq, env);
  1333. }
  1334. free_ait (ait);
  1335. }
  1336. /**
  1337. * Issues a ticket to another relying party. The identity may use
  1338. * @GNUNET_RECLAIM_ticket_consume to consume the ticket
  1339. * and retrieve the attributes specified in the attribute list.
  1340. *
  1341. * @param h the reclaim to use
  1342. * @param iss the issuing identity (= the user)
  1343. * @param rp the subject of the ticket (= the relying party)
  1344. * @param attrs the attributes that the relying party is given access to
  1345. * @param cb the callback
  1346. * @param cb_cls the callback closure
  1347. * @return handle to abort the operation
  1348. */
  1349. struct GNUNET_RECLAIM_Operation *
  1350. GNUNET_RECLAIM_ticket_issue (
  1351. struct GNUNET_RECLAIM_Handle *h,
  1352. const struct GNUNET_IDENTITY_PrivateKey *iss,
  1353. const struct GNUNET_IDENTITY_PublicKey *rp,
  1354. const struct GNUNET_RECLAIM_AttributeList *attrs,
  1355. GNUNET_RECLAIM_IssueTicketCallback cb,
  1356. void *cb_cls)
  1357. {
  1358. struct GNUNET_RECLAIM_Operation *op;
  1359. struct IssueTicketMessage *tim;
  1360. size_t attr_len;
  1361. fprintf (stderr, "Issuing ticket\n");
  1362. op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
  1363. op->h = h;
  1364. op->ti_cb = cb;
  1365. op->cls = cb_cls;
  1366. op->r_id = h->r_id_gen++;
  1367. GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
  1368. attr_len = GNUNET_RECLAIM_attribute_list_serialize_get_size (attrs);
  1369. op->env = GNUNET_MQ_msg_extra (tim,
  1370. attr_len,
  1371. GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET);
  1372. tim->identity = *iss;
  1373. tim->rp = *rp;
  1374. tim->id = htonl (op->r_id);
  1375. GNUNET_RECLAIM_attribute_list_serialize (attrs, (char *) &tim[1]);
  1376. tim->attr_len = htons (attr_len);
  1377. if (NULL != h->mq)
  1378. GNUNET_MQ_send_copy (h->mq, op->env);
  1379. return op;
  1380. }
  1381. /**
  1382. * Consumes an issued ticket. The ticket is persisted
  1383. * and used to retrieve identity information from the issuer
  1384. *
  1385. * @param h the reclaim to use
  1386. * @param identity the identity that is the subject of the issued ticket (the
  1387. * relying party)
  1388. * @param ticket the issued ticket to consume
  1389. * @param cb the callback to call
  1390. * @param cb_cls the callback closure
  1391. * @return handle to abort the operation
  1392. */
  1393. struct GNUNET_RECLAIM_Operation *
  1394. GNUNET_RECLAIM_ticket_consume (
  1395. struct GNUNET_RECLAIM_Handle *h,
  1396. const struct GNUNET_IDENTITY_PrivateKey *identity,
  1397. const struct GNUNET_RECLAIM_Ticket *ticket,
  1398. GNUNET_RECLAIM_AttributeTicketResult cb,
  1399. void *cb_cls)
  1400. {
  1401. struct GNUNET_RECLAIM_Operation *op;
  1402. struct ConsumeTicketMessage *ctm;
  1403. op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
  1404. op->h = h;
  1405. op->atr_cb = cb;
  1406. op->cls = cb_cls;
  1407. op->r_id = h->r_id_gen++;
  1408. GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
  1409. op->env = GNUNET_MQ_msg (ctm, GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET);
  1410. ctm->identity = *identity;
  1411. ctm->id = htonl (op->r_id);
  1412. ctm->ticket = *ticket;
  1413. if (NULL != h->mq)
  1414. GNUNET_MQ_send_copy (h->mq, op->env);
  1415. else
  1416. reconnect (h);
  1417. return op;
  1418. }
  1419. /**
  1420. * Lists all tickets that have been issued to remote
  1421. * identites (relying parties)
  1422. *
  1423. * @param h the reclaim to use
  1424. * @param identity the issuing identity
  1425. * @param error_cb function to call on error (i.e. disconnect),
  1426. * the handle is afterwards invalid
  1427. * @param error_cb_cls closure for @a error_cb
  1428. * @param proc function to call on each ticket; it
  1429. * will be called repeatedly with a value (if available)
  1430. * @param proc_cls closure for @a proc
  1431. * @param finish_cb function to call on completion
  1432. * the handle is afterwards invalid
  1433. * @param finish_cb_cls closure for @a finish_cb
  1434. * @return an iterator handle to use for iteration
  1435. */
  1436. struct GNUNET_RECLAIM_TicketIterator *
  1437. GNUNET_RECLAIM_ticket_iteration_start (
  1438. struct GNUNET_RECLAIM_Handle *h,
  1439. const struct GNUNET_IDENTITY_PrivateKey *identity,
  1440. GNUNET_SCHEDULER_TaskCallback error_cb,
  1441. void *error_cb_cls,
  1442. GNUNET_RECLAIM_TicketCallback proc,
  1443. void *proc_cls,
  1444. GNUNET_SCHEDULER_TaskCallback finish_cb,
  1445. void *finish_cb_cls)
  1446. {
  1447. struct GNUNET_RECLAIM_TicketIterator *it;
  1448. struct GNUNET_MQ_Envelope *env;
  1449. struct TicketIterationStartMessage *msg;
  1450. uint32_t rid;
  1451. rid = h->r_id_gen++;
  1452. it = GNUNET_new (struct GNUNET_RECLAIM_TicketIterator);
  1453. it->h = h;
  1454. it->error_cb = error_cb;
  1455. it->error_cb_cls = error_cb_cls;
  1456. it->finish_cb = finish_cb;
  1457. it->finish_cb_cls = finish_cb_cls;
  1458. it->tr_cb = proc;
  1459. it->cls = proc_cls;
  1460. it->r_id = rid;
  1461. GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head, h->ticket_it_tail, it);
  1462. env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START);
  1463. msg->id = htonl (rid);
  1464. msg->identity = *identity;
  1465. if (NULL == h->mq)
  1466. it->env = env;
  1467. else
  1468. GNUNET_MQ_send (h->mq, env);
  1469. return it;
  1470. }
  1471. /**
  1472. * Calls the ticket processor specified in
  1473. * #GNUNET_RECLAIM_ticket_iteration_start for the next record.
  1474. *
  1475. * @param it the iterator
  1476. */
  1477. void
  1478. GNUNET_RECLAIM_ticket_iteration_next (struct GNUNET_RECLAIM_TicketIterator *it)
  1479. {
  1480. struct GNUNET_RECLAIM_Handle *h = it->h;
  1481. struct TicketIterationNextMessage *msg;
  1482. struct GNUNET_MQ_Envelope *env;
  1483. env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT);
  1484. msg->id = htonl (it->r_id);
  1485. GNUNET_MQ_send (h->mq, env);
  1486. }
  1487. /**
  1488. * Stops iteration and releases the handle for further calls. Must
  1489. * be called on any iteration that has not yet completed prior to calling
  1490. * #GNUNET_RECLAIM_disconnect.
  1491. *
  1492. * @param it the iterator
  1493. */
  1494. void
  1495. GNUNET_RECLAIM_ticket_iteration_stop (struct GNUNET_RECLAIM_TicketIterator *it)
  1496. {
  1497. struct GNUNET_RECLAIM_Handle *h = it->h;
  1498. struct GNUNET_MQ_Envelope *env;
  1499. struct TicketIterationStopMessage *msg;
  1500. if (NULL != h->mq)
  1501. {
  1502. env =
  1503. GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP);
  1504. msg->id = htonl (it->r_id);
  1505. GNUNET_MQ_send (h->mq, env);
  1506. }
  1507. GNUNET_free (it);
  1508. }
  1509. /**
  1510. * Revoked an issued ticket. The relying party will be unable to retrieve
  1511. * attributes. Other issued tickets remain unaffected.
  1512. * This includes tickets issued to other relying parties as well as to
  1513. * other tickets issued to the audience specified in this ticket.
  1514. *
  1515. * @param h the identity provider to use
  1516. * @param identity the issuing identity
  1517. * @param ticket the ticket to revoke
  1518. * @param cb the callback
  1519. * @param cb_cls the callback closure
  1520. * @return handle to abort the operation
  1521. */
  1522. struct GNUNET_RECLAIM_Operation *
  1523. GNUNET_RECLAIM_ticket_revoke (
  1524. struct GNUNET_RECLAIM_Handle *h,
  1525. const struct GNUNET_IDENTITY_PrivateKey *identity,
  1526. const struct GNUNET_RECLAIM_Ticket *ticket,
  1527. GNUNET_RECLAIM_ContinuationWithStatus cb,
  1528. void *cb_cls)
  1529. {
  1530. struct GNUNET_RECLAIM_Operation *op;
  1531. struct RevokeTicketMessage *msg;
  1532. uint32_t rid;
  1533. rid = h->r_id_gen++;
  1534. op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
  1535. op->h = h;
  1536. op->rvk_cb = cb;
  1537. op->cls = cb_cls;
  1538. op->r_id = rid;
  1539. GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
  1540. op->env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET);
  1541. msg->id = htonl (rid);
  1542. msg->identity = *identity;
  1543. msg->ticket = *ticket;
  1544. if (NULL != h->mq)
  1545. {
  1546. GNUNET_MQ_send (h->mq, op->env);
  1547. op->env = NULL;
  1548. }
  1549. return op;
  1550. }
  1551. /* end of reclaim_api.c */