Changeset 989 for vendor/current/source4/dns_server
- Timestamp:
- Nov 25, 2016, 8:04:54 PM (9 years ago)
- Location:
- vendor/current/source4/dns_server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/dns_server/dns_crypto.c
r988 r989 147 147 tkey = dns_find_tkey(dns->tkeys, state->tsig->name); 148 148 if (tkey == NULL) { 149 /* 150 * We must save the name for use in the TSIG error 151 * response and have no choice here but to save the 152 * keyname from the TSIG request. 153 */ 154 state->key_name = talloc_strdup(state->mem_ctx, 155 state->tsig->name); 156 if (state->key_name == NULL) { 157 return WERR_NOMEM; 158 } 149 159 state->tsig_error = DNS_RCODE_BADKEY; 150 160 return DNS_ERR(NOTAUTH); 161 } 162 163 /* 164 * Remember the keyname that found an existing tkey, used 165 * later to fetch the key with dns_find_tkey() when signing 166 * and adding a TSIG record with MAC. 167 */ 168 state->key_name = talloc_strdup(state->mem_ctx, tkey->name); 169 if (state->key_name == NULL) { 170 return WERR_NOMEM; 151 171 } 152 172 … … 208 228 } 209 229 210 /*FIXME: Why is there too much padding? */211 buffer_len -= 2;212 213 230 /* Now we also need to count down the additional record counter */ 214 231 arcount = RSVAL(buffer, 10); … … 218 235 buffer, buffer_len, &sig); 219 236 if (NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) { 220 return DNS_ERR(BADKEY); 237 state->tsig_error = DNS_RCODE_BADSIG; 238 return DNS_ERR(NOTAUTH); 221 239 } 222 240 … … 227 245 228 246 state->authenticated = true; 229 state->key_name = talloc_strdup(state->mem_ctx, tkey->name); 230 if (state->key_name == NULL) { 231 return WERR_NOMEM; 232 } 233 247 248 return WERR_OK; 249 } 250 251 static WERROR dns_tsig_compute_mac(TALLOC_CTX *mem_ctx, 252 struct dns_request_state *state, 253 struct dns_name_packet *packet, 254 struct dns_server_tkey *tkey, 255 time_t current_time, 256 DATA_BLOB *_psig) 257 { 258 NTSTATUS status; 259 enum ndr_err_code ndr_err; 260 DATA_BLOB packet_blob, tsig_blob, sig; 261 uint8_t *buffer = NULL; 262 uint8_t *p = NULL; 263 size_t buffer_len = 0; 264 struct dns_fake_tsig_rec *check_rec = talloc_zero(mem_ctx, 265 struct dns_fake_tsig_rec); 266 size_t mac_size = 0; 267 268 if (check_rec == NULL) { 269 return WERR_NOMEM; 270 } 271 272 /* first build and verify check packet */ 273 check_rec->name = talloc_strdup(check_rec, tkey->name); 274 if (check_rec->name == NULL) { 275 return WERR_NOMEM; 276 } 277 check_rec->rr_class = DNS_QCLASS_ANY; 278 check_rec->ttl = 0; 279 check_rec->algorithm_name = talloc_strdup(check_rec, tkey->algorithm); 280 if (check_rec->algorithm_name == NULL) { 281 return WERR_NOMEM; 282 } 283 check_rec->time_prefix = 0; 284 check_rec->time = current_time; 285 check_rec->fudge = 300; 286 check_rec->error = state->tsig_error; 287 check_rec->other_size = 0; 288 check_rec->other_data = NULL; 289 290 ndr_err = ndr_push_struct_blob(&packet_blob, mem_ctx, packet, 291 (ndr_push_flags_fn_t)ndr_push_dns_name_packet); 292 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 293 DEBUG(1, ("Failed to push packet: %s!\n", 294 ndr_errstr(ndr_err))); 295 return DNS_ERR(SERVER_FAILURE); 296 } 297 298 ndr_err = ndr_push_struct_blob(&tsig_blob, mem_ctx, check_rec, 299 (ndr_push_flags_fn_t)ndr_push_dns_fake_tsig_rec); 300 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 301 DEBUG(1, ("Failed to push packet: %s!\n", 302 ndr_errstr(ndr_err))); 303 return DNS_ERR(SERVER_FAILURE); 304 } 305 306 if (state->tsig != NULL) { 307 mac_size = state->tsig->rdata.tsig_record.mac_size; 308 } 309 310 buffer_len = mac_size; 311 312 buffer_len += packet_blob.length; 313 if (buffer_len < packet_blob.length) { 314 return WERR_INVALID_PARAM; 315 } 316 buffer_len += tsig_blob.length; 317 if (buffer_len < tsig_blob.length) { 318 return WERR_INVALID_PARAM; 319 } 320 321 buffer = talloc_zero_array(mem_ctx, uint8_t, buffer_len); 322 if (buffer == NULL) { 323 return WERR_NOMEM; 324 } 325 326 p = buffer; 327 328 /* 329 * RFC 2845 "4.2 TSIG on Answers", how to lay out the buffer 330 * that we're going to sign: 331 * 1. MAC of request (if present) 332 * 2. Outgoing packet 333 * 3. TSIG record 334 */ 335 if (mac_size > 0) { 336 memcpy(p, state->tsig->rdata.tsig_record.mac, mac_size); 337 p += mac_size; 338 } 339 340 memcpy(p, packet_blob.data, packet_blob.length); 341 p += packet_blob.length; 342 343 memcpy(p, tsig_blob.data, tsig_blob.length); 344 345 status = gensec_sign_packet(tkey->gensec, mem_ctx, buffer, buffer_len, 346 buffer, buffer_len, &sig); 347 if (!NT_STATUS_IS_OK(status)) { 348 return ntstatus_to_werror(status); 349 } 350 351 *_psig = sig; 234 352 return WERR_OK; 235 353 } … … 242 360 { 243 361 WERROR werror; 244 NTSTATUS status;245 enum ndr_err_code ndr_err;246 362 time_t current_time = time(NULL); 247 DATA_BLOB packet_blob, tsig_blob, sig; 248 uint8_t *buffer = NULL; 249 size_t buffer_len = 0; 250 struct dns_server_tkey * tkey = NULL; 251 struct dns_res_rec *tsig = talloc_zero(mem_ctx, struct dns_res_rec); 252 253 struct dns_fake_tsig_rec *check_rec = talloc_zero(mem_ctx, 254 struct dns_fake_tsig_rec); 255 363 struct dns_res_rec *tsig = NULL; 364 DATA_BLOB sig = (DATA_BLOB) { 365 .data = NULL, 366 .length = 0 367 }; 368 369 tsig = talloc_zero(mem_ctx, struct dns_res_rec); 256 370 if (tsig == NULL) { 257 371 return WERR_NOMEM; 258 372 } 259 373 260 if (check_rec == NULL) { 261 return WERR_NOMEM; 262 } 263 264 tkey = dns_find_tkey(dns->tkeys, state->key_name); 265 if (tkey == NULL) { 266 /* FIXME: read up on what to do when we can't find a key */ 267 return WERR_OK; 268 } 269 270 /* first build and verify check packet */ 271 check_rec->name = talloc_strdup(check_rec, tkey->name); 272 if (check_rec->name == NULL) { 273 return WERR_NOMEM; 274 } 275 check_rec->rr_class = DNS_QCLASS_ANY; 276 check_rec->ttl = 0; 277 check_rec->algorithm_name = talloc_strdup(check_rec, tkey->algorithm); 278 if (check_rec->algorithm_name == NULL) { 279 return WERR_NOMEM; 280 } 281 check_rec->time_prefix = 0; 282 check_rec->time = current_time; 283 check_rec->fudge = 300; 284 check_rec->error = state->tsig_error; 285 check_rec->other_size = 0; 286 check_rec->other_data = NULL; 287 288 ndr_err = ndr_push_struct_blob(&packet_blob, mem_ctx, packet, 289 (ndr_push_flags_fn_t)ndr_push_dns_name_packet); 290 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 291 DEBUG(1, ("Failed to push packet: %s!\n", 292 ndr_errstr(ndr_err))); 293 return DNS_ERR(SERVER_FAILURE); 294 } 295 296 ndr_err = ndr_push_struct_blob(&tsig_blob, mem_ctx, check_rec, 297 (ndr_push_flags_fn_t)ndr_push_dns_fake_tsig_rec); 298 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 299 DEBUG(1, ("Failed to push packet: %s!\n", 300 ndr_errstr(ndr_err))); 301 return DNS_ERR(SERVER_FAILURE); 302 } 303 304 buffer_len = packet_blob.length + tsig_blob.length; 305 buffer = talloc_zero_array(mem_ctx, uint8_t, buffer_len); 306 if (buffer == NULL) { 307 return WERR_NOMEM; 308 } 309 310 memcpy(buffer, packet_blob.data, packet_blob.length); 311 memcpy(buffer+packet_blob.length, tsig_blob.data, tsig_blob.length); 312 313 314 status = gensec_sign_packet(tkey->gensec, mem_ctx, buffer, buffer_len, 315 buffer, buffer_len, &sig); 316 if (!NT_STATUS_IS_OK(status)) { 317 return ntstatus_to_werror(status); 318 } 319 320 tsig->name = talloc_strdup(tsig, check_rec->name); 374 if (state->tsig_error == DNS_RCODE_OK) { 375 struct dns_server_tkey *tkey = dns_find_tkey( 376 dns->tkeys, state->key_name); 377 if (tkey == NULL) { 378 return DNS_ERR(SERVER_FAILURE); 379 } 380 381 werror = dns_tsig_compute_mac(mem_ctx, state, packet, 382 tkey, current_time, &sig); 383 if (!W_ERROR_IS_OK(werror)) { 384 return werror; 385 } 386 } 387 388 tsig->name = talloc_strdup(tsig, state->key_name); 321 389 if (tsig->name == NULL) { 322 390 return WERR_NOMEM; 323 391 } 324 tsig->rr_class = check_rec->rr_class;392 tsig->rr_class = DNS_QCLASS_ANY; 325 393 tsig->rr_type = DNS_QTYPE_TSIG; 326 394 tsig->ttl = 0; 327 395 tsig->length = UINT16_MAX; 328 tsig->rdata.tsig_record.algorithm_name = talloc_strdup(tsig, 329 check_rec->algorithm_name); 330 tsig->rdata.tsig_record.time_prefix = check_rec->time_prefix; 331 tsig->rdata.tsig_record.time = check_rec->time; 332 tsig->rdata.tsig_record.fudge = check_rec->fudge; 396 tsig->rdata.tsig_record.algorithm_name = talloc_strdup(tsig, "gss-tsig"); 397 tsig->rdata.tsig_record.time_prefix = 0; 398 tsig->rdata.tsig_record.time = current_time; 399 tsig->rdata.tsig_record.fudge = 300; 333 400 tsig->rdata.tsig_record.error = state->tsig_error; 334 401 tsig->rdata.tsig_record.original_id = packet->id; 335 402 tsig->rdata.tsig_record.other_size = 0; 336 403 tsig->rdata.tsig_record.other_data = NULL; 337 tsig->rdata.tsig_record.mac_size = sig.length; 338 tsig->rdata.tsig_record.mac = talloc_memdup(tsig, sig.data, sig.length); 339 404 if (sig.length > 0) { 405 tsig->rdata.tsig_record.mac_size = sig.length; 406 tsig->rdata.tsig_record.mac = talloc_memdup(tsig, sig.data, sig.length); 407 } 340 408 341 409 if (packet->arcount == 0) { -
vendor/current/source4/dns_server/dns_server.c
r988 r989 153 153 } 154 154 155 ret = dns_verify_tsig(dns, state, &state->state, &state->in_packet, in);156 if (!W_ERROR_IS_OK(ret)) {157 DEBUG(1, ("Failed to verify TSIG!\n"));158 state->dns_err = werr_to_dns_err(ret);159 tevent_req_done(req);160 return tevent_req_post(req, ev);161 }162 163 155 if (state->in_packet.operation & DNS_FLAG_REPLY) { 164 156 DEBUG(1, ("Won't reply to replies.\n")); … … 176 168 177 169 state->out_packet = state->in_packet; 170 171 ret = dns_verify_tsig(dns, state, &state->state, &state->out_packet, in); 172 if (!W_ERROR_IS_OK(ret)) { 173 state->dns_err = werr_to_dns_err(ret); 174 tevent_req_done(req); 175 return tevent_req_post(req, ev); 176 } 178 177 179 178 switch (state->in_packet.operation & DNS_OPCODE) { … … 237 236 } 238 237 if ((state->dns_err != DNS_RCODE_OK) && 239 (state->dns_err != DNS_RCODE_NXDOMAIN)) { 238 (state->dns_err != DNS_RCODE_NXDOMAIN) && 239 (state->dns_err != DNS_RCODE_NOTAUTH)) 240 { 240 241 goto drop; 241 242 }
Note:
See TracChangeset
for help on using the changeset viewer.