From: Kai Blin Date: Wed, 18 Apr 2012 16:33:22 +0000 (+0200) Subject: WIP: more tkey work X-Git-Url: http://git.samba.org/?a=commitdiff_plain;h=a49137b09d2b2e5d0f1668a716c1b92aa6d1e84d;p=kai%2Fsamba.git WIP: more tkey work --- diff --git a/source4/dns_server/dns_crypto.c b/source4/dns_server/dns_crypto.c index 465d0890b9f..0355a8aeaea 100644 --- a/source4/dns_server/dns_crypto.c +++ b/source4/dns_server/dns_crypto.c @@ -228,8 +228,10 @@ WERROR dns_verify_tsig(struct dns_server *dns, } /*FIXME: calculate a real tsig here */ -WERROR dns_sign_tsig(struct dns_server *dns, - struct dns_request_state *state, +WERROR dns_sign_tsig(const struct dns_server_key *key, + const char *name, + const uint8_t *req_mac, + uint16_t req_size, struct dns_name_packet *packet, uint16_t error) { @@ -237,14 +239,12 @@ WERROR dns_sign_tsig(struct dns_server *dns, time_t current_time = time(NULL); uint16_t mac_size; uint8_t *mac; - struct dns_server_key *key; struct dns_res_rec *tsig = talloc_zero(packet, struct dns_res_rec); W_ERROR_HAVE_NO_MEMORY(tsig); - tsig->name = talloc_strdup(tsig, state->tsig->name); + tsig->name = talloc_strdup(tsig, name); W_ERROR_HAVE_NO_MEMORY(tsig->name); - key = dns_find_tsig_key(dns, tsig->name); if (key == NULL) { state->flags |= DNS_RCODE_NOTAUTH; state->tsig_error = DNS_RCODE_BADKEY; @@ -254,8 +254,7 @@ WERROR dns_sign_tsig(struct dns_server *dns, tsig->rr_type = DNS_QTYPE_TSIG; tsig->ttl = 0; tsig->length = UINT16_MAX; - tsig->rdata.tsig_record.algorithm_name = talloc_strdup(tsig, - state->tsig->rdata.tsig_record.algorithm_name); + tsig->rdata.tsig_record.algorithm_name = talloc_strdup(tsig, algorithm); tsig->rdata.tsig_record.time_prefix = 0; tsig->rdata.tsig_record.time = current_time; tsig->rdata.tsig_record.fudge = 300; @@ -265,8 +264,7 @@ WERROR dns_sign_tsig(struct dns_server *dns, tsig->rdata.tsig_record.other_data = NULL; werror = dns_generate_tsig_mac(packet, key, packet, tsig, - state->tsig->rdata.tsig_record.mac, - state->tsig->rdata.tsig_record.mac_size, + req_mac, req_size, &mac, &mac_size); W_ERROR_NOT_OK_RETURN(werror); diff --git a/source4/dns_server/dns_server.h b/source4/dns_server/dns_server.h index cbaea02bdb6..4175e7114b2 100644 --- a/source4/dns_server/dns_server.h +++ b/source4/dns_server/dns_server.h @@ -107,8 +107,10 @@ WERROR dns_name2dn(struct dns_server *dns, WERROR dns_verify_tsig(struct dns_server *dns, struct dns_request_state *state, struct dns_name_packet *in_packet); -WERROR dns_sign_tsig(struct dns_server *dns, - struct dns_request_state *state, +WERROR dns_sign_tsig(const struct dns_server_key *key, + const char *name, + const uint8_t *req_mac, + uint16_t req_size, struct dns_name_packet *packet, uint16_t error); diff --git a/source4/dns_server/wscript_build b/source4/dns_server/wscript_build index f5153438225..0d705e65f5f 100644 --- a/source4/dns_server/wscript_build +++ b/source4/dns_server/wscript_build @@ -1,15 +1,24 @@ #!/usr/bin/env python bld.SAMBA_MODULE('service_dns', - source='dns_server.c dns_query.c dns_update.c dns_utils.c dns_crypto.c', + source='dns_server.c dns_query.c dns_update.c', subsystem='service', init_function='server_service_dns_init', deps='''samba-hostconfig LIBTSOCKET LIBSAMBA_TSOCKET ldbsamba LIBCLI_DNS - LIBCRYPTO gensec auth''', + gensec auth dns-utils dns-crypto''', local_include=False, internal_module=False, ) +bld.SAMBA_SUBSYSTEM('dns-crypto', + source='dns_crypto.c', + public_deps='LIBCRYPTO dns-utils' + ) + +bld.SAMBA_SUBSYSTEM('dns-utils', + source='dns_utils.c', + ) + # a bind9 dlz module giving access to the Samba DNS SAM bld.SAMBA_LIBRARY('dlz_bind9', source='dlz_bind9.c', diff --git a/utils/dns-tsig.c b/utils/dns-tsig.c index e9d137de97d..c4aa1505c02 100644 --- a/utils/dns-tsig.c +++ b/utils/dns-tsig.c @@ -14,42 +14,6 @@ static void usage(void) printf("Usage: dns-tsig \n\n"); } -static WERROR dns_copy_tsig(TALLOC_CTX *mem_ctx, - struct dns_res_rec *old, - struct dns_res_rec *new_rec) -{ - new_rec->name = talloc_strdup(mem_ctx, old->name); - W_ERROR_HAVE_NO_MEMORY(new_rec->name); - - new_rec->rr_type = old->rr_type; - new_rec->rr_class = old->rr_class; - new_rec->ttl = old->ttl; - new_rec->length = old->length; - new_rec->rdata.tsig_record.algorithm_name = talloc_strdup(mem_ctx, - old->rdata.tsig_record.algorithm_name); - W_ERROR_HAVE_NO_MEMORY(new_rec->rdata.tsig_record.algorithm_name); - - new_rec->rdata.tsig_record.time_prefix = old->rdata.tsig_record.time_prefix; - new_rec->rdata.tsig_record.time = old->rdata.tsig_record.time; - new_rec->rdata.tsig_record.fudge = old->rdata.tsig_record.fudge; - new_rec->rdata.tsig_record.mac_size = old->rdata.tsig_record.mac_size; - new_rec->rdata.tsig_record.mac = talloc_memdup(mem_ctx, - old->rdata.tsig_record.mac, - old->rdata.tsig_record.mac_size); - W_ERROR_HAVE_NO_MEMORY(new_rec->rdata.tsig_record.mac); - - new_rec->rdata.tsig_record.original_id = old->rdata.tsig_record.original_id; - new_rec->rdata.tsig_record.error = old->rdata.tsig_record.error; - new_rec->rdata.tsig_record.other_size = old->rdata.tsig_record.other_size; - new_rec->rdata.tsig_record.other_data = talloc_memdup(mem_ctx, - old->rdata.tsig_record.other_data, - old->rdata.tsig_record.other_size); - W_ERROR_HAVE_NO_MEMORY(new_rec->rdata.tsig_record.other_data); - - return WERR_OK; -} - - static struct dns_name_packet *make_name_packet(TALLOC_CTX *mem_ctx) { struct dns_name_packet *packet = talloc_zero(mem_ctx, @@ -92,212 +56,12 @@ static char *dns_get_string_wire_format(TALLOC_CTX *mem_ctx, const char* string) return wire_format; } -static WERROR dns_generate_tsig_mac(TALLOC_CTX *mem_ctx, - const struct dns_server_key *key, - const struct dns_name_packet *packet, - const struct dns_res_rec *tsig, - const uint8_t *req_mac, - uint16_t req_mac_length, - uint8_t **mac, - uint16_t *mac_length) -{ - HMACMD5Context *ctx; - uint16_t digest_length = 16; - uint8_t *digest; - DATA_BLOB blob; - enum ndr_err_code ndr_err; - uint16_t dummy16; - uint32_t dummy32; - char *fake_name; - char *fake_alg; - - if (key == NULL) { - DEBUG(1, ("No key found, bailing out\n")); - *mac = NULL; - *mac_length = 0; - return WERR_OK; - } - - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, packet, - (ndr_push_flags_fn_t)ndr_push_dns_name_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return DNS_ERR(FORMAT_ERROR); - } - - ctx = talloc_zero(mem_ctx, HMACMD5Context); - W_ERROR_HAVE_NO_MEMORY(ctx); - - /* Build up the MAC as per RFC2845 */ - hmac_md5_init_rfc2104(key->data, key->length, ctx); - - /* 4.2 on replies, also hash the request MAC */ - if (req_mac != NULL) { - hmac_md5_update(req_mac, req_mac_length, ctx); - } - - /* 3.4.1 dns message */ - hmac_md5_update(blob.data, blob.length, ctx); - - /* 3.4.2 tsig variables */ - fake_name = dns_get_string_wire_format(mem_ctx, tsig->name); - hmac_md5_update((const uint8_t *)fake_name, strlen(fake_name)+1, ctx); - - dummy16 = htons(tsig->rr_class); - hmac_md5_update((const uint8_t *)&dummy16, 2, ctx); - - dummy32 = htonl(tsig->ttl); - hmac_md5_update((const uint8_t *)&dummy32, 4, ctx); - - fake_alg = dns_get_string_wire_format(mem_ctx, - tsig->rdata.tsig_record.algorithm_name); - hmac_md5_update((const uint8_t *)fake_alg, - strlen(fake_alg)+1, ctx); - - dummy16 = htons(tsig->rdata.tsig_record.time_prefix); - hmac_md5_update((const uint8_t *)&dummy16, 2, ctx); - - dummy32 = htonl(tsig->rdata.tsig_record.time); - hmac_md5_update((const uint8_t *)&dummy32, 4, ctx); - - dummy16 = htons(tsig->rdata.tsig_record.fudge); - hmac_md5_update((const uint8_t *)&dummy16, 2, ctx); - - dummy16 = htons(tsig->rdata.tsig_record.error); - hmac_md5_update((const uint8_t *)&dummy16, 2, ctx); - - dummy16 = htons(tsig->rdata.tsig_record.other_size); - hmac_md5_update((const uint8_t *)&dummy16, 2, ctx); - - hmac_md5_update((const uint8_t*)&tsig->rdata.tsig_record.other_data, - tsig->rdata.tsig_record.other_size, ctx); - - digest = talloc_array(mem_ctx, uint8_t, digest_length); - W_ERROR_HAVE_NO_MEMORY(digest); - hmac_md5_final(digest, ctx); - - *mac = digest; - *mac_length = digest_length; - - return WERR_OK; -} - -static WERROR sign_tsig(TALLOC_CTX *mem_ctx, - struct dns_server_key *key, - struct dns_name_packet *packet) -{ - WERROR werror; - time_t current_time = time(NULL); - uint8_t *mac; - uint16_t mac_length = 0; - struct dns_res_rec *tsig = talloc_zero(packet, struct dns_res_rec); - W_ERROR_HAVE_NO_MEMORY(tsig); - - tsig->name = talloc_strdup(tsig, "test"); - W_ERROR_HAVE_NO_MEMORY(tsig->name); - - tsig->rr_class = DNS_QCLASS_ANY; - tsig->rr_type = DNS_QTYPE_TSIG; - tsig->ttl = 0; - tsig->length = UINT16_MAX; - tsig->rdata.tsig_record.algorithm_name = talloc_strdup(tsig, - "hmac-md5.sig-alg.reg.int"); - tsig->rdata.tsig_record.time_prefix = 0; -// tsig->rdata.tsig_record.time = 0x4f74260d; - tsig->rdata.tsig_record.time = current_time; - tsig->rdata.tsig_record.fudge = 300; - tsig->rdata.tsig_record.original_id = 0xc25d; - tsig->rdata.tsig_record.error = 0; - tsig->rdata.tsig_record.other_size = 0; - tsig->rdata.tsig_record.other_data = NULL; - - werror = dns_generate_tsig_mac(mem_ctx, key, packet, tsig, - NULL, 0, &mac, &mac_length); - tsig->rdata.tsig_record.mac = mac; - tsig->rdata.tsig_record.mac_size = mac_length; - - if (packet->arcount == 0) { - packet->additional = talloc_zero(packet, struct dns_res_rec); - W_ERROR_HAVE_NO_MEMORY(packet->additional); - } - packet->additional = talloc_realloc(packet, packet->additional, - struct dns_res_rec, - packet->arcount + 1); - W_ERROR_HAVE_NO_MEMORY(packet->additional); - - werror = dns_copy_tsig(packet, tsig, - &packet->additional[packet->arcount]); - W_ERROR_NOT_OK_RETURN(werror); - - packet->arcount++; - - return WERR_OK; -} - -static WERROR verify_tsig(TALLOC_CTX *mem_ctx, - struct dns_server_key *key, - const uint8_t old_mac[16], - struct dns_name_packet *packet) -{ - WERROR werror; - bool found_tsig = false; - uint16_t i, mac_length = 0; - uint8_t *mac = NULL; - struct dns_res_rec *tsig; - - /* Find the first TSIG record in the additional records */ - for (i=0; i < packet->arcount; i++) { - if (packet->additional[i].rr_type == DNS_QTYPE_TSIG) { - found_tsig = true; - break; - } - } - - if (!found_tsig) { - return WERR_OK; - } - - /* The TSIG record needs to be the last additional record */ - if (found_tsig && i + 1 != packet->arcount) { - DEBUG(0, ("TSIG record not the last additional record!\n")); - return DNS_ERR(FORMAT_ERROR); - } - - NDR_PRINT_DEBUG(dns_name_packet, packet); - /* We got a TSIG, so we need to sign our reply */ - - tsig = talloc_zero(mem_ctx, struct dns_res_rec); - W_ERROR_HAVE_NO_MEMORY(tsig); - - werror = dns_copy_tsig(tsig, &packet->additional[i], - tsig); - W_ERROR_NOT_OK_RETURN(werror); - - packet->arcount--; - - werror = dns_generate_tsig_mac(mem_ctx, key, packet, tsig, - old_mac, 16, &mac, &mac_length); - W_ERROR_NOT_OK_RETURN(werror); - - - if (memcmp(tsig->rdata.tsig_record.mac, mac, mac_length) != 0) { - DEBUG(1, ("TSIG MAC mismatch\n")); - dump_data(1, tsig->rdata.tsig_record.mac, - tsig->rdata.tsig_record.mac_size); - dump_data(1, mac, mac_length); - return DNS_ERR(NOTAUTH); - } - - /* FIXME: Do a time check here, too. */ - return WERR_OK; -} - - int main(int argc, char **argv) { TALLOC_CTX *mem_ctx = talloc_init("samba-dig"); struct tevent_context *ev; struct dns_name_packet *dns_packet, *in_packet; - struct dns_server_key *key; + struct dns_server_tkey *key; enum ndr_err_code ndr_err; struct tevent_req *req; uint8_t out_mac[16]; @@ -316,13 +80,15 @@ int main(int argc, char **argv) dns_packet = make_name_packet(mem_ctx); + state = talloc_zero(mem_ctx, struct dns_request_state); + key = talloc_zero(mem_ctx, struct dns_server_key); key->name = talloc_strdup(key, "test"); key->length = 12; key->data = talloc_zero_size(key, key->length); - sign_tsig(mem_ctx, key, dns_packet); + dns_sign_tsig(key, dns_packet); memcpy(out_mac, dns_packet->additional[0].rdata.tsig_record.mac, 16); @@ -366,7 +132,7 @@ int main(int argc, char **argv) //NDR_PRINT_DEBUG(dns_name_packet, in_packet); - verify_tsig(mem_ctx, key, out_mac, in_packet); + dns_verify_tsig(mem_ctx, key, out_mac, in_packet); error: return ret; diff --git a/utils/wscript_build b/utils/wscript_build index 7b499d6025c..74e44c77922 100644 --- a/utils/wscript_build +++ b/utils/wscript_build @@ -7,7 +7,7 @@ bld.SAMBA_BINARY('samba-dig', bld.SAMBA_BINARY('dns-tsig', source='dns-tsig.c', - deps='samba-util NDR_DNS tevent LIBCLI_DNS' + deps='samba-util NDR_DNS tevent LIBCLI_DNS dns-utils dns-crypto' ) bld.SAMBA_BINARY('addns-update',