gsaslserverpam.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2013 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 // gsaslserverpam.cpp
19 //
20 
21 #include "gdef.h"
22 #include "gnet.h"
23 #include "gauth.h"
24 #include "gpam.h"
25 #include "gsaslserverpam.h"
26 #include "gexception.h"
27 #include "gstr.h"
28 
29 namespace GAuth
30 {
31  class PamImp ;
32  class SaslServerPamImp ;
33 }
34 
40 class GAuth::PamImp : public G::Pam
41 {
42 public:
44  G_EXCEPTION_CLASS( NoPrompt , "no password prompt received from pam module" ) ;
45 
46  PamImp( const std::string & app , const std::string & id ) ;
47  virtual ~PamImp() ;
48  void fail() ;
49  void apply( const std::string & ) ;
50  std::string id() const ;
51 
52 protected:
53  virtual void converse( ItemArray & ) ;
54  virtual void delay( unsigned int usec ) ;
55 
56 private:
57  PamImp( const PamImp & ) ;
58  void operator=( const PamImp & ) ;
59 
60 private:
61  std::string m_app ;
62  std::string m_id ;
63  std::string m_pwd ;
64 } ;
65 
66 // ==
67 
73 {
74 public:
75  explicit SaslServerPamImp( bool valid ) ;
76  virtual ~SaslServerPamImp() ;
77  bool active() const ;
78  std::string apply( const std::string & pwd , bool & done ) ;
79  std::string id() const ;
80  bool authenticated() const ;
81 
82 private:
84  void operator=( const SaslServerPamImp & ) ;
85 
86 private:
87  bool m_active ;
88  PamImp * m_pam ;
89 } ;
90 
91 // ==
92 
93 GAuth::PamImp::PamImp( const std::string & app , const std::string & id ) :
94  G::Pam(app,id,true) ,
95  m_app(app) ,
96  m_id(id)
97 {
98  G_DEBUG( "GAuth::PamImp::ctor: [" << app << "] [" << id << "]" ) ;
99 }
100 
102 {
103 }
104 
105 std::string GAuth::PamImp::id() const
106 {
107  return m_id ;
108 }
109 
111 {
112  bool done = false ;
113  for( ItemArray::iterator p = items.begin() ; p != items.end() ; ++p )
114  {
115  if( (*p).in_type == "password" )
116  {
117  (*p).out = m_pwd ;
118  (*p).out_defined = true ;
119  done = true ;
120  }
121  }
122  if( !done )
123  {
124  throw NoPrompt() ;
125  }
126 }
127 
128 void GAuth::PamImp::apply( const std::string & pwd )
129 {
130  m_pwd = pwd ;
131  authenticate( true ) ; // base class -- calls converse() -- thows on error
132 }
133 
134 void GAuth::PamImp::delay( unsigned int )
135 {
136  // TODO - pam delay - probably not possible with non-blocking i/o
137 }
138 
139 // ==
140 
142  m_active(active) ,
143  m_pam(NULL)
144 {
145 }
146 
148 {
149  delete m_pam ;
150 }
151 
153 {
154  return m_active ;
155 }
156 
157 std::string GAuth::SaslServerPamImp::id() const
158 {
159  return m_pam ? m_pam->id() : std::string() ;
160 }
161 
162 std::string GAuth::SaslServerPamImp::apply( const std::string & response , bool & done )
163 {
164  // parse the PLAIN response
165  std::string sep( 1U , '\0' ) ;
166  std::string s = G::Str::tail( response , response.find(sep) , std::string() ) ;
167  std::string id = G::Str::head( s , s.find(sep) , std::string() ) ;
168  std::string pwd = G::Str::tail( s , s.find(sep) , std::string() ) ;
169 
170  delete m_pam ;
171  m_pam = NULL ;
172  m_pam = new PamImp( "emailrelay" , id ) ;
173 
174  try
175  {
176  m_pam->apply( pwd ) ;
177  }
178  catch( G::Pam::Error & e )
179  {
180  G_WARNING( "GAuth::SaslServer::apply: " << e.what() ) ;
181  delete m_pam ;
182  m_pam = NULL ;
183  }
184  catch( PamImp::NoPrompt & e )
185  {
186  G_WARNING( "GAuth::SaslServer::apply: pam error: " << e.what() ) ;
187  delete m_pam ;
188  m_pam = NULL ;
189  }
190 
191  done = true ; // (only single challenge-response supported)
192  return std::string() ; // challenge
193 }
194 
195 // ==
196 
197 GAuth::SaslServerPam::SaslServerPam( const Secrets & secrets , bool , bool ) :
198  m_imp(new SaslServerPamImp(secrets.valid()))
199 {
200 }
201 
203 {
204  delete m_imp ;
205 }
206 
207 std::string GAuth::SaslServerPam::mechanisms( char ) const
208 {
209  return "PLAIN" ;
210 }
211 
213 {
214  return "PLAIN" ;
215 }
216 
218 {
219  return false ;
220 }
221 
223 {
224  return m_imp->active() ;
225 }
226 
228 {
229  return false ;
230 }
231 
232 bool GAuth::SaslServerPam::init( const std::string & mechanism )
233 {
234  return mechanism == "PLAIN" ;
235 }
236 
238 {
239  return std::string() ;
240 }
241 
242 std::string GAuth::SaslServerPam::apply( const std::string & response , bool & done )
243 {
244  return m_imp->apply( response , done ) ;
245 }
246 
248 {
249  return !m_imp->id().empty() ;
250 }
251 
252 std::string GAuth::SaslServerPam::id() const
253 {
254  return m_imp->id() ;
255 }
256 
258 {
259  return true ;
260 }
261 
virtual bool trusted(GNet::Address) const
Final override from GAuth::SaslServer.
virtual void delay(unsigned int usec)
Called when the pam library wants the application to introduce a delay to prevent brute-force attacks...
The Address class encapsulates an IP transport address.
Definition: gaddress.h:48
GAuth::PamImp::ItemArray ItemArray
static std::string tail(const std::string &in, std::string::size_type pos, const std::string &default_=std::string())
Returns the last part of the string after the given position.
Definition: gstr.cpp:842
PamImp(const std::string &app, const std::string &id)
std::vector< Item > ItemArray
Definition: gpam.h:69
virtual std::string initialChallenge() const
Final override from GAuth::SaslServer.
virtual ~SaslServerPam()
Destructor.
An exception class used by G::Pam.
Definition: gpam.h:72
virtual std::string mechanisms(char sep= ' ') const
Final override from GAuth::SaslServer.
virtual bool requiresEncryption() const
Final override from GAuth::SaslServer.
Low-level classes.
static std::string head(const std::string &in, std::string::size_type pos, const std::string &default_=std::string())
Returns the first part of the string up to just before the given position.
Definition: gstr.cpp:834
virtual std::string id() const
Final override from GAuth::SaslServer.
virtual std::string apply(const std::string &response, bool &done)
Final override from GAuth::SaslServer.
std::string id() const
A private implementation class used by GAuth::SaslServerPam.
std::string id() const
#define G_DEBUG(expr)
Definition: glog.h:95
virtual bool authenticated() const
Final override from GAuth::SaslServer.
virtual void converse(ItemArray &)
Called to pass a message to the user, or request a password etc.
bool authenticated() const
SaslServerPam(const Secrets &, bool ignored, bool force_one_mechanism)
Constructor.
A private implementation of the G::Pam interface used by GAuth::SaslServerPamImp, which is itself a p...
virtual std::string mechanism() const
Final override from GAuth::SaslServer.
void apply(const std::string &)
virtual const char * what() const
Override from std::exception.
Definition: gexception.cpp:62
virtual bool active() const
Final override from GAuth::SaslServer.
An interface used by GAuth::SaslServer to obtain authentication secrets.
Definition: gsaslserver.h:81
SASL authentication classes.
virtual bool mustChallenge() const
Final override from GAuth::SaslServer.
virtual bool init(const std::string &mechanism)
Final override from GAuth::SaslServer.
std::string apply(const std::string &pwd, bool &done)
#define G_WARNING(expr)
Definition: glog.h:107
#define G_EXCEPTION_CLASS(class_name, description)
Definition: gexception.h:87
A thin abstract interface to the system PAM library.
Definition: gpam.h:58