XOAUTH2 authentication mechanism (for GMail).
This commit is contained in:
parent
3dd5975422
commit
7e36a74645
@ -50,6 +50,9 @@ const serviceInfos::property serviceInfos::property::AUTH_USERNAME
|
||||
const serviceInfos::property serviceInfos::property::AUTH_PASSWORD
|
||||
("auth.password", serviceInfos::property::TYPE_STRING);
|
||||
|
||||
const serviceInfos::property serviceInfos::property::AUTH_ACCESS_TOKEN
|
||||
("auth.accesstoken", serviceInfos::property::TYPE_STRING);
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
const serviceInfos::property serviceInfos::property::CONNECTION_TLS
|
||||
|
@ -90,6 +90,10 @@ public:
|
||||
* password used to authenticate with the server. */
|
||||
static const property AUTH_PASSWORD;
|
||||
|
||||
/** The common property 'auth.accesstoken' which is the
|
||||
* access token used to authenticate with the server. */
|
||||
static const property AUTH_ACCESS_TOKEN;
|
||||
|
||||
#if VMIME_HAVE_TLS_SUPPORT
|
||||
|
||||
/** The common property 'connection.tls': this is used to
|
||||
|
@ -81,6 +81,15 @@ public:
|
||||
*/
|
||||
virtual const string getPassword() const = 0;
|
||||
|
||||
/** Return the optional access token for authentication. This is
|
||||
* used for example with XOAuth2 SASL authentication.
|
||||
*
|
||||
* @return access token
|
||||
* @throw exceptions::no_auth_information if the information
|
||||
* could not be provided
|
||||
*/
|
||||
virtual const string getAccessToken() const = 0;
|
||||
|
||||
/** Return the local host name of the machine.
|
||||
*
|
||||
* @return hostname
|
||||
|
@ -76,6 +76,20 @@ const string defaultAuthenticator::getPassword() const
|
||||
}
|
||||
|
||||
|
||||
const string defaultAuthenticator::getAccessToken() const
|
||||
{
|
||||
shared_ptr <const net::service> service = m_service.lock();
|
||||
|
||||
const string prefix = service->getInfos().getPropertyPrefix();
|
||||
const propertySet& props = service->getSession()->getProperties();
|
||||
|
||||
if (props.hasProperty(prefix + net::serviceInfos::property::AUTH_ACCESS_TOKEN.getName()))
|
||||
return props[prefix + net::serviceInfos::property::AUTH_ACCESS_TOKEN.getName()];
|
||||
|
||||
throw exceptions::no_auth_information();
|
||||
}
|
||||
|
||||
|
||||
const string defaultAuthenticator::getHostname() const
|
||||
{
|
||||
return platform::getHandler()->getHostName();
|
||||
|
@ -53,6 +53,7 @@ public:
|
||||
const string getHostname() const;
|
||||
const string getAnonymousToken() const;
|
||||
const string getServiceName() const;
|
||||
const string getAccessToken() const;
|
||||
|
||||
void setService(shared_ptr <net::service> serv);
|
||||
weak_ptr <net::service> getService() const;
|
||||
|
98
src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp
Normal file
98
src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
|
||||
#include "vmime/security/sasl/XOAuth2SASLAuthenticator.hpp"
|
||||
|
||||
#include "vmime/security/sasl/SASLMechanism.hpp"
|
||||
#include "vmime/security/sasl/SASLSession.hpp"
|
||||
#include "vmime/security/sasl/SASLContext.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace security {
|
||||
namespace sasl {
|
||||
|
||||
|
||||
XOAuth2SASLAuthenticator::XOAuth2SASLAuthenticator(const Mode mode)
|
||||
: m_mode(mode)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
XOAuth2SASLAuthenticator::~XOAuth2SASLAuthenticator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const std::vector <shared_ptr <SASLMechanism> >
|
||||
XOAuth2SASLAuthenticator::getAcceptableMechanisms
|
||||
(const std::vector <shared_ptr <SASLMechanism> >& available,
|
||||
shared_ptr <SASLMechanism> suggested) const
|
||||
{
|
||||
if (m_mode == MODE_EXCLUSIVE)
|
||||
{
|
||||
std::vector <shared_ptr <SASLMechanism> > mechs;
|
||||
|
||||
for (size_t i = available.size() ; i != 0 ; --i)
|
||||
{
|
||||
shared_ptr <SASLMechanism> mech = available[i - 1];
|
||||
|
||||
if ("XOAUTH2" == mech->getName())
|
||||
{
|
||||
// Only allow XOAuth2
|
||||
mechs.push_back(mech);
|
||||
}
|
||||
}
|
||||
|
||||
return mechs;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = available.size() ; i != 0 ; --i)
|
||||
{
|
||||
shared_ptr <SASLMechanism> mech = available[i - 1];
|
||||
|
||||
if ("XOAUTH2" == mech->getName())
|
||||
{
|
||||
// Suggest using XOAuth2
|
||||
suggested = mech;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultSASLAuthenticator::getAcceptableMechanisms(available, suggested);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // sasl
|
||||
} // security
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
|
78
src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp
Normal file
78
src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_SECURITY_SASL_XOAUTH2SASLAUTHENTICATOR_HPP_INCLUDED
|
||||
#define VMIME_SECURITY_SASL_XOAUTH2SASLAUTHENTICATOR_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
|
||||
#include "vmime/security/sasl/defaultSASLAuthenticator.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace security {
|
||||
namespace sasl {
|
||||
|
||||
|
||||
/** An authenticator that is capable of providing information
|
||||
* for XOAuth2 authentication mechanisms (username and access token).
|
||||
* This authenticator force using the XOAUTH2 mechanism.
|
||||
*/
|
||||
class VMIME_EXPORT XOAuth2SASLAuthenticator : public defaultSASLAuthenticator
|
||||
{
|
||||
public:
|
||||
|
||||
enum Mode
|
||||
{
|
||||
MODE_SUGGEST, /**< Try XOAUTH2 before other mechanisms. */
|
||||
MODE_EXCLUSIVE /**< Use XOAUTH2 and nothing else. */
|
||||
};
|
||||
|
||||
|
||||
XOAuth2SASLAuthenticator(const Mode mode);
|
||||
~XOAuth2SASLAuthenticator();
|
||||
|
||||
const std::vector <shared_ptr <SASLMechanism> > getAcceptableMechanisms
|
||||
(const std::vector <shared_ptr <SASLMechanism> >& available,
|
||||
shared_ptr <SASLMechanism> suggested) const;
|
||||
|
||||
private:
|
||||
|
||||
Mode m_mode;
|
||||
};
|
||||
|
||||
|
||||
} // sasl
|
||||
} // security
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
#endif // VMIME_SECURITY_SASL_XOAUTH2SASLAUTHENTICATOR_HPP_INCLUDED
|
||||
|
142
src/vmime/security/sasl/XOAuth2SASLMechanism.cpp
Normal file
142
src/vmime/security/sasl/XOAuth2SASLMechanism.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
|
||||
#include "vmime/security/sasl/XOAuth2SASLMechanism.hpp"
|
||||
|
||||
#include "vmime/security/sasl/SASLContext.hpp"
|
||||
#include "vmime/security/sasl/SASLSession.hpp"
|
||||
|
||||
#include "vmime/exception.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace security {
|
||||
namespace sasl {
|
||||
|
||||
|
||||
XOAuth2SASLMechanism::XOAuth2SASLMechanism(shared_ptr <SASLContext> ctx, const string& /* name */)
|
||||
: m_context(ctx), m_complete(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
XOAuth2SASLMechanism::~XOAuth2SASLMechanism()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const string XOAuth2SASLMechanism::getName() const
|
||||
{
|
||||
return "XOAUTH2";
|
||||
}
|
||||
|
||||
|
||||
bool XOAuth2SASLMechanism::step
|
||||
(shared_ptr <SASLSession> sess,
|
||||
const byte_t* /* challenge */, const size_t /* challengeLen */,
|
||||
byte_t** response, size_t* responseLen)
|
||||
{
|
||||
// Build initial response
|
||||
//
|
||||
// The SASL XOAUTH2 initial client response has the following format:
|
||||
// base64("user=" {User} "^Aauth=Bearer " {Access Token} "^A^A")
|
||||
|
||||
const std::string user(sess->getAuthenticator()->getUsername());
|
||||
const std::string accessToken(sess->getAuthenticator()->getAccessToken());
|
||||
|
||||
std::ostringstream initRespBytes;
|
||||
initRespBytes.write("user=", 5);
|
||||
initRespBytes.write(user.c_str(), user.length());
|
||||
initRespBytes.write("\x01", 1);
|
||||
initRespBytes.write("auth=Bearer ", 12);
|
||||
initRespBytes.write(accessToken.c_str(), accessToken.length());
|
||||
initRespBytes.write("\x01\x01", 2);
|
||||
|
||||
const std::string initResp = initRespBytes.str();
|
||||
|
||||
// Set initial response
|
||||
byte_t* res = new byte_t[initResp.length()];
|
||||
std::copy(initResp.c_str(), initResp.c_str() + initResp.length(), res);
|
||||
|
||||
*response = res;
|
||||
*responseLen = initResp.length();
|
||||
m_complete = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool XOAuth2SASLMechanism::isComplete() const
|
||||
{
|
||||
return m_complete;
|
||||
}
|
||||
|
||||
|
||||
bool XOAuth2SASLMechanism::hasInitialResponse() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void XOAuth2SASLMechanism::encode
|
||||
(shared_ptr <SASLSession> /* sess */,
|
||||
const byte_t* input, const size_t inputLen,
|
||||
byte_t** output, size_t* outputLen)
|
||||
{
|
||||
// No encoding performed, just copy input bytes
|
||||
byte_t* res = new byte_t[inputLen];
|
||||
std::copy(input, input + inputLen, res);
|
||||
|
||||
*outputLen = inputLen;
|
||||
*output = res;
|
||||
}
|
||||
|
||||
|
||||
void XOAuth2SASLMechanism::decode
|
||||
(shared_ptr <SASLSession> /* sess */,
|
||||
const byte_t* input, const size_t inputLen,
|
||||
byte_t** output, size_t* outputLen)
|
||||
{
|
||||
// No decoding performed, just copy input bytes
|
||||
byte_t* res = new byte_t[inputLen];
|
||||
std::copy(input, input + inputLen, res);
|
||||
|
||||
*outputLen = inputLen;
|
||||
*output = res;
|
||||
}
|
||||
|
||||
|
||||
} // sasl
|
||||
} // security
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
|
91
src/vmime/security/sasl/XOAuth2SASLMechanism.hpp
Normal file
91
src/vmime/security/sasl/XOAuth2SASLMechanism.hpp
Normal file
@ -0,0 +1,91 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_SECURITY_SASL_XOAUTH2SASLMECHANISM_HPP_INCLUDED
|
||||
#define VMIME_SECURITY_SASL_XOAUTH2SASLMECHANISM_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
|
||||
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
|
||||
#include "vmime/security/sasl/SASLMechanism.hpp"
|
||||
|
||||
|
||||
namespace vmime {
|
||||
namespace security {
|
||||
namespace sasl {
|
||||
|
||||
|
||||
class SASLContext;
|
||||
|
||||
|
||||
/** SASL XOAUTH2 mechanism, used by GMail.
|
||||
*/
|
||||
class VMIME_EXPORT XOAuth2SASLMechanism : public SASLMechanism
|
||||
{
|
||||
public:
|
||||
|
||||
XOAuth2SASLMechanism(shared_ptr <SASLContext> ctx, const string& name);
|
||||
~XOAuth2SASLMechanism();
|
||||
|
||||
|
||||
const string getName() const;
|
||||
|
||||
bool step(shared_ptr <SASLSession> sess,
|
||||
const byte_t* challenge, const size_t challengeLen,
|
||||
byte_t** response, size_t* responseLen);
|
||||
|
||||
bool isComplete() const;
|
||||
|
||||
bool hasInitialResponse() const;
|
||||
|
||||
void encode(shared_ptr <SASLSession> sess,
|
||||
const byte_t* input, const size_t inputLen,
|
||||
byte_t** output, size_t* outputLen);
|
||||
|
||||
void decode(shared_ptr <SASLSession> sess,
|
||||
const byte_t* input, const size_t inputLen,
|
||||
byte_t** output, size_t* outputLen);
|
||||
|
||||
private:
|
||||
|
||||
/** SASL context */
|
||||
shared_ptr <SASLContext> m_context;
|
||||
|
||||
/** Authentication process status. */
|
||||
bool m_complete;
|
||||
};
|
||||
|
||||
|
||||
} // sasl
|
||||
} // security
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
|
||||
|
||||
#endif // VMIME_SECURITY_SASL_XOAUTH2SASLMECHANISM_HPP_INCLUDED
|
||||
|
@ -89,6 +89,12 @@ const string defaultSASLAuthenticator::getPassword() const
|
||||
}
|
||||
|
||||
|
||||
const string defaultSASLAuthenticator::getAccessToken() const
|
||||
{
|
||||
return m_default.getAccessToken();
|
||||
}
|
||||
|
||||
|
||||
const string defaultSASLAuthenticator::getHostname() const
|
||||
{
|
||||
return m_default.getHostname();
|
||||
|
@ -59,6 +59,7 @@ public:
|
||||
const string getHostname() const;
|
||||
const string getAnonymousToken() const;
|
||||
const string getServiceName() const;
|
||||
const string getAccessToken() const;
|
||||
|
||||
void setService(shared_ptr <net::service> serv);
|
||||
weak_ptr <net::service> getService() const;
|
||||
|
Loading…
Reference in New Issue
Block a user