1 /* srp-parse.c 2 * 3 * Copyright (c) 2018-2022 Apple Inc. All rights reserved. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * https://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 * This file contains support routines for the DNSSD SRP update and mDNS proxies. 18 */ 19 20 #include <stdlib.h> 21 #include <string.h> 22 #include <stdio.h> 23 #include <unistd.h> 24 #include <errno.h> 25 #include <sys/socket.h> 26 #include <netinet/in.h> 27 #include <arpa/inet.h> 28 #include <fcntl.h> 29 #include <sys/time.h> 30 #include <dns_sd.h> 31 #include <inttypes.h> 32 33 #include "srp.h" 34 #include "dns-msg.h" 35 #include "srp-crypto.h" 36 #include "ioloop.h" 37 #include "srp-gw.h" 38 #include "config-parse.h" 39 #include "srp-proxy.h" 40 #include "cti-services.h" 41 #include "srp-mdns-proxy.h" 42 #include "dnssd-proxy.h" 43 #include "srp-replication.h" 44 45 46 static dns_name_t *service_update_zone; // The zone to update when we receive an update for default.service.arpa. 47 48 // Free the data structures into which the SRP update was parsed. The pointers to the various DNS objects that these 49 // structures point to are owned by the parsed DNS message, and so these do not need to be freed here. 50 void 51 srp_parse_client_updates_free_(client_update_t *messages, const char *file, int line) 52 { 53 client_update_t *message = messages; 54 while (message) { 55 INFO("%p at " PUB_S_SRP ":%d", message, file, line); 56 client_update_t *next_message = message->next; 57 58 for (service_instance_t *sip = message->instances; sip; ) { 59 service_instance_t *next = sip->next; 60 free(sip); 61 sip = next; 62 } 63 for (service_t *sp = message->services; sp; ) { 64 service_t *next = sp->next; 65 free(sp); 66 sp = next; 67 } 68 for (delete_t *dp = message->removes; dp != NULL; ) { 69 delete_t *next = dp->next; 70 free(dp); 71 dp = next; 72 } 73 if (message->host != NULL) { 74 host_addr_t *host_addr, *next; 75 for (host_addr = message->host->addrs; host_addr; host_addr = next) { 76 next = host_addr->next; 77 free(host_addr); 78 } 79 free(message->host); 80 } 81 if (message->parsed_message != NULL) { 82 dns_message_free(message->parsed_message); 83 } 84 if (message->message != NULL) { 85 ioloop_message_release(message->message); 86 } 87 #if SRP_FEATURE_REPLICATION 88 if (message->srpl_connection != NULL) { 89 srpl_connection_release(message->srpl_connection); 90 message->srpl_connection = NULL; 91 } 92 #endif 93 if (message->connection != NULL) { 94 ioloop_comm_release(message->connection); 95 message->connection = NULL; 96 } 97 free(message); 98 message = next_message; 99 } 100 } 101 102 static bool 103 add_host_addr(host_addr_t **dest, dns_rr_t *rr) 104 { 105 host_addr_t *addr = calloc(1, sizeof *addr); 106 if (addr == NULL) { 107 ERROR("add_host_addr: no memory for record"); 108 return false; 109 } 110 111 while (*dest) { 112 dest = &(*dest)->next; 113 } 114 *dest = addr; 115 addr->rr = *rr; 116 return true; 117 } 118 119 static bool 120 replace_zone_name(dns_name_t **nzp_in, dns_name_t *uzp, dns_name_t *replacement_zone) 121 { 122 dns_name_t **nzp = nzp_in; 123 while (*nzp != NULL && *nzp != uzp) { 124 nzp = &((*nzp)->next); 125 } 126 if (*nzp == NULL) { 127 ERROR("replace_zone: dns_name_subdomain_of returned bogus pointer."); 128 return false; 129 } 130 131 // Free the suffix we're replacing 132 dns_name_free(*nzp); 133 134 // Replace it. 135 *nzp = dns_name_copy(replacement_zone); 136 if (*nzp == NULL) { 137 ERROR("replace_zone_name: no memory for replacement zone"); 138 return false; 139 } 140 return true; 141 } 142 143 // We call advertise_finished when a client request has finished, successfully or otherwise. 144 static void 145 send_fail_response(comm_t *connection, message_t *message, int rcode) 146 { 147 struct iovec iov; 148 dns_wire_t response; 149 150 INFO("rcode = " PUB_S_SRP, dns_rcode_name(rcode)); 151 memset(&response, 0, DNS_HEADER_SIZE); 152 response.id = message->wire.id; 153 response.bitfield = message->wire.bitfield; 154 dns_rcode_set(&response, rcode); 155 dns_qr_set(&response, dns_qr_response); 156 157 iov.iov_base = &response; 158 iov.iov_len = DNS_HEADER_SIZE; 159 160 ioloop_send_message(connection, message, &iov, 1); 161 } 162 163 static int 164 make_delete(delete_t **delete_list, delete_t **delete_out, dns_rr_t *rr, dns_name_t *update_zone) 165 { 166 int status = dns_rcode_noerror; 167 delete_t *dp, **dpp; 168 169 for (dpp = delete_list; *dpp;) { 170 dp = *dpp; 171 if (dns_names_equal(dp->name, rr->name)) { 172 DNS_NAME_GEN_SRP(rr->name, name_buf); 173 ERROR("two deletes for the same name: " PRI_DNS_NAME_SRP, 174 DNS_NAME_PARAM_SRP(rr->name, name_buf)); 175 return dns_rcode_formerr; 176 } 177 dpp = &dp->next; 178 } 179 dp = calloc(1, sizeof *dp); 180 if (!dp) { 181 ERROR("no memory."); 182 return dns_rcode_servfail; 183 } 184 // Add to the deletes list 185 *dpp = dp; 186 187 // Make sure the name is a subdomain of the zone being updated. 188 dp->zone = dns_name_subdomain_of(rr->name, update_zone); 189 if (dp->zone == NULL) { 190 DNS_NAME_GEN_SRP(update_zone, update_zone_buf); 191 DNS_NAME_GEN_SRP(rr->name, name_buf); 192 ERROR("delete for record not in update zone " PRI_DNS_NAME_SRP ": " PRI_DNS_NAME_SRP, 193 DNS_NAME_PARAM_SRP(update_zone, update_zone_buf), DNS_NAME_PARAM_SRP(rr->name, name_buf)); 194 status = dns_rcode_formerr; 195 goto out; 196 } 197 dp->name = rr->name; 198 if (delete_out != NULL) { 199 *delete_out = dp; 200 } 201 out: 202 if (status != dns_rcode_noerror) { 203 free(dp); 204 } 205 return status; 206 } 207 208 // Find a delete in the delete list that has target as its target. 209 static delete_t * 210 srp_find_delete(delete_t *deletes, dns_rr_t *target) 211 { 212 for (delete_t *dp = deletes; dp; dp = dp->next) { 213 if (dns_names_equal(dp->name, target->name)) { 214 return dp; 215 } 216 } 217 return NULL; 218 } 219 220 static bool 221 srp_parse_lease_times(dns_message_t *message, uint32_t *r_lease, uint32_t *r_key_lease) 222 { 223 // Get the lease time. We need this to differentiate between a mass host deletion and an add. 224 uint32_t lease_time = 3600; 225 uint32_t key_lease_time = 604800; 226 bool found_lease = false; 227 for (dns_edns0_t *edns0 = message->edns0; edns0; edns0 = edns0->next) { 228 if (edns0->type == dns_opt_update_lease) { 229 unsigned off = 0; 230 if (edns0->length != 4 && edns0->length != 8) { 231 ERROR("edns0 update-lease option length bogus: %d", edns0->length); 232 return false; 233 } 234 dns_u32_parse(edns0->data, edns0->length, &off, &lease_time); 235 if (edns0->length == 8) { 236 dns_u32_parse(edns0->data, edns0->length, &off, &key_lease_time); 237 } else { 238 key_lease_time = 7 * lease_time; 239 } 240 found_lease = true; 241 } 242 } 243 244 // Update-lease option is required for SRP. 245 if (!found_lease) { 246 ERROR("no update-lease edns0 option found in supposed SRP update"); 247 return false; 248 } 249 *r_lease = lease_time; 250 *r_key_lease = key_lease_time; 251 return true; 252 } 253 254 client_update_t * 255 srp_evaluate(const char *remote_name, dns_message_t **in_parsed_message, message_t *raw_message, int index) 256 { 257 unsigned i; 258 dns_host_description_t *host_description = NULL; 259 delete_t *deletes = NULL, *dp, **dpp = NULL, **rpp = NULL, *removes = NULL; 260 service_instance_t *service_instances = NULL, *sip, **sipp = &service_instances; 261 service_t *services = NULL, *sp, **spp = &services; 262 dns_rr_t *signature; 263 struct timeval now; 264 dns_name_t *update_zone = NULL, *replacement_zone = NULL; 265 dns_name_t *uzp; 266 dns_rr_t *key = NULL; 267 dns_rr_t **keys = NULL; 268 unsigned num_keys = 0; 269 unsigned max_keys = 1; 270 bool found_key = false; 271 #if SRP_PARSE_DEBUG_VERBOSE 272 char namebuf2[DNS_MAX_NAME_SIZE]; 273 #endif 274 dns_message_t *message; 275 276 277 client_update_t *ret = calloc(1, sizeof(*ret)); 278 if (ret == NULL) { 279 ERROR("no memory for client update"); 280 return NULL; 281 } 282 283 ret->drop = false; 284 ret->rcode = dns_rcode_servfail; 285 286 if (in_parsed_message != NULL) { 287 ret->parsed_message = *in_parsed_message; 288 *in_parsed_message = NULL; 289 } else { 290 // Parse the UPDATE message. 291 if (!dns_wire_parse(&ret->parsed_message, &raw_message->wire, raw_message->length, false)) { 292 ERROR("dns_wire_parse failed."); 293 goto out; 294 } 295 } 296 ret->message = raw_message; 297 RETAIN_HERE(ret->message, message); 298 message = ret->parsed_message; // For brevity 299 300 if (!srp_parse_lease_times(ret->parsed_message, &ret->host_lease, &ret->key_lease)) { 301 ret->rcode = dns_rcode_formerr; 302 goto out; 303 } 304 305 // Update requires a single SOA record as the question 306 if (message->qdcount != 1) { 307 ERROR("update received with qdcount > 1"); 308 ret->rcode = dns_rcode_formerr; 309 return ret; 310 } 311 312 // Update should contain zero answers. 313 if (message->ancount != 0) { 314 ERROR("update received with ancount > 0"); 315 ret->rcode = dns_rcode_formerr; 316 return ret; 317 } 318 319 if (message->questions[0].type != dns_rrtype_soa) { 320 ERROR("update received with rrtype %d instead of SOA in question section.", 321 message->questions[0].type); 322 ret->rcode = dns_rcode_formerr; 323 return ret; 324 } 325 326 if (remote_name == NULL) { 327 raw_message->received_time = srp_time(); 328 } 329 330 update_zone = message->questions[0].name; 331 if (service_update_zone != NULL && dns_names_equal_text(update_zone, "default.service.arpa.")) { 332 #if SRP_PARSE_DEBUG_VERBOSE 333 INFO(PRI_S_SRP " is in default.service.arpa, using replacement zone: " PUB_S_SRP, 334 dns_name_print(update_zone, namebuf2, sizeof(namebuf2)), 335 dns_name_print(service_update_zone, namebuf1, sizeof(namebuf1))); 336 #endif 337 replacement_zone = service_update_zone; 338 } else { 339 #if SRP_PARSE_DEBUG_VERBOSE 340 INFO(PRI_S_SRP " is not in default.service.arpa, or no replacement zone (%p)", 341 dns_name_print(update_zone, namebuf2, sizeof(namebuf2)), service_update_zone); 342 #endif 343 replacement_zone = NULL; 344 } 345 346 // Scan over the authority RRs; do the delete consistency check. We can't do other consistency checks 347 // because we can't assume a particular order to the records other than that deletes have to come before 348 // adds. 349 for (i = 0; i < message->nscount; i++) { 350 dns_rr_t *rr = &message->authority[i]; 351 352 // If this is a delete for all the RRs on a name, record it in the list of deletes. 353 if (rr->type == dns_rrtype_any && rr->qclass == dns_qclass_any && rr->ttl == 0) { 354 int status = make_delete(&deletes, NULL, rr, update_zone); 355 if (status != dns_rcode_noerror) { 356 ret->rcode = status; 357 goto out; 358 } 359 } 360 361 // The update should really only contain one key, but it's allowed for keys to appear on 362 // service instance names as well, since that's what will be stored in the zone. So if 363 // we get one key, we'll assume it's a host key until we're done scanning, and then check. 364 // If we get more than one, we allocate a buffer and store all the keys so that we can 365 // check them all later. 366 else if (rr->type == dns_rrtype_key) { 367 if (num_keys < 1) { 368 key = rr; 369 num_keys++; 370 } else { 371 if (num_keys == 1) { 372 // We can't have more keys than there are authority records left, plus 373 // one for the key we already have, so allocate a buffer that large. 374 max_keys = message->nscount - i + 1; 375 keys = calloc(max_keys, sizeof *keys); 376 if (keys == NULL) { 377 ERROR("no memory"); 378 goto out; 379 } 380 keys[0] = key; 381 } 382 if (num_keys >= max_keys) { 383 ERROR("coding error in key allocation"); 384 goto out; 385 } 386 keys[num_keys++] = rr; 387 } 388 } 389 390 // Otherwise if it's an A or AAAA record, it's part of a hostname entry. 391 else if (rr->type == dns_rrtype_a || rr->type == dns_rrtype_aaaa) { 392 // Allocate the hostname record 393 if (!host_description) { 394 host_description = calloc(1, sizeof *host_description); 395 if (!host_description) { 396 ERROR("no memory"); 397 goto out; 398 } 399 } 400 401 // Make sure it's preceded by a deletion of all the RRs on the name. 402 if (!host_description->delete) { 403 dp = srp_find_delete(deletes, rr); 404 if (dp == NULL) { 405 DNS_NAME_GEN_SRP(rr->name, name_buf); 406 ERROR("ADD for hostname " PRI_DNS_NAME_SRP " without a preceding delete.", 407 DNS_NAME_PARAM_SRP(rr->name, name_buf)); 408 ret->rcode = dns_rcode_formerr; 409 goto out; 410 } 411 host_description->delete = dp; 412 host_description->name = dp->name; 413 dp->consumed = true; // This delete is accounted for. 414 415 // In principle, we should be checking this name to see that it's a subdomain of the update 416 // zone. However, it turns out we don't need to, because the /delete/ has to be a subdomain 417 // of the update zone, and we won't find that delete if it's not present. 418 } 419 420 if (rr->type == dns_rrtype_a || rr->type == dns_rrtype_aaaa) { 421 if (!add_host_addr(&host_description->addrs, rr)) { 422 goto out; 423 } 424 } 425 } 426 427 // Otherwise if it's an SRV entry, that should be a service instance name. 428 else if (rr->type == dns_rrtype_srv || rr->type == dns_rrtype_txt) { 429 // Should be a delete that precedes this service instance. 430 dp = srp_find_delete(deletes, rr); 431 if (dp == NULL) { 432 DNS_NAME_GEN_SRP(rr->name, name_buf); 433 ERROR("ADD for service instance not preceded by delete: " PRI_DNS_NAME_SRP, 434 DNS_NAME_PARAM_SRP(rr->name, name_buf)); 435 ret->rcode = dns_rcode_formerr; 436 goto out; 437 } 438 for (sip = service_instances; sip; sip = sip->next) { 439 if (dns_names_equal(sip->name, rr->name)) { 440 break; 441 } 442 } 443 if (!sip) { 444 sip = calloc(1, sizeof *sip); 445 if (sip == NULL) { 446 ERROR("no memory"); 447 goto out; 448 } 449 sip->delete = dp; 450 dp->consumed = true; 451 sip->name = dp->name; 452 // Add to the service instances list 453 *sipp = sip; 454 sipp = &sip->next; 455 } 456 if (rr->type == dns_rrtype_srv) { 457 if (sip->srv != NULL) { 458 DNS_NAME_GEN_SRP(rr->name, name_buf); 459 ERROR("more than one SRV rr received for service instance: " PRI_DNS_NAME_SRP, 460 DNS_NAME_PARAM_SRP(rr->name, name_buf)); 461 ret->rcode = dns_rcode_formerr; 462 goto out; 463 } 464 sip->srv = rr; 465 } else if (rr->type == dns_rrtype_txt) { 466 if (sip->txt != NULL) { 467 DNS_NAME_GEN_SRP(rr->name, name_buf); 468 ERROR("more than one TXT rr received for service instance: " PRI_DNS_NAME_SRP, 469 DNS_NAME_PARAM_SRP(rr->name, name_buf)); 470 ret->rcode = dns_rcode_formerr; 471 goto out; 472 } 473 sip->txt = rr; 474 } 475 } 476 477 // Otherwise if it's a PTR entry, that should be a service name 478 else if (rr->type == dns_rrtype_ptr) { 479 service_t *base_type = NULL; 480 481 // See if the service is a subtype. If it is, it should be preceded in the list of RRs in 482 // the update by a PTR record for the base service type. E.g., if there is a PTR for 483 // _foo._sub._ipps._tcp.default.service.arpa, there should, earlier in the SRP update, 484 // be a PTR for _ipps._tcp.default.service.arpa. Both the base type and the subtype PTR 485 // records must have the same target. 486 if (rr->name != NULL && 487 rr->name->next != NULL && rr->name->next->next != NULL && !strcmp(rr->name->next->data, "_sub")) 488 { 489 dns_name_t *base_type_name = rr->name->next->next; 490 for (base_type = services; base_type != NULL; base_type = base_type->next) { 491 if (!dns_names_equal(base_type->rr->data.ptr.name, rr->data.ptr.name)) { 492 continue; 493 } 494 if (dns_names_equal(base_type->rr->name, base_type_name)) { 495 break; 496 } 497 } 498 if (base_type == NULL) { 499 DNS_NAME_GEN_SRP(rr->name, name_buf); 500 DNS_NAME_GEN_SRP(rr->data.ptr.name, target_name_buf); 501 ERROR("service subtype " PRI_DNS_NAME_SRP " for " PRI_DNS_NAME_SRP 502 " has no preceding base type ", DNS_NAME_PARAM_SRP(rr->name, name_buf), 503 DNS_NAME_PARAM_SRP(rr->data.ptr.name, target_name_buf)); 504 ret->rcode = dns_rcode_formerr; 505 goto out; 506 } 507 } 508 509 // If qclass is none and ttl is zero, this is a delete specific RR from RRset, not an add RR to RRset. 510 if (rr->qclass == dns_qclass_none && rr->ttl == 0) { 511 int status = make_delete(&deletes, &dp, rr, update_zone); 512 if (status != dns_rcode_noerror) { 513 ret->rcode = status; 514 goto out; 515 } 516 } else { 517 sp = calloc(1, sizeof *sp); 518 if (sp == NULL) { 519 ERROR("no memory"); 520 goto out; 521 } 522 523 // Add to the services list 524 *spp = sp; 525 spp = &sp->next; 526 sp->rr = rr; 527 if (base_type != NULL) { 528 sp->base_type = base_type; 529 } else { 530 sp->base_type = sp; 531 } 532 533 // Make sure the service name is in the update zone. 534 sp->zone = dns_name_subdomain_of(sp->rr->name, update_zone); 535 if (sp->zone == NULL) { 536 DNS_NAME_GEN_SRP(rr->name, name_buf); 537 DNS_NAME_GEN_SRP(rr->data.ptr.name, data_name_buf); 538 ERROR("service name " PRI_DNS_NAME_SRP " for " PRI_DNS_NAME_SRP 539 " is not in the update zone", DNS_NAME_PARAM_SRP(rr->name, name_buf), 540 DNS_NAME_PARAM_SRP(rr->data.ptr.name, data_name_buf)); 541 ret->rcode = dns_rcode_formerr; 542 goto out; 543 } 544 } 545 } 546 547 // Otherwise it's not a valid update 548 else { 549 DNS_NAME_GEN_SRP(rr->name, name_buf); 550 ERROR("unexpected rrtype %d on " PRI_DNS_NAME_SRP " in update.", rr->type, 551 DNS_NAME_PARAM_SRP(rr->name, name_buf)); 552 ret->rcode = dns_rcode_formerr; 553 goto out; 554 } 555 } 556 557 // Now that we've scanned the whole update, do the consistency checks for updates that might 558 // not have come in order. 559 560 // If we don't yet have a host description, but this is a delete of the entire host registration (host_lease == 0) and 561 // we do have a delete record and a key record for the host, create a host description with no addresses here. 562 if (host_description == NULL && ret->host_lease == 0) { 563 // If we get here and we have a key, then that suggests that this SRP update is a host remove with a KEY RR to 564 // authenticate it (and possibly leave behind). 565 if (key != NULL) { 566 dp = srp_find_delete(deletes, key); 567 if (dp != NULL) { 568 host_description = calloc(1, sizeof *host_description); 569 if (host_description == NULL) { 570 ERROR("no memory"); 571 goto out; 572 } 573 host_description->delete = dp; 574 host_description->name = dp->name; 575 dp->consumed = true; // This delete is accounted for. 576 } 577 } 578 } 579 // Make sure there's a host description. 580 if (!host_description) { 581 ERROR("SRP update does not include a host description."); 582 ret->rcode = dns_rcode_formerr; 583 goto out; 584 } 585 586 // Make sure that each service add references a service instance that's in the same update. 587 for (sp = services; sp; sp = sp->next) { 588 // A service instance can never point to a service subtype--it has to point to the base type. 589 if (sp->base_type != sp) { 590 continue; 591 } 592 for (sip = service_instances; sip; sip = sip->next) { 593 if (dns_names_equal(sip->name, sp->rr->data.ptr.name)) { 594 // Note that we have already verified that there is only one service instance 595 // with this name, so this could only ever happen once in this loop even without 596 // the break statement. 597 sip->service = sp; 598 sip->num_instances++; 599 break; 600 } 601 } 602 // If this service doesn't point to a service instance that's in the update, then the 603 // update fails validation. 604 if (sip == NULL) { 605 DNS_NAME_GEN_SRP(sp->rr->name, name_buf); 606 ERROR("service points to an instance that's not included: " PRI_DNS_NAME_SRP, 607 DNS_NAME_PARAM_SRP(sp->rr->name, name_buf)); 608 ret->rcode = dns_rcode_formerr; 609 goto out; 610 } 611 } 612 613 for (sip = service_instances; sip; sip = sip->next) { 614 // For each service instance, make sure that at least one service references it 615 if (sip->num_instances == 0) { 616 DNS_NAME_GEN_SRP(sip->name, name_buf); 617 ERROR("service instance update for " PRI_DNS_NAME_SRP 618 " is not referenced by a service update.", DNS_NAME_PARAM_SRP(sip->name, name_buf)); 619 ret->rcode = dns_rcode_formerr; 620 goto out; 621 } 622 623 // For each service instance, make sure that it references the host description 624 if (dns_names_equal(host_description->name, sip->srv->data.srv.name)) { 625 sip->host = host_description; 626 host_description->num_instances++; 627 } 628 } 629 630 // Make sure that at least one service instance references the host description, unless the update is deleting the host address records. 631 #ifdef REJECT_HOST_WITHOUT_SERVICES 632 if (host_description->num_instances == 0 && host_description->addrs != NULL) { 633 DNS_NAME_GEN_SRP(host_description->name, name_buf); 634 ERROR("host description " PRI_DNS_NAME_SRP " is not referenced by any service instances.", 635 DNS_NAME_PARAM_SRP(host_description->name, name_buf)); 636 ret->rcode = dns_rcode_formerr; 637 goto out; 638 } 639 640 // Make sure the host description has at least one address record, unless we're deleting the host. 641 if (host_description->addrs == NULL && host_description->num_instances != 0 && ret->host_lease != 0) { 642 DNS_NAME_GEN_SRP(host_description->name, name_buf); 643 ERROR("host description " PRI_DNS_NAME_SRP " doesn't contain any IP addresses, but services are being added.", 644 DNS_NAME_PARAM_SRP(host_description->name, name_buf)); 645 ret->rcode = dns_rcode_formerr; 646 goto out; 647 } 648 #endif 649 650 for (i = 0; i < num_keys; i++) { 651 // If this isn't the only key, make sure it's got the same contents as the other keys. 652 if (i > 0) { 653 if (!dns_keys_rdata_equal(key, keys[i])) { 654 ERROR("more than one key presented"); 655 ret->rcode = dns_rcode_formerr; 656 goto out; 657 } 658 // This is a hack so that if num_keys == 1, we don't have to allocate keys[]. 659 // At the bottom of this if statement, key is always the key we are looking at. 660 key = keys[i]; 661 } 662 // If there is a key, and the host description doesn't currently have a key, check 663 // there first since that's the default. 664 if (host_description->key == NULL && dns_names_equal(key->name, host_description->name)) { 665 host_description->key = key; 666 found_key = true; 667 } else { 668 for (sip = service_instances; sip != NULL; sip = sip->next) { 669 if (dns_names_equal(sip->name, key->name)) { 670 found_key = true; 671 break; 672 } 673 } 674 } 675 if (!found_key) { 676 DNS_NAME_GEN_SRP(key->name, key_name_buf); 677 ERROR("key present for name " PRI_DNS_NAME_SRP 678 " which is neither a host nor an instance name.", DNS_NAME_PARAM_SRP(key->name, key_name_buf)); 679 ret->rcode = dns_rcode_formerr; 680 goto out; 681 } 682 } 683 if (keys != NULL) { 684 free(keys); 685 keys = NULL; 686 } 687 688 // And make sure it has a key record 689 if (host_description->key == NULL) { 690 DNS_NAME_GEN_SRP(host_description->name, host_name_buf); 691 ERROR("host description " PRI_DNS_NAME_SRP " doesn't contain a key.", 692 DNS_NAME_PARAM_SRP(host_description->name, host_name_buf)); 693 ret->rcode = dns_rcode_formerr; 694 goto out; 695 } 696 697 // Find any deletes that weren't consumed. These will be presumed to be removes of service instances previously 698 // registered. These can't be validated here--we have to actually go look at the database. 699 dpp = &deletes; 700 rpp = &removes; 701 while (*dpp) { 702 dp = *dpp; 703 if (!dp->consumed) { 704 DNS_NAME_GEN_SRP(dp->name, delete_name_buf); 705 INFO("delete for presumably previously-registered instance which is being withdrawn: " PRI_DNS_NAME_SRP, 706 DNS_NAME_PARAM_SRP(dp->name, delete_name_buf)); 707 *rpp = dp; 708 rpp = &dp->next; 709 *dpp = dp->next; 710 dp->next = NULL; 711 } else { 712 dpp = &dp->next; 713 } 714 } 715 716 // The signature should be the last thing in the additional section. Even if the signature 717 // is valid, if it's not at the end we reject it. Note that we are just checking for SIG(0) 718 // so if we don't find what we're looking for, we forward it to the DNS auth server which 719 // will either accept or reject it. 720 if (message->arcount < 1) { 721 ERROR("signature not present"); 722 ret->rcode = dns_rcode_formerr; 723 goto out; 724 } 725 signature = &message->additional[message->arcount -1]; 726 if (signature->type != dns_rrtype_sig) { 727 ERROR("signature is not at the end or is not present"); 728 ret->rcode = dns_rcode_formerr; 729 goto out; 730 } 731 732 // Make sure that the signer name is the hostname. If it's not, it could be a legitimate 733 // update with a different key, but it's not an SRP update, so we pass it on. 734 if (!dns_names_equal(signature->data.sig.signer, host_description->name)) { 735 DNS_NAME_GEN_SRP(signature->data.sig.signer, signer_name_buf); 736 DNS_NAME_GEN_SRP(host_description->name, host_name_buf); 737 ERROR("signer " PRI_DNS_NAME_SRP " doesn't match host " PRI_DNS_NAME_SRP, 738 DNS_NAME_PARAM_SRP(signature->data.sig.signer, signer_name_buf), 739 DNS_NAME_PARAM_SRP(host_description->name, host_name_buf)); 740 ret->rcode = dns_rcode_formerr; 741 goto out; 742 } 743 744 // Make sure we're in the time limit for the signature. Zeroes for the inception and expiry times 745 // mean the host that send this doesn't have a working clock. One being zero and the other not isn't 746 // valid unless it's 1970. 747 if (signature->data.sig.inception != 0 || signature->data.sig.expiry != 0) { 748 gettimeofday(&now, NULL); 749 if (raw_message->received_time != 0) { 750 // The received time is in srp_time, but the signature time will be in wall clock time, so 751 // convert from srpl_time to wall clock time. 752 now.tv_sec = raw_message->received_time - srp_time() + now.tv_sec; 753 now.tv_usec = 0; 754 } 755 756 // The sender does the bracketing, so we can just do a simple comparison. 757 if ((uint32_t)(now.tv_sec & UINT32_MAX) > signature->data.sig.expiry || 758 (uint32_t)(now.tv_sec & UINT32_MAX) < signature->data.sig.inception) { 759 ERROR("signature is not timely: %lu < %lu < %lu does not hold", 760 (unsigned long)signature->data.sig.inception, (unsigned long)now.tv_sec, 761 (unsigned long)signature->data.sig.expiry); 762 goto badsig; 763 } 764 } 765 766 // Now that we have the key, we can validate the signature. If the signature doesn't validate, 767 // there is no need to pass the message on. 768 if (!srp_sig0_verify(&raw_message->wire, host_description->key, signature)) { 769 ERROR("signature is not valid"); 770 goto badsig; 771 } 772 773 // Now that we have validated the SRP message, go through and fix up all instances of 774 // *default.service.arpa to use the replacement zone, if this update is for 775 // default.services.arpa and there is a replacement zone. 776 if (replacement_zone != NULL) { 777 // All of the service instances and the host use the name from the delete, so if 778 // we update these, the names for those are taken care of. We already found the 779 // zone for which the delete is a subdomain, so we can just replace it without 780 // finding it again. 781 for (dp = deletes; dp; dp = dp->next) { 782 replace_zone_name(&dp->name, dp->zone, replacement_zone); 783 } 784 785 // We also need to update the names of removes. 786 for (dp = removes; dp; dp = dp->next) { 787 replace_zone_name(&dp->name, dp->zone, replacement_zone); 788 } 789 790 // All services have PTR records, which point to names. Both the service name and the 791 // PTR name have to be fixed up. 792 for (sp = services; sp; sp = sp->next) { 793 replace_zone_name(&sp->rr->name, sp->zone, replacement_zone); 794 uzp = dns_name_subdomain_of(sp->rr->data.ptr.name, update_zone); 795 // We already validated that the PTR record points to something in the zone, so this 796 // if condition should always be false. 797 if (uzp == NULL) { 798 ERROR("service PTR record zone match fail!!"); 799 ret->rcode = dns_rcode_formerr; 800 goto out; 801 } 802 replace_zone_name(&sp->rr->data.ptr.name, uzp, replacement_zone); 803 } 804 805 // All service instances have SRV records, which point to names. The service instance 806 // name is already fixed up, because it's the same as the delete, but the name in the 807 // SRV record must also be fixed. 808 for (sip = service_instances; sip; sip = sip->next) { 809 uzp = dns_name_subdomain_of(sip->srv->data.srv.name, update_zone); 810 // We already validated that the SRV record points to something in the zone, so this 811 // if condition should always be false. 812 if (uzp == NULL) { 813 ERROR("service instance SRV record zone match fail!!"); 814 ret->rcode = dns_rcode_formerr; 815 goto out; 816 } 817 replace_zone_name(&sip->srv->data.srv.name, uzp, replacement_zone); 818 } 819 820 // We shouldn't need to replace the hostname zone because it's actually pointing to 821 // the name of a delete. 822 } 823 824 // Start the update. 825 DNS_NAME_GEN_SRP(host_description->name, host_description_name_buf); 826 char time_buf[28]; 827 if (raw_message->received_time == 0) { 828 static char msg[] = "not set"; 829 memcpy(time_buf, msg, sizeof(msg)); 830 } else { 831 srp_format_time_offset(time_buf, sizeof(time_buf), srp_time() - raw_message->received_time); 832 } 833 834 INFO("update for " PRI_DNS_NAME_SRP " #%d, xid %x validates, key lease %d, host lease %d, message lease %d, receive_time " 835 PUB_S_SRP ", remote " PRI_S_SRP " -> %p.", 836 DNS_NAME_PARAM_SRP(host_description->name, host_description_name_buf), index, raw_message->wire.id, 837 ret->key_lease, ret->host_lease, raw_message->lease, time_buf, remote_name == NULL ? "(none)" : remote_name, ret); 838 ret->rcode = dns_rcode_noerror; 839 goto out; 840 841 badsig: 842 ret->drop = true; 843 844 out: 845 // No matter how we get out of this, we free the delete structures that weren't dangling removes, 846 // because they are not used to do the update. 847 for (dp = deletes; dp; ) { 848 delete_t *next = dp->next; 849 free(dp); 850 dp = next; 851 } 852 853 // We always return what we got, even if we failed 854 ret->host = host_description; 855 ret->instances = service_instances; 856 ret->services = services; 857 ret->removes = removes; 858 ret->update_zone = replacement_zone == NULL ? update_zone : replacement_zone; 859 return ret; 860 } 861 862 bool 863 srp_dns_evaluate(comm_t *connection, srp_server_t *server_state, message_t *message, dns_message_t **p_parsed_message) 864 { 865 bool continuing = false; 866 client_update_t *update = NULL; 867 868 // Drop incoming responses--we're a server, so we only accept queries. 869 if (dns_qr_get(&message->wire) == dns_qr_response) { 870 ERROR("received a message that was a DNS response: %d", dns_opcode_get(&message->wire)); 871 goto out; 872 } 873 874 // Forward incoming messages that are queries to the dnssd-proxy code. 875 if (dns_opcode_get(&message->wire) == dns_opcode_query) 876 { 877 dns_proxy_input_for_server(connection, server_state, message, NULL); 878 goto out; 879 } 880 881 if (dns_opcode_get(&message->wire) != dns_opcode_update) { 882 // dns_forward(connection) 883 send_fail_response(connection, message, dns_rcode_refused); 884 ERROR("received a message that was not a DNS update: %d", dns_opcode_get(&message->wire)); 885 goto out; 886 } 887 888 // We need the wire message to validate the signature... 889 update = srp_evaluate(NULL, p_parsed_message, message, 0); 890 if (update == NULL) { 891 send_fail_response(connection, message, dns_rcode_servfail); 892 goto out; 893 } 894 if (update->rcode != dns_rcode_noerror) { 895 if (!update->drop) { 896 send_fail_response(connection, message, update->rcode); 897 } 898 goto out; 899 } 900 901 update->connection = connection; 902 ioloop_comm_retain(update->connection); 903 update->server_state = server_state; 904 905 continuing = srp_update_start(update); 906 goto good; 907 out: 908 srp_parse_client_updates_free(update); 909 good: 910 return continuing; 911 } 912 913 #if SRP_FEATURE_REPLICATION 914 static bool 915 srp_parse_eliminate_shadowed_updates(srp_server_t *server_state, client_update_t *new_message, client_update_t *old_message) 916 { 917 (void)server_state; 918 919 // We only ever want the last host update. 920 old_message->skip_host_updates = true; 921 922 // Look for matching instances. 923 for (service_instance_t *old = old_message->instances; old != NULL; old = old->next) { 924 for (service_instance_t *new = new_message->instances; new != NULL; new = new->next) { 925 if (dns_names_equal(old->name, new->name)) { 926 old->skip_update = true; 927 } 928 } 929 for (delete_t *delete = new_message->removes; delete != NULL; delete = delete->next) { 930 DNS_NAME_GEN_SRP(old->name, old_name_buf); 931 DNS_NAME_GEN_SRP(delete->name, delete_name_buf); 932 INFO("old service " PRI_DNS_NAME_SRP ", delete " PRI_DNS_NAME_SRP, 933 DNS_NAME_PARAM_SRP(old->name, old_name_buf), DNS_NAME_PARAM_SRP(delete->name, delete_name_buf)); 934 if (dns_names_equal(old->name, delete->name)) { 935 old->skip_update = true; 936 } 937 } 938 } 939 return true; 940 } 941 942 // For SRP replication 943 bool 944 srp_parse_host_messages_evaluate(srp_server_t *UNUSED server_state, srpl_connection_t *srpl_connection, 945 message_t **messages, int num_messages) 946 { 947 client_update_t *client_updates = NULL; 948 bool ret = false; 949 950 for (int i = 0; i < num_messages; i++) { 951 message_t *message = messages[i]; 952 953 // Drop incoming responses--we're a server, so we only accept queries. 954 if (dns_qr_get(&message->wire) == dns_qr_response) { 955 ERROR("received a message that was a DNS response: %d", dns_opcode_get(&message->wire)); 956 goto out; 957 } 958 959 // Forward incoming messages that are queries but not updates. 960 // XXX do this later--for now we operate only as a translator, not a proxy. 961 if (dns_opcode_get(&message->wire) != dns_opcode_update) { 962 ERROR("received a message that was not a DNS update: %d", dns_opcode_get(&message->wire)); 963 goto out; 964 } 965 966 // We need the wire message to validate the signature... 967 INFO("evaluating message #%d from %s", i, srpl_connection->name); 968 client_update_t *update = srp_evaluate(srpl_connection->name, NULL, message, i); 969 if (update == NULL) { 970 goto out; 971 } 972 if (update->rcode != dns_rcode_noerror) { 973 update->next = client_updates; 974 client_updates = update; 975 goto out; 976 } 977 update->srpl_connection = srpl_connection; 978 srpl_connection_retain(update->srpl_connection); 979 update->server_state = server_state; 980 update->index = i; 981 982 // We build the list of messages so that message 0 winds up at the /end/ of the list; message 0 is 983 // the earliest message. 984 update->next = client_updates; 985 client_updates = update; 986 } 987 988 // Now that we've parsed and validated everything, eliminate earlier updates that are in the shadow of 989 // later updates. 990 // The list off of client_updates is ordered with most recent messages first, so what we want to do 991 // is, for each message on the list, see if any earlier messages update the same instance. If so, remove 992 // the earlier update, since it is out of date and could create a conflict if we tried to apply it. 993 // If we get an update that deletes the host, every update earlier than that is invalidated. It would 994 // be weird for us to get an update that is earlier than a full delete, but we could well get a full 995 // delete as the earliest recorded update. 996 for (client_update_t *em = client_updates; em != NULL; em = em->next) { 997 for (client_update_t *lem = em->next; lem != NULL; lem = lem->next) { 998 srp_parse_eliminate_shadowed_updates(server_state, em, lem); 999 } 1000 } 1001 1002 // Now re-order the list oldest to newest. 1003 client_update_t *current = client_updates, *next = NULL, *prev = NULL; 1004 while (current != NULL) { 1005 next = current->next; 1006 current->next = prev; 1007 prev = current; 1008 current = next; 1009 } 1010 client_updates = prev; 1011 1012 // Now that we've eliminated shadowed updates, we can actually call srp_update_start. 1013 ret = srp_update_start(client_updates); 1014 goto good; 1015 out: 1016 srp_parse_client_updates_free(client_updates); 1017 good: 1018 return ret; 1019 } 1020 #endif 1021 1022 void 1023 dns_input(comm_t *comm, message_t *message, void *context) 1024 { 1025 srp_server_t *server_state = context; 1026 srp_dns_evaluate(comm, server_state, message, NULL); 1027 } 1028 1029 struct srp_proxy_listener_state { 1030 comm_t *NULLABLE tcp_listener; 1031 comm_t *NULLABLE tls_listener; 1032 comm_t *NULLABLE udp_listener; 1033 }; 1034 1035 comm_t * 1036 srp_proxy_listen(uint16_t *avoid_ports, int num_avoid_ports, const char *interface_name, ready_callback_t ready, 1037 cancel_callback_t cancel_callback, addr_t *address, finalize_callback_t context_release_callback, 1038 void *context) 1039 { 1040 unsigned ifindex = 0; 1041 if (interface_name != NULL) { 1042 ifindex = if_nametoindex(interface_name); 1043 if (ifindex == 0) { 1044 return false; 1045 } 1046 } 1047 1048 // XXX UDP listeners should bind to interface addresses, not INADDR_ANY. 1049 return ioloop_listener_create(false, false, false, avoid_ports, num_avoid_ports, address, NULL, "SRP UDP listener", 1050 dns_input, NULL, cancel_callback, ready, context_release_callback, NULL, ifindex, context); 1051 } 1052 1053 void 1054 srp_proxy_init(const char *update_zone) 1055 { 1056 // For now, hardcoded, should be configurable 1057 if (service_update_zone != NULL) { 1058 dns_name_free(service_update_zone); 1059 } 1060 service_update_zone = dns_pres_name_parse(update_zone); 1061 1062 } 1063 1064 // Local Variables: 1065 // mode: C 1066 // tab-width: 4 1067 // c-file-style: "bsd" 1068 // c-basic-offset: 4 1069 // fill-column: 108 1070 // indent-tabs-mode: nil 1071 // End: 1072