v1.0.2
This commit is contained in:
parent
3ce0ea8b14
commit
ae6c79ec56
@ -1,6 +1,13 @@
|
||||
E-MailRelay Change Log
|
||||
======================
|
||||
|
||||
1.0.0 -> 1.0.2
|
||||
--------------
|
||||
* Support for trusted IP addresses, allowing certain clients to avoid authentication.
|
||||
* Address verifier interface extended to include authentication information.
|
||||
* New public mail relay section added to the user guide.
|
||||
* Example verifier scripts etc. added to the reference guide.
|
||||
|
||||
1.0.0 -> 1.0.1
|
||||
--------------
|
||||
* In proxy mode unexpected client-side disconnects and timeouts result in ".bad" files [bug-id 659039].
|
||||
|
2
configure
vendored
2
configure
vendored
@ -1453,7 +1453,7 @@ fi
|
||||
|
||||
# Define the identity of the package.
|
||||
PACKAGE=emailrelay
|
||||
VERSION=1.0.1
|
||||
VERSION=1.0.2
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
|
@ -21,7 +21,7 @@ dnl
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT(src/gsmtp/gsmtp.h)
|
||||
AM_INIT_AUTOMAKE(emailrelay,1.0.1)
|
||||
AM_INIT_AUTOMAKE(emailrelay,1.0.2)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl ===
|
||||
|
@ -201,8 +201,11 @@ verifier program, using the "--verifier" command-line switch.
|
||||
|
||||
The verifier program is passed a command-line containing the full address, the
|
||||
user-name part of the address, the host-name part, the local host's fully
|
||||
qualified domain name, and the current "MAIL" command's "FROM:" address or the
|
||||
empty string for the "VRFY" command.
|
||||
qualified domain name, the current "MAIL" command's "FROM:" address or the
|
||||
empty string for the "VRFY" command, the IP address of the client connection,
|
||||
the authentication mechanism used by the client ("NONE" if trusted), and either
|
||||
the authentication name or the fourth field from authentication secrets file if
|
||||
a trusted IP address.
|
||||
|
||||
For valid local mailbox addresses the verifier is expected to write two lines to
|
||||
the standard output -- the full name associated with the mailbox, and the
|
||||
@ -215,6 +218,40 @@ written to the standard output is taken as the failure reason.
|
||||
(Only the few few thousand characters are read from the verifier's standard
|
||||
output stream; any more is thrown away.)
|
||||
|
||||
In this simple example script all addresses are accepted as long as they contain
|
||||
an at sign. This has the effect of removing the normal "postmaster" functionality,
|
||||
which is in any case not very useful when running in proxy mode:
|
||||
|
||||
#!/bin/sh
|
||||
# verifier.sh
|
||||
# An address verifier script for E-MailRelay.
|
||||
address="${1}"
|
||||
user="${2}"
|
||||
host="${3}"
|
||||
if test "${address}" != "${user}@${host}" ; then exit 2 ; fi
|
||||
echo "${address}"
|
||||
echo "${address}" # again
|
||||
exit 1 # accept
|
||||
|
||||
As another example, the following address verifier script accepts all recipient
|
||||
addresses by default, but rejects remote addresses if the client has bypassed
|
||||
authentication by connecting on a trusted IP address:
|
||||
|
||||
#!/bin/sh
|
||||
# verifier.sh
|
||||
# An address verifier script for E-MailRelay.
|
||||
host="$3"
|
||||
local_domain="$4"
|
||||
auth_mechanism="$7"
|
||||
if test "${auth_mechanism}" = "NONE" -a "${host}" != "${local_domain}"
|
||||
then
|
||||
echo "cannot relay without authentication"
|
||||
exit 2 # reject the recipient address
|
||||
fi
|
||||
echo "${address}"
|
||||
echo "${address}" # again
|
||||
exit 1 # accept the recipient address
|
||||
|
||||
Administration interface
|
||||
------------------------
|
||||
If enabled, the server will provide a network interface for performing
|
||||
@ -373,17 +410,24 @@ least make sure that the secrets file has tight permissions, and that the
|
||||
passwords in it are not also used for anything important (such as root access).
|
||||
|
||||
On the server side authentication is advertised in the response to the SMTP
|
||||
"EHLO" command if the "--auth-server" command-line switch is used, but
|
||||
authentication by the client is optional. If the client does authenticate then
|
||||
"EHLO" command if the "--auth-server" command-line switch is used, and
|
||||
authentication by the client is mandatory unless the client's IP address is
|
||||
configured as a trusted address. If the client does authenticate then
|
||||
the authenticated user-id is stored with the message and then passed on to a
|
||||
next-hop server using an "AUTH=userid" parameter on the SMTP "MAIL FROM"
|
||||
command. If the client chooses not to authenticate then the submitted messages
|
||||
command. If the client does not to authenticate then the submitted messages
|
||||
will be forwarded using "AUTH=<>" on the "MAIL FROM" command. Note that any
|
||||
"AUTH=userid" information on incoming submitted messages is ignored and
|
||||
discarded: it is the authorised userid from the AUTH command which is
|
||||
propagated, not the userid from the incoming "MAIL FROM" command's "AUTH="
|
||||
parameter.
|
||||
|
||||
Trusted IP addresses are configured with lines in the secrets file having "NONE"
|
||||
in the first field, "server" in the second field, a wildcarded IP address in
|
||||
the third field, and an arbitrary keyword in the fourth field. The keyword
|
||||
is passed to any external address verifier program specified by the "--verifier"
|
||||
command-line switch.
|
||||
|
||||
On the client side authentication is performed when the client has connected to
|
||||
a server which supports the AUTH extension with the LOGIN or CRAM-MD5 mechanism.
|
||||
If client authentication is enabled (with the "--auth-client" switch) but the
|
||||
|
@ -297,6 +297,26 @@ from cygwin/bash on Win98 keeps stderr open (albeit with dreadful performance),
|
||||
whereas the standard command prompt does not. If necessary the environment
|
||||
variable "GLOGOUTPUT_FILE" can be defined as the name of a log file.
|
||||
|
||||
Preventing public mail relay
|
||||
----------------------------
|
||||
If you are running E-MailRelay as a server with a permanent connection to the
|
||||
Internet it is important to prevent public mail relay. By default public mail
|
||||
relaying is not possible because E-MailRelay does not accept IP connections from
|
||||
remote clients. However, if the "--remote-clients" switch is used then you need
|
||||
to be more careful. One option is to require all clients to authenticate, by
|
||||
using the "--server-auth" switch. But if you need local clients, such as your
|
||||
own e-mail front-end, to connect without authentication then you will need to
|
||||
put those trusted IP addresses in the secrets file with an authentication
|
||||
mechanism of "NONE". Refer to the reference guide for more information.
|
||||
|
||||
Taking it one stage further, you may want to allow clients to connect from any
|
||||
IP address without authentication, but only allow them to send mail to local
|
||||
users. You can do this by requiring authentication with the "--server-auth"
|
||||
switch but then exempting all clients from authentication with a "NONE server *.*.*.* x"
|
||||
line in the secrets file. To complete the solution you must have an address
|
||||
verifier script ("--verifier") which rejects remote addresses if the client has
|
||||
not authenticated. Again, refer to the reference guide for further details.
|
||||
|
||||
Glossary
|
||||
--------
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
Summary: Simple e-mail message transfer agent using SMTP
|
||||
Name: emailrelay
|
||||
Version: 1.0.1
|
||||
Version: 1.0.2
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: System Environment/Daemons
|
||||
Source: http://emailrelay.sourceforge.net/.../emailrelay-src-1.0.1.tar.gz
|
||||
Source: http://emailrelay.sourceforge.net/.../emailrelay-src-1.0.2.tar.gz
|
||||
BuildRoot: /tmp/emailrelay-install
|
||||
|
||||
%define prefix /usr
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "gsmtp.h"
|
||||
#include "gsecrets.h"
|
||||
#include "gexception.h"
|
||||
#include "gaddress.h"
|
||||
#include "gstrings.h"
|
||||
#include "gpath.h"
|
||||
#include <map>
|
||||
@ -132,6 +133,10 @@ public:
|
||||
// Initialiser. Returns true if a supported mechanism.
|
||||
// May be used more than once.
|
||||
|
||||
std::string mechanism() const ;
|
||||
// Returns the mechanism, as passed to the last init()
|
||||
// call to return true.
|
||||
|
||||
bool mustChallenge() const ;
|
||||
// Returns true if the mechanism must start with
|
||||
// a non-empty server challenge.
|
||||
@ -149,12 +154,16 @@ public:
|
||||
// Precondition: apply() returned empty
|
||||
|
||||
std::string id() const ;
|
||||
// Returns the authenticated identity. Returns the
|
||||
// empty string if not authenticated.
|
||||
// Returns the authenticated or trusted identity. Returns the
|
||||
// empty string if not authenticated and not trusted.
|
||||
|
||||
std::string mechanisms( char sep = ' ' ) const ;
|
||||
// Returns a list of supported mechanisms.
|
||||
|
||||
bool trusted( GNet::Address ) ;
|
||||
// Returns true if a trusted client that
|
||||
// does not need to authenticate.
|
||||
|
||||
private:
|
||||
SaslServer( const SaslServer & ) ; // not implemented
|
||||
void operator=( const SaslServer & ) ; // not implemented
|
||||
|
@ -52,9 +52,12 @@ public:
|
||||
std::string m_challenge ;
|
||||
bool m_authenticated ;
|
||||
std::string m_id ;
|
||||
std::string m_trustee ;
|
||||
SaslServerImp() ;
|
||||
void init( const std::string & mechanism ) ;
|
||||
bool init( const std::string & mechanism ) ;
|
||||
bool validate( const std::string & secret , const std::string & response ) const ;
|
||||
bool trusted( GNet::Address ) ;
|
||||
bool trustedCore( const std::string & , const std::string & ) ;
|
||||
static std::string clientResponse( const std::string & secret ,
|
||||
const std::string & challenge , bool & error ) ;
|
||||
} ;
|
||||
@ -65,19 +68,31 @@ GSmtp::SaslServerImp::SaslServerImp() :
|
||||
{
|
||||
}
|
||||
|
||||
void GSmtp::SaslServerImp::init( const std::string & mechanism )
|
||||
bool GSmtp::SaslServerImp::init( const std::string & mechanism )
|
||||
{
|
||||
m_mechanism = mechanism ;
|
||||
m_authenticated = false ;
|
||||
m_id = std::string() ;
|
||||
m_trustee = std::string() ;
|
||||
m_first = true ;
|
||||
m_challenge = std::string() ;
|
||||
m_mechanism = std::string() ;
|
||||
|
||||
if( m_mechanism == "CRAM-MD5" )
|
||||
if( mechanism == "LOGIN" )
|
||||
{
|
||||
m_mechanism = mechanism ;
|
||||
return true ;
|
||||
}
|
||||
else if( mechanism == "CRAM-MD5" )
|
||||
{
|
||||
m_mechanism = mechanism ;
|
||||
std::ostringstream ss ;
|
||||
ss << "<" << ::rand() << "." << G::DateTime::now() << "@" << GNet::Local::fqdn() << ">" ;
|
||||
m_challenge = ss.str() ;
|
||||
return true ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,6 +135,41 @@ std::string GSmtp::SaslServerImp::clientResponse( const std::string & secret ,
|
||||
return std::string() ;
|
||||
}
|
||||
|
||||
bool GSmtp::SaslServerImp::trusted( GNet::Address address )
|
||||
{
|
||||
std::string ip = address.displayString(false) ;
|
||||
G_DEBUG( "GSmtp::SaslServerImp::trusted: \"" << ip << "\"" ) ;
|
||||
G::Str::StringArray part ;
|
||||
G::Str::splitIntoFields( ip , part , "." ) ;
|
||||
if( part.size() == 4U )
|
||||
{
|
||||
return
|
||||
trustedCore(ip,ip) ||
|
||||
trustedCore(ip,part[0]+"."+part[1]+"."+part[2]+".*") ||
|
||||
trustedCore(ip,part[0]+"."+part[1]+".*.*") ||
|
||||
trustedCore(ip,part[0]+".*.*.*") ||
|
||||
trustedCore(ip,"*.*.*.*") ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return trustedCore( ip , ip ) ;
|
||||
}
|
||||
}
|
||||
|
||||
bool GSmtp::SaslServerImp::trustedCore( const std::string & full , const std::string & key )
|
||||
{
|
||||
G_DEBUG( "GSmtp::SaslServerImp::trustedCore: \"" << full << "\", \"" << key << "\"" ) ;
|
||||
std::string secret = Sasl::instance().serverSecrets().secret("NONE",key) ;
|
||||
bool trusted = ! secret.empty() ;
|
||||
if( trusted )
|
||||
{
|
||||
G_LOG( "GSmtp::SaslServer::trusted: trusting \"" << full << "\" "
|
||||
<< "(matched on NONE/server/" << key << "/" << secret << ")" ) ;
|
||||
m_trustee = secret ;
|
||||
}
|
||||
return trusted ;
|
||||
}
|
||||
|
||||
// ===
|
||||
|
||||
std::string GSmtp::SaslServer::mechanisms( char c ) const
|
||||
@ -151,10 +201,19 @@ bool GSmtp::SaslServer::mustChallenge() const
|
||||
|
||||
bool GSmtp::SaslServer::init( const std::string & mechanism )
|
||||
{
|
||||
m_imp->init( mechanism ) ;
|
||||
G_DEBUG( "GSmtp::SaslServer::init: mechanism \"" << mechanism << "\"" ) ;
|
||||
return m_imp->init( mechanism ) ;
|
||||
}
|
||||
|
||||
G_DEBUG( "GSmtp::SaslServer::init: mechanism \"" << m_imp->m_mechanism << "\"" ) ;
|
||||
return m_imp->m_mechanism == "LOGIN" || m_imp->m_mechanism == "CRAM-MD5" ;
|
||||
std::string GSmtp::SaslServer::mechanism() const
|
||||
{
|
||||
return m_imp->m_mechanism ;
|
||||
}
|
||||
|
||||
bool GSmtp::SaslServer::trusted( GNet::Address a )
|
||||
{
|
||||
G_DEBUG( "GSmtp::SaslServer::trusted: checking \"" << a.displayString(false) << "\"" ) ;
|
||||
return m_imp->trusted(a) ;
|
||||
}
|
||||
|
||||
std::string GSmtp::SaslServer::initialChallenge() const
|
||||
@ -210,7 +269,7 @@ bool GSmtp::SaslServer::authenticated() const
|
||||
|
||||
std::string GSmtp::SaslServer::id() const
|
||||
{
|
||||
return m_imp->m_authenticated ? m_imp->m_id : std::string() ;
|
||||
return m_imp->m_authenticated ? m_imp->m_id : m_imp->m_trustee ;
|
||||
}
|
||||
|
||||
// ===
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include <string>
|
||||
|
||||
GSmtp::ServerProtocol::ServerProtocol( Sender & sender , Verifier & verifier , ProtocolMessage & pmessage ,
|
||||
const std::string & thishost , const std::string & peer_address ) :
|
||||
const std::string & thishost , GNet::Address peer_address ) :
|
||||
m_sender(sender) ,
|
||||
m_pmessage(pmessage) ,
|
||||
m_verifier(verifier) ,
|
||||
@ -88,7 +88,7 @@ bool GSmtp::ServerProtocol::apply( const std::string & line )
|
||||
G_LOG( "GSmtp::ServerProtocol: rx<<: [message content not logged]" ) ;
|
||||
G_LOG( "GSmtp::ServerProtocol: rx<<: \"" << G::Str::toPrintableAscii(line) << "\"" ) ;
|
||||
m_fsm.reset( sProcessing ) ;
|
||||
m_pmessage.process( *this , m_sasl.id() , m_peer_address ) ; // -> processDone() callback
|
||||
m_pmessage.process( *this , m_sasl.id() , m_peer_address.displayString(false) ) ; // -> processDone() callback
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -145,7 +145,7 @@ void GSmtp::ServerProtocol::doNoop( const std::string & , bool & )
|
||||
void GSmtp::ServerProtocol::doVrfy( const std::string & line , bool & )
|
||||
{
|
||||
std::string mbox = parseMailbox( line ) ;
|
||||
Verifier::Status rc = m_verifier.verify( mbox ) ;
|
||||
Verifier::Status rc = verify( mbox , "" ) ;
|
||||
bool local = rc.is_local ;
|
||||
if( local && rc.full_name.length() )
|
||||
sendVerified( rc.full_name ) ;
|
||||
@ -155,6 +155,15 @@ void GSmtp::ServerProtocol::doVrfy( const std::string & line , bool & )
|
||||
sendWillAccept( mbox ) ;
|
||||
}
|
||||
|
||||
GSmtp::Verifier::Status GSmtp::ServerProtocol::verify( const std::string & to , const std::string & from ) const
|
||||
{
|
||||
std::string mechanism = m_sasl.active() ? m_sasl.mechanism() : std::string() ;
|
||||
std::string id = m_sasl.active() ? m_sasl.id() : std::string() ;
|
||||
if( m_sasl.active() && !m_authenticated )
|
||||
mechanism = "NONE" ;
|
||||
return m_verifier.verify( to , from , m_peer_address , mechanism , id ) ;
|
||||
}
|
||||
|
||||
std::string GSmtp::ServerProtocol::parseMailbox( const std::string & line ) const
|
||||
{
|
||||
std::string user ;
|
||||
@ -300,7 +309,7 @@ void GSmtp::ServerProtocol::sendChallenge( const std::string & s )
|
||||
|
||||
void GSmtp::ServerProtocol::doMail( const std::string & line , bool & predicate )
|
||||
{
|
||||
if( m_sasl.active() && ! m_authenticated )
|
||||
if( m_sasl.active() && !m_sasl.trusted(m_peer_address) && !m_authenticated )
|
||||
{
|
||||
predicate = false ;
|
||||
sendAuthRequired() ;
|
||||
@ -321,7 +330,7 @@ void GSmtp::ServerProtocol::doMail( const std::string & line , bool & predicate
|
||||
void GSmtp::ServerProtocol::doRcpt( const std::string & line , bool & predicate )
|
||||
{
|
||||
std::string to = parseTo( line ) ;
|
||||
bool ok = m_pmessage.addTo( to , m_verifier.verify(to,m_pmessage.from()) ) ;
|
||||
bool ok = m_pmessage.addTo( to , verify(to,m_pmessage.from()) ) ;
|
||||
predicate = ok ;
|
||||
if( ok )
|
||||
sendRcptReply() ;
|
||||
@ -337,7 +346,7 @@ void GSmtp::ServerProtocol::doUnknown( const std::string & line , bool & )
|
||||
void GSmtp::ServerProtocol::doRset( const std::string & , bool & )
|
||||
{
|
||||
m_pmessage.clear() ;
|
||||
m_authenticated = false ; // (not clear in the RFCs)
|
||||
m_sasl.init("") ; m_authenticated = false ; // (not clear in the RFCs)
|
||||
sendRsetReply() ;
|
||||
}
|
||||
|
||||
@ -575,7 +584,7 @@ std::string GSmtp::ServerProtocol::receivedLine() const
|
||||
ss
|
||||
<< "Received: "
|
||||
<< "FROM " << m_peer_name << " "
|
||||
<< "([" << m_peer_address << "]) "
|
||||
<< "([" << m_peer_address.displayString(false) << "]) "
|
||||
<< "BY " << m_thishost << " "
|
||||
<< "WITH ESMTP "
|
||||
<< "; "
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "gdef.h"
|
||||
#include "gsmtp.h"
|
||||
#include "gprotocolmessage.h"
|
||||
#include "gaddress.h"
|
||||
#include "gverifier.h"
|
||||
#include "gsasl.h"
|
||||
#include "gstatemachine.h"
|
||||
@ -71,7 +72,7 @@ public:
|
||||
} ;
|
||||
|
||||
ServerProtocol( Sender & sender , Verifier & verifier , ProtocolMessage & pmessage ,
|
||||
const std::string & thishost , const std::string & peer_address ) ;
|
||||
const std::string & thishost , GNet::Address peer_address ) ;
|
||||
// Constructor.
|
||||
//
|
||||
// The Verifier interface is used to verify recipient
|
||||
@ -185,6 +186,7 @@ private:
|
||||
std::string parsePeerName( const std::string & ) const ;
|
||||
std::string parse( const std::string & ) const ;
|
||||
std::string receivedLine() const ;
|
||||
Verifier::Status verify( const std::string & , const std::string & ) const ;
|
||||
|
||||
private:
|
||||
Sender & m_sender ;
|
||||
@ -193,7 +195,7 @@ private:
|
||||
Fsm m_fsm ;
|
||||
std::string m_thishost ;
|
||||
std::string m_peer_name ;
|
||||
std::string m_peer_address ;
|
||||
GNet::Address m_peer_address ;
|
||||
bool m_authenticated ;
|
||||
SaslServer m_sasl ;
|
||||
} ;
|
||||
|
@ -41,7 +41,7 @@ GSmtp::ServerPeer::ServerPeer( GNet::StreamSocket * socket , GNet::Address peer_
|
||||
m_buffer( crlf() ) ,
|
||||
m_verifier( verifier ) ,
|
||||
m_pmessage( pmessage ) ,
|
||||
m_protocol( *this, m_verifier, *m_pmessage.get(), thishost(), peer_address.displayString(false) )
|
||||
m_protocol( *this, m_verifier, *m_pmessage.get(), thishost(), peer_address )
|
||||
{
|
||||
G_LOG_S( "GSmtp::ServerPeer: smtp connection from " << peer_address.displayString() ) ;
|
||||
m_protocol.init( ident ) ;
|
||||
|
@ -38,9 +38,13 @@ GSmtp::Verifier::Verifier( const G::Path & path ) :
|
||||
{
|
||||
}
|
||||
|
||||
GSmtp::Verifier::Status GSmtp::Verifier::verify( const std::string & address , const std::string & from ) const
|
||||
GSmtp::Verifier::Status GSmtp::Verifier::verify( const std::string & address ,
|
||||
const std::string & from , const GNet::Address & ip ,
|
||||
const std::string & mechanism , const std::string & extra ) const
|
||||
{
|
||||
G_DEBUG( "GSmtp::ProtocolMessage::verify: to \"" << address << "\": from \"" << from << "\"" ) ;
|
||||
G_DEBUG( "GSmtp::ProtocolMessage::verify: to \"" << address << "\": from \"" << from << "\": "
|
||||
<< "ip \"" << ip.displayString(false) << "\": auth-mechanism \"" << mechanism << "\": "
|
||||
<< "auth-extra \"" << extra << "\"" ) ;
|
||||
|
||||
std::string fqdn = GNet::Local::fqdn() ;
|
||||
std::string host ;
|
||||
@ -57,14 +61,14 @@ GSmtp::Verifier::Status GSmtp::Verifier::verify( const std::string & address , c
|
||||
|
||||
Status status =
|
||||
m_path == G::Path() ?
|
||||
verifyInternal( address , user , host , fqdn , from ) :
|
||||
verifyExternal( address , user , host , fqdn , from ) ;
|
||||
verifyInternal( address , user , host , fqdn ) :
|
||||
verifyExternal( address , user , host , fqdn , from , ip , mechanism , extra ) ;
|
||||
|
||||
return status ;
|
||||
}
|
||||
|
||||
GSmtp::Verifier::Status GSmtp::Verifier::verifyInternal( const std::string & address , const std::string & user ,
|
||||
const std::string & host , const std::string & fqdn , const std::string & ) const
|
||||
const std::string & host , const std::string & fqdn ) const
|
||||
{
|
||||
Status status ;
|
||||
if( user == "POSTMASTER" && ( host.empty() || host == "LOCALHOST" || host == fqdn ) )
|
||||
@ -93,7 +97,8 @@ GSmtp::Verifier::Status GSmtp::Verifier::verifyInternal( const std::string & add
|
||||
}
|
||||
|
||||
GSmtp::Verifier::Status GSmtp::Verifier::verifyExternal( const std::string & address , const std::string & user ,
|
||||
const std::string & host , const std::string & fqdn , const std::string & from ) const
|
||||
const std::string & host , const std::string & fqdn , const std::string & from ,
|
||||
const GNet::Address & ip , const std::string & mechanism , const std::string & extra ) const
|
||||
{
|
||||
G::Strings args ;
|
||||
args.push_back( address ) ;
|
||||
@ -101,7 +106,12 @@ GSmtp::Verifier::Status GSmtp::Verifier::verifyExternal( const std::string & add
|
||||
args.push_back( host ) ;
|
||||
args.push_back( fqdn ) ;
|
||||
args.push_back( from ) ;
|
||||
G_LOG( "GSmtp::Verifier: executing " << m_path << " " << address << " " << user << " " << host << " " << fqdn << " " << from ) ;
|
||||
args.push_back( ip.displayString(false) ) ;
|
||||
args.push_back( mechanism ) ;
|
||||
args.push_back( extra ) ;
|
||||
G_LOG( "GSmtp::Verifier: executing " << m_path << " " << address << " " << user << " "
|
||||
<< host << " " << fqdn << " " << from << " " << ip.displayString(false) << " "
|
||||
<< "\"" << mechanism << "\" \"" << extra << "\"" ) ;
|
||||
|
||||
std::string response ;
|
||||
int rc = G::Process::spawn( G::Root::nobody() , m_path , args , &response ) ;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "gdef.h"
|
||||
#include "gsmtp.h"
|
||||
#include "gpath.h"
|
||||
#include "gaddress.h"
|
||||
#include <string>
|
||||
|
||||
namespace GSmtp
|
||||
@ -55,34 +56,37 @@ public:
|
||||
explicit Verifier( const G::Path & exe ) ;
|
||||
// Constructor.
|
||||
|
||||
Status verify( const std::string & recipient_address , const std::string & from = std::string() ) const ;
|
||||
// Checks a recipient address returning
|
||||
// a structure which indicates whether the
|
||||
// address is local, what the full name is,
|
||||
// and the canonical address.
|
||||
//
|
||||
// If invalid then 'is_valid' is set false
|
||||
// and a 'reason' is supplied.
|
||||
//
|
||||
// If valid and syntactically local then
|
||||
// 'is_local' is set true, 'full_name' is
|
||||
// set to the full description
|
||||
// and 'address' is set to the
|
||||
// canonical local address (without an
|
||||
// at sign).
|
||||
//
|
||||
// If valid and syntactically remote, then
|
||||
// 'is_local' is set false, 'full_name' is
|
||||
// empty, and 'address' is copied from
|
||||
// 'recipient_address'.
|
||||
//
|
||||
// The 'from' address is passed in for
|
||||
// RCPT commands, but not VRFY.
|
||||
Status verify( const std::string & rcpt_to_parameter ,
|
||||
const std::string & mail_from_parameter , const GNet::Address & client_ip ,
|
||||
const std::string & auth_mechanism , const std::string & auth_extra ) const ;
|
||||
// Checks a recipient address returning
|
||||
// a structure which indicates whether the
|
||||
// address is local, what the full name is,
|
||||
// and the canonical address.
|
||||
//
|
||||
// If invalid then 'is_valid' is set false
|
||||
// and a 'reason' is supplied.
|
||||
//
|
||||
// If valid and syntactically local then
|
||||
// 'is_local' is set true, 'full_name' is
|
||||
// set to the full description
|
||||
// and 'address' is set to the
|
||||
// canonical local address (without an
|
||||
// at sign).
|
||||
//
|
||||
// If valid and syntactically remote, then
|
||||
// 'is_local' is set false, 'full_name' is
|
||||
// empty, and 'address' is copied from
|
||||
// 'recipient_address'.
|
||||
//
|
||||
// The 'from' address is passed in for
|
||||
// RCPT commands, but not VRFY.
|
||||
|
||||
private:
|
||||
Status verifyInternal( const std::string & , const std::string & , const std::string & ,
|
||||
const std::string & , const std::string & ) const ;
|
||||
const std::string & ) const ;
|
||||
Status verifyExternal( const std::string & , const std::string & , const std::string & ,
|
||||
const std::string & , const std::string & , const GNet::Address & ,
|
||||
const std::string & , const std::string & ) const ;
|
||||
|
||||
private:
|
||||
|
9
src/main/auth.cfg
Normal file
9
src/main/auth.cfg
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
|
||||
NONE server 192.168.0.* local
|
||||
NONE server 192.168.*.* local
|
||||
NONE server 192.168.0.3 local
|
||||
NONE server *.*.*.* any
|
||||
LOGIN server john secret
|
||||
LOGIN server jane password
|
||||
|
@ -66,7 +66,7 @@ std::string Main::CommandLine::switchSpec()
|
||||
<< "m!immediate!forwards each message as soon as it is received (requires --forward-to)!0!!3|"
|
||||
<< "I!interface!listen on a specific interface!1!ip-address!3|"
|
||||
<< "i!pid-file!records the daemon process-id in the given file!1!pid-file!3|"
|
||||
<< "Z!verifier!!1!program!3|"
|
||||
<< "Z!verifier!defines an external program for validating recipient addresses!1!program!3|"
|
||||
;
|
||||
return ss.str() ;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
# General configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = E-MailRelay
|
||||
PROJECT_NUMBER = 1.0.1
|
||||
PROJECT_NUMBER = 1.0.2
|
||||
OUTPUT_DIRECTORY =
|
||||
OUTPUT_LANGUAGE = English
|
||||
EXTRACT_ALL = YES
|
||||
|
@ -80,7 +80,7 @@ Main::Run * Main::Run::m_this = NULL ;
|
||||
//static
|
||||
std::string Main::Run::versionNumber()
|
||||
{
|
||||
return "1.0.1" ;
|
||||
return "1.0.2" ;
|
||||
}
|
||||
|
||||
Main::Run::Run( const G::Arg & arg ) :
|
||||
|
@ -89,7 +89,7 @@ static void process( const G::Path & path , std::istream & stream ,
|
||||
{
|
||||
std::string to = *to_p ;
|
||||
G::Str::trim( to , " \t\r\n" ) ;
|
||||
GSmtp::Verifier::Status status = verifier.verify( to ) ;
|
||||
GSmtp::Verifier::Status status = verifier.verify( to , "" , GNet::Address::localhost(0U) , "" , "" ) ;
|
||||
msg->addTo( status.address , status.is_local ) ;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user