21#ifndef G_SMTP_CLIENT_PROTOCOL_H
22#define G_SMTP_CLIENT_PROTOCOL_H
38 class ClientProtocol ;
39 class ClientProtocolReply ;
50 PositivePreliminary = 1 ,
51 PositiveCompletion = 2 ,
52 PositiveIntermediate = 3 ,
53 TransientNegative = 4 ,
66 Internal_filter_ok = 222 ,
67 Internal_filter_abandon = 223 ,
68 Internal_secure = 224 ,
69 ServiceReady_220 = 220 ,
71 Authenticated_235 = 235 ,
74 SyntaxError_500 = 500 ,
75 SyntaxError_501 = 501 ,
76 NotImplemented_502 = 502 ,
77 BadSequence_503 = 503 ,
78 Internal_filter_error = 590 ,
79 NotAuthenticated_535 = 535 ,
80 NotAvailable_454 = 454 ,
110 bool is( Value v )
const ;
116 std::string
text()
const ;
131 std::string
textLine(
const std::string & prefix )
const ;
142 static bool is_digit(
char ) ;
145 bool m_complete{
false} ;
146 bool m_valid{
false} ;
149 std::string m_reason ;
158 G_EXCEPTION( NotReady ,
"not ready" ) ;
159 G_EXCEPTION( TlsError ,
"tls/ssl error" ) ;
160 G_EXCEPTION_CLASS( SmtpError ,
"smtp error" ) ;
166 virtual bool protocolSend(
const std::string & , std::size_t offset ,
bool go_secure ) = 0 ;
185 std::string thishost_name ;
186 unsigned int response_timeout{0U} ;
187 unsigned int ready_timeout{0U} ;
188 unsigned int filter_timeout{0U} ;
189 bool use_starttls_if_possible{
false} ;
190 bool must_use_tls{
false} ;
191 bool must_authenticate{
false} ;
192 bool anonymous{
false} ;
193 bool must_accept_all_recipients{
false} ;
194 bool eight_bit_strict{
false} ;
196 Config(
const std::string & name ,
unsigned int response_timeout ,
197 unsigned int ready_timeout ,
unsigned int filter_timeout ,
198 bool use_starttls_if_possible ,
bool must_use_tls ,
199 bool must_authenticate ,
bool anonymous ,
200 bool must_accept_all_recipients ,
bool eight_bit_strict ) ;
201 Config & set_thishost_name(
const std::string & ) ;
202 Config & set_response_timeout(
unsigned int ) ;
203 Config & set_ready_timeout(
unsigned int ) ;
204 Config & set_filter_timeout(
unsigned int ) ;
205 Config & set_use_starttls_if_possible(
bool =
true ) ;
206 Config & set_must_use_tls(
bool =
true ) ;
207 Config & set_must_authenticate(
bool =
true ) ;
208 Config & set_anonymous(
bool =
true ) ;
209 Config & set_must_accept_all_recipients(
bool =
true ) ;
210 Config & set_eight_bit_strict(
bool =
true ) ;
215 const Config & config ,
bool in_secure_tunnel ) ;
233 void start( std::weak_ptr<StoredMessage> ) ;
247 void filterDone(
bool ok ,
const std::string & response ,
const std::string & reason ) ;
257 bool apply(
const std::string & rx ) ;
270 struct AuthError :
public SmtpError
273 std::string str()
const ;
277 void onTimeout()
override ;
280 std::shared_ptr<StoredMessage> message() ;
281 void send(
const char * ) ;
282 void send(
const char * ,
const std::string & ) ;
283 void send(
const char * ,
const std::string & ,
const std::string & ) ;
284 bool send(
const std::string & ,
bool eot ,
bool sensitive =
false ) ;
285 bool sendLine( std::string & ) ;
286 std::size_t sendLines() ;
290 void sendMailCore() ;
291 bool endOfContent() ;
292 bool applyEvent(
const Reply & event ,
bool is_start_event =
false ) ;
293 static bool parseReply( Reply & ,
const std::string & , std::string & ) ;
294 void raiseDoneSignal(
int ,
const std::string & ,
const std::string & = std::string() ) ;
297 void startFiltering() ;
324 std::unique_ptr<GAuth::SaslClient> m_sasl ;
325 std::weak_ptr<StoredMessage> m_message ;
328 std::size_t m_to_index ;
329 std::size_t m_to_accepted ;
331 bool m_server_has_starttls ;
332 bool m_server_has_auth ;
333 bool m_server_secure ;
334 bool m_server_has_8bitmime ;
336 bool m_authenticated_with_server ;
337 std::string m_auth_mechanism ;
338 bool m_in_secure_tunnel ;
345inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_thishost_name(
const std::string & s ) { thishost_name = s ;
return *this ; }
349inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_use_starttls_if_possible(
bool b ) { use_starttls_if_possible = b ;
return *this ; }
351inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_must_authenticate(
bool b ) { must_authenticate = b ;
return *this ; }
353inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_must_accept_all_recipients(
bool b ) { must_accept_all_recipients = b ;
return *this ; }
354inline GSmtp::ClientProtocol::Config & GSmtp::ClientProtocol::Config::set_eight_bit_strict(
bool b ) { eight_bit_strict = 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.
A private implementation class used by ClientProtocol.
std::string text() const
Returns the text of the reply, excluding the numeric part, and with embedded newlines.
bool is(Value v) const
Returns true if the reply value is 'v'.
std::string textLine(const std::string &prefix) const
Returns a line of text() which starts with prefix.
std::string errorReason() const
Returns an error reason string, as passed to error().
bool textContains(std::string s) const
Returns true if the text() contains the given substring.
SubType subType() const
Returns the reply sub-type.
bool add(const ClientProtocolReply &other)
Adds more lines to this reply.
Type type() const
Returns the reply type (category).
bool positive() const
Returns true if the numeric value of the reply is less than four hundred.
int value() const
Returns the numeric value of the reply.
std::string errorText() const
Returns the text() string, plus any error reason, but with the guarantee that the returned string is ...
static ClientProtocolReply error(Value, const std::string &response, const std::string &error_reason)
Factory function for an error reply with a specific 5xx value.
bool incomplete() const
Returns true if the reply is incomplete.
ClientProtocolReply(const std::string &line=std::string())
Constructor for one line of text.
static ClientProtocolReply ok()
Factory function for an ok reply.
bool validFormat() const
Returns true if a valid format.
An interface used by ClientProtocol to send protocol messages.
virtual bool protocolSend(const std::string &, 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.
G::Slot::Signal & filterSignal()
Returns a signal that is raised when the protocol needs to do message filtering.
G::Slot::Signal< int, const std::string &, const std::string &, const G::StringArray & > & doneSignal()
Returns a signal that is raised once the protocol has finished with a 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.
void start(std::weak_ptr< StoredMessage >)
Starts transmission of the given message.
ClientProtocol(GNet::ExceptionSink, Sender &sender, const GAuth::SaslClientSecrets &secrets, const std::string &sasl_client_config, const Config &config, bool in_secure_tunnel)
Constructor.
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.
void filterDone(bool ok, const std::string &response, const std::string &reason)
To be called when the Filter interface has done its thing.
SMTP and message-store classes.
std::vector< std::string > StringArray
A std::vector of std::strings.
A structure containing GSmtp::ClientProtocol configuration parameters.