gclientprotocol.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2013 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 // ===
20 
21 #ifndef G_SMTP_CLIENT_PROTOCOL_H
22 #define G_SMTP_CLIENT_PROTOCOL_H
23 
24 #include "gdef.h"
25 #include "gnet.h"
26 #include "gsmtp.h"
27 #include "gmessagestore.h"
28 #include "gsaslclient.h"
29 #include "gsecrets.h"
30 #include "gslot.h"
31 #include "gstrings.h"
32 #include "gtimer.h"
33 #include "gexception.h"
34 #include <memory>
35 #include <iostream>
36 
38 namespace GSmtp
39 {
40  class ClientProtocol ;
41  class ClientProtocolReply ;
42 }
43 
49 {
50 public:
51  enum Type
52  {
58  } ;
59  enum SubType
60  {
61  Syntax = 0 ,
64  MailSystem = 3 ,
66  } ;
67  enum Value
68  {
69  Internal_2xx = 222 ,
70  Internal_2yy = 223 ,
71  Internal_2zz = 224 ,
73  Ok_250 = 250 ,
75  Challenge_334 = 334 ,
76  OkForData_354 = 354 ,
83  Invalid = 0
84  } ;
85 
86  static ClientProtocolReply ok() ;
88 
89  static ClientProtocolReply ok( Value ) ;
91 
92  static ClientProtocolReply error( const std::string & reason ) ;
94 
95  explicit ClientProtocolReply( const std::string & line = std::string() ) ;
97 
98  bool add( const ClientProtocolReply & other ) ;
101 
102  bool incomplete() const ;
104 
105  bool validFormat() const ;
107 
108  bool positive() const ;
111 
112  bool is( Value v ) const ;
114 
115  int value() const ;
117 
118  std::string text() const ;
122 
123  std::string errorText() const ;
127 
128  bool textContains( std::string s ) const ;
131 
132  std::string textLine( const std::string & prefix ) const ;
135 
136  Type type() const ;
138 
139  SubType subType() const ;
141 
142 private:
143  static bool is_digit( char ) ;
144 
145 private:
146  bool m_complete ;
147  bool m_valid ;
148  int m_value ;
149  std::string m_text ;
150 } ;
151 
161 {
162 public:
163  G_EXCEPTION( NotReady , "not ready" ) ;
164  G_EXCEPTION( ResponseError , "protocol error: unexpected response" ) ;
165  G_EXCEPTION( NoMechanism , "cannot do authentication mandated by remote server" ) ;
166  G_EXCEPTION( AuthenticationRequired , "authentication required by the remote smtp server" ) ;
167  G_EXCEPTION( AuthenticationNotSupported , "authentication not supported by the remote smtp server" ) ;
168  G_EXCEPTION( AuthenticationError , "authentication error" ) ;
169  G_EXCEPTION( TlsError , "tls/ssl error" ) ;
170  typedef ClientProtocolReply Reply ;
171 
173  class Sender
174  {
175  public: virtual bool protocolSend( const std::string & , size_t offset , bool go_secure ) = 0 ;
187 
188  private: void operator=( const Sender & ) ; // not implemented
189  public: virtual ~Sender() ;
190  } ;
191 
193  struct Config
194  {
195  std::string thishost_name ;
196  unsigned int response_timeout ;
197  unsigned int ready_timeout ;
198  unsigned int preprocessor_timeout ;
202  Config( const std::string & , unsigned int , unsigned int , unsigned int , bool , bool , bool ) ;
203  } ;
204 
205  ClientProtocol( Sender & sender , const GAuth::Secrets & secrets , Config config ) ;
216 
223 
228 
229  void start( const std::string & from , const G::Strings & to , bool eight_bit ,
230  std::string authentication , std::string server_name ,
231  std::auto_ptr<std::istream> content ) ;
240 
241  void sendDone() ;
244 
245  void preprocessorDone( bool ok , const std::string & reason ) ;
251 
252  void secure() ;
255 
256  bool apply( const std::string & rx ) ;
260 
261 protected:
262  virtual void onTimeout() ;
264 
265  virtual void onTimeoutException( std::exception & ) ;
267 
268 private:
269  void send( const char * ) ;
270  void send( const char * , const std::string & ) ;
271  void send( const char * , const std::string & , const char * ) ;
272  bool send( const std::string & , bool eot , bool sensitive = false ) ;
273  bool sendLine( std::string & ) ;
274  size_t sendLines() ;
275  void sendEhlo() ;
276  void sendHelo() ;
277  void sendMail() ;
278  void sendMailCore() ;
279  bool endOfContent() const ;
280  static const std::string & crlf() ;
281  bool applyEvent( const Reply & event , bool is_start_event = false ) ;
282  static bool parseReply( Reply & , const std::string & , std::string & ) ;
283  void raiseDoneSignal( const std::string & , int = 0 , bool = false ) ;
284  bool serverAuth( const ClientProtocolReply & reply ) const ;
285  G::Strings serverAuthMechanisms( const ClientProtocolReply & reply ) const ;
286  void startPreprocessing() ;
287 
288 private:
289  enum State { sInit , sStarted , sServiceReady , sSentEhlo , sSentHelo , sAuth1 , sAuth2 , sSentMail ,
290  sPreprocessing , sSentRcpt , sSentData , sSentDataStub , sData , sSentDot , sStartTls , sSentTlsEhlo , sDone } ;
291  Sender & m_sender ;
292  const GAuth::Secrets & m_secrets ;
293  std::string m_thishost ;
294  State m_state ;
295  std::string m_from ;
296  G::Strings m_to ;
297  size_t m_to_size ;
298  size_t m_to_accepted ;
299  std::auto_ptr<std::istream> m_content ;
300  bool m_server_has_auth ;
301  bool m_server_has_8bitmime ;
302  bool m_server_has_tls ;
303  bool m_message_is_8bit ;
304  std::string m_message_authentication ;
305  Reply m_reply ;
306  bool m_authenticated_with_server ;
307  std::string m_auth_mechanism ;
308  std::auto_ptr<GAuth::SaslClient> m_sasl ;
309  bool m_must_authenticate ;
310  bool m_must_accept_all_recipients ;
311  bool m_strict ;
312  bool m_warned ;
313  unsigned int m_response_timeout ;
314  unsigned int m_ready_timeout ;
315  unsigned int m_preprocessor_timeout ;
316  G::Signal2<std::string,int> m_done_signal ;
317  G::Signal0 m_preprocessor_signal ;
318 } ;
319 
320 #endif
void secure()
To be called when the secure socket protocol has been successfully established.
SMTP and message-store classes.
ClientProtocol(Sender &sender, const GAuth::Secrets &secrets, Config config)
Constructor.
Type type() const
Returns the reply type (category).
bool incomplete() const
Returns true if the reply is incomplete.
std::string errorText() const
Returns the text() string but with the guarantee that the returned string is empty if and only if the...
std::list< std::string > Strings
A std::list of std::strings.
Definition: gstrings.h:39
virtual void onTimeoutException(std::exception &)
Final override from GNet::AbstractTimer.
bool validFormat() const
Returns true if a valid format.
A structure containing GSmtp::ClientProtocol configuration parameters.
An interface used by ClientProtocol to send protocol messages.
bool is(Value v) const
Returns true if the reply value is 'v'.
G::Signal2< std::string, int > & doneSignal()
Returns a signal that is raised once the protocol has finished with a given message.
Implements the client-side SMTP protocol.
virtual void onTimeout()
Final override from GNet::AbstractTimer.
ClientProtocolReply(const std::string &line=std::string())
Constructor for one line of text.
A simple interface to a store of secrets as used in authentication.
Definition: gsecrets.h:44
static ClientProtocolReply ok()
Factory function for an ok reply.
std::string textLine(const std::string &prefix) const
Returns a line of text() which starts with prefix.
void sendDone()
To be called when a blocked connection becomes unblocked.
ClientProtocolReply Reply
void start(const std::string &from, const G::Strings &to, bool eight_bit, std::string authentication, std::string server_name, std::auto_ptr< std::istream > content)
Starts transmission of the given message.
int value() const
Returns the numeric value of the reply.
Part of the slot/signal system.
Definition: gslot.h:138
#define G_EXCEPTION(class_name, description)
define as a function rather than a type if optimising for size
Definition: gexception.h:93
SubType subType() const
Returns the reply sub-type.
bool apply(const std::string &rx)
Called on receipt of a line of text from the server.
Config(const std::string &, unsigned int, unsigned int, unsigned int, bool, bool, bool)
bool textContains(std::string s) const
Returns true if the text() contains the given substring.
bool add(const ClientProtocolReply &other)
Adds more lines to this reply.
static ClientProtocolReply error(const std::string &reason)
Factory function for a generalised error reply.
virtual bool protocolSend(const std::string &, size_t offset, bool go_secure)=0
Called by the Protocol class to send network data to the peer.
bool positive() const
Returns true if the numeric value of the reply is less that four hundred.
G::Signal0 & preprocessorSignal()
Returns a signal that is raised when the protocol needs to do message preprocessing.
void preprocessorDone(bool ok, const std::string &reason)
To be called when the Preprocessor interface has done its thing.
A private implementation class used by ClientProtocol.
std::string text() const
Returns the complete text of the reply, excluding the numeric part, and with embedded newlines...
A timer base class that calls a pure virtual method on expiry.
Definition: gtimer.h:41