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