Home | History | Annotate | Line # | Download | only in ServiceRegistration
      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