From 313d7741e03f767652a61265d1bfc8e2186ef98a Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Tue, 19 Jun 2012 18:41:47 +0000 Subject: [PATCH] -zone revocation --- src/gns/Makefile.am | 18 +- src/gns/gnunet-service-gns_resolver.c | 114 ++++++-- src/gns/gnunet-service-gns_resolver.h | 4 +- src/gns/test_gns_revocation.c | 352 +++++++++++++++++++++++++ src/include/gnunet_gns_service.h | 17 +- src/include/gnunet_namestore_service.h | 5 + 6 files changed, 483 insertions(+), 27 deletions(-) create mode 100644 src/gns/test_gns_revocation.c diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am index 718257bfd..bb10a5973 100644 --- a/src/gns/Makefile.am +++ b/src/gns/Makefile.am @@ -51,7 +51,8 @@ check_PROGRAMS = \ test_gns_max_queries \ test_gns_dht_threepeer \ test_gns_cname_lookup \ - test_gns_ns_lookup + test_gns_ns_lookup \ + test_gns_revocation # test_gns_simple_lookup @@ -225,6 +226,21 @@ test_gns_ns_lookup_DEPENDENCIES = \ $(top_builddir)/src/gns/libgnunetgns.la \ $(top_builddir)/src/testing_old/libgnunettesting_old.la + +test_gns_revocation_SOURCES = \ + test_gns_revocation.c +test_gns_revocation_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing_old/libgnunettesting_old.la +test_gns_revocation_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing_old/libgnunettesting_old.la + + gnunet_gns_SOURCES = \ gnunet-gns.c gnunet_gns_LDADD = \ diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index 0236c7207..c09bcca90 100644 --- a/src/gns/gnunet-service-gns_resolver.c +++ b/src/gns/gnunet-service-gns_resolver.c @@ -2603,6 +2603,13 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GNS_PHASE_DELEGATE_NS-%llu: Resolution status: %d.\n", rh->id, rh->status); + + if (rh->status & RSL_PKEY_REVOKED) + { + finish_lookup (rh, rlh, 0, NULL); + free_resolver_handle (rh); + return; + } if (strcmp(rh->name, "") == 0) { @@ -2668,7 +2675,16 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, } else if (rh->status & RSL_DELEGATE_PKEY) { - if (rlh->record_type == GNUNET_GNS_RECORD_PKEY) + if (rh->status & RSL_PKEY_REVOKED) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Resolved PKEY is revoked.\n", + rh->id); + finish_lookup (rh, rlh, 0, NULL); + free_resolver_handle (rh); + return; + } + else if (rlh->record_type == GNUNET_GNS_RECORD_PKEY) { GNUNET_assert(rd_count == 1); GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, @@ -2760,6 +2776,77 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, resolve_delegation_dht(rh); } +/** + * This is a callback function that checks for key revocation + * + * @param cls the pending query + * @param key the key of the zone we did the lookup + * @param expiration expiration date of the record data set in the namestore + * @param name the name for which we need an authority + * @param rd_count the number of records with 'name' + * @param rd the record data + * @param signature the signature of the authority for the record data + */ +static void +process_pkey_revocation_result_ns (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, + struct GNUNET_TIME_Absolute expiration, + const char *name, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + struct ResolverHandle *rh = cls; + struct GNUNET_TIME_Relative remaining_time; + int i; + + remaining_time = GNUNET_TIME_absolute_get_remaining (expiration); + + for (i = 0; i < rd_count; i++) + { + if (rd[i].record_type == GNUNET_GNS_RECORD_REV) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: Zone has been revoked.\n", + rh->id); + rh->status |= RSL_PKEY_REVOKED; + rh->proc (rh->proc_cls, rh, 0, NULL); + return; + } + } + + if ((name == NULL) || + (remaining_time.rel_value == 0)) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%llu: + Records don't exist or are expired.\n", + rh->id, name); + //FIXME start BG lookup + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "GNS_PHASE_DELEGATE_NS-%d: Starting background lookup for %s type %d\n", + rh->id, "+.gnunet", GNUNET_GNS_RECORD_REV); + + gns_resolver_lookup_record(rh->authority, + rh->private_local_zone, + GNUNET_GNS_RECORD_REV, + GNUNET_GNS_TLD, + rh->priv_key, + GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_NO, + &background_lookup_result_processor, + NULL); + } + + /** + * We are done with PKEY resolution if name is empty + * else resolve again with new authority + */ + if (strcmp (rh->name, "") == 0) + rh->proc (rh->proc_cls, rh, 0, NULL); + else + resolve_delegation_ns (rh); + return; +} /** @@ -2777,7 +2864,7 @@ handle_delegation_ns (void* cls, struct ResolverHandle *rh, * @param signature the signature of the authority for the record data */ static void -process_delegation_result_ns(void* cls, +process_delegation_result_ns (void* cls, const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, struct GNUNET_TIME_Absolute expiration, const char *name, @@ -2962,22 +3049,15 @@ process_delegation_result_ns(void* cls, rh->authority_chain_tail, auth); - /** try to import pkey if private key available - * TODO: Only import last one? - */ - //if (rh->priv_key && (name != NULL) && is_canonical (rh->name)) - // process_discovered_authority((char*)name, auth->zone, - // rh->authority_chain_tail->zone, - // rh->priv_key); - /** - * We are done with PKEY resolution if name is empty - * else resolve again with new authority - */ - if (strcmp (rh->name, "") == 0) - rh->proc (rh->proc_cls, rh, rd_count, rd); - else - resolve_delegation_ns (rh); + /* Check for key revocation and delegate */ + GNUNET_NAMESTORE_lookup_record (namestore_handle, + &rh->authority, + "+", + GNUNET_GNS_RECORD_REV, + &process_pkey_revocation_result_ns, + rh); return; + } /** diff --git a/src/gns/gnunet-service-gns_resolver.h b/src/gns/gnunet-service-gns_resolver.h index 0e18f13a6..b93e6acec 100644 --- a/src/gns/gnunet-service-gns_resolver.h +++ b/src/gns/gnunet-service-gns_resolver.h @@ -92,6 +92,7 @@ typedef void (*ResolutionResultProcessor) (void *cls, * RSL_DELEGATE_NS: Found NS delegation * RSL_DELEGATE_PKEY: Found PKEY delegation * RSL_CNAME_FOUND: Found CNAME record + * RSL_PKEY_REVOKED: Found PKEY has been revoked */ enum ResolutionStatus { @@ -101,7 +102,8 @@ enum ResolutionStatus RSL_DELEGATE_VPN = 8, RSL_DELEGATE_NS = 16, RSL_DELEGATE_PKEY = 32, - RSL_CNAME_FOUND = 64 + RSL_CNAME_FOUND = 64, + RSL_PKEY_REVOKED = 128 }; /** diff --git a/src/gns/test_gns_revocation.c b/src/gns/test_gns_revocation.c new file mode 100644 index 000000000..f5d2c47cd --- /dev/null +++ b/src/gns/test_gns_revocation.c @@ -0,0 +1,352 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +/** + * @file gns/test_gns_revovation.c + * @brief base testcase for testing zone revocation + * + */ +#include "platform.h" +#include "gnunet_testing_lib.h" +#include "gnunet_core_service.h" +#include "block_dns.h" +#include "gnunet_signatures.h" +#include "gnunet_namestore_service.h" +#include "../namestore/namestore.h" +#include "gnunet_dnsparser_lib.h" +#include "gnunet_gns_service.h" + +/* DEFINES */ +#define VERBOSE GNUNET_YES + +/* Timeout for entire testcase */ +#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 20) + +/* If number of peers not in config file, use this number */ +#define DEFAULT_NUM_PEERS 2 + +/* test records to resolve */ +#define TEST_DOMAIN "www.bob.gnunet" +#define TEST_IP "127.0.0.1" +#define TEST_RECORD_NAME "www" + +#define TEST_AUTHORITY_NAME "bob" + +#define KEYFILE_BOB "../namestore/zonefiles/HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey" + +/* Globals */ + +/** + * Directory to store temp data in, defined in config file + */ +static char *test_directory; + +static struct GNUNET_TESTING_PeerGroup *pg; + +/* Task handle to use to schedule test failure */ +GNUNET_SCHEDULER_TaskIdentifier die_task; + +/* Global return value (0 for success, anything else for failure) */ +static int ok; + +static struct GNUNET_NAMESTORE_Handle *namestore_handle; + +static struct GNUNET_GNS_Handle *gns_handle; + +const struct GNUNET_CONFIGURATION_Handle *cfg; + +/** + * Check whether peers successfully shut down. + */ +void +shutdown_callback (void *cls, const char *emsg) +{ + if (emsg != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error on shutdown! ret=%d\n", ok); + if (ok == 0) + ok = 2; + } + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "done(ret=%d)!\n", ok); +} + +static void +on_lookup_result(void *cls, uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + struct in_addr a; + int i; + char* addr; + + if (rd_count == 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Lookup failed, this is good!\n"); + ok = 0; + } + else + { + ok = 1; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "name: %s\n", (char*)cls); + for (i=0; i