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
#ifdef _WITH_PTHREADS
00046
#include <pthread.h>
00047
#endif
00048
00049
#include "util.h"
00050
#include "dns.h"
00051
00052
#undef VERSION
00053
00054
00055
#ifdef _WITH_PTHREADS
00056
00057
00058
00059
00060
00061
00062 pthread_mutex_t
util_mutex;
00063
00064
#else
00065
00066 void *
util_mutex;
00067
00068
#endif
00069
00070
00071
00072
00073
00074
00075
00076
00077
extern int errno;
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 void _pprintf_dbg(u_int8_t level,
const char *func,
const char * file,
00098
const size_t line,
const char *s)
00099 {
00100
char *buf;
00101
00102
00103
if (!s)
00104 {
00105 fprintf(stderr,
"_eprintf_dbg passed a NULL string\n");
00106 fflush(stderr);
00107
00108
return;
00109 }
00110
00111 buf =
xmalloc(
SPF_MAX_DEBUG + 1);
00112 snprintf(buf,
SPF_MAX_DEBUG,
"[%s :: %s->%i]; %s", func, file, line, s);
00113
00114
if (
f_bit_set(
confg.
level, level))
00115 {
00116
if (level ==
FL_D)
00117 {
00118 fprintf(stdout, buf);
00119 fflush(stdout);
00120 }
00121 }
00122
00123
if (level ==
FL_F)
00124 {
00125 fprintf(stderr, buf);
00126 fflush(stderr);
00127 }
00128
00129
xfree(buf);
00130
00131
return;
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 void _printf_dbg(u_int8_t level,
const char *func,
const char *file,
00155
const size_t line,
const char *format,...)
00156 {
00157
#ifdef _SPF_DEBUG_LOGFILE
00158
FILE *fp = NULL;
00159
#endif
00160
00161
char *buf;
00162
char *tbuf;
00163
00164 va_list argptr;
00165
00166
00167
xpthread_mutex_lock(&
util_mutex);
00168
00169
if (!format || *format ==
'\0')
00170 {
00171 fprintf(stderr,
"_printf_dbg passed null format array\n");
00172 fflush(stderr);
00173
00174
return;
00175 }
00176
00177 buf =
xmalloc(
SPF_MAX_DEBUG + 1);
00178 tbuf =
xmalloc(
SPF_MAX_DEBUG + 1);
00179
00180 va_start(argptr, format);
00181 vsnprintf(buf,
SPF_MAX_DEBUG, format, argptr);
00182 va_end(argptr);
00183
00184 snprintf(tbuf,
SPF_MAX_DEBUG,
"[%s :: %s->%i]; %s", func, file, line, buf);
00185
00186
00187
if (level ==
FL_E)
00188 {
00189 fprintf(stderr, tbuf);
00190 fflush(stderr);
00191 }
00192
else
00193 {
00194
if (
f_bit_set(
confg.
level, level))
00195 {
00196
#ifndef _SPF_DEBUG_LOGFILE
00197
fprintf(stdout, tbuf);
00198 fflush(stdout);
00199
#else
00200
if ((fp = fopen(
DEBUG_LOG_FILE,
"a")) != NULL)
00201 {
00202 fprintf(fp,
"[%s :: %s->%i]; %s", func, file, line, buf);
00203 fclose(fp);
00204 }
00205
else
00206 {
00207 fprintf(stderr,
"libSPF can't open file (%s) for writing!\n",
00208
DEBUG_LOG_FILE);
00209 fflush(stderr);
00210 perror(func);
00211 }
00212
#endif
00213 }
00214 }
00215
00216 free(buf);
00217 free(tbuf);
00218
00219
xpthread_mutex_unlock(&
util_mutex);
00220
00221
return;
00222 }
00223
00224
00225
#ifndef _SPF_DEBUG_LOGFILE
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 void _dummy_debug(
const u_int8_t level,
const char *func,
const char *file,
00238
const size_t line,
const char *format,...)
00239 {
00240
return;
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 void _dummy_pdebug(
const u_int8_t level,
const char *func,
const char *file,
00256
const size_t line,
const char *s)
00257 {
00258
return;
00259 }
00260
00261
#endif
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 char *
UTIL_get_date(
void)
00283 {
00284
struct tm *now;
00285
struct tm tmbuf;
00286
00287 time_t curtime;
00288
00289
char *my_time;
00290
00291
00292
xpthread_mutex_lock(&
util_mutex);
00293
00294 curtime = time(NULL);
00295 now = localtime_r(&curtime, &tmbuf);
00296 my_time =
xmalloc(
SPF_MAX_DATETIME);
00297
00298 strftime(my_time,
SPF_MAX_DATETIME,
"%Y-%m-%d %H:%M:%S ", now);
00299 my_time[(
SPF_MAX_DATETIME - 1)] =
'\0';
00300
00301
xpthread_mutex_unlock(&
util_mutex);
00302
00303
return(my_time);
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 void UTIL_log_result(
peer_info_t *p)
00327 {
00328 FILE *fp = NULL;
00329
00330
char *buf;
00331
char *date;
00332
00333
00334 date =
UTIL_get_date();
00335 buf =
xmalloc(
SPF_MAX_DEBUG);
00336 *(date + (strlen(date) - 1)) =
'\0';
00337
00338
if (p->
spf_ver == 0)
00339 {
00340 p->
spf_ver =
SPF_VERSION;
00341 }
00342
00343
xpthread_mutex_lock(&
util_mutex);
00344
00345 snprintf(buf,
SPF_MAX_DEBUG,
00346
"[%s] result: %s :: %s [%s], ver: %i, depth: %i, error: (%s)\n",
00347 date, p->
spf_result[p->
RES].s, p->
from,
00348 p->
r_ip, p->
spf_rlevel, p->
spf_ver, p->
error);
00349
00350
if ((fp = fopen(
OUTPUT_LOG_FILE,
"a")) != NULL)
00351 {
00352 fprintf(fp,
"%s", buf);
00353 fclose(fp);
00354 }
00355
00356
xpthread_mutex_unlock(&
util_mutex);
00357
00358
xfree(date);
00359
xfree(buf);
00360
00361
return;
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 char *
UTIL_strndup(
const char *s,
const size_t n)
00379 {
00380
char *ret_ptr = NULL;
00381
00382
00383
if ((s == NULL) || (n <= 0))
00384 {
00385
xepprintf(
"Passed string is NULL. Abort!.\n");
00386
00387
return(
SPF_FALSE);
00388 }
00389
00390 ret_ptr =
xmalloc(n + 1);
00391
xvprintf(
"Allocated %u bytes of memory.\n", n);
00392 snprintf(ret_ptr, n, s);
00393
xvprintf(
"leaving function; returning string: (%s)\n", ret_ptr);
00394
00395
return(ret_ptr);
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 char *
UTIL_strdup(
const char *s)
00413 {
00414
char *ret_ptr = NULL;
00415
00416
00417
if (s == NULL)
00418 {
00419
xepprintf(
"Passed string is NULL. Abort!.\n");
00420
00421
return(
SPF_FALSE);
00422 }
00423
00424
if ((ret_ptr = strdup(s)) == NULL)
00425 {
00426
xepprintf(
"Unable to allocate memory\n");
00427 }
00428
00429
xvprintf(
"leaving function; returning string: (%s)\n", ret_ptr);
00430
00431
return(ret_ptr);
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 void *
UTIL_malloc(
const int32_t n,
const char *file, int32_t line,
00448
const char *func)
00449 {
00450
void *x = malloc(n);
00451
00452
if (x == NULL)
00453 {
00454
xvprintf(
"Unable to allocate %i bytes at %s:%i in %s\n",
00455 n, file, line, func);
00456
00457
00458
00459
00460
00461
00462
00463 exit(0);
00464 }
00465
00466 memset(x,
'\0', n);
00467
00468
return(x);
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 void *
UTIL_realloc(
void *p,
const int32_t n,
const char *file,
00487
const int32_t line,
const char *func)
00488 {
00489
void *x = NULL;
00490
00491
if (p == NULL)
00492 {
00493
return(
UTIL_malloc(n, file, line, func));
00494 }
00495
00496 x = realloc(p, n);
00497
if (x == NULL)
00498 {
00499
xvprintf(
"Unable to reallocate %i bytes at %s:%i in %s; " \
00500
"original address 0x%x\n", n, file, line, func, (uintptr_t)p);
00501
00502 exit(0);
00503 }
00504
00505
return(x);
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522 void UTIL_free(
void *p,
const char *file,
const int32_t line,
const char *func)
00523 {
00524
if (p == NULL)
00525 {
00526
xvprintf(
"Unable to free() on NULL pointer at %s:%i in %s; " \
00527
"address 0x%x.\n", file, line, func, (uintptr_t)p);
00528
00529
return;
00530 }
00531
00532
xvprintf(
"Free address 0x%x by %s on line %i (%s)\n",
00533 (uintptr_t)p, func, line, file);
00534
00535 free(p);
00536
00537
return;
00538 }
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 int16_t
UTIL_index(
const char *s,
const char c)
00565 {
00566 int16_t i;
00567
00568
00569
if (s == NULL)
00570 {
00571
xepprintf(
"passed a NULL string. Abort!\n");
00572
00573
return(-1);
00574 }
00575
00576
xvprintf(
"called with string: (%s); char: %c\n", s, c);
00577
00578 i = 0;
00579
while (*s)
00580 {
00581
if (*s == c)
00582 {
00583
xvprintf(
"Found search char: (%c); Returning: (%i)\n", *s, i);
00584
00585
return(i);
00586 }
00587 i++;
00588 s++;
00589 }
00590
00591
xpprintf(
"leaving function\n");
00592
00593
return(0);
00594 }
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 char *
UTIL_split_str(
const char *s,
const char c,
const u_int8_t num)
00616 {
00617 u_int8_t i;
00618
00619
char *cp;
00620
char *p;
00621
char *ret;
00622
00623
00624
if (s == NULL)
00625 {
00626
xepprintf(
"passed a NULL string. Abort!\n");
00627
00628
return(NULL);
00629 }
00630
00631
xvprintf(
"called with string: (%s); char (%c); int: (%i)\n",
00632 s, c, num);
00633
00634 p = cp =
xstrndup(s,
SPF_MAX_STR);
00635
00636 i = 0;
00637
while(*p)
00638 {
00639
if (*p == c)
00640 {
00641 i++;
00642
if (i == num)
00643 {
00644 p++;
00645 ret =
xstrndup(p,
SPF_MAX_STR);
00646
00647
xfree(cp);
00648
00649
xvprintf(
"returning: %s\n", ret);
00650
00651
return(ret);
00652 }
00653 }
00654 p++;
00655 }
00656
00657
xfree(cp);
00658
xvprintf(
"[%i] returning NULL\n", i);
00659
00660
return(NULL);
00661 }
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 char *
UTIL_split_strr(
const char *s,
const char c,
const u_int8_t num)
00685 {
00686 u_int8_t i;
00687
00688
char *p;
00689
char *ret;
00690
00691
00692
if ((s == NULL) || (*s ==
'\0'))
00693 {
00694
xepprintf(
"passed a NULL string. Abort!\n");
00695
00696
return(NULL);
00697 }
00698
00699
xvprintf(
"called with (%s)\n", s);
00700
00701
00702
00703
00704 p = (strchr(s,
'\0') - 1);
00705
00706 i = 0;
00707
while(p != s)
00708 {
00709
if (*p == c)
00710 {
00711 i++;
00712
if (i == num)
00713 {
00714
if (*p ==
'.')
00715 {
00716 p++;
00717 }
00718
00719 ret =
xstrdup(p);
00720
00721
xvprintf(
"delimiter found (%i) times; returning (%s).\n", i, ret);
00722
00723
return(ret);
00724 }
00725 }
00726 p--;
00727 }
00728
00729
xvprintf(
"delimiter (%c) found (%u) times; returing NULL\n", c, i);
00730
00731
return(NULL);
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751 u_int8_t
UTIL_count_delim(
const char *s,
const char c)
00752 {
00753 u_int8_t i = 0;
00754
00755
00756
if (s == NULL)
00757 {
00758
xepprintf(
"passed a NULL string. Abort!\n");
00759
00760
return(0);
00761 }
00762
00763
while (*s && i <
SPF_MAX_DELIM)
00764 {
00765
if (*s == c)
00766 {
00767 i++;
00768 }
00769 s++;
00770 }
00771
00772
xvprintf(
"found (%i) number of delimiters; returning.\n", i);
00773
00774
return(i);
00775 }
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790 SPF_BOOL UTIL_is_spf_delim(
const char c)
00791 {
00792
00793
if (!c)
00794 {
00795
xepprintf(
"called with a NULL char! Aborting check.\n");
00796
00797
return(
SPF_FALSE);
00798 }
00799
00800
xvprintf(
"called with char (%c)\n", c);
00801
00802
if (c ==
'.' ||
00803 c ==
'-' ||
00804 c ==
'+' ||
00805 c ==
',' ||
00806 c ==
'|' ||
00807 c ==
'_')
00808 {
00809
xpprintf(
"leaving function; returning SPF_FALSE\n");
00810
00811
return(
SPF_TRUE);
00812 }
00813
00814
xpprintf(
"leaving function; returning SPF_FALSE\n");
00815
00816
return(
SPF_FALSE);
00817 }
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832 SPF_BOOL UTIL_is_spf_result(
const char c)
00833 {
00834
if (!c)
00835 {
00836
xpprintf(
"passed a NULL or empty char!\n");
00837
00838
return(
SPF_FALSE);
00839 }
00840
00841
xvprintf(
"called with char (%c)\n", c);
00842
00843
if (c ==
'+' || c ==
'-' || c ==
'~' || c ==
'?')
00844 {
00845
xpprintf(
"leaving function; returning SPF_TRUE\n");
00846
00847
return(
SPF_TRUE);
00848 }
00849
00850
xpprintf(
"leaving function; returning SPF_FALSE\n");
00851
00852
return(
SPF_FALSE);
00853 }
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869 SPF_BOOL UTIL_is_macro(
const char *s)
00870 {
00871
if (s == NULL)
00872 {
00873
xepprintf(
"passed a NULL string. Abort!\n");
00874
00875
return(
SPF_FALSE);
00876 }
00877
00878
xvprintf(
"called with string (%s)\n", s);
00879
00880
while (*s++)
00881 {
00882
if ((*s ==
'%') && (*(s + 1) ==
'{'))
00883 {
00884
if (strstr(s,
"}"))
00885 {
00886
xpprintf(
"leaving function; returning SPF_TRUE\n");
00887
00888
return(
SPF_TRUE);
00889 }
00890 }
00891 }
00892
00893
xpprintf(
"leaving function; returning SPF_FALSE\n");
00894
00895
return(
SPF_FALSE);
00896 }
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914 SPF_BOOL UTIL_mx_cmp(
peer_info_t *p,
const char *s,
const int8_t cidr)
00915 {
00916
SPF_BOOL MX_SPF_MATCH;
00917
00918
char *rr_data = NULL;
00919
char *token;
00920
char *token_ptr;
00921
char *peer_ip;
00922
00923
00924 MX_SPF_MATCH =
SPF_FALSE;
00925 token_ptr = rr_data;
00926
00927
if ((rr_data =
DNS_query(p, s, T_MX, NULL)) == NULL)
00928 {
00929
xpprintf(
"SPF_ERROR parsing DNS Query\n");
00930
00931
return(
SPF_FALSE);
00932 }
00933
00934
xvprintf(
"rr_data is: (%s)\n", rr_data);
00935
00936 peer_ip =
xstrndup(inet_ntoa(p->
addr), 16);
00937 token = strtok_r(rr_data,
" ", &token_ptr);
00938
00939
while (token != NULL)
00940 {
00941
xvprintf(
"TOKEN: (%s)\n", token);
00942
00943
if (
UTIL_validate_hostname(p, token, cidr) ==
SPF_TRUE)
00944 {
00945
xvprintf(
"%s validated via (%s)\n", p->
from, token);
00946
00947 MX_SPF_MATCH =
SPF_TRUE;
00948
UTIL_assoc_prefix(p,
SPF_PASS, NULL);
00949 token = NULL;
00950 }
00951
else
00952 {
00953 token = strtok_r(NULL,
" ", &token_ptr);
00954 }
00955 }
00956
00957
xfree(peer_ip);
00958
xfree(rr_data);
00959
00960
return(MX_SPF_MATCH);
00961 }
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980 SPF_BOOL UTIL_a_cmp(
peer_info_t *p,
const char *s,
const int8_t cidr)
00981 {
00982 int16_t pos;
00983
00984
int tmp_errno = 0;
00985
00986 size_t s_len;
00987
00988
char *rr_data = NULL;
00989
char *token_ptr = NULL;
00990
char *gbuf = NULL;
00991
char *copy = NULL;
00992
char *cp = NULL;
00993
00994
char **a;
00995
00996
struct hostent *hp = NULL;
00997
struct hostent tmp_hp;
00998
00999
policy_addr_t policy_addr;
01000
01001
01002
if (s == NULL)
01003 {
01004
xepprintf(
"Passed string is NULL. Abort!.\n");
01005
01006
return(
SPF_FALSE);
01007 }
01008
01009
xvprintf(
"called with (%s) and cidr: %i\n", s, cidr);
01010
01011 gbuf =
xmalloc(
SPF_MAX_GHBNR_DBUF);
01012 s_len = strlen(s);
01013 token_ptr = rr_data;
01014
01015
01016
if ((s_len > 1) && (*(s + 1) ==
':'))
01017 {
01018 cp = copy =
xstrndup(s, (s_len + 1));
01019
01020
if (cidr != 32)
01021 {
01022
01023 cp[s_len - 3] =
'\0';
01024 }
01025
01026
if ((pos =
UTIL_index(cp,
':')) <= 0)
01027 {
01028
xeprintf(
"ERROR parsing passed mechanism token (%s)\n", cp);
01029
01030
xfree(copy);
01031
xfree(gbuf);
01032
01033
return(
SPF_FALSE);
01034 }
01035
01036
01037 cp += (pos + 1);
01038 }
01039
else
01040 {
01041 cp = copy =
xstrndup(p->
current_domain,
SPF_MAX_HNAME);
01042 }
01043
01044
if ((hp =
xgethostbyname(cp, &tmp_hp, gbuf,
SPF_MAX_GHBNR_DBUF,
01045 &tmp_errno)) != NULL)
01046 {
01047
for (a = hp->h_addr_list; *a; a++)
01048 {
01049 memcpy(&policy_addr.addr.s_addr, *a,
SIZEOF(
struct in_addr));
01050
01051
xvprintf(
"IN ADDR; Checking: %lu\n", policy_addr.addr.s_addr);
01052
01053
01054 policy_addr.cidr = cidr;
01055
01056
if (
UTIL_cidr_cmp(&policy_addr, &p->
addr) ==
SPF_TRUE)
01057 {
01058 *a = NULL;
01059
01060
UTIL_assoc_prefix(p,
SPF_PASS, NULL);
01061
01062
xfree(copy);
01063
xfree(gbuf);
01064
01065
xgethostbyname_free();
01066
01067
return(
SPF_TRUE);
01068 }
01069 }
01070
01071
for (a = hp->h_aliases; *a; a++)
01072 {
01073 memcpy(&policy_addr.addr.s_addr, *a,
SIZEOF(
struct in_addr));
01074
01075
xvprintf(
"IN CNAME; Checking: %lu\n", policy_addr.addr.s_addr);
01076
01077
01078 policy_addr.cidr = cidr;
01079
01080
if (
UTIL_cidr_cmp(&policy_addr, &p->
addr) ==
SPF_TRUE)
01081 {
01082 *a = NULL;
01083
01084
UTIL_assoc_prefix(p,
SPF_PASS, NULL);
01085
01086
xfree(copy);
01087
xfree(gbuf);
01088
01089
xgethostbyname_free();
01090
01091
return(
SPF_TRUE);
01092 }
01093 }
01094 }
01095
else
01096 {
01097
xvprintf(
"No address associated with hostname (%s); Reason: %s\n",
01098 s, hstrerror(tmp_errno));
01099 }
01100
01101
xfree(copy);
01102
xfree(gbuf);
01103
01104
xgethostbyname_free();
01105
01106
return(
SPF_FALSE);
01107 }
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135 SPF_BOOL UTIL_ptr_cmp(
peer_info_t *p,
const char *s)
01136 {
01137
char *ptr_addr;
01138
char *tmp_ptr;
01139
01140
01141
if (s == NULL)
01142 {
01143
xepprintf(
"Passed string is NULL. Abort!\n");
01144
01145
return(
SPF_FALSE);
01146 }
01147
01148
xvprintf(
"called with (%s)\n", s);
01149
01150
01151 ptr_addr =
UTIL_rev_addr(p->
r_ip);
01152
01153
xvprintf(
"address: %s\n", ptr_addr);
01154
01155
if ((s = strstr(s,
":")) != NULL)
01156 {
01157 s++;
01158 tmp_ptr =
xstrndup(s, (strlen(s) + 1));
01159 }
01160
else
01161 {
01162 tmp_ptr =
xstrndup(p->
current_domain,
SPF_MAX_HNAME);
01163 }
01164
01165
if (
DNS_query(p, ptr_addr, T_PTR, tmp_ptr) != (
char *)
SPF_TRUE)
01166 {
01167
xvprintf(
"Failed to pass SPF PTR mechanism check:%s\n",
"");
01168
xvprintf(
"the domain pointed to by %s is not a valid subdomain of %s\n",
01169 ptr_addr, tmp_ptr);
01170
01171
xfree(ptr_addr);
01172
xfree(tmp_ptr);
01173
01174
return(
SPF_FALSE);
01175 }
01176
01177
xvprintf(
"PTR lookup succeeded: (%s):(%s)\n", p->
rs,
01178 p->
error);
01179
01180
xfree(ptr_addr);
01181
xfree(tmp_ptr);
01182
01183
return(
SPF_TRUE);
01184 }
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198 SPF_MECHANISM UTIL_get_policy_mech(
const char *s)
01199 {
01200
if (s == NULL || !s)
01201 {
01202
xepprintf(
"passed a NULL string. Abort!\n");
01203
01204
return(
NO_POLICY);
01205 }
01206
01207
xvprintf(
"called with: (%s)\n", s);
01208
01209
if (strncmp(s,
"v=", 2) == 0)
01210 {
01211
xvprintf(
"leaving function; returning %i (VERSION)\n",
VERSION);
01212
01213
return(
VERSION);
01214 }
01215
else if (strncmp(s,
"ip4:", 4) == 0 )
01216 {
01217
xvprintf(
"leaving function; returning %i (IP4)\n",
IP4);
01218
01219
return(
IP4);
01220 }
01221
else if (strncmp(s,
"ip6:", 4) == 0)
01222 {
01223
xvprintf(
"leaving function; returning %i (IP6)\n",
IP6);
01224
01225
return(
IP6);
01226 }
01227
else if (strncmp(s,
"all", 3) == 0)
01228 {
01229
xvprintf(
"leaving function; returning %i (ALL)\n",
ALL);
01230
01231
return(
ALL);
01232 }
01233
else if (strncmp(s,
"mx", 2) == 0)
01234 {
01235
xvprintf(
"leaving function; returning %i (MX)\n",
MX);
01236
01237
return(
MX);
01238 }
01239
else if (strncmp(s,
"a:", 2) == 0 || (*s ==
'a' && *(s + 1) ==
'/')
01240 || ((*s ==
'a') && !*(s + 1)))
01241 {
01242
xvprintf(
"leaving function; returning %i (A)\n",
A);
01243
01244
return(
A);
01245 }
01246
else if (strncmp(s,
"ptr", 3) == 0)
01247 {
01248
xvprintf(
"leaving function; returning %i (PTR)\n",
PTR);
01249
01250
return(
PTR);
01251 }
01252
else if (strncmp(s,
"include:", 7) == 0)
01253 {
01254
xvprintf(
"leaving function; returning %i (INCLUDE)\n",
INCLUDE);
01255
01256
return(
INCLUDE);
01257 }
01258
else if (strncmp(s,
"exists:", 6) == 0)
01259 {
01260
xvprintf(
"leaving function; returning %i (EXISTS)\n",
EXISTS);
01261
01262
return(
EXISTS);
01263 }
01264
else if (strncmp(s,
"redirect=", 9) == 0)
01265 {
01266
xvprintf(
"leaving function; returning %i (REDIRECT)\n",
REDIRECT);
01267
01268
return(
REDIRECT);
01269 }
01270
else if (strncmp(s,
"exp=", 3) == 0)
01271 {
01272
xvprintf(
"leaving function; returning %i (EXPLAIN)\n",
EXPLAIN);
01273
01274
return(
EXPLAIN);
01275 }
01276
else if (strncmp(s,
"default", 7) == 0)
01277 {
01278
xvprintf(
"leaving function; returning %i (DEFAULT)\n",
DEFAULT);
01279
01280
return(
DEFAULT);
01281 }
01282
else if (strstr(s,
":"))
01283 {
01284
xvprintf(
"leaving function; returning %i (UNMECH)\n",
UNMECH);
01285
01286
return(
UNMECH);
01287 }
01288
01289
xpprintf(
"leaving function; returning NO_POLICY\n");
01290
return(
NO_POLICY);
01291 }
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309 SPF_BOOL UTIL_assoc_prefix(
peer_info_t *p,
SPF_RESULT res,
const char *s)
01310 {
01311 int16_t pos;
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
if (s != NULL)
01327 {
01328
xvprintf(
"Entering function (%i) (%s)\n", res, s);
01329
01330
01331
if (strncmp(s,
"default", 7) == 0 && (pos =
UTIL_index(s,
'=')) > 0)
01332 {
01333 s += (pos + 1);
01334
if (strncmp(s,
"deny", 4) == 0)
01335 {
01336
xvprintf(
"Stored SPF_H_FAIL (%i) (%i)\n",
01337 res,
SPF_H_FAIL);
01338
01339 p->
RES =
SPF_H_FAIL;
01340 p->
rs = p->
spf_result[
SPF_H_FAIL].
s;
01341
01342 snprintf(p->
error,
SPF_MAX_ERROR,
"policy result: (%s) from rule (%s)",
01343 p->
rs, p->
last_m);
01344
01345
return(
SPF_TRUE);
01346 }
01347
else if (strncmp(s,
"pass", 4) == 0)
01348 {
01349
xvprintf(
"Stored SPF_PASS (%i) (%i)\n",
01350 res,
SPF_PASS);
01351
01352 p->
RES =
SPF_PASS;
01353 p->
rs = p->
spf_result[
SPF_PASS].
s;
01354
01355 snprintf(p->
error,
SPF_MAX_ERROR,
"policy result: (%s) from rule (%s)",
01356 p->
rs, p->
last_m);
01357
01358
return(
SPF_TRUE);
01359 }
01360
else if (strncmp(s,
"softdeny", 8) == 0)
01361 {
01362
xvprintf(
"Stored SPF_S_FAIL (%i) (%i)\n",
01363 res,
SPF_S_FAIL);
01364
01365 p->
RES =
SPF_S_FAIL;
01366 p->
rs = p->
spf_result[
SPF_S_FAIL].
s;
01367
01368 snprintf(p->
error,
SPF_MAX_ERROR,
"policy result: (%s) from rule (%s)",
01369 p->
rs, p->
last_m);
01370
01371
return(
SPF_TRUE);
01372 }
01373
else if (strncmp(s,
"unknown", 7) == 0)
01374 {
01375
xvprintf(
"Stored SPF_NEUTRAL (%i) (%i)\n",
01376 res,
SPF_NEUTRAL);
01377
01378 p->
RES =
SPF_NEUTRAL;
01379 p->
rs = p->
spf_result[
SPF_NEUTRAL].
s;
01380
01381 snprintf(p->
error,
SPF_MAX_ERROR,
"policy result: (%s) from rule (%s)",
01382 p->
rs, p->
last_m);
01383
01384
return(
SPF_TRUE);
01385 }
01386
else if (strncmp(s,
"include", 7) == 0)
01387 {
01388
xvprintf(
"Stored SPF_UNKNOWN (%i) (%i)\n",
01389 res,
SPF_UNKNOWN);
01390
01391 p->
RES =
SPF_UNKNOWN;
01392 p->
rs = p->
spf_result[
SPF_UNKNOWN].
s;
01393
01394 snprintf(p->
error,
SPF_MAX_ERROR,
"policy result: (%s) from rule (%s)",
01395 p->
rs, p->
last_m);
01396
01397
return(
SPF_TRUE);
01398 }
01399
else
01400 {
01401
xvprintf(
"Stored SPF_ERROR (%i) (%i)\n",
01402 res,
SPF_ERROR);
01403
01404 p->
RES =
SPF_UNKNOWN;
01405 p->
rs = p->
spf_result[
SPF_UNKNOWN].
s;
01406
01407 snprintf(p->
error,
SPF_MAX_ERROR,
"policy result: (%s) from rule (%s)",
01408 p->
rs, p->
last_m);
01409
01410
return(
SPF_FALSE);
01411 }
01412 }
01413 }
01414
01415
switch (res)
01416 {
01417
01418
01419
case SPF_PASS:
01420
xvprintf(
"Stored SPF_PASS (%i) (%i)\n",
01421 res,
SPF_PASS);
01422
01423 p->
RES =
SPF_PASS;
01424 p->
rs = p->
spf_result[
SPF_PASS].
s;
01425
01426 snprintf(p->
error,
SPF_MAX_ERROR,
"policy result: (%s) from rule (%s)",
01427 p->
rs, p->
last_m);
01428
01429
return(
SPF_TRUE);
01430
01431
01432
case SPF_NONE:
01433
xvprintf(
"Stored SPF_NONE (%i) (%i)\n",
01434 res,
SPF_NONE);
01435
01436 p->
RES =
SPF_NONE;
01437 p->
rs = p->
spf_result[
SPF_NONE].
s;
01438
01439 snprintf(p->
error,
SPF_MAX_ERROR,
"policy result: (%s) from rule (%s)",
01440 p->
rs, p->
last_m);
01441
01442
return(
SPF_TRUE);
01443
01444
01445
case SPF_S_FAIL:
01446
xvprintf(
"Stored SPF_S_FAIL (%i) (%i)\n",
01447 res,
SPF_S_FAIL);
01448
01449 p->
RES =
SPF_S_FAIL;
01450 p->
rs = p->
spf_result[
SPF_S_FAIL].
s;
01451
01452 snprintf(p->
error,
SPF_MAX_ERROR,
"policy result: (%s) from rule (%s)",
01453 p->
rs, p->
last_m);
01454
01455
return(
SPF_TRUE);
01456
01457
01458
case SPF_H_FAIL:
01459
xvprintf(
"Stored SPF_H_FAIL (%i) (%i)\n",
01460 res,
SPF_H_FAIL);
01461
01462 p->
RES =
SPF_H_FAIL;
01463 p->
rs = p->
spf_result[
SPF_H_FAIL].
s;
01464
01465 snprintf(p->
error,
SPF_MAX_ERROR,
"policy result: (%s) from rule (%s)",
01466 p->
rs, p->
last_m);
01467
01468
return(
SPF_TRUE);
01469
01470
01471
case SPF_NEUTRAL:
01472
xvprintf(
"Stored SPF_NEUTRAL (%i) (%i)\n",
01473 res,
SPF_NEUTRAL);
01474
01475 p->
RES =
SPF_NEUTRAL;
01476 p->
rs = p->
spf_result[
SPF_NEUTRAL].
s;
01477
01478 snprintf(p->
error,
SPF_MAX_ERROR,
"policy result: (%s) from rule (%s)",
01479 p->
rs, p->
last_m);
01480
01481
return(
SPF_TRUE);
01482
01483
01484
case SPF_UNKNOWN:
01485
xvprintf(
"Stored SPF_UNKNOWN (%i) (%i)\n",
01486 res,
SPF_UNKNOWN);
01487
01488 p->
RES =
SPF_UNKNOWN;
01489 p->
rs = p->
spf_result[
SPF_UNKNOWN].
s;
01490
01491 snprintf(p->
error,
SPF_MAX_ERROR,
"policy result: (%s) from rule (%s)",
01492 p->
rs, p->
last_m);
01493
01494
return(
SPF_TRUE);
01495
01496
01497
case SPF_ERROR:
01498
xvprintf(
"Stored SPF_ERROR (%i) (%i)\n",
01499 p,
SPF_ERROR);
01500
01501 p->
RES =
SPF_ERROR;
01502 p->
rs = p->
spf_result[
SPF_ERROR].
s;
01503
01504 snprintf(p->
error,
SPF_MAX_ERROR,
"policy result: (%s) from rule (%s)",
01505 p->
rs, p->
last_m);
01506
01507
return(
SPF_TRUE);
01508
01509
01510
case SPF_UNMECH:
01511
xvprintf(
"Stored SPF_UNMECH (%i) (%i)\n",
01512 res,
SPF_UNMECH);
01513
01514 p->
RES =
SPF_UNMECH;
01515 p->
rs = p->
spf_result[
SPF_UNMECH].
s;
01516
01517 snprintf(p->
error,
SPF_MAX_ERROR,
"policy result: (%s) from rule (%s)",
01518 p->
rs, p->
last_m);
01519
01520
return(
SPF_TRUE);
01521
01522
01523
default:
01524
xvprintf(
"Stored SPF_PASS (%i) (%i)\n",
01525 res,
SPF_PASS);
01526
01527 p->
RES =
SPF_PASS;
01528 p->
rs = p->
spf_result[
SPF_PASS].
s;
01529
01530 snprintf(p->
error,
SPF_MAX_ERROR,
"policy result: (%s) from rule (%s)",
01531 p->
rs, p->
last_m);
01532
01533
return(
SPF_TRUE);
01534 }
01535
01536
xepprintf(
"leaving function; returning SPF_FALSE.\n");
01537
01538
return(
SPF_FALSE);
01539 }
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555 SPF_RESULT UTIL_get_mech_prefix(
peer_info_t *p,
const char *s)
01556 {
01557 int16_t pos;
01558
01559
01560
if (s == NULL)
01561 {
01562
xepprintf(
"passed a NULL string. Abort!\n");
01563
01564
return(
SPF_ERROR);
01565 }
01566
01567
xprintf(
"called with char: (%s)\n", s);
01568 snprintf(p->
last_m,
SPF_MAX_HNAME,
"%s", s);
01569
01570
switch (*s)
01571 {
01572
01573
01574
case '+':
01575 p->
RES_P =
SPF_PASS;
01576
xvprintf(
"leaving function; returning SPF_PASS (%s) %i\n",
01577 s,
SPF_PASS);
01578
01579
return(
SPF_PASS);
01580
01581
01582
01583
case '-':
01584 p->
RES_P =
SPF_H_FAIL;
01585
xvprintf(
"leaving function; returning SPF_H_FAIL (%s) %i\n",
01586 s,
SPF_H_FAIL);
01587
01588
return(
SPF_H_FAIL);
01589
01590
01591
case '?':
01592 p->
RES_P =
SPF_NEUTRAL;
01593
xvprintf(
"leaving function; returning SPF_NEUTRAL (%s) %i\n",
01594 s,
SPF_NEUTRAL);
01595
01596
return(
SPF_NEUTRAL);
01597
01598
01599
case '~':
01600 p->
RES_P =
SPF_S_FAIL;
01601
xvprintf(
"leaving function; returning SPF_S_FAIL (%s) %i\n",
01602 s,
SPF_S_FAIL);
01603
01604
return(
SPF_S_FAIL);
01605
01606
01607
default:
01608
if (p->
ALL ==
SPF_TRUE)
01609 {
01610 p->
RES_P =
SPF_NEUTRAL;
01611
xvprintf(
"leaving function; returning (def) SPF_NEUTRAL (%s) %i\n",
01612 s,
SPF_NEUTRAL);
01613 }
01614
else
01615 {
01616 p->
RES_P =
SPF_PASS;
01617
xvprintf(
"leaving function; returning (def) SPF_PASS (%s) %i\n",
01618 s,
SPF_PASS);
01619 }
01620
01621
xvprintf(
"leaving function; returning (%i)\n", p->
RES_P);
01622
01623
return(p->
RES_P);
01624 }
01625
01626
01627
01628
01629
01630
01631
01632
01633
if ((pos =
UTIL_index(s,
'=')) > 0)
01634 {
01635 s += (pos + 1);
01636
01637
if (strncmp(s,
"deny", 4) == 0)
01638 {
01639 p->
RES_P =
SPF_H_FAIL;
01640
xvprintf(
"leaving function; returning SPF_H_FAIL on (%s)\n", s);
01641
01642
return(
SPF_H_FAIL);
01643 }
01644
else if (strncmp(s,
"pass", 4) == 0)
01645 {
01646 p->
RES_P =
SPF_PASS;
01647
xvprintf(
"leaving function; returning SPF_PASS on (%s)\n", s);
01648
01649
return(
SPF_PASS);
01650 }
01651
else if (strncmp(s,
"softdeny", 8) == 0)
01652 {
01653 p->
RES_P =
SPF_S_FAIL;
01654
xvprintf(
"leaving function; returning SPF_S_FAIL on (%s)\n", s);
01655
01656
return(
SPF_S_FAIL);
01657 }
01658
else if (strncmp(s,
"unknown", 7) == 0)
01659 {
01660 p->
RES_P =
SPF_NEUTRAL;
01661
xvprintf(
"leaving function; returning SPF_NEUTRAL on (%s)\n", s);
01662
01663
return(
SPF_NEUTRAL);
01664 }
01665
else
01666 {
01667
xvprintf(
"leaving function; returning SPF_NEUTRAL on (%s)\n", s);
01668
01669
return(
SPF_NEUTRAL);
01670 }
01671 }
01672
01673
xvprintf(
"leaving function; returning SPF_ERROR on (%s)\n", s);
01674
01675
return(
SPF_ERROR);
01676 }
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694 policy_addr_t *
UTIL_expand_ip(
const char *s)
01695 {
01696 int8_t cidr = 0;
01697
01698 size_t len;
01699 size_t pos;
01700
01701
char *ip;
01702
01703
const char *token_ptr;
01704
01705
policy_addr_t *policy_addr;
01706
01707
01708
if (s == NULL)
01709 {
01710
xepprintf(
"passed a NULL string. Abort!\n");
01711
01712
return(NULL);
01713 }
01714
01715 len = strlen(s);
01716 token_ptr = s;
01717
01718
xvprintf(
"called with string: (%s)\n", token_ptr);
01719
01720
if ((pos =
UTIL_index(token_ptr,
':')) == 0)
01721 {
01722
xvprintf(
"SPF_ERROR: Unable to get position on token (%s)\n",
01723 token_ptr);
01724
01725
return(NULL);
01726 }
01727
01728
01729 token_ptr += pos + 1;
01730
01731 policy_addr =
xmalloc(
SIZEOF(
policy_addr_t));
01732
01733
01734
if ((pos =
UTIL_index(token_ptr,
'/')) == 0)
01735 {
01736
xvprintf(
"Unable to get position on token (%s), assuming /32 cidr " \
01737
"block\n", token_ptr);
01738
01739 pos = strlen(token_ptr);
01740 cidr = 32;
01741 }
01742
01743
01744 ip =
xstrndup(token_ptr, (pos + 1));
01745
01746
01747
if ((inet_pton(AF_INET, ip, &policy_addr->
addr)) == 0)
01748 {
01749
xvprintf(
"SPF_ERROR: inet_pton unable to convert ip to binary " \
01750
"(%s)\n", ip);
01751
01752
xfree(ip);
01753
return(NULL);
01754 }
01755
01756
if (cidr != 32)
01757 {
01758 token_ptr += (pos + 1);
01759 cidr = atoi(token_ptr);
01760 }
01761
01762
xfree(ip);
01763
01764
if ((cidr < 0) || (cidr > 32))
01765 {
01766
xvprintf(
"ERROR: cidr violation (%u)\n", cidr);
01767
01768
return(NULL);
01769 }
01770
01771 policy_addr->
cidr = cidr;
01772
01773
xvprintf(
"CIDR: (%i) IP: (%s)\n",
01774 policy_addr->
cidr, inet_ntoa(policy_addr->
addr));
01775
01776
return(policy_addr);
01777 }
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793 SPF_BOOL UTIL_is_ip(
const char *
id)
01794 {
01795 u_int8_t i = 0;
01796
01797
if (!
id)
01798 {
01799
xepprintf(
"called without an IP address!\n");
01800
01801
return(
SPF_FALSE);
01802 }
01803
01804
xvprintf(
"called with address: (%s)\n",
id);
01805
01806
while (*id)
01807 {
01808
if (*
id ==
'.')
01809 {
01810 i++;
01811 }
01812
else if (isdigit(*
id) == 0)
01813 {
01814
return(
SPF_FALSE);
01815 }
01816
id++;
01817 }
01818
01819
if (i == 3)
01820 {
01821
return(
SPF_TRUE);
01822 }
01823
01824
xpprintf(
"leaving function; returning SPF_FALSE\n");
01825
01826
return(
SPF_FALSE);
01827 }
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843 char *
UTIL_rev_addr(
const char *s)
01844 {
01845 u_int8_t i = 0;
01846 u_int8_t tmp[4][1];
01847
01848 u_int16_t len = 0;
01849
01850
char *cp;
01851
char *token;
01852
char *new_addr;
01853
01854
01855
if (s == NULL)
01856 {
01857
xepprintf(
"passed a null string. Abort!\n");
01858
01859
return(NULL);
01860 }
01861
01862 len = (strlen(s) + 1);
01863
01864
xprintf(
"called with: (%s) len: (%i)\n", s, (len - 1));
01865
01866 cp =
xstrndup(s, len);
01867 token = strtok(cp,
".");
01868
01869
while ((token != NULL) && (i <= 3))
01870 {
01871
xvprintf(
"token : (%s)\n", token);
01872
01873 tmp[i][0] = atoi(token);
01874 token = strtok(NULL,
".");
01875 i++;
01876 }
01877
01878
xfree(cp);
01879
01880
01881 new_addr =
xmalloc(len + 13);
01882
01883 snprintf(new_addr, (len + 13),
"%u.%u.%u.%u.in-addr.arpa",
01884 tmp[3][0], tmp[2][0], tmp[1][0], tmp[0][0]);
01885
01886
xvprintf(
"leaving function; returning reversed ip: %s\n", new_addr);
01887
01888
return(new_addr);
01889 }
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906 char *
UTIL_get_dname(
const char *s)
01907 {
01908 u_int8_t i = 0;
01909
01910
char *buf = NULL;
01911
01912
01913
if (s == NULL)
01914 {
01915
xepprintf(
"called with NULL. Abort!\n");
01916
01917
return(NULL);
01918 }
01919
01920
xvprintf(
"called with (%s)\n", s);
01921
01922 i =
UTIL_count_delim(s,
'.');
01923
01924
switch (i)
01925 {
01926
case 0:
01927
break;
01928
case 1:
01929 buf =
xstrndup(s, (strlen(s) + 1));
01930
xprintf(
"leaving function; returning buffer: (%s)\n", buf);
01931
01932
return(buf);
01933
default:
01934 buf =
UTIL_split_str(s,
'.', (i - 1));
01935
xprintf(
"leaving function; returning buffer: (%s)\n", buf);
01936
01937
return(buf);
01938 }
01939
01940
xepprintf(
"leaving function; returning NULL\n");
01941
01942
return(NULL);
01943 }
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961 SPF_BOOL UTIL_cidr_cmp(
const policy_addr_t *policy_addr,
const struct in_addr
01962 *peer_addr)
01963 {
01964 u_int32_t a;
01965 u_int32_t b;
01966
01967
char *peer_ip = NULL;
01968
char *policy_ip = NULL;
01969
01970
01971
if ((policy_addr->
addr.s_addr <= 0) && (peer_addr->s_addr <= 0))
01972 {
01973
xepprintf(
"Passed with NULL chars. Aborting.\n");
01974
01975
return(
SPF_FALSE);
01976 }
01977
01978
xvprintf(
"POL: %lu PEER: %lu CIDR: %i\n", policy_addr->
addr.s_addr,
01979 peer_addr->s_addr, policy_addr->
cidr);
01980
01981
01982
01983
01984
01985
01986
01987 a = ntohl(peer_addr->s_addr);
01988 b = ntohl(policy_addr->
addr.s_addr);
01989
01990
if (policy_addr->
cidr != 32)
01991 {
01992
if ((a&(~0U<<(32-policy_addr->
cidr))) != (b&(~0U<<(32-policy_addr->
cidr))))
01993 {
01994
return(
SPF_FALSE);
01995 }
01996 }
01997
else
01998 {
01999
if (peer_addr->s_addr != policy_addr->
addr.s_addr)
02000 {
02001
xvprintf(
"%lu and %lu using 32 cidr do not match\n",
02002 peer_addr->s_addr, policy_addr->
addr.s_addr);
02003
02004
return(
SPF_FALSE);
02005 }
02006 }
02007
02008
02009 peer_ip =
xstrndup(inet_ntoa(*peer_addr),
SPF_MAX_IP_ADDR);
02010 policy_ip =
xstrndup(inet_ntoa(policy_addr->
addr),
SPF_MAX_IP_ADDR);
02011
02012
xvprintf(
"Peer: (%s) matches address %s with network %i\n",
02013 peer_ip, policy_ip, policy_addr->
cidr);
02014
02015
xfree(peer_ip);
02016
xfree(policy_ip);
02017
02018
return(
SPF_TRUE);
02019 }
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038 SPF_BOOL UTIL_validate_ptr(
peer_info_t *p)
02039 {
02040
char *ptr_addr;
02041
char *tmp_ptr;
02042
02043
02044
if (!p)
02045 {
02046
xepprintf(
"called with an invalid peer info structure!\n");
02047
02048
return(
SPF_FALSE);
02049 }
02050
02051
02052 ptr_addr =
UTIL_rev_addr(p->
r_ip);
02053
xvprintf(
"[address: %s]\n", ptr_addr);
02054
02055 tmp_ptr =
xstrndup(p->
current_domain,
SPF_MAX_HNAME);
02056
02057
if (
DNS_query(p, ptr_addr, T_PTR, tmp_ptr) != (
char *)
SPF_TRUE)
02058 {
02059
xvprintf(
"PTR lookup failed: (%s) (%s)\n", p->
rs, p->
error);
02060
02061
xfree(ptr_addr);
02062
xfree(tmp_ptr);
02063
02064
return(
SPF_FALSE);
02065 }
02066
02067
xvprintf(
"Peer (%s) successfully validated hostname (%s)\n",
02068 p->
r_ip, p->
r_vhname);
02069
02070
xfree(ptr_addr);
02071
xfree(tmp_ptr);
02072
02073
return(
SPF_TRUE);
02074 }
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100 SPF_BOOL UTIL_validate_hostname(
peer_info_t *p,
const char *s,
const int8_t cidr)
02101 {
02102
int tmp_errno = 0;
02103
02104
char **a = NULL;
02105
02106
char *ip = NULL;
02107
char *gbuf = NULL;
02108
02109
struct in_addr addr;
02110
struct hostent *hp = NULL;
02111
struct hostent tmp_hp;
02112
02113
policy_addr_t policy_addr;
02114
02115
02116
if (s == NULL)
02117 {
02118
xepprintf(
"passed a NULL string.\n");
02119
02120
return(
SPF_FALSE);
02121 }
02122
02123
xvprintf(
"called with: (%lu) and (%s)\n", p->
r_ip, s);
02124
02125 gbuf =
xmalloc(
SPF_MAX_GHBNR_DBUF);
02126
02127
if ((hp =
xgethostbyname(s, &tmp_hp, gbuf,
SPF_MAX_GHBNR_DBUF,
02128 &tmp_errno)) != NULL)
02129 {
02130
02131
for (a = hp->h_addr_list; *a; a++)
02132 {
02133 memcpy(&addr.s_addr, *a,
SIZEOF(
struct in_addr));
02134 ip =
xstrndup(inet_ntoa(addr),
SPF_MAX_IP_ADDR);
02135
02136
xvprintf(
"CLI: %s (%lu) SRV: %s (%lu)\n", ip, addr.s_addr,
02137 p->
r_ip, p->
addr.s_addr);
02138
02139
if (cidr == 32)
02140 {
02141
if (((
struct in_addr *)(*a))->s_addr == p->
addr.s_addr)
02142 {
02143
xvprintf(
"%s (%lu) matches %s (%lu)\n", ip,
02144 ((
struct in_addr *)(*a))->s_addr, p->
r_ip, p->
addr.s_addr);
02145
02146
UTIL_assoc_prefix(p,
SPF_PASS, NULL);
02147
02148
xfree(ip);
02149
xfree(gbuf);
02150
02151
xgethostbyname_free();
02152
02153
return(
SPF_TRUE);
02154 }
02155 }
02156
else if ((cidr < 32) && (cidr >= 8))
02157 {
02158
02159
if ((inet_pton(AF_INET, ip, &policy_addr.addr)) == 0)
02160 {
02161
xepprintf(
"Unable to execute inet_pton()\n");
02162 }
02163
02164 policy_addr.cidr = cidr;
02165
02166
xvprintf(
"Address: %lu with CIDR %i\n",
02167 policy_addr.addr.s_addr, policy_addr.cidr);
02168
02169
02170
if ((
UTIL_cidr_cmp(&policy_addr, &p->
addr)) ==
SPF_TRUE)
02171 {
02172
xvprintf(
"(%lu) matches (%lu) with CIDR %u\n",
02173 policy_addr.addr.s_addr, p->
addr.s_addr, cidr);
02174
02175
02176
UTIL_assoc_prefix(p,
SPF_PASS, NULL);
02177
02178
xfree(ip);
02179
xfree(gbuf);
02180
02181
xgethostbyname_free();
02182
02183
return(
SPF_TRUE);
02184 }
02185 }
02186
02187
xfree(ip);
02188
02189 }
02190
02191
02192
for (a = hp->h_aliases; *a; a++)
02193 {
02194 memcpy(&addr.s_addr, *a,
SIZEOF(
struct in_addr));
02195 ip =
xstrndup(inet_ntoa(addr),
SPF_MAX_IP_ADDR);
02196
02197
xvprintf(
"client: %s (%lu); policy: %s (%lu)\n",
02198 ip, addr.s_addr, p->
r_ip, p->
addr.s_addr);
02199
02200
if (cidr == 32)
02201 {
02202
if (((
struct in_addr *)(*a))->s_addr == p->
addr.s_addr)
02203 {
02204
xvprintf(
"IN A: client: %s (%lu) matches policy: %s (%lu)\n",
02205 ip, ((
struct in_addr *)(*a))->s_addr, p->
r_ip, p->
addr.s_addr);
02206
02207
xfree(ip);
02208
xfree(gbuf);
02209
02210
return(
SPF_TRUE);
02211 }
02212 }
02213
else if ((cidr < 32) && (cidr >= 8))
02214 {
02215
if (inet_pton(AF_INET, ip, &policy_addr.addr) == 0)
02216 {
02217
xepprintf(
"Unable to execute inet_pton()\n");
02218 }
02219
02220 policy_addr.cidr = cidr;
02221
02222
if (
UTIL_cidr_cmp(&policy_addr, &p->
addr) ==
SPF_TRUE)
02223 {
02224
xvprintf(
"client: (%lu) matches policy (%lu) with CIDR %u\n",
02225 policy_addr.addr.s_addr, p->
addr.s_addr, cidr);
02226
02227
xfree(ip);
02228
xfree(gbuf);
02229
02230
02231
UTIL_assoc_prefix(p,
SPF_PASS, NULL);
02232
02233
return(
SPF_TRUE);
02234 }
02235 }
02236
02237
xfree(ip);
02238
02239 }
02240 }
02241
else
02242 {
02243
xvprintf(
"No address associated with hostname (%s); Reason: %s\n",
02244 s, hstrerror(tmp_errno));
02245 }
02246
02247
xfree(gbuf);
02248
02249
xgethostbyname_free();
02250
02251
xpprintf(
"leaving function; returning SPF_FALSE\n");
02252
02253
return(
SPF_FALSE);
02254 }
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272 char *
UTIL_url_encode(
const char *s)
02273 {
02274
int len;
02275
02276
char *
new;
02277
char *encoded;
02278
02279
02280
if (s != NULL)
02281 {
02282
02283
02284
02285
02286 len = (strlen(s) * 3);
02287 }
02288
else
02289 {
02290
xepprintf(
"passed a NULL string. Abort!\n");
02291
02292
return(NULL);
02293 }
02294
02295 encoded =
new =
xmalloc(len);
02296
02297
while (*s !=
'\0')
02298 {
02299
if (
urlchr_test(*s) == 0)
02300 {
02301 *
new++ = *s++;
02302 }
02303
else
02304 {
02305
02306 snprintf(
new, 4,
"%%%x", *s);
02307
new += 3;
02308 s++;
02309 }
02310 }
02311
02312 *
new++ =
'\0';
02313
xvprintf(
"leaving function; returning (%s)\n", encoded);
02314
02315
return(encoded);
02316 }
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331 char *
UTIL_reverse(
const char *s,
const char delim)
02332 {
02333 size_t len;
02334
02335
char *buf;
02336
char *p;
02337
char *cp;
02338
char *c;
02339
02340
split_str_t *master;
02341
02342
split_str_node_t *c_node;
02343
split_str_node_t *kill_node;
02344
02345
02346
if (s == NULL)
02347 {
02348
xepprintf(
"passed a NULL string. Abort!\n");
02349
02350
return(NULL);
02351 }
02352
02353
xvprintf(
"called with (%s) and delim (%c)\n", s, delim);
02354
02355 len = strlen(s);
02356 cp = c =
xstrndup(s, (len + 1));
02357
02358 master =
xmalloc(
SIZEOF(
split_str_t));
02359 master->
head = NULL;
02360 master->
tail = NULL;
02361 master->
elements = 0;
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376 len++;
02377 buf =
xmalloc(len);
02378
while ((p = strrchr(cp, delim)) != NULL)
02379 {
02380 p++;
02381
UTIL_addnode(master, p,
SPF_TRUE);
02382 p--;
02383 *p =
'\0';
02384 }
02385
02386
UTIL_addnode(master, cp,
SPF_FALSE);
02387
02388 c_node = master->
head;
02389
while ((kill_node = c_node) != NULL)
02390 {
02391 strncat(buf, kill_node->
s, kill_node->
len);
02392
xfree(kill_node->
s);
02393 c_node = c_node->
next;
02394
xfree(kill_node);
02395 }
02396
02397
xfree(cp);
02398
xfree(master);
02399
02400
xvprintf(
"leaving function; returning (%s)\n", buf);
02401
02402
return(buf);
02403 }
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421 SPF_BOOL UTIL_addnode(
split_str_t *master,
const char *s,
SPF_BOOL last)
02422 {
02423 size_t len;
02424
02425
split_str_node_t *c_node;
02426
split_str_node_t *new_node;
02427
split_str_node_t *prev_node;
02428
02429
02430
if (!s || (s == NULL))
02431 {
02432
xepprintf(
"passed a NULL string. Abort!\n");
02433
02434
return(
SPF_FALSE);
02435 }
02436
02437
xvprintf(
"called with string: (%s); boolean: (%s)\n", s,
02438 last ?
"FALSE" :
"TRUE");
02439
02440 len = strlen(s);
02441
02442
if (last ==
SPF_TRUE)
02443 {
02444 len += 2;
02445 }
02446
else
02447 {
02448 len++;
02449 }
02450
02451
02452 new_node =
xmalloc(
SIZEOF(
split_str_node_t));
02453
02454
02455 new_node->
next = NULL;
02456
02457 new_node->
s =
xmalloc(len);
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469 snprintf(new_node->
s, len,
"%s%c", s, last ?
'.' :
'\0');
02470 new_node->
len = (len - 1);
02471
02472 prev_node = NULL;
02473 c_node = master->
head;
02474
02475
02476
while (c_node != NULL)
02477 {
02478 prev_node = c_node;
02479 c_node = c_node->
next;
02480 }
02481
02482
if (prev_node != NULL)
02483 {
02484 new_node->
next = prev_node->
next;
02485 prev_node->
next = new_node;
02486 }
02487
else
02488 {
02489 master->
head = new_node;
02490 }
02491
02492 master->
tail = new_node;
02493 master->
elements++;
02494
02495
xpprintf(
"leaving function; returning SPF_TRUE\n");
02496
02497
return(
SPF_TRUE);
02498 }
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512 void _UTIL_pthread_mutex(
void *mutex,
SPF_BOOL action)
02513 {
02514
02515
#ifdef _WITH_PTHREADS
02516
02517
switch (action)
02518 {
02519
case SPF_TRUE:
02520 pthread_mutex_lock((pthread_mutex_t *)mutex);
02521
return;
02522
02523
case SPF_FALSE:
02524 pthread_mutex_unlock((pthread_mutex_t *)mutex);
02525
return;
02526 }
02527
02528
#endif
02529
02530
return;
02531 }
02532
02533
02534