E-MailRelay
gsaslserver.h
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 gsaslserver.h
19///
20
21#ifndef G_SASL_SERVER_H
22#define G_SASL_SERVER_H
23
24#include "gdef.h"
25#include "gexception.h"
26#include "gaddress.h"
27#include "gstringarray.h"
28#include "gpath.h"
29#include <memory>
30#include <utility>
31
32namespace GAuth
33{
34 class SaslServer ;
35 class SaslServerImp ;
36}
37
38//| \class GAuth::SaslServer
39/// An interface for implementing the server-side SASL challenge/response
40/// concept. In practice there is one derived class for basic authentication
41/// mechanisms using a secrets file, and another for PAM.
42///
43/// Usage:
44/// \code
45/// SaslServer sasl( secrets ) ;
46/// if( !sasl.mechanisms(peer.secure()).empty() )
47/// {
48/// peer.advertise( sasl.mechanisms(peer.secure()) ) ;
49/// if( sasl.init(peer.secure(),peer.preferred()) )
50/// {
51/// if( peer.haveInitialResponse() && sasl.mustChallenge() )
52/// throw ProtocolError() ;
53/// bool done = false ;
54/// string challenge = peer.haveInitialResponse() ?
55/// sasl.apply(peer.initialResponse(),done) : sasl.initialChallenge() ;
56/// while( !done )
57/// {
58/// peer.send( challenge ) ;
59/// string response = peer.receive() ;
60/// challenge = sasl.apply( response , done ) ;
61/// }
62/// bool ok = sasl.authenticated() ;
63/// }
64/// }
65/// \endcode
66///
67/// \see GAuth::SaslClient, RFC-2554, RFC-4422
68///
69/// Available mechanisms depend on the encryption state ('secure'). In practice
70/// there can often be no mechanisms when in the insecure state. If there are no
71/// mechanisms then the protocol might advertise a mechanism that always fails
72/// to authenticate, returning a 'secure connection required' error to the
73/// client -- but that behaviour is out of scope at this interface.
74///
76{
77public:
78 virtual ~SaslServer() = default ;
79 ///< Destructor.
80
81 virtual G::StringArray mechanisms( bool secure ) const = 0 ;
82 ///< Returns a list of supported, standard mechanisms that
83 ///< can be advertised to the client. The parameter
84 ///< indicates whether the transport connection is currently
85 ///< encrypted.
86 ///<
87 ///< Returns the empty set if authentication is not possible
88 ///< for the given encryption state.
89
90 virtual void reset() = 0 ;
91 ///< Clears the internal state as if just constructed.
92 ///< Postcondition: mechanism().empty() && id().empty() && !authenticated() && !trusted()
93
94 virtual bool init( bool secure , const std::string & mechanism ) = 0 ;
95 ///< Initialiser for the given mechanism. Returns true iff
96 ///< the requested mechanism is in the mechanisms() list.
97 ///< May be used more than once. The initialChallenge() is
98 ///< re-initialised on each successful init().
99
100 virtual std::string mechanism() const = 0 ;
101 ///< Returns the current mechanism, as selected by the last
102 ///< successful init().
103
104 virtual std::string preferredMechanism( bool secure ) const = 0 ;
105 ///< Returns a preferred mechanism if authentication with the
106 ///< current mechanism has failed. Returns the empty string if
107 ///< there is no preference. This allows the negotiation of the
108 ///< mechanism to be user-specific, perhaps by having the
109 ///< first mechanism a probe mechanism that fails for all users.
110
111 virtual bool mustChallenge() const = 0 ;
112 ///< Returns true if authentication using the current mechanism
113 ///< must always start with a non-empty server challenge, ie.
114 ///< it is a "server-first" mechanism as per RFC-4422.
115 ///<
116 ///< Returns false for the "LOGIN" mechanism since the initial
117 ///< challenge ("Username:") is not essential, ie. it is a
118 ///< RFC-4422 "variable" mechanism.
119 ///<
120 ///< The server should call initialChallenge() to decide whether
121 ///< to send an initial challenge; this method is only to
122 ///< stop a client providing an initial response before an
123 ///< initial challenge has been sent.
124
125 virtual std::string initialChallenge() const = 0 ;
126 ///< Returns the possibly-empty initial server challenge.
127
128 virtual std::string apply( const std::string & response , bool & done ) = 0 ;
129 ///< Applies the client response and returns the next
130 ///< challenge and a 'done' flag by reference.
131 ///<
132 ///< Note that some mechanisms generate an extra round-trip
133 ///< even after the authentication status has been settled.
134 ///< In this case the 'done' flag will be set true only
135 ///< when the final empty response from the client is
136 ///< apply()d.
137
138 virtual bool authenticated() const = 0 ;
139 ///< Returns true if authenticated sucessfully.
140 ///< Precondition: apply() 'done'
141
142 virtual std::string id() const = 0 ;
143 ///< Returns the authenticated or trusted identity. Returns the
144 ///< empty string if not authenticated and not trusted.
145
146 virtual bool trusted( const G::StringArray & address_wildcards ,
147 const std::string & address_display ) const = 0 ;
148 ///< Returns true if a trusted client that does not need
149 ///< to authenticate. Pass Address::wildcards() and
150 ///< Address::hostPartString().
151} ;
152
153#endif
An interface for implementing the server-side SASL challenge/response concept.
Definition: gsaslserver.h:76
virtual std::string apply(const std::string &response, bool &done)=0
Applies the client response and returns the next challenge and a 'done' flag by reference.
virtual bool init(bool secure, const std::string &mechanism)=0
Initialiser for the given mechanism.
virtual bool mustChallenge() const =0
Returns true if authentication using the current mechanism must always start with a non-empty server ...
virtual bool trusted(const G::StringArray &address_wildcards, const std::string &address_display) const =0
Returns true if a trusted client that does not need to authenticate.
virtual std::string id() const =0
Returns the authenticated or trusted identity.
virtual std::string preferredMechanism(bool secure) const =0
Returns a preferred mechanism if authentication with the current mechanism has failed.
virtual G::StringArray mechanisms(bool secure) const =0
Returns a list of supported, standard mechanisms that can be advertised to the client.
virtual std::string mechanism() const =0
Returns the current mechanism, as selected by the last successful init().
virtual ~SaslServer()=default
Destructor.
virtual bool authenticated() const =0
Returns true if authenticated sucessfully.
virtual std::string initialChallenge() const =0
Returns the possibly-empty initial server challenge.
virtual void reset()=0
Clears the internal state as if just constructed.
SASL authentication classes.
Definition: gcram.cpp:38
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstringarray.h:30