363
365
struct rw_transport *module;
368
CString *receivedspfhelo;
369
CString *receivedspfmailfrom;
370
int mailfrom_passed_spf;
367
373
static void mailfromerr(int msgnum, const char *errtext, struct rw_info *rwi)
470
static const char *my_spf_lookup(const char *checkname,
471
const char *mailfrom,
472
const char *tcpremoteip,
473
const char *helodomain,
476
size_t errmsg_buf_size)
478
static const char * const keys[]={
484
const char *values[5];
486
char result=rfc1035_spf_lookup((values[0]=mailfrom),
487
(values[1]=tcpremoteip),
488
(values[2]=getenv("TCPREMOTEHOST")),
489
(values[3]=helodomain),
490
(values[4]=config_esmtphelo()),
521
(*hdrOut)="Received-SPF: ";
523
for (q=errmsg_buf; *q; q++)
524
if (*q < ' ' || *q >= 127)
529
(*hdrOut) += errmsg_buf;
530
(*hdrOut) += ")\n SPF=";
531
(*hdrOut) += checkname;
534
for (i=0; i<sizeof(values)/sizeof(values[0]); i++)
536
char *v=strdup(values[i] ? values[i]:"");
538
for (q=v; q && *q; q++)
539
if (*q < ' ' || *q >= 127)
544
(*hdrOut) += keys[i];
546
(*hdrOut) += v ? v:strerror(errno);
552
static CString get_spf_errmsg(const char *bofh_var,
554
const char *errmsg_txt,
559
if (!bofh_checkspf_status(bofh_var, "off", result))
561
const char *p=getenv("BOFHSPFNOVERBOSE");
563
errmsg += bofh_checkspf("BOFHSPFHARDERROR",
564
"fail,softfail", result)
573
errmsg += "Rejected by the Sender Policy Framework.";
574
else errmsg += errmsg_txt;
464
579
static int getsender(struct rw_transport *module)
466
581
struct mailfrominfo frominfo;
470
585
AliasSearch asearch;
586
CString receivedspfhelo;
587
CString receivedspfmailfrom;
472
589
frominfo.asptr= &asearch;
474
591
frominfo.module=module;
475
592
frominfo.dsnformat=0;
476
593
frominfo.envid=0;
594
frominfo.receivedspfhelo=NULL;
595
frominfo.receivedspfmailfrom=NULL;
596
frominfo.mailfrom_passed_spf=0;
478
598
if (buf << cin) return (1);
503
623
setmsgopts(frominfo, q);
505
625
const char *tcpremoteip=getenv("TCPREMOTEIP");
626
int bofhcheckhelo=(q=getenv("BOFHCHECKHELO")) == NULL ? 0:atoi(q);
507
if ((q=getenv("BOFHCHECKHELO")) != 0 && atoi(q) &&
508
strcmp(module->name, "esmtp") == 0 && receivedfrommta &&
509
strncmp(receivedfrommta, "dns; ", 5) == 0 && tcpremoteip &&
510
getenv("RELAYCLIENT") == NULL)
628
if (strcmp(module->name, "esmtp") == 0 && receivedfrommta &&
629
strncmp(receivedfrommta, "dns; ", 5) == 0 && tcpremoteip)
512
631
const char *s=receivedfrommta+5;
519
638
memcpy(sbuf, receivedfrommta+5, s-receivedfrommta-5);
520
639
sbuf[s-receivedfrommta-5]=0;
640
frominfo.helohost=sbuf;
642
q=getenv("BOFHSPFTRUSTME");
644
if (q && atoi(q) && getenv("RELAYCLIENT"))
646
putenv("BOFHSPFHELO=off");
647
putenv("BOFHSPFMAILFROM=off");
648
putenv("BOFHSPFFROM=off");
654
putenv("BOFHSPFHELO=off");
655
putenv("BOFHSPFMAILFROM=off");
656
putenv("BOFHSPFFROM=off");
659
if (tcpremoteip && frominfo.helohost.GetLength())
664
if (!bofh_checkspf("BOFHSPFHELO", "off", "off"))
668
if (ipcmp(tcpremoteip, frominfo.helohost) == 0)
670
/* Consider HELO=ip.address a PASS */
673
result=my_spf_lookup("HELO",
681
if (strcmp(result, "pass") == 0)
685
get_spf_errmsg("BOFHSPFHELO", result,
689
if (errmsg_buf.GetLength() > 0)
691
cout << errmsg_buf << endl;
694
frominfo.receivedspfhelo=
699
if (*p && !bofh_checkspf("BOFHSPFMAILFROM", "off", "off"))
704
result=my_spf_lookup("MAILFROM",
708
&receivedspfmailfrom,
713
get_spf_errmsg("BOFHSPFMAILFROM", result,
716
if (errmsg_buf.GetLength() > 0)
718
cout << errmsg_buf << endl;
721
frominfo.receivedspfmailfrom=
722
&receivedspfmailfrom;
723
if (strcmp(result, "pass") == 0)
724
frominfo.mailfrom_passed_spf=1;
730
getenv("RELAYCLIENT") == NULL)
523
733
** If HELO/EHLO does not match the IP address, query the MX
526
736
struct rfc1035_mxlist *mxlist, *mxp;
529
if (ipcmp(sbuf, tcpremoteip)) switch (rfc1035_mxlist_create(&rfc1035_default_resolver,
739
if (ipcmp(frominfo.helohost, tcpremoteip)) switch (rfc1035_mxlist_create(&rfc1035_default_resolver,
740
frominfo.helohost, &mxlist))
532
742
case RFC1035_MX_OK:
554
764
rfc1035_mxlist_free(mxlist);
558
767
rfc1035_mxlist_free(mxlist);
560
769
if (!checked_a) /* No need to recheck A records */
771
int rc=checka(frominfo.helohost);
570
778
if (rc > 0) /* temp failure */
572
780
cout << "417 DNS lookup on HELO "
574
782
<< " failed. Try again later."
575
783
<< endl << flush;
581
cout << "517 HELO " << sbuf
788
cout << "517 HELO " << frominfo.helohost
582
789
<< " does not match " << tcpremoteip << endl;
586
792
case RFC1035_MX_HARDERR:
587
cout << "517 HELO " << sbuf << " does not exist." << endl;
793
cout << "517 HELO " << frominfo.helohost << " does not exist." << endl;
589
795
case RFC1035_MX_BADDNS:
590
cout << "517 RFC 1035 violation: recursive CNAME records for " << sbuf << "." << endl;
796
cout << "517 RFC 1035 violation: recursive CNAME records for " << frominfo.helohost << "." << endl;
593
cout << "417 DNS lookup on HELO " << sbuf <<
799
cout << "417 DNS lookup on HELO " << frominfo.helohost <<
594
800
" failed. Try again later." << endl << flush;
1301
1512
free(new_header);
1302
1513
header += '\n';
1515
if (headername == "from" &&
1516
!bofh_checkspf("BOFHSPFFROM", "off", "off"))
1519
rfc822t_alloc_new(header,
1525
struct rfc822a *a=rfc822a_alloc(t);
1529
if (a->naddrs > 0 && a->addrs[0].tokens)
1531
char *s=rfc822_getaddr(a, 0);
1542
if (mf->mailfrom_passed_spf &&
1543
bofh_checkspf("BOFHSPFFROM", "off",
1546
spf_from_address="";
1305
1552
else if (headername == "message-id") has_msgid=1;
1306
1553
else if (headername == "date") has_date=1;
1308
1555
// Quote Return-Path:'s at this point
1310
if (headername == "return-path")
1557
if (headername == "return-path" ||
1558
(headername == "received-spf" &&
1559
mf->helohost.GetLength() > 0))
1311
1560
headernameorig="Old-"+headernameorig;
1313
1562
my_rcptinfo.submitfile.Message(headernameorig);
1320
1569
accumulated_errmsg += "511 Headers specify no receipients.\n";
1574
if (spf_from_address.GetLength() > 0)
1576
CString received_spf;
1579
const char *result=my_spf_lookup("FROM",
1581
getenv("TCPREMOTEIP"),
1588
get_spf_errmsg("BOFHSPFFROM", result,
1589
errmsg, spf_from_address);
1591
if (errmsg_buf.GetLength() > 0)
1593
while (cin.get() != EOF)
1596
cout << errmsg_buf << endl;
1599
my_rcptinfo.submitfile.Message(received_spf);
1323
1602
if (accumulated_errmsg)
1325
1604
int n=atoi(accumulated_errmsg);