E-MailRelay
gsmtpserver.h
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2021 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 gsmtpserver.h
19///
20
21#ifndef G_SMTP_SERVER_H
22#define G_SMTP_SERVER_H
23
24#include "gdef.h"
25#include "gmultiserver.h"
26#include "gsmtpclient.h"
27#include "gfilterfactory.h"
28#include "gdnsblock.h"
29#include "glinebuffer.h"
30#include "gverifier.h"
31#include "gmessagestore.h"
32#include "gsmtpserverprotocol.h"
33#include "gprotocolmessage.h"
34#include "gexception.h"
35#include <string>
36#include <sstream>
37#include <memory>
38#include <list>
39
40namespace GSmtp
41{
42 class Server ;
43 class ServerPeer ;
44}
45
46//| \class GSmtp::Server
47/// An SMTP server class.
48///
50{
51public:
52 using AddressList = std::vector<GNet::Address> ;
53
54 struct Config /// A structure containing GSmtp::Server configuration parameters.
55 {
56 bool allow_remote{false} ;
57 G::StringArray interfaces ;
58 unsigned int port{0U} ;
59 std::string ident ;
60 bool anonymous{false} ;
61 std::string filter_address ;
62 unsigned int filter_timeout{0U} ;
63 std::string verifier_address ;
64 unsigned int verifier_timeout{0U} ;
65 GNet::ServerPeerConfig server_peer_config ;
66 GNet::ServerConfig server_config ;
67 ServerProtocol::Config protocol_config ;
68 std::string sasl_server_config ;
69 std::string dnsbl_config ;
70
71 Config() ;
72 Config( bool allow_remote , const G::StringArray & interfaces , unsigned int port ,
73 const std::string & ident , bool anonymous , const std::string & filter_address ,
74 unsigned int filter_timeout , const std::string & verifier_adress ,
75 unsigned int verifier_timeout , GNet::ServerPeerConfig server_peer_config ,
76 ServerProtocol::Config protocol_config , const std::string & sasl_server_config ,
77 const std::string & dnsbl_config ) ;
78 Config & set_allow_remote( bool = true ) ;
79 Config & set_interfaces( const G::StringArray & ) ;
80 Config & set_port( unsigned int ) ;
81 Config & set_ident( const std::string & ) ;
82 Config & set_anonymous( bool = true ) ;
83 Config & set_filter_address( const std::string & ) ;
84 Config & set_filter_timeout( unsigned int ) ;
85 Config & set_verifier_address( const std::string & ) ;
86 Config & set_verifier_timeout( unsigned int ) ;
87 Config & set_server_peer_config( const GNet::ServerPeerConfig & ) ;
88 Config & set_server_config( const GNet::ServerConfig & ) ;
89 Config & set_protocol_config( const ServerProtocol::Config & ) ;
90 Config & set_sasl_server_config( const std::string & ) ;
91 Config & set_dnsbl_config( const std::string & ) ;
92 } ;
93
95 const GAuth::SaslClientSecrets & client_secrets , const GAuth::SaslServerSecrets & server_secrets ,
96 const Config & server_config , const std::string & forward_to ,
97 const GSmtp::Client::Config & client_config ) ;
98 ///< Constructor. Listens on the given port number using INET_ANY
99 ///< if 'server_config.interfaces' is empty, or on specific
100 ///< interfaces otherwise.
101 ///<
102 ///< If the forward-to address is given then all messages are
103 ///< forwarded immediately, using the given client configuration.
104
105 ~Server() override ;
106 ///< Destructor.
107
108 void report() const ;
109 ///< Generates helpful diagnostics after construction.
110
112 ///< Returns a signal that indicates that something has happened.
113
114 std::unique_ptr<ProtocolMessage> newProtocolMessage( GNet::ExceptionSink ) ;
115 ///< Called by GSmtp::ServerPeer to construct a ProtocolMessage.
116
117private: // overrides
118 std::unique_ptr<GNet::ServerPeer> newPeer( GNet::ExceptionSinkUnbound , GNet::ServerPeerInfo , GNet::MultiServer::ServerInfo ) override ; // Override from GNet::MultiServer.
119
120public:
121 Server( const Server & ) = delete ;
122 Server( Server && ) = delete ;
123 void operator=( const Server & ) = delete ;
124 void operator=( Server && ) = delete ;
125
126private:
127 std::unique_ptr<Filter> newFilter( GNet::ExceptionSink ) const ;
128 std::unique_ptr<ProtocolMessage> newProtocolMessageStore( std::unique_ptr<Filter> ) ;
129 std::unique_ptr<ProtocolMessage> newProtocolMessageForward( GNet::ExceptionSink , std::unique_ptr<ProtocolMessage> ) ;
130 std::unique_ptr<ServerProtocol::Text> newProtocolText( bool , const GNet::Address & ) const ;
131
132private:
133 MessageStore & m_store ;
134 FilterFactory & m_ff ;
135 Config m_server_config ;
136 Client::Config m_client_config ;
137 const GAuth::SaslServerSecrets & m_server_secrets ;
138 std::string m_sasl_server_config ;
139 std::string m_forward_to ;
140 const GAuth::SaslClientSecrets & m_client_secrets ;
141 std::string m_sasl_client_config ;
143} ;
144
145//| \class GSmtp::ServerPeer
146/// Handles a connection from a remote SMTP client.
147/// \see GSmtp::Server
148///
150{
151public:
152 G_EXCEPTION( SendError , "failed to send smtp response" ) ;
153
154 ServerPeer( GNet::ExceptionSinkUnbound , const GNet::ServerPeerInfo & peer_info , Server & server ,
155 const GAuth::SaslServerSecrets & server_secrets , const Server::Config & server_config ,
156 std::unique_ptr<ServerProtocol::Text> ptext ) ;
157 ///< Constructor.
158
159private: // overrides
160 void onSendComplete() override ; // Override from GNet::ServerPeer.
161 void onDelete( const std::string & reason ) override ; // Override from GNet::ServerPeer.
162 bool onReceive( const char * , std::size_t , std::size_t , std::size_t , char ) override ; // Override from GNet::ServerPeer.
163 void onSecure( const std::string & , const std::string & , const std::string & ) override ; // Override from GNet::SocketProtocolSink.
164 void protocolSend( const std::string & line , bool ) override ; // Override from ServerProtocol::Sender.
165 void protocolShutdown() override ; // Override from ServerProtocol::Sender.
166 void onDnsBlockResult( const GNet::DnsBlockResult & ) override ; // Override from GNet::DnsBlockCallback.
167 void onData( const char * , std::size_t ) override ; // Override from GNet::ServerPeer.
168
169public:
170 ~ServerPeer() override = default ;
171 ServerPeer( const ServerPeer & ) = delete ;
172 ServerPeer( ServerPeer && ) = delete ;
173 void operator=( const ServerPeer & ) = delete ;
174 void operator=( ServerPeer && ) = delete ;
175
176private:
177 void onCheckTimeout() ;
178 void onFlushTimeout() ;
179
180private:
181 Server & m_server ;
182 GNet::DnsBlock m_block ;
183 GNet::Timer<ServerPeer> m_flush_timer ;
184 GNet::Timer<ServerPeer> m_check_timer ;
185 std::unique_ptr<Verifier> m_verifier ;
186 std::unique_ptr<ProtocolMessage> m_pmessage ;
187 std::unique_ptr<ServerProtocol::Text> m_ptext ;
188 GNet::LineBuffer m_line_buffer ;
189 ServerProtocol m_protocol ; // order dependency -- last
190} ;
191
192inline GSmtp::Server::Config & GSmtp::Server::Config::set_allow_remote( bool b ) { allow_remote = b ; return *this ; }
193inline GSmtp::Server::Config & GSmtp::Server::Config::set_interfaces( const G::StringArray & a ) { interfaces = a ; return *this ; }
194inline GSmtp::Server::Config & GSmtp::Server::Config::set_port( unsigned int n ) { port = n ; return *this ; }
195inline GSmtp::Server::Config & GSmtp::Server::Config::set_ident( const std::string & s ) { ident = s ; return *this ; }
196inline GSmtp::Server::Config & GSmtp::Server::Config::set_anonymous( bool b ) { anonymous = b ; return *this ; }
197inline GSmtp::Server::Config & GSmtp::Server::Config::set_filter_address( const std::string & s ) { filter_address = s ; return *this ; }
198inline GSmtp::Server::Config & GSmtp::Server::Config::set_filter_timeout( unsigned int t ) { filter_timeout = t ; return *this ; }
199inline GSmtp::Server::Config & GSmtp::Server::Config::set_verifier_address( const std::string & s ) { verifier_address = s ; return *this ; }
200inline GSmtp::Server::Config & GSmtp::Server::Config::set_verifier_timeout( unsigned int t ) { verifier_timeout = t ; return *this ; }
201inline GSmtp::Server::Config & GSmtp::Server::Config::set_server_peer_config( const GNet::ServerPeerConfig & c ) { server_peer_config = c ; return *this ; }
202inline GSmtp::Server::Config & GSmtp::Server::Config::set_server_config( const GNet::ServerConfig & c ) { server_config = c ; return *this ; }
203inline GSmtp::Server::Config & GSmtp::Server::Config::set_protocol_config( const ServerProtocol::Config & c ) { protocol_config = c ; return *this ; }
204inline GSmtp::Server::Config & GSmtp::Server::Config::set_sasl_server_config( const std::string & s ) { sasl_server_config = s ; return *this ; }
205inline GSmtp::Server::Config & GSmtp::Server::Config::set_dnsbl_config( const std::string & s ) { dnsbl_config = s ; return *this ; }
206
207#endif
An interface used by GAuth::SaslClient to obtain a client id and its authentication secret.
An interface used by GAuth::SaslServer to obtain authentication secrets.
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:53
A callback interface for GNet::DnsBlock.
Definition: gdnsblock.h:208
A result structure for GNet::DnsBlock, as delivered by the DnsBlockCallback interface.
Definition: gdnsblock.h:78
Implements DNS blocklisting, as per RFC-5782.
Definition: gdnsblock.h:145
A potential ExceptionSink that is realised by bind()ing an exception source pointer.
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
A class that does line buffering, supporting auto-detection of line endings and fixed-size block extr...
Definition: glinebuffer.h:83
A server that listens on more than one address using a facade pattern to multiple GNet::Server instan...
Definition: gmultiserver.h:45
A structure that GNet::Server uses to configure its ServerPeer objects.
Definition: gserverpeer.h:51
A structure used in GNet::Server::newPeer().
Definition: gserver.h:142
An abstract base class for the GNet::Server's connection to a remote client.
Definition: gserverpeer.h:68
A timer class template in which the timeout is delivered to the specified method.
Definition: gtimer.h:129
A factory interface for GSmtp::Filter message processors.
A class which allows SMTP messages to be stored and retrieved.
Definition: gmessagestore.h:73
Handles a connection from a remote SMTP client.
Definition: gsmtpserver.h:150
ServerPeer(GNet::ExceptionSinkUnbound, const GNet::ServerPeerInfo &peer_info, Server &server, const GAuth::SaslServerSecrets &server_secrets, const Server::Config &server_config, std::unique_ptr< ServerProtocol::Text > ptext)
Constructor.
Definition: gsmtpserver.cpp:77
An interface used by ServerProtocol to send protocol replies.
Implements the SMTP server-side protocol.
An SMTP server class.
Definition: gsmtpserver.h:50
G::Slot::Signal< const std::string &, const std::string & > & eventSignal()
Returns a signal that indicates that something has happened.
~Server() override
Destructor.
Server(GNet::ExceptionSink es, MessageStore &store, FilterFactory &, const GAuth::SaslClientSecrets &client_secrets, const GAuth::SaslServerSecrets &server_secrets, const Config &server_config, const std::string &forward_to, const GSmtp::Client::Config &client_config)
Constructor.
std::unique_ptr< ProtocolMessage > newProtocolMessage(GNet::ExceptionSink)
Called by GSmtp::ServerPeer to construct a ProtocolMessage.
void report() const
Generates helpful diagnostics after construction.
SMTP and message-store classes.
Definition: gadminserver.h:39
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:31
A structure used in GNet::MultiServer::newPeer().
Definition: gmultiserver.h:52
A configuration structure for GNet::Server.
Definition: gserver.h:50
A structure containing GSmtp::Client configuration parameters.
Definition: gsmtpclient.h:57
A structure containing configuration parameters for ServerProtocol.
A structure containing GSmtp::Server configuration parameters.
Definition: gsmtpserver.h:55