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 
#include "spf.h"
00046 
#include "dns.h"
00047 
#include "macro.h"
00048 
#include "util.h"
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 char *
MACRO_expand(
peer_info_t *p, 
const char *s)
00072 {
00073   
const char * 
const macro_p = 
"%";     
00074   
const char * 
const macro_d = 
"%20";   
00075   
const char * 
const macro_u = 
" ";     
00076 
00077   
char *buf;                            
00078   
char *ptr;                            
00079   
char *cp;                             
00080   
char *macro;
00081   
char *s_macro;                        
00082 
00083   
strbuf_t *master;                     
00084   
strbuf_node_t *c_node;                
00085   
strbuf_node_t *kill_node;             
00086 
00087   size_t len;                           
00088   size_t i = 0;                         
00089   size_t length = 0;                    
00090 
00091 
00092   
if (s == NULL)
00093   {
00094     
xepprintf(
"Passed a NULL string.  Abort!\n");
00095     
return(NULL);
00096   }
00097 
00098   len = strlen(s);
00099   ptr = cp = 
xstrndup(s, (len + 1));
00100 
00101   master = 
xmalloc(
SIZEOF(
strbuf_t));
00102   master->
head      = NULL;
00103   master->
elements  = 0;
00104   length            = 0;
00105 
00106   
while (*ptr)
00107   {
00108      
00109 
00110 
00111 
00112 
00113 
00114     
if (*ptr == 
'%') 
00115     {
00116       
switch (*(ptr + 1))
00117       {
00118         
case '%':
00119 
00120           
00121           
if (
MACRO_addbuf(master, (
char *)macro_p, 1) == 
SPF_FALSE)
00122           {
00123             
xvprintf(
"Unable to allocate list node with (%c)!\n", macro_p);
00124 
00125             
return(NULL);
00126           }
00127 
00128           ptr += 2;
00129           length++;
00130           
break;
00131 
00132         
case '_':
00133 
00134           
00135           
if (
MACRO_addbuf(master, (
char *)macro_u, 1) == 
SPF_FALSE)
00136           {
00137             
xvprintf(
"Unable to allocate list node with (%c)!\n", macro_u);
00138 
00139             
return(NULL);
00140           }
00141 
00142           ptr += 2;
00143           length++;
00144           
break;
00145 
00146         
case '-':
00147 
00148           
00149           
if (
MACRO_addbuf(master, (
char *)macro_d, 3) == 
SPF_FALSE)
00150           {
00151             
xvprintf(
"Unable to allocate list node with (%s)!\n", macro_d);
00152 
00153             
return(NULL);
00154           }
00155 
00156           ptr    += 2;
00157           length += 3;
00158           
break;
00159 
00160         
case '{':
00161 
00162           *ptr++ = 
'\0'; 
00163           *ptr++ = 
'\0'; 
00164 
00165           
if ((i = 
UTIL_index(ptr, 
'}')) == 0)
00166           {
00167             
xvprintf(
"'}' Invalid Macro (%c)\n", *(s + 1));
00168 
00169             
return(NULL);  
00170           }
00171 
00172           *(ptr + i) = 
'\0'; 
00173 
00174           
xvprintf(
"Actual macro (%s)\n", ptr);
00175           
if ((macro = 
MACRO_process(p, ptr, (i + 1))) == NULL)
00176           {
00177             
xepprintf(
"macro process returned null!\n");
00178           }
00179           
else
00180           {
00181             length += strlen(macro);
00182             
xvprintf(
"Macro expanded to: (%s) %i bytes\n", macro,
00183               strlen(macro));
00184 
00185             
if (
MACRO_addbuf(master, macro, strlen(macro)) == 
SPF_FALSE)
00186             {
00187               
xvprintf(
"Unable to allocate list node with (%s)!\n", macro);
00188               
xfree(macro);
00189 
00190               
return(NULL);  
00191             }
00192             
xfree(macro);
00193           }
00194           ptr += i;
00195           
break;
00196 
00197         
default:
00198 
00199           
xvprintf(
"ERROR: Invalid macro. (%s) Abort!\n", *(ptr + 1));
00200 
00201           
00202           
return(NULL);
00203           
break;
00204 
00205       } 
00206     } 
00207     
else
00208     {
00209       
if ((i = 
UTIL_index(ptr, 
'%')) == 0)
00210       {
00211         
while (*(ptr + i))
00212         {
00213           i++;
00214         }
00215         s_macro = 
xmalloc(i + 1);
00216         memcpy(s_macro, ptr, (i + 1));
00217       }
00218       
else
00219       {
00220         s_macro = 
xmalloc(i + 1);
00221         memcpy(s_macro, ptr, i);
00222       }
00223 
00224       length += i;
00225 
00226       
if (
MACRO_addbuf(master, s_macro, (i + 1)) == 
SPF_FALSE)
00227       {
00228         
xvprintf(
"Unable to allocate list node with (%s)!\n", s_macro);
00229 
00230         
return(NULL);
00231       }
00232 
00233       ptr += (i - 1);
00234       
xvprintf(
"Freeing s_macro temp buf (%s)\n", s_macro);
00235       
xfree(s_macro);
00236     }
00237     ptr++;
00238     
xvprintf(
"Remaining buffer (%s)\n", ptr);
00239   } 
00240 
00241   
xprintf(
"Allocated %i bytes for return buf\n", length);
00242   buf = 
xmalloc(length + 1);
00243 
00244   c_node = master->
head;
00245   
while (c_node != NULL)
00246   {
00247     kill_node = c_node;
00248 
00249     
if (kill_node->
len > 1)
00250     {
00251       
xvprintf(
"NODE: (%s) LEN: %i\n", kill_node->
s, kill_node->
len);
00252     }
00253     
else
00254     {
00255       
xvprintf(
"NODE: (%c) LEN: %i\n", kill_node->
s, kill_node->
len);
00256     }
00257 
00258     strncat(buf, kill_node->
s, kill_node->
len);
00259     
xfree(kill_node->
s);
00260     c_node = c_node->next;
00261     
xfree(kill_node);
00262   }
00263 
00264   
xfree(cp);
00265   
xfree(master);
00266 
00267   
xvprintf(
"Returning expanded macro: (%s)\n", buf);
00268 
00269   
return(buf);
00270 }
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 char *
MACRO_process(
peer_info_t *p, 
char *macro, 
const size_t size)
00302 {
00303   
int c;             
00304 
00305   size_t i;          
00306 
00307   
char *rev_addr;    
00308 
00309 
00310   
if (macro == NULL)
00311   {
00312     
xepprintf(
"Passed a NULL string.  Abort!\n");
00313 
00314     
return(
SPF_FALSE);
00315   }
00316 
00317   
xprintf(
"called with (%s) and len: %i\n",macro, size);
00318 
00319   rev_addr = NULL;
00320   i = 0;
00321 
00322   
if (isupper(*macro))
00323   {
00324     c = tolower(*macro);
00325   }
00326   
else
00327   {
00328     c = *macro;
00329   }
00330 
00331   
switch (c)
00332   {
00333     
00334     
case 'd':
00335       
if (*(macro + 1))
00336       {
00337         
return(
MACRO_eatmore(macro, p->
current_domain));
00338       }
00339       
else
00340       {
00341         
xvprintf(
"macro 'd' expands to: (%s)\n",
00342           p->
current_domain);
00343 
00344         
return(
xstrndup(p->
current_domain, 
SPF_MAX_STR));
00345       }
00346     
00347     
case 'h':
00348       
if (*(macro + 1))
00349       {
00350         
return(
MACRO_eatmore(macro, p->
helo));
00351       }
00352       
else
00353       {
00354         
xvprintf(
"macro 'h' expands to: (%s)\n", p->
helo);
00355 
00356         
if (p->
helo != NULL)
00357         {
00358           
return(
xstrndup(p->
helo, 
SPF_MAX_ENV_HELO));
00359         }
00360         
else
00361         {
00362           
return(
xstrndup(p->
ehlo, 
SPF_MAX_ENV_HELO));
00363         }
00364       }
00365     
00366     
case 'i':
00367       
if (*(macro + 1))
00368       {
00369         
return(
MACRO_eatmore(macro, p->
r_ip));
00370       }
00371       
else
00372       {
00373         
xvprintf(
"macro 'i' expands to: (%s)\n", p->
r_ip);
00374 
00375         
return(
xstrndup(p->
r_ip, 
SPF_MAX_IP_ADDR));
00376       }
00377     
00378     
case 'l':
00379       
if (*(macro + 1))
00380       {
00381         
return(
MACRO_eatmore(macro, p->
local_part));
00382       }
00383       
else
00384       {
00385         
xvprintf(
"macro 'l' expands to: (%s)\n", p->
local_part);
00386 
00387         
return(
xstrndup(p->
local_part, 
SPF_MAX_LOCAL_PART));
00388       }
00389     
00390     
case 'o':
00391       
if (*(macro + 1))
00392       {
00393         
return(
MACRO_eatmore(macro, p->
current_domain));
00394       }
00395       
else
00396       {
00397         
xvprintf(
"macro 'o' expands to: (%s)\n",
00398           p->
current_domain);
00399 
00400         
return(
xstrndup(p->
current_domain, 
SPF_MAX_STR));
00401       }
00402     
00403     
case 'p':
00404       
if (
DNS_check_client_reverse(p) == 
SPF_FALSE)
00405       {
00406         p->
r_vhname = 
xmalloc(8);
00407         snprintf(p->
r_vhname, 8, 
"unknown");
00408       }
00409 
00410       
if (*(macro + 1))
00411       {
00412         
xvprintf(
"macro 'p' expands to: (%s)\n", p->
r_vhname);
00413 
00414         
return(
MACRO_eatmore(macro, p->
r_vhname));
00415       }
00416       
else
00417       {
00418         
xvprintf(
"macro 'p' expands to: (%s)\n", p->
r_vhname);
00419 
00420         
return(
xstrndup(p->
r_vhname, 
SPF_MAX_STR));
00421       }
00422     
00423     
case 's':
00424 
00425       
if ((p->
cur_eaddr != NULL) || p->
cur_eaddr)
00426       {
00427         
xfree(p->
cur_eaddr);
00428       }
00429 
00430       
xprintf(
"local-part: (%s); current domain: (%s)\n",
00431         p->
local_part, p->
current_domain);
00432       i = ((strlen(p->
local_part) + strlen(p->
current_domain) + 2));
00433       p->
cur_eaddr = 
xmalloc(i);
00434       snprintf(p->
cur_eaddr, i, 
"%s@%s",
00435         p->
local_part, p->
current_domain);
00436 
00437       
if (*(macro + 1))
00438       {
00439         
return(
MACRO_eatmore(macro, p->
cur_eaddr));
00440       }
00441       
else
00442       {
00443         
xvprintf(
"macro 's' expands to: (%s)\n", p->
cur_eaddr);
00444 
00445         
return(
xstrndup(p->
cur_eaddr, 
SPF_MAX_STR));
00446       }
00447     
00448     
case 't':
00449       
if (*(macro + 1))
00450       {
00451         
return(
MACRO_eatmore(macro, p->
utc_time));
00452       }
00453       
else
00454       {
00455         
xvprintf(
"macro 't' expands to: (%s)\n", p->
utc_time);
00456 
00457         
return(
xstrndup(p->
utc_time, 
SPF_MAX_UTC_TIME));
00458       }
00459     
00460     
case 'v':
00461       
if (*(macro + 1))
00462       {
00463         
return(
MACRO_eatmore(macro, p->
ip_ver));
00464       }
00465       
else
00466       {
00467         
xvprintf(
"macro 'v' expands to: (%s)\n", p->
ip_ver);
00468         
return(
xstrndup(p->
ip_ver, 
SPF_MAX_IP_ADDR));
00469       }
00470     
00471     
case 'x':
00472       
if (size > 1)
00473       {
00474         
if (*(macro + 1) == 
'R' || *(macro + 1) == 
'r')
00475         {
00476           
return(
xstrndup(p->
mta_hname, 
SPF_MAX_HNAME));
00477         }
00478       }
00479       
break;
00480 
00481     
default:
00482       
return(
xstrndup(macro, 
SPF_MAX_STR));
00483   } 
00484 
00485   
return(NULL);
00486 }
00487 
00488 
00489 
00490 
00491 
00492 
00493 
00494 
00495 
00496 
00497 
00498 
00499 
00500 
00501 
00502 
00503 
00504 
00505 char *
MACRO_eatmore(
char *macro, 
char *s)
00506 {
00507   size_t i;          
00508 
00509   
char delim;        
00510 
00511   
char *cp;          
00512   
char *buf;         
00513   
char *rev_str;     
00514   
char *d_buf;       
00515 
00516   u_int8_t n_dot;    
00517   u_int8_t rev;      
00518   u_int8_t digit;    
00519 
00520 
00521   
if (macro == NULL)
00522   {
00523     
xepprintf(
"Passed a NULL string.  Abort!\n");
00524     
return(NULL);
00525   }
00526 
00527   
xprintf(
"Called with macro (%s) and string (%s)\n", macro, s);
00528 
00529   
00530 
00531 
00532   cp      = macro;
00533   rev     = 0;
00534   digit   = 0;
00535   delim   = 
'.';
00536   buf     = NULL;
00537   rev_str = NULL;
00538 
00539   
while (*cp)
00540   {
00541     
if (isdigit(*cp))
00542     {
00543       digit = atoi(cp);
00544     }
00545     
else if (
UTIL_is_spf_delim(*cp) == 
SPF_TRUE)
00546     {
00547       delim = *cp;
00548     }
00549     
else if ((*cp == 
'r') || (*cp == 
'R'))
00550     {
00551       rev = 1;
00552     }
00553     cp++;
00554   }
00555 
00556   
xvprintf(
"mac:(%s) r:(%i) dig:(%i) dlm: (%c)\n",
00557     macro, rev, digit, delim);
00558 
00559   i = 0;
00560   
00561   
if (rev == 1)
00562   {
00563     
00564     rev_str = 
UTIL_reverse(s, delim);
00565     s = NULL;
00566   }
00567 
00568   
if (s == NULL)
00569   {
00570     cp = rev_str;
00571   }
00572   
else
00573   {
00574     cp = s;
00575   }
00576 
00577   
00578   
if (digit > 0)
00579   {
00580     n_dot = 
UTIL_count_delim(cp, delim);
00581 
00582     
if (digit > n_dot)
00583     {
00584       digit = n_dot;
00585     }
00586 
00587     
if ((d_buf = 
UTIL_split_strr(cp, delim, digit)) != NULL)
00588     {
00589       i = strlen(d_buf);
00590     }
00591     
else
00592     {
00593       d_buf = cp;
00594       i = strlen(d_buf);
00595     }
00596 
00597     buf = 
xmalloc(i + 1);
00598     memcpy(buf, d_buf, (i + 1));
00599 
00600     
if (d_buf != cp)
00601     {
00602       
xfree(d_buf);
00603     }
00604   }
00605   
else if (rev == 1)
00606   {
00607     buf = 
xstrndup(rev_str, 
SPF_MAX_MACRO);
00608   }
00609 
00610   
xvprintf(
"Returning (%s) (%i bytes)\n", buf, strlen(buf));
00611 
00612   
if (rev == 1)
00613   {
00614     
xfree(rev_str);
00615   }
00616 
00617   
return(buf);
00618 }
00619 
00620 
00621 
00622 
00623 
00624 
00625 
00626 
00627 
00628 
00629 
00630 
00631 
00632 
00633 
00634 
00635 
00636 
00637 
00638 SPF_BOOL MACRO_addbuf(
strbuf_t *master, 
char *s, size_t size)
00639 {
00640   
strbuf_node_t *c_node     = NULL;  
00641   
strbuf_node_t *new_node   = NULL;  
00642   
strbuf_node_t *prev_node  = NULL;  
00643 
00644 
00645   
if (s == NULL)
00646   {
00647     
xepprintf(
"Passed a NULL string.  Abort!\n");
00648 
00649     
return(
SPF_FALSE);
00650   }
00651 
00652   
xvprintf(
"Called with (%s) %i (%i) bytes.\n", s, size, strlen(s));
00653 
00654   new_node    = 
xmalloc(
SIZEOF(
strbuf_node_t));
00655   new_node->
s = 
xmalloc(size + 1);
00656 
00657   strncpy(new_node->
s, s, size);
00658   new_node->
len   = size;
00659   new_node->
next  = NULL;
00660 
00661   
xvprintf(
"Added (%s) to node of len: %i)\n", new_node->
s,
00662     new_node->
len);
00663 
00664   prev_node = NULL;
00665   c_node    = master->
head;
00666 
00667   
00668   
while (c_node != NULL)
00669   {
00670     prev_node = c_node;
00671     c_node    = c_node->
next;
00672   }
00673 
00674   
if (prev_node != NULL)
00675   {
00676     new_node->
next  = prev_node->
next;
00677     prev_node->
next = new_node;
00678   }
00679   
else
00680   {
00681     master->
head = new_node;
00682   }
00683 
00684   master->
elements++;
00685 
00686   
return(
SPF_TRUE);
00687 }
00688 
00689 
00690