00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
#ifdef _WITH_PTHREADS
00047
#include <pthread.h>
00048
#ifdef HAVE_GETHOSTBYNAME_R
00049
#include <errno.h>
00050
#endif
00051
#endif
00052
00053
#include "spf.h"
00054
#include "util.h"
00055
#include "dns.h"
00056
#include "../../config.h"
00057
00058
#ifdef _WITH_PTHREADS
00059
00060
00061 pthread_mutex_t
dns_mutex = PTHREAD_MUTEX_INITIALIZER;
00062
00063
#ifdef HAVE_GETHOSTBYNAME_R
00064
00065
00066
extern int errno;
00067
00068
#endif
00069
#else
00070
00071
00072 void *
dns_mutex;
00073
00074
#endif
00075
00076
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 char *
DNS_query(
peer_info_t *p,
const char *s,
const int T_TYPE,
00218
const char *mta)
00219 {
00220 HEADER *hdr;
00221
00222 int8_t ancount;
00223
00224 int16_t r_len;
00225 int16_t rc;
00226
00227
int ttl;
00228
00229
char buf[
SPF_MAXDNAME];
00230
char answer[
SPF_PACKETSZ];
00231
00232
char *rr_data = NULL;
00233
00234 u_char *msg_ptr;
00235 u_char *eom_ptr;
00236 u_char *rd_ptr;
00237
00238
00239
if (s == NULL)
00240 {
00241
xepprintf(
"Passed a NULL char. Aborting.\n");
00242
return(NULL);
00243 }
00244
00245
xprintf(
"Called with (%s) and type: %i\n", s, T_TYPE);
00246
00247 r_len = res_search(s, C_IN, T_TYPE, (u_char *)answer,
SPF_PACKETSZ);
00248
00249
if (r_len <= 0)
00250 {
00251
switch (
h_errno)
00252 {
00253
case HOST_NOT_FOUND:
00254 snprintf(p->
error,
SPF_MAX_ERROR,
"%s\n", hstrerror(
h_errno));
00255
UTIL_assoc_prefix(p,
SPF_NONE, NULL);
00256
xvprintf(
"%s\n", p->
error);
00257
00258
return(NULL);
00259
00260
case TRY_AGAIN:
00261 snprintf(p->
error,
SPF_MAX_ERROR,
"%s\n", hstrerror(
h_errno));
00262
UTIL_assoc_prefix(p,
SPF_NONE, NULL);
00263
xvprintf(
"%s\n", p->
error);
00264
00265
return(NULL);
00266
00267
case NO_RECOVERY:
00268 snprintf(p->
error,
SPF_MAX_ERROR,
"%s\n", hstrerror(
h_errno));
00269
UTIL_assoc_prefix(p,
SPF_ERROR, NULL);
00270
xvprintf(
"%s\n", p->
error);
00271
00272
return(NULL);
00273
00274
case NO_DATA:
00275 snprintf(p->
error,
SPF_MAX_ERROR,
"%s\n", hstrerror(
h_errno));
00276
UTIL_assoc_prefix(p,
SPF_NONE, NULL);
00277
xvprintf(
"%s\n", p->
error);
00278
00279
return(NULL);
00280
00281
default:
00282 snprintf(p->
error,
SPF_MAX_ERROR,
"%s\n", hstrerror(
h_errno));
00283
UTIL_assoc_prefix(p,
SPF_ERROR, NULL);
00284
xvprintf(
"%s\n", p->
error);
00285
00286
return(NULL);
00287 }
00288 }
00289
00290 hdr = (HEADER *)&answer;
00291 ancount = ntohs(hdr->ancount);
00292
00293
xvprintf(
"Received packet size of %i bytes which contains %i answers.\n",
00294 r_len, ancount);
00295
00296
xvprintf(
"ANSWERS: %i\n", ancount);
00297
xvprintf(
"QUESTIONS: %i\n", ntohs(hdr->qdcount));
00298
00299
if (ancount > 0)
00300 {
00301 msg_ptr = (u_char *)&answer;
00302 eom_ptr = (u_char *)&answer + r_len;
00303 rd_ptr = (u_char *)&answer + HFIXEDSZ;
00304
00305
if ((rc = dn_skipname(rd_ptr, eom_ptr)) < 0)
00306 {
00307
xepprintf(
"Error obtaining QUESTION!\n");
00308
00309
return(NULL);
00310 }
00311
00312 rd_ptr += rc + QFIXEDSZ;
00313
00314
switch (T_TYPE)
00315 {
00316
00317
00318
00319
00320
case T_A:
00321
return((
char *)
SPF_TRUE);
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
case T_TXT:
00333
if ((rr_data =
DNS_txt_answer(ancount, (u_char *)msg_ptr, (u_char *)eom_ptr,
00334 (u_char *)rd_ptr, buf, &ttl)) == NULL)
00335 {
00336
return(NULL);
00337 }
00338
break;
00339
00340
00341
00342
00343
00344
00345
case T_MX:
00346
if ((rr_data =
DNS_mx_answer(ancount, (u_char *)msg_ptr, (u_char *)eom_ptr,
00347 (u_char *)rd_ptr, buf, &ttl)) == NULL)
00348 {
00349
return(NULL);
00350 }
00351
break;
00352
00353
00354
00355
00356
00357
00358
case T_PTR:
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
if (
DNS_ptr_answer(p, ancount, (u_char *)msg_ptr, (u_char *)eom_ptr,
00372 (u_char *)rd_ptr, buf, mta, &ttl) ==
SPF_FALSE)
00373 {
00374
return((
char *)
SPF_FALSE);
00375 }
00376
else
00377 {
00378
return((
char *)
SPF_TRUE);
00379 }
00380
break;
00381
00382
00383
00384
00385
00386
case T_CNAME:
00387
if ((rr_data =
DNS_cname_answer(ancount, (u_char *)msg_ptr, (u_char *)eom_ptr,
00388 (u_char *)rd_ptr, buf, &ttl)) == NULL)
00389 {
00390
return(NULL);
00391 }
00392
break;
00393
default:
00394
break;
00395 }
00396
return(rr_data);
00397 }
00398
00399
return(NULL);
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 char *
DNS_txt_answer(int16_t ancount,
const u_char *msg_ptr,
00420
const u_char *eom_ptr, u_char *rd_ptr,
char *buf,
int *ttl)
00421 {
00422 int16_t i;
00423 int16_t j;
00424 int16_t rc;
00425 int16_t rd_type;
00426 int16_t rd_len;
00427
00428 int32_t rd_ttl;
00429
00430
char *rr_data = NULL;
00431
char *r_buf = NULL;
00432
char *pos = NULL;
00433
00434
00435
if ((msg_ptr == NULL) || (eom_ptr == NULL) ||
00436 (rd_ptr == NULL) || (buf == NULL))
00437 {
00438
xepprintf(
"Called with NULL pointers\n");
00439
return(NULL);
00440 }
00441
00442
xpprintf(
"entering function\n");
00443
00444 i = 0;
00445 j = ancount;
00446
while ((ancount > 0) && (rd_ptr < eom_ptr))
00447 {
00448
if ((rc = dn_expand(msg_ptr, eom_ptr, rd_ptr, buf,
SPF_MAXCDNAME)) < 0)
00449 {
00450
xvprintf(
"Unable to expand T_TXT response packet!; Reason: %s\n",
00451 hstrerror(
h_errno));
00452
00453
if (rr_data != NULL)
00454 {
00455
xfree(rr_data);
00456 }
00457
00458
return(NULL);
00459 }
00460
00461
00462 rd_ptr += rc;
00463 GETSHORT(rd_type, rd_ptr);
00464 rd_ptr += INT16SZ;
00465 GETLONG(rd_ttl, rd_ptr);
00466 GETSHORT(rd_len, rd_ptr);
00467
00468 *ttl = rd_ttl;
00469
00470
if (rd_type != T_TXT)
00471 {
00472
xvprintf(
"Ignoring record not of T_TXT type. (%i)\n", rd_type);
00473 rd_ptr += rd_len;
00474
continue;
00475 }
00476
00477 rd_ptr++;
00478
00479 rd_ptr[rd_len] =
'\0';
00480 rd_ptr[rd_len - 1] =
' ';
00481
00482 i += rd_len;
00483
00484
xvprintf(
"Answer %i has length %i. (%i)\n", ancount, rd_len, i);
00485
00486
00487
00488
00489
00490
if ((j == 1) && ((*rd_ptr !=
'v') && (*(rd_ptr + 1) !=
'=')))
00491 {
00492
xvprintf(
"INVALID Answer Data: (%s) len: %i\n", rd_ptr, rd_len);
00493
00494
if (rr_data != NULL)
00495 {
00496
xfree(rr_data);
00497 }
00498
00499
return(NULL);
00500 }
00501
00502
xvprintf(
"Answer Data: (%s) len: %i\n", rd_ptr, rd_len);
00503
00504
if ((rd_len <= SPF_MAXDNAME) && (rd_len > 0))
00505 {
00506
if (rr_data == NULL)
00507 {
00508 rr_data =
xmalloc(i + 1);
00509 }
00510
else
00511 {
00512 rr_data =
xrealloc(rr_data, (i + 1));
00513 }
00514
00515
xvprintf(
"REALLOCATE memory: %i bytes\n", i);
00516
00517 strncat(rr_data, (
char *)rd_ptr, rd_len);
00518 rr_data[i - 1] =
' ';
00519 rr_data[i] =
'\0';
00520 }
00521
00522 rd_ptr += rd_len;
00523 ancount--;
00524 }
00525
00526
if (rr_data == NULL)
00527 {
00528
xpprintf(
"rr_data is NULL (no ANSWERS in packet(s)), returning\n");
00529
00530
return(NULL);
00531 }
00532
00533 rr_data[i] =
'\0';
00534
00535
xvprintf(
"RR_DATA: (%s)\n", rr_data);
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
if ((*rr_data ==
'v') &&
00558 (*(rr_data + 1) ==
'=') &&
00559 (*(rr_data + 2) ==
's') &&
00560 (*(rr_data + 3) ==
'p') &&
00561 (*(rr_data + 4) ==
'f') &&
00562 (*(rr_data + 5) ==
'1'))
00563 {
00564
xvprintf(
"Returning with valid SPFv1 record: (%s)\n", rr_data);
00565
00566
return(rr_data);
00567 }
00568
else
00569 {
00570
00571
if ((pos = strstr(rr_data,
"v=spf1")) != NULL)
00572 {
00573
xvprintf(
"Found SPFv1 version mechanism: (%s)\n", pos);
00574
00575 r_buf =
xstrndup(pos,
SPF_MAX_STR);
00576 r_buf[strlen(pos)] =
'\0';
00577
00578
xvprintf(
"Old buffer: (%s)\n", rr_data);
00579
xvprintf(
"New buffer: (%s)\n", r_buf);
00580
00581 pos = NULL;
00582 }
00583
00584
00585
xfree(rr_data);
00586
00587
return(r_buf);
00588 }
00589
00590
xpprintf(
"Returning NULL (not a valid SPF TXT record)\n");
00591
00592
return(NULL);
00593 }
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 char *
DNS_mx_answer(int16_t ancount,
const u_char *msg_ptr,
00612
const u_char *eom_ptr, u_char *rd_ptr,
char *buf,
int *ttl)
00613 {
00614 size_t buf_len;
00615
00616 int16_t i;
00617 int16_t rc;
00618 int16_t rd_pref;
00619 int16_t rd_type;
00620 int16_t rd_len = 0;
00621
00622 int32_t rd_ttl;
00623
00624
char *rr_data = NULL;
00625
00626
00627 i = 0;
00628
while ((ancount > 0) && (rd_ptr < eom_ptr))
00629 {
00630
if ((rc = dn_expand(msg_ptr, eom_ptr, rd_ptr, buf,
SPF_MAXCDNAME)) < 0)
00631 {
00632
xvprintf(
"Error expanding ANSWER packet at count %i; Reason: %s \n",
00633 ancount, hstrerror(
h_errno));
00634
00635
return(NULL);
00636 }
00637
00638
00639 rd_ptr += rc;
00640 GETSHORT(rd_type, rd_ptr);
00641 rd_ptr += INT16SZ;
00642 GETLONG(rd_ttl, rd_ptr);
00643 GETSHORT(rd_len, rd_ptr);
00644
00645 *ttl = rd_ttl;
00646
00647
if (rd_type != T_MX)
00648 {
00649
xprintf(
"Forged packet?! We requested T_MX (15) but got %i\n", rd_type);
00650 rd_ptr += rd_len;
00651
continue;
00652 }
00653
00654 GETSHORT(rd_pref, rd_ptr);
00655
00656
if ((rc = dn_expand(msg_ptr, eom_ptr, rd_ptr, buf,
SPF_MAXCDNAME)) < 0)
00657 {
00658
xvprintf(
"Error expanding ANSWER packet at count %i; Reason: %s \n",
00659 ancount, hstrerror(
h_errno));
00660
00661
return(NULL);
00662 }
00663
00664
xvprintf(
"MX: %s Preference: %i\n", buf, rd_pref);
00665
00666 buf_len = strlen(buf);
00667 i += (buf_len + 1);
00668
00669
if ((rd_len <= SPF_MAXDNAME) && (rd_len > 0))
00670 {
00671
if (rr_data == NULL)
00672 {
00673 rr_data =
xmalloc(i + 1);
00674
00675 }
00676
else
00677 {
00678 rr_data =
xrealloc(rr_data, (i + 1));
00679 }
00680
00681
xvprintf(
"REALLOCATE memory: %i bytes\n", (i + 1));
00682
00683 strncat(rr_data, buf, buf_len);
00684 rr_data[i - 1] =
' ';
00685 rr_data[i] =
'\0';
00686 }
00687
00688 rd_ptr += rc;
00689 ancount--;
00690 }
00691
00692
if (rr_data != NULL)
00693 {
00694 rr_data[i - 1] =
'\0';
00695 }
00696
00697
return(rr_data);
00698 }
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716 SPF_BOOL DNS_ptr_answer(
peer_info_t *p, int16_t ancount,
00717
const u_char *msg_ptr,
const u_char *eom_ptr, u_char *rd_ptr,
char *buf,
00718
const char *mta,
int *ttl)
00719 {
00720 int16_t rc;
00721 int16_t rd_type;
00722 int16_t rd_len = 0;
00723
00724 int32_t rd_ttl;
00725
00726
char *buf_cmp = NULL;
00727
char *mta_cmp = NULL;
00728
00729
00730
while ((ancount > 0) && (rd_ptr < eom_ptr))
00731 {
00732
if ((rc = dn_expand(msg_ptr, eom_ptr, rd_ptr, buf,
SPF_MAXCDNAME)) < 0)
00733 {
00734
xvprintf(
"Error expanding ANSWER packet at count %i; Reason: %s \n",
00735 ancount, hstrerror(
h_errno));
00736
00737
return(
SPF_FALSE);
00738 }
00739
00740
00741 rd_ptr += rc;
00742 GETSHORT(rd_type, rd_ptr);
00743 rd_ptr += INT16SZ;
00744 GETLONG(rd_ttl, rd_ptr);
00745 GETSHORT(rd_len, rd_ptr);
00746
00747 *ttl = rd_ttl;
00748
00749
if (rd_type != T_PTR)
00750 {
00751 rc = dn_expand(msg_ptr, eom_ptr, rd_ptr, buf,
SPF_MAXCDNAME);
00752
00753
xvprintf(
"Error expanding ANSWER packet at count %i; Reason: %s \n",
00754 ancount, hstrerror(
h_errno));
00755
00756
xvprintf(
"Got answer to type %i (%s) when we asked for T_PTR (%i)\n",
00757 rd_type, buf, T_PTR);
00758
00759 rd_ptr += rd_len;
00760
continue;
00761 }
00762
00763
if ((rc = dn_expand(msg_ptr, eom_ptr, rd_ptr, buf,
SPF_MAXCDNAME)) < 0)
00764 {
00765
xvprintf(
"Error expanding ANSWER packet at count %i; Reason: %s \n",
00766 ancount, hstrerror(
h_errno));
00767
00768
xvprintf(
"Error expanding ANSWER packet at count %i. (%s)\n",
00769 ancount, buf);
00770
00771
return(
SPF_FALSE);
00772 }
00773
00774
xvprintf(
"Answer %i has length %i.\n", ancount, rd_len);
00775
xvprintf(
"Answer data (buffer): (%s); buffer length: %i\n",
00776 buf, strlen(buf));
00777
00778
if ((rd_len <= SPF_MAXDNAME) && (rd_len > 0))
00779 {
00780
if (
UTIL_validate_hostname(p, buf, 32) ==
SPF_FALSE)
00781 {
00782
xvprintf(
"Unable to validate hostname (%s) with (%s)\n",
00783 buf, mta);
00784
00785 rd_ptr += rc;
00786 ancount--;
00787
continue;
00788 }
00789
00790
00791
if (strlen(buf) < strlen(mta))
00792 {
00793
00794 rd_ptr += rc;
00795 ancount--;
00796
continue;
00797 }
00798
else if (strlen(buf) == strlen(mta))
00799 {
00800
if (strcasecmp(buf, mta) == 0)
00801 {
00802
return (
SPF_TRUE);
00803 }
00804
else
00805 {
00806 rd_ptr += rc;
00807 ancount--;
00808
continue;
00809 }
00810 }
00811
else
00812 {
00813 buf_cmp = &(buf[strlen(buf) - 1]);
00814 mta_cmp = (
char *)&(mta[strlen(mta) - 1]);
00815
00816
while (mta_cmp != mta - 1)
00817 {
00818
if (*mta_cmp-- != *buf_cmp--)
00819 {
00820 rd_ptr += rc;
00821 ancount--;
00822
continue;
00823 }
00824 }
00825
00826
if (*buf_cmp ==
'.')
00827 {
00828
return (
SPF_TRUE);
00829 }
00830
else
00831 {
00832 rd_ptr += rc;
00833 ancount--;
00834
continue;
00835 }
00836 }
00837 }
00838
else
00839 {
00840
xepprintf(
"Answer length is too long!\n");
00841 }
00842
00843 rd_ptr += rc;
00844 ancount--;
00845 }
00846
00847
return(
SPF_FALSE);
00848 }
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866 char *
DNS_cname_answer(int16_t ancount,
const u_char *msg_ptr,
00867
const u_char *eom_ptr, u_char *rd_ptr,
char *buf,
int *ttl)
00868 {
00869 int16_t i;
00870 int16_t rc;
00871 int16_t rd_type;
00872 int16_t rd_len;
00873
00874 int32_t rd_ttl;
00875
00876 size_t buf_len;
00877
00878
char *rr_data = NULL;
00879
00880
00881
if ((msg_ptr == NULL) || (eom_ptr == NULL) ||
00882 (rd_ptr == NULL) || (buf == NULL))
00883 {
00884
xepprintf(
"Called with NULL pointers\n");
00885
00886
return(NULL);
00887 }
00888
00889
xpprintf(
"entering function\n");
00890
00891 i = 0;
00892
while ((ancount > 0) && (rd_ptr < eom_ptr))
00893 {
00894
if ((rc = dn_expand(msg_ptr, eom_ptr, rd_ptr, buf,
SPF_MAXCDNAME)) < 0)
00895 {
00896
xvprintf(
"Error expanding ANSWER packet at count %i; Reason: %s \n",
00897 ancount, hstrerror(
h_errno));
00898
00899
return(NULL);
00900 }
00901
00902
00903 rd_ptr += rc;
00904 GETSHORT(rd_type, rd_ptr);
00905 rd_ptr += INT16SZ;
00906 GETLONG(rd_ttl, rd_ptr);
00907 GETSHORT(rd_len, rd_ptr);
00908
00909 *ttl = rd_ttl;
00910
00911
if (rd_type != T_CNAME)
00912 {
00913
xvprintf(
"Ignoring record not of T_CNAME type. (%i)\n", rd_type);
00914 rd_ptr += rd_len;
00915
continue;
00916 }
00917
00918
if (dn_expand(msg_ptr, eom_ptr, rd_ptr, buf,
SPF_MAXCDNAME) < 0)
00919 {
00920
xvprintf(
"Error expanding ANSWER packet at count %i; Reason: %s \n",
00921 ancount, hstrerror(
h_errno));
00922
00923
return(NULL);
00924 }
00925
00926 buf_len = strlen(buf);
00927 i += (buf_len + 1);
00928
00929
if ((rd_len <= SPF_MAXDNAME) && (rd_len > 0))
00930 {
00931
if (rr_data == NULL)
00932 {
00933 rr_data =
xmalloc(i + 1);
00934
00935 }
00936
else
00937 {
00938 rr_data =
xrealloc(rr_data, (i + 1));
00939 }
00940
00941
xvprintf(
"REALLOCATE memory: %i bytes\n", (i + 1));
00942
00943 strncat(rr_data, buf, buf_len);
00944 rr_data[i - 1] =
' ';
00945 rr_data[i] =
'\0';
00946 }
00947
00948 rd_ptr += rc;
00949 ancount--;
00950 }
00951
00952
if (rr_data != NULL)
00953 {
00954 rr_data[i - 1] =
'\0';
00955 }
00956
00957
xpprintf(
"leaving function\n");
00958
return(rr_data);
00959 }
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975 SPF_BOOL DNS_check_client_reverse(
peer_info_t *p)
00976 {
00977
00978 HEADER *hdr;
00979
00980 int8_t ancount;
00981
00982 int16_t rd_type;
00983 int16_t rd_len = 0;
00984 int16_t r_len;
00985 int16_t rc;
00986
00987
char buf[
SPF_MAXDNAME];
00988
char answer[
SPF_PACKETSZ];
00989
00990
char *addr_arpa = NULL;
00991
00992 u_char *msg_ptr;
00993 u_char *eom_ptr;
00994 u_char *rd_ptr;
00995
00996
00997
if (p == NULL)
00998 {
00999
xepprintf(
"Unable to continue, peer info struct is NULL!\n");
01000
01001
return(
SPF_FALSE);
01002 }
01003
01004
xpprintf(
"entering function\n");
01005
01006 addr_arpa =
UTIL_rev_addr(p->
r_ip);
01007
01008 r_len = res_search(addr_arpa, C_IN, T_PTR, (u_char *)answer,
01009
SPF_PACKETSZ);
01010
01011
xfree(addr_arpa);
01012
01013 hdr = (HEADER *)&answer;
01014 ancount = ntohs(hdr->ancount);
01015
01016
xvprintf(
"Received packet size of %i bytes which contains %i answers.\n",
01017 r_len, ancount);
01018
xvprintf(
"ANSWERS: %i\n", ancount);
01019
xvprintf(
"QUESTIONS: %i\n", ntohs(hdr->qdcount));
01020
01021
if (ancount > 0)
01022 {
01023 msg_ptr = (u_char *)&answer;
01024 eom_ptr = ((u_char *)&answer + r_len);
01025 rd_ptr = ((u_char *)&answer + HFIXEDSZ);
01026
01027
if ((rc = dn_skipname(rd_ptr, eom_ptr)) < 0)
01028 {
01029
xepprintf(
"Error obtaining QUESTION!\n");
01030
01031
return(
SPF_FALSE);
01032 }
01033
01034 rd_ptr += rc + QFIXEDSZ;
01035
01036
while ((ancount > 0) && (rd_ptr < eom_ptr))
01037 {
01038
if ((rc = dn_expand(msg_ptr, eom_ptr, rd_ptr, buf,
SPF_MAXCDNAME)) < 0)
01039 {
01040
xeprintf(
"Error expanding ANSWER packet at count %i. (%s)\n",
01041 ancount, buf);
01042
01043
return(
SPF_FALSE);
01044 }
01045
01046
01047 rd_ptr += rc;
01048 GETSHORT(rd_type, rd_ptr);
01049 rd_ptr += INT16SZ;
01050 rd_ptr += INT32SZ;
01051 GETSHORT(rd_len, rd_ptr);
01052
01053
if (rd_type != T_PTR)
01054 {
01055 rc = dn_expand(msg_ptr, eom_ptr, rd_ptr, buf,
SPF_MAXCDNAME);
01056
01057
xvprintf(
"Got answer to type %i (%s) when we asked for T_PTR (%i)\n",
01058 rd_type, buf, T_PTR);
01059
01060 rd_ptr += rd_len;
01061
continue;
01062 }
01063
01064
if ((rc = dn_expand(msg_ptr, eom_ptr, rd_ptr, buf,
SPF_MAXCDNAME)) < 0)
01065 {
01066
xvprintf(
"Error expanding ANSWER packet at count %i. (%s)\n",
01067 ancount, buf);
01068
01069
return(
SPF_FALSE);
01070 }
01071
01072
xvprintf(
"Answer %i has length %i.\n", ancount, rd_len);
01073
xvprintf(
"Answer data (buffer): (%s); data length: %i\n",
01074 buf, strlen(buf));
01075
01076
if ((rd_len <= SPF_MAXDNAME) && (rd_len > 0))
01077 {
01078
if (
UTIL_validate_hostname(p, buf, 32) ==
SPF_FALSE)
01079 {
01080
xvprintf(
"Unable to validate hostname (%s) with (%s)\n",
01081 buf, p->
r_ip);
01082
01083 rd_ptr += rc;
01084 ancount--;
01085
continue;
01086 }
01087
else
01088 {
01089
if (p->
r_vhname != NULL)
01090 {
01091
xfree(p->
r_vhname);
01092 }
01093
01094 p->
r_vhname =
xstrndup(buf, strlen(buf) + 1);
01095
01096
return(
SPF_TRUE);
01097 }
01098 }
01099
else
01100 {
01101
xepprintf(
"Answer length is too long!\n");
01102
continue;
01103 }
01104
01105 rd_ptr += rc;
01106 ancount--;
01107
01108 }
01109 }
01110
01111
return(
SPF_FALSE);
01112 }
01113
01114
#ifdef _WITH_PTHREADS
01115
#ifdef HAVE_GETHOSTBYNAME_R
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
struct hostent *_DNS_GNU_gethostbyname_r(
const char *name,
01132
struct hostent *result,
char *buf,
int buf_len,
int *h_errnop)
01133 {
01134
struct hostent *hp = NULL;
01135
01136
01137
if (!name)
01138 {
01139
xepprintf(
"ERROR: No hostname to resolve.\n");
01140
01141
return(NULL);
01142 }
01143
01144
xpprintf(
"entering function\n");
01145
01146
if (buf_len >=
SPF_MAX_STR)
01147 {
01148
xvprintf(
"buf_len (%i) is > max size (%i); Disregarded.\n",
01149 buf_len, SPF_MAX_STR);
01150
01151
return(NULL);
01152 }
01153
01154
xvprintf(
"called with hostname (%s)\n", name);
01155 memset(buf,
'\0', SPF_MAX_GHBNR_DBUF);
01156 hp =
xmalloc(
SIZEOF(
struct hostent));
01157
01158 gethostbyname_r(name, result, buf, (size_t)buf_len, &hp, h_errnop);
01159
01160
xpprintf(
"leaving function\n");
01161
01162
return(hp);
01163 }
01164
01165
#else
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
struct hostent *_DNS_gethostbyname_r(
const char *name,
01184
struct hostent *result,
char *buf,
int buf_len,
int *h_errnop)
01185 {
01186
struct hostent *hp;
01187
01188
if (!name)
01189 {
01190
xepprintf(
"ERROR: No hostname to resolve!\n");
01191
01192
return(NULL);
01193 }
01194
01195
xvprintf(
"called with hostname (%s)\n", name);
01196
01197
xpthread_mutex_lock(&dns_mutex);
01198
01199 hp = gethostbyname(name);
01200 *h_errnop =
h_errno;
01201
01202
xpprintf(
"leaving function\n");
01203
01204
return(hp);
01205 }
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
void _DNS_gethostbyname_r_free(
void)
01223 {
01224
xpthread_mutex_unlock(&dns_mutex);
01225
01226
return;
01227 }
01228
01229
#endif
01230
#endif
01231
01232
01233