/** * Method called to inform about the egos of this peer. * * When used with #GNUNET_IDENTITY_connect, this function is * initially called for all egos and then again whenever a * ego's name changes or if it is deleted. At the end of * the initial pass over all egos, the function is once called * with 'NULL' for @a ego. That does NOT mean that the callback won't * be invoked in the future or that there was an error. * * When used with #GNUNET_IDENTITY_create or #GNUNET_IDENTITY_get, * this function is only called ONCE, and 'NULL' being passed in * @a ego does indicate an error (i.e. name is taken or no default * value is known). If @a ego is non-NULL and if '*ctx' * is set in those callbacks, the value WILL be passed to a subsequent * call to the identity callback of #GNUNET_IDENTITY_connect (if * that one was not NULL). * * When an identity is renamed, this function is called with the * (known) @a ego but the NEW @a name. * * When an identity is deleted, this function is called with the * (known) ego and "NULL" for the @a name. In this case, * the @a ego is henceforth invalid (and the @a ctx should also be * cleaned up). * * @param cls closure * @param ego ego handle * @param ctx context for application to store data for this ego * (during the lifetime of this process, initially NULL) * @param name name assigned by the user for this ego, * NULL if the user just deleted the ego and it * must thus no longer be used */ static void identity_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *name) { const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key; struct GNUNET_GNSRECORD_Data rd; char *rd_string; char *peername; if (NULL == name) return; if (NULL == ego) { if (NULL == qe) { fprintf (stderr, "Failed to find master-zone ego\n"); GNUNET_SCHEDULER_shutdown (); return; } GNUNET_IDENTITY_disconnect (identity); identity = NULL; return; } GNUNET_assert (NULL != name); if (0 != strcmp (name, "master-zone")) { fprintf (stderr, "Unexpected name %s\n", name); return; } zone_key = GNUNET_IDENTITY_ego_get_private_key (ego); rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; peername = GNUNET_strdup (GNUNET_i2s_full (&id)); GNUNET_asprintf (&rd_string, "6 %s %s", peername, "www"); GNUNET_free (peername); GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_string_to_value (GNUNET_GNSRECORD_TYPE_VPN, rd_string, (void**) &rd.data, &rd.data_size)); rd.record_type = GNUNET_GNSRECORD_TYPE_VPN; qe = GNUNET_NAMESTORE_records_store (namestore, zone_key, "www", 1, &rd, &commence_testing, NULL); GNUNET_free ((void**)rd.data); GNUNET_free (rd_string); }
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TESTING_Peer *peer) { enum MHD_FLAG flags; struct GNUNET_CRYPTO_EcdsaPrivateKey *host_key; struct GNUNET_GNSRECORD_Data rd; char *zone_keyfile; namestore = GNUNET_NAMESTORE_connect (cfg); GNUNET_assert (NULL != namestore); flags = MHD_USE_DEBUG; mhd = MHD_start_daemon (flags, PORT, NULL, NULL, &mhd_ahc, NULL, MHD_OPTION_END); GNUNET_assert (NULL != mhd); mhd_main (); tmp_cfgfile = GNUNET_DISK_mktemp ("test_gns_proxy_tmp.conf"); if (NULL == tmp_cfgfile) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create tmp cfg!\n"); do_shutdown (); return; } if (GNUNET_OK != GNUNET_CONFIGURATION_write ((struct GNUNET_CONFIGURATION_Handle *)cfg, tmp_cfgfile)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to write tmp cfg\n"); do_shutdown (); return; } proxy_proc = GNUNET_OS_start_process (GNUNET_NO, GNUNET_OS_INHERIT_STD_ALL, NULL, NULL, NULL, "gnunet-gns-proxy", "gnunet-gns-proxy", "-c", tmp_cfgfile, NULL); if (NULL == proxy_proc) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to start proxy\n"); do_shutdown (); return; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns", "ZONEKEY", &zone_keyfile)) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n"); return; } host_key = GNUNET_CRYPTO_ecdsa_key_create_from_file (zone_keyfile); rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_string_to_value (GNUNET_DNSPARSER_TYPE_A, "127.0.0.1", (void**)&rd.data, &rd.data_size)); rd.record_type = GNUNET_DNSPARSER_TYPE_A; GNUNET_NAMESTORE_record_create (namestore, host_key, "www", &rd, &commence_testing, NULL); GNUNET_free ((void**)rd.data); GNUNET_free (zone_keyfile); GNUNET_free (host_key); }
/** * Convert human-readable version of a 'value' of a record to the binary * representation. * * @param cls closure, unused * @param type type of the record * @param s human-readable string * @param data set to value in binary encoding (will be allocated) * @param data_size set to number of bytes in @a data * @return #GNUNET_OK on success */ static int gns_string_to_value (void *cls, uint32_t type, const char *s, void **data, size_t *data_size) { struct GNUNET_CRYPTO_EcdsaPublicKey pkey; if (NULL == s) return GNUNET_SYSERR; switch (type) { case GNUNET_GNSRECORD_TYPE_PKEY: if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (s, strlen (s), &pkey)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse PKEY record `%s'\n"), s); return GNUNET_SYSERR; } *data = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); memcpy (*data, &pkey, sizeof (pkey)); *data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); return GNUNET_OK; case GNUNET_GNSRECORD_TYPE_NICK: *data = GNUNET_strdup (s); *data_size = strlen (s); return GNUNET_OK; case GNUNET_GNSRECORD_TYPE_LEHO: *data = GNUNET_strdup (s); *data_size = strlen (s); return GNUNET_OK; case GNUNET_GNSRECORD_TYPE_GNS2DNS: { char nsbuf[514]; char *cpy; char *at; size_t off; cpy = GNUNET_strdup (s); at = strchr (cpy, '@'); if (NULL == at) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse GNS2DNS record `%s'\n"), s); GNUNET_free (cpy); return GNUNET_SYSERR; } *at = '\0'; at++; off = 0; if ( (GNUNET_OK != GNUNET_DNSPARSER_builder_add_name (nsbuf, sizeof (nsbuf), &off, cpy)) || (GNUNET_OK != GNUNET_DNSPARSER_builder_add_name (nsbuf, sizeof (nsbuf), &off, at)) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to serialize GNS2DNS record with value `%s'\n"), s); GNUNET_free (cpy); return GNUNET_SYSERR; } GNUNET_free (cpy); *data_size = off; *data = GNUNET_malloc (off); memcpy (*data, nsbuf, off); return GNUNET_OK; } case GNUNET_GNSRECORD_TYPE_VPN: { struct GNUNET_TUN_GnsVpnRecord *vpn; char s_peer[103 + 1]; char s_serv[253 + 1]; unsigned int proto; if (3 != SSCANF (s, "%u %103s %253s", &proto, s_peer, s_serv)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse VPN record string `%s'\n"), s); return GNUNET_SYSERR; } *data_size = sizeof (struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1; *data = vpn = GNUNET_malloc (*data_size); if (GNUNET_OK != GNUNET_CRYPTO_eddsa_public_key_from_string ((char*) s_peer, strlen (s_peer), &vpn->peer.public_key)) { GNUNET_free (vpn); *data_size = 0; return GNUNET_SYSERR; } vpn->proto = htons ((uint16_t) proto); strcpy ((char*)&vpn[1], s_serv); return GNUNET_OK; } case GNUNET_GNSRECORD_TYPE_BOX: { struct GNUNET_GNSRECORD_BoxRecord *box; size_t rest; unsigned int protocol; unsigned int service; unsigned int record_type; void *bval; size_t bval_size; if (3 != SSCANF (s, "%u %u %u ", &protocol, &service, &record_type)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse BOX record string `%s'\n"), s); return GNUNET_SYSERR; } rest = snprintf (NULL, 0, "%u %u %u ", protocol, service, record_type); if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (record_type, &s[rest], &bval, &bval_size)) return GNUNET_SYSERR; *data_size = sizeof (struct GNUNET_GNSRECORD_BoxRecord) + bval_size; *data = box = GNUNET_malloc (*data_size); box->protocol = htons (protocol); box->service = htons (service); box->record_type = htonl (record_type); memcpy (&box[1], bval, bval_size); GNUNET_free (bval); return GNUNET_OK; } default: return GNUNET_SYSERR; } }
/** * Function called with the result from the check if the namestore * service is actually running. If it is, we start the actual * operation. * * @param cls closure with our configuration * @param result #GNUNET_YES if the namestore service is running */ static void testservice_task (void *cls, int result) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; struct GNUNET_CRYPTO_EcdsaPublicKey pub; struct GNUNET_GNSRECORD_Data rd; if (GNUNET_YES != result) { FPRINTF (stderr, _("Service `%s' is not running\n"), "namestore"); return; } if (! (add|del|list|(NULL != nickstring)|(NULL != uri)|(NULL != reverse_pkey)) ) { /* nothing more to be done */ fprintf (stderr, _("No options given\n")); GNUNET_SCHEDULER_shutdown (); return; } GNUNET_CRYPTO_ecdsa_key_get_public (&zone_pkey, &pub); ns = GNUNET_NAMESTORE_connect (cfg); if (NULL == ns) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to connect to namestore\n")); return; } if (add) { if (NULL == name) { fprintf (stderr, _("Missing option `%s' for operation `%s'\n"), "-n", _("add")); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } if (NULL == typestring) { fprintf (stderr, _("Missing option `%s' for operation `%s'\n"), "-t", _("add")); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } type = GNUNET_GNSRECORD_typename_to_number (typestring); if (UINT32_MAX == type) { fprintf (stderr, _("Unsupported type `%s'\n"), typestring); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } if (NULL == value) { fprintf (stderr, _("Missing option `%s' for operation `%s'\n"), "-V", _("add")); ret = 1; GNUNET_SCHEDULER_shutdown (); return; } if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (type, value, &data, &data_size)) { fprintf (stderr, _("Value `%s' invalid for record type `%s'\n"), value, typestring); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } if (NULL == expirationstring) { fprintf (stderr, _("Missing option `%s' for operation `%s'\n"), "-e", _("add")); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } if (0 == strcmp (expirationstring, "never")) { etime_abs = GNUNET_TIME_UNIT_FOREVER_ABS; etime_is_rel = GNUNET_NO; } else if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_relative (expirationstring, &etime_rel)) { etime_is_rel = GNUNET_YES; } else if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, &etime_abs)) { etime_is_rel = GNUNET_NO; } else { fprintf (stderr, _("Invalid time format `%s'\n"), expirationstring); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } add_qe = GNUNET_NAMESTORE_records_lookup (ns, &zone_pkey, name, &get_existing_record, NULL ); } if (del) { if (NULL == name) { fprintf (stderr, _("Missing option `%s' for operation `%s'\n"), "-n", _("del")); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } del_qe = GNUNET_NAMESTORE_records_lookup (ns, &zone_pkey, name, &del_monitor, NULL); } if (list) { list_it = GNUNET_NAMESTORE_zone_iteration_start (ns, &zone_pkey, &display_record, NULL); } if (NULL != reverse_pkey) { struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (reverse_pkey, strlen (reverse_pkey), &pubkey)) { fprintf (stderr, _("Invalid public key for reverse lookup `%s'\n"), reverse_pkey); GNUNET_SCHEDULER_shutdown (); } reverse_qe = GNUNET_NAMESTORE_zone_to_name (ns, &zone_pkey, &pubkey, &handle_reverse_lookup, NULL); } if (NULL != uri) { char sh[105]; char sname[64]; struct GNUNET_CRYPTO_EcdsaPublicKey pkey; GNUNET_STRINGS_utf8_tolower (uri, uri); if ( (2 != (sscanf (uri, "gnunet://gns/%52s/%63s", sh, sname)) ) || (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (sh, strlen (sh), &pkey)) ) { fprintf (stderr, _("Invalid URI `%s'\n"), uri); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } memset (&rd, 0, sizeof (rd)); rd.data = &pkey; rd.data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY; if (GNUNET_YES == etime_is_rel) { rd.expiration_time = etime_rel.rel_value_us; rd.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; } else if (GNUNET_NO == etime_is_rel) rd.expiration_time = etime_abs.abs_value_us; else rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; if (1 == is_shadow) rd.flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD; add_qe_uri = GNUNET_NAMESTORE_records_store (ns, &zone_pkey, sname, 1, &rd, &add_continuation, &add_qe_uri); } if (NULL != nickstring) { if (0 == strlen(nickstring)) { fprintf (stderr, _("Invalid nick `%s'\n"), nickstring); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } add_qe_uri = GNUNET_NAMESTORE_set_nick(ns, &zone_pkey, nickstring, &add_continuation, &add_qe_uri); } if (monitor) { zm = GNUNET_NAMESTORE_zone_monitor_start (cfg, &zone_pkey, GNUNET_YES, &display_record, &sync_cb, NULL); } }
/** * Convert human-readable version of a 'value' of a record to the binary * representation. * * @param cls closure, unused * @param type type of the record * @param s human-readable string * @param data set to value in binary encoding (will be allocated) * @param data_size set to number of bytes in @a data * @return #GNUNET_OK on success */ static int gns_string_to_value (void *cls, uint32_t type, const char *s, void **data, size_t *data_size) { struct GNUNET_CRYPTO_EcdsaPublicKey pkey; if (NULL == s) return GNUNET_SYSERR; switch (type) { case GNUNET_GNSRECORD_TYPE_PKEY: if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (s, strlen (s), &pkey)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse PKEY record `%s'\n"), s); return GNUNET_SYSERR; } *data = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); GNUNET_memcpy (*data, &pkey, sizeof (pkey)); *data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); return GNUNET_OK; case GNUNET_GNSRECORD_TYPE_NICK: *data = GNUNET_strdup (s); *data_size = strlen (s); return GNUNET_OK; case GNUNET_GNSRECORD_TYPE_LEHO: *data = GNUNET_strdup (s); *data_size = strlen (s); return GNUNET_OK; case GNUNET_GNSRECORD_TYPE_GNS2DNS: { char nsbuf[514]; char *cpy; char *at; size_t off; cpy = GNUNET_strdup (s); at = strchr (cpy, '@'); if (NULL == at) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse GNS2DNS record `%s'\n"), s); GNUNET_free (cpy); return GNUNET_SYSERR; } *at = '\0'; at++; off = 0; if ( (GNUNET_OK != GNUNET_DNSPARSER_builder_add_name (nsbuf, sizeof (nsbuf), &off, cpy)) || (GNUNET_OK != GNUNET_DNSPARSER_builder_add_name (nsbuf, sizeof (nsbuf), &off, at)) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to serialize GNS2DNS record with value `%s'\n"), s); GNUNET_free (cpy); return GNUNET_SYSERR; } GNUNET_free (cpy); *data_size = off; *data = GNUNET_malloc (off); GNUNET_memcpy (*data, nsbuf, off); return GNUNET_OK; } case GNUNET_GNSRECORD_TYPE_VPN: { struct GNUNET_TUN_GnsVpnRecord *vpn; char s_peer[103 + 1]; char s_serv[253 + 1]; unsigned int proto; if (3 != SSCANF (s, "%u %103s %253s", &proto, s_peer, s_serv)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse VPN record string `%s'\n"), s); return GNUNET_SYSERR; } *data_size = sizeof (struct GNUNET_TUN_GnsVpnRecord) + strlen (s_serv) + 1; *data = vpn = GNUNET_malloc (*data_size); if (GNUNET_OK != GNUNET_CRYPTO_eddsa_public_key_from_string ((char*) s_peer, strlen (s_peer), &vpn->peer.public_key)) { GNUNET_free (vpn); *data_size = 0; return GNUNET_SYSERR; } vpn->proto = htons ((uint16_t) proto); strcpy ((char*)&vpn[1], s_serv); return GNUNET_OK; } case GNUNET_GNSRECORD_TYPE_BOX: { struct GNUNET_GNSRECORD_BoxRecord *box; size_t rest; unsigned int protocol; unsigned int service; unsigned int record_type; void *bval; size_t bval_size; if (3 != SSCANF (s, "%u %u %u ", &protocol, &service, &record_type)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse BOX record string `%s'\n"), s); return GNUNET_SYSERR; } rest = snprintf (NULL, 0, "%u %u %u ", protocol, service, record_type); if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (record_type, &s[rest], &bval, &bval_size)) return GNUNET_SYSERR; *data_size = sizeof (struct GNUNET_GNSRECORD_BoxRecord) + bval_size; *data = box = GNUNET_malloc (*data_size); box->protocol = htons (protocol); box->service = htons (service); box->record_type = htonl (record_type); GNUNET_memcpy (&box[1], bval, bval_size); GNUNET_free (bval); return GNUNET_OK; } case GNUNET_GNSRECORD_TYPE_REVERSE: { struct GNUNET_GNSRECORD_ReverseRecord *rev; char known_by[253 + 1]; struct GNUNET_TIME_Absolute expiration; /* TODO: From crypto_ecc.c * Why is this not a constant??? */ size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8; if (enclen % 5 > 0) enclen += 5 - enclen % 5; enclen /= 5; /* 260/5 = 52 */ char pkey_str[enclen + 1]; if (3 != SSCANF (s, "%253s %52s %"SCNu64, known_by, pkey_str, &expiration.abs_value_us)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse REVERSE record string `%s'\n"), s); return GNUNET_SYSERR; } *data_size = sizeof (struct GNUNET_GNSRECORD_ReverseRecord) + strlen (known_by) + 1; *data = rev = GNUNET_malloc (*data_size); GNUNET_CRYPTO_ecdsa_public_key_from_string (pkey_str, strlen (pkey_str), &rev->pkey); rev->expiration = expiration; GNUNET_memcpy (&rev[1], known_by, strlen (known_by)); return GNUNET_OK; } default: return GNUNET_SYSERR; } }