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_RECORD 20 #define INC_SPF_RECORD 21 22 typedef struct SPF_record_struct SPF_record_t; 23 typedef struct SPF_macro_struct SPF_macro_t; 24 25 #include "spf_response.h" 26 #include "spf_request.h" 27 #include "spf_server.h" 28 29 /** 30 * @file 31 * 32 * Compiled SPF record 33 * 34 * The compiled form of the SPF record is as follows: 35 * 36 * * A four byte header which contains the version, and information 37 * about the mechanisms and modifiers 38 * 39 * * Mechanism information, repeated once for each mechanism 40 * 41 * * A two byte header describing the mechanism 42 * 43 * * Data associated with the mechanism. This can be of several forms 44 * 45 * * ip4/ip6 have a fixed format data field, cidr length is in 46 * the mechanism's parm_len field 47 * 48 * * Mechanisms that allow a macro-string 49 * 50 * * Optional two byte CIDR length structure. (Yes, this is at 51 * the beginning, rather than at the end.) 52 * 53 * * tokenized data description blocks that can be either: 54 * 55 * * two byte macro variable description 56 * 57 * * two byte string description, followed by the string 58 * 59 * * Modifier information, repeated once for each modifier 60 * 61 * * two byte header describing the modifier 62 * 63 * * name of the modifier 64 * 65 * * tokenized data description blocks that can be either: 66 * 67 * * two byte macro variable description 68 * 69 * * two byte string description, followed by the string 70 */ 71 72 73 #define SPF_MAX_STR_LEN 255 /* limits on SPF_data_str_t.len, */ 74 /* SPF_mod_t.name_len and */ 75 /* SPF_mod_t.data_len */ 76 77 #define SPF_MAX_MECH_LEN 511 78 #define SPF_MAX_MOD_LEN 511 79 80 81 82 83 84 85 /** 86 * Tokens and macros to be expanded in SPF_data_str_t in mech/mod 87 */ 88 #define PARM_LP_FROM 0 /**< l = local-part of envelope-sender */ 89 #define PARM_ENV_FROM 1 /**< s = envelope-sender */ 90 #define PARM_DP_FROM 2 /**< o = envelope-domain */ 91 #define PARM_CUR_DOM 3 /**< d = current-domain */ 92 #define PARM_CLIENT_IP 4 /**< i = SMTP client IP */ 93 #define PARM_CLIENT_IP_P 5 /**< c = SMTP client IP (pretty) */ 94 #define PARM_TIME 6 /**< t = time in UTC epoch secs */ 95 #define PARM_CLIENT_DOM 7 /**< p = SMTP client domain name */ 96 #define PARM_CLIENT_VER 8 /**< v = IP ver str - in-addr/ip6 */ 97 #define PARM_HELO_DOM 9 /**< h = HELO/EHLO domain */ 98 #define PARM_REC_DOM 10 /**< r = receiving domain */ 99 #define PARM_CIDR 11 /**< CIDR lengths (IPv4 and v6) */ 100 #define PARM_STRING 12 /**< literal string */ 101 102 103 typedef 104 struct SPF_data_str_struct 105 { 106 unsigned char parm_type; 107 unsigned char len; /* XXX Does this need to be size_t? */ 108 unsigned char __unused0; 109 unsigned char __unused1; 110 /* text: (char[len]) follows */ 111 } SPF_data_str_t; 112 113 114 typedef 115 struct SPF_data_var_struct 116 { 117 unsigned char parm_type; 118 unsigned char num_rhs; /**< chop subdomain name */ 119 unsigned short rev: 1; /**< reverse */ 120 unsigned short url_encode: 1; /**< do URL encoding */ 121 unsigned short delim_dot: 1; /**< delimiter char: . */ 122 unsigned short delim_dash: 1; /**< delimiter char: - */ 123 unsigned short delim_plus: 1; /**< delimiter char: + */ 124 unsigned short delim_equal: 1; /**< delimiter char: = */ 125 unsigned short delim_bar: 1; /**< delimiter char: | */ 126 unsigned short delim_under: 1; /**< delimiter char: _ */ 127 } SPF_data_var_t; 128 129 typedef 130 struct SPF_data_cidr_struct 131 { 132 unsigned char parm_type; 133 unsigned char ipv4; 134 unsigned char ipv6; 135 unsigned char __unused0; 136 /** If we are the first operand in an IP4 or IP6 instruction then 137 * addr: (struct in[6]_addr) follows */ 138 } SPF_data_cidr_t; 139 140 typedef 141 union SPF_data_union 142 { 143 SPF_data_var_t dv; 144 SPF_data_str_t ds; 145 SPF_data_cidr_t dc; 146 } SPF_data_t; 147 148 149 150 /** 151 * Prefixes 152 */ 153 #define PREFIX_PASS SPF_RESULT_PASS 154 #define PREFIX_FAIL SPF_RESULT_FAIL 155 #define PREFIX_SOFTFAIL SPF_RESULT_SOFTFAIL 156 #define PREFIX_NEUTRAL SPF_RESULT_NEUTRAL 157 #define PREFIX_UNKNOWN SPF_RESULT_PERMERROR 158 159 /** 160 * Mechanisms 161 */ 162 #define MECH_UNKNOWN 0 /**< Return PERMERROR */ 163 #define MECH_A 1 164 #define MECH_MX 2 165 #define MECH_PTR 3 166 #define MECH_INCLUDE 4 167 #define MECH_IP4 5 168 #define MECH_IP6 6 169 #define MECH_EXISTS 7 170 #define MECH_ALL 8 171 #define MECH_REDIRECT 9 172 173 typedef 174 struct SPF_mech_struct 175 { 176 unsigned char prefix_type; /**< PASS/FAIL/... */ 177 unsigned char mech_type; /**< A/MX/PTR/... */ 178 unsigned short mech_len; /**< bytes of data or cidr len */ 179 /** data: (SPF_data_t[] = char[mech_len]) follows */ 180 } SPF_mech_t; 181 182 183 /* 184 * Modifiers 185 */ 186 typedef 187 struct SPF_mod_struct 188 { 189 unsigned short name_len; 190 unsigned short data_len; 191 /** name: (char[name_len]) follows */ 192 /** data: (SPF_data_t[] = char[data_len]) follows */ 193 } SPF_mod_t; 194 195 196 197 /** 198 * Compiled SPF records as used internally by libspf2 199 */ 200 struct SPF_record_struct 201 { 202 SPF_server_t *spf_server; 203 204 /* Header */ 205 unsigned char version; /**< SPF spec version number. */ 206 unsigned char num_mech; /**< Number of mechanisms. */ 207 unsigned char num_mod; /**< Number of modifiers. */ 208 unsigned char num_dns_mech; /**< Number of DNS mechanisms. */ 209 210 /* Data */ 211 SPF_mech_t *mech_first; /**< Buffer for mechanisms. */ 212 size_t mech_size; /**< Malloc'ed size. */ 213 size_t mech_len; /**< Used size (non-network format). */ 214 215 SPF_mod_t *mod_first; /**< Buffer for modifiers. */ 216 size_t mod_size; /**< Malloc'ed size. */ 217 size_t mod_len; /**< Used size (non-network format). */ 218 }; 219 220 struct SPF_macro_struct 221 { 222 size_t macro_len; /**< bytes of data */ 223 /** data: (SPF_data_t[] = char[macro_len]) follows */ 224 }; 225 226 227 /** In spf_record.c */ 228 SPF_record_t *SPF_record_new(SPF_server_t *spf_server, 229 const char *text); 230 void SPF_record_free(SPF_record_t *rp); 231 void SPF_macro_free(SPF_macro_t *mac); 232 #if 0 /* static */ 233 SPF_errcode_t SPF_record_find_mod_data(SPF_server_t *spf_server, 234 SPF_record_t *spf_record, 235 const char *mod_name, 236 SPF_data_t **datap, size_t *datalenp); 237 #endif 238 SPF_errcode_t SPF_record_find_mod_value(SPF_server_t *spf_server, 239 SPF_request_t *spf_request, 240 SPF_response_t *spf_response, 241 SPF_record_t *spf_record, 242 const char *mod_name, 243 char **bufp, size_t *buflenp); 244 245 /** In spf_compile.c */ 246 SPF_errcode_t SPF_record_compile(SPF_server_t *spf_server, 247 SPF_response_t *spf_response, 248 SPF_record_t **spf_recordp, 249 const char *record); 250 SPF_errcode_t SPF_record_compile_macro(SPF_server_t *spf_server, 251 SPF_response_t *spf_response, 252 SPF_macro_t **spf_macrop, 253 const char *record); 254 /** In spf_interpret.c */ 255 SPF_errcode_t SPF_record_interpret( 256 SPF_record_t *spf_record, 257 SPF_request_t *spf_request, 258 SPF_response_t *spf_response, 259 int depth); 260 /** In spf_expand.c */ 261 SPF_errcode_t SPF_record_expand_data(SPF_server_t *spf_server, 262 SPF_request_t *spf_request, 263 SPF_response_t *spf_response, 264 SPF_data_t *data, size_t data_len, 265 char **bufp, size_t *buflenp); 266 /** In spf_print.c */ 267 SPF_errcode_t SPF_record_print(SPF_record_t *spf_record); 268 SPF_errcode_t SPF_record_stringify(SPF_record_t *spf_record, 269 char **bufp, size_t *buflenp); 270 271 #endif 272