1 /*
2 **  Copyright (c) 2012-2016, 2018, 2021, The Trusted Domain Project.
3 **    All rights reserved.
4 */
5 
6 #ifndef DMARC_H
7 #define DMARC_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif /* __cplusplus */
12 
13 #include <sys/param.h>
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <netinet/in.h>
17 #include <resolv.h>
18 
19 #define	OPENDMARC_LIB_VERSION	0x00000000
20 
21 #define	DMARC_MAXHOSTNAMELEN		(256)
22 
23 # define DMARC_POLICY_IP_TYPE_IPV4		(4)
24 # define DMARC_POLICY_IP_TYPE_IPV6		(6)
25 
26 # define DMARC_POLICY_SPF_ORIGIN_MAILFROM 	(1)
27 # define DMARC_POLICY_SPF_ORIGIN_HELO		(2)
28 
29 # define DMARC_POLICY_SPF_OUTCOME_NONE		(0)
30 # define DMARC_POLICY_SPF_OUTCOME_PASS		(1)
31 # define DMARC_POLICY_SPF_OUTCOME_FAIL		(2)
32 # define DMARC_POLICY_SPF_OUTCOME_TMPFAIL 	(3)
33 # define DMARC_POLICY_SPF_ALIGNMENT_PASS 	(4)
34 # define DMARC_POLICY_SPF_ALIGNMENT_FAIL 	(5)
35 
36 # define DMARC_POLICY_DKIM_OUTCOME_NONE		(0)
37 # define DMARC_POLICY_DKIM_OUTCOME_PASS		(1)
38 # define DMARC_POLICY_DKIM_OUTCOME_FAIL		(2)
39 # define DMARC_POLICY_DKIM_OUTCOME_TMPFAIL 	(3)
40 # define DMARC_POLICY_DKIM_ALIGNMENT_PASS 	(4)
41 # define DMARC_POLICY_DKIM_ALIGNMENT_FAIL 	(5)
42 
43 #define DMARC_RECORD_A_UNSPECIFIED	('\0')		/* adkim and aspf */
44 #define DMARC_RECORD_A_STRICT		('s')		/* adkim and aspf */
45 #define DMARC_RECORD_A_RELAXED		('r')		/* adkim and aspf */
46 #define DMARC_RECORD_P_UNSPECIFIED	('\0')		/* p and sp */
47 #define DMARC_RECORD_P_NONE		('n')		/* p and sp */
48 #define DMARC_RECORD_P_QUARANTINE	('q')		/* p and sp */
49 #define DMARC_RECORD_P_REJECT		('r')		/* p and sp */
50 #define DMARC_RECORD_RF_UNSPECIFIED	(0x0)		/* rf, a bitmap */
51 #define DMARC_RECORD_RF_AFRF		(0x1)		/* rf, a bitmap */
52 #define DMARC_RECORD_RF_IODEF		(0x2)		/* rf, a bitmap */
53 #define DMARC_RECORD_FO_UNSPECIFIED	(0x0)		/* fo, a bitmap */
54 #define DMARC_RECORD_FO_0		(0x1)		/* fo, a bitmap */
55 #define DMARC_RECORD_FO_1		(0x2)		/* fo, a bitmap */
56 #define DMARC_RECORD_FO_D		(0x4)		/* fo, a bitmap */
57 #define DMARC_RECORD_FO_S		(0x8)		/* fo, a bitmap */
58 
59 #define DMARC_PARSE_OKAY			(0)	/* Okay to continue */
60 #define DMARC_PARSE_ERROR_EMPTY			(1)	/* Nothing to parse */
61 #define DMARC_PARSE_ERROR_NULL_CTX		(2)	/* Got a NULL context */
62 #define DMARC_PARSE_ERROR_BAD_VERSION		(3)	/* Such as v=DBOB1 */
63 #define DMARC_PARSE_ERROR_BAD_VALUE		(4)	/* Bad token value like p=bob */
64 #define DMARC_PARSE_ERROR_NO_REQUIRED_P		(5)	/* Required p= missing */
65 #define DMARC_PARSE_ERROR_NO_DOMAIN		(6)	/* No domain, e.g. <>  */
66 #define DMARC_PARSE_ERROR_NO_ALLOC		(7)	/* Memory Allocation Faliure */
67 #define DMARC_PARSE_ERROR_BAD_SPF_MACRO		(8)	/* Was not a macro from above */
68 #define DMARC_PARSE_ERROR_BAD_DKIM_MACRO	DMARC_PARSE_ERROR_BAD_SPF_MACRO
69 #define DMARC_DNS_ERROR_NO_RECORD		(9)	/* No DMARC record was found */
70 #define DMARC_DNS_ERROR_NXDOMAIN		(10)	/* No such domain exists */
71 #define DMARC_DNS_ERROR_TMPERR			(11)	/* Recoverable DNS error */
72 #define DMARC_TLD_ERROR_UNKNOWN			(12)	/* Undefined TLD type    */
73 #define DMARC_FROM_DOMAIN_ABSENT		(13)	/* No From: domain was supplied */
74 
75 #define DMARC_POLICY_ABSENT			(14)	/* Policy up to you. No DMARC record found */
76 #define DMARC_POLICY_PASS			(15)	/* Policy OK so accept message */
77 #define DMARC_POLICY_REJECT			(16)	/* Policy says to reject message */
78 #define DMARC_POLICY_QUARANTINE			(17)	/* Policy says to quarantine message */
79 #define DMARC_POLICY_NONE			(18)	/* Policy says to monitor and report */
80 
81 #define DMARC_USED_POLICY_IS_P			(19)	/* Domain policy taken (aka 'p')*/
82 #define DMARC_USED_POLICY_IS_SP			(20)	/* Sub-domain policy taken (aka 'sp')*/
83 
84 #ifndef OPENDMARC_POLICY_C
85  typedef struct dmarc_policy_t DMARC_POLICY_T;
86 #endif
87 
88 #define OPENDMARC_STATUS_T int
89 
90 #ifndef MAXPATHLEN
91 # define MAXPATHLEN (2048)
92 #endif
93 #ifndef MAXNS
94 # define MAXNS (3)
95 #endif
96 #define OPENDMARC_MAX_NSADDRLIST (8)
97 typedef struct {
98 	int			tld_type;
99 	u_char 			tld_source_file[MAXPATHLEN];
100 	int    			nscount;
101 	struct sockaddr_in 	nsaddr_list[MAXNS];
102 } OPENDMARC_LIB_T;
103 
104 #define OPENDMARC_TLD_TYPE_NONE    (0)	/* Will not use a tld file             */
105 #define OPENDMARC_TLD_TYPE_MOZILLA (1)	/* mozilla.org effective_tld_names.dat */
106 
107 /*
108  * Library one time initialization.
109  */
110 OPENDMARC_STATUS_T  opendmarc_policy_library_init(OPENDMARC_LIB_T *lib_init);
111 OPENDMARC_STATUS_T  opendmarc_policy_library_shutdown(OPENDMARC_LIB_T *lib_init);
112 
113 /*
114  * Context management.
115  */
116 DMARC_POLICY_T * opendmarc_policy_connect_init(u_char *ip_addr, int ip_type);
117 DMARC_POLICY_T * opendmarc_policy_connect_clear(DMARC_POLICY_T *pctx);
118 DMARC_POLICY_T * opendmarc_policy_connect_rset(DMARC_POLICY_T *pctx);
119 DMARC_POLICY_T * opendmarc_policy_connect_shutdown(DMARC_POLICY_T *pctx);
120 
121 /*
122  * Store information routines.
123  */
124 OPENDMARC_STATUS_T opendmarc_policy_store_from_domain(DMARC_POLICY_T *pctx, u_char *domain);
125 OPENDMARC_STATUS_T opendmarc_policy_store_dkim(DMARC_POLICY_T *pctx, u_char *domain, u_char *selector, int result, u_char *human_result);
126 OPENDMARC_STATUS_T opendmarc_policy_store_spf(DMARC_POLICY_T *pctx, u_char *domain, int result, int origin, u_char *human_result);
127 
128 /*
129  * The DMARC record itself.
130  */
131 OPENDMARC_STATUS_T opendmarc_policy_query_dmarc(DMARC_POLICY_T *pctx, u_char *domain);
132 OPENDMARC_STATUS_T opendmarc_policy_parse_dmarc(DMARC_POLICY_T *pctx, u_char *domain, u_char *record);
133 OPENDMARC_STATUS_T opendmarc_policy_store_dmarc(DMARC_POLICY_T *pctx, u_char *dmarc_record, u_char *domain, u_char *organizationaldomain);
134 
135 /*
136  * Access to parts of the DMARC record.
137  */
138 OPENDMARC_STATUS_T opendmarc_get_policy_to_enforce(DMARC_POLICY_T *pctx);
139 OPENDMARC_STATUS_T opendmarc_policy_fetch_alignment(DMARC_POLICY_T *pctx, int *dkim_alignment, int *spf_alignment);
140 OPENDMARC_STATUS_T opendmarc_policy_fetch_pct(DMARC_POLICY_T *pctx, int *pctp);
141 OPENDMARC_STATUS_T opendmarc_policy_fetch_adkim(DMARC_POLICY_T *pctx, int *adkim);
142 OPENDMARC_STATUS_T opendmarc_policy_fetch_aspf(DMARC_POLICY_T *pctx, int *aspf);
143 OPENDMARC_STATUS_T opendmarc_policy_fetch_p(DMARC_POLICY_T *pctx, int *p);
144 OPENDMARC_STATUS_T opendmarc_policy_fetch_sp(DMARC_POLICY_T *pctx, int *sp);
145 u_char **	   opendmarc_policy_fetch_rua(DMARC_POLICY_T *pctx, u_char *list_buf, size_t size_of_buf, int constant);
146 u_char **	   opendmarc_policy_fetch_ruf(DMARC_POLICY_T *pctx, u_char *list_buf, size_t size_of_buf, int constant);
147 OPENDMARC_STATUS_T opendmarc_policy_fetch_utilized_domain(DMARC_POLICY_T *pctx, u_char *buf, size_t buflen);
148 OPENDMARC_STATUS_T opendmarc_policy_fetch_from_domain(DMARC_POLICY_T *pctx, u_char *buf, size_t buflen);
149 OPENDMARC_STATUS_T opendmarc_policy_query_dmarc_xdomain(DMARC_POLICY_T *pctx, u_char *uri);
150 OPENDMARC_STATUS_T opendmarc_get_policy_token_used(DMARC_POLICY_T *pctx);
151 
152 /*
153  * TLD processing
154  */
155 int  		   opendmarc_tld_read_file(char *path_fname, char *commentstring, char *drop, char *except);
156 void		   opendmarc_tld_shutdown(void);
157 
158 /*
159  * XML Parsing
160  */
161 u_char **          opendmarc_xml(char *b, size_t blen, char *e, size_t elen);
162 u_char **          opendmarc_xml_parse(char *fname, char *err_buf, size_t err_len);
163 
164 /*
165  * Utility routines
166  */
167 void		   opendmarc_dns_fake_record(const char *name, const char *answer);
168 u_char ** 	   opendmarc_util_clearargv(u_char **ary);
169 const char *	   opendmarc_policy_status_to_str(OPENDMARC_STATUS_T status);
170 int                opendmarc_policy_check_alignment(u_char *subdomain, u_char *tld, int mode);
171 int 		   opendmarc_policy_to_buf(DMARC_POLICY_T *pctx, char *buf, size_t buflen);
172 
173 /*
174  * SPF Processing
175  */
176 int     opendmarc_spf_test(char *ip_address, char *mail_from_domain, char *helo_domain, char *spf_record, int soft_fail_as_pass, char *human_readable, size_t human_readable_len, int *use_mailfrom);
177 int	opendmarc_spf2_test(char *ip_address, char *mail_from_domain, char *helo_domain, char *spf_record, int softfail_okay_flag, char *human_readable, size_t human_readable_len, int *used_mfrom);
178 
179 #ifdef __cplusplus
180 }
181 #endif /* __cplusplus */
182 
183 #endif /* DMARC_H */
184