summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-12-28 11:19:38 +0100
committerChristian Grothoff <christian@grothoff.org>2020-12-28 11:19:38 +0100
commitad2fda925733eb2db4388ea1c8ea09b15ee59a9b (patch)
tree2a0bd587d459bb45010ae9318f043b00fbc3d847
parente9d73b0a901d7dfe1fd219aecc960747e7c49483 (diff)
parent3ea7b6e726d80050bc3541e56fc6f9d1a5dbb72a (diff)
Merge branch 'master' of git+ssh://gnunet.org/gnunet
-rw-r--r--doc/handbook/chapters/user.texi66
-rw-r--r--src/reclaim/gnunet-service-reclaim.c411
-rw-r--r--src/reclaim/gnunet-service-reclaim_tickets.c1
-rw-r--r--src/reclaim/oidc_helper.c23
-rw-r--r--src/reclaim/plugin_reclaim_attribute_basic.c2
-rw-r--r--src/reclaim/plugin_reclaim_credential_jwt.c49
-rw-r--r--src/reclaim/plugin_rest_openid_connect.c40
-rw-r--r--src/reclaim/plugin_rest_reclaim.c2
-rw-r--r--src/reclaim/reclaim_attribute.c31
-rw-r--r--src/reclaim/reclaim_credential.c36
10 files changed, 486 insertions, 175 deletions
diff --git a/doc/handbook/chapters/user.texi b/doc/handbook/chapters/user.texi
index 4ae9aa951..ebc1a7979 100644
--- a/doc/handbook/chapters/user.texi
+++ b/doc/handbook/chapters/user.texi
@@ -2000,9 +2000,11 @@ integrate reclaimID as an Identity Provider with little effort.
@menu
* Managing Attributes::
+* Managing Credentials::
* Sharing Attributes with Third Parties::
* Revoking Authorizations of Third Parties::
* OpenID Connect::
+* Providing Third Party Attestation::
@end menu
@node Managing Attributes
@@ -2032,13 +2034,51 @@ $ gnunet-reclaim -e "user" -D
Currently, and by default, attribute values are interpreted as plain text.
In the future there might be more value types such as X.509 certificate credentials.
+@node Managing Credentials
+@subsection Managing Credentials
+
+Attribute values may reference a claim in a third party attested credential.
+Such a credential can have a variety of formats such as JSON-Web-Tokens or
+X.509 certificates.
+Currently, reclaimID only supports JSON-Web-Token credentials.
+
+To add a credential to your user profile, invoke the @command{gnunet-reclaim} command line tool as follows:
+
+@example
+$ gnunet-reclaim -e "user"\
+ --credential-name="email"\
+ --credential-type="JWT"\
+ --value="ey..."
+@end example
+
+All of your credentials can be listed using the @command{gnunet-reclaim}
+command line tool as well:
+
+@example
+$ gnunet-reclaim -e "user" --credentials
+@end example
+
+In order to add an attribe backed by a credential, specify the attribute
+value as the claim name in the credential to reference along with the credential
+ID:
+
+@example
+$ gnunet-reclaim -e "user"\
+ --add="email"\
+ --value="verified_email"\
+ --credential-id="<CREDENTIAL_ID>"
+@end example
+
+
@node Sharing Attributes with Third Parties
@subsection Sharing Attributes with Third Parties
If you want to allow a third party such as a website or friend to access to your attributes (or a subset thereof) execute:
@example
-$ TICKET=$(gnunet-reclaim -e "user" -r "$RP_KEY" -i "attribute1,attribute2,...")
+$ TICKET=$(gnunet-reclaim -e "user"\
+ -r "$RP_KEY"\
+ -i "attribute1,attribute2,...")
@end example
The command will return a "ticket" string.
@@ -2173,6 +2213,30 @@ The authorization code flow optionally supports @uref{https://tools.ietf.org/htm
If PKCE is used, the client does not need to authenticate against the token
endpoint.
+@node Providing Third Party Attestation
+@subsection Providing Third Party Attestation
+
+If you are running an identity provider (IdP) service you may be able to
+support providing credentials for re:claimID users.
+IdPs can issue JWT credentials as long as they support OpenID Connect and
+@uref{https://openid.net/specs/openid-connect-discovery-1_0.html,OpenID Connect Discovery}.
+
+In order to allow users to import attributes through the re:claimID user interface,
+you need to register the following public OAuth2/OIDC client:
+
+@itemize @bullet
+@item client_id: reclaimid
+@item client_secret: none
+@item redirect_uri: https://ui.reclaim (The URI of the re:claimID webextension)
+@item grant_type: authorization_code with PKCE (@uref{https://tools.ietf.org/html/rfc7636, RFC7636})
+@item scopes: all you want to offer.
+@item id_token: JWT
+@end itemize
+
+When your users add an attribute with name "email" which supports webfinger
+discovery they will be prompted with the option to retrieve the OpenID Connect
+ID Token through the user interface.
+
@node Using the Virtual Public Network
@section Using the Virtual Public Network
diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c
index 5614f05db..913b667b7 100644
--- a/src/reclaim/gnunet-service-reclaim.c
+++ b/src/reclaim/gnunet-service-reclaim.c
@@ -300,6 +300,16 @@ struct AttributeDeleteHandle
struct TicketRecordsEntry *tickets_to_update_tail;
/**
+ * Existing attributes
+ */
+ struct GNUNET_RECLAIM_AttributeList *existing_attributes;
+
+ /**
+ * Existing credentials
+ */
+ struct GNUNET_RECLAIM_CredentialList *existing_credentials;
+
+ /**
* Attribute label
*/
char *label;
@@ -490,6 +500,10 @@ cleanup_adh (struct AttributeDeleteHandle *adh)
GNUNET_free (adh->claim);
if (NULL != adh->credential)
GNUNET_free (adh->credential);
+ if (NULL != adh->existing_credentials)
+ GNUNET_RECLAIM_credential_list_destroy (adh->existing_credentials);
+ if (NULL != adh->existing_attributes)
+ GNUNET_RECLAIM_attribute_list_destroy (adh->existing_attributes);
while (NULL != (le = adh->tickets_to_update_head))
{
GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
@@ -1301,7 +1315,7 @@ send_delete_response (struct AttributeDeleteHandle *adh, int32_t success)
* @param rd record data
*/
static void
-ticket_iter (void *cls,
+consistency_iter (void *cls,
const struct GNUNET_IDENTITY_PrivateKey *zone,
const char *label,
unsigned int rd_count,
@@ -1309,26 +1323,42 @@ ticket_iter (void *cls,
{
struct AttributeDeleteHandle *adh = cls;
struct TicketRecordsEntry *le;
- int has_changed = GNUNET_NO;
+ struct GNUNET_RECLAIM_AttributeListEntry *ale;
+ struct GNUNET_RECLAIM_CredentialListEntry *cle;
+ int is_ticket = GNUNET_NO;
for (int i = 0; i < rd_count; i++)
{
- if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF != rd[i].record_type)
- continue;
- if (adh->claim != NULL)
- if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (rd[i].data,
- &adh->claim->id))
- continue;
- if (adh->credential != NULL)
- if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (rd[i].data,
- &adh->credential->id))
- continue;
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Attribute to delete found (%s)\n",
- adh->label);
- has_changed = GNUNET_YES;
- break;
+ switch (rd[i].record_type) {
+ case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE:
+ ale = GNUNET_new (struct GNUNET_RECLAIM_AttributeListEntry);
+ GNUNET_RECLAIM_attribute_deserialize (rd[i].data,
+ rd[i].data_size,
+ &ale->attribute);
+ GNUNET_CONTAINER_DLL_insert (adh->existing_attributes->list_head,
+ adh->existing_attributes->list_tail,
+ ale);
+ break;
+ case GNUNET_GNSRECORD_TYPE_RECLAIM_CREDENTIAL:
+ cle = GNUNET_new (struct GNUNET_RECLAIM_CredentialListEntry);
+ cle->credential = GNUNET_RECLAIM_credential_deserialize (rd[i].data,
+ rd[i].data_size);
+ GNUNET_CONTAINER_DLL_insert (adh->existing_credentials->list_head,
+ adh->existing_credentials->list_tail,
+ cle);
+ break;
+ case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET:
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Ticket to delete found (%s)\n",
+ label);
+ is_ticket = GNUNET_YES;
+ break;
+ default:
+ break;
+ }
+ if (GNUNET_YES == is_ticket)
+ break;
}
- if (GNUNET_YES == has_changed)
+ if (GNUNET_YES == is_ticket)
{
le = GNUNET_new (struct TicketRecordsEntry);
le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
@@ -1384,15 +1414,12 @@ update_tickets (void *cls)
if (NULL == adh->tickets_to_update_head)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Finished updating tickets, success\n");
send_delete_response (adh, GNUNET_OK);
cleanup_adh (adh);
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Updating %s\n",
- adh->tickets_to_update_head->label);
le = adh->tickets_to_update_head;
GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
adh->tickets_to_update_tail,
@@ -1411,21 +1438,53 @@ update_tickets (void *cls)
return;
}
int j = 0;
- for (int i = 0; i < le->rd_count; i++)
+ int i = 0;
+ struct GNUNET_RECLAIM_AttributeListEntry *ale;
+ struct GNUNET_RECLAIM_CredentialListEntry *cle;
+ struct GNUNET_RECLAIM_Presentation *presentation;
+ for (i = 0; i < le->rd_count; i++)
{
- if (adh->claim != NULL)
- if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF == rd[i].record_type)
- && (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data,
- &adh->claim->id)))
- continue;
- if (adh->credential != NULL)
- if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF == rd[i].record_type)
- && (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data,
- &adh->credential->id)))
- continue;
- rd_new[j] = rd[i];
- j++;
+ switch (rd[i].record_type) {
+ case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF:
+ for (ale = adh->existing_attributes->list_head; NULL != ale; ale = ale->next) {
+ if (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data,
+ &ale->attribute->id)) {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Found attribute %s, readding...\n",
+ ale->attribute->name);
+ rd_new[j] = rd[i];
+ j++;
+ break; //Found and added
+ }
+ }
+ break;
+ case GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION:
+ presentation = GNUNET_RECLAIM_presentation_deserialize (rd[i].data,
+ rd[i].data_size);
+ for (cle = adh->existing_credentials->list_head; NULL != cle; cle = cle->next) {
+ if (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (&presentation->credential_id,
+ &cle->credential->id)) {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Found presentation for credential %s, readding...\n",
+ cle->credential->name);
+ rd_new[j] = rd[i];
+ j++;
+ break; //Found and added
+ }
+ }
+ GNUNET_free (presentation);
+ break;
+ case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET:
+ rd_new[j] = rd[i];
+ j++;
+ break; //Found and added
+ default:
+ GNUNET_break (0);
+ }
}
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Updating ticket with %d entries (%d before)...\n",
+ j, i);
adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
&adh->identity,
le->label,
@@ -1438,6 +1497,90 @@ update_tickets (void *cls)
GNUNET_free (le);
}
+/**
+ * Delete all attributes which reference credentials
+ * that no longer exist
+ */
+static void
+purge_attributes (void *cls);;
+
+static void
+offending_attr_delete_cont (void *cls, int32_t success, const char *emsg)
+{
+ struct AttributeDeleteHandle *adh = cls;
+
+ adh->ns_qe = NULL;
+ if (GNUNET_SYSERR == success)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Error deleting attribute %s\n",
+ adh->label);
+ send_delete_response (adh, GNUNET_SYSERR);
+ cleanup_adh (adh);
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Continuing consistency check...\n");
+ GNUNET_SCHEDULER_add_now (&purge_attributes, adh);
+}
+
+
+
+/**
+ * Delete all attributes which reference credentials
+ * that no longer exist
+ */
+static void
+purge_attributes (void *cls)
+{
+ struct AttributeDeleteHandle *adh = cls;
+ struct GNUNET_RECLAIM_AttributeListEntry *ale;
+ struct GNUNET_RECLAIM_CredentialListEntry *cle;
+
+ for (ale = adh->existing_attributes->list_head; NULL != ale; ale = ale->next)
+ {
+ if (GNUNET_YES ==
+ GNUNET_RECLAIM_id_is_zero (&ale->attribute->credential))
+ continue;
+
+ for (cle = adh->existing_credentials->list_head;
+ NULL != cle; cle = cle->next) {
+ if (GNUNET_YES !=
+ GNUNET_RECLAIM_id_is_equal (&cle->credential->id,
+ &ale->attribute->credential))
+ continue;
+ break;
+ }
+ if (NULL == cle) {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Found attribute with missing credential\n");
+ break;
+ }
+ }
+ if (NULL == ale) {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Attributes consistent, updating tickets.\n");
+ GNUNET_SCHEDULER_add_now (&update_tickets, adh);
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Attributes inconsistent, deleting offending attribute.\n");
+ char *label
+ = GNUNET_STRINGS_data_to_string_alloc (&ale->attribute->id,
+ sizeof(ale->attribute->id));
+
+ adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+ &adh->identity,
+ label,
+ 0,
+ NULL,
+ &offending_attr_delete_cont,
+ adh);
+ GNUNET_CONTAINER_DLL_remove (adh->existing_attributes->list_head,
+ adh->existing_attributes->list_tail,
+ ale);
+ GNUNET_free (ale);
+ GNUNET_free (label);
+}
/**
* Done collecting affected tickets, start updating.
@@ -1445,11 +1588,11 @@ update_tickets (void *cls)
* @param cls our attribute deletion handle
*/
static void
-ticket_iter_fin (void *cls)
+consistency_iter_fin (void *cls)
{
struct AttributeDeleteHandle *adh = cls;
adh->ns_it = NULL;
- GNUNET_SCHEDULER_add_now (&update_tickets, adh);
+ GNUNET_SCHEDULER_add_now (&purge_attributes, adh);
}
@@ -1459,14 +1602,13 @@ ticket_iter_fin (void *cls)
* @param cls our attribute deletion handle
*/
static void
-ticket_iter_err (void *cls)
+consistency_iter_err (void *cls)
{
struct AttributeDeleteHandle *adh = cls;
adh->ns_it = NULL;
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Namestore error on delete %s\n",
- adh->label);
+ "Namestore error on consistency check\n");
send_delete_response (adh, GNUNET_SYSERR);
cleanup_adh (adh);
}
@@ -1479,17 +1621,20 @@ ticket_iter_err (void *cls)
* @param cls attribute deletion handle
*/
static void
-start_ticket_update (void *cls)
+start_consistency_update (void *cls)
{
struct AttributeDeleteHandle *adh = cls;
+ adh->existing_attributes = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
+ adh->existing_credentials = GNUNET_new (struct GNUNET_RECLAIM_CredentialList);
+
adh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
&adh->identity,
- &ticket_iter_err,
+ &consistency_iter_err,
adh,
- &ticket_iter,
+ &consistency_iter,
adh,
- &ticket_iter_fin,
+ &consistency_iter_fin,
adh);
}
@@ -1517,7 +1662,7 @@ attr_delete_cont (void *cls, int32_t success, const char *emsg)
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
- GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
+ GNUNET_SCHEDULER_add_now (&start_consistency_update, adh);
}
@@ -1586,12 +1731,12 @@ handle_attribute_delete_message (void *cls,
/**
- * Credential deleted callback
- *
- * @param cls our handle
- * @param success success status
- * @param emsg error message (NULL if success=GNUNET_OK)
- */
+ * Credential deleted callback
+ *
+ * @param cls our handle
+ * @param success success status
+ * @param emsg error message (NULL if success=GNUNET_OK)
+ */
static void
cred_delete_cont (void *cls, int32_t success, const char *emsg)
{
@@ -1608,7 +1753,7 @@ cred_delete_cont (void *cls, int32_t success, const char *emsg)
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
- GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
+ GNUNET_SCHEDULER_add_now (&start_consistency_update, adh);
}
@@ -1642,7 +1787,7 @@ check_credential_delete_message (void *cls,
*/
static void
handle_credential_delete_message (void *cls,
- const struct AttributeDeleteMessage *dam)
+ const struct AttributeDeleteMessage *dam)
{
struct AttributeDeleteHandle *adh;
struct IdpClient *idp = cls;
@@ -1676,8 +1821,8 @@ handle_credential_delete_message (void *cls,
/*************************************************
-* Attrubute iteration
-*************************************************/
+ * Attrubute iteration
+ *************************************************/
/**
@@ -1860,8 +2005,8 @@ handle_iteration_next (void *cls,
/*************************************************
-* Credential iteration
-*************************************************/
+ * Credential iteration
+ *************************************************/
/**
@@ -2050,8 +2195,8 @@ handle_credential_iteration_next (void *cls,
/******************************************************
-* Ticket iteration
-******************************************************/
+ * Ticket iteration
+ ******************************************************/
/**
* Got a ticket. Return to client
@@ -2094,8 +2239,8 @@ ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket)
*/
static void
handle_ticket_iteration_start (
- void *cls,
- const struct TicketIterationStartMessage *tis_msg)
+ void *cls,
+ const struct TicketIterationStartMessage *tis_msg)
{
struct IdpClient *client = cls;
struct TicketIteration *ti;
@@ -2267,76 +2412,76 @@ client_connect_cb (void *cls,
* Define "main" method using service macro.
*/
GNUNET_SERVICE_MAIN (
- "reclaim",
- GNUNET_SERVICE_OPTION_NONE,
- &run,
- &client_connect_cb,
- &client_disconnect_cb,
- NULL,
- GNUNET_MQ_hd_var_size (attribute_store_message,
- GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
- struct AttributeStoreMessage,
- NULL),
- GNUNET_MQ_hd_var_size (credential_store_message,
- GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_STORE,
- struct AttributeStoreMessage,
- NULL),
- GNUNET_MQ_hd_var_size (attribute_delete_message,
- GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
- struct AttributeDeleteMessage,
- NULL),
- GNUNET_MQ_hd_var_size (credential_delete_message,
- GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_DELETE,
- struct AttributeDeleteMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (iteration_start,
- GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
- struct AttributeIterationStartMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (iteration_next,
- GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
- struct AttributeIterationNextMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (iteration_stop,
- GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
- struct AttributeIterationStopMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (credential_iteration_start,
- GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_START,
- struct CredentialIterationStartMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (credential_iteration_next,
- GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_NEXT,
- struct CredentialIterationNextMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (credential_iteration_stop,
- GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_STOP,
- struct CredentialIterationStopMessage,
- NULL),
-
- GNUNET_MQ_hd_var_size (issue_ticket_message,
- GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
- struct IssueTicketMessage,
- NULL),
- GNUNET_MQ_hd_var_size (consume_ticket_message,
- GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
- struct ConsumeTicketMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
- GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
- struct TicketIterationStartMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
- GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
- struct TicketIterationNextMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
- GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
- struct TicketIterationStopMessage,
- NULL),
- GNUNET_MQ_hd_var_size (revoke_ticket_message,
- GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
- struct RevokeTicketMessage,
- NULL),
- GNUNET_MQ_handler_end ());
+ "reclaim",
+ GNUNET_SERVICE_OPTION_NONE,
+ &run,
+ &client_connect_cb,
+ &client_disconnect_cb,
+ NULL,
+ GNUNET_MQ_hd_var_size (attribute_store_message,
+ GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
+ struct AttributeStoreMessage,
+ NULL),
+ GNUNET_MQ_hd_var_size (credential_store_message,
+ GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_STORE,
+ struct AttributeStoreMessage,
+ NULL),
+ GNUNET_MQ_hd_var_size (attribute_delete_message,
+ GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
+ struct AttributeDeleteMessage,
+ NULL),
+ GNUNET_MQ_hd_var_size (credential_delete_message,
+ GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_DELETE,
+ struct AttributeDeleteMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (iteration_start,
+ GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
+ struct AttributeIterationStartMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (iteration_next,
+ GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
+ struct AttributeIterationNextMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (iteration_stop,
+ GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
+ struct AttributeIterationStopMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (credential_iteration_start,
+ GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_START,
+ struct CredentialIterationStartMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (credential_iteration_next,
+ GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_NEXT,
+ struct CredentialIterationNextMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (credential_iteration_stop,
+ GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_STOP,
+ struct CredentialIterationStopMessage,
+ NULL),
+
+ GNUNET_MQ_hd_var_size (issue_ticket_message,
+ GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
+ struct IssueTicketMessage,
+ NULL),
+ GNUNET_MQ_hd_var_size (consume_ticket_message,
+ GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
+ struct ConsumeTicketMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
+ GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
+ struct TicketIterationStartMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
+ GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
+ struct TicketIterationNextMessage,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
+ GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
+ struct TicketIterationStopMessage,
+ NULL),
+ GNUNET_MQ_hd_var_size (revoke_ticket_message,
+ GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
+ struct RevokeTicketMessage,
+ NULL),
+ GNUNET_MQ_handler_end ());
/* end of gnunet-service-reclaim.c */
diff --git a/src/reclaim/gnunet-service-reclaim_tickets.c b/src/reclaim/gnunet-service-reclaim_tickets.c
index 0b1730bec..ef2303bd7 100644
--- a/src/reclaim/gnunet-service-reclaim_tickets.c
+++ b/src/reclaim/gnunet-service-reclaim_tickets.c
@@ -1542,6 +1542,7 @@ filter_tickets_cb (void *cls,
tih->presentations->list_tail,
ple);
GNUNET_free (cred);
+ break;
}
}
if (GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION == rd[i].record_type)
diff --git a/src/reclaim/oidc_helper.c b/src/reclaim/oidc_helper.c
index a90d02d68..84a90833c 100644
--- a/src/reclaim/oidc_helper.c
+++ b/src/reclaim/oidc_helper.c
@@ -193,6 +193,7 @@ generate_userinfo_json (const struct GNUNET_IDENTITY_PublicKey *sub_key,
json_object_set_new (body, "iss", json_string (SERVER_ADDRESS));
// sub REQUIRED public key identity, not exceed 255 ASCII length
json_object_set_new (body, "sub", json_string (subject));
+ GNUNET_free (subject);
pres_val_str = NULL;
source_name = NULL;
int i = 0;
@@ -202,11 +203,15 @@ generate_userinfo_json (const struct GNUNET_IDENTITY_PublicKey *sub_key,
GNUNET_asprintf (&source_name,
"src%d",
i);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding new presentation source #%d\n", i);
aggr_sources_jwt = json_object ();
pres_val_str =
GNUNET_RECLAIM_presentation_value_to_string (ple->presentation->type,
ple->presentation->data,
ple->presentation->data_size);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Presentation is: %s\n", pres_val_str);
json_object_set_new (aggr_sources_jwt,
GNUNET_RECLAIM_presentation_number_to_typename (
ple->presentation->type),
@@ -220,7 +225,9 @@ generate_userinfo_json (const struct GNUNET_IDENTITY_PublicKey *sub_key,
for (le = attrs->list_head; NULL != le; le = le->next)
{
-
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Processing %s for userinfo body\n",
+ le->attribute->name);
if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&le->attribute->credential))
{
@@ -256,18 +263,6 @@ generate_userinfo_json (const struct GNUNET_IDENTITY_PublicKey *sub_key,
int j = 0;
for (ple = presentations->list_head; NULL != ple; ple = ple->next)
{
- char *tmp;
- tmp = GNUNET_STRINGS_data_to_string_alloc (&le->attribute->credential,
- sizeof (le->attribute->credential));
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Checking : %s\n", tmp);
- GNUNET_free (tmp);
-
- tmp = GNUNET_STRINGS_data_to_string_alloc (&ple->presentation->credential_id,
- sizeof (ple->presentation->credential_id));
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- " against: %s\n", tmp);
- GNUNET_free (tmp);
if (GNUNET_YES ==
GNUNET_RECLAIM_id_is_equal (&ple->presentation->credential_id,
&le->attribute->credential))
@@ -285,7 +280,7 @@ generate_userinfo_json (const struct GNUNET_IDENTITY_PublicKey *sub_key,
GNUNET_asprintf (&source_name,
"src%d",
j);
- json_object_set_new (aggr_names, le->attribute->data,
+ json_object_set_new (aggr_names, le->attribute->name,
json_string (source_name));
GNUNET_free (source_name);
}
diff --git a/src/reclaim/plugin_reclaim_attribute_basic.c b/src/reclaim/plugin_reclaim_attribute_basic.c
index 286186a93..c87922886 100644
--- a/src/reclaim/plugin_reclaim_attribute_basic.c
+++ b/src/reclaim/plugin_reclaim_attribute_basic.c
@@ -82,7 +82,7 @@ basic_string_to_value (void *cls,
{
case GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING:
*data = GNUNET_strdup (s);
- *data_size = strlen (s);
+ *data_size = strlen (s) + 1;
return GNUNET_OK;
default:
diff --git a/src/reclaim/plugin_reclaim_credential_jwt.c b/src/reclaim/plugin_reclaim_credential_jwt.c
index 6f52f3a4e..c1e12f4a0 100644
--- a/src/reclaim/plugin_reclaim_credential_jwt.c
+++ b/src/reclaim/plugin_reclaim_credential_jwt.c
@@ -81,7 +81,7 @@ jwt_string_to_value (void *cls,
{
case GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT:
*data = GNUNET_strdup (s);
- *data_size = strlen (s);
+ *data_size = strlen (s) + 1;
return GNUNET_OK;
default:
@@ -151,7 +151,8 @@ jwt_number_to_typename (void *cls, uint32_t type)
*/
struct GNUNET_RECLAIM_AttributeList *
jwt_parse_attributes (void *cls,
- const char *data)
+ const char *data,
+ size_t data_size)
{
char *jwt_string;
struct GNUNET_RECLAIM_AttributeList *attrs;
@@ -164,7 +165,7 @@ jwt_parse_attributes (void *cls,
attrs = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
- jwt_string = GNUNET_strdup (data);
+ jwt_string = GNUNET_strndup (data, data_size);
const char *jwt_body = strtok (jwt_string, delim);
jwt_body = strtok (NULL, delim);
GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body),
@@ -172,6 +173,7 @@ jwt_parse_attributes (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decoded JWT: %s\n", decoded_jwt);
GNUNET_assert (NULL != decoded_jwt);
json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
+ GNUNET_free (decoded_jwt);
const char *key;
json_t *value;
json_object_foreach (json_val, key, value) {
@@ -196,6 +198,7 @@ jwt_parse_attributes (void *cls,
strlen (val_str));
GNUNET_free (val_str);
}
+ json_decref (json_val);
GNUNET_free (jwt_string);
return attrs;
}
@@ -212,7 +215,7 @@ struct GNUNET_RECLAIM_AttributeList *
jwt_parse_attributes_c (void *cls,
const struct GNUNET_RECLAIM_Credential *cred)
{
- return jwt_parse_attributes (cls, cred->data);
+ return jwt_parse_attributes (cls, cred->data, cred->data_size);
}
@@ -227,7 +230,7 @@ struct GNUNET_RECLAIM_AttributeList *
jwt_parse_attributes_p (void *cls,
const struct GNUNET_RECLAIM_Presentation *cred)
{
- return jwt_parse_attributes (cls, cred->data);
+ return jwt_parse_attributes (cls, cred->data, cred->data_size);
}
@@ -240,7 +243,8 @@ jwt_parse_attributes_p (void *cls,
*/
char *
jwt_get_issuer (void *cls,
- const char *data)
+ const char *data,
+ size_t data_size)
{
const char *jwt_body;
char *jwt_string;
@@ -252,17 +256,23 @@ jwt_get_issuer (void *cls,
json_t *json_val;
json_error_t *json_err = NULL;
- jwt_string = GNUNET_strdup (data);
+ jwt_string = GNUNET_strndup (data, data_size);
jwt_body = strtok (jwt_string, delim);
jwt_body = strtok (NULL, delim);
GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body),
(void **) &decoded_jwt);
json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
+ GNUNET_free (decoded_jwt);
+ GNUNET_free (jwt_string);
+ if (NULL == json_val)
+ return NULL;
issuer_json = json_object_get (json_val, "iss");
- if ((NULL == issuer_json) || (! json_is_string (issuer_json)))
+ if ((NULL == issuer_json) || (! json_is_string (issuer_json))) {
+ json_decref (json_val);
return NULL;
+ }
issuer = GNUNET_strdup (json_string_value (issuer_json));
- GNUNET_free (jwt_string);
+ json_decref (json_val);
return issuer;
}
@@ -280,7 +290,7 @@ jwt_get_issuer_c (void *cls,
{
if (GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT != cred->type)
return NULL;
- return jwt_get_issuer (cls, cred->data);
+ return jwt_get_issuer (cls, cred->data, cred->data_size);
}
@@ -297,7 +307,7 @@ jwt_get_issuer_p (void *cls,
{
if (GNUNET_RECLAIM_CREDENTIAL_TYPE_JWT != cred->type)
return NULL;
- return jwt_get_issuer (cls, cred->data);
+ return jwt_get_issuer (cls, cred->data, cred->data_size);
}
@@ -311,6 +321,7 @@ jwt_get_issuer_p (void *cls,
int
jwt_get_expiration (void *cls,
const char *data,
+ size_t data_size,
struct GNUNET_TIME_Absolute *exp)
{
const char *jwt_body;
@@ -322,17 +333,23 @@ jwt_get_expiration (void *cls,
json_t *json_val;
json_error_t *json_err = NULL;
- jwt_string = GNUNET_strdup (data);
+ jwt_string = GNUNET_strndup (data, data_size);
jwt_body = strtok (jwt_string, delim);
jwt_body = strtok (NULL, delim);
GNUNET_STRINGS_base64url_decode (jwt_body, strlen (jwt_body),
(void **) &decoded_jwt);
json_val = json_loads (decoded_jwt, JSON_DECODE_ANY, json_err);
+ GNUNET_free (decoded_jwt);
+ GNUNET_free (jwt_string);
+ if (NULL == json_val)
+ return GNUNET_SYSERR;
exp_json = json_object_get (json_val, "exp");
- if ((NULL == exp_json) || (! json_is_integer (exp_json)))
+ if ((NULL == exp_json) || (! json_is_integer (exp_json))) {
+ json_decref (json_val);
return GNUNET_SYSERR;
+ }
exp->abs_value_us = json_integer_value (exp_json) * 1000 * 1000;
- GNUNET_free (jwt_string);
+ json_decref (json_val);
return GNUNET_OK;
}
@@ -349,7 +366,7 @@ jwt_get_expiration_c (void *cls,
const struct GNUNET_RECLAIM_Credential *cred,
struct GNUNET_TIME_Absolute *exp)
{
- return jwt_get_expiration (cls, cred->data, exp);
+ return jwt_get_expiration (cls, cred->data, cred->data_size, exp);
}
@@ -365,7 +382,7 @@ jwt_get_expiration_p (void *cls,
const struct GNUNET_RECLAIM_Presentation *cred,
struct GNUNET_TIME_Absolute *exp)
{
- return jwt_get_expiration (cls, cred->data, exp);
+ return jwt_get_expiration (cls, cred->data, cred->data_size, exp);
}
diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c
index 5eb1ff093..0ee61755b 100644
--- a/src/reclaim/plugin_rest_openid_connect.c
+++ b/src/reclaim/plugin_rest_openid_connect.c
@@ -610,6 +610,10 @@ cleanup_handle (struct RequestHandle *handle)
GNUNET_free (handle->oidc->response_type);
GNUNET_free (handle->oidc->scope);
GNUNET_free (handle->oidc->state);
+ if (NULL != handle->oidc->claims)
+ GNUNET_free (handle->oidc->claims);
+ if (NULL != handle->oidc->code_challenge)
+ GNUNET_free (handle->oidc->code_challenge);
GNUNET_free (handle->oidc);
}
if (NULL!=handle->attr_idtoken_list)
@@ -1193,8 +1197,7 @@ attr_in_claims_request (struct RequestHandle *handle,
return GNUNET_YES;
/** Try claims parameter if not in scope */
- if ((NULL != handle->oidc->claims) &&
- (GNUNET_YES != ret))
+ if (NULL != handle->oidc->claims)
{
root = json_loads (handle->oidc->claims, JSON_DECODE_ANY, &error);
claims_j = json_object_get (root, claims_parameter);
@@ -1708,8 +1711,6 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
handle->ego_entry = ego_tail;
}
}
- handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scope: %s\n", handle->oidc->scope);
if (NULL == handle->tld)
GNUNET_CONFIGURATION_iterate_section_values (cfg, "gns", tld_iter, handle);
if (NULL == handle->tld)
@@ -1872,11 +1873,18 @@ parse_credentials_post_body (struct RequestHandle *handle,
if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle
->url_param_map,
&cache_key))
+ {
+ GNUNET_free (*client_id);
+ *client_id = NULL;
return GNUNET_SYSERR;
+ }
pass = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map,
&cache_key);
- if (NULL == pass)
+ if (NULL == pass) {
+ GNUNET_free (*client_id);
+ *client_id = NULL;
return GNUNET_SYSERR;
+ }
*client_secret = strdup (pass);
return GNUNET_OK;
}
@@ -1938,12 +1946,16 @@ check_authorization (struct RequestHandle *handle,
GNUNET_free (expected_pass);
handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT);
handle->response_code = MHD_HTTP_UNAUTHORIZED;
+ GNUNET_free (received_cpw);
+ GNUNET_free (received_cid);
return GNUNET_SYSERR;
}
GNUNET_free (expected_pass);
}
else
{
+ GNUNET_free (received_cpw);
+ GNUNET_free (received_cid);
handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR);
handle->edesc = GNUNET_strdup ("gnunet configuration failed");
handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
@@ -2102,9 +2114,13 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
handle->edesc = GNUNET_strdup ("invalid code");
handle->response_code = MHD_HTTP_BAD_REQUEST;
GNUNET_free (code);
+ if (NULL != code_verifier)
+ GNUNET_free (code_verifier);
GNUNET_SCHEDULER_add_now (&do_error, handle);
return;
}
+ if (NULL != code_verifier)
+ GNUNET_free (code_verifier);
// create jwt
if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg,
@@ -2116,6 +2132,8 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
handle->edesc = GNUNET_strdup ("gnunet configuration failed");
handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
GNUNET_free (code);
+ if (NULL != nonce)
+ GNUNET_free (nonce);
GNUNET_SCHEDULER_add_now (&do_error, handle);
return;
}
@@ -2131,6 +2149,8 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
handle->edesc = GNUNET_strdup ("No signing secret configured!");
handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
GNUNET_free (code);
+ if (NULL != nonce)
+ GNUNET_free (nonce);
GNUNET_SCHEDULER_add_now (&do_error, handle);
return;
}
@@ -2141,6 +2161,9 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
&expiration_time,
(NULL != nonce) ? nonce : NULL,
jwt_secret);
+ GNUNET_free (jwt_secret);
+ if (NULL != nonce)
+ GNUNET_free (nonce);
access_token = OIDC_access_token_new (&ticket);
/* Store mapping from access token to code so we can later
* fall back on the provided attributes in userinfo
@@ -2293,6 +2316,8 @@ consume_timeout (void*cls)
handle->edesc = GNUNET_strdup ("invalid code");
handle->response_code = MHD_HTTP_BAD_REQUEST;
GNUNET_free (cached_code);
+ if (NULL != nonce)
+ GNUNET_free (nonce);
GNUNET_SCHEDULER_add_now (&do_error, handle);
return;
}
@@ -2337,7 +2362,7 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
const struct EgoEntry *aud_ego;
const struct GNUNET_IDENTITY_PrivateKey *privkey;
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Getting userinfo\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting userinfo\n");
GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY,
strlen (OIDC_AUTHORIZATION_HEADER_KEY),
&cache_key);
@@ -2403,7 +2428,7 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
GNUNET_free (authorization);
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Consuming ticket\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Consuming ticket\n");
privkey = GNUNET_IDENTITY_ego_get_private_key (aud_ego->ego);
handle->attr_userinfo_list =
GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
@@ -2617,6 +2642,7 @@ oidc_config_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
oidc_config_str = json_dumps (oidc_config, JSON_INDENT (1));
resp = GNUNET_REST_create_response (oidc_config_str);
handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
+ json_decref (oidc_config);
GNUNET_free (oidc_config_str);
cleanup_handle (handle);
}
diff --git a/src/reclaim/plugin_rest_reclaim.c b/src/reclaim/plugin_rest_reclaim.c
index 022744c82..84456b386 100644
--- a/src/reclaim/plugin_rest_reclaim.c
+++ b/src/reclaim/plugin_rest_reclaim.c
@@ -974,9 +974,11 @@ attr_collect (void *cls,
id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->id,
sizeof(attr->id));
json_object_set_new (attr_obj, "id", json_string (id_str));
+ GNUNET_free (id_str);
id_str = GNUNET_STRINGS_data_to_string_alloc (&attr->credential,
sizeof(attr->credential));
json_object_set_new (attr_obj, "credential", json_string (id_str));
+ GNUNET_free (id_str);
json_array_append (handle->resp_object, attr_obj);
json_decref (attr_obj);
GNUNET_free (tmp_value);
diff --git a/src/reclaim/reclaim_attribute.c b/src/reclaim/reclaim_attribute.c
index 2217987ac..14690d7c9 100644
--- a/src/reclaim/reclaim_attribute.c
+++ b/src/reclaim/reclaim_attribute.c
@@ -102,6 +102,37 @@ init ()
NULL);
}
+/**
+ * Dual function to #init().
+ */
+void __attribute__ ((destructor))
+RECLAIM_ATTRIBUTE_fini ()
+{
+ struct Plugin *plugin;
+ const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
+ const struct GNUNET_OS_ProjectData *dpd = GNUNET_OS_project_data_default ();
+
+ if (pd != dpd)
+ GNUNET_OS_init (dpd);
+
+ for (unsigned int i = 0; i < num_plugins; i++)
+ {
+ plugin = attr_plugins[i];
+ GNUNET_break (NULL ==
+ GNUNET_PLUGIN_unload (plugin->library_name,
+ plugin->api));
+ GNUNET_free (plugin->library_name);
+ GNUNET_free (plugin);
+ }
+ GNUNET_free (attr_plugins);
+
+ if (pd != dpd)
+ GNUNET_OS_init (pd);
+
+ attr_plugins = NULL;
+}
+
+
/**
* Convert a type name to the corresponding number
diff --git a/src/reclaim/reclaim_credential.c b/src/reclaim/reclaim_credential.c
index 5c8974400..05601c3d3 100644
--- a/src/reclaim/reclaim_credential.c
+++ b/src/reclaim/reclaim_credential.c
@@ -104,6 +104,38 @@ init ()
/**
+ * Dual function to #init().
+ */
+void __attribute__ ((destructor))
+RECLAIM_CREDENTIAL_fini ()
+{
+ struct Plugin *plugin;
+ const struct GNUNET_OS_ProjectData *pd = GNUNET_OS_project_data_get ();
+ const struct GNUNET_OS_ProjectData *dpd = GNUNET_OS_project_data_default ();
+
+ if (pd != dpd)
+ GNUNET_OS_init (dpd);
+
+ for (unsigned int i = 0; i < num_plugins; i++)
+ {
+ plugin = credential_plugins[i];
+ GNUNET_break (NULL ==
+ GNUNET_PLUGIN_unload (plugin->library_name,
+ plugin->api));
+ GNUNET_free (plugin->library_name);
+ GNUNET_free (plugin);
+ }
+ GNUNET_free (credential_plugins);
+
+ if (pd != dpd)
+ GNUNET_OS_init (pd);
+
+ credential_plugins = NULL;
+}
+
+
+
+/**
* Convert an credential type name to the corresponding number
*
* @param typename name to convert
@@ -721,7 +753,6 @@ GNUNET_RECLAIM_presentation_list_serialize_get_size (
{
GNUNET_assert (NULL != le->presentation);
len += GNUNET_RECLAIM_presentation_serialize_get_size (le->presentation);
- len += sizeof(struct GNUNET_RECLAIM_PresentationListEntry);
}
return len;
}
@@ -774,8 +805,7 @@ GNUNET_RECLAIM_presentation_list_deserialize (const char *data, size_t
al = GNUNET_new (struct GNUNET_RECLAIM_PresentationList);
- if ((data_size < sizeof(struct Presentation)
- + sizeof(struct GNUNET_RECLAIM_PresentationListEntry)))
+ if (data_size < sizeof(struct Presentation))
return al;
read_ptr = data;