"Fossies" - the Fresh Open Source Software Archive 
Member "libspf2-1.2.10/src/libspf2/spf_get_exp.c" (28 Jan 2012, 5033 Bytes) of package /linux/privat/libspf2-1.2.10.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "spf_get_exp.c" see the
Fossies "Dox" file reference documentation.
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 #ifdef STDC_HEADERS
19 # include <stdlib.h> /* malloc / free */
20 # include <stdio.h> /* stdin / stdout */
21 #endif
22
23 #ifdef HAVE_NETDB_H
24 #include <netdb.h>
25 #endif
26
27 #ifdef HAVE_STRING_H
28 # include <string.h> /* strstr / strdup */
29 #else
30 # ifdef HAVE_STRINGS_H
31 # include <strings.h> /* strstr / strdup */
32 # endif
33 #endif
34
35
36 #include "spf.h"
37 #include "spf_dns.h"
38 #include "spf_internal.h"
39 #include "spf_dns_internal.h"
40
41
42 /* This never happens. We get SPF_DEFAULT_EXP instead.
43 * This is a panic response which must not contain macros. */
44 #define SPF_LAME_EXP "SPF failure: no explanation available"
45
46 static SPF_errcode_t
47 SPF_server_get_default_explanation(SPF_server_t *spf_server,
48 SPF_request_t *spf_request,
49 SPF_response_t *spf_response,
50 char **bufp, size_t *buflenp)
51 {
52 SPF_errcode_t err;
53 SPF_macro_t *spf_macro;
54
55 spf_macro = spf_server->explanation;
56 if (spf_macro != NULL) {
57 err = SPF_record_expand_data(spf_server,
58 spf_request, spf_response,
59 SPF_macro_data(spf_macro), spf_macro->macro_len,
60 bufp, buflenp);
61 return err;
62 }
63 else {
64 size_t len = sizeof(SPF_LAME_EXP) + 1;
65 if (*buflenp < len) {
66 char *tmp = realloc(*bufp, len);
67 if (tmp == NULL)
68 return SPF_E_NO_MEMORY;
69 *bufp = tmp;
70 *buflenp = len;
71 }
72 strcpy(*bufp, SPF_LAME_EXP);
73 return SPF_E_SUCCESS;
74 }
75 }
76
77 #define RETURN_DEFAULT_EXP() do { \
78 return SPF_server_get_default_explanation(spf_server, \
79 spf_request, spf_response, bufp, buflenp); \
80 } while(0)
81
82 SPF_errcode_t
83 SPF_request_get_exp(SPF_server_t *spf_server,
84 SPF_request_t *spf_request,
85 SPF_response_t *spf_response,
86 SPF_record_t *spf_record,
87 char **bufp, size_t *buflenp)
88 {
89 SPF_macro_t *spf_macro;
90 SPF_dns_server_t *resolver;
91 SPF_dns_rr_t *rr_txt;
92 SPF_errcode_t err;
93 const char *domain;
94
95
96 /*
97 * There are lots of places to look for the explanation message,
98 * some require DNS lookups, some don't.
99 */
100
101 SPF_ASSERT_NOTNULL(spf_server);
102 SPF_ASSERT_NOTNULL(spf_request);
103 SPF_ASSERT_NOTNULL(spf_response);
104 SPF_ASSERT_NOTNULL(spf_record);
105 SPF_ASSERT_NOTNULL(bufp);
106 SPF_ASSERT_NOTNULL(buflenp);
107
108 domain = spf_request->cur_dom;
109
110 if ( domain == NULL )
111 return SPF_response_add_warn(spf_response, SPF_E_NOT_CONFIG,
112 "Could not identify current domain for explanation");
113
114 /*
115 * start looking... check spfid for exp-text=
116 */
117
118 err = SPF_record_find_mod_value(spf_server, spf_request,
119 spf_response, spf_record,
120 SPF_EXP_MOD_NAME, bufp, buflenp);
121 if (err == SPF_E_SUCCESS)
122 return err;
123
124
125 /*
126 * still looking... check the spfid for exp=
127 */
128
129 err = SPF_record_find_mod_value(spf_server, spf_request,
130 spf_response, spf_record,
131 "exp", bufp, buflenp );
132 if (err != SPF_E_SUCCESS) {
133 /*
134 * still looking... try to return default exp from spfcid
135 */
136 RETURN_DEFAULT_EXP();
137 }
138
139 if (*bufp == NULL || (*bufp)[0] == '\0') {
140 /*
141 * still looking... try to return default exp from spfcid
142 */
143 SPF_response_add_warn(spf_response, SPF_E_NOT_SPF,
144 "Explanation is blank!");
145 RETURN_DEFAULT_EXP();
146 }
147
148
149 /*
150 * still looking... try doing a DNS lookup on the exp= name
151 */
152
153 resolver = spf_server->resolver;
154
155 if (resolver->get_exp)
156 return resolver->get_exp(spf_server, *bufp, bufp, buflenp);
157
158 rr_txt = SPF_dns_lookup(resolver, *bufp, ns_t_txt, TRUE);
159 if (rr_txt == NULL) {
160 SPF_dns_rr_free(rr_txt);
161 RETURN_DEFAULT_EXP();
162 }
163
164 switch (rr_txt->herrno) {
165 case HOST_NOT_FOUND:
166 case NO_DATA:
167 SPF_dns_rr_free(rr_txt);
168 RETURN_DEFAULT_EXP();
169 break;
170
171 case TRY_AGAIN:
172 SPF_dns_rr_free(rr_txt);
173 RETURN_DEFAULT_EXP();
174 break;
175
176 case NETDB_SUCCESS:
177 break;
178
179 default:
180 SPF_warning("Unknown DNS lookup error code");
181 SPF_dns_rr_free(rr_txt);
182 RETURN_DEFAULT_EXP();
183 break;
184 }
185
186 if (rr_txt->num_rr == 0) {
187 SPF_response_add_warn(spf_response, SPF_E_NOT_SPF,
188 "No TXT records returned from DNS lookup");
189 RETURN_DEFAULT_EXP();
190 }
191
192
193 /*
194 * still looking... try compiling this TXT record
195 */
196
197 /* FIXME we are supposed to concatenate the TXT records */
198
199 /* FIXME: If this generates any errors, demote them to warnings. */
200 spf_macro = NULL;
201 err = SPF_record_compile_macro(spf_server, spf_response, &spf_macro,
202 rr_txt->rr[0]->txt);
203 if (err != SPF_E_SUCCESS) {
204 if (spf_macro)
205 SPF_macro_free(spf_macro);
206 SPF_dns_rr_free(rr_txt);
207 RETURN_DEFAULT_EXP();
208 }
209
210 err = SPF_record_expand_data(spf_server,
211 spf_request, spf_response,
212 SPF_macro_data(spf_macro), spf_macro->macro_len,
213 bufp, buflenp);
214 SPF_macro_free(spf_macro);
215 SPF_dns_rr_free(rr_txt);
216
217 return err;
218 }