E-MailRelay
gnetworkverifier.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 gnetworkverifier.cpp
19///
20
21#include "gdef.h"
22#include "gnetworkverifier.h"
23#include "glocal.h"
24#include "gstr.h"
25#include "glog.h"
26
28 const std::string & server , unsigned int connection_timeout ,
29 unsigned int response_timeout ) :
30 m_es(es) ,
31 m_location(server) ,
32 m_connection_timeout(connection_timeout) ,
33 m_response_timeout(response_timeout)
34{
35 G_DEBUG( "GSmtp::NetworkVerifier::ctor: " << server ) ;
36 m_client_ptr.eventSignal().connect( G::Slot::slot(*this,&GSmtp::NetworkVerifier::clientEvent) ) ;
37 m_client_ptr.deletedSignal().connect( G::Slot::slot(*this,&GSmtp::NetworkVerifier::clientDeleted) ) ;
38}
39
41{
42 m_client_ptr.eventSignal().disconnect() ;
43 m_client_ptr.deletedSignal().disconnect() ;
44}
45
46void GSmtp::NetworkVerifier::verify( const std::string & mail_to_address ,
47 const std::string & mail_from_address , const GNet::Address & client_ip ,
48 const std::string & auth_mechanism , const std::string & auth_extra )
49{
50 if( m_client_ptr.get() == nullptr )
51 {
52 m_client_ptr.reset( std::make_unique<RequestClient>(
53 GNet::ExceptionSink(m_client_ptr,m_es.esrc()),
54 "verify" , "" ,
55 m_location , m_connection_timeout , m_response_timeout ) ) ;
56 }
57
58 G::StringArray args ;
59 args.push_back( mail_to_address ) ;
60 args.push_back( mail_from_address ) ;
61 args.push_back( client_ip.displayString() ) ;
62 args.push_back( GNet::Local::canonicalName() ) ;
63 args.push_back( G::Str::lower(auth_mechanism) ) ;
64 args.push_back( auth_extra ) ;
65
66 m_to_address = mail_to_address ;
67 m_client_ptr->request( G::Str::join("|",args) ) ;
68}
69
70void GSmtp::NetworkVerifier::clientDeleted( const std::string & reason )
71{
72 G_DEBUG( "GSmtp::NetworkVerifier::clientDeleted: reason=[" << reason << "]" ) ;
73 if( !reason.empty() )
74 {
75 std::string to_address = m_to_address ;
76 m_to_address.erase() ;
77
78 VerifierStatus status = VerifierStatus::invalid( to_address ,
79 true , "cannot verify" , reason ) ;
80
81 doneSignal().emit( status ) ;
82 }
83}
84
85void GSmtp::NetworkVerifier::clientEvent( const std::string & s1 , const std::string & s2 , const std::string & )
86{
87 G_DEBUG( "GSmtp::NetworkVerifier::clientEvent: [" << s1 << "] [" << s2 << "]" ) ;
88 if( s1 == "verify" )
89 {
90 // parse the output from the remote verifier using pipe-delimited
91 // fields based on the script-based verifier interface, but backwards
92 //
93 G::StringArray parts ;
94 G::Str::splitIntoFields( s2 , parts , {"|",1U} ) ;
95 VerifierStatus status = VerifierStatus::invalid( m_to_address ) ;
96 if( !parts.empty() && parts[0U] == "100" )
97 {
98 status.is_valid = false ;
99 status.abort = true ;
100 }
101 else if( parts.size() >= 2U && parts[0U] == "1" )
102 {
103 const std::string & address = parts[1U] ;
104 status = VerifierStatus::remote( m_to_address , address ) ;
105 }
106 else if( parts.size() >= 3U && parts[0U] == "0" )
107 {
108 const std::string & mbox = parts[1U] ;
109 const std::string & full_name = parts[2U] ;
110 status = VerifierStatus::local( m_to_address , full_name , mbox ) ;
111 }
112 else if( parts.size() >= 2U && ( parts[0U] == "2" || parts[0U] == "3" ) )
113 {
114 bool temporary = parts[0U] == "3" ;
115 const std::string & response = parts[1U] ;
116 std::string reason = parts.size() >= 3 ? parts[2U] : std::string() ;
117 status = VerifierStatus::invalid( m_to_address ,
118 temporary , response , reason ) ;
119 }
120
121 doneSignal().emit( status ) ;
122 }
123}
124
125G::Slot::Signal<const GSmtp::VerifierStatus&> & GSmtp::NetworkVerifier::doneSignal()
126{
127 return m_done_signal ;
128}
129
130void GSmtp::NetworkVerifier::cancel()
131{
132 m_to_address.erase() ;
133 m_client_ptr.reset() ;
134}
135
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:53
std::string displayString(bool with_scope_id=false) const
Returns a string which represents the transport address.
Definition: gaddress.cpp:375
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
static std::string canonicalName()
Returns the canonical network name assiciated with hostname().
Definition: glocal.cpp:53
NetworkVerifier(GNet::ExceptionSink, const std::string &server, unsigned int connection_timeout, unsigned int response_timeout)
Constructor.
~NetworkVerifier() override
Destructor.
static VerifierStatus local(const std::string &recipient, const std::string &full_name, const std::string &mbox)
Constructor for a valid local mailbox.
static VerifierStatus invalid(const std::string &recipient, bool temporary=false, const std::string &response={}, const std::string &reason={})
Factory for an invalid address.
static VerifierStatus remote(const std::string &recipient, const std::string &address={})
Constructor for a valid remote mailbox.
static std::string join(const std::string &sep, const StringArray &strings)
Concatenates an array of strings with separators.
Definition: gstr.cpp:1195
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
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
Slot< Args... > slot(TSink &sink, void(TSink::*method)(Args...))
A factory function for Slot objects.
Definition: gslot.h:201
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:31