1*4afad4b7Schristos /* $NetBSD: ssu.h,v 1.1 2024/02/18 20:57:38 christos Exp $ */ 2*4afad4b7Schristos 3*4afad4b7Schristos /* 4*4afad4b7Schristos * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5*4afad4b7Schristos * 6*4afad4b7Schristos * SPDX-License-Identifier: MPL-2.0 7*4afad4b7Schristos * 8*4afad4b7Schristos * This Source Code Form is subject to the terms of the Mozilla Public 9*4afad4b7Schristos * License, v. 2.0. If a copy of the MPL was not distributed with this 10*4afad4b7Schristos * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11*4afad4b7Schristos * 12*4afad4b7Schristos * See the COPYRIGHT file distributed with this work for additional 13*4afad4b7Schristos * information regarding copyright ownership. 14*4afad4b7Schristos */ 15*4afad4b7Schristos 16*4afad4b7Schristos #ifndef DNS_SSU_H 17*4afad4b7Schristos #define DNS_SSU_H 1 18*4afad4b7Schristos 19*4afad4b7Schristos /*! \file dns/ssu.h */ 20*4afad4b7Schristos 21*4afad4b7Schristos #include <stdbool.h> 22*4afad4b7Schristos 23*4afad4b7Schristos #include <isc/lang.h> 24*4afad4b7Schristos 25*4afad4b7Schristos #include <dns/acl.h> 26*4afad4b7Schristos #include <dns/types.h> 27*4afad4b7Schristos 28*4afad4b7Schristos #include <dst/dst.h> 29*4afad4b7Schristos 30*4afad4b7Schristos ISC_LANG_BEGINDECLS 31*4afad4b7Schristos 32*4afad4b7Schristos typedef enum { 33*4afad4b7Schristos dns_ssumatchtype_name = 0, 34*4afad4b7Schristos dns_ssumatchtype_subdomain = 1, 35*4afad4b7Schristos dns_ssumatchtype_wildcard = 2, 36*4afad4b7Schristos dns_ssumatchtype_self = 3, 37*4afad4b7Schristos dns_ssumatchtype_selfsub = 4, 38*4afad4b7Schristos dns_ssumatchtype_selfwild = 5, 39*4afad4b7Schristos dns_ssumatchtype_selfkrb5 = 6, 40*4afad4b7Schristos dns_ssumatchtype_selfms = 7, 41*4afad4b7Schristos dns_ssumatchtype_subdomainms = 8, 42*4afad4b7Schristos dns_ssumatchtype_subdomainkrb5 = 9, 43*4afad4b7Schristos dns_ssumatchtype_tcpself = 10, 44*4afad4b7Schristos dns_ssumatchtype_6to4self = 11, 45*4afad4b7Schristos dns_ssumatchtype_external = 12, 46*4afad4b7Schristos dns_ssumatchtype_local = 13, 47*4afad4b7Schristos dns_ssumatchtype_selfsubms = 14, 48*4afad4b7Schristos dns_ssumatchtype_selfsubkrb5 = 15, 49*4afad4b7Schristos dns_ssumatchtype_max = 15, /* max value */ 50*4afad4b7Schristos 51*4afad4b7Schristos dns_ssumatchtype_dlz = 16 /* intentionally higher than _max */ 52*4afad4b7Schristos } dns_ssumatchtype_t; 53*4afad4b7Schristos 54*4afad4b7Schristos isc_result_t 55*4afad4b7Schristos dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **table); 56*4afad4b7Schristos /*%< 57*4afad4b7Schristos * Creates a table that will be used to store simple-secure-update rules. 58*4afad4b7Schristos * Note: all locking must be provided by the client. 59*4afad4b7Schristos * 60*4afad4b7Schristos * Requires: 61*4afad4b7Schristos *\li 'mctx' is a valid memory context 62*4afad4b7Schristos *\li 'table' is not NULL, and '*table' is NULL 63*4afad4b7Schristos * 64*4afad4b7Schristos * Returns: 65*4afad4b7Schristos *\li ISC_R_SUCCESS 66*4afad4b7Schristos *\li ISC_R_NOMEMORY 67*4afad4b7Schristos */ 68*4afad4b7Schristos 69*4afad4b7Schristos isc_result_t 70*4afad4b7Schristos dns_ssutable_createdlz(isc_mem_t *mctx, dns_ssutable_t **tablep, 71*4afad4b7Schristos dns_dlzdb_t *dlzdatabase); 72*4afad4b7Schristos /*%< 73*4afad4b7Schristos * Create an SSU table that contains a dlzdatabase pointer, and a 74*4afad4b7Schristos * single rule with matchtype dns_ssumatchtype_dlz. This type of SSU 75*4afad4b7Schristos * table is used by writeable DLZ drivers to offload authorization for 76*4afad4b7Schristos * updates to the driver. 77*4afad4b7Schristos */ 78*4afad4b7Schristos 79*4afad4b7Schristos void 80*4afad4b7Schristos dns_ssutable_attach(dns_ssutable_t *source, dns_ssutable_t **targetp); 81*4afad4b7Schristos /*%< 82*4afad4b7Schristos * Attach '*targetp' to 'source'. 83*4afad4b7Schristos * 84*4afad4b7Schristos * Requires: 85*4afad4b7Schristos *\li 'source' is a valid SSU table 86*4afad4b7Schristos *\li 'targetp' points to a NULL dns_ssutable_t *. 87*4afad4b7Schristos * 88*4afad4b7Schristos * Ensures: 89*4afad4b7Schristos *\li *targetp is attached to source. 90*4afad4b7Schristos */ 91*4afad4b7Schristos 92*4afad4b7Schristos void 93*4afad4b7Schristos dns_ssutable_detach(dns_ssutable_t **tablep); 94*4afad4b7Schristos /*%< 95*4afad4b7Schristos * Detach '*tablep' from its simple-secure-update rule table. 96*4afad4b7Schristos * 97*4afad4b7Schristos * Requires: 98*4afad4b7Schristos *\li 'tablep' points to a valid dns_ssutable_t 99*4afad4b7Schristos * 100*4afad4b7Schristos * Ensures: 101*4afad4b7Schristos *\li *tablep is NULL 102*4afad4b7Schristos *\li If '*tablep' is the last reference to the SSU table, all 103*4afad4b7Schristos * resources used by the table will be freed. 104*4afad4b7Schristos */ 105*4afad4b7Schristos 106*4afad4b7Schristos isc_result_t 107*4afad4b7Schristos dns_ssutable_addrule(dns_ssutable_t *table, bool grant, 108*4afad4b7Schristos const dns_name_t *identity, dns_ssumatchtype_t matchtype, 109*4afad4b7Schristos const dns_name_t *name, unsigned int ntypes, 110*4afad4b7Schristos dns_rdatatype_t *types); 111*4afad4b7Schristos /*%< 112*4afad4b7Schristos * Adds a new rule to a simple-secure-update rule table. The rule 113*4afad4b7Schristos * either grants or denies update privileges of an identity (or set of 114*4afad4b7Schristos * identities) to modify a name (or set of names) or certain types present 115*4afad4b7Schristos * at that name. 116*4afad4b7Schristos * 117*4afad4b7Schristos * Notes: 118*4afad4b7Schristos *\li If 'matchtype' is of SELF type, this rule only matches if the 119*4afad4b7Schristos * name to be updated matches the signing identity. 120*4afad4b7Schristos * 121*4afad4b7Schristos *\li If 'ntypes' is 0, this rule applies to all types except 122*4afad4b7Schristos * NS, SOA, RRSIG, and NSEC. 123*4afad4b7Schristos * 124*4afad4b7Schristos *\li If 'types' includes ANY, this rule applies to all types 125*4afad4b7Schristos * except NSEC. 126*4afad4b7Schristos * 127*4afad4b7Schristos * Requires: 128*4afad4b7Schristos *\li 'table' is a valid SSU table 129*4afad4b7Schristos *\li 'identity' is a valid absolute name 130*4afad4b7Schristos *\li 'matchtype' must be one of the defined constants. 131*4afad4b7Schristos *\li 'name' is a valid absolute name 132*4afad4b7Schristos *\li If 'ntypes' > 0, 'types' must not be NULL 133*4afad4b7Schristos * 134*4afad4b7Schristos * Returns: 135*4afad4b7Schristos *\li ISC_R_SUCCESS 136*4afad4b7Schristos *\li ISC_R_NOMEMORY 137*4afad4b7Schristos */ 138*4afad4b7Schristos 139*4afad4b7Schristos bool 140*4afad4b7Schristos dns_ssutable_checkrules(dns_ssutable_t *table, const dns_name_t *signer, 141*4afad4b7Schristos const dns_name_t *name, const isc_netaddr_t *addr, 142*4afad4b7Schristos bool tcp, const dns_aclenv_t *env, dns_rdatatype_t type, 143*4afad4b7Schristos const dst_key_t *key); 144*4afad4b7Schristos /*%< 145*4afad4b7Schristos * Checks that the attempted update of (name, type) is allowed according 146*4afad4b7Schristos * to the rules specified in the simple-secure-update rule table. If 147*4afad4b7Schristos * no rules are matched, access is denied. 148*4afad4b7Schristos * 149*4afad4b7Schristos * Notes: 150*4afad4b7Schristos * In dns_ssutable_checkrules(), 'addr' should only be 151*4afad4b7Schristos * set if the request received via TCP. This provides a 152*4afad4b7Schristos * weak assurance that the request was not spoofed. 153*4afad4b7Schristos * 'addr' is to to validate dns_ssumatchtype_tcpself 154*4afad4b7Schristos * and dns_ssumatchtype_6to4self rules. 155*4afad4b7Schristos * 156*4afad4b7Schristos * In dns_ssutable_checkrules2(), 'addr' can also be passed for 157*4afad4b7Schristos * UDP requests and TCP is specified via the 'tcp' parameter. 158*4afad4b7Schristos * In addition to dns_ssumatchtype_tcpself and 159*4afad4b7Schristos * tcp_ssumatchtype_6to4self rules, the address 160*4afad4b7Schristos * also be used to check dns_ssumatchtype_local rules. 161*4afad4b7Schristos * If 'addr' is set then 'env' must also be set so that 162*4afad4b7Schristos * requests from non-localhost addresses can be rejected. 163*4afad4b7Schristos * 164*4afad4b7Schristos * For dns_ssumatchtype_tcpself the addresses are mapped to 165*4afad4b7Schristos * the standard reverse names under IN-ADDR.ARPA and IP6.ARPA. 166*4afad4b7Schristos * RFC 1035, Section 3.5, "IN-ADDR.ARPA domain" and RFC 3596, 167*4afad4b7Schristos * Section 2.5, "IP6.ARPA Domain". 168*4afad4b7Schristos * 169*4afad4b7Schristos * For dns_ssumatchtype_6to4self, IPv4 address are converted 170*4afad4b7Schristos * to a 6to4 prefix (48 bits) per the rules in RFC 3056. Only 171*4afad4b7Schristos * the top 48 bits of the IPv6 address are mapped to the reverse 172*4afad4b7Schristos * name. This is independent of whether the most significant 16 173*4afad4b7Schristos * bits match 2002::/16, assigned for 6to4 prefixes, or not. 174*4afad4b7Schristos * 175*4afad4b7Schristos * Requires: 176*4afad4b7Schristos *\li 'table' is a valid SSU table 177*4afad4b7Schristos *\li 'signer' is NULL or a valid absolute name 178*4afad4b7Schristos *\li 'addr' is NULL or a valid network address. 179*4afad4b7Schristos *\li 'aclenv' is NULL or a valid ACL environment. 180*4afad4b7Schristos *\li 'name' is a valid absolute name 181*4afad4b7Schristos *\li if 'addr' is not NULL, 'env' is not NULL. 182*4afad4b7Schristos */ 183*4afad4b7Schristos 184*4afad4b7Schristos /*% Accessor functions to extract rule components */ 185*4afad4b7Schristos bool 186*4afad4b7Schristos dns_ssurule_isgrant(const dns_ssurule_t *rule); 187*4afad4b7Schristos /*% Accessor functions to extract rule components */ 188*4afad4b7Schristos dns_name_t * 189*4afad4b7Schristos dns_ssurule_identity(const dns_ssurule_t *rule); 190*4afad4b7Schristos /*% Accessor functions to extract rule components */ 191*4afad4b7Schristos unsigned int 192*4afad4b7Schristos dns_ssurule_matchtype(const dns_ssurule_t *rule); 193*4afad4b7Schristos /*% Accessor functions to extract rule components */ 194*4afad4b7Schristos dns_name_t * 195*4afad4b7Schristos dns_ssurule_name(const dns_ssurule_t *rule); 196*4afad4b7Schristos /*% Accessor functions to extract rule components */ 197*4afad4b7Schristos unsigned int 198*4afad4b7Schristos dns_ssurule_types(const dns_ssurule_t *rule, dns_rdatatype_t **types); 199*4afad4b7Schristos 200*4afad4b7Schristos isc_result_t 201*4afad4b7Schristos dns_ssutable_firstrule(const dns_ssutable_t *table, dns_ssurule_t **rule); 202*4afad4b7Schristos /*%< 203*4afad4b7Schristos * Initiates a rule iterator. There is no need to maintain any state. 204*4afad4b7Schristos * 205*4afad4b7Schristos * Returns: 206*4afad4b7Schristos *\li #ISC_R_SUCCESS 207*4afad4b7Schristos *\li #ISC_R_NOMORE 208*4afad4b7Schristos */ 209*4afad4b7Schristos 210*4afad4b7Schristos isc_result_t 211*4afad4b7Schristos dns_ssutable_nextrule(dns_ssurule_t *rule, dns_ssurule_t **nextrule); 212*4afad4b7Schristos /*%< 213*4afad4b7Schristos * Returns the next rule in the table. 214*4afad4b7Schristos * 215*4afad4b7Schristos * Returns: 216*4afad4b7Schristos *\li #ISC_R_SUCCESS 217*4afad4b7Schristos *\li #ISC_R_NOMORE 218*4afad4b7Schristos */ 219*4afad4b7Schristos 220*4afad4b7Schristos bool 221*4afad4b7Schristos dns_ssu_external_match(const dns_name_t *identity, const dns_name_t *signer, 222*4afad4b7Schristos const dns_name_t *name, const isc_netaddr_t *tcpaddr, 223*4afad4b7Schristos dns_rdatatype_t type, const dst_key_t *key, 224*4afad4b7Schristos isc_mem_t *mctx); 225*4afad4b7Schristos /*%< 226*4afad4b7Schristos * Check a policy rule via an external application 227*4afad4b7Schristos */ 228*4afad4b7Schristos 229*4afad4b7Schristos isc_result_t 230*4afad4b7Schristos dns_ssu_mtypefromstring(const char *str, dns_ssumatchtype_t *mtype); 231*4afad4b7Schristos /*%< 232*4afad4b7Schristos * Set 'mtype' from 'str' 233*4afad4b7Schristos * 234*4afad4b7Schristos * Requires: 235*4afad4b7Schristos *\li 'str' is not NULL. 236*4afad4b7Schristos *\li 'mtype' is not NULL, 237*4afad4b7Schristos * 238*4afad4b7Schristos * Returns: 239*4afad4b7Schristos *\li #ISC_R_SUCCESS 240*4afad4b7Schristos *\li #ISC_R_NOTFOUND 241*4afad4b7Schristos */ 242*4afad4b7Schristos 243*4afad4b7Schristos ISC_LANG_ENDDECLS 244*4afad4b7Schristos 245*4afad4b7Schristos #endif /* DNS_SSU_H */ 246