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 <stdio.h>
00020 # include <stdlib.h>
00021 #endif
00022
00023 #ifdef HAVE_STRING_H
00024 # include <string.h>
00025 #else
00026 # ifdef HAVE_STRINGS_H
00027 # include <strings.h>
00028 # endif
00029 #endif
00030
00031
00032 #include "spf.h"
00033 #include "spf_dns.h"
00034 #include "spf_response.h"
00035
00036 SPF_response_t *
00037 SPF_response_new(SPF_request_t *spf_request)
00038 {
00039 SPF_response_t *rp;
00040
00041 rp = (SPF_response_t *)malloc(sizeof(SPF_response_t));
00042 if (! rp)
00043 return rp;
00044 memset(rp, 0, sizeof(SPF_response_t));
00045
00046 rp->spf_request = spf_request;
00047 rp->result = SPF_RESULT_INVALID;
00048
00049 return rp;
00050 }
00051
00052 void
00053 SPF_response_free(SPF_response_t *rp)
00054 {
00055 int i;
00056
00057 if (rp->received_spf)
00058 free(rp->received_spf);
00059
00060 if (rp->header_comment)
00061 free(rp->header_comment);
00062 if (rp->smtp_comment)
00063 free(rp->smtp_comment);
00064 if (rp->explanation)
00065 free(rp->explanation);
00066
00067 if (rp->errors) {
00068 for (i = 0; i < rp->errors_length; i++) {
00069 free(rp->errors[i].message);
00070 }
00071 free(rp->errors);
00072 }
00073
00074 free(rp);
00075 }
00076
00077 static SPF_response_t *
00078 SPF_response_choose(SPF_response_t *yes, SPF_response_t *no)
00079 {
00080 SPF_response_free(no);
00081 return yes;
00082 }
00083
00084
00085
00086
00087
00088
00089 SPF_response_t *
00090 SPF_response_combine(SPF_response_t *main, SPF_response_t *r2mx)
00091 {
00092 switch (SPF_response_result(main)) {
00093 case SPF_RESULT_INVALID:
00094
00095 return SPF_response_choose(r2mx, main);
00096
00097 case SPF_RESULT_PASS:
00098
00099 return SPF_response_choose(main, r2mx);
00100
00101 case SPF_RESULT_NEUTRAL:
00102
00103 switch (SPF_response_result(r2mx)) {
00104 case SPF_RESULT_PASS:
00105
00106 return SPF_response_choose(r2mx, main);
00107 default:
00108
00109 return SPF_response_choose(main, r2mx);
00110 }
00111
00112 case SPF_RESULT_FAIL:
00113
00114 return SPF_response_choose(r2mx, main);
00115
00116 case SPF_RESULT_TEMPERROR:
00117 case SPF_RESULT_PERMERROR:
00118 case SPF_RESULT_SOFTFAIL:
00119 default:
00120
00121 switch (SPF_response_result(r2mx)) {
00122 case SPF_RESULT_PASS:
00123 case SPF_RESULT_NEUTRAL:
00124 case SPF_RESULT_SOFTFAIL:
00125
00126 return SPF_response_choose(r2mx, main);
00127 default:
00128
00129 return SPF_response_choose(main, r2mx);
00130 }
00131 }
00132 }
00133
00134 SPF_result_t
00135 SPF_response_result(SPF_response_t *rp)
00136 {
00137 return rp->result;
00138 }
00139
00140 SPF_reason_t
00141 SPF_response_reason(SPF_response_t *rp)
00142 {
00143 return rp->reason;
00144 }
00145
00146 SPF_errcode_t
00147 SPF_response_errcode(SPF_response_t *rp)
00148 {
00149 return rp->err;
00150 }
00151
00152 const char *
00153 SPF_response_get_received_spf(SPF_response_t *rp)
00154 {
00155 return rp->received_spf;
00156 }
00157
00158 const char *
00159 SPF_response_get_received_spf_value(SPF_response_t *rp)
00160 {
00161 return rp->received_spf_value;
00162 }
00163
00164 const char *
00165 SPF_response_get_header_comment(SPF_response_t *rp)
00166 {
00167 return rp->header_comment;
00168 }
00169
00170 const char *
00171 SPF_response_get_smtp_comment(SPF_response_t *rp)
00172 {
00173 return rp->smtp_comment;
00174 }
00175
00176 const char *
00177 SPF_response_get_explanation(SPF_response_t *rp)
00178 {
00179 return rp->explanation;
00180 }
00181
00182
00183
00184 #define SPF_ERRMSGSIZE 4096
00185
00186 static SPF_errcode_t
00187 SPF_response_add_error_v(SPF_response_t *rp,
00188 SPF_errcode_t code, int is_error,
00189 const char *text, int idx,
00190 const char *format, va_list ap)
00191 {
00192 SPF_error_t *tmp;
00193 char buf[SPF_ERRMSGSIZE];
00194 int size;
00195
00196
00197
00198 if (!format)
00199 format = SPF_strerror(code);
00200 size = vsnprintf(buf, sizeof(buf), format, ap);
00201 if (text != NULL) {
00202 snprintf(&buf[size], sizeof(buf) - size,
00203 " near '%.12s'", &text[idx]);
00204 }
00205 buf[SPF_ERRMSGSIZE - 1] = '\0';
00206
00207 if (rp->errors_length == rp->errors_size) {
00208 size = rp->errors_size + (rp->errors_size / 4) + 4;
00209 tmp = (SPF_error_t *)realloc(rp->errors, size * sizeof(SPF_error_t));
00210 if (! tmp) {
00211 SPF_error("Failed to allocate memory for extra response error");
00212 return code;
00213 }
00214 rp->errors = tmp;
00215 rp->errors_size = size;
00216 }
00217
00218 rp->errors[rp->errors_length].code = code;
00219 rp->errors[rp->errors_length].is_error = is_error;
00220
00221 rp->errors[rp->errors_length].message = strdup(buf);
00222 rp->errors_length++;
00223
00224 return code;
00225 }
00226
00227 #define SPF_ADD_ERROR(_ise, _txt, _ix) \
00228 va_list ap; va_start(ap, format); \
00229 SPF_response_add_error_v(rp, code, _ise, _txt, _ix, format, ap); \
00230 rp->num_errors++; \
00231 va_end(ap); return code;
00232 #define SPF_ADD_WARN(_ise, _txt, _ix) \
00233 va_list ap; va_start(ap, format); \
00234 SPF_response_add_error_v(rp, code, _ise, _txt, _ix, format, ap); \
00235 va_end(ap); return code;
00236
00237 SPF_errcode_t
00238 SPF_response_add_error_ptr(SPF_response_t *rp,
00239 SPF_errcode_t code,
00240 const char *text, const char *tptr,
00241 const char *format, ...)
00242 {
00243 SPF_ADD_ERROR(1, text ? text : tptr, text ? (tptr - text) : 0);
00244 }
00245
00246 SPF_errcode_t
00247 SPF_response_add_error_idx(SPF_response_t *rp,
00248 SPF_errcode_t code,
00249 const char *text, int idx,
00250 const char *format, ...)
00251 {
00252 SPF_ADD_ERROR(1, text, idx);
00253 }
00254
00255 SPF_errcode_t
00256 SPF_response_add_error(SPF_response_t *rp,
00257 SPF_errcode_t code,
00258 const char *format, ...)
00259 {
00260 SPF_ADD_ERROR(1, NULL, 0);
00261 }
00262
00263 SPF_errcode_t
00264 SPF_response_add_warn_ptr(SPF_response_t *rp,
00265 SPF_errcode_t code,
00266 const char *text, const char *tptr,
00267 const char *format, ...)
00268 {
00269 SPF_ADD_WARN(0, text ? text : tptr, text ? (tptr - text) : 0);
00270 }
00271
00272 SPF_errcode_t
00273 SPF_response_add_warn_idx(SPF_response_t *rp,
00274 SPF_errcode_t code,
00275 const char *text, int idx,
00276 const char *format, ...)
00277 {
00278 SPF_ADD_WARN(0, text, idx);
00279 }
00280
00281 SPF_errcode_t
00282 SPF_response_add_warn(SPF_response_t *rp,
00283 SPF_errcode_t code,
00284 const char *format, ...)
00285 {
00286 SPF_ADD_WARN(0, NULL, 0);
00287 }
00288
00289 int
00290 SPF_response_messages(SPF_response_t *rp)
00291 {
00292 return rp->errors_length;
00293 }
00294
00295 int
00296 SPF_response_errors(SPF_response_t *rp)
00297 {
00298 return rp->num_errors;
00299 }
00300
00301 int
00302 SPF_response_warnings(SPF_response_t *rp)
00303 {
00304 return rp->errors_length - rp->num_errors;
00305 }
00306
00307 SPF_error_t *
00308 SPF_response_message(SPF_response_t *rp, int idx)
00309 {
00310 return &rp->errors[idx];
00311 }
00312
00313 SPF_errcode_t
00314 SPF_error_code(SPF_error_t *err)
00315 {
00316 return err->code;
00317 }
00318
00319 const char *
00320 SPF_error_message(SPF_error_t *err)
00321 {
00322 return err->message;
00323 }
00324
00325 char
00326 SPF_error_errorp(SPF_error_t *err)
00327 {
00328 return err->is_error;
00329 }