E-MailRelay

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gserverprotocol.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2018 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 // ===
17 ///
18 /// \file gserverprotocol.h
19 ///
20
21 #ifndef G_SMTP_SERVER_PROTOCOL_H
22 #define G_SMTP_SERVER_PROTOCOL_H
23
24 #include "gdef.h"
25 #include "gsmtp.h"
26 #include "gprotocolmessage.h"
27 #include "geventhandler.h"
28 #include "gaddress.h"
29 #include "gverifier.h"
30 #include "gverifierstatus.h"
31 #include "gsaslserver.h"
32 #include "gsecrets.h"
33 #include "gstatemachine.h"
34 #include "gtimer.h"
35 #include "gexception.h"
36 #include <map>
37 #include <utility>
38 #include <memory>
39
40 namespace GSmtp
41 {
42 class ServerProtocol ;
43 class ServerProtocolText ;
44 }
45
46 /// \class GSmtp::ServerProtocol
47 /// Implements the SMTP server-side protocol.
48 ///
49 /// Uses the ProtocolMessage class as its down-stream interface,
50 /// used for assembling and processing the incoming email
51 /// messages.
52 ///
53 /// Uses the ServerProtocol::Sender as its "sideways" interface
54 /// to talk back to the email-sending client.
55 ///
56 /// \see GSmtp::ProtocolMessage, RFC-2821
57 ///
58 class GSmtp::ServerProtocol : private GNet::TimerBase
59 {
60 public:
61 G_EXCEPTION( ProtocolDone , "smtp protocol done" ) ;
62 class Sender /// An interface used by ServerProtocol to send protocol replies.
63 {
64 public: virtual void protocolSend( const std::string & s , bool go_secure ) = 0 ;
65 ///< Called when the protocol class wants to send
66 ///< data down the socket.
67
68 public: virtual void protocolShutdown() = 0 ;
69 ///< Called on receipt of a quit command after the quit
70 ///< response has been sent allowing the socket to be
71 ///< shut down.
72
73 public: virtual ~Sender() ;
74 private: void operator=( const Sender & ) ; // not implemented
75 } ;
76 class Text /// An interface used by ServerProtocol to provide response text strings.
77 {
78 public: virtual std::string greeting() const = 0 ;
79 public: virtual std::string hello( const std::string & smtp_peer_name ) const = 0 ;
80 public: virtual std::string received( const std::string & smtp_peer_name , bool a , bool s ) const = 0 ;
81 public: virtual ~Text() ;
82 private: void operator=( const Text & ) ; // not implemented
83 } ;
84 struct Config /// A structure containing configuration parameters for ServerProtocol.
85 {
86 bool with_vrfy ;
87 unsigned int filter_timeout ;
88 size_t max_size ;
89 bool authentication_requires_encryption ;
90 bool mail_requires_encryption ;
91 bool disconnect_on_max_size ;
92 bool advertise_tls_if_possible ;
93 Config( bool with_vrfy , unsigned int filter_timeout , size_t max_size ,
94 bool authentication_requires_encryption ,
95 bool mail_requires_encryption ,
96 bool advertise_tls_if_possible ) ;
97 } ;
98
99 ServerProtocol( GNet::ExceptionHandler & , Sender & , Verifier & , ProtocolMessage & ,
100 const GAuth::Secrets & secrets , Text & text , GNet::Address peer_address ,
101 Config config ) ;
102 ///< Constructor.
103 ///<
104 ///< The Verifier interface is used to verify recipient
105 ///< addresses. See GSmtp::Verifier.
106 ///<
107 ///< The ProtocolMessage interface is used to assemble and
108 ///< process an incoming message.
109 ///<
110 ///< The Sender interface is used to send protocol
111 ///< replies back to the client.
112 ///<
113 ///< The Text interface is used to get informational text
114 ///< for returning to the client.
115 ///<
116 ///< Exceptions thrown out of event-loop and timer callbacks
117 ///< are delivered to the given exception handler interface.
118 ///<
119 ///< All references are kept.
120
121 void init() ;
122 ///< Starts the protocol. Use only once after construction.
123
124 virtual ~ServerProtocol() ;
125 ///< Destructor.
126
127 bool apply( const char * line_data , size_t line_size , size_t eolsize ) ;
128 ///< Called on receipt of a line of text from the remote client
129 ///< Returns true. Throws ProtocolDone at the end of the
130 ///< protocol.
131
132 void secure( const std::string & certificate ) ;
133 ///< To be called when the transport protocol goes
134 ///< into secure mode.
135
136 protected:
137 virtual void onTimeout() override ;
138 ///< Override from GNet::TimerBase.
139
140 private:
141 enum Event
142 {
143 eQuit ,
144 eHelo ,
145 eEhlo ,
146 eRset ,
147 eNoop ,
148 eExpn ,
149 eData ,
150 eRcpt ,
151 eMail ,
152 eStartTls ,
153 eSecure ,
154 eVrfy ,
155 eVrfyReply ,
156 eHelp ,
157 eAuth ,
158 eAuthData ,
159 eContent ,
160 eEot ,
161 eDone ,
162 eTimeout ,
163 eUnknown
164 } ;
165 enum State
166 {
167 sStart ,
168 sEnd ,
169 sIdle ,
170 sGotMail ,
171 sGotRcpt ,
172 sVrfyStart ,
173 sVrfyIdle ,
174 sVrfyGotMail ,
175 sVrfyGotRcpt ,
176 sVrfyTo1 ,
177 sVrfyTo2 ,
178 sData ,
179 sProcessing ,
180 sAuth ,
181 sStartingTls ,
182 sDiscarding ,
183 s_Any ,
184 s_Same
185 } ;
186 typedef std::pair<const char *,size_t> EventData ;
187 typedef G::StateMachine<ServerProtocol,State,Event,EventData> Fsm ;
188
189 private:
190 ServerProtocol( const ServerProtocol & ) ; // not implemented
191 void operator=( const ServerProtocol & ) ; // not implemented
192 void send( std::string , bool = false ) ;
193 Event commandEvent( const std::string & ) const ;
194 std::string commandWord( const std::string & line ) const ;
195 std::string commandLine( const std::string & line ) const ;
196 static const std::string & crlf() ;
197 bool authenticationRequiresEncryption() const ;
198 void reset() ;
199 void badClientEvent() ;
200 void processDone( bool , unsigned long , std::string , std::string ) ; // ProtocolMessage::doneSignal()
201 void prepareDone( bool , bool , std::string ) ;
202 bool isEndOfText( const char * , size_t ) const ;
203 bool isEscaped( const char * , size_t ) const ;
204 void doNoop( EventData , bool & ) ;
205 void doIgnore( EventData , bool & ) ;
206 void doNothing( EventData , bool & ) ;
207 void doDiscarded( EventData , bool & ) ;
208 void doDiscard( EventData , bool & ) ;
209 void doHelp( EventData , bool & ) ;
210 void doExpn( EventData , bool & ) ;
211 void doQuit( EventData , bool & ) ;
212 void doEhlo( EventData , bool & ) ;
213 void doHelo( EventData , bool & ) ;
214 void doAuth( EventData , bool & ) ;
215 void doAuthData( EventData , bool & ) ;
216 void doMail( EventData , bool & ) ;
217 void doRcpt( EventData , bool & ) ;
218 void doUnknown( EventData , bool & ) ;
219 void doRset( EventData , bool & ) ;
220 void doData( EventData , bool & ) ;
221 void doContent( EventData , bool & ) ;
222 void doComplete( EventData , bool & ) ;
223 void doEot( EventData , bool & ) ;
224 void doVrfy( EventData , bool & ) ;
225 void doVrfyReply( EventData , bool & ) ;
226 void doVrfyToReply( EventData , bool & ) ;
227 void doNoRecipients( EventData , bool & ) ;
228 void doStartTls( EventData , bool & ) ;
229 void doSecure( EventData , bool & ) ;
230 void verifyDone( std::string , VerifierStatus status ) ;
231 void sendBadFrom( std::string ) ;
232 void sendTooBig( bool disconnecting = false ) ;
233 void sendChallenge( const std::string & ) ;
234 void sendBadTo( const std::string & , bool ) ;
235 void sendOutOfSequence( const std::string & ) ;
236 void sendGreeting( const std::string & ) ;
237 void sendClosing() ;
238 void sendUnrecognised( const std::string & ) ;
239 void sendNotImplemented() ;
240 void sendHeloReply() ;
241 void sendEhloReply() ;
242 void sendRsetReply() ;
243 void sendMailReply() ;
244 void sendRcptReply() ;
245 void sendDataReply() ;
246 void sendCompletionReply( bool ok , const std::string & ) ;
247 void sendAuthRequired() ;
248 void sendEncryptionRequired() ;
249 void sendNoRecipients() ;
250 void sendMissingParameter() ;
251 void sendVerified( const std::string & ) ;
252 void sendNotVerified( const std::string & , bool ) ;
253 void sendWillAccept( const std::string & ) ;
254 void sendAuthDone( bool ok ) ;
255 void sendOk() ;
256 std::pair<std::string,std::string> parseAddress( const std::string & ) const ;
257 std::pair<std::string,std::string> parseMailFrom( const std::string & ) const ;
258 std::string parseMailParameter( const std::string & , const std::string & ) const ;
259 size_t parseMailSize( const std::string & ) const ;
260 std::string parseMailAuth( const std::string & ) const ;
261 std::pair<std::string,std::string> parseRcptTo( const std::string & ) const ;
262 std::string parseRcptParameter( const std::string & ) const ;
263 std::string parsePeerName( const std::string & ) const ;
264 void verify( const std::string & , const std::string & ) ;
265
266 private:
267 Sender & m_sender ;
268 Verifier & m_verifier ;
269 Text & m_text ;
270 ProtocolMessage & m_message ;
271 unique_ptr<GAuth::SaslServer> m_sasl ;
272 Config m_config ;
273 Fsm m_fsm ;
274 bool m_with_starttls ;
275 GNet::Address m_peer_address ;
276 bool m_secure ;
277 std::string m_certificate ;
278 unsigned int m_bad_client_count ;
279 unsigned int m_bad_client_limit ;
280 std::string m_session_peer_name ;
281 bool m_session_authenticated ;
282 std::string m_buffer ;
283 } ;
284
285 /// \class GSmtp::ServerProtocolText
286 /// A default implementation for the
287 /// ServerProtocol::Text interface.
288 ///
289 class GSmtp::ServerProtocolText : public ServerProtocol::Text
290 {
291 public:
292 ServerProtocolText( const std::string & code_ident , const std::string & thishost ,
293 const GNet::Address & peer_address ) ;
294 ///< Constructor.
295
296 virtual std::string greeting() const override ;
297 ///< Override from GSmtp::ServerProtocol::Text.
298
299 virtual std::string hello( const std::string & smtp_peer_name_from_helo ) const override ;
300 ///< Override from GSmtp::ServerProtocol::Text.
301
302 virtual std::string received( const std::string & smtp_peer_name_from_helo ,
303 bool authenticated , bool secure ) const override ;
304 ///< Override from GSmtp::ServerProtocol::Text.
305
306 static std::string receivedLine( const std::string & smtp_peer_name_from_helo ,
307 const std::string & peer_address , const std::string & thishost ,
308 bool authenticated , bool secure ) ;
309 ///< Returns a standard "Received:" line.
310
311 private:
312 std::string m_code_ident ;
313 std::string m_thishost ;
314 GNet::Address m_peer_address ;
315 } ;
316
317 #endif
GSmtp::ServerProtocol::secure
void secure(const std::string &certificate)
To be called when the transport protocol goes into secure mode.
Definition: gserverprotocol.cpp:116
GSmtp::ServerProtocol::Sender
An interface used by ServerProtocol to send protocol replies.
Definition: gserverprotocol.h:62
GSmtp::ServerProtocolText::ServerProtocolText
ServerProtocolText(const std::string &code_ident, const std::string &thishost, const GNet::Address &peer_address)
Constructor.
Definition: gserverprotocol.cpp:896
GSmtp
SMTP and message-store classes.
Definition: gadminserver.h:39
GSmtp::ServerProtocol::Text
An interface used by ServerProtocol to provide response text strings.
Definition: gserverprotocol.h:76
gverifierstatus.h
gprotocolmessage.h
GNet::Address
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:54
gsaslserver.h
GSmtp::ServerProtocol::Sender::protocolSend
virtual void protocolSend(const std::string &s, bool go_secure)=0
Called when the protocol class wants to send data down the socket.
GSmtp::ServerProtocol
Implements the SMTP server-side protocol.
Definition: gserverprotocol.h:58
GSmtp::ServerProtocolText::received
virtual std::string received(const std::string &smtp_peer_name_from_helo, bool authenticated, bool secure) const override
Override from GSmtp::ServerProtocol::Text.
Definition: gserverprotocol.cpp:914
gstatemachine.h
gverifier.h
GSmtp::Verifier
An asynchronous interface that verifies recipient 'to' addresses.
Definition: gverifier.h:43
GNet::ExceptionHandler
An abstract interface for handling exceptions thrown out of event-loop callbacks (socket events...
Definition: gexceptionhandler.h:44
GSmtp::ServerProtocol::init
void init()
Starts the protocol. Use only once after construction.
Definition: gserverprotocol.cpp:105
gsecrets.h
GAuth::Secrets
A simple interface for a store of secrets used in authentication.
Definition: gsecrets.h:40
GSmtp::ServerProtocol::~ServerProtocol
virtual ~ServerProtocol()
Destructor.
Definition: gserverprotocol.cpp:110
gtimer.h
GSmtp::ServerProtocolText::hello
virtual std::string hello(const std::string &smtp_peer_name_from_helo) const override
Override from GSmtp::ServerProtocol::Text.
Definition: gserverprotocol.cpp:909
geventhandler.h
GSmtp::ServerProtocolText::receivedLine
static std::string receivedLine(const std::string &smtp_peer_name_from_helo, const std::string &peer_address, const std::string &thishost, bool authenticated, bool secure)
Returns a standard "Received:" line.
Definition: gserverprotocol.cpp:920
GSmtp::ServerProtocolText
A default implementation for the ServerProtocol::Text interface.
Definition: gserverprotocol.h:289
gexception.h
GSmtp::ServerProtocol::Config
A structure containing configuration parameters for ServerProtocol.
Definition: gserverprotocol.h:84
GSmtp::ProtocolMessage
An interface used by the ServerProtocol class to assemble and process an incoming message...
Definition: gprotocolmessage.h:63
GSmtp::ServerProtocolText::greeting
virtual std::string greeting() const override
Override from GSmtp::ServerProtocol::Text.
Definition: gserverprotocol.cpp:904
GNet::TimerBase
An interface used by GNet::TimerList to keep track of pending timeouts and to deliver timeout events...
Definition: gtimer.h:40
gsmtp.h
gaddress.h
GSmtp::ServerProtocol::apply
bool apply(const char *line_data, size_t line_size, size_t eolsize)
Called on receipt of a line of text from the remote client Returns true.
Definition: gserverprotocol.cpp:148
GSmtp::ServerProtocol::onTimeout
virtual void onTimeout() override
Override from GNet::TimerBase.
Definition: gserverprotocol.cpp:218
GSmtp::ServerProtocol::Sender::protocolShutdown
virtual void protocolShutdown()=0
Called on receipt of a quit command after the quit response has been sent allowing the socket to be s...
G::StateMachine< ServerProtocol, State, Event, EventData >
GSmtp::ServerProtocol::ServerProtocol
ServerProtocol(GNet::ExceptionHandler &, Sender &, Verifier &, ProtocolMessage &, const GAuth::Secrets &secrets, Text &text, GNet::Address peer_address, Config config)
Constructor.
Definition: gserverprotocol.cpp:36