enum ndr_err_code ndr_err;
uint16_t dummy16;
uint32_t dummy32;
+ /*FIXME: Don't fake these, use ndr to convert the strings */
+ const char *fake_name = "\x4test";
+ const char *fake_alg = "\x8hmac-md5\7sig-alg\3reg\3int";
if (key == NULL) {
DEBUG(1, ("No key found, bailing out\n"));
/* Build up the MAC as per RFC2845 */
hmac_md5_init_rfc2104(key->data, key->length, ctx);
- /* 4.2 request MAC, if this is a reply */
+ /* 4.2 on replies, also hash the request MAC */
if (req_mac != NULL) {
hmac_md5_update(req_mac, req_mac_length, ctx);
}
hmac_md5_update(blob.data, blob.length, ctx);
/* 3.4.2 tsig variables */
- hmac_md5_update((const uint8_t *)tsig->name, strlen(tsig->name), ctx);
+ 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);
- hmac_md5_update((const uint8_t *)tsig->rdata.tsig_record.algorithm_name,
- strlen(tsig->rdata.tsig_record.algorithm_name), ctx);
+ 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);
return WERR_OK;
}
-
WERROR dns_verify_tsig(struct dns_server *dns,
struct dns_request_state *state,
struct dns_name_packet *packet)
return DNS_ERR(FORMAT_ERROR);
}
+ NDR_PRINT_DEBUG(dns_name_packet, packet);
/* We got a TSIG, so we need to sign our reply */
state->sign = true;
NULL, 0, &mac, &mac_length);
W_ERROR_NOT_OK_RETURN(werror);
- dump_data(1, mac, mac_length);
- state->tsig_error = DNS_RCODE_BADKEY;
- return DNS_ERR(NOTAUTH);
+
+ if (memcmp(state->tsig->rdata.tsig_record.mac, mac, mac_length) != 0) {
+ DEBUG(1, ("TSIG MAC mismatch\n"));
+ dump_data(1, state->tsig->rdata.tsig_record.mac,
+ state->tsig->rdata.tsig_record.mac_size);
+ dump_data(1, mac, mac_length);
+ state->tsig_error = DNS_RCODE_BADSIG;
+ return DNS_ERR(NOTAUTH);
+ }
+
+ /* FIXME: Do a time check here, too. */
+ return WERR_OK;
}
/*FIXME: calculate a real tsig here */
{
WERROR werror;
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);
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;
+ }
+
tsig->rr_class = DNS_QCLASS_ANY;
tsig->rr_type = DNS_QTYPE_TSIG;
tsig->ttl = 0;
tsig->rdata.tsig_record.other_size = 0;
tsig->rdata.tsig_record.other_data = NULL;
- /* And here's the part where we fake stuff */
- tsig->rdata.tsig_record.mac_size = 0;
- tsig->rdata.tsig_record.mac = NULL;
+ werror = dns_generate_tsig_mac(packet, key, packet, tsig,
+ state->tsig->rdata.tsig_record.mac,
+ state->tsig->rdata.tsig_record.mac_size,
+ &mac, &mac_size);
+ W_ERROR_NOT_OK_RETURN(werror);
+ tsig->rdata.tsig_record.mac_size = mac_size;
+ tsig->rdata.tsig_record.mac = mac;
if (packet->arcount == 0) {
packet->additional = talloc_zero(packet, struct dns_res_rec);
return packet;
}
+static char *dns_get_string_wire_format(TALLOC_CTX *mem_ctx, const char* string)
+{
+ DATA_BLOB blob;
+ char *wire_format;
+ enum ndr_err_code ndr_err;
+
+ ndr_err = ndr_push_struct_blob(&blob, mem_ctx, string,
+ (ndr_push_flags_fn_t)ndr_push_dns_string);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return NULL;
+ }
+
+ wire_format = talloc_strdup(mem_ctx, blob.data);
+ dump_data(1, wire_format, strlen(wire_format) + 1);
+ 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,
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"));
/* Build up the MAC as per RFC2845 */
hmac_md5_init_rfc2104(key->data, key->length, ctx);
- dump_data(1, blob.data, blob.length);
-
/* 3.4.1 dns message */
hmac_md5_update(blob.data, blob.length, ctx);
/* 3.4.2 tsig variables */
- dump_data(1, tsig->name, strlen(tsig->name)+1);
- hmac_md5_update((const uint8_t *)tsig->name, strlen(tsig->name)+1, ctx);
+ 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);
- dump_data(1, tsig->rdata.tsig_record.algorithm_name,
- strlen(tsig->rdata.tsig_record.algorithm_name)+1);
- hmac_md5_update((const uint8_t *)tsig->rdata.tsig_record.algorithm_name,
- strlen(tsig->rdata.tsig_record.algorithm_name)+1, 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);
struct dns_res_rec *tsig = talloc_zero(packet, struct dns_res_rec);
W_ERROR_HAVE_NO_MEMORY(tsig);
- tsig->name = talloc_strdup(tsig, "\x4test");
+ tsig->name = talloc_strdup(tsig, "test");
W_ERROR_HAVE_NO_MEMORY(tsig->name);
tsig->rr_class = DNS_QCLASS_ANY;
tsig->ttl = 0;
tsig->length = UINT16_MAX;
tsig->rdata.tsig_record.algorithm_name = talloc_strdup(tsig,
- "\x8hmac-md5\x7sig-alg\x3reg\x3int");
+ "hmac-md5.sig-alg.reg.int");
tsig->rdata.tsig_record.time_prefix = 0;
tsig->rdata.tsig_record.time = 0x4f74260d;
tsig->rdata.tsig_record.fudge = 300;
werror = dns_generate_tsig_mac(mem_ctx, key, packet, tsig,
&mac, &mac_length);
-
- /* And here's the part where we fake stuff */
- fake_mac = talloc_zero_size(tsig, 16);
- fake_mac[0] = 0xc9;
- fake_mac[1] = 0x49;
- fake_mac[2] = 0xcd;
- fake_mac[3] = 0x39;
- fake_mac[4] = 0xf5;
- fake_mac[5] = 0xf5;
- fake_mac[6] = 0x9d;
- fake_mac[7] = 0xfa;
- fake_mac[8] = 0x73;
- fake_mac[9] = 0xc6;
- fake_mac[10] = 0xfe;
- fake_mac[11] = 0x42;
- fake_mac[12] = 0x12;
- fake_mac[13] = 0x8c;
- fake_mac[14] = 0xf1;
- fake_mac[15] = 0xfa;
- tsig->rdata.tsig_record.mac_size = 16;
- tsig->rdata.tsig_record.mac = fake_mac;
-
- dump_data(1, mac, mac_length);
- dump_data(1, fake_mac, 16);
+ 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);
DATA_BLOB out, in;
int ret = 0;
-#if 0
if (argc < 2) {
usage();
exit(1);
}
-#endif
ev = tevent_context_init(mem_ctx);
setup_logging("samba-dig", DEBUG_STDERR);
key = talloc_zero(mem_ctx, struct dns_server_key);
key->name = talloc_strdup(key, "test");
- /* FIXME: 12??? */
key->length = 12;
key->data = talloc_zero_size(key, key->length);
sign_tsig(mem_ctx, key, dns_packet);
-#if 1
NDR_PRINT_DEBUG(dns_name_packet, dns_packet);
ndr_err = ndr_push_struct_blob(&out, mem_ctx, dns_packet,
(ndr_push_flags_fn_t)ndr_push_dns_name_packet);
}
dump_data(1, out.data, out.length);
-#endif
+ req = dns_udp_request_send(mem_ctx, ev, argv[1], out.data, out.length);
+ if (req == NULL) {
+ DEBUG(0, ("Failed to allocate memory for tevent_req\n"));
+ ret = 1;
+ goto error;
+ }
+ if (!tevent_req_poll(req, ev)) {
+ DEBUG(0, ("Error sending dns request\n"));
+ ret = 1;
+ goto error;
+ }
+ w_err = dns_udp_request_recv(req, mem_ctx, &in.data, &in.length);
+ if (!W_ERROR_IS_OK(w_err)) {
+ DEBUG(0, ("Error receiving dns request: %s\n", win_errstr(w_err)));
+ ret = 1;
+ goto error;
+ }
+
+ in_packet = talloc(mem_ctx, struct dns_name_packet);
+
+ ndr_err = ndr_pull_struct_blob(&in, in_packet, in_packet,
+ (ndr_pull_flags_fn_t)ndr_pull_dns_name_packet);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(0, ("Failed to unmarshall dns_name_packet: %d\n", ndr_err));
+ ret = 1;
+ goto error;
+ }
+
+ NDR_PRINT_DEBUG(dns_name_packet, in_packet);
error:
return ret;