*/
struct GNUNET_RECLAIM_ATTESTATION_Claim *attest;
+ /**
+ * The reference to delete
+ */
+ struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *reference;
/**
* Tickets to update
*/
GNUNET_free (adh->claim);
if (NULL != adh->attest)
GNUNET_free (adh->attest);
+ if (NULL != adh->reference)
+ GNUNET_free (adh->reference);
while (NULL != (le = adh->tickets_to_update_head))
{
GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
return;
}
+/**
+ * Error looking up potential reference value. Abort.
+ *
+ * @param cls our attribute delete handle
+ */
+static void
+ref_del_error (void *cls)
+{
+ struct AttributeDeleteHandle *adh = cls;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to find Attestation entry for Attestation reference\n");
+ cleanup_adh (adh);
+ GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+ return;
+}
/**
* Reference store result handler
*
{
if (0 == ash->reference->id_attest)
{
- ash->reference->id = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
- UINT64_MAX);
+ ash->reference->id = GNUNET_CRYPTO_random_u64 (
+ GNUNET_CRYPTO_QUALITY_STRONG,
+ UINT64_MAX);
}
else
{
ash,
&ref_add_cb,
ash);
- GNUNET_free (label);
+ GNUNET_free (label);
}
/**
*/
static int
check_reference_store_message (void *cls,
- const struct
- AttributeStoreMessage *sam)
+ const struct
+ AttributeStoreMessage *sam)
{
uint16_t size;
for (int i = 0; i < rd_count; i++)
{
if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type) &&
- (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[i].record_type))
+ (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[i].record_type) &&
+ (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF != rd[i].record_type))
continue;
if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof(uint64_t)))
continue;
if (0 != memcmp (rd[i].data, (&adh->attest->id), sizeof(uint64_t)))
continue;
+ if (0 != memcmp (rd[i].data, &adh->reference->id, sizeof(uint64_t)))
+ continue;
+
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Attribute or Attestation to delete found (%s)\n",
+ "Attribute or Attestation/Reference to delete found (%s)\n",
adh->label);
has_changed = GNUNET_YES;
break;
if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR == rd[i].record_type)
&& (0 == memcmp (rd[i].data, &adh->attest->id, sizeof(uint64_t))))
continue;
+ if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_REF == rd[i].record_type)
+ && (0 == memcmp (rd[i].data, &adh->reference->id, sizeof(uint64_t))))
+ continue;
rd_new[j] = rd[i];
j++;
}
+/**
+* Reference deleted callback
+*
+* @param cls our handle
+* @param success success status
+* @param emsg error message (NULL if success=GNUNET_OK)
+*/
+static void
+reference_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 reference %s\n",
+ adh->label);
+ send_delete_response (adh, GNUNET_SYSERR);
+ cleanup_adh (adh);
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
+ GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
+}
+
+static void
+ref_del_cb (void *cls,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+ const char *label,
+ unsigned int rd_count,
+ const struct GNUNET_GNSRECORD_Data *rd)
+{
+
+ struct AttributeDeleteHandle *adh = cls;
+ char *data_tmp;
+ struct GNUNET_GNSRECORD_Data rd_new[rd_count - 1];
+ struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *ref;
+ size_t attr_len;
+
+ if (0 == rd_count )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to find Attestation entry for Attestation reference\n");
+ cleanup_adh (adh);
+ GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+ return;
+ }
+ if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTEST_ATTR != rd[0].record_type)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Intended Reference location is not an attestation\n");
+ cleanup_adh (adh);
+ GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
+ return;
+ }
+ rd_new[0] = rd[0];
+ int i;
+ int j = 1;
+ for (i = 1; i<rd_count; i++)
+ {
+ data_tmp = GNUNET_malloc (rd[i].data_size);
+ GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
+ attr_len = htons (rd->data_size);
+ ref = GNUNET_RECLAIM_ATTESTATION_REF_deserialize (data_tmp, attr_len);
+ if (NULL == ref )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unable to parse attestation reference from %s\n",
+ data_tmp);
+ rd_new[j] = rd[i];
+ j += 1;
+ continue;
+ }
+ if ((strcmp (adh->reference->name,ref->name) == 0)&&
+ (strcmp (adh->reference->reference_value,ref->reference_value)==0) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Found reference to delete.\n");
+ }
+ else
+ {
+ rd_new[j] = rd[i];
+ j += 1;
+ }
+ GNUNET_free (data_tmp);
+ }
+ adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+ &adh->identity,
+ label,
+ j,
+ rd_new,
+ &reference_delete_cont,
+ adh);
+}
+
+/**
+ * Check an attestation reference delete message
+ *
+ * @param cls unused
+ * @param sam the message to check
+ */
+static int
+check_reference_delete_message (void *cls,
+ const struct AttributeDeleteMessage *dam)
+{
+ uint16_t size;
+
+ size = ntohs (dam->header.size);
+ if (size <= sizeof(struct AttributeDeleteMessage))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+/**
+ * Handle reference deletion
+ *
+ * @param cls our client
+ * @param dam deletion message
+ */
+static void
+handle_reference_delete_message (void *cls,
+ const struct AttributeDeleteMessage *dam)
+{
+ struct AttributeDeleteHandle *adh;
+ struct IdpClient *idp = cls;
+ size_t data_len;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REFERENCE_DELETE message\n");
+ data_len = ntohs (dam->attr_len);
+ adh = GNUNET_new (struct AttributeDeleteHandle);
+ adh->reference = GNUNET_RECLAIM_ATTESTATION_REF_deserialize ((char *) &dam[1],
+ data_len);
+ adh->r_id = ntohl (dam->id);
+ adh->identity = dam->identity;
+ adh->label
+ = GNUNET_STRINGS_data_to_string_alloc (&adh->reference->id,
+ sizeof(uint64_t));
+ GNUNET_SERVICE_client_continue (idp->client);
+ adh->client = idp;
+ GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
+ adh->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
+ &adh->identity,
+ adh->label,
+ &ref_del_error,
+ adh,
+ &ref_del_cb,
+ adh);
+}
GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_STORE,
struct AttributeStoreMessage,
NULL),
+ GNUNET_MQ_hd_var_size (reference_delete_message,
+ GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE,
+ struct AttributeDeleteMessage,
+ NULL),
GNUNET_MQ_hd_fixed_size (
iteration_start,
GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
return;
}
identity = handle->url + strlen (
- GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen ("reference/") + 1;
+ GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen ("reference/")
+ + 1;
for (ego_entry = handle->ego_head; NULL != ego_entry;
ego_entry = ego_entry->next)
if (0 == strcmp (identity, ego_entry->identifier))
handle);
}
+/**
+ * Deletes reference from an identity
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
+static void
+delete_attestation_ref_cont (struct GNUNET_REST_RequestHandle *con_handle,
+ const char *url,
+ void *cls)
+{
+ struct RequestHandle *handle = cls;
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
+ struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr;
+ struct EgoEntry *ego_entry;
+ char *identity;
+ char *identity_id_str;
+ char *id;
+ char term_data[handle->rest_handle->data_size + 1];
+ json_t *data_json;
+ json_error_t err;
+
+ struct GNUNET_JSON_Specification attrspec[] =
+ { GNUNET_RECLAIM_JSON_spec_claim_attest_ref (&attr),
+ GNUNET_JSON_spec_end () };
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Deleting attestation reference.\n");
+ if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) + strlen (
+ "reference/") + 1 >= strlen (
+ handle->url))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
+ GNUNET_SCHEDULER_add_now (&do_error, handle);
+ return;
+ }
+ identity_id_str = strdup (handle->url + strlen (
+ GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
+ + strlen ("reference/")
+ + 1);
+ identity = strtok (identity_id_str, "/");
+ id = strtok (NULL, "/");
+
+ if ((NULL == identity) || (NULL == id))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed request.\n");
+ GNUNET_SCHEDULER_add_now (&do_error, handle);
+ return;
+ }
+ for (ego_entry = handle->ego_head; NULL != ego_entry;
+ ego_entry = ego_entry->next)
+ if (0 == strcmp (identity, ego_entry->identifier))
+ break;
+ handle->resp_object = json_array ();
+ if (NULL == ego_entry)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", identity);
+ GNUNET_SCHEDULER_add_now (&return_response, handle);
+ return;
+ }
+ priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
+ if (0 >= handle->rest_handle->data_size)
+ {
+ GNUNET_SCHEDULER_add_now (&do_error, handle);
+ return;
+ }
+
+ term_data[handle->rest_handle->data_size] = '\0';
+ GNUNET_memcpy (term_data,
+ handle->rest_handle->data,
+ handle->rest_handle->data_size);
+ data_json = json_loads (term_data, JSON_DECODE_ANY, &err);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_JSON_parse (data_json, attrspec, NULL, NULL));
+ json_decref (data_json);
+ if (NULL == attr)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unable to parse attestation reference from %s\n",
+ term_data);
+ GNUNET_SCHEDULER_add_now (&do_error, handle);
+ return;
+ }
+ GNUNET_STRINGS_string_to_data (id, strlen (id), &attr->id, sizeof(uint64_t));
+
+ handle->idp = GNUNET_RECLAIM_connect (cfg);
+ handle->idp_op = GNUNET_RECLAIM_attestation_reference_delete (handle->idp,
+ priv_key,
+ attr,
+ &
+ delete_finished_cb,
+ handle);
+ GNUNET_JSON_parse_free (attrspec);
+}
+
+
/**
* Deletes attestation from an identity
*
const char *url,
void *cls)
{
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
struct RequestHandle *handle = cls;
+ /* Check for substring "reference" */
+ if (strlen (GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE) < strlen (
+ handle->url))
+ {
+ if ( strncmp ("reference", (handle->url + strlen (
+ GNUNET_REST_API_NS_RECLAIM_ATTESTATION_REFERENCE)
+ + 1), strlen (
+ "reference")) == 0)
+ {
+ delete_attestation_ref_cont (con_handle,url,cls);
+ return;
+ }
+ }
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
struct GNUNET_RECLAIM_ATTESTATION_Claim attr;
struct EgoEntry *ego_entry;
char *identity_id_str;
return op;
}
+/**
+ * Delete an attestation reference. Tickets used to share this reference are updated
+ * accordingly.
+ *
+ * @param h handle to the re:claimID service
+ * @param pkey Private key of the identity to delete the reference from
+ * @param attr The reference
+ * @param cont Continuation to call when done
+ * @param cont_cls Closure for @a cont
+ * @return handle Used to to abort the request
+ */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attestation_reference_delete (
+ struct GNUNET_RECLAIM_Handle *h,
+ const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+ const struct GNUNET_RECLAIM_ATTESTATION_REFERENCE *attr,
+ GNUNET_RECLAIM_ContinuationWithStatus cont,
+ void *cont_cls)
+{
+
+ struct GNUNET_RECLAIM_Operation *op;
+ struct AttributeDeleteMessage *dam;
+ size_t attr_len;
+
+ op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
+ op->h = h;
+ op->as_cb = cont;
+ op->cls = cont_cls;
+ op->r_id = h->r_id_gen++;
+ GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
+ attr_len = GNUNET_RECLAIM_ATTESTATION_REF_serialize_get_size (attr);
+ op->env = GNUNET_MQ_msg_extra (dam,
+ attr_len,
+ GNUNET_MESSAGE_TYPE_RECLAIM_REFERENCE_DELETE);
+ dam->identity = *pkey;
+ dam->id = htonl (op->r_id);
+ GNUNET_RECLAIM_ATTESTATION_REF_serialize (attr, (char *) &dam[1]);
+
+ dam->attr_len = htons (attr_len);
+ if (NULL != h->mq)
+ GNUNET_MQ_send_copy (h->mq, op->env);
+ return op;
+}
/**
* List all attributes for a local identity.