21#ifndef G_SMTP_SERVER_PROTOCOL_H
22#define G_SMTP_SERVER_PROTOCOL_H
45 class ServerProtocol ;
81 G_EXCEPTION_CLASS( Done ,
tx(
"smtp protocol done") ) ;
82 G_EXCEPTION( Busy ,
tx(
"smtp protocol busy") ) ;
83 using ApplyArgsTuple = std::tuple<const char *,std::size_t,std::size_t,std::size_t,char,bool> ;
91 virtual std::string
hello(
const std::string & smtp_peer_name )
const = 0 ;
94 virtual std::string
received(
const std::string & smtp_peer_name ,
bool auth ,
bool secure ,
95 const std::string & protocol ,
const std::string & cipher )
const = 0 ;
104 bool mail_requires_authentication {
false} ;
105 bool mail_requires_encryption {
false} ;
107 bool with_vrfy {
false} ;
108 bool with_chunking {
true} ;
109 bool with_pipelining {
true} ;
110 bool with_smtputf8 {
false} ;
111 bool smtputf8_strict {
false} ;
113 bool tls_starttls {
false} ;
114 bool tls_connection {
false} ;
115 int shutdown_how_on_quit {1} ;
116 unsigned int client_error_limit {8U} ;
117 std::size_t max_size {0U} ;
118 std::string sasl_server_config ;
119 std::string sasl_server_challenge_hostname ;
122 Config & set_mail_requires_authentication(
bool =
true ) noexcept ;
123 Config & set_mail_requires_encryption(
bool =
true ) noexcept ;
124 Config & set_with_vrfy(
bool =
true ) noexcept ;
125 Config & set_with_chunking(
bool =
true ) noexcept ;
126 Config & set_with_pipelining(
bool =
true ) noexcept ;
127 Config & set_with_smtputf8(
bool =
true ) noexcept ;
128 Config & set_smtputf8_strict(
bool =
true ) noexcept ;
129 Config & set_max_size( std::size_t ) noexcept ;
130 Config & set_tls_starttls(
bool =
true ) noexcept ;
131 Config & set_tls_connection(
bool =
true ) noexcept ;
132 Config & set_shutdown_how_on_quit(
int ) noexcept ;
133 Config & set_client_error_limit(
unsigned int ) noexcept ;
134 Config & set_sasl_server_config(
const std::string & ) ;
135 Config & set_sasl_server_challenge_hostname(
const std::string & ) ;
182 bool apply(
const ApplyArgsTuple & ) ;
201 void secure(
const std::string & certificate ,
const std::string & protocol ,
const std::string & cipher ) ;
277 bool sendFlush()
const override ;
280 struct AddressCommand
282 AddressCommand() = default ;
283 AddressCommand(
const std::string & e ) : error(e) {}
285 std::string address ;
286 std::size_t tailpos {std::string::npos} ;
287 std::size_t size {0U} ;
290 static std::unique_ptr<GAuth::SaslServer> newSaslServer(
const GAuth::SaslServerSecrets & ,
const std::string & ,
const std::string & ) ;
291 static int code( EventData ) ;
292 static std::string str( EventData ) ;
293 void applyEvent( Event , EventData = {} ) ;
300 bool messageAddContentFailed() ;
301 bool messageAddContentTooBig() ;
302 void badClientEvent() ;
303 void protocolMessageProcessed(
const ProtocolMessage::ProcessedInfo & ) ;
304 bool rcptState()
const ;
306 bool isEndOfText(
const ApplyArgsTuple & )
const ;
307 bool isEscaped(
const ApplyArgsTuple & )
const ;
308 void doNoop( EventData ,
bool & ) ;
309 void doIgnore( EventData ,
bool & ) ;
310 void doNothing( EventData ,
bool & ) ;
311 void doHelp( EventData ,
bool & ) ;
312 void doExpn( EventData ,
bool & ) ;
313 void doQuit( EventData ,
bool & ) ;
314 void doEhlo( EventData ,
bool & ) ;
315 void doHelo( EventData ,
bool & ) ;
316 void doAuthInvalid( EventData ,
bool & ) ;
317 void doAuth( EventData ,
bool & ) ;
318 void doAuthData( EventData ,
bool & ) ;
319 void doMail( EventData ,
bool & ) ;
320 void doRcpt( EventData ,
bool & ) ;
321 void doUnknown( EventData ,
bool & ) ;
322 void doRset( EventData ,
bool & ) ;
323 void doData( EventData ,
bool & ) ;
324 void doDataContent( EventData ,
bool & ) ;
325 void doBadDataCommand( EventData ,
bool & ) ;
326 void doBdatOutOfSequence( EventData ,
bool & ) ;
327 void doBdatFirst( EventData ,
bool & ) ;
328 void doBdatFirstLast( EventData ,
bool & ) ;
329 void doBdatFirstLastZero( EventData ,
bool & ) ;
330 void doBdatMore( EventData ,
bool & ) ;
331 void doBdatMoreLast( EventData ,
bool & ) ;
332 void doBdatMoreLastZero( EventData ,
bool & ) ;
334 void doBdatContent( EventData ,
bool & ) ;
335 void doBdatContentLast( EventData ,
bool & ) ;
336 void doBdatCheck( EventData ,
bool & ) ;
337 void doBdatComplete( EventData ,
bool & ) ;
338 void doComplete( EventData ,
bool & ) ;
339 void doEot( EventData ,
bool & ) ;
340 void doVrfy( EventData ,
bool & ) ;
341 void doVrfyReply( EventData ,
bool & ) ;
342 void doRcptToReply( EventData ,
bool & ) ;
343 void doNoRecipients( EventData ,
bool & ) ;
344 void doStartTls( EventData ,
bool & ) ;
345 void doSecure( EventData ,
bool & ) ;
346 void doSecureGreeting( EventData ,
bool & ) ;
347 void verifyDone( Verifier::Command ,
const VerifierStatus & ) ;
348 std::string useStartTls()
const ;
349 void verify( Verifier::Command ,
const std::string & ,
const std::string & = {} ) ;
352 ServerSender * m_sender ;
353 Verifier & m_verifier ;
355 ProtocolMessage & m_pm ;
356 std::unique_ptr<GAuth::SaslServer> m_sasl ;
359 const ApplyArgsTuple * m_apply_data ;
362 bool m_with_starttls ;
365 std::string m_certificate ;
366 std::string m_protocol ;
367 std::string m_cipher ;
368 unsigned int m_client_error_count ;
369 std::string m_session_peer_name ;
370 bool m_session_esmtp ;
371 std::size_t m_bdat_arg ;
372 std::size_t m_bdat_sum ;
377inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_with_chunking(
bool b )
noexcept { with_chunking = b ;
return *this ; }
378inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_max_size( std::size_t n )
noexcept { max_size = n ;
return *this ; }
379inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_mail_requires_authentication(
bool b )
noexcept { mail_requires_authentication = b ;
return *this ; }
380inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_mail_requires_encryption(
bool b )
noexcept { mail_requires_encryption = b ;
return *this ; }
381inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_tls_starttls(
bool b )
noexcept { tls_starttls = b ;
return *this ; }
382inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_tls_connection(
bool b )
noexcept { tls_connection = b ;
return *this ; }
383inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_with_pipelining(
bool b )
noexcept { with_pipelining = b ;
return *this ; }
384inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_with_smtputf8(
bool b )
noexcept { with_smtputf8 = b ;
return *this ; }
385inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_shutdown_how_on_quit(
int i )
noexcept { shutdown_how_on_quit = i ;
return *this ; }
386inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_client_error_limit(
unsigned int n )
noexcept { client_error_limit = n ;
return *this ; }
387inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_smtputf8_strict(
bool b )
noexcept { smtputf8_strict = b ;
return *this ; }
388inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_sasl_server_config(
const std::string & s ) { sasl_server_config = s ;
return *this ; }
389inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_sasl_server_challenge_hostname(
const std::string & s ) { sasl_server_challenge_hostname = s ;
return *this ; }
An interface used by GAuth::SaslServer to obtain authentication secrets.
The GNet::Address class encapsulates a TCP/UDP transport address.
An interface used by the ServerProtocol class to assemble and process an incoming message.
A static mix-in class for GSmtp::ServerProtocol to do SMTP command parsing.
An interface used by GSmtp::ServerProtocol to provide response text strings.
virtual std::string greeting() const =0
Returns a system identifier for the initial greeting.
virtual std::string received(const std::string &smtp_peer_name, bool auth, bool secure, const std::string &protocol, const std::string &cipher) const =0
Returns a complete 'Received' line.
virtual ~Text()=default
Destructor.
virtual std::string hello(const std::string &smtp_peer_name) const =0
Returns a hello response.
Implements the SMTP server-side protocol.
G::Slot::Signal & changeSignal() noexcept
A signal that is emitted at the end of apply() or whenever the protocol state might have changed by s...
bool inBusyState() const
Returns true if in a state where the protocol is waiting for an asynchronous filter of address-verifi...
bool apply(const ApplyArgsTuple &)
Called on receipt of a complete line of text from the client, or possibly a line fragment iff this ob...
void setSender(ServerSender &)
Sets the ServerSender interface, overriding the constructor parameter.
void init()
Starts the protocol.
~ServerProtocol() override
Destructor.
void secure(const std::string &certificate, const std::string &protocol, const std::string &cipher)
To be called when the transport protocol successfully goes into secure mode.
bool inDataState() const
Returns true if currently in a data-transfer state meaning that the next apply() does not need to con...
ServerProtocol(ServerSender &, Verifier &, ProtocolMessage &, const GAuth::SaslServerSecrets &secrets, Text &text, const GNet::Address &peer_address, const Config &config, bool enabled)
Constructor.
A simple mix-in class for GSmtp::ServerProtocol that sends protocol responses via a GSmtp::ServerSend...
An interface used by ServerProtocol to send protocol responses.
An asynchronous interface that verifies recipient 'to' addresses.
A class like c++17's std::string_view.
bool enabled() noexcept
Returns true if pop code is built in.
std::vector< std::string > StringArray
A std::vector of std::strings.
constexpr const char * tx(const char *p)
A briefer alternative to G::gettext_noop().
A configuration structure for GSmtp::ServerProtocol.
A slot holder, with connect() and emit() methods.