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 #include "spf_sys_config.h"
17 
18 
19 #ifdef STDC_HEADERS
20 # include <stdio.h>		/* stdin / stdout */
21 # include <stdlib.h>	   /* malloc / free */
22 # include <ctype.h>		/* isupper / tolower */
23 #endif
24 
25 #ifdef HAVE_INTTYPES_H
26 #include <inttypes.h>
27 #endif
28 
29 #ifdef HAVE_STRING_H
30 # include <string.h>	   /* strstr / strdup */
31 #else
32 # ifdef HAVE_STRINGS_H
33 #  include <strings.h>	   /* strstr / strdup */
34 # endif
35 #endif
36 
37 
38 
39 #include "spf.h"
40 #include "spf_internal.h"
41 #include "spf_record.h"
42 
43 
44 #define SPF_MSGSIZE		4096
45 
46 
47 SPF_record_t *
SPF_record_new(SPF_server_t * spf_server,const char * text)48 SPF_record_new(SPF_server_t *spf_server, const char *text)
49 {
50 	SPF_record_t	*rp;
51 
52 	rp = (SPF_record_t *)malloc(sizeof(SPF_record_t));
53 	if (!rp)
54 		return rp;
55 	memset(rp, 0, sizeof(SPF_record_t));
56 
57 	rp->spf_server = spf_server;
58 
59 	return rp;
60 }
61 
62 void
SPF_record_free(SPF_record_t * rp)63 SPF_record_free(SPF_record_t *rp)
64 {
65 	if (rp->mech_first)
66 		free(rp->mech_first);
67 	if (rp->mod_first)
68 		free(rp->mod_first);
69 	free(rp);
70 }
71 
72 void
SPF_macro_free(SPF_macro_t * mac)73 SPF_macro_free(SPF_macro_t *mac)
74 {
75 	free(mac);
76 }
77 
78 /* This expects datap and datalenp NOT to be initialised. */
79 static SPF_errcode_t
SPF_record_find_mod_data(SPF_record_t * spf_record,const char * mod_name,SPF_data_t ** datap,size_t * datalenp)80 SPF_record_find_mod_data(
81 		SPF_record_t *spf_record,
82 		const char *mod_name,
83 		SPF_data_t **datap, size_t *datalenp)
84 {
85 	SPF_mod_t	*mod;
86 	size_t		name_len;
87 	int			i;
88 
89 	name_len = strlen( mod_name );
90 
91 	/*
92 	 * make sure we were passed valid data to work with
93 	 */
94 	SPF_ASSERT_NOTNULL(spf_record);
95 	SPF_ASSERT_NOTNULL(mod_name);
96 	SPF_ASSERT_NOTNULL(datap);
97 	SPF_ASSERT_NOTNULL(datalenp);
98 
99 	/*
100 	 * find modifier
101 	 */
102 
103 	mod = spf_record->mod_first;
104 	for( i = 0; i < spf_record->num_mod; i++ ) {
105 		if ( name_len == mod->name_len
106 			 && strncasecmp( SPF_mod_name( mod ), mod_name, name_len ) == 0 )
107 		{
108 			*datap = SPF_mod_data( mod );
109 			*datalenp = mod->data_len;
110 
111 			return 0;
112 		}
113 
114 		mod = SPF_mod_next( mod );
115 	}
116 
117 	return SPF_E_MOD_NOT_FOUND;
118 }
119 
120 /* Nota Bene: *datap and *datalenp MUST BE INITIALIZED, possibly to
121  * NULL. SPF_record_expand_data requires this. I do not strictly
122  * approve, but
123  * I guess it makes things easier on the allocator? It clouds the
124  * issue of responsibility for memory. */
125 SPF_errcode_t
SPF_record_find_mod_value(SPF_server_t * spf_server,SPF_request_t * spf_request,SPF_response_t * spf_response,SPF_record_t * spf_record,const char * mod_name,char ** bufp,size_t * buflenp)126 SPF_record_find_mod_value(SPF_server_t *spf_server,
127 		SPF_request_t *spf_request,
128 		SPF_response_t *spf_response,
129 		SPF_record_t *spf_record,
130 		const char *mod_name,
131 		char **bufp, size_t *buflenp)
132 {
133 	SPF_data_t		*data;
134 	size_t		 data_len;
135 	SPF_errcode_t	 err;
136 
137 	/*
138 	 * make sure we were passed valid data to work with
139 	 */
140 	SPF_ASSERT_NOTNULL(spf_record);
141 	SPF_ASSERT_NOTNULL(mod_name);
142 	SPF_ASSERT_NOTNULL(bufp);
143 	SPF_ASSERT_NOTNULL(buflenp);
144 
145 	err = SPF_record_find_mod_data(spf_record,
146 					mod_name, &data, &data_len);
147 	if (err)
148 		return err;
149 
150 	return SPF_record_expand_data(spf_server, spf_request, spf_response,
151 					data, data_len, bufp, buflenp);
152 }
153