gexecutableverifier.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2013 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 "gstrings.h"
24 #include "gexecutableverifier.h"
25 #include "gprocess.h"
26 #include "gnewprocess.h"
27 #include "gfile.h"
28 #include "groot.h"
29 #include "gstr.h"
30 #include "glocal.h"
31 #include "gassert.h"
32 #include "glog.h"
33 
35  m_exe(exe)
36 {
37 }
38 
39 void GSmtp::ExecutableVerifier::verify( const std::string & to ,
40  const std::string & from , const GNet::Address & ip ,
41  const std::string & mechanism , const std::string & extra )
42 {
43  G_DEBUG( "GSmtp::ExecutableVerifier::verify: to \"" << to << "\": from \"" << from << "\": "
44  << "ip \"" << ip.displayString(false) << "\": auth-mechanism \"" << mechanism << "\": "
45  << "auth-extra \"" << extra << "\"" ) ;
46 
47  std::string user = G::Str::head( to , to.find('@') , to ) ;
48  std::string host = G::Str::tail( to , to.find('@') , std::string() ) ;
49 
50  VerifierStatus status =
51  verifyExternal( to , G::Str::upper(user) , G::Str::upper(host) ,
52  G::Str::upper(GNet::Local::fqdn()) , from , ip , mechanism , extra ) ;
53 
54  doneSignal().emit( to , status ) ;
55 }
56 
57 GSmtp::VerifierStatus GSmtp::ExecutableVerifier::verifyExternal( const std::string & address ,
58  const std::string & user , const std::string & host , const std::string & fqdn , const std::string & from ,
59  const GNet::Address & ip , const std::string & mechanism , const std::string & extra ) const
60 {
61  G::Strings args( m_exe.args() ) ;
62  args.push_back( address ) ;
63  args.push_back( user ) ;
64  args.push_back( host ) ;
65  args.push_back( fqdn ) ;
66  args.push_back( from ) ;
67  args.push_back( ip.displayString(false) ) ;
68  args.push_back( mechanism ) ;
69  args.push_back( extra ) ;
70  G_LOG( "GSmtp::ExecutableVerifier: executing " << m_exe.exe() << " " << address << " " << user << " "
71  << host << " " << fqdn << " " << from << " " << ip.displayString(false) << " "
72  << "\"" << mechanism << "\" \"" << extra << "\"" ) ;
73 
74  std::string response ;
75  int rc = G::NewProcess::spawn( G::Root::nobody() , m_exe.exe() , args , &response ) ;
76 
77  G_LOG( "GSmtp::ExecutableVerifier: " << rc << ": \"" << G::Str::printable(response) << "\"" ) ;
78  G::Str::trimRight( response , " \n\t" ) ;
79  G::Str::replaceAll( response , "\r\n" , "\n" ) ;
80  G::Str::replaceAll( response , "\r" , "" ) ;
81  G::Strings response_parts ;
82  G::Str::splitIntoFields( response , response_parts , "\n" ) ;
83 
84  VerifierStatus status ;
85  if( ( rc == 0 || rc == 1 ) && response_parts.size() >= 2 )
86  {
87  status.is_valid = true ;
88  status.is_local = rc == 0 ;
89  status.full_name = response_parts.front() ;
90  response_parts.pop_front() ;
91  status.address = response_parts.front() ;
92  }
93  else if( rc == 100 )
94  {
95  throw Verifier::AbortRequest() ;
96  }
97  else
98  {
99  status.is_valid = false ;
100  status.temporary = rc == 3 ;
101  status.reason = response.empty() ? G::Str::fromInt(rc) : response ;
102  G::Str::replaceAll( status.reason , "\n" , " " ) ;
103  status.reason = G::Str::printable( status.reason ) ;
104  status.help = "rejected by external verifier program" ;
105  }
106  return status ;
107 }
108 
110 {
111  return m_done_signal ;
112 }
113 
115 {
116 }
117 
static int spawn(Identity nobody, const Path &exe, const Strings &args, std::string *pipe_result_p=NULL, int error_return=127, std::string(*error_decode_fn)(int)=0)
Runs a command in an unprivileged child process.
static std::string printable(const std::string &in, char escape= '\\')
Returns a printable represention of the given input string.
Definition: gstr.cpp:507
static Identity nobody()
Returns the 'nobody' identity.
Definition: groot.cpp:82
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)
Final override from GSmtp::Verifier.
std::list< std::string > Strings
A std::list of std::strings.
Definition: gstrings.h:39
static void splitIntoFields(const std::string &in, Strings &out, const std::string &seperators, char escape= '\0', bool discard_bogus_escapes=true)
Splits the string into fields.
Definition: gstr.cpp:765
A structure representing an external program, holding a path and a set of arguments.
Definition: gexecutable.h:43
The Address class encapsulates an IP transport address.
Definition: gaddress.h:48
static std::string fqdn()
Returns the fully-qualified-domain-name.
Definition: glocal.cpp:67
static std::string fromInt(int i)
Converts int 'i' to a string.
Definition: gstr.cpp:236
static std::string tail(const std::string &in, std::string::size_type pos, const std::string &default_=std::string())
Returns the last part of the string after the given position.
Definition: gstr.cpp:842
std::string displayString(bool with_port=true, bool with_scope_id=false) const
Returns a string which represents the address for debugging and diagnostics purposes.
static unsigned int replaceAll(std::string &s, const std::string &from, const std::string &to)
Does a global replace on string 's', replacing all occurences of sub-string 'from' with 'to'...
Definition: gstr.cpp:78
static std::string head(const std::string &in, std::string::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:834
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:122
#define G_LOG(expr)
Definition: glog.h:98
static std::string upper(const std::string &s)
Returns a copy of 's' in which all lowercase characters have been replaced by uppercase characters...
Definition: gstr.cpp:426
#define G_DEBUG(expr)
Definition: glog.h:95
ExecutableVerifier(const G::Executable &)
Constructor.
A structure returned by GSmtp::Verifier to describe the status of a rcpt-to recipient.
virtual void reset()
Final override from GSmtp::Verifier.
virtual G::Signal2< std::string, VerifierStatus > & doneSignal()
Final override from GSmtp::Verifier.