diff options
author | Not Zed <NotZed@Ximian.com> | 2001-08-03 23:33:57 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2001-08-03 23:33:57 +0800 |
commit | 99e55fbc6b1ad39fd840c8b917583bc1b2cce2dd (patch) | |
tree | 81f1d48fe93bc80703eaeba37dcb94ed29e226db /camel/camel-sasl-popb4smtp.c | |
parent | 68518c1d989ded3031c490fb0b542424aef369cf (diff) | |
download | gsoc2013-evolution-99e55fbc6b1ad39fd840c8b917583bc1b2cce2dd.tar.gz gsoc2013-evolution-99e55fbc6b1ad39fd840c8b917583bc1b2cce2dd.tar.zst gsoc2013-evolution-99e55fbc6b1ad39fd840c8b917583bc1b2cce2dd.zip |
special case popb4smtp auth before we try and connect, and do the magic
2001-08-03 Not Zed <NotZed@Ximian.com>
* providers/smtp/camel-smtp-transport.c (smtp_connect): special
case popb4smtp auth before we try and connect, and do the magic
here first.
2001-08-02 Not Zed <NotZed@Ximian.com>
* providers/smtp/camel-smtp-transport.c (smtp_connect): Check for
POPB4SMTP separate to the esmtp auth list.
(smtp_auth): If creating the sasl object means it is
already authenticated, then exit early. Sort of 'clean hack' to
help popb4smtp work.
(smtp_auth): Unref the sasl object, clean up a memleak i think.
* providers/smtp/camel-smtp-provider.c
(camel_provider_module_init): Added POPB4SMTP auth type.
* camel-sasl.c (camel_sasl_authtype): Added POPB4SMTP type.
* camel-sasl-popb4smtp.c: New file for pop before smtp
'authentication'.
* Makefile.am (libcamel_la_SOURCES, HEADERS): Add
camel-sasl-popb4smtp.[ch].
svn path=/trunk/; revision=11615
Diffstat (limited to 'camel/camel-sasl-popb4smtp.c')
-rw-r--r-- | camel/camel-sasl-popb4smtp.c | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/camel/camel-sasl-popb4smtp.c b/camel/camel-sasl-popb4smtp.c new file mode 100644 index 0000000000..7acd8e385c --- /dev/null +++ b/camel/camel-sasl-popb4smtp.c @@ -0,0 +1,155 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Michael Zucchi <notzed@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 <time.h> +#include "camel-sasl-popb4smtp.h" +#include "camel-service.h" +#include "camel-session.h" + +CamelServiceAuthType camel_sasl_popb4smtp_authtype = { + N_("POP before SMTP"), + + N_("This option will authorise a POP connection before attempting SMTP"), + + "POPB4SMTP", + FALSE, +}; + +/* last time the pop was accessed (through the auth method anyway), *time_t */ +static GHashTable *poplast; + +/* use 1 hour as our pop timeout */ +#define POPB4SMTP_TIMEOUT (60*60) + +#ifdef ENABLE_THREADS +#include <pthread.h> +static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +#define POPB4SMTP_LOCK(l) pthread_mutex_lock(&l) +#define POPB4SMTP_UNLOCK(l) pthread_mutex_unlock(&l) +#else +#define POPB4SMTP_LOCK(l) +#define POPB4SMTP_UNLOCK(l) +#endif + +static CamelSaslClass *parent_class = NULL; + +/* Returns the class for a CamelSaslPOPB4SMTP */ +#define CSP_CLASS(so) CAMEL_SASL_POPB4SMTP_CLASS (CAMEL_OBJECT_GET_CLASS (so)) + +static GByteArray *popb4smtp_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex); + +static void +camel_sasl_popb4smtp_class_init (CamelSaslPOPB4SMTPClass *camel_sasl_popb4smtp_class) +{ + CamelSaslClass *camel_sasl_class = CAMEL_SASL_CLASS (camel_sasl_popb4smtp_class); + + parent_class = CAMEL_SASL_CLASS (camel_type_get_global_classfuncs (camel_sasl_get_type ())); + + /* virtual method overload */ + camel_sasl_class->challenge = popb4smtp_challenge; + + poplast = g_hash_table_new(g_str_hash, g_str_equal); +} + +CamelType +camel_sasl_popb4smtp_get_type (void) +{ + static CamelType type = CAMEL_INVALID_TYPE; + + if (type == CAMEL_INVALID_TYPE) { + type = camel_type_register (camel_sasl_get_type (), + "CamelSaslPOPB4SMTP", + sizeof (CamelSaslPOPB4SMTP), + sizeof (CamelSaslPOPB4SMTPClass), + (CamelObjectClassInitFunc) camel_sasl_popb4smtp_class_init, + NULL, + NULL, + NULL); + } + + return type; +} + +static GByteArray * +popb4smtp_challenge (CamelSasl *sasl, GByteArray *token, CamelException *ex) +{ + char *popuri; + CamelSession *session = sasl->service->session; + CamelStore *store; + time_t now, *timep; + + sasl->authenticated = FALSE; + + popuri = camel_session_get_password(session, _("POP Source URI"), FALSE, + sasl->service, "popb4smtp_uri", ex); + + if (popuri == NULL) { + camel_exception_setv(ex, 1, _("POP Before SMTP auth using an unknown transport")); + return NULL; + } + + if (strncasecmp(popuri, "pop:", 4) != 0) { + camel_exception_setv(ex, 1, _("POP Before SMTP auth using a non-pop source")); + return NULL; + } + + /* check if we've done it before recently in this session */ + now = time(0); + + /* need to lock around the whole thing until finished with timep */ + + POPB4SMTP_LOCK(lock); + timep = g_hash_table_lookup(poplast, popuri); + if (timep) { + if ((*timep + POPB4SMTP_TIMEOUT) > now) { + sasl->authenticated = TRUE; + POPB4SMTP_UNLOCK(lock); + g_free(popuri); + return NULL; + } + } else { + timep = g_malloc0(sizeof(*timep)); + g_hash_table_insert(poplast, g_strdup(popuri), timep); + } + + /* connect to pop session */ + store = camel_session_get_store(session, popuri, ex); + if (store) { + sasl->authenticated = TRUE; + camel_object_unref((CamelObject *)store); + *timep = now; + } else { + sasl->authenticated = FALSE; + *timep = 0; + } + + POPB4SMTP_UNLOCK(lock); + + g_free(popuri); + + return NULL; +} |