libspf2
1.2.10
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of either: 00004 * 00005 * a) The GNU Lesser General Public License as published by the Free 00006 * Software Foundation; either version 2.1, or (at your option) any 00007 * later version, 00008 * 00009 * OR 00010 * 00011 * b) The two-clause BSD license. 00012 * 00013 * These licenses can be found with the distribution in the file LICENSES 00014 */ 00015 00016 00017 #include "spf_sys_config.h" 00018 00019 #ifdef STDC_HEADERS 00020 # include <stdio.h> /* stdin / stdout */ 00021 # include <stdlib.h> /* malloc / free */ 00022 #endif 00023 00024 #ifdef HAVE_STRING_H 00025 # include <string.h> /* strstr / strdup */ 00026 #else 00027 # ifdef HAVE_STRINGS_H 00028 # include <strings.h> /* strstr / strdup */ 00029 # endif 00030 #endif 00031 00032 #ifdef HAVE_NETDB_H 00033 #include <netdb.h> 00034 #endif 00035 00036 #ifdef HAVE_ARPA_NAMESER_H 00037 #include <arpa/nameser.h> 00038 #endif 00039 00040 00041 #include "spf.h" 00042 #include "spf_dns.h" 00043 #include "spf_internal.h" 00044 #include "spf_dns_internal.h" 00045 #include "spf_dns_rr.h" 00046 00052 SPF_dns_rr_t * 00053 SPF_dns_rr_new_nxdomain(SPF_dns_server_t *spf_dns_server, 00054 const char *domain) 00055 { 00056 return SPF_dns_rr_new_init(spf_dns_server, 00057 domain, ns_t_any, 0, HOST_NOT_FOUND); 00058 } 00059 00060 SPF_dns_rr_t * 00061 SPF_dns_rr_new_init(SPF_dns_server_t *spf_dns_server, 00062 const char *domain, 00063 ns_type rr_type, int ttl, 00064 SPF_dns_stat_t herrno) 00065 { 00066 SPF_dns_rr_t *spfrr; 00067 00068 spfrr = SPF_dns_rr_new(); 00069 if (spfrr == NULL) 00070 return spfrr; 00071 00072 spfrr->source = spf_dns_server; 00073 if (domain && (domain[0] != '\0')) { 00074 spfrr->domain = strdup(domain); 00075 if (spfrr->domain == NULL) { 00076 SPF_dns_rr_free(spfrr); 00077 return NULL; 00078 } 00079 spfrr->domain_buf_len = strlen(domain) + 1; 00080 } 00081 else { 00082 spfrr->domain = NULL; 00083 spfrr->domain_buf_len = 0; 00084 } 00085 spfrr->rr_type = rr_type; 00086 spfrr->ttl = ttl; 00087 spfrr->herrno = herrno; 00088 00089 return spfrr; 00090 } 00091 00092 SPF_dns_rr_t * 00093 SPF_dns_rr_new() 00094 { 00095 SPF_dns_rr_t *spfrr; 00096 00097 spfrr = malloc(sizeof(SPF_dns_rr_t)); 00098 if (spfrr == NULL) 00099 return spfrr; 00100 memset(spfrr, 0, sizeof(SPF_dns_rr_t)); 00101 00102 spfrr->domain = NULL; 00103 spfrr->domain_buf_len = 0; 00104 spfrr->rr_type = ns_t_invalid; 00105 spfrr->num_rr = 0; 00106 spfrr->ttl = 0; 00107 spfrr->utc_ttl = 0; 00108 spfrr->herrno = HOST_NOT_FOUND; 00109 00110 return spfrr; 00111 } 00112 00113 void 00114 SPF_dns_rr_free(SPF_dns_rr_t *spfrr) 00115 { 00116 int i; 00117 00118 if (spfrr->domain) 00119 free(spfrr->domain); 00120 if (spfrr->rr) { 00121 for (i = 0; i < spfrr->rr_buf_num; i++) 00122 if (spfrr->rr[i]) 00123 free(spfrr->rr[i]); 00124 free(spfrr->rr); 00125 } 00126 if (spfrr->rr_buf_len) 00127 free(spfrr->rr_buf_len); 00128 if(spfrr->hook) 00129 free(spfrr->hook); 00130 free(spfrr); 00131 } 00132 00133 SPF_errcode_t 00134 SPF_dns_rr_buf_realloc(SPF_dns_rr_t *spfrr, int idx, size_t len) 00135 { 00136 SPF_dns_rr_data_t **new_data; 00137 size_t *new_buf_len; 00138 int new_num; 00139 void *new_rr; 00140 int j; 00141 00142 if (spfrr->rr_buf_num <= idx) { 00143 /* allocate lots so we don't have to remalloc often */ 00144 new_num = spfrr->rr_buf_num + (idx + (idx >> 2) + 4 ); 00145 00146 new_data = realloc(spfrr->rr, 00147 new_num * sizeof(*new_data)); 00148 if (new_data == NULL) 00149 return SPF_E_NO_MEMORY; 00150 spfrr->rr = new_data; 00151 00152 new_buf_len = realloc(spfrr->rr_buf_len, 00153 new_num * sizeof(*new_buf_len)); 00154 if (new_buf_len == NULL) 00155 return SPF_E_NO_MEMORY; 00156 spfrr->rr_buf_len = new_buf_len; 00157 00158 for(j = spfrr->rr_buf_num; j < new_num; j++) { 00159 spfrr->rr[j] = NULL; 00160 spfrr->rr_buf_len[j] = 0; 00161 } 00162 00163 spfrr->rr_buf_num = new_num; 00164 } 00165 00166 if (len < sizeof(SPF_dns_rr_data_t)) 00167 len = sizeof(SPF_dns_rr_data_t); 00168 if (spfrr->rr_buf_len[idx] >= len) 00169 return SPF_E_SUCCESS; 00170 00171 new_rr = realloc(spfrr->rr[idx], len); 00172 if (new_rr == NULL) 00173 return SPF_E_NO_MEMORY; 00174 spfrr->rr[idx] = new_rr; 00175 spfrr->rr_buf_len[idx] = len; 00176 00177 return SPF_E_SUCCESS; 00178 } 00179 00180 00188 SPF_errcode_t 00189 SPF_dns_rr_dup(SPF_dns_rr_t **dstp, SPF_dns_rr_t *src) 00190 { 00191 SPF_dns_rr_t *dst; 00192 SPF_errcode_t err; 00193 int i; 00194 00195 SPF_ASSERT_NOTNULL(src); 00196 SPF_ASSERT_NOTNULL(dstp); 00197 dst = SPF_dns_rr_new_init(src->source, 00198 src->domain, src->rr_type, src->ttl, src->herrno); 00199 if (!dst) { 00200 *dstp = NULL; 00201 return SPF_E_NO_MEMORY; 00202 } 00203 *dstp = dst; 00204 00205 dst->utc_ttl = src->utc_ttl; 00206 dst->num_rr = src->num_rr; 00207 00208 #define SPF_DNS_RR_REALLOC(d, i, s) do { \ 00209 err = SPF_dns_rr_buf_realloc(d, i, s); \ 00210 if (err) return err; \ 00211 } while(0) 00212 00213 for (i = dst->num_rr - 1; i >= 0; i--) { 00214 switch (dst->rr_type) { 00215 case ns_t_a: 00216 SPF_DNS_RR_REALLOC(dst, i, sizeof(SPF_dns_rr_data_t)); 00217 dst->rr[i]->a = src->rr[i]->a; 00218 break; 00219 00220 case ns_t_ptr: 00221 SPF_DNS_RR_REALLOC(dst, i, strlen(src->rr[i]->ptr) + 1); 00222 strcpy(dst->rr[i]->ptr, src->rr[i]->ptr); 00223 break; 00224 00225 case ns_t_mx: 00226 SPF_DNS_RR_REALLOC(dst, i, strlen(src->rr[i]->mx) + 1); 00227 strcpy(dst->rr[i]->mx, src->rr[i]->mx); 00228 break; 00229 00230 case ns_t_txt: 00231 case ns_t_spf: 00232 SPF_DNS_RR_REALLOC(dst, i, strlen(src->rr[i]->txt) + 1); 00233 strcpy(dst->rr[i]->txt, src->rr[i]->txt); 00234 break; 00235 00236 case ns_t_aaaa: 00237 SPF_DNS_RR_REALLOC(dst, i, sizeof(SPF_dns_rr_data_t)); 00238 dst->rr[i]->aaaa = src->rr[i]->aaaa; 00239 break; 00240 00241 default: 00242 SPF_warningf("Attempt to dup unknown rr type %d", 00243 dst->rr_type); 00244 break; 00245 } 00246 } 00247 00248 return SPF_E_SUCCESS; 00249 }