aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/pop3
diff options
context:
space:
mode:
authorDan Winship <danw@src.gnome.org>2000-05-04 23:23:43 +0800
committerDan Winship <danw@src.gnome.org>2000-05-04 23:23:43 +0800
commitba6b73fe56390dc752b43443701073fff7289709 (patch)
treedbcb834a29a525587107981b0883f486b9141f8d /camel/providers/pop3
parent929f89ce1c6fd86370839283e467127c2a1be3f6 (diff)
downloadgsoc2013-evolution-ba6b73fe56390dc752b43443701073fff7289709.tar.gz
gsoc2013-evolution-ba6b73fe56390dc752b43443701073fff7289709.tar.zst
gsoc2013-evolution-ba6b73fe56390dc752b43443701073fff7289709.zip
New function to replace camel_provider_scan. Returns a list of either (a)
* camel-session.c (camel_session_list_providers): New function to replace camel_provider_scan. Returns a list of either (a) all currently-loaded providers, or (b) all available providers. * camel-url.[ch]: Add an "empty" flag to CamelURL (indicating that it contains only a protocol). * camel-service.c (camel_service_query_auth_types): Make this take a CamelException (since it may have to try to connect to the server, and it might not able to.) * providers/pop3/camel-pop3-store.c: add KPOP (Kerberized POP) support. This is mostly so I have two kinds of authmech to play with instead of just one. (But it does actually work.) * providers/smtp/camel-smtp-transport.c (query_auth_types): update for prototype change, but disable the functionality, since it doesn't really support any auth types yet. (camel_smtp_transport_get_type): add an object init function to set the service url_flags. svn path=/trunk/; revision=2797
Diffstat (limited to 'camel/providers/pop3')
-rw-r--r--camel/providers/pop3/Makefile.am4
-rw-r--r--camel/providers/pop3/camel-pop3-store.c133
2 files changed, 127 insertions, 10 deletions
diff --git a/camel/providers/pop3/Makefile.am b/camel/providers/pop3/Makefile.am
index 49bb2fc254..f30d73e736 100644
--- a/camel/providers/pop3/Makefile.am
+++ b/camel/providers/pop3/Makefile.am
@@ -17,7 +17,7 @@ INCLUDES = \
-I$(top_srcdir)/intl \
$(GTK_INCLUDEDIR) \
-I$(top_srcdir)/camel \
- -I$(srcdir)/../mbox \
+ $(KRB4_CFLAGS) \
-DG_LOG_DOMAIN=\"camel-pop3-provider\"
libcamelpop3_la_SOURCES = \
@@ -30,6 +30,6 @@ libcamelpop3include_HEADERS = \
camel-pop3-store.h
-libcamelpop3_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir)
+libcamelpop3_la_LDFLAGS = $(KRB4_LDFLAGS) -version-info 0:0:0 -rpath $(libdir)
EXTRA_DIST = libcamelpop3.urls
diff --git a/camel/providers/pop3/camel-pop3-store.c b/camel/providers/pop3/camel-pop3-store.c
index 4f4410234d..eb5c77558e 100644
--- a/camel/providers/pop3/camel-pop3-store.c
+++ b/camel/providers/pop3/camel-pop3-store.c
@@ -46,13 +46,20 @@
/* Specified in RFC 1939 */
#define POP3_PORT 110
+#ifdef HAVE_KRB4
+/* Specified nowhere */
+#define KPOP_PORT 1109
+
+#include <krb.h>
+#endif
+
static CamelServiceClass *service_class = NULL;
static void finalize (GtkObject *object);
static gboolean pop3_connect (CamelService *service, CamelException *ex);
static gboolean pop3_disconnect (CamelService *service, CamelException *ex);
-static GList *query_auth_types (CamelService *service);
+static GList *query_auth_types (CamelService *service, CamelException *ex);
static void free_auth_types (CamelService *service, GList *authtypes);
static CamelFolder *get_folder (CamelStore *store, const char *folder_name,
@@ -139,7 +146,7 @@ finalize (GtkObject *object)
static CamelServiceAuthType password_authtype = {
- "Password/APOP",
+ "Password",
"This option will connect to the POP server using the APOP "
"protocol if possible, or a plaintext password if not.",
@@ -148,12 +155,78 @@ static CamelServiceAuthType password_authtype = {
TRUE
};
-static GList
-*query_auth_types (CamelService *service)
+#ifdef HAVE_KRB4
+static CamelServiceAuthType kpop_authtype = {
+ "Kerberos 4 (KPOP)",
+
+ "This will connect to the POP server and use Kerberos 4 "
+ "to authenticate to it.",
+
+ "+KPOP",
+ FALSE
+};
+
+static gboolean
+try_connect (CamelService *service, CamelException *ex)
+{
+ struct hostent *h;
+ struct sockaddr_in sin;
+ int fd;
+
+ h = camel_service_gethost (service, ex);
+ if (!h)
+ return FALSE;
+
+ sin.sin_family = h->h_addrtype;
+ if (service->url->port)
+ sin.sin_port = htons (service->url->port);
+ else
+ sin.sin_port = htons (POP3_PORT);
+ memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr));
+
+ fd = socket (h->h_addrtype, SOCK_STREAM, 0);
+ if (fd == -1 ||
+ connect (fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
+ if (fd > -1)
+ close (fd);
+ return FALSE;
+ }
+
+ close (fd);
+ return TRUE;
+}
+#endif
+
+static GList *
+query_auth_types (CamelService *service, CamelException *ex)
{
- GList *ret;
+ GList *ret = NULL;
+ gboolean passwd = TRUE;
+#ifdef HAVE_KRB4
+ gboolean kpop = TRUE;
+ int saved_port;
+#endif
+
+ if (service->url) {
+ passwd = try_connect (service, ex);
+ if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE)
+ return NULL;
+#ifdef HAVE_KRB4
+ saved_port = service->url->port;
+ service->url->port = KPOP_PORT;
+ kpop = try_connect (service, ex);
+ service->url->port = saved_port;
+ if (camel_exception_get_id (ex) != CAMEL_EXCEPTION_NONE)
+ return NULL;
+#endif
+ }
- ret = g_list_append (NULL, &password_authtype);
+ if (passwd)
+ ret = g_list_append (ret, &password_authtype);
+#ifdef HAVE_KRB4
+ if (kpop)
+ ret = g_list_append (ret, &kpop_authtype);
+#endif
return ret;
}
@@ -213,12 +286,16 @@ pop3_connect (CamelService *service, CamelException *ex)
int fd, status;
char *buf, *apoptime, *apopend;
CamelPop3Store *store = CAMEL_POP3_STORE (service);
+#ifdef HAVE_KRB4
+ gboolean kpop = (service->url->authmech &&
+ !strcmp (service->url->authmech, "+KPOP"));
+#endif
h = camel_service_gethost (service, ex);
if (!h)
return FALSE;
- if (!service->url->passwd) {
+ if (!service->url->authmech && !service->url->passwd) {
char *prompt = g_strdup_printf ("Please enter the POP3 password for %s@%s",
service->url->user, h->h_name);
service->url->passwd =
@@ -232,7 +309,15 @@ pop3_connect (CamelService *service, CamelException *ex)
}
sin.sin_family = h->h_addrtype;
- sin.sin_port = htons (service->url->port ? service->url->port : POP3_PORT);
+ if (service->url->port)
+ sin.sin_port = service->url->port;
+#ifdef HAVE_KRB4
+ else if (kpop)
+ sin.sin_port = KPOP_PORT;
+#endif
+ else
+ sin.sin_port = POP3_PORT;
+ sin.sin_port = htons (sin.sin_port);
memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr));
fd = socket (h->h_addrtype, SOCK_STREAM, 0);
@@ -247,6 +332,38 @@ pop3_connect (CamelService *service, CamelException *ex)
return FALSE;
}
+#ifdef HAVE_KRB4
+ if (kpop) {
+ KTEXT_ST ticket_st;
+ MSG_DAT msg_data;
+ CREDENTIALS cred;
+ Key_schedule schedule;
+ char *hostname;
+
+ /* Need to copy hostname, because krb_realmofhost will
+ * call gethostbyname as well, and gethostbyname uses
+ * static storage.
+ */
+ hostname = g_strdup (h->h_name);
+ status = krb_sendauth (0, fd, &ticket_st, "pop", hostname,
+ krb_realmofhost (hostname), 0,
+ &msg_data, &cred, schedule,
+ NULL, NULL, "KPOPV0.1");
+ g_free (hostname);
+ if (status != KSUCCESS) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ "Could not authenticate to KPOP "
+ "server: %s",
+ krb_err_txt[status]);
+ close (fd);
+ return FALSE;
+ }
+
+ if (!service->url->passwd)
+ service->url->passwd = g_strdup (service->url->user);
+ }
+#endif /* HAVE_KRB4 */
+
store->ostream = camel_stream_fs_new_with_fd (fd);
store->istream = camel_stream_buffer_new (store->ostream,
CAMEL_STREAM_BUFFER_READ);