From ba6b73fe56390dc752b43443701073fff7289709 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 4 May 2000 15:23:43 +0000 Subject: 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 --- camel/providers/pop3/Makefile.am | 4 +- camel/providers/pop3/camel-pop3-store.c | 133 ++++++++++++++++++++++++++-- camel/providers/smtp/camel-smtp-transport.c | 40 ++++++--- 3 files changed, 157 insertions(+), 20 deletions(-) (limited to 'camel/providers') 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 +#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); diff --git a/camel/providers/smtp/camel-smtp-transport.c b/camel/providers/smtp/camel-smtp-transport.c index cc57e29b1d..992948560e 100644 --- a/camel/providers/smtp/camel-smtp-transport.c +++ b/camel/providers/smtp/camel-smtp-transport.c @@ -57,7 +57,7 @@ static gboolean _send_to (CamelTransport *transport, CamelMedium *message, GList static gboolean smtp_connect (CamelService *service, CamelException *ex); static gboolean smtp_disconnect (CamelService *service, CamelException *ex); static GList *esmtp_get_authtypes(gchar *buffer); -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 gchar *smtp_get_email_addr_from_text (gchar *text); static gboolean smtp_helo (CamelSmtpTransport *transport, CamelException *ex); @@ -89,6 +89,14 @@ camel_smtp_transport_class_init (CamelSmtpTransportClass *camel_smtp_transport_c camel_transport_class->send_to = _send_to; } +static void +camel_smtp_transport_init (gpointer object, gpointer klass) +{ + CamelService *service = CAMEL_SERVICE (object); + + service->url_flags = CAMEL_SERVICE_URL_NEED_HOST; +} + GtkType camel_smtp_transport_get_type (void) { @@ -101,7 +109,7 @@ camel_smtp_transport_get_type (void) sizeof (CamelSmtpTransport), sizeof (CamelSmtpTransportClass), (GtkClassInitFunc) camel_smtp_transport_class_init, - (GtkObjectInitFunc) NULL, + (GtkObjectInitFunc) camel_smtp_transport_init, /* reserved_1 */ NULL, /* reserved_2 */ NULL, (GtkClassInitFunc) NULL, @@ -209,23 +217,35 @@ static GList return ret; } -static CamelServiceAuthType password_authtype = { - "Password/CRAM-MD5", +static CamelServiceAuthType no_authtype = { + "No authentication required", - "This option will connect to the ESMTP server using the CRAM-MD5 " - "authentication if possible.", + "This option will connect to the SMTP server without using any " + "kind of authentication. This should be fine for connecting to " + "most SMTP servers." "", + FALSE +}; + +static CamelServiceAuthType cram_md5_authtype = { + "CRAM-MD5", + + "This option will connect to the SMTP server using CRAM-MD5 " + "authentication.", + + "CRAM-MD5", TRUE }; static GList -*query_auth_types (CamelService *service) +*query_auth_types (CamelService *service, CamelException *ex) { - GList *ret; + /* FIXME: Re-enable this when auth types are actually + * implemented. + */ - ret = g_list_append (NULL, &password_authtype); - return ret; + return NULL; } static void -- cgit v1.2.3