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