33 const char * login_challenge_1 =
"Username:" ;
34 const char * login_challenge_2 =
"Password:" ;
46 const std::string & challenge ,
bool cram ,
bool & error ) ;
47 static std::string
digest(
const std::string & secret ,
const std::string & challenge ) ;
48 static std::string
cramDigest(
const std::string & secret ,
const std::string & challenge ) ;
59 const std::string & challenge ,
bool cram ,
bool & error )
63 G_DEBUG(
"GAuth::SaslClientImp::clientResponse: challenge=\"" << challenge <<
"\"" ) ;
64 return cram ? cramDigest(secret,challenge) : digest(secret,challenge) ;
66 catch( std::exception & e )
68 std::string what = e.what() ;
69 G_DEBUG(
"GAuth::SaslClient: " << what ) ;
72 return std::string() ;
90 G_IGNORE_PARAMETER(std::string,server_name) ;
91 G_DEBUG(
"GAuth::SaslClient::ctor: server-name=\"" << server_name <<
"\", active=" <<
active() ) ;
101 return m_imp->m_secrets.valid() ;
105 bool & done ,
bool & error ,
bool & sensitive )
const
112 if( mechanism ==
"CRAM-MD5" || mechanism ==
"APOP" )
114 const bool cram = mechanism ==
"CRAM-MD5" ;
115 std::string
id = m_imp->m_secrets.id(mechanism) ;
116 std::string secret = m_imp->m_secrets.secret(mechanism) ;
117 error =
id.empty() || secret.empty() ;
123 else if( mechanism ==
"PLAIN" )
125 std::string sep( 1U ,
'\0' ) ;
126 std::string
id = m_imp->m_secrets.id(mechanism) ;
127 std::string secret = m_imp->m_secrets.secret(mechanism) ;
128 rsp = sep +
id + sep + secret ;
129 error =
id.empty() || secret.empty() ;
133 else if( mechanism ==
"LOGIN" )
135 if( challenge == login_challenge_1 )
137 rsp = m_imp->m_secrets.id(mechanism) ;
138 error = rsp.empty() ;
141 else if( challenge == login_challenge_2 )
143 rsp = m_imp->m_secrets.secret(mechanism) ;
144 error = rsp.empty() ;
160 G_WARNING(
"GAuth::SaslClient: invalid challenge" ) ;
169 G_DEBUG(
"GAuth::SaslClient::preferred: server's mechanisms: [" <<
G::Str::join(mechanism_list,
",") <<
"]" ) ;
174 return std::string() ;
176 const std::string login(
"LOGIN" ) ;
177 const std::string plain(
"PLAIN" ) ;
178 const std::string cram(
"CRAM-MD5" ) ;
181 std::set<std::string> them ;
182 for( G::Strings::const_iterator p = mechanism_list.begin() ; p != mechanism_list.end() ; ++p )
186 std::set<std::string> us ;
187 if( !m_imp->m_secrets.id(login).empty() ) us.insert(login) ;
188 if( !m_imp->m_secrets.id(plain).empty() ) us.insert(plain) ;
189 if( !m_imp->m_secrets.id(cram).empty() ) us.insert(cram) ;
192 std::set<std::string> both ;
193 std::set_intersection( them.begin() , them.end() , us.begin() , us.end() , std::inserter(both,both.end()) ) ;
197 if( m.empty() && both.find(cram) != both.end() ) m = cram ;
198 if( m.empty() && both.find(plain) != both.end() ) m = plain ;
199 if( m.empty() && both.find(login) != both.end() ) m = login ;
200 G_DEBUG(
"GAuth::SaslClient::preferred: we prefer \"" << m <<
"\"" ) ;
An overload discriminator for G::Md5::hmac()
std::string preferred(const G::Strings &mechanisms) const
Returns the name of the preferred mechanism taken from the given set.
static std::string digest(const std::string &secret, const std::string &challenge)
std::string response(const std::string &mechanism, const std::string &challenge, bool &done, bool &error, bool &sensitive) const
Returns a response to the given challenge.
std::list< std::string > Strings
A std::list of std::strings.
SaslClientImp(const SaslClient::Secrets &)
SaslClient(const Secrets &secrets, const std::string &server_name)
Constructor. The secrets reference is kept.
bool active() const
Returns true if the constructor's secrets object is valid.
static std::string hmac(const std::string &key, const std::string &input)
Computes a Hashed Message Authentication Code using MD5 as the hash function.
A private pimple-pattern implementation class used by GAuth::SaslClient.
An interface used by GAuth::SaslClient to obtain authentication secrets.
static std::string cramDigest(const std::string &secret, const std::string &challenge)
static std::string upper(const std::string &s)
Returns a copy of 's' in which all lowercase characters have been replaced by uppercase characters...
static std::string digest(const std::string &input)
Creates an MD5 digest.
const SaslClient::Secrets & m_secrets
static std::string clientResponse(const std::string &secret, const std::string &challenge, bool cram, bool &error)
static std::string join(const Strings &strings, const std::string &sep)
Concatenates a set of strings.
static std::string printable(const std::string &input)
Converts a binary string into a printable form, using a lowercase hexadecimal encoding.