E-MailRelay

gpopserver.cpp
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 gpopserver.cpp
19///
20
21#include "gdef.h"
22#include "gpopserver.h"
23#include "gsocketprotocol.h"
24#include "glocal.h"
25#include "glog.h"
26#include <string>
27
28 GPop::ServerPeer::ServerPeer( GNet::ExceptionSinkUnbound esu , const GNet::ServerPeerInfo & peer_info , Store & store ,
29 const GAuth::SaslServerSecrets & server_secrets , const std::string & sasl_server_config ,
30 std::unique_ptr<ServerProtocol::Text> ptext , const ServerProtocol::Config & protocol_config ) :
31 GNet::ServerPeer(esu.bind(this),peer_info,GNet::LineBufferConfig::pop()) ,
32 m_ptext(ptext.release()) ,
33 m_protocol(*this,*this,store,server_secrets,sasl_server_config,*m_ptext,peer_info.m_address,protocol_config)
34{
35 G_LOG_S( "GPop::ServerPeer: pop connection from " << peer_info.m_address.displayString() ) ;
36 m_protocol.init() ;
37}
38
39 void GPop::ServerPeer::onDelete( const std::string & reason )
40{
41 G_LOG_S( "GPop::ServerPeer: pop connection closed: " << reason << (reason.empty()?"":": ")
42 << peerAddress().second.displayString() ) ;
43}
44
45 bool GPop::ServerPeer::onReceive( const char * line_data , std::size_t line_size , std::size_t , std::size_t , char )
46{
47 processLine( std::string(line_data,line_size) ) ;
48 return true ;
49}
50
51 void GPop::ServerPeer::processLine( const std::string & line )
52{
53 m_protocol.apply( line ) ;
54}
55
56 bool GPop::ServerPeer::protocolSend( const std::string & line , std::size_t offset )
57{
58 return send( line , offset ) ; // ServerPeer::send()
59}
60
61 void GPop::ServerPeer::onSendComplete()
62{
63 m_protocol.resume() ; // calls back to protocolSend()
64}
65
66 bool GPop::ServerPeer::securityEnabled() const
67{
68 // require a tls server certificate -- see GSsl::Library::addProfile()
69 bool enabled = GNet::SocketProtocol::secureAcceptCapable() ;
70 G_DEBUG( "ServerPeer::securityEnabled: tls library " << (enabled?"enabled":"disabled") ) ;
71 return enabled ;
72}
73
74 void GPop::ServerPeer::securityStart()
75{
76 secureAccept() ; // base class
77}
78
79 void GPop::ServerPeer::onSecure( const std::string & , const std::string & , const std::string & )
80{
81 m_protocol.secure() ;
82}
83
84// ===
85
86 GPop::Server::Server( GNet::ExceptionSink es , Store & store , const GAuth::SaslServerSecrets & secrets , const Config & config ) :
87 GNet::MultiServer(es,config.addresses,config.port,"pop",config.server_peer_config,config.server_config) ,
88 m_config(config) ,
89 m_store(store) ,
90 m_secrets(secrets)
91{
92}
93
94 GPop::Server::~Server()
95{
96 serverCleanup() ; // base class early cleanup
97}
98
99 void GPop::Server::report() const
100{
101 serverReport() ; // base class implementation
102 G_LOG_S( "GPop::Server: pop authentication secrets from \"" << m_secrets.source() << "\"" ) ;
103}
104
105std::unique_ptr<GNet::ServerPeer> GPop::Server::newPeer( GNet::ExceptionSinkUnbound esu , GNet::ServerPeerInfo peer_info , GNet::MultiServer::ServerInfo )
106{
107 std::unique_ptr<GNet::ServerPeer> ptr ;
108 try
109 {
110 std::string reason ;
111 if( !m_config.allow_remote && !GNet::Local::isLocal(peer_info.m_address,reason) )
112 {
113 G_WARNING( "GPop::Server: configured to reject non-local pop connection: " << reason ) ;
114 }
115 else
116 {
117 ptr = std::make_unique<ServerPeer>( esu , peer_info , m_store , m_secrets , m_config.sasl_server_config ,
118 newProtocolText(peer_info.m_address) , ServerProtocol::Config() ) ; // up-cast (GPop::ServerPeer to GNet::ServerPeer)
119 }
120 }
121 catch( std::exception & e ) // newPeer()
122 {
123 G_WARNING( "GPop::Server: new connection error: " << e.what() ) ;
124 }
125 return ptr ;
126}
127
128std::unique_ptr<GPop::ServerProtocol::Text> GPop::Server::newProtocolText( const GNet::Address & peer_address ) const
129{
130 return std::make_unique<ServerProtocolText>(peer_address) ; // up-cast
131}
132
133// ===
134
135GPop::Server::Config::Config() :
136 server_peer_config(0U)
137{
138}
139
140GPop::Server::Config::Config( bool allow_remote_ , unsigned int port_ , const G::StringArray & addresses_ ,
141 const GNet::ServerPeerConfig & server_peer_config_ , const GNet::ServerConfig & server_config_ ,
142 const std::string & sasl_server_config_ ) :
143 allow_remote(allow_remote_) ,
144 port(port_) ,
145 addresses(addresses_) ,
146 server_peer_config(server_peer_config_) ,
147 server_config(server_config_) ,
148 sasl_server_config(sasl_server_config_)
149{
150}
151
GAuth::SaslServerSecrets
An interface used by GAuth::SaslServer to obtain authentication secrets.
Definition: gsaslserversecrets.h:40
GNet::Address
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:53
GNet::Address::displayString
std::string displayString(bool with_scope_id=false) const
Returns a string which represents the transport address.
Definition: gaddress.cpp:375
GNet::ExceptionSinkUnbound
A potential ExceptionSink that is realised by bind()ing an exception source pointer.
Definition: gexceptionsink.h:154
GNet::ExceptionSink
A tuple containing an ExceptionHandler interface pointer and a bound 'exception source' pointer.
Definition: gexceptionsink.h:100
GNet::Local::isLocal
static bool isLocal(const Address &, std::string &reason)
Returns true if the given address appears to be 'local', or a helpful error message if not.
Definition: glocal.cpp:64
GNet::ServerPeerConfig
A structure that GNet::Server uses to configure its ServerPeer objects.
Definition: gserverpeer.h:51
GNet::ServerPeerInfo
A structure used in GNet::Server::newPeer().
Definition: gserver.h:142
GNet::SocketProtocol::secureAcceptCapable
static bool secureAcceptCapable()
Returns true if the implementation supports TLS/SSL and a "server" profile has been configured.
Definition: gsocketprotocol.cpp:804
GPop::ServerPeer
Represents a connection from a POP client.
Definition: gpopserver.h:48
GPop::ServerPeer::ServerPeer
ServerPeer(GNet::ExceptionSinkUnbound, const GNet::ServerPeerInfo &, Store &, const GAuth::SaslServerSecrets &, const std::string &sasl_server_config, std::unique_ptr< ServerProtocol::Text > ptext, const ServerProtocol::Config &)
Constructor.
Definition: gpopserver.cpp:28
GPop::ServerProtocol::init
void init()
Starts the protocol.
Definition: gpopserverprotocol.cpp:74
GPop::Server::Server
Server(GNet::ExceptionSink, Store &store, const GAuth::SaslServerSecrets &, const Config &)
Constructor. The 'secrets' reference is kept.
Definition: gpopserver.cpp:86
GPop::Server::~Server
~Server() override
Destructor.
Definition: gpopserver.cpp:94
GPop::Server::report
void report() const
Generates helpful diagnostics after construction.
Definition: gpopserver.cpp:99
GPop::Store
A message store.
Definition: gpopstore.h:45
glocal.h
glog.h
gpopserver.h
gsocketprotocol.h
GNet
Network classes.
Definition: gdef.h:1115
G::StringArray
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:31
GNet::MultiServer::ServerInfo
A structure used in GNet::MultiServer::newPeer().
Definition: gmultiserver.h:52
GNet::ServerConfig
A configuration structure for GNet::Server.
Definition: gserver.h:50
GPop::ServerProtocol::Config
A structure containing configuration parameters for ServerProtocol, currently empty.
Definition: gpopserverprotocol.h:70
GPop::Server::Config
A structure containing GPop::Server configuration parameters.
Definition: gpopserver.h:89