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