From 3900beb1ed0370041bccbe84643d84a6f5204475 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Philipp=20T=C3=B6lke?= Date: Tue, 26 Oct 2010 13:55:55 +0000 Subject: [PATCH] modified the DNS_Record-block --- src/block/plugin_block_dns.c | 17 ++++++-- src/include/block_dns.h | 40 +++++++++++------- src/include/gnunet_signatures.h | 5 +++ src/vpn/gnunet-service-dns.c | 73 ++++++++++++++++++++++++--------- 4 files changed, 98 insertions(+), 37 deletions(-) diff --git a/src/block/plugin_block_dns.c b/src/block/plugin_block_dns.c index 1e1a577fc..205cff4b8 100644 --- a/src/block/plugin_block_dns.c +++ b/src/block/plugin_block_dns.c @@ -27,6 +27,7 @@ #include "platform.h" #include "plugin_block.h" #include "block_dns.h" +#include "gnunet_signatures.h" #define DEBUG_DHT GNUNET_NO @@ -65,11 +66,21 @@ block_plugin_dns_evaluate (void *cls, if (reply_block_size == 0) return GNUNET_BLOCK_EVALUATION_REQUEST_VALID; - if (reply_block_size < sizeof(struct GNUNET_DNS_Record)) + if (reply_block_size != sizeof(struct GNUNET_DNS_Record)) return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; const struct GNUNET_DNS_Record* rec = reply_block; - if(reply_block_size != (sizeof(struct GNUNET_DNS_Record) + rec->namelen - 1)) + + if (ntohl(rec->purpose.size) != sizeof(struct GNUNET_DNS_Record) - sizeof(struct GNUNET_CRYPTO_RsaSignature)) + return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + + if (GNUNET_TIME_relative_get_zero().value == GNUNET_TIME_absolute_get_remaining(rec->expiration_time).value) + return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; + + if (GNUNET_OK != GNUNET_CRYPTO_rsa_verify (htonl(GNUNET_SIGNATURE_PURPOSE_DNS_RECORD), + &rec->purpose, + &rec->signature, + &rec->peer)) return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; /* How to decide whether there are no more? */ @@ -101,7 +112,7 @@ block_plugin_dns_get_key (void *cls, if (type != GNUNET_BLOCK_TYPE_DNS) return GNUNET_SYSERR; const struct GNUNET_DNS_Record* rec = block; - GNUNET_CRYPTO_hash(rec->name, rec->namelen, key); + memcpy(key, &rec->service_descriptor, sizeof(GNUNET_HashCode)); return GNUNET_OK; } diff --git a/src/include/block_dns.h b/src/include/block_dns.h index d8f3fa50e..6be82b126 100644 --- a/src/include/block_dns.h +++ b/src/include/block_dns.h @@ -2,26 +2,38 @@ #define _GNVPN_BLOCKDNS_H_ #include "gnunet_common.h" +#include "gnunet_crypto_lib.h" /** - * Bitmask describing what ip-services are supported by services - * It is 2 bytes long + * Bitmask describing what IP-protocols are supported by the service */ -struct GNUNET_ipservices { - unsigned UDP:1 GNUNET_PACKED; - unsigned TCP:1 GNUNET_PACKED; - unsigned RESERVED:14 GNUNET_PACKED; +enum GNUNET_DNS_ServiceTypes +{ + GNUNET_DNS_SERVICE_TYPE_UDP = 1, + GNUNET_DNS_SERVICE_TYPE_TCP = 2 }; + /** * This is the structure describing an dns-record such as www.gnunet. */ struct GNUNET_DNS_Record { + /** + * Signature of the peer affirming that he is offering the service. + */ + struct GNUNET_CRYPTO_RsaSignature signature; + + /** + * Beginning of signed portion of the record, signs everything until + * the end of the struct. + */ + struct GNUNET_CRYPTO_RsaSignaturePurpose purpose; + /** * The peer providing this service */ - struct GNUNET_PeerIdentity peer; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded peer; /** * The descriptor for the service @@ -30,20 +42,20 @@ struct GNUNET_DNS_Record GNUNET_HashCode service_descriptor; /** - * What connection-types (UDP, TCP, ...) are supported by the service + * When does this record expire? */ - struct GNUNET_ipservices connectiontypes; + struct GNUNET_TIME_Absolute expiration_time; /** - * The length of the name of the service + * Four TCP and UDP-Ports that are used by this service, big endian format */ - unsigned char namelen; + uint64_t ports; /** - * The name of the service - * This is namelen bytes + * What connection-types (UDP, TCP, ...) are supported by the service. + * Contains an 'enum GNUNET_DNS_ServiceTypes' in big endian format. */ - char name[1]; + uint32_t service_type; }; #endif diff --git a/src/include/gnunet_signatures.h b/src/include/gnunet_signatures.h index a3199c735..98c449486 100644 --- a/src/include/gnunet_signatures.h +++ b/src/include/gnunet_signatures.h @@ -97,6 +97,11 @@ extern "C" */ #define GNUNET_SIGNATURE_PURPOSE_RESOLVER_RESPONSE 10 +/** + * Signature of an GNUNET_DNS_Record + */ +#define GNUNET_SIGNATURE_PURPOSE_DNS_RECORD 11 + #if 0 /* keep Emacsens' auto-indent happy */ { diff --git a/src/vpn/gnunet-service-dns.c b/src/vpn/gnunet-service-dns.c index 1ad3c8784..0c688db34 100644 --- a/src/vpn/gnunet-service-dns.c +++ b/src/vpn/gnunet-service-dns.c @@ -36,6 +36,8 @@ #include "gnunet_dht_service.h" #include "gnunet_block_lib.h" #include "block_dns.h" +#include "gnunet_crypto_lib.h" +#include "gnunet_signatures.h" struct dns_cls { struct GNUNET_SCHEDULER_Handle *sched; @@ -46,6 +48,8 @@ struct dns_cls { unsigned short dnsoutport; + const struct GNUNET_CONFIGURATION_Handle *cfg; + struct answer_packet_list *head; struct answer_packet_list *tail; }; @@ -265,28 +269,55 @@ publish_name (void *cls, return; char* name = "philipptoelke.gnunet."; - size_t size = sizeof(struct GNUNET_DNS_Record) + strlen(name); - struct GNUNET_DNS_Record *data = alloca(size); - memset(data, 0, size); - memcpy(data->name, name, strlen(name) + 1); - data->namelen = strlen(name) + 1; - *((unsigned int*)&data->service_descriptor) = 0x11223344; - *((unsigned int*)&data->peer) = 0x55667788; - - GNUNET_HashCode key; - GNUNET_CRYPTO_hash(name, strlen(name)+1, &key); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Putting with key %08x, len is %d\n", *((unsigned int*)&key), strlen(name)); + size_t size = sizeof(struct GNUNET_DNS_Record); + struct GNUNET_DNS_Record data; + memset(&data, 0, size); + + data.purpose.size = htonl(size - sizeof(struct GNUNET_CRYPTO_RsaSignature)); + data.purpose.purpose = GNUNET_SIGNATURE_PURPOSE_DNS_RECORD; + + GNUNET_CRYPTO_hash(name, strlen(name)+1, &data.service_descriptor); + + char* keyfile; + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename(mycls.cfg, "GNUNETD", + "HOSTKEY", &keyfile)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "could not read keyfile-value\n"); + if (keyfile != NULL) GNUNET_free(keyfile); + return; + } + + struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file(keyfile); + GNUNET_free(keyfile); + + GNUNET_CRYPTO_rsa_key_get_public(my_private_key, &data.peer); + + data.expiration_time = GNUNET_TIME_relative_to_absolute(GNUNET_TIME_UNIT_HOURS); + + /* Sign the block + */ + + if (GNUNET_OK != GNUNET_CRYPTO_rsa_sign(my_private_key, + &data.purpose, + &data.signature)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "could not sign DNS_Record\n"); + return; + } + GNUNET_free(my_private_key); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Putting with key %08x\n", *((unsigned int*)&data.service_descriptor)); GNUNET_DHT_put(mycls.dht, - &key, - GNUNET_DHT_RO_NONE, - GNUNET_BLOCK_TYPE_DNS, - size, - (char*)data, - GNUNET_TIME_relative_to_absolute(GNUNET_TIME_UNIT_HOURS), - GNUNET_TIME_UNIT_MINUTES, - NULL, - NULL); + &data.service_descriptor, + GNUNET_DHT_RO_NONE, + GNUNET_BLOCK_TYPE_DNS, + size, + (char*)&data, + GNUNET_TIME_relative_to_absolute(GNUNET_TIME_UNIT_HOURS), + GNUNET_TIME_UNIT_MINUTES, + NULL, + NULL); GNUNET_SCHEDULER_add_delayed (mycls.sched, GNUNET_TIME_UNIT_HOURS, publish_name, NULL); } @@ -309,6 +340,8 @@ run (void *cls, {NULL, NULL, 0, 0} }; + mycls.cfg = cfg; + { int i; for (i = 0; i < 65536; i++) { -- 2.25.1