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