E-MailRelay

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gexecutableverifier.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2018 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // gexecutableverifier.cpp
19 //
20
21 #include "gdef.h"
22 #include "gsmtp.h"
23 #include "gexecutableverifier.h"
24 #include "gexecutablecommand.h"
25 #include "gstrings.h"
26 #include "gprocess.h"
27 #include "gnewprocess.h"
28 #include "gfile.h"
29 #include "groot.h"
30 #include "gstr.h"
31 #include "glocal.h"
32 #include "gassert.h"
33 #include "glog.h"
34
35 GSmtp::ExecutableVerifier::ExecutableVerifier( GNet::ExceptionHandler & eh , const G::Path & path , bool compatible ) :
36 m_path(path) ,
37 m_task(*this,eh,"<<verifier exec error: __strerror__>>",G::Root::nobody()) ,
38 m_compatible(compatible)
39 {
40 }
41
42 void GSmtp::ExecutableVerifier::verify( const std::string & to_address ,
43 const std::string & from_address , const GNet::Address & ip ,
44 const std::string & auth_mechanism , const std::string & auth_extra )
45 {
46 G_DEBUG( "GSmtp::ExecutableVerifier::verify: to \"" << to_address << "\": from \"" << from_address << "\": "
47 << "ip \"" << ip.hostPartString() << "\": auth-mechanism \"" << auth_mechanism << "\": "
48 << "auth-extra \"" << auth_extra << "\"" ) ;
49
50 G::ExecutableCommand commandline( m_path.str() , G::StringArray() ) ;
51 if( m_compatible )
52 {
53 std::string user = G::Str::head( to_address , "@" , false ) ;
54 std::string host = G::Str::tail( to_address , "@" , true ) ;
55 commandline.add( to_address ) ;
56 commandline.add( G::Str::upper(user) ) ;
57 commandline.add( G::Str::upper(host) ) ;
58 commandline.add( G::Str::upper(GNet::Local::canonicalName()) ) ;
59 commandline.add( from_address ) ;
60 commandline.add( ip.hostPartString() ) ;
61 commandline.add( auth_mechanism ) ;
62 commandline.add( auth_extra ) ;
63 }
64 else
65 {
66 commandline.add( to_address ) ;
67 commandline.add( from_address ) ;
68 commandline.add( ip.displayString() ) ;
69 commandline.add( GNet::Local::canonicalName() ) ;
70 commandline.add( G::Str::lower(auth_mechanism) ) ;
71 commandline.add( auth_extra ) ;
72 }
73
74 G_LOG( "GSmtp::ExecutableVerifier: address verifier: executing " << commandline.displayString() ) ;
75 m_to_address = to_address ;
76 m_task.start( commandline ) ;
77 }
78
79 void GSmtp::ExecutableVerifier::onTaskDone( int exit_code , const std::string & response_in )
80 {
81 std::string response( response_in ) ;
82 G::Str::trimRight( response , " \n\t" ) ;
83 G::Str::replaceAll( response , "\r\n" , "\n" ) ;
84 G::Str::replaceAll( response , "\r" , "" ) ;
85
86 G::StringArray response_parts ;
87 response_parts.reserve( 2U ) ;
88 G::Str::splitIntoFields( response , response_parts , "\n" ) ;
89 size_t parts = response_parts.size() ;
90 response_parts.resize( 2U ) ;
91
92 G_LOG( "GSmtp::ExecutableVerifier: address verifier: exit code " << exit_code << " "
93 << "[" << G::Str::printable(response_parts[0]) << "] [" << G::Str::printable(response_parts[1]) << "]" ) ;
94
95 VerifierStatus status ;
96 if( ( exit_code == 0 || exit_code == 1 ) && parts >= 2 )
97 {
98 status.is_valid = true ;
99 status.is_local = exit_code == 0 ;
100 status.full_name = G::Str::printable( response_parts.at(0U) ) ;
101 status.address = G::Str::printable( response_parts.at(1U) ) ;
102 }
103 else if( exit_code == 100 )
104 {
105 status.is_valid = false ;
106 status.abort = true ;
107 }
108 else
109 {
110 status.is_valid = false ;
111 status.temporary = exit_code == 3 ;
112
113 if( m_compatible )
114 {
115 G::Str::replaceAll( response , "\n" , " " ) ;
116 status.response = "no such mailbox: " +
117 ( response.empty() ? G::Str::fromInt(exit_code) : G::Str::printable(response) ) ;
118 status.reason = "rejected by verifier" ;
119 }
120 else
121 {
122 status.response = parts > 0U ?
123 G::Str::printable(response_parts.at(0U)) :
124 std::string("mailbox unavailable") ;
125
126 status.reason = parts > 1U ?
127 G::Str::printable(response_parts.at(1U)) :
128 ( "exit code " + G::Str::fromInt(exit_code) ) ;
129 }
130 }
131
132 doneSignal().emit( m_to_address , status ) ;
133 }
134
135 G::Slot::Signal2<std::string,GSmtp::VerifierStatus> & GSmtp::ExecutableVerifier::doneSignal()
136 {
137 return m_done_signal ;
138 }
139
140 void GSmtp::ExecutableVerifier::cancel()
141 {
142 }
143
144 /// \file gexecutableverifier.cpp
G::Str::printable
static std::string printable(const std::string &in, char escape= '\\')
Returns a printable represention of the given input string.
Definition: gstr.cpp:701
GNet::Local::canonicalName
static std::string canonicalName()
Returns the canonical network name assiciated with hostname().
Definition: glocal.cpp:54
gstrings.h
G::Str::tail
static std::string tail(const std::string &in, size_type pos, const std::string &default_=std::string())
Returns the last part of the string after the given position.
Definition: gstr.cpp:1102
glog.h
G::Slot::Signal2< std::string, GSmtp::VerifierStatus >
G::Str::head
static std::string head(const std::string &in, size_type pos, const std::string &default_=std::string())
Returns the first part of the string up to just before the given position.
Definition: gstr.cpp:1088
gexecutableverifier.h
GNet::Address
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:54
G::StringArray
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:33
GSmtp::ExecutableVerifier::cancel
virtual void cancel() override
Override from GSmtp::Verifier.
Definition: gexecutableverifier.cpp:140
groot.h
G::Str::fromInt
static std::string fromInt(int i)
Converts int 'i' to a string.
Definition: gstr.cpp:332
gexecutablecommand.h
GNet::ExceptionHandler
An abstract interface for handling exceptions thrown out of event-loop callbacks (socket events...
Definition: gexceptionhandler.h:44
G::Str::lower
static std::string lower(const std::string &s)
Returns a copy of 's' in which all Latin-1 uppercase characters have been replaced by lowercase chara...
Definition: gstr.cpp:599
gstr.h
gassert.h
G::Str::replaceAll
static unsigned int replaceAll(std::string &s, const std::string &from, const std::string &to)
Does a global replace on string 's', replacing all occurances of sub-string 'from' with 'to'...
Definition: gstr.cpp:195
G
Low-level classes.
Definition: garg.h:29
G::Str::trimRight
static void trimRight(std::string &s, const std::string &ws, size_type limit=0U)
Trims the rhs of s, taking off up to 'limit' of the 'ws' characters.
Definition: gstr.cpp:235
GNet::Address::hostPartString
std::string hostPartString() const
Returns a string which represents the network address for debugging and diagnostics purposes...
Definition: gaddress_ipv4.cpp:134
gfile.h
GSmtp::ExecutableVerifier::verify
virtual void 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) override
Override from GSmtp::Verifier.
Definition: gexecutableverifier.cpp:42
G::Str::upper
static std::string upper(const std::string &s)
Returns a copy of 's' in which all Latin-1 lowercase characters have been replaced by uppercase chara...
Definition: gstr.cpp:619
gprocess.h
GSmtp::ExecutableVerifier::doneSignal
virtual G::Slot::Signal2< std::string, VerifierStatus > & doneSignal() override
Override from GSmtp::Verifier.
Definition: gexecutableverifier.cpp:135
gnewprocess.h
G::ExecutableCommand
A structure representing an external program, holding a path and a set of arguments.
Definition: gexecutablecommand.h:43
GSmtp::VerifierStatus
A structure returned by GSmtp::Verifier to describe the status of a 'rcpt-to' recipient.
Definition: gverifierstatus.h:51
glocal.h
gsmtp.h
G::Str::splitIntoFields
static void splitIntoFields(const std::string &in, StringArray &out, const std::string &separators, char escape= '\0', bool remove_escapes=true)
Splits the string into fields.
Definition: gstr.cpp:975
GSmtp::ExecutableVerifier::ExecutableVerifier
ExecutableVerifier(GNet::ExceptionHandler &, const G::Path &, bool compatible)
Constructor.
Definition: gexecutableverifier.cpp:35
G::Path
A Path object represents a file system path.
Definition: gpath.h:72
GNet::Address::displayString
std::string displayString() const
Returns a string which represents the transport address for debugging and diagnostics purposes...
Definition: gaddress_ipv4.cpp:129