E-MailRelay

gexecutableverifier.cpp
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2021 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/// \file gexecutableverifier.cpp
19///
20
21#include "gdef.h"
22#include "gexecutableverifier.h"
23#include "gexecutablecommand.h"
24#include "gprocess.h"
25#include "gnewprocess.h"
26#include "gfile.h"
27#include "groot.h"
28#include "gstr.h"
29#include "glocal.h"
30#include "glog.h"
31
32 GSmtp::ExecutableVerifier::ExecutableVerifier( GNet::ExceptionSink es , const G::Path & path ) :
33 m_path(path) ,
34 m_task(*this,es,"<<verifier exec error: __strerror__>>",G::Root::nobody())
35{
36}
37
38 void GSmtp::ExecutableVerifier::verify( const std::string & to_address ,
39 const std::string & from_address , const GNet::Address & ip ,
40 const std::string & auth_mechanism , const std::string & auth_extra )
41{
42 G_DEBUG( "GSmtp::ExecutableVerifier::verify: to \"" << to_address << "\": from \"" << from_address << "\": "
43 << "ip \"" << ip.hostPartString() << "\": auth-mechanism \"" << auth_mechanism << "\": "
44 << "auth-extra \"" << auth_extra << "\"" ) ;
45
46 G::ExecutableCommand commandline( m_path.str() , G::StringArray() ) ;
47 commandline.add( to_address ) ;
48 commandline.add( from_address ) ;
49 commandline.add( ip.displayString() ) ;
50 commandline.add( GNet::Local::canonicalName() ) ;
51 commandline.add( G::Str::lower(auth_mechanism) ) ;
52 commandline.add( auth_extra ) ;
53
54 G_LOG( "GSmtp::ExecutableVerifier: address verifier: executing " << commandline.displayString() ) ;
55 m_to_address = to_address ;
56 m_task.start( commandline ) ;
57}
58
59 void GSmtp::ExecutableVerifier::onTaskDone( int exit_code , const std::string & result_in )
60{
61 std::string result( result_in ) ;
62 G::Str::trimRight( result , {" \n\t",3U} ) ;
63 G::Str::replaceAll( result , "\r\n" , "\n" ) ;
64 G::Str::replaceAll( result , "\r" , "" ) ;
65
66 G::StringArray result_parts ;
67 result_parts.reserve( 2U ) ;
68 G::Str::splitIntoFields( result , result_parts , {"\n",1U} ) ;
69 std::size_t parts = result_parts.size() ;
70 result_parts.resize( 2U ) ;
71
72 G_LOG( "GSmtp::ExecutableVerifier: address verifier: exit code " << exit_code << ": "
73 << "[" << G::Str::printable(result_parts[0]) << "] [" << G::Str::printable(result_parts[1]) << "]" ) ;
74
75 VerifierStatus status = VerifierStatus::invalid( m_to_address ) ;
76 if( exit_code == 0 && parts >= 2 )
77 {
78 std::string full_name = G::Str::printable( result_parts.at(0U) ) ;
79 std::string mbox = G::Str::printable( result_parts.at(1U) ) ;
80 status = VerifierStatus::local( m_to_address , full_name , mbox ) ;
81 }
82 else if( exit_code == 1 && parts >= 2 )
83 {
84 std::string address = G::Str::printable( result_parts.at(1U) ) ;
85 status = VerifierStatus::remote( m_to_address , address ) ;
86 }
87 else if( exit_code == 100 )
88 {
89 status.abort = true ;
90 }
91 else
92 {
93 bool temporary = exit_code == 3 ;
94
95 std::string response = parts > 0U ?
96 G::Str::printable(result_parts.at(0U)) :
97 std::string("mailbox unavailable") ;
98
99 std::string reason = parts > 1U ?
100 G::Str::printable(result_parts.at(1U)) :
101 ( "exit code " + G::Str::fromInt(exit_code) ) ;
102
103 status = VerifierStatus::invalid( m_to_address ,
104 temporary , response , reason ) ;
105 }
106
107 doneSignal().emit( status ) ;
108}
109
110 G::Slot::Signal<const GSmtp::VerifierStatus&> & GSmtp::ExecutableVerifier::doneSignal()
111{
112 return m_done_signal ;
113}
114
115 void GSmtp::ExecutableVerifier::cancel()
116{
117}
118
GNet::Address
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:53
GNet::Address::hostPartString
std::string hostPartString(bool raw=false) const
Returns a string which represents the network address.
Definition: gaddress.cpp:384
GNet::Address::displayString
std::string displayString(bool with_scope_id=false) const
Returns a string which represents the transport address.
Definition: gaddress.cpp:375
GNet::ExceptionSink
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
Definition: gexceptionsink.h:100
GNet::Local::canonicalName
static std::string canonicalName()
Returns the canonical network name assiciated with hostname().
Definition: glocal.cpp:53
GSmtp::ExecutableVerifier::ExecutableVerifier
ExecutableVerifier(GNet::ExceptionSink, const G::Path &)
Constructor.
Definition: gexecutableverifier.cpp:32
GSmtp::VerifierStatus::local
static VerifierStatus local(const std::string &recipient, const std::string &full_name, const std::string &mbox)
Constructor for a valid local mailbox.
Definition: gverifierstatus.cpp:54
GSmtp::VerifierStatus::invalid
static VerifierStatus invalid(const std::string &recipient, bool temporary=false, const std::string &response={}, const std::string &reason={})
Factory for an invalid address.
Definition: gverifierstatus.cpp:31
GSmtp::VerifierStatus::remote
static VerifierStatus remote(const std::string &recipient, const std::string &address={})
Constructor for a valid remote mailbox.
Definition: gverifierstatus.cpp:43
G::ExecutableCommand
A structure representing an external program, holding a path and a set of arguments.
Definition: gexecutablecommand.h:44
G::Path
A Path object represents a file system path.
Definition: gpath.h:72
G::Str::splitIntoFields
static void splitIntoFields(const std::string &in, StringArray &out, string_view ws, char escape='\0', bool remove_escapes=true)
Splits the string into fields.
Definition: gstr.cpp:1146
G::Str::trimRight
static std::string & trimRight(std::string &s, string_view ws, std::size_t limit=0U)
Trims the rhs of s, taking off up to 'limit' of the 'ws' characters.
Definition: gstr.cpp:347
G::Str::printable
static std::string printable(const std::string &in, char escape='\\')
Returns a printable representation of the given input string, using chacter code ranges 0x20 to 0x7e ...
Definition: gstr.cpp:885
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 occurrences of sub-string 'from' with 'to'.
Definition: gstr.cpp:287
G::Str::lower
static std::string lower(const std::string &s)
Returns a copy of 's' in which all Latin-1 upper-case characters have been replaced by lower-case cha...
Definition: gstr.cpp:741
gexecutablecommand.h
gexecutableverifier.h
gfile.h
glocal.h
glog.h
gnewprocess.h
gprocess.h
groot.h
gstr.h
G
Low-level classes.
Definition: galign.h:28
G::StringArray
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:31
G::Slot::Signal< const GSmtp::VerifierStatus & >