00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "spf_sys_config.h"
00017
00018 #ifdef STDC_HEADERS
00019 # include <stdlib.h>
00020 # include <stdio.h>
00021 #endif
00022
00023 #ifdef HAVE_NETDB_H
00024 #include <netdb.h>
00025 #endif
00026
00027 #ifdef HAVE_STRING_H
00028 # include <string.h>
00029 #else
00030 # ifdef HAVE_STRINGS_H
00031 # include <strings.h>
00032 # endif
00033 #endif
00034
00035
00036 #include "spf.h"
00037 #include "spf_dns.h"
00038 #include "spf_internal.h"
00039 #include "spf_dns_internal.h"
00040
00041
00042
00043
00044 #define SPF_LAME_EXP "SPF failure: no explanation available"
00045
00046 static SPF_errcode_t
00047 SPF_server_get_default_explanation(SPF_server_t *spf_server,
00048 SPF_request_t *spf_request,
00049 SPF_response_t *spf_response,
00050 char **bufp, size_t *buflenp)
00051 {
00052 SPF_errcode_t err;
00053 SPF_macro_t *spf_macro;
00054
00055 spf_macro = spf_server->explanation;
00056 if (spf_macro != NULL) {
00057 err = SPF_record_expand_data(spf_server,
00058 spf_request, spf_response,
00059 SPF_macro_data(spf_macro), spf_macro->macro_len,
00060 bufp, buflenp);
00061 return err;
00062 }
00063 else {
00064 size_t len = sizeof(SPF_LAME_EXP) + 1;
00065 if (*buflenp < len) {
00066 char *tmp = realloc(*bufp, len);
00067 if (tmp == NULL)
00068 return SPF_E_NO_MEMORY;
00069 *bufp = tmp;
00070 *buflenp = len;
00071 }
00072 strcpy(*bufp, SPF_LAME_EXP);
00073 return SPF_E_SUCCESS;
00074 }
00075 }
00076
00077 #define RETURN_DEFAULT_EXP() do { \
00078 return SPF_server_get_default_explanation(spf_server, \
00079 spf_request, spf_response, bufp, buflenp); \
00080 } while(0)
00081
00082 SPF_errcode_t
00083 SPF_request_get_exp(SPF_server_t *spf_server,
00084 SPF_request_t *spf_request,
00085 SPF_response_t *spf_response,
00086 SPF_record_t *spf_record,
00087 char **bufp, size_t *buflenp)
00088 {
00089 SPF_macro_t *spf_macro;
00090 SPF_dns_server_t *resolver;
00091 SPF_dns_rr_t *rr_txt;
00092 SPF_errcode_t err;
00093 const char *domain;
00094
00095
00096
00097
00098
00099
00100
00101 SPF_ASSERT_NOTNULL(spf_server);
00102 SPF_ASSERT_NOTNULL(spf_request);
00103 SPF_ASSERT_NOTNULL(spf_response);
00104 SPF_ASSERT_NOTNULL(spf_record);
00105 SPF_ASSERT_NOTNULL(bufp);
00106 SPF_ASSERT_NOTNULL(buflenp);
00107
00108 domain = spf_request->cur_dom;
00109
00110 if ( domain == NULL )
00111 return SPF_response_add_warn(spf_response, SPF_E_NOT_CONFIG,
00112 "Could not identify current domain for explanation");
00113
00114
00115
00116
00117
00118 err = SPF_record_find_mod_value(spf_server, spf_request,
00119 spf_response, spf_record,
00120 SPF_EXP_MOD_NAME, bufp, buflenp);
00121 if (err == SPF_E_SUCCESS)
00122 return err;
00123
00124
00125
00126
00127
00128
00129 err = SPF_record_find_mod_value(spf_server, spf_request,
00130 spf_response, spf_record,
00131 "exp", bufp, buflenp );
00132 if (err != SPF_E_SUCCESS) {
00133
00134
00135
00136 RETURN_DEFAULT_EXP();
00137 }
00138
00139 if (*bufp == NULL || (*bufp)[0] == '\0') {
00140
00141
00142
00143 SPF_response_add_warn(spf_response, SPF_E_NOT_SPF,
00144 "Explanation is blank!");
00145 RETURN_DEFAULT_EXP();
00146 }
00147
00148
00149
00150
00151
00152
00153 resolver = spf_server->resolver;
00154
00155 if (resolver->get_exp)
00156 return resolver->get_exp(spf_server, *bufp, bufp, buflenp);
00157
00158 rr_txt = SPF_dns_lookup(resolver, *bufp, ns_t_txt, TRUE);
00159 if (rr_txt == NULL) {
00160 SPF_dns_rr_free(rr_txt);
00161 RETURN_DEFAULT_EXP();
00162 }
00163
00164 switch (rr_txt->herrno) {
00165 case HOST_NOT_FOUND:
00166 case NO_DATA:
00167 SPF_dns_rr_free(rr_txt);
00168 RETURN_DEFAULT_EXP();
00169 break;
00170
00171 case TRY_AGAIN:
00172 SPF_dns_rr_free(rr_txt);
00173 RETURN_DEFAULT_EXP();
00174 break;
00175
00176 case NETDB_SUCCESS:
00177 break;
00178
00179 default:
00180 SPF_warning("Unknown DNS lookup error code");
00181 SPF_dns_rr_free(rr_txt);
00182 RETURN_DEFAULT_EXP();
00183 break;
00184 }
00185
00186 if (rr_txt->num_rr == 0) {
00187 SPF_response_add_warn(spf_response, SPF_E_NOT_SPF,
00188 "No TXT records returned from DNS lookup");
00189 RETURN_DEFAULT_EXP();
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 spf_macro = NULL;
00201 err = SPF_record_compile_macro(spf_server, spf_response, &spf_macro,
00202 rr_txt->rr[0]->txt);
00203 if (err != SPF_E_SUCCESS) {
00204 if (spf_macro)
00205 SPF_macro_free(spf_macro);
00206 SPF_dns_rr_free(rr_txt);
00207 RETURN_DEFAULT_EXP();
00208 }
00209
00210 err = SPF_record_expand_data(spf_server,
00211 spf_request, spf_response,
00212 SPF_macro_data(spf_macro), spf_macro->macro_len,
00213 bufp, buflenp);
00214 SPF_macro_free(spf_macro);
00215 SPF_dns_rr_free(rr_txt);
00216
00217 return err;
00218 }