diff options
Diffstat (limited to '')
-rw-r--r-- | src/security/sasl/SASLContext.cpp | 189 | ||||
-rw-r--r-- | src/security/sasl/SASLMechanismFactory.cpp | 131 | ||||
-rw-r--r-- | src/security/sasl/SASLSession.cpp | 179 | ||||
-rw-r--r-- | src/security/sasl/SASLSocket.cpp | 167 | ||||
-rw-r--r-- | src/security/sasl/builtinSASLMechanism.cpp | 182 | ||||
-rw-r--r-- | src/security/sasl/defaultSASLAuthenticator.cpp | 139 |
6 files changed, 987 insertions, 0 deletions
diff --git a/src/security/sasl/SASLContext.cpp b/src/security/sasl/SASLContext.cpp new file mode 100644 index 00000000..dd8cbd93 --- /dev/null +++ b/src/security/sasl/SASLContext.cpp @@ -0,0 +1,189 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2005 Vincent Richard <[email protected]> +// +// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#include <sstream> + +#include <gsasl.h> + +#include "vmime/security/sasl/SASLContext.hpp" +#include "vmime/security/sasl/SASLMechanism.hpp" + +#include "vmime/base.hpp" +#include "vmime/encoderFactory.hpp" + +#include "vmime/utility/stream.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); +} + + +ref <SASLSession> SASLContext::createSession + (const string& serviceName, + ref <authenticator> auth, ref <SASLMechanism> mech) +{ + return vmime::create <SASLSession> + (serviceName, thisRef().dynamicCast <SASLContext>(), auth, mech); +} + + +ref <SASLMechanism> SASLContext::createMechanism(const string& name) +{ + return SASLMechanismFactory::getInstance()->create + (thisRef().dynamicCast <SASLContext>(), name); +} + + +ref <SASLMechanism> SASLContext::suggestMechanism + (const std::vector <ref <SASLMechanism> >& mechs) +{ + if (mechs.empty()) + return 0; + + 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 0; +} + + +void SASLContext::decodeB64(const string& input, byte** output, int* outputLen) +{ + string res; + + utility::inputStreamStringAdapter is(input); + utility::outputStreamStringAdapter os(res); + + ref <encoder> dec = encoderFactory::getInstance()->create("base64"); + + dec->decode(is, os); + + byte* out = new byte[res.length()]; + + std::copy(res.begin(), res.end(), out); + + *output = out; + *outputLen = res.length(); +} + + +const string SASLContext::encodeB64(const byte* input, const int inputLen) +{ + string res; + + utility::inputStreamByteBufferAdapter is(input, inputLen); + utility::outputStreamStringAdapter os(res); + + ref <encoder> enc = 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 + diff --git a/src/security/sasl/SASLMechanismFactory.cpp b/src/security/sasl/SASLMechanismFactory.cpp new file mode 100644 index 00000000..fda4448c --- /dev/null +++ b/src/security/sasl/SASLMechanismFactory.cpp @@ -0,0 +1,131 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2005 Vincent Richard <[email protected]> +// +// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#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; +} + + +ref <SASLMechanism> SASLMechanismFactory::create + (ref <SASLContext> ctx, const string& name_) +{ + const string name(utility::stringUtils::toUpper(name_)); + + // Check for built-in mechanisms + if (isMechanismSupported(name)) + { + return vmime::create <builtinSASLMechanism>(ctx, name); + } + // Check for registered mechanisms + else + { + MapType::iterator it = m_mechs.find(name); + + if (it != m_mechs.end()) + return (*it).second->create(ctx, name); + } + + throw exceptions::no_such_mechanism(name); + return 0; +} + + +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; + } + } + + free(out); + } + + return list; +} + + +const bool SASLMechanismFactory::isMechanismSupported(const string& name) const +{ + return (gsasl_client_support_p(m_gsaslContext, name.c_str()) != 0 || + m_mechs.find(name) != m_mechs.end()); +} + + +} // sasl +} // security +} // vmime + diff --git a/src/security/sasl/SASLSession.cpp b/src/security/sasl/SASLSession.cpp new file mode 100644 index 00000000..f4d8bf13 --- /dev/null +++ b/src/security/sasl/SASLSession.cpp @@ -0,0 +1,179 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2005 Vincent Richard <[email protected]> +// +// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#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, ref <SASLContext> ctx, + ref <authenticator> auth, ref <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 = 0; + + gsasl_done(m_gsaslContext); + m_gsaslContext = 0; +} + + +void SASLSession::init() +{ + ref <SASLAuthenticator> saslAuth = m_auth.dynamicCast <SASLAuthenticator>(); + + if (saslAuth) + { + saslAuth->setSASLMechanism(m_mech); + saslAuth->setSASLSession(thisRef().dynamicCast <SASLSession>()); + } +} + + +ref <authenticator> SASLSession::getAuthenticator() +{ + return m_auth; +} + + +ref <SASLMechanism> SASLSession::getMechanism() +{ + return m_mech; +} + + +ref <SASLContext> SASLSession::getContext() +{ + return m_context; +} + + +const bool SASLSession::evaluateChallenge + (const byte* challenge, const int challengeLen, + byte** response, int* responseLen) +{ + return m_mech->step(thisRef().dynamicCast <SASLSession>(), + challenge, challengeLen, response, responseLen); +} + + +ref <net::socket> SASLSession::getSecuredSocket(ref <net::socket> sok) +{ + return vmime::create <SASLSocket>(thisRef().dynamicCast <SASLSession>(), 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; + + ref <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 (exceptions::no_auth_information&) + catch (...) + { + return GSASL_NO_CALLBACK; + } +} + + +} // sasl +} // security +} // vmime + diff --git a/src/security/sasl/SASLSocket.cpp b/src/security/sasl/SASLSocket.cpp new file mode 100644 index 00000000..321f90f7 --- /dev/null +++ b/src/security/sasl/SASLSocket.cpp @@ -0,0 +1,167 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2005 Vincent Richard <[email protected]> +// +// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#include "vmime/security/sasl/SASLSocket.hpp" +#include "vmime/security/sasl/SASLSession.hpp" + +#include "vmime/exception.hpp" + +#include <algorithm> + +#include <gsasl.h> + + +namespace vmime { +namespace security { +namespace sasl { + + + +SASLSocket::SASLSocket(ref <SASLSession> sess, ref <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(); +} + + +const bool SASLSocket::isConnected() const +{ + return m_wrapped->isConnected(); +} + + +void SASLSocket::receive(string& buffer) +{ + const int n = receiveRaw(m_recvBuffer, sizeof(m_recvBuffer)); + + buffer = string(m_recvBuffer, n); +} + + +const int SASLSocket::receiveRaw(char* buffer, const int count) +{ + if (m_pendingLen != 0) + { + const int 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 int n = m_wrapped->receiveRaw(buffer, count); + + byte* output = 0; + int outputLen = 0; + + m_session->getMechanism()->decode + (m_session, reinterpret_cast <const byte*>(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(buffer.data(), buffer.length()); +} + + +void SASLSocket::sendRaw(const char* buffer, const int count) +{ + byte* output = 0; + int outputLen = 0; + + m_session->getMechanism()->encode + (m_session, reinterpret_cast <const byte*>(buffer), count, + &output, &outputLen); + + try + { + m_wrapped->sendRaw + (reinterpret_cast <const char*>(output), outputLen); + } + catch (...) + { + delete [] output; + throw; + } + + delete [] output; +} + + +} // sasl +} // security +} // vmime + diff --git a/src/security/sasl/builtinSASLMechanism.cpp b/src/security/sasl/builtinSASLMechanism.cpp new file mode 100644 index 00000000..89704eeb --- /dev/null +++ b/src/security/sasl/builtinSASLMechanism.cpp @@ -0,0 +1,182 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2005 Vincent Richard <[email protected]> +// +// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#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(ref <SASLContext> ctx, const string& name) + : m_context(ctx), m_name(name), m_complete(false) +{ +} + + +builtinSASLMechanism::~builtinSASLMechanism() +{ +} + + +const string builtinSASLMechanism::getName() const +{ + return m_name; +} + + +const bool builtinSASLMechanism::step + (ref <SASLSession> sess, const byte* challenge, const int challengeLen, + byte** response, int* 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* res = new byte[outputLen]; + + for (size_t i = 0 ; i < outputLen ; ++i) + res[i] = output[i]; + + *response = res; + *responseLen = outputLen; + + 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)); + } +} + + +const bool builtinSASLMechanism::isComplete() const +{ + return m_complete; +} + + +void builtinSASLMechanism::encode + (ref <SASLSession> sess, const byte* input, const int inputLen, + byte** output, int* 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* res = new byte[coutputLen]; + + std::copy(coutput, coutput + coutputLen, res); + + *output = res; + *outputLen = static_cast <int>(coutputLen); + } + catch (...) + { + free(coutput); + throw; + } + + free(coutput); +} + + +void builtinSASLMechanism::decode + (ref <SASLSession> sess, const byte* input, const int inputLen, + byte** output, int* 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* res = new byte[coutputLen]; + + std::copy(coutput, coutput + coutputLen, res); + + *output = res; + *outputLen = static_cast <int>(coutputLen); + } + catch (...) + { + free(coutput); + throw; + } + + free(coutput); +} + + +} // sasl +} // security +} // vmime + diff --git a/src/security/sasl/defaultSASLAuthenticator.cpp b/src/security/sasl/defaultSASLAuthenticator.cpp new file mode 100644 index 00000000..d396e069 --- /dev/null +++ b/src/security/sasl/defaultSASLAuthenticator.cpp @@ -0,0 +1,139 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2005 Vincent Richard <[email protected]> +// +// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA. +// + +#include "vmime/security/sasl/defaultSASLAuthenticator.hpp" + +#include "vmime/security/sasl/SASLMechanism.hpp" +#include "vmime/security/sasl/SASLSession.hpp" + +#include "vmime/net/service.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +defaultSASLAuthenticator::defaultSASLAuthenticator() +{ +} + + +defaultSASLAuthenticator::~defaultSASLAuthenticator() +{ +} + + +const std::vector <ref <SASLMechanism> > + defaultSASLAuthenticator::getAcceptableMechanisms + (const std::vector <ref <SASLMechanism> >& available, + ref <SASLMechanism> suggested) const +{ + if (suggested) + { + std::vector <ref <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::getHostname() const +{ + return m_default.getHostname(); +} + + +const string defaultSASLAuthenticator::getAnonymousToken() const +{ + return m_default.getAnonymousToken(); +} + + +const string defaultSASLAuthenticator::getServiceName() const +{ + return m_saslSession->getServiceName(); +} + + +void defaultSASLAuthenticator::setService(ref <net::service> serv) +{ + m_service = serv; + m_default.setService(serv); +} + + +weak_ref <net::service> defaultSASLAuthenticator::getService() const +{ + return m_service; +} + + +void defaultSASLAuthenticator::setSASLSession(ref <SASLSession> sess) +{ + m_saslSession = sess; +} + + +ref <SASLSession> defaultSASLAuthenticator::getSASLSession() const +{ + return m_saslSession; +} + + +void defaultSASLAuthenticator::setSASLMechanism(ref <SASLMechanism> mech) +{ + m_saslMech = mech; +} + + +ref <SASLMechanism> defaultSASLAuthenticator::getSASLMechanism() const +{ + return m_saslMech; +} + + +} // sasl +} // security +} // vmime + |