21#ifndef G_SMTP_CLIENT_PROTOCOL_H
22#define G_SMTP_CLIENT_PROTOCOL_H
43 class ClientProtocol ;
52 G_EXCEPTION( NotReady ,
tx(
"not ready") ) ;
53 G_EXCEPTION( TlsError ,
tx(
"tls/ssl error") ) ;
54 G_EXCEPTION( BadSelector ,
tx(
"no client authentication account") ) ;
55 G_EXCEPTION_CLASS( SmtpError ,
tx(
"smtp error") ) ;
79 std::string thishost_name ;
80 unsigned int response_timeout {0U} ;
81 unsigned int ready_timeout {0U} ;
82 bool use_starttls_if_possible {
false} ;
83 bool must_use_tls {
false} ;
84 bool authentication_fallthrough {
false} ;
85 bool anonymous{
false} ;
86 bool must_accept_all_recipients {
false} ;
87 bool eightbit_strict {
false} ;
88 bool binarymime_strict {
false} ;
89 bool smtputf8_strict {
false} ;
90 bool pipelining {
false} ;
92 std::size_t bdat_chunk_size {1000000} ;
93 bool crlf_only {
false} ;
94 bool try_reauthentication {
false} ;
96 Config & set_thishost_name(
const std::string & ) ;
97 Config & set_response_timeout(
unsigned int ) noexcept ;
98 Config & set_ready_timeout(
unsigned int ) noexcept ;
99 Config & set_use_starttls_if_possible(
bool =
true ) noexcept ;
100 Config & set_must_use_tls(
bool =
true ) noexcept ;
101 Config & set_authentication_fallthrough(
bool =
true ) noexcept ;
102 Config & set_anonymous(
bool =
true ) noexcept ;
103 Config & set_must_accept_all_recipients(
bool =
true ) noexcept ;
104 Config & set_eightbit_strict(
bool =
true ) noexcept ;
105 Config & set_binarymime_strict(
bool =
true ) noexcept ;
106 Config & set_smtputf8_strict(
bool =
true ) noexcept ;
107 Config & set_pipelining(
bool =
true ) noexcept ;
108 Config & set_reply_size_limit( std::size_t ) noexcept ;
109 Config & set_crlf_only(
bool =
true ) noexcept ;
110 Config & set_try_reauthentication(
bool =
true ) noexcept ;
116 std::string response ;
123 const Config & config ,
bool in_secure_tunnel ) ;
165 bool apply( const
std::
string & rx ) ;
178 void onTimeout() override ;
205 bool has_starttls {
false} ;
206 bool has_auth {
false} ;
208 bool has_8bitmime {
false} ;
209 bool has_binarymime {
false} ;
210 bool has_chunking {
false} ;
211 bool has_pipelining {
false} ;
212 bool has_smtputf8 {
false} ;
217 std::weak_ptr<GStore::StoredMessage> ptr ;
219 std::string selector ;
220 std::size_t content_size {0U} ;
221 std::size_t to_index {0U} ;
222 std::size_t to_accepted {0U} ;
224 std::size_t chunk_data_size {0U} ;
225 std::string chunk_data_size_str ;
231 bool authenticated {
false} ;
232 std::string auth_selector ;
233 std::string auth_mechanism ;
234 bool ok(
const std::string & s )
const
236 return !authenticated || auth_selector == s ;
241 State state {State::Init} ;
243 std::size_t replySize()
const ;
247 using BodyType = GStore::MessageStore::BodyType ;
249 std::string checkSendable() ;
250 bool endOfContent() ;
251 bool applyEvent(
const ClientReply & event ) ;
252 void raiseDoneSignal(
int ,
const std::string & ,
const std::string & = {} ) ;
253 void startFiltering() ;
257 void sendCommandLines(
const std::string & ) ;
261 std::size_t sendContentLines() ;
262 bool sendNextContentLine( std::string & ) ;
265 bool sendMailFrom() ;
267 bool sendBdatAndChunk( std::size_t ,
const std::string & ,
bool ) ;
269 bool sendContentLineImp(
const std::string & , std::size_t ) ;
270 void sendChunkImp(
const char * , std::size_t ) ;
271 bool sendImp(
G::string_view , std::size_t sensitive_from = std::string::npos ) ;
275 std::unique_ptr<GAuth::SaslClient> m_sasl ;
277 const bool m_in_secure_tunnel ;
278 bool m_eightbit_warned ;
279 bool m_binarymime_warned ;
283 Protocol m_protocol ;
284 MessageState m_message_state ;
286 std::vector<char> m_message_buffer ;
287 std::string m_message_line ;
288 SessionState m_session ;
291inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_thishost_name(
const std::string & s ) { thishost_name = s ;
return *this ; }
292inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_response_timeout(
unsigned int t )
noexcept { response_timeout =
t ;
return *this ; }
293inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_ready_timeout(
unsigned int t )
noexcept { ready_timeout =
t ;
return *this ; }
294inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_use_starttls_if_possible(
bool b )
noexcept { use_starttls_if_possible = b ;
return *this ; }
295inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_must_use_tls(
bool b )
noexcept { must_use_tls = b ;
return *this ; }
296inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_authentication_fallthrough(
bool b )
noexcept { authentication_fallthrough = b ;
return *this ; }
298inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_must_accept_all_recipients(
bool b )
noexcept { must_accept_all_recipients = b ;
return *this ; }
299inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_eightbit_strict(
bool b )
noexcept { eightbit_strict = b ;
return *this ; }
300inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_binarymime_strict(
bool b )
noexcept { binarymime_strict = b ;
return *this ; }
301inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_smtputf8_strict(
bool b )
noexcept { smtputf8_strict = b ;
return *this ; }
303inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_reply_size_limit( std::size_t n )
noexcept { reply_size_limit = n ;
return *this ; }
305inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_try_reauthentication(
bool b )
noexcept { try_reauthentication = b ;
return *this ; }
An interface used by GAuth::SaslClient to obtain a client id and its authentication secret.
A class that implements the client-side SASL challenge/response concept.
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
An interface used by GNet::TimerList to keep track of pending timeouts and to deliver timeout events.
G::TimerTime t() const
Used by TimerList to get the expiry epoch time.
An interface used by ClientProtocol to send protocol messages.
virtual bool protocolSend(G::string_view, std::size_t offset, bool go_secure)=0
Called by the Protocol class to send network data to the peer.
virtual ~Sender()=default
Destructor.
Implements the client-side SMTP protocol.
void start(std::weak_ptr< GStore::StoredMessage >)
Starts transmission of the given message.
void secure()
To be called when the secure socket protocol has been successfully established.
void finish()
Called after the last message has been sent.
ClientProtocol(GNet::ExceptionSink, Sender &sender, const GAuth::SaslClientSecrets &secrets, const std::string &sasl_client_config, const Config &config, bool in_secure_tunnel)
Constructor.
void filterDone(Filter::Result result, const std::string &response, const std::string &reason)
To be called when the Filter interface has done its thing.
G::Slot::Signal< const DoneInfo & > & doneSignal() noexcept
Returns a signal that is raised once the protocol has finished with a given message.
G::Slot::Signal & filterSignal() noexcept
Returns a signal that is raised when the protocol needs to do message filtering.
void sendComplete()
To be called when a blocked connection becomes unblocked.
bool apply(const std::string &rx)
Called on receipt of a line of text from the remote server.
An interface for processing a message file through a filter.
An abstract interface for messages which have come from the store.
A class like c++17's std::string_view.
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().
Result structure returned from GAuth::SaslClient::response.
A structure containing GSmtp::ClientProtocol configuration parameters.
Parameters for GSmtp::ClientProtocol::doneSignal()
A set of compile-time buffer sizes.
A slot holder, with connect() and emit() methods.