1 /* 2 * This program is free software; you can redistribute it and/or modify 3 * it under the terms of either: 4 * 5 * a) The GNU Lesser General Public License as published by the Free 6 * Software Foundation; either version 2.1, or (at your option) any 7 * later version, 8 * 9 * OR 10 * 11 * b) The two-clause BSD license. 12 * 13 * These licenses can be found with the distribution in the file LICENSES 14 */ 15 16 17 18 19 #ifndef INC_SPF_DNS 20 #define INC_SPF_DNS 21 22 23 /** 24 * @file 25 * 26 * This library has the ability to use one or more of any of a number 27 * of DNS "layers" to obtain DNS information. These layers all have 28 * compatible APIs, with only minor differences that relate to their 29 * specific functions. So, they can be mixed and matched in any order 30 * to do what you want. 31 * 32 * When you create a new DNS layer, you can (optionally) specify the 33 * layer below it. If the current DNS layer is not able to resolve 34 * the query, it will automatically call the lower layer. 35 * 36 * Some of the DNS layers allow for debugging information to be 37 * printed, some do caching, and, of course, some return actual DNS 38 * results either by query the network or by looking up the query in a 39 * database. 40 * 41 * For details about each DNS layer, see the appropriate 42 * spf_dns_<layer>.h include file. 43 * 44 * 45 * For example, there is a caching DNS layer that saves the compiled 46 * SPF records for future use. While it takes a small amount of time 47 * to compile the AOL SPF record, you will more than make up for it by 48 * not having to parse the record every time you get a message from 49 * AOL. 50 * 51 * If you wanted to, you can even run the SPF system without using 52 * real DNS lookups at all. For testing, I used a DNS layer that 53 * contained a built-in zone file. This idea could easily be extended 54 * to being able to read the zone file from disk, or to use a database 55 * to access information. 56 * 57 * One example of what you could do with such a zone file would be to 58 * create your own SPF records for the many free-email providers. 59 * Depending on whether you layer this local zone file before or after 60 * the real DNS lookups, you can either override published SPF 61 * records, or you can provide defaults until SPF records are 62 * published. 63 * 64 */ 65 66 67 /* 68 * For those who don't have <arpa/nameserv.h> 69 */ 70 71 /* XXX This should use a more sensible define. */ 72 #if !defined( HAVE_NS_TYPE ) 73 74 #define ns_t_invalid 0 75 #define ns_t_a 1 76 #define ns_t_ns 2 77 #define ns_t_cname 5 78 #define ns_t_ptr 12 79 #define ns_t_mx 15 80 #define ns_t_txt 16 81 #define ns_t_aaaa 28 82 /* #define ns_t_a6 38 */ 83 #define ns_t_any 255 /**< Wildcard match. */ 84 85 typedef int ns_type; 86 #endif 87 88 #if ! HAVE_DECL_NS_T_SPF 89 #define ns_t_spf 99 90 #endif 91 92 #if ! HAVE_DECL_NS_T_INVALID 93 #define ns_t_invalid 0 94 #endif 95 96 97 /* 98 * For those who don't have <netdb.h> 99 */ 100 101 #if !defined(HAVE_NETDB_H) && !defined(_WIN32) 102 #define NETDB_SUCCESS 0 103 #define HOST_NOT_FOUND 1 /**< NXDOMAIN (authoritative answer)*/ 104 #define TRY_AGAIN 2 /**< SERVFAIL (no authoritative answer)*/ 105 #define NO_RECOVERY 3 /**< invalid/unimplmeneted query */ 106 #define NO_DATA 4 /**< host found, but no RR of req type*/ 107 #endif 108 typedef int SPF_dns_stat_t; 109 110 typedef struct SPF_dns_server_struct SPF_dns_server_t; 111 112 #include "spf_request.h" 113 #include "spf_dns_rr.h" 114 115 /* 116 * bundle up the info needed to use a dns method 117 */ 118 119 typedef void (*SPF_dns_destroy_t)(SPF_dns_server_t *spf_dns_server); 120 typedef SPF_dns_rr_t *(*SPF_dns_lookup_t)( 121 SPF_dns_server_t *spf_dns_server, 122 const char *domain, 123 ns_type ns_type, int should_cache 124 ); 125 typedef SPF_errcode_t (*SPF_dns_get_spf_t)( SPF_server_t *spf_server, 126 SPF_request_t *spf_request, 127 SPF_response_t *spf_response, 128 SPF_record_t **spf_recordp); 129 typedef SPF_errcode_t (*SPF_dns_get_exp_t)( SPF_server_t *spf_server, 130 const char *domain, 131 char **buf, size_t *buf_len ); 132 typedef int (*SPF_dns_add_cache_t)( SPF_server_t *spf_server, 133 SPF_dns_rr_t spfrr ); 134 135 struct SPF_dns_server_struct 136 { 137 /** The destructor for this SPF_dns_server_t. If this is NULL, then 138 * the structure is assumed to be shared between multiple SPF_server_t 139 * objects, and is not freed when the server is destroyed, or by any call 140 * to SPF_dns_free(). In this case, it is assumed that somebody else knows, 141 * and will free the resolver at the appropriate object. */ 142 SPF_dns_destroy_t destroy; 143 144 SPF_dns_lookup_t lookup; 145 SPF_dns_get_spf_t get_spf; 146 SPF_dns_get_exp_t get_exp; 147 SPF_dns_add_cache_t add_cache; 148 149 /* the next DNS layer down to call if this layer can't give an answer */ 150 SPF_dns_server_t *layer_below; 151 152 const char *name; /* name of the layer */ 153 int debug; 154 void *hook; /* server-specific data */ 155 }; 156 157 158 void SPF_dns_free( SPF_dns_server_t *spf_dns_server ); 159 SPF_dns_rr_t *SPF_dns_lookup( SPF_dns_server_t *spf_dns_server, 160 const char *domain, ns_type rr_type, 161 int should_cache ); 162 SPF_dns_rr_t *SPF_dns_rlookup( SPF_dns_server_t *spf_dns_server, 163 struct in_addr ipv4, ns_type rr_type, 164 int should_cache ); 165 SPF_dns_rr_t *SPF_dns_rlookup6( SPF_dns_server_t *spf_dns_server, 166 struct in6_addr ipv6, ns_type rr_type, 167 int should_cache ); 168 169 170 /** 171 * The client domain is the validated domain name of the client IP 172 * address. This is not just the domain name(s) found in the reverse 173 * DNS tree, but involves checking to make sure these name(s) use the 174 * client IP address. The complete validation procedure is described 175 * in section 5.4 of the SPF spec. 176 */ 177 char *SPF_dns_get_client_dom(SPF_dns_server_t *spf_dns_server, 178 SPF_request_t *sr); 179 180 181 #endif 182