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