- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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
48 class GSmtp::ClientProtocolReply
49 {
50 public:
51 enum Type
52 {
53 PositivePreliminary = 1 ,
54 PositiveCompletion = 2 ,
55 PositiveIntermediate = 3 ,
56 TransientNegative = 4 ,
57 PermanentNegative = 5
58 } ;
59 enum SubType
60 {
61 Syntax = 0 ,
62 Information = 1 ,
63 Connections = 2 ,
64 MailSystem = 3 ,
65 Invalid_SubType = 4
66 } ;
67 enum Value
68 {
69 Internal_2xx = 222 ,
70 Internal_2yy = 223 ,
71 Internal_2zz = 224 ,
72 ServiceReady_220 = 220 ,
73 Ok_250 = 250 ,
74 Authenticated_235 = 235 ,
75 Challenge_334 = 334 ,
76 OkForData_354 = 354 ,
77 SyntaxError_500 = 500 ,
78 SyntaxError_501 = 501 ,
79 NotImplemented_502 = 502 ,
80 BadSequence_503 = 503 ,
81 NotAuthenticated_535 = 535 ,
82 NotAvailable_454 = 454 ,
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
160 class GSmtp::ClientProtocol : private GNet::AbstractTimer
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 ;
199 bool must_authenticate ;
200 bool must_accept_all_recipients ;
201 bool eight_bit_strict ;
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
217 G::Signal2<std::string,int> & doneSignal() ;
223
224 G::Signal0 & preprocessorSignal() ;
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
GSmtp::ClientProtocol::secure
void secure()
To be called when the secure socket protocol has been successfully established.
Definition: gclientprotocol.cpp:100
G::Signal2< std::string, int >
gstrings.h
GSmtp
SMTP and message-store classes.
GSmtp::ClientProtocol::ClientProtocol
ClientProtocol(Sender &sender, const GAuth::Secrets &secrets, Config config)
Constructor.
Definition: gclientprotocol.cpp:37
GSmtp::ClientProtocolReply::type
Type type() const
Returns the reply type (category).
Definition: gclientprotocol.cpp:747
GSmtp::ClientProtocol::Config::ready_timeout
unsigned int ready_timeout
Definition: gclientprotocol.h:197
gsaslclient.h
GSmtp::ClientProtocolReply::Authenticated_235
Definition: gclientprotocol.h:74
GSmtp::ClientProtocolReply::incomplete
bool incomplete() const
Returns true if the reply is incomplete.
Definition: gclientprotocol.cpp:696
GSmtp::ClientProtocolReply::errorText
std::string errorText() const
Returns the text() string but with the guarantee that the returned string is empty if and only if the...
Definition: gclientprotocol.cpp:716
GSmtp::ClientProtocolReply::SyntaxError_500
Definition: gclientprotocol.h:77
GSmtp::ClientProtocolReply::Invalid_SubType
Definition: gclientprotocol.h:65
G::Strings
std::list< std::string > Strings
A std::list of std::strings.
Definition: gstrings.h:39
GSmtp::ClientProtocol::onTimeoutException
virtual void onTimeoutException(std::exception &)
Final override from GNet::AbstractTimer.
Definition: gclientprotocol.cpp:506
GSmtp::ClientProtocolReply::OkForData_354
Definition: gclientprotocol.h:76
GSmtp::ClientProtocolReply::validFormat
bool validFormat() const
Returns true if a valid format.
Definition: gclientprotocol.cpp:691
GSmtp::ClientProtocol::Config
A structure containing GSmtp::ClientProtocol configuration parameters.
Definition: gclientprotocol.h:193
GSmtp::ClientProtocolReply::SyntaxError_501
Definition: gclientprotocol.h:78
GSmtp::ClientProtocolReply::MailSystem
Definition: gclientprotocol.h:64
gslot.h
GSmtp::ClientProtocolReply::Type
Type
Definition: gclientprotocol.h:51
GSmtp::ClientProtocolReply::Information
Definition: gclientprotocol.h:62
GSmtp::ClientProtocolReply::Value
Value
Definition: gclientprotocol.h:67
GSmtp::ClientProtocol::Sender
An interface used by ClientProtocol to send protocol messages.
Definition: gclientprotocol.h:173
GSmtp::ClientProtocolReply::is
bool is(Value v) const
Returns true if the reply value is 'v'.
Definition: gclientprotocol.cpp:711
GSmtp::ClientProtocol::doneSignal
G::Signal2< std::string, int > & doneSignal()
Returns a signal that is raised once the protocol has finished with a given message.
Definition: gclientprotocol.cpp:625
GSmtp::ClientProtocol
Implements the client-side SMTP protocol.
Definition: gclientprotocol.h:160
GSmtp::ClientProtocolReply::SubType
SubType
Definition: gclientprotocol.h:59
gsecrets.h
GSmtp::ClientProtocol::onTimeout
virtual void onTimeout()
Final override from GNet::AbstractTimer.
Definition: gclientprotocol.cpp:485
GSmtp::ClientProtocol::Config::must_authenticate
bool must_authenticate
Definition: gclientprotocol.h:199
GSmtp::ClientProtocolReply::ClientProtocolReply
ClientProtocolReply(const std::string &line=std::string())
Constructor for one line of text.
Definition: gclientprotocol.cpp:637
GAuth::Secrets
A simple interface to a store of secrets as used in authentication.
Definition: gsecrets.h:44
GSmtp::ClientProtocolReply::Internal_2xx
Definition: gclientprotocol.h:69
gtimer.h
GSmtp::ClientProtocolReply::ok
static ClientProtocolReply ok()
Factory function for an ok reply.
Definition: gclientprotocol.cpp:660
GSmtp::ClientProtocolReply::BadSequence_503
Definition: gclientprotocol.h:80
GSmtp::ClientProtocolReply::textLine
std::string textLine(const std::string &prefix) const
Returns a line of text() which starts with prefix.
Definition: gclientprotocol.cpp:727
GSmtp::ClientProtocol::sendDone
void sendDone()
To be called when a blocked connection becomes unblocked.
Definition: gclientprotocol.cpp:106
GSmtp::ClientProtocolReply::TransientNegative
Definition: gclientprotocol.h:56
GSmtp::ClientProtocol::Reply
ClientProtocolReply Reply
Definition: gclientprotocol.h:163
GSmtp::ClientProtocol::start
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.
Definition: gclientprotocol.cpp:60
GSmtp::ClientProtocolReply::Challenge_334
Definition: gclientprotocol.h:75
GSmtp::ClientProtocolReply::Internal_2yy
Definition: gclientprotocol.h:70
gmessagestore.h
GSmtp::ClientProtocol::Config::preprocessor_timeout
unsigned int preprocessor_timeout
Definition: gclientprotocol.h:198
GSmtp::ClientProtocolReply::PermanentNegative
Definition: gclientprotocol.h:57
GSmtp::ClientProtocolReply::value
int value() const
Returns the numeric value of the reply.
Definition: gclientprotocol.cpp:706
G::Signal0
Part of the slot/signal system.
Definition: gslot.h:138
gexception.h
GSmtp::ClientProtocolReply::NotAvailable_454
Definition: gclientprotocol.h:82
GSmtp::ClientProtocolReply::NotAuthenticated_535
Definition: gclientprotocol.h:81
GSmtp::ClientProtocol::Config::response_timeout
unsigned int response_timeout
Definition: gclientprotocol.h:196
G_EXCEPTION
#define G_EXCEPTION(class_name, description)
define as a function rather than a type if optimising for size
Definition: gexception.h:93
GSmtp::ClientProtocolReply::subType
SubType subType() const
Returns the reply sub-type.
Definition: gclientprotocol.cpp:753
GSmtp::ClientProtocolReply::Ok_250
Definition: gclientprotocol.h:73
GSmtp::ClientProtocol::Config::thishost_name
std::string thishost_name
Definition: gclientprotocol.h:195
GSmtp::ClientProtocolReply::ServiceReady_220
Definition: gclientprotocol.h:72
GSmtp::ClientProtocol::apply
bool apply(const std::string &rx)
Called on receipt of a line of text from the server.
Definition: gclientprotocol.cpp:146
GSmtp::ClientProtocol::Config::Config
Config(const std::string &, unsigned int, unsigned int, unsigned int, bool, bool, bool)
Definition: gclientprotocol.cpp:790
GSmtp::ClientProtocol::Config::must_accept_all_recipients
bool must_accept_all_recipients
Definition: gclientprotocol.h:200
gsmtp.h
GSmtp::ClientProtocolReply::textContains
bool textContains(std::string s) const
Returns true if the text() contains the given substring.
Definition: gclientprotocol.cpp:774
GSmtp::ClientProtocolReply::add
bool add(const ClientProtocolReply &other)
Adds more lines to this reply.
Definition: gclientprotocol.cpp:763
GSmtp::ClientProtocolReply::Syntax
Definition: gclientprotocol.h:61
GSmtp::ClientProtocolReply::error
static ClientProtocolReply error(const std::string &reason)
Factory function for a generalised error reply.
Definition: gclientprotocol.cpp:682
GSmtp::ClientProtocolReply::NotImplemented_502
Definition: gclientprotocol.h:79
GSmtp::ClientProtocol::Sender::protocolSend
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.
GSmtp::ClientProtocolReply::positive
bool positive() const
Returns true if the numeric value of the reply is less that four hundred.
Definition: gclientprotocol.cpp:701
GSmtp::ClientProtocol::preprocessorSignal
G::Signal0 & preprocessorSignal()
Returns a signal that is raised when the protocol needs to do message preprocessing.
Definition: gclientprotocol.cpp:630
GSmtp::ClientProtocolReply::Internal_2zz
Definition: gclientprotocol.h:71
GSmtp::ClientProtocolReply::Connections
Definition: gclientprotocol.h:63
GSmtp::ClientProtocolReply::PositivePreliminary
Definition: gclientprotocol.h:53
GSmtp::ClientProtocol::Sender::~Sender
virtual ~Sender()
Definition: gclientprotocol.cpp:784
GSmtp::ClientProtocolReply::PositiveIntermediate
Definition: gclientprotocol.h:55
GSmtp::ClientProtocol::preprocessorDone
void preprocessorDone(bool ok, const std::string &reason)
To be called when the Preprocessor interface has done its thing.
Definition: gclientprotocol.cpp:81
GSmtp::ClientProtocolReply
A private implementation class used by ClientProtocol.
Definition: gclientprotocol.h:48
GSmtp::ClientProtocolReply::PositiveCompletion
Definition: gclientprotocol.h:54
GSmtp::ClientProtocol::Config::eight_bit_strict
bool eight_bit_strict
Definition: gclientprotocol.h:201
GSmtp::ClientProtocolReply::text
std::string text() const
Returns the complete text of the reply, excluding the numeric part, and with embedded newlines...
Definition: gclientprotocol.cpp:722
GSmtp::ClientProtocolReply::Invalid
Definition: gclientprotocol.h:83
GNet::AbstractTimer
A timer base class that calls a pure virtual method on expiry.
Definition: gtimer.h:41