E-MailRelay
gpopserver.cpp
Go to the documentation of this file.
1//
2// Copyright (C) 2001-2024 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
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(esbind(esu,this),std::move(peer_info),GNet::LineBuffer::Config::pop()) ,
32 m_ptext(ptext.release()) ,
33 m_protocol(*this,*this,store,server_secrets,sasl_server_config,*m_ptext,peerAddress(),protocol_config)
34{
35 G_LOG_S( "GPop::ServerPeer: pop connection from " << peerAddress().displayString() ) ;
36 m_protocol.init() ;
37}
38
39void GPop::ServerPeer::onDelete( const std::string & reason )
40{
41 G_LOG_S( "GPop::ServerPeer: pop connection closed: " << reason << (reason.empty()?"":": ")
42 << peerAddress().displayString() ) ;
43}
44
45bool 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
51void GPop::ServerPeer::processLine( const std::string & line )
52{
53 m_protocol.apply( line ) ;
54}
55
56bool GPop::ServerPeer::protocolSend( std::string_view line , std::size_t offset )
57{
58 std::string_view output = line.substr( std::min(offset,line.size()) ) ;
59 return output.empty() ? true : send( output ) ; // GNet::ServerPeer::send()
60}
61
62void GPop::ServerPeer::onSendComplete()
63{
64 m_protocol.resume() ; // calls back to protocolSend()
65}
66
67bool GPop::ServerPeer::securityEnabled() const
68{
69 // require a tls server certificate -- see GSsl::Library::addProfile()
70 bool enabled = secureAcceptCapable() ;
71 G_DEBUG( "ServerPeer::securityEnabled: tls library " << (enabled?"enabled":"disabled") ) ;
72 return enabled ;
73}
74
75void GPop::ServerPeer::securityStart()
76{
77 secureAccept() ; // base class
78}
79
80void GPop::ServerPeer::onSecure( const std::string & , const std::string & , const std::string & )
81{
82 m_protocol.secure() ;
83}
84
85// ===
86
87GPop::Server::Server( GNet::EventState es , Store & store , const GAuth::SaslServerSecrets & secrets , const Config & config ) :
88 GNet::MultiServer(es,config.addresses,config.port,"pop",config.net_server_peer_config,config.net_server_config) ,
89 m_config(config) ,
90 m_store(store) ,
91 m_secrets(secrets)
92{
93}
94
96{
97 serverCleanup() ; // base class early cleanup
98}
99
100void GPop::Server::report( const std::string & group ) const
101{
102 serverReport( group ) ; // base class implementation
103 G_LOG_S( "GPop::Server: " << (group.empty()?"":"[") << group << (group.empty()?"":"] ")
104 << "pop server authentication secrets from \"" << m_secrets.source() << "\"" ) ;
105}
106
107std::unique_ptr<GNet::ServerPeer> GPop::Server::newPeer( GNet::EventStateUnbound esu , GNet::ServerPeerInfo && peer_info , GNet::MultiServer::ServerInfo )
108{
109 std::unique_ptr<GNet::ServerPeer> ptr ;
110 try
111 {
112 std::string reason ;
113 if( !m_config.allow_remote && !peer_info.m_address.isLocal(reason) )
114 {
115 G_WARNING( "GPop::Server: configured to reject non-local pop connection: " << reason ) ;
116 }
117 else
118 {
119 GNet::Address peer_address = peer_info.m_address ;
120 ptr = std::make_unique<ServerPeer>( esu , std::move(peer_info) , m_store , m_secrets ,
121 m_config.sasl_server_config , newProtocolText(peer_address) , m_config.protocol_config ) ;
122 }
123 }
124 catch( std::exception & e ) // newPeer()
125 {
126 G_WARNING( "GPop::Server: new connection error: " << e.what() ) ;
127 }
128 return ptr ;
129}
130
131std::unique_ptr<GPop::ServerProtocol::Text> GPop::Server::newProtocolText( const GNet::Address & peer_address ) const
132{
133 return std::make_unique<ServerProtocolText>(peer_address) ; // up-cast
134}
An interface used by GAuth::SaslServer to obtain authentication secrets.
The GNet::Address class encapsulates a TCP/UDP transport address.
Definition: gaddress.h:63
The EventStateUnbound class is used as a device to force factory methods to plumb-in an ExceptionSour...
Definition: geventstate.h:231
A lightweight object containing an ExceptionHandler pointer, optional ExceptionSource pointer and opt...
Definition: geventstate.h:131
A move-only structure used in GNet::Server::newPeer() and containing the new socket.
Definition: gserver.h:142
Address peerAddress() const override
Returns the peer address.
Represents a connection from a POP client.
Definition: gpopserver.h:49
ServerPeer(GNet::EventStateUnbound, 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
void init()
Starts the protocol.
void report(const std::string &group={}) const
Generates helpful diagnostics after construction.
Definition: gpopserver.cpp:100
~Server() override
Destructor.
Definition: gpopserver.cpp:95
Server(GNet::EventState, Store &store, const GAuth::SaslServerSecrets &, const Config &)
Constructor. The 'secrets' reference is kept.
Definition: gpopserver.cpp:87
A message store.
Definition: gpopstore.h:47
Network classes.
Definition: gdef.h:1243
bool enabled() noexcept
Returns true if pop code is built in.
STL namespace.
A structure used in GNet::MultiServer::newPeer().
Definition: gmultiserver.h:55
A configuration structure for GNet::ServerPeer.
Definition: gserverpeer.h:64
A structure containing configuration parameters for ServerProtocol.
A structure containing GPop::Server configuration parameters.
Definition: gpopserver.h:90