summaryrefslogtreecommitdiff
path: root/source4/dns_server
diff options
context:
space:
mode:
authorKai Blin <kai@samba.org>2012-09-05 08:09:22 +0200
committerKai Blin <kai@samba.org>2012-09-05 08:41:24 +0200
commit140a8d86acd9fe1b00a2865552f16f6250280d32 (patch)
treefc8c5b988ce8b262e9478335a68a090e3ca67fcb /source4/dns_server
parent17c91b5db0363b61c5f41d62b1c8073e89b40f09 (diff)
downloadsamba-140a8d86acd9fe1b00a2865552f16f6250280d32.tar.gz
samba-140a8d86acd9fe1b00a2865552f16f6250280d32.tar.bz2
samba-140a8d86acd9fe1b00a2865552f16f6250280d32.zip
more tsig_verify stuff
Diffstat (limited to 'source4/dns_server')
-rw-r--r--source4/dns_server/dns_crypto.c30
-rw-r--r--source4/dns_server/dns_server.c2
-rw-r--r--source4/dns_server/dns_server.h3
3 files changed, 23 insertions, 12 deletions
diff --git a/source4/dns_server/dns_crypto.c b/source4/dns_server/dns_crypto.c
index 7a049c04ef..14dc4ca69b 100644
--- a/source4/dns_server/dns_crypto.c
+++ b/source4/dns_server/dns_crypto.c
@@ -91,16 +91,17 @@ struct dns_server_tkey *dns_find_tkey(struct dns_server_tkey_store *store,
WERROR dns_verify_tsig(struct dns_server *dns,
TALLOC_CTX *mem_ctx,
struct dns_request_state *state,
- struct dns_name_packet *packet)
+ struct dns_name_packet *packet,
+ DATA_BLOB *in)
{
WERROR werror;
NTSTATUS status;
enum ndr_err_code ndr_err;
bool found_tsig = false;
- uint16_t i;
- DATA_BLOB packet_blob, tsig_blob, sig;
+ uint16_t i, arcount = 0;
+ DATA_BLOB tsig_blob, fake_tsig_blob, sig;
uint8_t *buffer = NULL;
- size_t buffer_len = 0;
+ size_t buffer_len = 0, packet_len = 0;
struct dns_server_tkey *tkey = NULL;
struct dns_fake_tsig_rec *check_rec = talloc_zero(mem_ctx,
struct dns_fake_tsig_rec);
@@ -169,15 +170,15 @@ WERROR dns_verify_tsig(struct dns_server *dns,
check_rec->other_size = 0;
check_rec->other_data = NULL;
- ndr_err = ndr_push_struct_blob(&packet_blob, mem_ctx, packet,
- (ndr_push_flags_fn_t)ndr_push_dns_name_packet);
+ ndr_err = ndr_push_struct_blob(&tsig_blob, mem_ctx, state->tsig,
+ (ndr_push_flags_fn_t)ndr_push_dns_res_rec);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
DEBUG(1, ("Failed to push packet: %s!\n",
ndr_errstr(ndr_err)));
return DNS_ERR(SERVER_FAILURE);
}
- ndr_err = ndr_push_struct_blob(&tsig_blob, mem_ctx, check_rec,
+ ndr_err = ndr_push_struct_blob(&fake_tsig_blob, mem_ctx, check_rec,
(ndr_push_flags_fn_t)ndr_push_dns_fake_tsig_rec);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
DEBUG(1, ("Failed to push packet: %s!\n",
@@ -185,14 +186,17 @@ WERROR dns_verify_tsig(struct dns_server *dns,
return DNS_ERR(SERVER_FAILURE);
}
- buffer_len = packet_blob.length + tsig_blob.length;
+ /* we need to work some magic here. we need to keep the input packet
+ * exactly like we got it, but we need to cut off the tsig record */
+ packet_len = in->length - tsig_blob.length;
+ buffer_len = packet_len + fake_tsig_blob.length;
buffer = talloc_zero_array(mem_ctx, uint8_t, buffer_len);
if (buffer == NULL) {
return WERR_NOMEM;
}
- memcpy(buffer, packet_blob.data, packet_blob.length);
- memcpy(buffer, tsig_blob.data, tsig_blob.length);
+ memcpy(buffer, in->data, packet_len);
+ memcpy(buffer + packet_len, fake_tsig_blob.data, fake_tsig_blob.length);
sig.length = state->tsig->rdata.tsig_record.mac_size;
sig.data = talloc_memdup(mem_ctx, state->tsig->rdata.tsig_record.mac, sig.length);
@@ -200,6 +204,12 @@ WERROR dns_verify_tsig(struct dns_server *dns,
return WERR_NOMEM;
}
+ /*FIXME: Why is there too much padding? */
+ buffer_len -= 2;
+
+ /* Now we also need to count down the additional record counter */
+ arcount = RSVAL(buffer, 10);
+ RSSVAL(buffer, 10, arcount-1);
status = gensec_check_packet(tkey->gensec, buffer, buffer_len,
buffer, buffer_len, &sig);
diff --git a/source4/dns_server/dns_server.c b/source4/dns_server/dns_server.c
index 57c3b0134f..c5f516dd20 100644
--- a/source4/dns_server/dns_server.c
+++ b/source4/dns_server/dns_server.c
@@ -145,7 +145,7 @@ static struct tevent_req *dns_process_send(TALLOC_CTX *mem_ctx,
NDR_PRINT_DEBUG(dns_name_packet, &state->in_packet);
}
- ret = dns_verify_tsig(dns, state, &state->state, &state->in_packet);
+ ret = dns_verify_tsig(dns, state, &state->state, &state->in_packet, in);
if (!W_ERROR_IS_OK(ret)) {
DEBUG(0, ("Bailing out early!\n"));
state->dns_err = werr_to_dns_err(ret);
diff --git a/source4/dns_server/dns_server.h b/source4/dns_server/dns_server.h
index f807cd1536..ef85730ff8 100644
--- a/source4/dns_server/dns_server.h
+++ b/source4/dns_server/dns_server.h
@@ -112,7 +112,8 @@ struct dns_server_tkey *dns_find_tkey(struct dns_server_tkey_store *store,
WERROR dns_verify_tsig(struct dns_server *dns,
TALLOC_CTX *mem_ctx,
struct dns_request_state *state,
- struct dns_name_packet *packet);
+ struct dns_name_packet *packet,
+ DATA_BLOB *in);
WERROR dns_sign_tsig(struct dns_server *dns,
TALLOC_CTX *mem_ctx,
struct dns_request_state *state,