aboutsummaryrefslogtreecommitdiffstats
path: root/src/security/sasl/SASLContext.cpp
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2005-09-17 09:08:45 +0000
committerVincent Richard <[email protected]>2005-09-17 09:08:45 +0000
commit0edaa87860dbfd4871c597a9f2fbec07fca67ed6 (patch)
tree0babae1fdc77724b92be66d90a03e0891dc8d0b8 /src/security/sasl/SASLContext.cpp
parentInput buffer size. (diff)
downloadvmime-0edaa87860dbfd4871c597a9f2fbec07fca67ed6.tar.gz
vmime-0edaa87860dbfd4871c597a9f2fbec07fca67ed6.zip
SASL authentication.
Diffstat (limited to 'src/security/sasl/SASLContext.cpp')
-rw-r--r--src/security/sasl/SASLContext.cpp189
1 files changed, 189 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
+