aboutsummaryrefslogtreecommitdiff
path: root/vmime-master/src/vmime/security/sasl
diff options
context:
space:
mode:
authorWojtek Kosior <wk@koszkonutek-tmp.pl.eu.org>2021-04-30 00:33:56 +0200
committerWojtek Kosior <wk@koszkonutek-tmp.pl.eu.org>2021-04-30 00:33:56 +0200
commitaa4d426b4d3527d7e166df1a05058c9a4a0f6683 (patch)
tree4ff17ce8b89a2321b9d0ed4bcfc37c447bcb6820 /vmime-master/src/vmime/security/sasl
downloadsmtps-and-pop3s-console-program-aa4d426b4d3527d7e166df1a05058c9a4a0f6683.tar.gz
smtps-and-pop3s-console-program-aa4d426b4d3527d7e166df1a05058c9a4a0f6683.zip
initial/final commitHEADmaster
Diffstat (limited to 'vmime-master/src/vmime/security/sasl')
-rw-r--r--vmime-master/src/vmime/security/sasl/SASLAuthenticator.hpp96
-rw-r--r--vmime-master/src/vmime/security/sasl/SASLContext.cpp221
-rw-r--r--vmime-master/src/vmime/security/sasl/SASLContext.hpp136
-rw-r--r--vmime-master/src/vmime/security/sasl/SASLMechanism.hpp153
-rw-r--r--vmime-master/src/vmime/security/sasl/SASLMechanismFactory.cpp149
-rw-r--r--vmime-master/src/vmime/security/sasl/SASLMechanismFactory.hpp155
-rw-r--r--vmime-master/src/vmime/security/sasl/SASLSession.cpp221
-rw-r--r--vmime-master/src/vmime/security/sasl/SASLSession.hpp180
-rw-r--r--vmime-master/src/vmime/security/sasl/SASLSocket.cpp273
-rw-r--r--vmime-master/src/vmime/security/sasl/SASLSocket.hpp108
-rw-r--r--vmime-master/src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp99
-rw-r--r--vmime-master/src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp77
-rw-r--r--vmime-master/src/vmime/security/sasl/XOAuth2SASLMechanism.cpp155
-rw-r--r--vmime-master/src/vmime/security/sasl/XOAuth2SASLMechanism.hpp102
-rw-r--r--vmime-master/src/vmime/security/sasl/builtinSASLMechanism.cpp221
-rw-r--r--vmime-master/src/vmime/security/sasl/builtinSASLMechanism.hpp105
-rw-r--r--vmime-master/src/vmime/security/sasl/defaultSASLAuthenticator.cpp159
-rw-r--r--vmime-master/src/vmime/security/sasl/defaultSASLAuthenticator.hpp91
18 files changed, 2701 insertions, 0 deletions
diff --git a/vmime-master/src/vmime/security/sasl/SASLAuthenticator.hpp b/vmime-master/src/vmime/security/sasl/SASLAuthenticator.hpp
new file mode 100644
index 0000000..a75bfa0
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/SASLAuthenticator.hpp
@@ -0,0 +1,96 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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_SASLAUTHENTICATOR_HPP_INCLUDED
+#define VMIME_SECURITY_SASL_SASLAUTHENTICATOR_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
+
+
+#include "vmime/types.hpp"
+
+#include "vmime/security/authenticator.hpp"
+
+
+namespace vmime {
+namespace security {
+namespace sasl {
+
+
+class SASLMechanism;
+class SASLSession;
+
+
+/** SASL-aware authenticator.
+ *
+ * Usually, you should not inherit from this class, but instead from the
+ * more convenient defaultSASLAuthenticator class.
+ */
+class VMIME_EXPORT SASLAuthenticator : public authenticator {
+
+public:
+
+ /** This method is called to allow the client to choose the
+ * authentication mechanisms that will be used. By default,
+ * the most secure mechanisms are chosen.
+ *
+ * @param available available mechanisms
+ * @param suggested suggested mechanism (or NULL if the system
+ * could not suggest a mechanism)
+ * @return ordered list of mechanism to use among the available
+ * mechanisms (from the first to try to the last)
+ */
+ virtual const std::vector <shared_ptr <SASLMechanism> > getAcceptableMechanisms(
+ const std::vector <shared_ptr <SASLMechanism> >& available,
+ const shared_ptr <SASLMechanism>& suggested
+ ) const = 0;
+
+ /** Set the SASL session which is using this authenticator.
+ *
+ * @param sess SASL session
+ */
+ virtual void setSASLSession(const shared_ptr <SASLSession>& sess) = 0;
+
+ /** Set the SASL mechanism which has been selected for the
+ * SASL authentication process. This may be called several times
+ * if the multiple mechanisms are tried by the service which
+ * use this authentication.
+ *
+ * @param mech SASL mechanism
+ */
+ virtual void setSASLMechanism(const shared_ptr <SASLMechanism>& mech) = 0;
+};
+
+
+} // sasl
+} // security
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
+
+#endif // VMIME_SECURITY_SASL_SASLAUTHENTICATOR_HPP_INCLUDED
diff --git a/vmime-master/src/vmime/security/sasl/SASLContext.cpp b/vmime-master/src/vmime/security/sasl/SASLContext.cpp
new file mode 100644
index 0000000..2174541
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/SASLContext.cpp
@@ -0,0 +1,221 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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 <sstream>
+
+#include <gsasl.h>
+
+#include "vmime/security/sasl/SASLContext.hpp"
+#include "vmime/security/sasl/SASLMechanism.hpp"
+
+#include "vmime/base.hpp"
+
+#include "vmime/utility/encoder/encoderFactory.hpp"
+
+#include "vmime/utility/stream.hpp"
+#include "vmime/utility/outputStreamStringAdapter.hpp"
+#include "vmime/utility/inputStreamStringAdapter.hpp"
+#include "vmime/utility/inputStreamByteBufferAdapter.hpp"
+
+
+namespace vmime {
+namespace security {
+namespace sasl {
+
+
+SASLContext::SASLContext() {
+
+ if (gsasl_init(&m_gsaslContext) != GSASL_OK) {
+ throw std::bad_alloc();
+ }
+}
+
+
+SASLContext::~SASLContext() {
+
+ gsasl_done(m_gsaslContext);
+}
+
+
+// static
+shared_ptr <SASLContext> SASLContext::create() {
+
+ return shared_ptr <SASLContext>(new SASLContext());
+}
+
+
+shared_ptr <SASLSession> SASLContext::createSession(
+ const string& serviceName,
+ const shared_ptr <authenticator>& auth,
+ const shared_ptr <SASLMechanism>& mech
+) {
+
+ return SASLSession::create
+ (serviceName, dynamicCast <SASLContext>(shared_from_this()), auth, mech);
+}
+
+
+shared_ptr <SASLMechanism> SASLContext::createMechanism(const string& name) {
+
+ return SASLMechanismFactory::getInstance()->create(
+ dynamicCast <SASLContext>(shared_from_this()), name
+ );
+}
+
+
+shared_ptr <SASLMechanism> SASLContext::suggestMechanism(
+ const std::vector <shared_ptr <SASLMechanism> >& mechs
+) {
+
+ if (mechs.empty()) {
+ return null;
+ }
+
+ std::ostringstream oss;
+
+ for (unsigned int i = 0 ; i < mechs.size() ; ++i) {
+ oss << mechs[i]->getName() << " ";
+ }
+
+ const string mechList = oss.str();
+ const char* suggested = gsasl_client_suggest_mechanism(m_gsaslContext, mechList.c_str());
+
+ if (suggested) {
+
+ for (unsigned int i = 0 ; i < mechs.size() ; ++i) {
+
+ if (mechs[i]->getName() == suggested) {
+ return mechs[i];
+ }
+ }
+ }
+
+ return null;
+}
+
+
+void SASLContext::decodeB64(const string& input, byte_t** output, size_t* outputLen) {
+
+ string res;
+
+ utility::inputStreamStringAdapter is(input);
+ utility::outputStreamStringAdapter os(res);
+
+ shared_ptr <utility::encoder::encoder> dec =
+ utility::encoder::encoderFactory::getInstance()->create("base64");
+
+ dec->decode(is, os);
+
+ byte_t* out = new byte_t[res.length()];
+
+ std::copy(res.begin(), res.end(), out);
+
+ *output = out;
+ *outputLen = res.length();
+}
+
+
+const string SASLContext::encodeB64(const byte_t* input, const size_t inputLen) {
+
+ string res;
+
+ utility::inputStreamByteBufferAdapter is(input, inputLen);
+ utility::outputStreamStringAdapter os(res);
+
+ shared_ptr <utility::encoder::encoder> enc =
+ utility::encoder::encoderFactory::getInstance()->create("base64");
+
+ enc->encode(is, os);
+
+ return res;
+}
+
+
+const string SASLContext::getErrorMessage(const string& fname, const int code) {
+
+ string msg = fname + "() returned ";
+
+#define ERROR(x) \
+ case x: msg += #x; break;
+
+ switch (code)
+ {
+ ERROR(GSASL_NEEDS_MORE)
+ ERROR(GSASL_UNKNOWN_MECHANISM)
+ ERROR(GSASL_MECHANISM_CALLED_TOO_MANY_TIMES)
+ ERROR(GSASL_MALLOC_ERROR)
+ ERROR(GSASL_BASE64_ERROR)
+ ERROR(GSASL_CRYPTO_ERROR)
+ ERROR(GSASL_SASLPREP_ERROR)
+ ERROR(GSASL_MECHANISM_PARSE_ERROR)
+ ERROR(GSASL_AUTHENTICATION_ERROR)
+ ERROR(GSASL_INTEGRITY_ERROR)
+ ERROR(GSASL_NO_CLIENT_CODE)
+ ERROR(GSASL_NO_SERVER_CODE)
+ ERROR(GSASL_NO_CALLBACK)
+ ERROR(GSASL_NO_ANONYMOUS_TOKEN)
+ ERROR(GSASL_NO_AUTHID)
+ ERROR(GSASL_NO_AUTHZID)
+ ERROR(GSASL_NO_PASSWORD)
+ ERROR(GSASL_NO_PASSCODE)
+ ERROR(GSASL_NO_PIN)
+ ERROR(GSASL_NO_SERVICE)
+ ERROR(GSASL_NO_HOSTNAME)
+ ERROR(GSASL_GSSAPI_RELEASE_BUFFER_ERROR)
+ ERROR(GSASL_GSSAPI_IMPORT_NAME_ERROR)
+ ERROR(GSASL_GSSAPI_INIT_SEC_CONTEXT_ERROR)
+ ERROR(GSASL_GSSAPI_ACCEPT_SEC_CONTEXT_ERROR)
+ ERROR(GSASL_GSSAPI_UNWRAP_ERROR)
+ ERROR(GSASL_GSSAPI_WRAP_ERROR)
+ ERROR(GSASL_GSSAPI_ACQUIRE_CRED_ERROR)
+ ERROR(GSASL_GSSAPI_DISPLAY_NAME_ERROR)
+ ERROR(GSASL_GSSAPI_UNSUPPORTED_PROTECTION_ERROR)
+ ERROR(GSASL_KERBEROS_V5_INIT_ERROR)
+ ERROR(GSASL_KERBEROS_V5_INTERNAL_ERROR)
+ ERROR(GSASL_SECURID_SERVER_NEED_ADDITIONAL_PASSCODE)
+ ERROR(GSASL_SECURID_SERVER_NEED_NEW_PIN)
+
+ default:
+
+ msg += "unknown error";
+ break;
+ }
+
+#undef ERROR
+
+ return msg;
+}
+
+
+} // sasl
+} // security
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
diff --git a/vmime-master/src/vmime/security/sasl/SASLContext.hpp b/vmime-master/src/vmime/security/sasl/SASLContext.hpp
new file mode 100644
index 0000000..93d80ff
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/SASLContext.hpp
@@ -0,0 +1,136 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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_SASLCONTEXT_HPP_INCLUDED
+#define VMIME_SECURITY_SASL_SASLCONTEXT_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
+
+
+#include "vmime/types.hpp"
+
+#include "vmime/security/sasl/SASLSession.hpp"
+#include "vmime/security/sasl/SASLMechanismFactory.hpp"
+
+
+namespace vmime {
+namespace security {
+namespace sasl {
+
+
+/** An SASL client context.
+ */
+class VMIME_EXPORT SASLContext : public object, public enable_shared_from_this <SASLContext> {
+
+ friend class SASLSession;
+ friend class builtinSASLMechanism;
+
+public:
+
+ ~SASLContext();
+
+ /** Construct and initialize a new SASL context.
+ *
+ * @return pointer to a new SASL context
+ */
+ static shared_ptr <SASLContext> create();
+
+ /** Create and initialize a new SASL session.
+ *
+ * @param serviceName name of the service which will use the session
+ * @param auth authenticator object to use during the session
+ * @param mech SASL mechanism
+ * @return a new SASL session
+ */
+ shared_ptr <SASLSession> createSession(
+ const string& serviceName,
+ const shared_ptr <authenticator>& auth,
+ const shared_ptr <SASLMechanism>& mech
+ );
+
+ /** Create an instance of an SASL mechanism.
+ *
+ * @param name mechanism name
+ * @return a new instance of the specified SASL mechanism
+ * @throw exceptions::no_such_mechanism if no mechanism is
+ * registered for the specified name
+ */
+ shared_ptr <SASLMechanism> createMechanism(const string& name);
+
+ /** Suggests an SASL mechanism among a set of mechanisms
+ * supported by the server.
+ *
+ * @param mechs list of mechanisms
+ * @return suggested mechanism (usually the safest mechanism
+ * supported by both the client and the server)
+ */
+ shared_ptr <SASLMechanism> suggestMechanism(
+ const std::vector <shared_ptr <SASLMechanism> >& mechs
+ );
+
+ /** Helper function for decoding Base64-encoded challenge.
+ *
+ * @param input input buffer
+ * @param output output buffer
+ * @param outputLen length of output buffer
+ */
+ void decodeB64(const string& input, byte_t** output, size_t* outputLen);
+
+ /** Helper function for encoding challenge in Base64.
+ *
+ * @param input input buffer
+ * @param inputLen length of input buffer
+ * @return Base64-encoded challenge
+ */
+ const string encodeB64(const byte_t* input, const size_t inputLen);
+
+private:
+
+ SASLContext();
+ SASLContext(SASLContext&);
+
+
+ static const string getErrorMessage(const string& fname, const int code);
+
+
+#ifdef GSASL_VERSION
+ Gsasl* m_gsaslContext;
+#else
+ void* m_gsaslContext;
+#endif // GSASL_VERSION
+
+};
+
+
+} // sasl
+} // security
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
+
+#endif // VMIME_SECURITY_SASL_SASLCONTEXT_HPP_INCLUDED
diff --git a/vmime-master/src/vmime/security/sasl/SASLMechanism.hpp b/vmime-master/src/vmime/security/sasl/SASLMechanism.hpp
new file mode 100644
index 0000000..a6e056d
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/SASLMechanism.hpp
@@ -0,0 +1,153 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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_SASLMECHANISM_HPP_INCLUDED
+#define VMIME_SECURITY_SASL_SASLMECHANISM_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
+
+
+#include "vmime/types.hpp"
+
+
+namespace vmime {
+namespace security {
+namespace sasl {
+
+
+class SASLSession;
+
+
+/** An SASL mechanism.
+ */
+class VMIME_EXPORT SASLMechanism : public object {
+
+public:
+
+ /** Return the name of this mechanism.
+ *
+ * @return mechanism name
+ */
+ virtual const string getName() const = 0;
+
+ /** Perform one step of SASL authentication. Accept data from the
+ * server (challenge), process it and return data to be returned
+ * in response to the server.
+ *
+ * If the challenge is empty (challengeLen == 0), the initial
+ * response is returned, if this mechanism has one.
+ *
+ * @param sess SASL session
+ * @param challenge challenge sent from the server
+ * @param challengeLen length of challenge
+ * @param response response to send to the server (allocated by
+ * this function, free with delete[])
+ * @param responseLen length of response buffer
+ * @return true if authentication terminated successfully, or
+ * false if the authentication process should continue
+ * @throw exceptions::sasl_exception if an error occurred during
+ * authentication (in this case, the values in 'response' and
+ * 'responseLen' are undetermined)
+ */
+ virtual bool step(
+ const shared_ptr <SASLSession>& sess,
+ const byte_t* challenge,
+ const size_t challengeLen,
+ byte_t** response,
+ size_t* responseLen
+ ) = 0;
+
+ /** Check whether authentication has completed. If false, more
+ * calls to evaluateChallenge() are needed to complete the
+ * authentication process).
+ *
+ * @return true if the authentication has finished, or false
+ * otherwise
+ */
+ virtual bool isComplete() const = 0;
+
+ /** Determine if this mechanism has an optional initial response.
+ * If true, caller should call step() with an empty challenge to
+ * get the initial response.
+ *
+ * @return true if this mechanism has an initial response, or
+ * false otherwise
+ */
+ virtual bool hasInitialResponse() const = 0;
+
+ /** Encode data according to negotiated SASL mechanism. This
+ * might mean that data is integrity or privacy protected.
+ *
+ * @param sess SASL session
+ * @param input input buffer
+ * @param inputLen length of input buffer
+ * @param output output buffer (allocated bu the function,
+ * free with delete[])
+ * @param outputLen length of output buffer
+ * @throw exceptions::sasl_exception if an error occurred during
+ * the encoding of data (in this case, the values in 'output' and
+ * 'outputLen' are undetermined)
+ */
+ virtual void encode(
+ const shared_ptr <SASLSession>& sess,
+ const byte_t* input,
+ const size_t inputLen,
+ byte_t** output,
+ size_t* outputLen
+ ) = 0;
+
+ /** Decode data according to negotiated SASL mechanism. This
+ * might mean that data is integrity or privacy protected.
+ *
+ * @param sess SASL session
+ * @param input input buffer
+ * @param inputLen length of input buffer
+ * @param output output buffer (allocated bu the function,
+ * free with delete[])
+ * @param outputLen length of output buffer
+ * @throw exceptions::sasl_exception if an error occurred during
+ * the encoding of data (in this case, the values in 'output' and
+ * 'outputLen' are undetermined)
+ */
+ virtual void decode(
+ const shared_ptr <SASLSession>& sess,
+ const byte_t* input,
+ const size_t inputLen,
+ byte_t** output,
+ size_t* outputLen
+ ) = 0;
+};
+
+
+} // sasl
+} // security
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
+
+#endif // VMIME_SECURITY_SASL_SASLMECHANISM_HPP_INCLUDED
diff --git a/vmime-master/src/vmime/security/sasl/SASLMechanismFactory.cpp b/vmime-master/src/vmime/security/sasl/SASLMechanismFactory.cpp
new file mode 100644
index 0000000..a2fbedb
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/SASLMechanismFactory.cpp
@@ -0,0 +1,149 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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 <stdexcept>
+#include <new>
+
+#include <gsasl.h>
+
+#include "vmime/security/sasl/SASLMechanismFactory.hpp"
+#include "vmime/security/sasl/builtinSASLMechanism.hpp"
+#include "vmime/security/sasl/SASLContext.hpp"
+
+#include "vmime/utility/stringUtils.hpp"
+
+#include "vmime/base.hpp"
+#include "vmime/exception.hpp"
+
+
+namespace vmime {
+namespace security {
+namespace sasl {
+
+
+SASLMechanismFactory::SASLMechanismFactory() {
+
+ if (gsasl_init(&m_gsaslContext) != GSASL_OK) {
+ throw std::bad_alloc();
+ }
+}
+
+
+SASLMechanismFactory::~SASLMechanismFactory() {
+
+ gsasl_done(m_gsaslContext);
+}
+
+
+// static
+SASLMechanismFactory* SASLMechanismFactory::getInstance() {
+
+ static SASLMechanismFactory instance;
+ return &instance;
+}
+
+
+shared_ptr <SASLMechanism> SASLMechanismFactory::create(
+ const shared_ptr <SASLContext>& ctx,
+ const string& name_
+) {
+
+ const string name(utility::stringUtils::toUpper(name_));
+
+ // Check for registered mechanisms
+ MapType::iterator it = m_mechs.find(name);
+
+ if (it != m_mechs.end()) {
+ return (*it).second->create(ctx, name);
+ }
+
+ // Check for built-in mechanisms
+ if (isBuiltinMechanism(name)) {
+ return make_shared <builtinSASLMechanism>(ctx, name);
+ }
+
+ throw exceptions::no_such_mechanism(name);
+ return null;
+}
+
+
+const std::vector <string> SASLMechanismFactory::getSupportedMechanisms() const {
+
+ std::vector <string> list;
+
+ // Registered mechanisms
+ for (MapType::const_iterator it = m_mechs.begin() ;
+ it != m_mechs.end() ; ++it) {
+
+ list.push_back((*it).first);
+ }
+
+ // Built-in mechanisms
+ char* out = 0;
+
+ if (gsasl_client_mechlist(m_gsaslContext, &out) == GSASL_OK) {
+
+ // 'out' contains SASL mechanism names, separated by spaces
+ for (char *start = out, *p = out ; ; ++p) {
+
+ if (*p == ' ' || !*p) {
+
+ list.push_back(string(start, p));
+ start = p + 1;
+
+ // End of string
+ if (!*p) break;
+ }
+ }
+
+ gsasl_free(out);
+ }
+
+ return list;
+}
+
+
+bool SASLMechanismFactory::isMechanismSupported(const string& name) const {
+
+ return isBuiltinMechanism(name) || m_mechs.find(name) != m_mechs.end();
+}
+
+
+bool SASLMechanismFactory::isBuiltinMechanism(const string& name) const {
+
+ return gsasl_client_support_p(m_gsaslContext, name.c_str()) != 0;
+}
+
+
+} // sasl
+} // security
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
diff --git a/vmime-master/src/vmime/security/sasl/SASLMechanismFactory.hpp b/vmime-master/src/vmime/security/sasl/SASLMechanismFactory.hpp
new file mode 100644
index 0000000..af76c96
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/SASLMechanismFactory.hpp
@@ -0,0 +1,155 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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_SASLMECHANISMFACTORY_HPP_INCLUDED
+#define VMIME_SECURITY_SASL_SASLMECHANISMFACTORY_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
+
+
+#include "vmime/types.hpp"
+#include "vmime/base.hpp"
+
+#include "vmime/security/sasl/SASLMechanism.hpp"
+
+#include <map>
+
+
+namespace vmime {
+namespace security {
+namespace sasl {
+
+
+class SASLContext;
+
+
+/** Constructs SASL mechanism objects.
+ */
+class VMIME_EXPORT SASLMechanismFactory : public object {
+
+private:
+
+ SASLMechanismFactory();
+ ~SASLMechanismFactory();
+
+
+ struct registeredMechanism : public object {
+
+ virtual shared_ptr <SASLMechanism> create(
+ const shared_ptr <SASLContext>& ctx, const string& name
+ ) = 0;
+ };
+
+ template <typename T>
+ struct registeredMechanismImpl : public registeredMechanism {
+
+ shared_ptr <SASLMechanism> create(
+ const shared_ptr <SASLContext>& ctx,
+ const string& name
+ ) {
+
+ return vmime::make_shared <T>(ctx, name);
+ }
+ };
+
+ typedef std::map <string, shared_ptr <registeredMechanism> > MapType;
+ MapType m_mechs;
+
+public:
+
+ static SASLMechanismFactory* getInstance();
+
+ /** Register a mechanism into this factory, so that subsequent
+ * calls to create return a valid object for this mechanism.
+ *
+ * @param name mechanism name
+ */
+ template <typename MECH_CLASS>
+ void registerMechanism(const string& name) {
+
+ m_mechs.insert(
+ MapType::value_type(
+ name,
+ vmime::make_shared <registeredMechanismImpl <MECH_CLASS> >()
+ )
+ );
+ }
+
+ /** Create a mechanism object given its name.
+ *
+ * @param ctx SASL context
+ * @param name mechanism name
+ * @return a new mechanism object
+ * @throw exceptions::no_such_mechanism if no mechanism is
+ * registered for the specified name
+ */
+ shared_ptr <SASLMechanism> create(const shared_ptr <SASLContext>& ctx, const string& name);
+
+ /** Return a list of supported mechanisms. This includes mechanisms
+ * registered using registerMechanism() as well as the ones that
+ * are built-in.
+ *
+ * @return list of supported mechanisms
+ */
+ const std::vector <string> getSupportedMechanisms() const;
+
+ /** Test whether an authentication mechanism is supported.
+ *
+ * @param name mechanism name
+ * @return true if the specified mechanism is supported,
+ * false otherwise
+ */
+ bool isMechanismSupported(const string& name) const;
+
+ /** Test whether an authentication mechanism is directly supported
+ * by the underlying SASL library.
+ *
+ * @param name mechanism name
+ * @return true if the specified mechanism is built-in,
+ * or false otherwise
+ */
+ bool isBuiltinMechanism(const string& name) const;
+
+private:
+
+#ifdef GSASL_VERSION
+ Gsasl* m_gsaslContext;
+#else
+ void* m_gsaslContext;
+#endif // GSASL_VERSION
+
+};
+
+
+} // sasl
+} // security
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
+
+#endif // VMIME_SECURITY_SASL_SASLMECHANISMFACTORY_HPP_INCLUDED
diff --git a/vmime-master/src/vmime/security/sasl/SASLSession.cpp b/vmime-master/src/vmime/security/sasl/SASLSession.cpp
new file mode 100644
index 0000000..7498b46
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/SASLSession.cpp
@@ -0,0 +1,221 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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 <sstream>
+
+#include <gsasl.h>
+
+#include "vmime/security/sasl/SASLSession.hpp"
+
+#include "vmime/security/sasl/SASLContext.hpp"
+#include "vmime/security/sasl/SASLSocket.hpp"
+#include "vmime/security/sasl/SASLAuthenticator.hpp"
+
+
+namespace vmime {
+namespace security {
+namespace sasl {
+
+
+SASLSession::SASLSession(
+ const string& serviceName,
+ const shared_ptr <SASLContext>& ctx,
+ const shared_ptr <authenticator>& auth,
+ const shared_ptr <SASLMechanism>& mech
+)
+ : m_serviceName(serviceName),
+ m_context(ctx),
+ m_auth(auth),
+ m_mech(mech),
+ m_gsaslContext(0),
+ m_gsaslSession(0) {
+
+ if (gsasl_init(&m_gsaslContext) != GSASL_OK) {
+ throw std::bad_alloc();
+ }
+
+ gsasl_client_start(m_gsaslContext, mech->getName().c_str(), &m_gsaslSession);
+
+ gsasl_callback_set(m_gsaslContext, gsaslCallback);
+ gsasl_callback_hook_set(m_gsaslContext, this);
+}
+
+
+SASLSession::~SASLSession() {
+
+ gsasl_finish(m_gsaslSession);
+ m_gsaslSession = NULL;
+
+ gsasl_done(m_gsaslContext);
+ m_gsaslContext = NULL;
+}
+
+
+// static
+shared_ptr <SASLSession> SASLSession::create(
+ const string& serviceName,
+ const shared_ptr <SASLContext>& ctx,
+ const shared_ptr <authenticator>& auth,
+ const shared_ptr <SASLMechanism>& mech
+) {
+
+ return shared_ptr <SASLSession>(new SASLSession(serviceName, ctx, auth, mech));
+}
+
+
+void SASLSession::init() {
+
+ shared_ptr <SASLAuthenticator> saslAuth = dynamicCast <SASLAuthenticator>(m_auth);
+
+ if (saslAuth) {
+ saslAuth->setSASLMechanism(m_mech);
+ saslAuth->setSASLSession(dynamicCast <SASLSession>(shared_from_this()));
+ }
+}
+
+
+shared_ptr <authenticator> SASLSession::getAuthenticator() {
+
+ return m_auth;
+}
+
+
+shared_ptr <SASLMechanism> SASLSession::getMechanism() {
+
+ return m_mech;
+}
+
+
+shared_ptr <SASLContext> SASLSession::getContext() {
+
+ return m_context;
+}
+
+
+bool SASLSession::evaluateChallenge(
+ const byte_t* challenge,
+ const size_t challengeLen,
+ byte_t** response,
+ size_t* responseLen
+) {
+
+ return m_mech->step(
+ dynamicCast <SASLSession>(shared_from_this()),
+ challenge, challengeLen, response, responseLen
+ );
+}
+
+
+shared_ptr <net::socket> SASLSession::getSecuredSocket(const shared_ptr <net::socket>& sok) {
+
+ return make_shared <SASLSocket>(dynamicCast <SASLSession>(shared_from_this()), sok);
+}
+
+
+const string SASLSession::getServiceName() const {
+
+ return m_serviceName;
+}
+
+
+// static
+int SASLSession::gsaslCallback(
+ Gsasl* ctx,
+ Gsasl_session* sctx,
+ Gsasl_property prop
+) {
+
+ SASLSession* sess = reinterpret_cast <SASLSession*>(gsasl_callback_hook_get(ctx));
+
+ if (!sess) {
+ return GSASL_AUTHENTICATION_ERROR;
+ }
+
+ shared_ptr <authenticator> auth = sess->getAuthenticator();
+
+ try {
+
+ string res;
+
+ switch (prop) {
+
+ case GSASL_AUTHID:
+
+ res = auth->getUsername();
+ break;
+
+ case GSASL_PASSWORD:
+
+ res = auth->getPassword();
+ break;
+
+ case GSASL_ANONYMOUS_TOKEN:
+
+ res = auth->getAnonymousToken();
+ break;
+
+ case GSASL_HOSTNAME:
+
+ res = auth->getHostname();
+ break;
+
+ case GSASL_SERVICE:
+
+ res = auth->getServiceName();
+ break;
+
+ case GSASL_AUTHZID:
+ case GSASL_GSSAPI_DISPLAY_NAME:
+ case GSASL_PASSCODE:
+ case GSASL_SUGGESTED_PIN:
+ case GSASL_PIN:
+ case GSASL_REALM:
+
+ default:
+
+ return GSASL_NO_CALLBACK;
+ }
+
+ gsasl_property_set(sctx, prop, res.c_str());
+
+ return GSASL_OK;
+
+ } catch (...) {
+
+ return GSASL_NO_CALLBACK;
+ }
+}
+
+
+} // sasl
+} // security
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
diff --git a/vmime-master/src/vmime/security/sasl/SASLSession.hpp b/vmime-master/src/vmime/security/sasl/SASLSession.hpp
new file mode 100644
index 0000000..7fc7225
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/SASLSession.hpp
@@ -0,0 +1,180 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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_SASLSESSION_HPP_INCLUDED
+#define VMIME_SECURITY_SASL_SASLSESSION_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
+
+
+#include "vmime/types.hpp"
+
+#include "vmime/net/socket.hpp"
+
+#include "vmime/security/sasl/SASLAuthenticator.hpp"
+#include "vmime/security/sasl/SASLMechanism.hpp"
+
+
+namespace vmime {
+namespace security {
+namespace sasl {
+
+
+class SASLContext;
+
+
+/** An SASL client session.
+ */
+class VMIME_EXPORT SASLSession : public object, public enable_shared_from_this <SASLSession> {
+
+ friend class builtinSASLMechanism;
+ friend class SASLSocket;
+
+public:
+
+ ~SASLSession();
+
+ /** Construct a new SASL session.
+ *
+ * @param serviceName name of the service using this session
+ * @param ctx SASL context
+ * @param auth authenticator to use for this session
+ * @param mech SASL mechanism
+ */
+ static shared_ptr <SASLSession> create(
+ const string& serviceName,
+ const shared_ptr <SASLContext>& ctx,
+ const shared_ptr <authenticator>& auth,
+ const shared_ptr <SASLMechanism>& mech
+ );
+
+ /** Initialize this SASL session. This must be called before
+ * calling any other method on this object (except accessors).
+ */
+ void init();
+
+ /** Return the authenticator used for this session. This is the
+ * authenticator which has been previously set with a call to
+ * setAuthenticator().
+ *
+ * @return authenticator object
+ */
+ shared_ptr <authenticator> getAuthenticator();
+
+ /** Return the mechanism used for this session.
+ *
+ * @return SASL mechanism
+ */
+ shared_ptr <SASLMechanism> getMechanism();
+
+ /** Return the SASL context.
+ *
+ * @return SASL context
+ */
+ shared_ptr <SASLContext> getContext();
+
+ /** Perform one step of SASL authentication. Accept data from the
+ * server (challenge), process it and return data to be returned
+ * in response to the server.
+ *
+ * If the challenge is empty (challengeLen == 0), the initial
+ * response is returned, if the mechanism has one.
+ *
+ * @param challenge challenge sent from the server
+ * @param challengeLen length of challenge
+ * @param response response to send to the server (allocated by
+ * this function, free with delete[])
+ * @param responseLen length of response buffer
+ * @return true if authentication terminated successfully, or
+ * false if the authentication process should continue
+ * @throw exceptions::sasl_exception if an error occurred during
+ * authentication (in this case, the values in 'response' and
+ * 'responseLen' are undetermined)
+ */
+ bool evaluateChallenge(
+ const byte_t* challenge,
+ const size_t challengeLen,
+ byte_t** response,
+ size_t* responseLen
+ );
+
+ /** Return a socket in which transmitted data is integrity
+ * and/or privacy protected, depending on the QOP (Quality of
+ * Protection) negotiated during the SASL authentication.
+ *
+ * @param sok socket to wrap
+ * @return secured socket
+ */
+ shared_ptr <net::socket> getSecuredSocket(const shared_ptr <net::socket>& sok);
+
+ /** Return the name of the service which is using this
+ * SASL session (eg. "imap"). This value should be returned
+ * by the authenticator when INFO_SERVICE is requested.
+ *
+ * @return service name
+ */
+ const string getServiceName() const;
+
+private:
+
+ SASLSession(
+ const string& serviceName,
+ const shared_ptr <SASLContext>& ctx,
+ const shared_ptr <authenticator>& auth,
+ const shared_ptr <SASLMechanism>& mech
+ );
+
+
+ const string m_serviceName;
+
+ shared_ptr <SASLContext> m_context;
+ shared_ptr <authenticator> m_auth;
+ shared_ptr <SASLMechanism> m_mech;
+
+#ifdef GSASL_VERSION
+ Gsasl* m_gsaslContext;
+ Gsasl_session* m_gsaslSession;
+
+ static int gsaslCallback(Gsasl* ctx, Gsasl_session* sctx, Gsasl_property prop);
+#else
+ void* m_gsaslContext;
+ void* m_gsaslSession;
+
+ static int gsaslCallback(void* ctx, void* sctx, int prop);
+#endif // GSASL_VERSION
+
+};
+
+
+} // sasl
+} // security
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
+
+#endif // VMIME_SECURITY_SASL_SASLSESSION_HPP_INCLUDED
diff --git a/vmime-master/src/vmime/security/sasl/SASLSocket.cpp b/vmime-master/src/vmime/security/sasl/SASLSocket.cpp
new file mode 100644
index 0000000..0dbafd8
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/SASLSocket.cpp
@@ -0,0 +1,273 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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/SASLSocket.hpp"
+#include "vmime/security/sasl/SASLSession.hpp"
+
+#include "vmime/utility/stringUtils.hpp"
+
+#include "vmime/exception.hpp"
+
+#include <algorithm>
+#include <cstring>
+
+#include <gsasl.h>
+
+
+namespace vmime {
+namespace security {
+namespace sasl {
+
+
+
+SASLSocket::SASLSocket(
+ const shared_ptr <SASLSession>& sess,
+ const shared_ptr <net::socket>& wrapped
+)
+ : m_session(sess),
+ m_wrapped(wrapped),
+ m_pendingBuffer(0),
+ m_pendingPos(0),
+ m_pendingLen(0) {
+
+}
+
+
+SASLSocket::~SASLSocket() {
+
+ if (m_pendingBuffer) {
+ delete [] m_pendingBuffer;
+ }
+}
+
+
+void SASLSocket::connect(const string& address, const port_t port) {
+
+ m_wrapped->connect(address, port);
+}
+
+
+void SASLSocket::disconnect() {
+
+ m_wrapped->disconnect();
+}
+
+
+bool SASLSocket::isConnected() const {
+
+ return m_wrapped->isConnected();
+}
+
+
+size_t SASLSocket::getBlockSize() const {
+
+ return m_wrapped->getBlockSize();
+}
+
+
+const string SASLSocket::getPeerName() const {
+
+ return m_wrapped->getPeerName();
+}
+
+
+const string SASLSocket::getPeerAddress() const {
+
+ return m_wrapped->getPeerAddress();
+}
+
+
+shared_ptr <net::timeoutHandler> SASLSocket::getTimeoutHandler() {
+
+ return m_wrapped->getTimeoutHandler();
+}
+
+
+void SASLSocket::setTracer(const shared_ptr <net::tracer>& tracer) {
+
+ m_wrapped->setTracer(tracer);
+}
+
+
+shared_ptr <net::tracer> SASLSocket::getTracer() {
+
+ return m_wrapped->getTracer();
+}
+
+
+bool SASLSocket::waitForRead(const int msecs) {
+
+ return m_wrapped->waitForRead(msecs);
+}
+
+
+bool SASLSocket::waitForWrite(const int msecs) {
+
+ return m_wrapped->waitForWrite(msecs);
+}
+
+
+void SASLSocket::receive(string& buffer) {
+
+ const size_t n = receiveRaw(m_recvBuffer, sizeof(m_recvBuffer));
+
+ buffer = utility::stringUtils::makeStringFromBytes(m_recvBuffer, n);
+}
+
+
+size_t SASLSocket::receiveRaw(byte_t* buffer, const size_t count) {
+
+ if (m_pendingLen != 0) {
+
+ const size_t copyLen =
+ (count >= m_pendingLen ? m_pendingLen : count);
+
+ std::copy(
+ m_pendingBuffer + m_pendingPos,
+ m_pendingBuffer + m_pendingPos + copyLen,
+ buffer
+ );
+
+ m_pendingLen -= copyLen;
+ m_pendingPos += copyLen;
+
+ if (m_pendingLen == 0) {
+
+ delete [] m_pendingBuffer;
+
+ m_pendingBuffer = 0;
+ m_pendingPos = 0;
+ m_pendingLen = 0;
+ }
+
+ return copyLen;
+ }
+
+ const size_t n = m_wrapped->receiveRaw(buffer, count);
+
+ byte_t* output = 0;
+ size_t outputLen = 0;
+
+ m_session->getMechanism()->decode(m_session, buffer, n, &output, &outputLen);
+
+ // If we can not copy all decoded data into the output buffer, put
+ // remaining data into a pending buffer for next calls to receive()
+ if (outputLen > count) {
+
+ std::copy(output, output + count, buffer);
+
+ m_pendingBuffer = output;
+ m_pendingLen = outputLen;
+ m_pendingPos = count;
+
+ return count;
+
+ } else {
+
+ std::copy(output, output + outputLen, buffer);
+
+ delete [] output;
+
+ return outputLen;
+ }
+}
+
+
+void SASLSocket::send(const string& buffer) {
+
+ sendRaw(reinterpret_cast <const byte_t*>(buffer.data()), buffer.length());
+}
+
+
+void SASLSocket::send(const char* str) {
+
+ sendRaw(reinterpret_cast <const byte_t*>(str), strlen(str));
+}
+
+
+void SASLSocket::sendRaw(const byte_t* buffer, const size_t count) {
+
+ byte_t* output = 0;
+ size_t outputLen = 0;
+
+ m_session->getMechanism()->encode(
+ m_session, buffer, count, &output, &outputLen
+ );
+
+ try {
+
+ m_wrapped->sendRaw(output, outputLen);
+
+ } catch (...) {
+
+ delete [] output;
+ throw;
+ }
+
+ delete [] output;
+}
+
+
+size_t SASLSocket::sendRawNonBlocking(const byte_t* buffer, const size_t count) {
+
+ byte_t* output = 0;
+ size_t outputLen = 0;
+
+ m_session->getMechanism()->encode(m_session, buffer, count, &output, &outputLen);
+
+ size_t bytesSent = 0;
+
+ try {
+
+ bytesSent = m_wrapped->sendRawNonBlocking(output, outputLen);
+
+ } catch (...) {
+
+ delete [] output;
+ throw;
+ }
+
+ delete [] output;
+
+ return bytesSent;
+}
+
+
+unsigned int SASLSocket::getStatus() const {
+
+ return m_wrapped->getStatus();
+}
+
+
+} // sasl
+} // security
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
diff --git a/vmime-master/src/vmime/security/sasl/SASLSocket.hpp b/vmime-master/src/vmime/security/sasl/SASLSocket.hpp
new file mode 100644
index 0000000..ac0e89e
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/SASLSocket.hpp
@@ -0,0 +1,108 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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_SASLSOCKET_HPP_INCLUDED
+#define VMIME_SECURITY_SASL_SASLSOCKET_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
+
+
+#include "vmime/types.hpp"
+
+#include "vmime/net/socket.hpp"
+
+
+namespace vmime {
+namespace security {
+namespace sasl {
+
+
+class SASLSession;
+
+
+/** A socket which provides data integrity and/or privacy protection.
+ */
+class VMIME_EXPORT SASLSocket : public net::socket {
+
+public:
+
+ SASLSocket(
+ const shared_ptr <SASLSession>& sess,
+ const shared_ptr <net::socket>& wrapped
+ );
+
+ ~SASLSocket();
+
+ void connect(const string& address, const port_t port);
+ void disconnect();
+
+ bool isConnected() const;
+
+ bool waitForRead(const int msecs = 30000);
+ bool waitForWrite(const int msecs = 30000);
+
+ void receive(string& buffer);
+ size_t receiveRaw(byte_t* buffer, const size_t count);
+
+ void send(const string& buffer);
+ void send(const char* str);
+ void sendRaw(const byte_t* buffer, const size_t count);
+ size_t sendRawNonBlocking(const byte_t* buffer, const size_t count);
+
+ size_t getBlockSize() const;
+
+ unsigned int getStatus() const;
+
+ const string getPeerName() const;
+ const string getPeerAddress() const;
+
+ shared_ptr <net::timeoutHandler> getTimeoutHandler();
+
+ void setTracer(const shared_ptr <net::tracer>& tracer);
+ shared_ptr <net::tracer> getTracer();
+
+private:
+
+ shared_ptr <SASLSession> m_session;
+ shared_ptr <net::socket> m_wrapped;
+
+ byte_t* m_pendingBuffer;
+ size_t m_pendingPos;
+ size_t m_pendingLen;
+
+ byte_t m_recvBuffer[65536];
+};
+
+
+} // sasl
+} // security
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
+
+#endif // VMIME_SECURITY_SASL_SASLSOCKET_HPP_INCLUDED
diff --git a/vmime-master/src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp b/vmime-master/src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp
new file mode 100644
index 0000000..ecc715a
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp
@@ -0,0 +1,99 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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,
+ const 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 {
+
+ shared_ptr <SASLMechanism> newSuggested(suggested);
+
+ for (size_t i = available.size() ; i != 0 ; --i) {
+
+ shared_ptr <SASLMechanism> mech = available[i - 1];
+
+ if ("XOAUTH2" == mech->getName()) {
+ // Suggest using XOAuth2
+ newSuggested = mech;
+ }
+ }
+
+ return defaultSASLAuthenticator::getAcceptableMechanisms(available, newSuggested);
+ }
+}
+
+
+} // sasl
+} // security
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
diff --git a/vmime-master/src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp b/vmime-master/src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp
new file mode 100644
index 0000000..e4d3d83
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp
@@ -0,0 +1,77 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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,
+ const 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
diff --git a/vmime-master/src/vmime/security/sasl/XOAuth2SASLMechanism.cpp b/vmime-master/src/vmime/security/sasl/XOAuth2SASLMechanism.cpp
new file mode 100644
index 0000000..e5ecd4b
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/XOAuth2SASLMechanism.cpp
@@ -0,0 +1,155 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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(
+ const 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(
+ const 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(
+ const 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(
+ const 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
diff --git a/vmime-master/src/vmime/security/sasl/XOAuth2SASLMechanism.hpp b/vmime-master/src/vmime/security/sasl/XOAuth2SASLMechanism.hpp
new file mode 100644
index 0000000..eacbb0a
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/XOAuth2SASLMechanism.hpp
@@ -0,0 +1,102 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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(const shared_ptr <SASLContext>& ctx, const string& name);
+ ~XOAuth2SASLMechanism();
+
+
+ const string getName() const;
+
+ bool step(
+ const 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(
+ const shared_ptr <SASLSession>& sess,
+ const byte_t* input,
+ const size_t inputLen,
+ byte_t** output,
+ size_t* outputLen
+ );
+
+ void decode(
+ const 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
diff --git a/vmime-master/src/vmime/security/sasl/builtinSASLMechanism.cpp b/vmime-master/src/vmime/security/sasl/builtinSASLMechanism.cpp
new file mode 100644
index 0000000..846e2cc
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/builtinSASLMechanism.cpp
@@ -0,0 +1,221 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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 <gsasl.h>
+
+#include "vmime/security/sasl/builtinSASLMechanism.hpp"
+
+#include "vmime/security/sasl/SASLContext.hpp"
+#include "vmime/security/sasl/SASLSession.hpp"
+
+#include "vmime/exception.hpp"
+
+#include <stdexcept>
+#include <new>
+
+
+namespace vmime {
+namespace security {
+namespace sasl {
+
+
+builtinSASLMechanism::builtinSASLMechanism(
+ const shared_ptr <SASLContext>& ctx,
+ const string& name
+)
+ : m_context(ctx),
+ m_name(name),
+ m_complete(false) {
+
+}
+
+
+builtinSASLMechanism::~builtinSASLMechanism() {
+
+}
+
+
+const string builtinSASLMechanism::getName() const {
+
+ return m_name;
+}
+
+
+bool builtinSASLMechanism::step(
+ const shared_ptr <SASLSession>& sess,
+ const byte_t* challenge,
+ const size_t challengeLen,
+ byte_t** response,
+ size_t* responseLen
+) {
+
+ char* output = 0;
+ size_t outputLen = 0;
+
+ const int result = gsasl_step(
+ sess->m_gsaslSession,
+ reinterpret_cast <const char*>(challenge), challengeLen,
+ &output, &outputLen
+ );
+
+ if (result == GSASL_OK || result == GSASL_NEEDS_MORE) {
+
+ byte_t* res = new byte_t[outputLen];
+
+ for (size_t i = 0 ; i < outputLen ; ++i) {
+ res[i] = output[i];
+ }
+
+ *response = res;
+ *responseLen = outputLen;
+
+ gsasl_free(output);
+
+ } else {
+
+ *response = 0;
+ *responseLen = 0;
+ }
+
+ if (result == GSASL_OK) {
+
+ // Authentication process completed
+ m_complete = true;
+ return true;
+
+ } else if (result == GSASL_NEEDS_MORE) {
+
+ // Continue authentication process
+ return false;
+
+ } else if (result == GSASL_MALLOC_ERROR) {
+
+ throw std::bad_alloc();
+
+ } else {
+
+ throw exceptions::sasl_exception(
+ "Error when processing challenge: "
+ + SASLContext::getErrorMessage("gsasl_step", result)
+ );
+ }
+}
+
+
+bool builtinSASLMechanism::isComplete() const {
+
+ return m_complete;
+}
+
+
+bool builtinSASLMechanism::hasInitialResponse() const {
+
+ // It seems GNU SASL does not support initial response
+ return false;
+}
+
+
+void builtinSASLMechanism::encode(
+ const shared_ptr <SASLSession>& sess,
+ const byte_t* input,
+ const size_t inputLen,
+ byte_t** output,
+ size_t* outputLen
+) {
+
+ char* coutput = 0;
+ size_t coutputLen = 0;
+
+ if (gsasl_encode(sess->m_gsaslSession, reinterpret_cast <const char*>(input), inputLen,
+ &coutput, &coutputLen) != GSASL_OK) {
+
+ throw exceptions::sasl_exception("Encoding error.");
+ }
+
+ try {
+
+ byte_t* res = new byte_t[coutputLen];
+
+ std::copy(coutput, coutput + coutputLen, res);
+
+ *output = res;
+ *outputLen = static_cast <int>(coutputLen);
+
+ } catch (...) {
+
+ gsasl_free(coutput);
+ throw;
+ }
+
+ gsasl_free(coutput);
+}
+
+
+void builtinSASLMechanism::decode(
+ const shared_ptr <SASLSession>& sess,
+ const byte_t* input,
+ const size_t inputLen,
+ byte_t** output,
+ size_t* outputLen
+) {
+
+ char* coutput = 0;
+ size_t coutputLen = 0;
+
+ try {
+
+ if (gsasl_decode(sess->m_gsaslSession, reinterpret_cast <const char*>(input), inputLen,
+ &coutput, &coutputLen) != GSASL_OK) {
+
+ throw exceptions::sasl_exception("Decoding error.");
+ }
+
+ byte_t* res = new byte_t[coutputLen];
+
+ std::copy(coutput, coutput + coutputLen, res);
+
+ *output = res;
+ *outputLen = static_cast <int>(coutputLen);
+
+ } catch (...) {
+
+ gsasl_free(coutput);
+ throw;
+ }
+
+ gsasl_free(coutput);
+}
+
+
+} // sasl
+} // security
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
diff --git a/vmime-master/src/vmime/security/sasl/builtinSASLMechanism.hpp b/vmime-master/src/vmime/security/sasl/builtinSASLMechanism.hpp
new file mode 100644
index 0000000..2e412d6
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/builtinSASLMechanism.hpp
@@ -0,0 +1,105 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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_BUILTINSASLMECHANISM_HPP_INCLUDED
+#define VMIME_SECURITY_SASL_BUILTINSASLMECHANISM_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;
+
+
+/** A built-in authentication mechanism that relies on
+ * the GNU SASL library.
+ */
+class VMIME_EXPORT builtinSASLMechanism : public SASLMechanism {
+
+public:
+
+ builtinSASLMechanism(const shared_ptr <SASLContext>& ctx, const string& name);
+ ~builtinSASLMechanism();
+
+
+ const string getName() const;
+
+ bool step(
+ const 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(
+ const shared_ptr <SASLSession>& sess,
+ const byte_t* input,
+ const size_t inputLen,
+ byte_t** output,
+ size_t* outputLen
+ );
+
+ void decode(
+ const 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;
+
+ /** Mechanism name */
+ const string m_name;
+
+ /** Authentication process status. */
+ bool m_complete;
+};
+
+
+} // sasl
+} // security
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
+
+#endif // VMIME_SECURITY_SASL_BUILTINSASLMECHANISM_HPP_INCLUDED
diff --git a/vmime-master/src/vmime/security/sasl/defaultSASLAuthenticator.cpp b/vmime-master/src/vmime/security/sasl/defaultSASLAuthenticator.cpp
new file mode 100644
index 0000000..ebd7e68
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/defaultSASLAuthenticator.cpp
@@ -0,0 +1,159 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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/defaultSASLAuthenticator.hpp"
+
+#include "vmime/security/sasl/SASLMechanism.hpp"
+#include "vmime/security/sasl/SASLSession.hpp"
+#include "vmime/security/sasl/SASLContext.hpp"
+
+#include "vmime/net/service.hpp"
+
+
+namespace vmime {
+namespace security {
+namespace sasl {
+
+
+defaultSASLAuthenticator::defaultSASLAuthenticator() {
+
+}
+
+
+defaultSASLAuthenticator::~defaultSASLAuthenticator() {
+
+}
+
+
+const std::vector <shared_ptr <SASLMechanism> > defaultSASLAuthenticator::getAcceptableMechanisms(
+ const std::vector <shared_ptr <SASLMechanism> >& available,
+ const shared_ptr <SASLMechanism>& suggested
+) const {
+
+ if (suggested) {
+
+ std::vector <shared_ptr <SASLMechanism> > res;
+
+ res.push_back(suggested);
+
+ for (unsigned int i = 0 ; i < available.size() ; ++i) {
+
+ if (available[i]->getName() != suggested->getName()) {
+ res.push_back(available[i]);
+ }
+ }
+
+ return res;
+
+ } else {
+
+ return available;
+ }
+}
+
+
+const string defaultSASLAuthenticator::getUsername() const {
+
+ return m_default.getUsername();
+}
+
+
+const string defaultSASLAuthenticator::getPassword() const {
+
+ return m_default.getPassword();
+}
+
+
+const string defaultSASLAuthenticator::getAccessToken() const {
+
+ return m_default.getAccessToken();
+}
+
+
+const string defaultSASLAuthenticator::getHostname() const {
+
+ return m_default.getHostname();
+}
+
+
+const string defaultSASLAuthenticator::getAnonymousToken() const {
+
+ return m_default.getAnonymousToken();
+}
+
+
+const string defaultSASLAuthenticator::getServiceName() const {
+
+ return m_saslSession.lock()->getServiceName();
+}
+
+
+void defaultSASLAuthenticator::setService(const shared_ptr <net::service>& serv) {
+
+ m_service = serv;
+ m_default.setService(serv);
+}
+
+
+weak_ptr <net::service> defaultSASLAuthenticator::getService() const {
+
+ return m_service;
+}
+
+
+void defaultSASLAuthenticator::setSASLSession(const shared_ptr <SASLSession>& sess) {
+
+ m_saslSession = sess;
+}
+
+
+shared_ptr <SASLSession> defaultSASLAuthenticator::getSASLSession() const {
+
+ return m_saslSession.lock();
+}
+
+
+void defaultSASLAuthenticator::setSASLMechanism(const shared_ptr <SASLMechanism>& mech) {
+
+ m_saslMech = mech;
+}
+
+
+shared_ptr <SASLMechanism> defaultSASLAuthenticator::getSASLMechanism() const {
+
+ return m_saslMech;
+}
+
+
+} // sasl
+} // security
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
diff --git a/vmime-master/src/vmime/security/sasl/defaultSASLAuthenticator.hpp b/vmime-master/src/vmime/security/sasl/defaultSASLAuthenticator.hpp
new file mode 100644
index 0000000..368e9ef
--- /dev/null
+++ b/vmime-master/src/vmime/security/sasl/defaultSASLAuthenticator.hpp
@@ -0,0 +1,91 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002 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_DEFAULTSASLAUTHENTICATOR_HPP_INCLUDED
+#define VMIME_SECURITY_SASL_DEFAULTSASLAUTHENTICATOR_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
+
+
+#include "vmime/security/sasl/SASLAuthenticator.hpp"
+#include "vmime/security/defaultAuthenticator.hpp"
+
+
+namespace vmime {
+namespace security {
+namespace sasl {
+
+
+/** An authenticator that is capable of providing information
+ * for simple authentication mechanisms (username and password).
+ */
+class VMIME_EXPORT defaultSASLAuthenticator : public SASLAuthenticator {
+
+public:
+
+ defaultSASLAuthenticator();
+ ~defaultSASLAuthenticator();
+
+ const std::vector <shared_ptr <SASLMechanism> > getAcceptableMechanisms(
+ const std::vector <shared_ptr <SASLMechanism> >& available,
+ const shared_ptr <SASLMechanism>& suggested
+ ) const;
+
+ const string getUsername() const;
+ const string getPassword() const;
+ const string getHostname() const;
+ const string getAnonymousToken() const;
+ const string getServiceName() const;
+ const string getAccessToken() const;
+
+ void setService(const shared_ptr <net::service>& serv);
+ weak_ptr <net::service> getService() const;
+
+ void setSASLSession(const shared_ptr <SASLSession>& sess);
+ shared_ptr <SASLSession> getSASLSession() const;
+
+ void setSASLMechanism(const shared_ptr <SASLMechanism>& mech);
+ shared_ptr <SASLMechanism> getSASLMechanism() const;
+
+private:
+
+ defaultAuthenticator m_default;
+
+ weak_ptr <net::service> m_service;
+ weak_ptr <SASLSession> m_saslSession;
+ shared_ptr <SASLMechanism> m_saslMech;
+};
+
+
+} // sasl
+} // security
+} // vmime
+
+
+#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT
+
+#endif // VMIME_SECURITY_SASL_DEFAULTSASLAUTHENTICATOR_HPP_INCLUDED