diff options
author | Dan Winship <danw@src.gnome.org> | 2000-05-04 23:23:43 +0800 |
---|---|---|
committer | Dan Winship <danw@src.gnome.org> | 2000-05-04 23:23:43 +0800 |
commit | ba6b73fe56390dc752b43443701073fff7289709 (patch) | |
tree | dbcb834a29a525587107981b0883f486b9141f8d /camel/providers/pop3 | |
parent | 929f89ce1c6fd86370839283e467127c2a1be3f6 (diff) | |
download | gsoc2013-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.am | 4 | ||||
-rw-r--r-- | camel/providers/pop3/camel-pop3-store.c | 133 |
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); |