aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog15
-rw-r--r--camel/Makefile.am2
-rw-r--r--camel/camel-sasl-login.c135
-rw-r--r--camel/camel-sasl-login.h61
-rw-r--r--camel/camel-sasl-plain.c11
-rw-r--r--camel/camel-sasl-plain.h2
-rw-r--r--camel/camel-sasl.c5
-rw-r--r--camel/providers/smtp/camel-smtp-transport.c33
8 files changed, 241 insertions, 23 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 94fe89f623..c2f0eb2e12 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,5 +1,20 @@
2001-04-01 Jeffrey Stedfast <fejj@ximian.com>
+ * camel-sasl-login.[c,h]: New files to handle the LOGIN SASL
+ mechanism.
+
+ * camel-sasl-plain.c: Removed the definition of
+ camel_sasl_login_authtype.
+
+ * camel-sasl.c (camel_sasl_new): Oops. I thought LOGIN was an
+ alias to PLAIN. I was wrong. These two SASL objects have to be
+ separate.
+
+ * providers/smtp/camel-smtp-transport.c (smtp_auth): Updated to
+ check for and use authmech->quick_login when available.
+
+2001-04-01 Jeffrey Stedfast <fejj@ximian.com>
+
* providers/pop3/camel-pop3-provider.c: Updated the authtypes here
too.
diff --git a/camel/Makefile.am b/camel/Makefile.am
index decc13d3c1..0c358b1caf 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -60,6 +60,7 @@ libcamel_la_SOURCES = \
camel-sasl-cram-md5.c \
camel-sasl-digest-md5.c \
camel-sasl-kerberos4.c \
+ camel-sasl-login.c \
camel-sasl-plain.c \
camel-search-private.c \
camel-seekable-stream.c \
@@ -131,6 +132,7 @@ libcamelinclude_HEADERS = \
camel-sasl-cram-md5.h \
camel-sasl-digest-md5.h \
camel-sasl-kerberos4.h \
+ camel-sasl-login.h \
camel-sasl-plain.h \
camel-seekable-stream.h \
camel-seekable-substream.h \
diff --git a/camel/camel-sasl-login.c b/camel/camel-sasl-login.c
new file mode 100644
index 0000000000..6396e51102
--- /dev/null
+++ b/camel/camel-sasl-login.c
@@ -0,0 +1,135 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2001 Ximian, Inc. (www.ximian.com)
+ *
+ * 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., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include "camel-sasl-login.h"
+#include "camel-service.h"
+
+CamelServiceAuthType camel_sasl_login_authtype = {
+ N_("NT Login"),
+
+ N_("This option will connect to the server using a "
+ "simple password."),
+
+ "LOGIN",
+ TRUE,
+ TRUE
+};
+
+enum {
+ LOGIN_USER,
+ LOGIN_PASSWD
+};
+
+static CamelSaslClass *parent_class = NULL;
+
+/* Returns the class for a CamelSaslLogin */
+#define CSP_CLASS(so) CAMEL_SASL_LOGIN_CLASS (CAMEL_OBJECT_GET_CLASS (so))
+
+static GByteArray *login_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex);
+
+struct _CamelSaslLoginPrivate {
+ int state;
+};
+
+static void
+camel_sasl_login_class_init (CamelSaslLoginClass *camel_sasl_login_class)
+{
+ CamelSaslClass *camel_sasl_class = CAMEL_SASL_CLASS (camel_sasl_login_class);
+
+ parent_class = CAMEL_SASL_CLASS (camel_type_get_global_classfuncs (camel_sasl_get_type ()));
+
+ /* virtual method overload */
+ camel_sasl_class->challenge = login_challenge;
+}
+
+static void
+camel_sasl_login_init (gpointer object, gpointer klass)
+{
+ CamelSaslLogin *sasl_login = CAMEL_SASL_LOGIN (object);
+
+ sasl_login->priv = g_new0 (struct _CamelSaslLoginPrivate, 1);
+}
+
+static void
+camel_sasl_login_finalize (CamelObject *object)
+{
+ CamelSaslLogin *sasl = CAMEL_SASL_LOGIN (object);
+
+ g_free (sasl->priv);
+}
+
+
+CamelType
+camel_sasl_login_get_type (void)
+{
+ static CamelType type = CAMEL_INVALID_TYPE;
+
+ if (type == CAMEL_INVALID_TYPE) {
+ type = camel_type_register (camel_sasl_get_type (),
+ "CamelSaslLogin",
+ sizeof (CamelSaslLogin),
+ sizeof (CamelSaslLoginClass),
+ (CamelObjectClassInitFunc) camel_sasl_login_class_init,
+ NULL,
+ (CamelObjectInitFunc) camel_sasl_login_init,
+ (CamelObjectFinalizeFunc) camel_sasl_login_finalize);
+ }
+
+ return type;
+}
+
+static GByteArray *
+login_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex)
+{
+ struct _CamelSaslLoginPrivate *priv = CAMEL_SASL_LOGIN (sasl)->priv;
+ GByteArray *buf = NULL;
+ CamelURL *url = sasl->service->url;
+
+ g_return_val_if_fail (url->passwd != NULL, NULL);
+
+ switch (priv->state) {
+ case LOGIN_USER:
+ buf = g_byte_array_new ();
+ g_byte_array_append (buf, url->user, strlen (url->user));
+ break;
+ case LOGIN_PASSWD:
+ buf = g_byte_array_new ();
+ g_byte_array_append (buf, url->passwd, strlen (url->passwd));
+
+ sasl->authenticated = TRUE;
+ break;
+ default:
+ if (!camel_exception_is_set (ex)) {
+ camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE,
+ _("Unknown authentication state."));
+ }
+ }
+
+ priv->state++;
+
+ return buf;
+}
diff --git a/camel/camel-sasl-login.h b/camel/camel-sasl-login.h
new file mode 100644
index 0000000000..7dacaf82e4
--- /dev/null
+++ b/camel/camel-sasl-login.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2001 Ximian, Inc. (www.ximian.com)
+ *
+ * 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., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef CAMEL_SASL_LOGIN_H
+#define CAMEL_SASL_LOGIN_H
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus }*/
+
+#include <camel/camel-sasl.h>
+
+#define CAMEL_SASL_LOGIN_TYPE (camel_sasl_login_get_type ())
+#define CAMEL_SASL_LOGIN(obj) (CAMEL_CHECK_CAST((obj), CAMEL_SASL_LOGIN_TYPE, CamelSaslLogin))
+#define CAMEL_SASL_LOGIN_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_SASL_LOGIN_TYPE, CamelSaslLoginClass))
+#define CAMEL_IS_SASL_LOGIN(o) (CAMEL_CHECK_TYPE((o), CAMEL_SASL_LOGIN_TYPE))
+
+typedef struct _CamelSaslLogin {
+ CamelSasl parent_object;
+
+ struct _CamelSaslLoginPrivate *priv;
+
+} CamelSaslLogin;
+
+
+typedef struct _CamelSaslLoginClass {
+ CamelSaslClass parent_class;
+
+} CamelSaslLoginClass;
+
+
+/* Standard Camel function */
+CamelType camel_sasl_login_get_type (void);
+
+extern CamelServiceAuthType camel_sasl_login_authtype;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* CAMEL_SASL_LOGIN_H */
diff --git a/camel/camel-sasl-plain.c b/camel/camel-sasl-plain.c
index 958a30e962..e0b7511ff0 100644
--- a/camel/camel-sasl-plain.c
+++ b/camel/camel-sasl-plain.c
@@ -39,17 +39,6 @@ CamelServiceAuthType camel_sasl_plain_authtype = {
FALSE
};
-CamelServiceAuthType camel_sasl_login_authtype = {
- N_("NT Login"),
-
- N_("This option will connect to the server using a "
- "simple password."),
-
- "LOGIN",
- TRUE,
- TRUE
-};
-
static CamelSaslClass *parent_class = NULL;
/* Returns the class for a CamelSaslPlain */
diff --git a/camel/camel-sasl-plain.h b/camel/camel-sasl-plain.h
index 047fc6b6a7..1e93ae5c7a 100644
--- a/camel/camel-sasl-plain.h
+++ b/camel/camel-sasl-plain.h
@@ -52,8 +52,6 @@ CamelType camel_sasl_plain_get_type (void);
extern CamelServiceAuthType camel_sasl_plain_authtype;
-extern CamelServiceAuthType camel_sasl_login_authtype;
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/camel/camel-sasl.c b/camel/camel-sasl.c
index 1044d58c21..dd4da2f081 100644
--- a/camel/camel-sasl.c
+++ b/camel/camel-sasl.c
@@ -32,6 +32,7 @@
#include "camel-sasl-cram-md5.h"
#include "camel-sasl-digest-md5.h"
#include "camel-sasl-kerberos4.h"
+#include "camel-sasl-login.h"
#include "camel-sasl-plain.h"
static CamelObjectClass *parent_class = NULL;
@@ -191,8 +192,10 @@ camel_sasl_new (const char *service_name, const char *mechanism, CamelService *s
else if (!strcmp (mechanism, "KERBEROS_V4"))
sasl = (CamelSasl *)camel_object_new (CAMEL_SASL_KERBEROS4_TYPE);
#endif
- else if (!strcmp (mechanism, "PLAIN") || !strcmp (mechanism, "LOGIN"))
+ else if (!strcmp (mechanism, "PLAIN"))
sasl = (CamelSasl *)camel_object_new (CAMEL_SASL_PLAIN_TYPE);
+ else if (!strcmp (mechanism, "LOGIN"))
+ sasl = (CamelSasl *)camel_object_new (CAMEL_SASL_LOGIN_TYPE);
else
return NULL;
diff --git a/camel/providers/smtp/camel-smtp-transport.c b/camel/providers/smtp/camel-smtp-transport.c
index af41b2f5b9..1c18c154b3 100644
--- a/camel/providers/smtp/camel-smtp-transport.c
+++ b/camel/providers/smtp/camel-smtp-transport.c
@@ -696,18 +696,39 @@ smtp_helo (CamelSmtpTransport *transport, CamelException *ex)
static gboolean
smtp_auth (CamelSmtpTransport *transport, const char *mech, CamelException *ex)
{
+ CamelServiceAuthType *authtype;
gchar *cmdbuf, *respbuf = NULL;
CamelSasl *sasl;
+ sasl = camel_sasl_new ("smtp", mech, CAMEL_SERVICE (transport));
+ if (!sasl) {
+ g_free (respbuf);
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Error creating SASL authentication object."));
+ return FALSE;
+ }
+
+ /* get the authtype object so we know if we can challenge the server */
+ authtype = camel_sasl_authtype (mech);
+
/* tell the server we want to authenticate... */
- cmdbuf = g_strdup_printf ("AUTH %s\r\n", mech);
+ if (authtype && authtype->quick_login) {
+ /* cool, we can challenge the server in our initial request */
+ char *challenge;
+
+ challenge = camel_sasl_challenge_base64 (sasl, NULL, ex);
+ cmdbuf = g_strdup_printf ("AUTH %s %s\r\n", mech, challenge);
+ g_free (challenge);
+ } else
+ cmdbuf = g_strdup_printf ("AUTH %s\r\n", mech);
+
d(fprintf (stderr, "sending : %s", cmdbuf));
if (camel_stream_write (transport->ostream, cmdbuf, strlen (cmdbuf)) == -1) {
g_free (cmdbuf);
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
_("AUTH request timed out: %s"),
g_strerror (errno));
- return FALSE;
+ goto lose;
}
g_free (cmdbuf);
@@ -719,13 +740,7 @@ smtp_auth (CamelSmtpTransport *transport, const char *mech, CamelException *ex)
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
_("AUTH request timed out: %s"),
g_strerror (errno));
- return FALSE;
- }
-
- sasl = camel_sasl_new ("smtp", mech, CAMEL_SERVICE (transport));
- if (!sasl) {
- g_free (respbuf);
- goto break_and_lose;
+ goto lose;
}
while (!camel_sasl_authenticated (sasl)) {