/** * * Update all ID_TOKEN records for an identity and store them * * @param cls the identity entry * @param zone the identity * @param lbl the name of the record * @param rd_count number of records * @param rd record data * */ static void token_collect (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *lbl, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) { struct EgoEntry *ego_entry = cls; if (NULL == lbl) { //Done GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, ">>> Updating Ego finished\n"); //Clear attribute map for ego GNUNET_CONTAINER_multihashmap_iterate (ego_entry->attr_map, &clear_ego_attrs, ego_entry); GNUNET_CONTAINER_multihashmap_clear (ego_entry->attr_map); GNUNET_SCHEDULER_add_now (&update_identities, ego_entry->next); return; } //There should be only a single record for a token under a label if ((1 != rd_count) || (rd->record_type != GNUNET_GNSRECORD_TYPE_ID_TOKEN) || (0 == (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION & rd->flags))) { GNUNET_NAMESTORE_zone_iterator_next (ns_it); return; } token = GNUNET_GNSRECORD_value_to_string (rd->record_type, rd->data, rd->data_size); label = GNUNET_strdup (lbl); GNUNET_SCHEDULER_add_now (&handle_token_update, ego_entry); }
/** * We were asked to delete something; this function is called with * the existing records. Now we should determine what should be * deleted and then issue the deletion operation. * * @param cls NULL * @param zone private key of the zone we are deleting from * @param label name of the records we are editing * @param rd_count size of the @a rd array * @param rd existing records */ static void del_monitor (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) { struct GNUNET_GNSRECORD_Data rdx[rd_count]; unsigned int rd_left; unsigned int i; uint32_t type; char *vs; del_qe = NULL; if (0 == rd_count) { FPRINTF (stderr, _("There are no records under label `%s' that could be deleted.\n"), label); test_finished (); return; } if ( (NULL == value) && (NULL == typestring) ) { /* delete everything */ del_qe = GNUNET_NAMESTORE_records_store (ns, &zone_pkey, name, 0, NULL, &del_continuation, NULL); return; } rd_left = 0; if (NULL != typestring) type = GNUNET_GNSRECORD_typename_to_number (typestring); else type = GNUNET_GNSRECORD_TYPE_ANY; for (i=0;i<rd_count;i++) { vs = NULL; if (! ( ( (GNUNET_GNSRECORD_TYPE_ANY == type) || (rd[i].record_type == type) ) && ( (NULL == value) || (NULL == (vs = (GNUNET_GNSRECORD_value_to_string (rd[i].record_type, rd[i].data, rd[i].data_size)))) || (0 == strcmp (vs, value)) ) ) ) rdx[rd_left++] = rd[i]; GNUNET_free_non_null (vs); } if (rd_count == rd_left) { /* nothing got deleted */ FPRINTF (stderr, _("There are no records under label `%s' that match the request for deletion.\n"), label); test_finished (); return; } /* delete everything but what we copied to 'rdx' */ del_qe = GNUNET_NAMESTORE_records_store (ns, &zone_pkey, name, rd_left, rdx, &del_continuation, NULL); }
/** * Process a record that was stored in the namestore. * * @param cls closure * @param zone_key private key of the zone * @param rname name that is being mapped (at most 255 characters long) * @param rd_len number of entries in @a rd array * @param rd array of records with data to store */ static void display_record (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, const char *rname, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd) { const char *typestring; char *s; unsigned int i; const char *ets; struct GNUNET_TIME_Absolute at; struct GNUNET_TIME_Relative rt; if (NULL == rname) { list_it = NULL; test_finished (); return; } if ( (NULL != name) && (0 != strcmp (name, rname)) ) { GNUNET_NAMESTORE_zone_iterator_next (list_it); return; } FPRINTF (stdout, "%s:\n", rname); for (i=0;i<rd_len;i++) { if ( (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) && (0 != strcmp (rname, "+")) ) continue; typestring = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type); s = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, rd[i].data, rd[i].data_size); if (NULL == s) { FPRINTF (stdout, _("\tCorrupt or unsupported record of type %u\n"), (unsigned int) rd[i].record_type); continue; } if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) { rt.rel_value_us = rd[i].expiration_time; ets = GNUNET_STRINGS_relative_time_to_string (rt, GNUNET_YES); } else { at.abs_value_us = rd[i].expiration_time; ets = GNUNET_STRINGS_absolute_time_to_string (at); } FPRINTF (stdout, "\t%s: %s (%s)\t%s\t%s\n", typestring, s, ets, (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) ? "PRIVATE" : "PUBLIC", (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_SHADOW_RECORD)) ? "SHADOW" : ""); GNUNET_free (s); } FPRINTF (stdout, "%s", "\n"); GNUNET_NAMESTORE_zone_iterator_next (list_it); }
/** * Convert the 'value' of a record to a string. * * @param cls closure, unused * @param type type of the record * @param data value in binary encoding * @param data_size number of bytes in @a data * @return NULL on error, otherwise human-readable representation of the value */ static char * gns_value_to_string (void *cls, uint32_t type, const void *data, size_t data_size) { const char *cdata; switch (type) { case GNUNET_GNSRECORD_TYPE_PKEY: if (data_size != sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) return NULL; return GNUNET_CRYPTO_ecdsa_public_key_to_string (data); case GNUNET_GNSRECORD_TYPE_NICK: return GNUNET_strndup (data, data_size); case GNUNET_GNSRECORD_TYPE_LEHO: return GNUNET_strndup (data, data_size); case GNUNET_GNSRECORD_TYPE_GNS2DNS: { char *ns; char *ip; size_t off; char *nstr; off = 0; ns = GNUNET_DNSPARSER_parse_name (data, data_size, &off); ip = GNUNET_DNSPARSER_parse_name (data, data_size, &off); if ( (NULL == ns) || (NULL == ip) || (off != data_size) ) { GNUNET_break_op (0); GNUNET_free_non_null (ns); GNUNET_free_non_null (ip); return NULL; } GNUNET_asprintf (&nstr, "%s@%s", ns, ip); GNUNET_free_non_null (ns); GNUNET_free_non_null (ip); return nstr; } case GNUNET_GNSRECORD_TYPE_VPN: { const struct GNUNET_TUN_GnsVpnRecord *vpn; char* vpn_str; cdata = data; if ( (data_size <= sizeof (struct GNUNET_TUN_GnsVpnRecord)) || ('\0' != cdata[data_size - 1]) ) return NULL; /* malformed */ vpn = data; GNUNET_asprintf (&vpn_str, "%u %s %s", (unsigned int) ntohs (vpn->proto), (const char*) GNUNET_i2s_full (&vpn->peer), (const char*) &vpn[1]); return vpn_str; } case GNUNET_GNSRECORD_TYPE_BOX: { const struct GNUNET_GNSRECORD_BoxRecord *box; uint32_t rt; char *box_str; char *ival; if (data_size < sizeof (struct GNUNET_GNSRECORD_BoxRecord)) return NULL; /* malformed */ box = data; rt = ntohl (box->record_type); ival = GNUNET_GNSRECORD_value_to_string (rt, &box[1], data_size - sizeof (struct GNUNET_GNSRECORD_BoxRecord)); if (NULL == ival) return NULL; /* malformed */ GNUNET_asprintf (&box_str, "%u %u %u %s", (unsigned int) ntohs (box->protocol), (unsigned int) ntohs (box->service), (unsigned int) rt, ival); GNUNET_free (ival); return box_str; } default: return NULL; } }
/** * Process a record that was stored in the namestore, adding * the information to the HTML. * * @param cls closure with the `struct ZoneinfoRequest *` * @param zone_key private key of the zone; NULL on disconnect * @param name label of the records; NULL on disconnect * @param rd_len number of entries in @a rd array, 0 if label was deleted * @param rd array of records with data to store */ static void iterate_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, const char *name, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd) { struct ZoneinfoRequest *zr = cls; struct MHD_Response *response; char* full_page; size_t bytes_free; char* pkey; char* new_buf; if (NULL == name) { zr->list_it = NULL; /* return static form */ GNUNET_asprintf (&full_page, ZONEINFO_PAGE, zr->zoneinfo, zr->zoneinfo); response = MHD_create_response_from_buffer (strlen (full_page), (void *) full_page, MHD_RESPMEM_MUST_FREE); MHD_add_response_header (response, MHD_HTTP_HEADER_CONTENT_TYPE, MIME_HTML); MHD_queue_response (zr->connection, MHD_HTTP_OK, response); MHD_destroy_response (response); GNUNET_free (zr->zoneinfo); GNUNET_free (zr); run_httpd_now (); return; } if (1 != rd_len) { GNUNET_NAMESTORE_zone_iterator_next (zr->list_it); return; } if (GNUNET_GNSRECORD_TYPE_PKEY != rd->record_type) { GNUNET_NAMESTORE_zone_iterator_next (zr->list_it); return; } bytes_free = zr->buf_len - zr->write_offset; pkey = GNUNET_GNSRECORD_value_to_string (rd->record_type, rd->data, rd->data_size); if (NULL == pkey) { GNUNET_break (0); GNUNET_NAMESTORE_zone_iterator_next (zr->list_it); return; } if (bytes_free < (strlen (name) + strlen (pkey) + 40)) { new_buf = GNUNET_malloc (zr->buf_len * 2); memcpy (new_buf, zr->zoneinfo, zr->write_offset); GNUNET_free (zr->zoneinfo); zr->zoneinfo = new_buf; zr->buf_len *= 2; } sprintf (zr->zoneinfo + zr->write_offset, "<tr><td>%s</td><td>%s</td></tr>", name, pkey); zr->write_offset = strlen (zr->zoneinfo); GNUNET_NAMESTORE_zone_iterator_next (zr->list_it); GNUNET_free (pkey); }
/** * * Collect all ID_ATTR records for an identity and store them * * @param cls the identity entry * @param zone the identity * @param lbl the name of the record * @param rd_count number of records * @param rd record data * */ static void attribute_collect (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *lbl, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd) { struct EgoEntry *ego_entry = cls; json_t *attr_value; struct GNUNET_HashCode key; char* attr; int i; if (NULL == lbl) { //Done GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, ">>> Updating Attributes finished\n"); ego_entry->attributes_dirty = GNUNET_NO; GNUNET_SCHEDULER_add_now (&update_identities, ego_entry); return; } if (0 == rd_count) { GNUNET_NAMESTORE_zone_iterator_next (ns_it); return; } GNUNET_CRYPTO_hash (lbl, strlen (lbl), &key); if (1 == rd_count) { if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR) { attr = GNUNET_GNSRECORD_value_to_string (rd->record_type, rd->data, rd->data_size); attr_value = json_string (attr); GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map, &key, attr_value, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); GNUNET_free (attr); } GNUNET_NAMESTORE_zone_iterator_next (ns_it); return; } attr_value = json_array(); for (i = 0; i < rd_count; i++) { if (rd[i].record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR) { attr = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, rd[i].data, rd[i].data_size); json_array_append_new (attr_value, json_string (attr)); GNUNET_free (attr); } } GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map, &key, attr_value, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); GNUNET_NAMESTORE_zone_iterator_next (ns_it); return; }
/** * Convert the 'value' of a record to a string. * * @param cls closure, unused * @param type type of the record * @param data value in binary encoding * @param data_size number of bytes in @a data * @return NULL on error, otherwise human-readable representation of the value */ static char * gns_value_to_string (void *cls, uint32_t type, const void *data, size_t data_size) { const char *cdata; switch (type) { case GNUNET_GNSRECORD_TYPE_PKEY: if (data_size != sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) return NULL; return GNUNET_CRYPTO_ecdsa_public_key_to_string (data); case GNUNET_GNSRECORD_TYPE_NICK: return GNUNET_strndup (data, data_size); case GNUNET_GNSRECORD_TYPE_LEHO: return GNUNET_strndup (data, data_size); case GNUNET_GNSRECORD_TYPE_GNS2DNS: { char *ns; char *ip; size_t off; char *nstr; off = 0; ns = GNUNET_DNSPARSER_parse_name (data, data_size, &off); ip = GNUNET_DNSPARSER_parse_name (data, data_size, &off); if ( (NULL == ns) || (NULL == ip) || (off != data_size) ) { GNUNET_break_op (0); GNUNET_free_non_null (ns); GNUNET_free_non_null (ip); return NULL; } GNUNET_asprintf (&nstr, "%s@%s", ns, ip); GNUNET_free_non_null (ns); GNUNET_free_non_null (ip); return nstr; } case GNUNET_GNSRECORD_TYPE_VPN: { struct GNUNET_TUN_GnsVpnRecord vpn; char* vpn_str; cdata = data; if ( (data_size <= sizeof (vpn)) || ('\0' != cdata[data_size - 1]) ) return NULL; /* malformed */ /* need to memcpy for alignment */ memcpy (&vpn, data, sizeof (vpn)); GNUNET_asprintf (&vpn_str, "%u %s %s", (unsigned int) ntohs (vpn.proto), (const char*) GNUNET_i2s_full (&vpn.peer), (const char*) &cdata[sizeof (vpn)]); return vpn_str; } case GNUNET_GNSRECORD_TYPE_BOX: { struct GNUNET_GNSRECORD_BoxRecord box; uint32_t rt; char *box_str; char *ival; cdata = data; if (data_size < sizeof (struct GNUNET_GNSRECORD_BoxRecord)) return NULL; /* malformed */ memcpy (&box, data, sizeof (box)); rt = ntohl (box.record_type); ival = GNUNET_GNSRECORD_value_to_string (rt, &cdata[sizeof (box)], data_size - sizeof (box)); if (NULL == ival) return NULL; /* malformed */ GNUNET_asprintf (&box_str, "%u %u %u %s", (unsigned int) ntohs (box.protocol), (unsigned int) ntohs (box.service), (unsigned int) rt, ival); GNUNET_free (ival); return box_str; } case GNUNET_GNSRECORD_TYPE_REVERSE: { struct GNUNET_GNSRECORD_ReverseRecord rev; char *rev_str; char *pkey_str; if (data_size < sizeof (struct GNUNET_GNSRECORD_ReverseRecord)) return NULL; /* malformed */ memcpy (&rev, data, sizeof (rev)); cdata = data; pkey_str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&rev.pkey); GNUNET_asprintf (&rev_str, "%s %s %"SCNu64, &cdata[sizeof (rev)], pkey_str, rev.expiration.abs_value_us); GNUNET_free (pkey_str); return rev_str; } default: return NULL; } }