21#ifndef G_SMTP_SERVER_PROTOCOL_H
22#define G_SMTP_SERVER_PROTOCOL_H
46 class ServerProtocol ;
82 G_EXCEPTION_CLASS( Done ,
tx(
"smtp protocol done") )
83 G_EXCEPTION( Busy ,
tx(
"smtp protocol busy") )
84 using ApplyArgsTuple = std::tuple<const char *,std::size_t,std::size_t,std::size_t,char,bool> ;
92 virtual std::string
hello(
const std::string & smtp_peer_name )
const = 0 ;
95 virtual std::string
received(
const std::string & smtp_peer_name ,
bool auth ,
bool secure ,
96 const std::string & protocol ,
const std::string & cipher )
const = 0 ;
105 bool mail_requires_authentication {
false} ;
106 bool mail_requires_encryption {
false} ;
108 bool with_vrfy {
false} ;
109 bool with_chunking {
true} ;
110 bool with_pipelining {
true} ;
111 bool with_smtputf8 {
false} ;
113 bool smtputf8_strict {
false} ;
115 bool tls_starttls {
false} ;
116 bool tls_connection {
false} ;
117 int shutdown_how_on_quit {1} ;
118 unsigned int client_error_limit {8U} ;
119 std::size_t max_size {0U} ;
120 std::string sasl_server_config ;
121 std::string sasl_server_challenge_hostname ;
124 Config & set_mail_requires_authentication(
bool =
true ) noexcept ;
125 Config & set_mail_requires_encryption(
bool =
true ) noexcept ;
126 Config & set_with_vrfy(
bool =
true ) noexcept ;
127 Config & set_with_chunking(
bool =
true ) noexcept ;
128 Config & set_with_pipelining(
bool =
true ) noexcept ;
129 Config & set_with_smtputf8(
bool =
true ) noexcept ;
131 Config & set_smtputf8_strict(
bool =
true ) noexcept ;
132 Config & set_max_size( std::size_t ) noexcept ;
133 Config & set_tls_starttls(
bool =
true ) noexcept ;
134 Config & set_tls_connection(
bool =
true ) noexcept ;
135 Config & set_shutdown_how_on_quit(
int ) noexcept ;
136 Config & set_client_error_limit(
unsigned int ) noexcept ;
137 Config & set_sasl_server_config(
const std::string & ) ;
138 Config & set_sasl_server_challenge_hostname(
const std::string & ) ;
185 bool apply(
const ApplyArgsTuple & ) ;
204 void secure(
const std::string & certificate ,
const std::string & protocol ,
const std::string & cipher ) ;
276 using EventData = std::string_view ;
280 bool sendFlush()
const override ;
283 struct AddressCommand
285 AddressCommand() = default ;
286 AddressCommand(
const std::string & e ) : error(e) {}
288 std::string address ;
289 std::size_t tailpos {std::string::npos} ;
290 std::size_t size {0U} ;
293 static std::unique_ptr<GAuth::SaslServer> newSaslServer(
const GAuth::SaslServerSecrets & ,
const std::string & ,
const std::string & ) ;
294 static int code( EventData ) ;
295 static std::string str( EventData ) ;
296 void applyEvent( Event , EventData = {} ) ;
297 Event commandEvent( std::string_view )
const ;
298 Event dataEvent( std::string_view )
const ;
299 Event bdatEvent( std::string_view )
const ;
303 bool messageAddContentFailed() ;
304 bool messageAddContentTooBig() ;
305 void badClientEvent() ;
306 void protocolMessageProcessed(
const ProtocolMessage::ProcessedInfo & ) ;
307 bool rcptState()
const ;
309 bool isEndOfText(
const ApplyArgsTuple & )
const ;
310 bool isEscaped(
const ApplyArgsTuple & )
const ;
311 void doNoop( EventData ,
bool & ) ;
312 void doIgnore( EventData ,
bool & ) ;
313 void doHelp( EventData ,
bool & ) ;
314 void doExpn( EventData ,
bool & ) ;
315 void doQuit( EventData ,
bool & ) ;
316 void doEhlo( EventData ,
bool & ) ;
317 void doHelo( EventData ,
bool & ) ;
318 void doAuthInvalid( EventData ,
bool & ) ;
319 void doAuth( EventData ,
bool & ) ;
320 void doAuthData( EventData ,
bool & ) ;
321 void doMail( EventData ,
bool & ) ;
322 void doRcpt( EventData ,
bool & ) ;
323 void doUnknown( EventData ,
bool & ) ;
324 void doRset( EventData ,
bool & ) ;
325 void doData( EventData ,
bool & ) ;
326 void doDataContent( EventData ,
bool & ) ;
327 void doBadDataCommand( EventData ,
bool & ) ;
328 void doBdatOutOfSequence( EventData ,
bool & ) ;
329 void doBdatFirst( EventData ,
bool & ) ;
330 void doBdatFirstLast( EventData ,
bool & ) ;
331 void doBdatFirstLastZero( EventData ,
bool & ) ;
332 void doBdatMore( EventData ,
bool & ) ;
333 void doBdatMoreLast( EventData ,
bool & ) ;
334 void doBdatMoreLastZero( EventData ,
bool & ) ;
335 void doBdatImp( std::string_view ,
bool & ,
bool ,
bool ,
bool ) ;
336 void doBdatContent( EventData ,
bool & ) ;
337 void doBdatContentLast( EventData ,
bool & ) ;
338 void doBdatCheck( EventData ,
bool & ) ;
339 void doBdatComplete( EventData ,
bool & ) ;
340 void doComplete( EventData ,
bool & ) ;
341 void doEot( EventData ,
bool & ) ;
342 void doVrfy( EventData ,
bool & ) ;
343 void doVrfyReply( EventData ,
bool & ) ;
344 void doRcptToReply( EventData ,
bool & ) ;
345 void doNoRecipients( EventData ,
bool & ) ;
346 void doStartTls( EventData ,
bool & ) ;
347 void doSecure( EventData ,
bool & ) ;
348 void doSecureGreeting( EventData ,
bool & ) ;
349 void verifyDone( Verifier::Command ,
const VerifierStatus & ) ;
350 std::string useStartTls()
const ;
351 void verify( Verifier::Command ,
const std::string & ,
const std::string & = {} ,
const std::string & = {} ) ;
352 void warnInvalidSpaces()
const ;
353 void warnNoBrackets()
const ;
354 static void warning(
const std::string & ) ;
357 ServerSender * m_sender ;
358 Verifier & m_verifier ;
360 ProtocolMessage & m_pm ;
361 std::unique_ptr<GAuth::SaslServer> m_sasl ;
364 const ApplyArgsTuple * m_apply_data {
nullptr} ;
365 bool m_apply_more {
false} ;
367 bool m_with_starttls {
false} ;
369 bool m_secure {
false} ;
370 std::string m_verifier_raw_address ;
371 std::string m_certificate ;
372 std::string m_protocol ;
373 std::string m_cipher ;
374 unsigned int m_client_error_count {0U} ;
375 std::string m_session_peer_name ;
376 bool m_session_esmtp {
false} ;
377 std::size_t m_bdat_arg {0U} ;
378 std::size_t m_bdat_sum {0U} ;
383inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_with_chunking(
bool b )
noexcept { with_chunking = b ;
return *this ; }
384inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_max_size( std::size_t n )
noexcept { max_size = n ;
return *this ; }
385inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_mail_requires_authentication(
bool b )
noexcept { mail_requires_authentication = b ;
return *this ; }
386inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_mail_requires_encryption(
bool b )
noexcept { mail_requires_encryption = b ;
return *this ; }
387inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_tls_starttls(
bool b )
noexcept { tls_starttls = b ;
return *this ; }
388inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_tls_connection(
bool b )
noexcept { tls_connection = b ;
return *this ; }
389inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_with_pipelining(
bool b )
noexcept { with_pipelining = b ;
return *this ; }
390inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_with_smtputf8(
bool b )
noexcept { with_smtputf8 = b ;
return *this ; }
391inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_parser_config(
const ServerParser::Config & c ) { parser_config = c ;
return *this ; }
392inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_shutdown_how_on_quit(
int i )
noexcept { shutdown_how_on_quit = i ;
return *this ; }
393inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_client_error_limit(
unsigned int n )
noexcept { client_error_limit = n ;
return *this ; }
394inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_smtputf8_strict(
bool b )
noexcept { smtputf8_strict = b ;
return *this ; }
395inline GSmtp::ServerProtocol::Config & GSmtp::ServerProtocol::Config::set_sasl_server_config(
const std::string & s ) { sasl_server_config = s ;
return *this ; }
396inline 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 class for SMTP command parsing, used by GSmtp::ServerProtocol as a mix-in base.
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.
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) noexcept
A briefer alternative to G::gettext_noop().
A configuration structure for GSmtp::ServerParser.
A configuration structure for GSmtp::ServerProtocol.
A slot holder, with connect() and emit() methods.