WIP: more tkey work dns_tkey
authorKai Blin <kai@samba.org>
Wed, 18 Apr 2012 16:33:22 +0000 (18:33 +0200)
committerKai Blin <kai@samba.org>
Wed, 18 Apr 2012 16:33:22 +0000 (18:33 +0200)
source4/dns_server/dns_crypto.c
source4/dns_server/dns_server.h
source4/dns_server/wscript_build
utils/dns-tsig.c
utils/wscript_build

index 465d0890b9f8e669f29b37461df205b80c59f155..0355a8aeaeaecf471476ed3215a9330d1bd214ab 100644 (file)
@@ -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);
 
index cbaea02bdb60b383e7343b41dd696720f1ed5b77..4175e7114b2bf7712083a0e6f5401b016d67c2b4 100644 (file)
@@ -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);
 
index f515343822580f526e4c91a1723dab975f0ccb26..0d705e65f5ff658f216b5b563977e5867c5a2ce9 100644 (file)
@@ -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',
index e9d137de97ddbfb1bf1978d2d4d46feb79a65e85..c4aa1505c0269112ca52430a69ea5dacaa808654 100644 (file)
@@ -14,42 +14,6 @@ static void usage(void)
        printf("Usage: dns-tsig <dns-server-ip>\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;
index 7b499d6025cf2a856054cd25f07d6a7a5e0fdba6..74e44c77922463476d1c65a9f4897a54bea9a41d 100644 (file)
@@ -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',