"Fossies" - the Fresh Open Source Software Archive 
Member "libspf2-1.2.10/src/libspf2/spf_dns_windns.c" (28 Jan 2012, 11073 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_dns_windns.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 #ifdef _WIN32
17
18 #include "spf_sys_config.h"
19
20 #ifdef HAVE_ERRNO_H
21 #include <errno.h>
22 #endif
23
24 #ifdef STDC_HEADERS
25 # include <stdio.h> /* stdin / stdout */
26 # include <stdlib.h> /* malloc / free */
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 #include "spf.h"
38 #include "spf_dns.h"
39 #include "spf_internal.h"
40 #include "spf_dns_internal.h"
41 #include "spf_dns_windns.h"
42 #pragma comment(lib, "dnsapi.lib")
43 #include <windns.h>
44
45
46 typedef struct
47 {
48 int debug;
49 SPF_dns_rr_t spfrr;
50 } SPF_dns_windns_config_t;
51
52
53 #define SPF_h_errno WSAGetLastError()
54
55
56 static inline SPF_dns_windns_config_t *SPF_voidp2spfhook( void *hook )
57 { return (SPF_dns_windns_config_t *)hook; }
58 static inline void *SPF_spfhook2voidp( SPF_dns_windns_config_t *spfhook )
59 { return (void *)spfhook; }
60
61
62 LPSTR SPF_dns_create_error_message_windns(DWORD last_error)
63 {
64 LPSTR error_message;
65
66 if (!FormatMessageA(
67 (FORMAT_MESSAGE_ALLOCATE_BUFFER |
68 FORMAT_MESSAGE_FROM_SYSTEM |
69 FORMAT_MESSAGE_IGNORE_INSERTS),
70 NULL,
71 last_error,
72 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
73 (LPSTR) &error_message,
74 0,
75 NULL))
76 {
77 return NULL;
78 }
79
80 return error_message;
81 }
82
83
84 void SPF_dns_destroy_error_message_windns(LPSTR error_message)
85 {
86 LocalFree( error_message );
87 }
88
89
90 size_t SPF_dns_txt_get_length_windns(DWORD count, PSTR strings[])
91 {
92 size_t length;
93 DWORD i;
94
95 length = 0;
96
97 for( i = 0; i < count; i++ )
98 {
99 length = length + strlen(strings[i]);
100 }
101
102 return length;
103 }
104
105
106 char *SPF_dns_txt_concat_windns(char *buffer, DWORD count, PSTR strings[])
107 {
108 DWORD i;
109
110 buffer[0] = 0;
111
112 for( i = 0; i < count; i++ )
113 {
114 if ( strcat( buffer, strings[i] ) == NULL )
115 return NULL;
116 }
117
118 return buffer;
119 }
120
121
122 static SPF_dns_rr_t *SPF_dns_lookup_windns( SPF_dns_config_t spfdcid, const char *domain, ns_type rr_type, int should_cache )
123 {
124 SPF_dns_iconfig_t *spfdic = SPF_dcid2spfdic( spfdcid );
125 SPF_dns_windns_config_t *spfhook = SPF_voidp2spfhook( spfdic->hook );
126 SPF_dns_rr_t *spfrr;
127
128 int cnt;
129
130 PDNS_RECORDA pDnsRecord;
131
132 DNS_STATUS status;
133 LPSTR error_message;
134
135 char ip4_buf[ INET_ADDRSTRLEN ];
136 char ip6_buf[ INET6_ADDRSTRLEN ];
137
138 int rdlen;
139
140 DNS_A_DATA *pA_data;
141 DNS_AAAA_DATA *pAAAA_data;
142 DNS_MX_DATAA *pMX_data;
143 DNS_TXT_DATAA *pTXT_data;
144 DNS_PTR_DATAA *pPTR_data;
145
146 size_t txt_data_len;
147 char *txt_concat;
148
149
150 /*
151 * initialize stuff
152 */
153 spfrr = &spfhook->spfrr;
154 SPF_dns_reset_rr( spfrr );
155 spfrr->herrno = NO_RECOVERY;
156 spfrr->rr_type = rr_type;
157 if ( domain && domain[0] != '\0' )
158 {
159 char *new_domain;
160 size_t new_len = strlen( domain ) + 1;
161
162 if ( spfrr->domain_buf_len < new_len )
163 {
164 new_domain = realloc( spfrr->domain, new_len );
165 if ( new_domain == NULL )
166 return spfrr;
167
168 spfrr->domain = new_domain;
169 spfrr->domain_buf_len = new_len;
170 }
171 strcpy( spfrr->domain, domain );
172 }
173 else if ( spfrr->domain )
174 spfrr->domain[0] = '\0';
175
176 cnt = 0;
177
178 if ( spfhook->debug )
179 SPF_debugf( "WinDNS looking for: %s %s (%d)",
180 domain,
181 (
182 (rr_type == ns_t_a) ? "A" :
183 (rr_type == ns_t_aaaa) ? "AAAA" :
184 (rr_type == ns_t_mx) ? "MX" :
185 (rr_type == ns_t_txt) ? "TXT" :
186 (rr_type == ns_t_ptr) ? "PTR" :
187 (rr_type == ns_t_any) ? "ANY" :
188 "??"
189 ),
190 rr_type );
191
192
193 /*
194 * try resolving the name
195 */
196 status = DnsQuery_A( domain, rr_type,
197 (DNS_QUERY_STANDARD + DNS_QUERY_TREAT_AS_FQDN),
198 NULL, &pDnsRecord, NULL );
199
200 if ( status != DNS_RCODE_NOERROR )
201 {
202 if ( spfhook->debug )
203 {
204 error_message = SPF_dns_create_error_message_windns(SPF_h_errno);
205
206 SPF_debugf( "query failed: err = %d %s (%d)",
207 status, error_message, SPF_h_errno );
208
209 SPF_dns_destroy_error_message_windns(error_message);
210 }
211
212 if (
213 ( SPF_h_errno == HOST_NOT_FOUND ) &&
214 ( spfdic->layer_below )
215 )
216 return SPF_dcid2spfdic( spfdic->layer_below )->lookup( spfdic->layer_below, domain, rr_type, should_cache );
217
218 spfrr->herrno = SPF_h_errno;
219 return spfrr;
220 }
221 else
222 spfrr->herrno = NETDB_SUCCESS;
223
224 while (pDnsRecord)
225 {
226 rdlen = pDnsRecord->wDataLength;
227
228 if ( spfhook->debug > 1 )
229 SPF_debugf( "name: %s type: %d ttl: %d rdlen: %d",
230 pDnsRecord->pName, pDnsRecord->wType,
231 pDnsRecord->dwTtl, rdlen );
232
233 if ( rdlen <= 0 )
234 {
235 pDnsRecord = pDnsRecord->pNext;
236 continue;
237 }
238
239 /* No sense in doing this twice */
240 if (pDnsRecord->wType == ns_t_txt)
241 {
242 pTXT_data = &pDnsRecord->Data.TXT;
243
244 txt_data_len =
245 SPF_dns_txt_get_length_windns(
246 pTXT_data->dwStringCount,
247 pTXT_data->pStringArray
248 );
249 }
250
251 if ( spfhook->debug > 1 )
252 {
253 switch( pDnsRecord->wType )
254 {
255 case ns_t_a:
256
257 pA_data = &pDnsRecord->Data.A;
258
259 SPF_debugf( "A: %s",
260 inet_ntop( AF_INET, &pA_data->IpAddress,
261 ip4_buf, sizeof( ip4_buf ) ));
262 break;
263
264 case ns_t_aaaa:
265
266 pAAAA_data = &pDnsRecord->Data.AAAA;
267
268 SPF_debugf( "AAAA: %s",
269 inet_ntop( AF_INET6, &pAAAA_data->Ip6Address,
270 ip6_buf, sizeof( ip6_buf ) ));
271 break;
272
273 case ns_t_ns:
274
275 SPF_debugf( "NS: %s", pDnsRecord->Data.NS.pNameHost );
276 break;
277
278 case ns_t_cname:
279
280 SPF_debugf( "CNAME: %s", pDnsRecord->Data.CNAME.pNameHost );
281 break;
282
283 case ns_t_mx:
284
285 pMX_data = &pDnsRecord->Data.MX;
286
287 SPF_debugf( "MX: %d %s",
288 pMX_data->wPreference, pMX_data->pNameExchange );
289 break;
290
291 case ns_t_txt:
292
293 txt_concat = malloc(txt_data_len + 1);
294
295 if ( txt_concat == NULL )
296 SPF_debugf( "TXT: (%d) - no memory for concatination",
297 txt_data_len );
298 else
299 {
300 if ( SPF_dns_txt_concat_windns(
301 txt_concat,
302 pTXT_data->dwStringCount,
303 pTXT_data->pStringArray
304 ) == NULL )
305 SPF_debugf( "TXT: (%d) - error in concatination",
306 txt_data_len );
307 else
308 {
309 SPF_debugf( "TXT: (%d) \"%s\"",
310 txt_data_len, txt_concat );
311 }
312 free( txt_concat );
313 }
314 break;
315
316 case ns_t_ptr:
317
318 pPTR_data = &pDnsRecord->Data.PTR;
319
320 SPF_debugf( "PTR: %s", pPTR_data->pNameHost );
321 break;
322
323 default:
324 SPF_debugf( "not parsed: type: %d", pDnsRecord->wType );
325 break;
326 }
327 }
328
329 if (
330 ( pDnsRecord->Flags.S.Section != DNSREC_ANSWER ) &&
331 ( spfhook->debug > 1 )
332 )
333 {
334 pDnsRecord = pDnsRecord->pNext;
335 continue;
336 }
337
338
339 if (
340 ( pDnsRecord->wType != spfrr->rr_type ) &&
341 ( pDnsRecord->wType != ns_t_cname )
342 )
343 {
344 SPF_debugf( "unexpected rr type: %d expected: %d",
345 pDnsRecord->wType, rr_type );
346 pDnsRecord = pDnsRecord->pNext;
347 continue;
348 }
349
350 switch( pDnsRecord->wType )
351 {
352 case ns_t_a:
353
354 pA_data = &pDnsRecord->Data.A;
355
356 if ( SPF_dns_rr_buf_malloc(
357 spfrr, cnt, sizeof( pA_data->IpAddress )
358 ) != SPF_E_SUCCESS )
359 return spfrr;
360
361 memmove( &spfrr->rr[cnt]->a, &pA_data->IpAddress,
362 sizeof( pA_data->IpAddress ) );
363
364 cnt++;
365 break;
366
367 case ns_t_aaaa:
368
369 pAAAA_data = &pDnsRecord->Data.AAAA;
370
371 if ( SPF_dns_rr_buf_malloc(
372 spfrr, cnt, sizeof( pAAAA_data->Ip6Address )
373 ) != SPF_E_SUCCESS )
374 return spfrr;
375
376 memmove( &spfrr->rr[cnt]->aaaa, &pAAAA_data->Ip6Address,
377 sizeof( pAAAA_data->Ip6Address ) );
378
379 cnt++;
380 break;
381
382 case ns_t_ns:
383 break;
384
385 case ns_t_cname:
386 /* FIXME: are CNAMEs always sent with the real RR? */
387 break;
388
389 case ns_t_mx:
390
391 pMX_data = &pDnsRecord->Data.MX;
392
393 if ( SPF_dns_rr_buf_malloc(
394 spfrr, cnt, strlen( pMX_data->pNameExchange ) + 1
395 ) != SPF_E_SUCCESS )
396 return spfrr;
397
398 strcpy( spfrr->rr[cnt]->mx, pMX_data->pNameExchange );
399
400 cnt++;
401 break;
402
403 case ns_t_txt:
404
405 if ( SPF_dns_rr_buf_malloc(
406 spfrr, cnt, txt_data_len + 1
407 ) != SPF_E_SUCCESS )
408 return spfrr;
409
410 if ( SPF_dns_txt_concat_windns(
411 spfrr->rr[cnt]->txt,
412 pTXT_data->dwStringCount,
413 pTXT_data->pStringArray
414 ) == NULL )
415 return spfrr;
416
417 cnt++;
418 break;
419
420 case ns_t_ptr:
421
422 pPTR_data = &pDnsRecord->Data.PTR;
423
424 if ( SPF_dns_rr_buf_malloc(
425 spfrr, cnt, strlen( pPTR_data->pNameHost ) + 1
426 ) != SPF_E_SUCCESS )
427 return spfrr;
428
429 strcpy( spfrr->rr[cnt]->ptr, pPTR_data->pNameHost );
430
431 cnt++;
432 break;
433
434 default:
435 break;
436 }
437
438 spfrr->num_rr = cnt;
439
440 pDnsRecord = pDnsRecord->pNext;
441 }
442
443 if ( spfrr->num_rr == 0 )
444 spfhook->spfrr.herrno = NO_DATA;
445
446 return spfrr;
447 }
448
449
450 SPF_dns_config_t SPF_dns_create_config_windns( SPF_dns_config_t layer_below, int debug )
451 {
452 SPF_dns_iconfig_t *spfdic;
453 SPF_dns_windns_config_t *spfhook;
454
455
456 spfdic = malloc( sizeof( *spfdic ) );
457 if ( spfdic == NULL )
458 return NULL;
459
460 spfdic->hook = calloc( 1, sizeof( SPF_dns_windns_config_t ) );
461 if ( spfdic->hook == NULL )
462 {
463 free( spfdic );
464 return NULL;
465 }
466
467 spfdic->destroy = SPF_dns_destroy_config_windns;
468 spfdic->lookup = SPF_dns_lookup_windns;
469 spfdic->get_spf = NULL;
470 spfdic->get_exp = NULL;
471 spfdic->add_cache = NULL;
472 spfdic->layer_below = layer_below;
473 spfdic->name = "windns";
474
475 spfhook = SPF_voidp2spfhook( spfdic->hook );
476
477 spfhook->debug = debug;
478 SPF_dns_reset_rr( &spfhook->spfrr );
479 spfhook->spfrr.source = SPF_spfdic2dcid( spfdic );
480
481 return SPF_spfdic2dcid( spfdic );
482 }
483
484 void SPF_dns_reset_config_windns( SPF_dns_config_t spfdcid )
485 {
486 SPF_dns_iconfig_t *spfdic = SPF_dcid2spfdic( spfdcid );
487
488
489 if ( spfdcid == NULL )
490 SPF_error( "spfdcid is NULL" );
491
492
493 SPF_dns_reset_rr( &(SPF_voidp2spfhook( spfdic->hook )->spfrr) );
494 }
495
496 void SPF_dns_destroy_config_windns( SPF_dns_config_t spfdcid )
497 {
498 SPF_dns_iconfig_t *spfdic = SPF_dcid2spfdic( spfdcid );
499
500 if ( spfdcid == NULL )
501 SPF_error( "spfdcid is NULL" );
502
503 if ( spfdic->hook )
504 {
505 SPF_dns_windns_config_t *spfhook = SPF_voidp2spfhook( spfdic->hook );
506
507 SPF_dns_destroy_rr_var( &spfhook->spfrr );
508
509 free( spfdic->hook );
510 }
511
512 if ( spfdic )
513 free( spfdic );
514 }
515
516 #endif