summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Roessler <roessler@does-not-exist.org>2001-05-29 20:26:21 +0000
committerThomas Roessler <roessler@does-not-exist.org>2001-05-29 20:26:21 +0000
commitfeab97555dcb12a4f1579d9dc29f53b6318b6188 (patch)
tree392120f8ccadd540eb13b5b372ae508054dfc4af
parentd4eef53ca2c3f215b8457f71cb3b597d2cbf78b4 (diff)
GSSAPI fixes, tunnel driver. From Brendan Cully.
-rw-r--r--Makefile.am12
-rw-r--r--README2
-rw-r--r--configure.in91
-rw-r--r--globals.h1
-rw-r--r--imap/auth.c2
-rw-r--r--imap/auth_gss.c121
-rw-r--r--imap/auth_sasl.c3
-rw-r--r--imap/imap.c1
-rw-r--r--init.h16
-rw-r--r--m4/gssapi.m473
-rw-r--r--mutt_socket.c25
-rw-r--r--mutt_socket.h3
-rw-r--r--mutt_tunnel.c111
-rw-r--r--mutt_tunnel.h24
14 files changed, 347 insertions, 138 deletions
diff --git a/Makefile.am b/Makefile.am
index 66cd7f9f..5565fd82 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -68,17 +68,17 @@ non_us_sources = pgp.c pgpinvoke.c pgpkey.c pgplib.c sha1.c \
pgppacket.c pgppacket.h
EXTRA_mutt_SOURCES = account.c md5c.c mutt_sasl.c mutt_socket.c mutt_ssl.c \
- pop.c pop_auth.c pop_lib.c pgp.c pgpinvoke.c pgpkey.c pgplib.c \
- sha1.c pgpmicalg.c gnupgparse.c resize.c dotlock.c remailer.c browser.h mbyte.h \
- remailer.h url.h mutt_ssl_nss.c pgppacket.c
+ mutt_tunnel.c pop.c pop_auth.c pop_lib.c pgp.c pgpinvoke.c pgpkey.c \
+ pgplib.c sha1.c pgpmicalg.c gnupgparse.c resize.c dotlock.c remailer.c \
+ browser.h mbyte.h remailer.h url.h mutt_ssl_nss.c pgppacket.c
EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP TODO configure acconfig.h account.h \
attach.h buffy.h charset.h copy.h dotlock.h functions.h gen_defs \
globals.h hash.h history.h init.h keymap.h \
mailbox.h mapping.h md5.h mime.h mutt.h mutt_curses.h mutt_menu.h \
- mutt_regex.h mutt_sasl.h mutt_socket.h mutt_ssl.h mx.h pager.h \
- pgp.h pop.h protos.h reldate.h rfc1524.h rfc2047.h rfc2231.h \
- rfc822.h sha1.h sort.h mime.types VERSION prepare \
+ mutt_regex.h mutt_sasl.h mutt_socket.h mutt_ssl.h mutt_tunnel.h \
+ mx.h pager.h pgp.h pop.h protos.h reldate.h rfc1524.h rfc2047.h \
+ rfc2231.h rfc822.h sha1.h sort.h mime.types VERSION prepare \
_regex.h OPS.MIX README.SECURITY remailer.c remailer.h browser.h \
mbyte.h lib.h extlib.c pgpewrap pgplib.h Muttrc.head Muttrc \
makedoc.c stamp-doc-rc README.SSL README.UPGRADE \
diff --git a/README b/README
index 3be608ee..74c8e0ae 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-README for mutt-1.1
+README for mutt-1.3
===================
If you got the mutt source code from the public CVS repository (CVS
diff --git a/configure.in b/configure.in
index f5df4041..d3e0e54a 100644
--- a/configure.in
+++ b/configure.in
@@ -590,72 +590,37 @@ then
AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt))
AC_CHECK_FUNCS(getaddrinfo)
AC_DEFINE(USE_SOCKET)
- MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS account.o mutt_socket.o"
+ MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS account.o mutt_socket.o mutt_tunnel.o"
fi
dnl -- imap dependencies --
-AC_ARG_WITH(gss, [ --with-gss[=DIR] Compile in GSSAPI authentication for IMAP],
- [
- if test "$need_imap" != "yes"
- then
- AC_MSG_ERROR([GSS support is only for IMAP, but IMAP is not enabled])
- fi
-
- if test "$with_gss" != "no"
- then
- if test "$with_gss" != "yes"
- then
- CPPFLAGS="$CPPFLAGS -I$with_gss/include"
- LDFLAGS="$LDFLAGS -L$with_gss/lib"
- fi
-
- saved_LIBS="$LIBS"
- gss_type="none"
-
- dnl New MIT kerberos V support
- AC_CHECK_LIB(gssapi_krb5, gss_init_sec_context, [
- gss_type="MIT",
- MUTTLIBS="$MUTTLIBS -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err"
- ],, -lkrb5 -lk5crypto -lcom_err)
-
- dnl Heimdal kerberos V support
- if test x$gss_type = xnone
- then
- AC_CHECK_LIB(gssapi, gss_init_sec_context, [
- gss_type="Heimdal",
- MUTTLIBS="$MUTTLIBS -lgssapi -lkrb5 -ldes -lasn1 -lroken"
- MUTTLIBS="$MUTTLIBS -lcrypt -lcom_err"
- AC_DEFINE(HAVE_HEIMDAL)
- ],, -lkrb5 -ldes -lasn1 -lroken -lcrypt -lcom_err)
- fi
-
- dnl Old MIT Kerberos V
- dnl Note: older krb5 distributions use -lcrypto instead of
- dnl -lk5crypto, which collides with OpenSSL. One way of dealing
- dnl with that is to extract all objects from krb5's libcrypto
- dnl and from openssl's libcrypto into the same directory, then
- dnl to create a new libcrypto from these.
- if test x$gss_type = xnone
- then
- AC_CHECK_LIB(gssapi_krb5, g_order_init, [
- gss_type="OldMIT",
- MUTTLIBS="$MUTTLIBS -lgssapi_krb5 -lkrb5 -lcrypto -lcom_err"
- ],, -lkrb5 -lcrypto -lcom_err)
- fi
-
- if test x$gss_type = xnone
- then
- AC_CACHE_SAVE
- AC_MSG_ERROR([GSSAPI support not found])
- fi
-
- LIBS="$saved_LIBS"
- AC_DEFINE(USE_GSS)
- need_gss="yes"
- fi
-
-])
+AC_ARG_WITH(gss, [ --with-gss[=PFX] Compile in GSSAPI authentication for IMAP],
+ gss_prefix="$withval", gss_prefix="no")
+if test "$gss_prefix" != "no"
+then
+ if test "$need_imap" = "yes"
+ then
+ MUTT_AM_PATH_GSSAPI(gss_prefix)
+ AC_MSG_CHECKING(GSSAPI implementation)
+ AC_MSG_RESULT($GSSAPI_IMPL)
+ if test "$GSSAPI_IMPL" = "none"
+ then
+ AC_CACHE_SAVE
+ AC_MSG_RESULT([GSSAPI libraries not found])
+ fi
+ if test "$GSSAPI_IMPL" = "Heimdal"
+ then
+ AC_DEFINE(HAVE_HEIMDAL, 1, [ Define if your GSSAPI implementation is Heimdal ])
+ fi
+ CPPFLAGS="$CPPFLAGS $GSSAPI_CFLAGS"
+ MUTTLIBS="$MUTTLIBS $GSSAPI_LIBS"
+ AC_DEFINE(USE_GSS, 1, [ Define if you have GSSAPI libraries available ])
+ need_gss="yes"
+ else
+ AC_MSG_WARN([GSS was requested but IMAP is not enabled])
+ fi
+fi
AM_CONDITIONAL(USE_GSS, test x$need_gss = xyes)
AC_ARG_WITH(ssl, [ --with-ssl[=PFX] Compile in SSL support for POP/IMAP],
@@ -717,7 +682,7 @@ AC_ARG_WITH(nss, [ --with-nss[=PFX] Compile in SSL support for POP/IM
dnl -- end imap dependencies --
-AC_ARG_WITH(sasl, [ --with-sasl[=DIR] Use Cyrus SASL library for POP/IMAP authentication],
+AC_ARG_WITH(sasl, [ --with-sasl[=PFX] Use Cyrus SASL library for POP/IMAP authentication],
[
if test "$need_socket" != "yes"
then
diff --git a/globals.h b/globals.h
index 1888d446..874b6d88 100644
--- a/globals.h
+++ b/globals.h
@@ -64,6 +64,7 @@ WHERE char *MsgFmt;
#ifdef USE_SOCKET
WHERE char *Preconnect INITVAL (NULL);
+WHERE char *Tunnel INITVAL (NULL);
#endif /* USE_SOCKET */
#ifdef MIXMASTER
diff --git a/imap/auth.c b/imap/auth.c
index 97ac5d12..e7c3661d 100644
--- a/imap/auth.c
+++ b/imap/auth.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
* Copyright (C) 1996-9 Brandon Long <blong@fiction.net>
- * Copyright (C) 1999-2000 Brendan Cully <brendan@kublai.com>
+ * Copyright (C) 1999-2001 Brendan Cully <brendan@kublai.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
diff --git a/imap/auth_gss.c b/imap/auth_gss.c
index a269230c..cfd7d2ad 100644
--- a/imap/auth_gss.c
+++ b/imap/auth_gss.c
@@ -83,6 +83,23 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
maj_stat = gss_release_buffer (&min_stat, &request_buf);
}
#endif
+ /* Acquire initial credentials - without a TGT GSSAPI is UNAVAIL */
+ sec_token = GSS_C_NO_BUFFER;
+ context = GSS_C_NO_CONTEXT;
+
+ /* build token */
+ maj_stat = gss_init_sec_context (&min_stat, GSS_C_NO_CREDENTIAL, &context,
+ target_name, GSS_C_NO_OID, GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG, 0,
+ GSS_C_NO_CHANNEL_BINDINGS, sec_token, NULL, &send_token,
+ (unsigned int*) &cflags, NULL);
+ if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
+ {
+ dprint (1, (debugfile, "Error acquiring credentials - no TGT?\n"));
+ gss_release_name (&min_stat, &target_name);
+
+ return IMAP_AUTH_UNAVAIL;
+ }
+
/* now begin login */
mutt_message _("Authenticating (GSSAPI)...");
@@ -102,62 +119,48 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
/* now start the security context initialisation loop... */
dprint (2, (debugfile, "Sending credentials\n"));
- sec_token = GSS_C_NO_BUFFER;
- context = GSS_C_NO_CONTEXT;
- do
+ mutt_to_base64 ((unsigned char*) buf1, send_token.value, send_token.length,
+ sizeof (buf1) - 2);
+ gss_release_buffer (&min_stat, &send_token);
+ strncat (buf1, "\r\n", sizeof (buf1));
+ mutt_socket_write (idata->conn, buf1);
+
+ while (maj_stat == GSS_S_CONTINUE_NEEDED)
{
- /* build token */
- maj_stat = gss_init_sec_context (&min_stat,
- GSS_C_NO_CREDENTIAL,
- &context,
- target_name,
- GSS_C_NO_OID,
- GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG,
- 0,
- GSS_C_NO_CHANNEL_BINDINGS,
- sec_token,
- NULL,
- &send_token,
- (unsigned int*) &cflags,
- NULL);
- if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
+ /* Read server data */
+ do
+ rc = imap_cmd_step (idata);
+ while (rc == IMAP_CMD_CONTINUE);
+
+ if (rc != IMAP_CMD_RESPOND)
{
- dprint (1, (debugfile, "Error exchanging credentials\n"));
+ dprint (1, (debugfile, "Error receiving server response.\n"));
gss_release_name (&min_stat, &target_name);
- /* end authentication attempt */
- mutt_socket_write (idata->conn, "*\r\n");
- do
- rc = imap_cmd_step (idata);
- while (rc == IMAP_CMD_CONTINUE);
goto bail;
}
- /* send token */
+ request_buf.length = mutt_from_base64 (buf2, idata->cmd.buf + 2);
+ request_buf.value = buf2;
+ sec_token = &request_buf;
+
+ /* Write client data */
+ maj_stat = gss_init_sec_context (&min_stat, GSS_C_NO_CREDENTIAL, &context,
+ target_name, GSS_C_NO_OID, GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG, 0,
+ GSS_C_NO_CHANNEL_BINDINGS, sec_token, NULL, &send_token,
+ (unsigned int*) &cflags, NULL);
+ if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
+ {
+ dprint (1, (debugfile, "Error exchanging credentials\n"));
+ gss_release_name (&min_stat, &target_name);
+
+ goto err_abort_cmd;
+ }
mutt_to_base64 ((unsigned char*) buf1, send_token.value,
send_token.length, sizeof (buf1) - 2);
gss_release_buffer (&min_stat, &send_token);
strncat (buf1, "\r\n", sizeof (buf1));
mutt_socket_write (idata->conn, buf1);
-
- if (maj_stat == GSS_S_CONTINUE_NEEDED)
- {
- do
- rc = imap_cmd_step (idata);
- while (rc == IMAP_CMD_CONTINUE);
-
- if (rc != IMAP_CMD_RESPOND)
- {
- dprint (1, (debugfile, "Error receiving server response.\n"));
- gss_release_name (&min_stat, &target_name);
- goto bail;
- }
-
- request_buf.length = mutt_from_base64 (buf2, idata->cmd.buf + 2);
- request_buf.value = buf2;
- sec_token = &request_buf;
- }
}
- while (maj_stat == GSS_S_CONTINUE_NEEDED);
gss_release_name (&min_stat, &target_name);
@@ -180,8 +183,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
{
dprint (2, (debugfile, "Couldn't unwrap security level data\n"));
gss_release_buffer (&min_stat, &send_token);
- mutt_socket_write(idata->conn, "*\r\n");
- goto bail;
+ goto err_abort_cmd;
}
dprint (2, (debugfile, "Credential exchange complete\n"));
@@ -189,10 +191,9 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
server_conf_flags = ((char*) send_token.value)[0];
if ( !(((char*) send_token.value)[0] & GSS_AUTH_P_NONE) )
{
- dprint (2, (debugfile, "Server requires integrity or privace\n"));
+ dprint (2, (debugfile, "Server requires integrity or privacy\n"));
gss_release_buffer (&min_stat, &send_token);
- mutt_socket_write(idata->conn, "*\r\n");
- goto bail;
+ goto err_abort_cmd;
}
/* we don't care about buffer size if we don't wrap content. But here it is */
@@ -218,8 +219,7 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
if (maj_stat != GSS_S_COMPLETE)
{
dprint (2, (debugfile, "Error creating login request\n"));
- mutt_socket_write(idata->conn, "*\r\n");
- goto bail;
+ goto err_abort_cmd;
}
mutt_to_base64 ((unsigned char*) buf1, send_token.value, send_token.length,
@@ -233,11 +233,10 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
do
rc = imap_cmd_step (idata);
while (rc == IMAP_CMD_CONTINUE);
- if (rc != IMAP_CMD_OK)
+ if (rc == IMAP_CMD_RESPOND)
{
- dprint (1, (debugfile, "Error receiving server response.\n"));
- mutt_socket_write(idata->conn, "*\r\n");
- goto bail;
+ dprint (1, (debugfile, "Unexpected server continuation request.\n"));
+ goto err_abort_cmd;
}
if (imap_code (idata->cmd.buf))
{
@@ -245,10 +244,8 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
dprint (2, (debugfile, "Releasing GSS credentials\n"));
maj_stat = gss_delete_sec_context (&min_stat, &context, &send_token);
if (maj_stat != GSS_S_COMPLETE)
- {
dprint (1, (debugfile, "Error releasing credentials\n"));
- goto bail;
- }
+
/* send_token may contain a notification to the server to flush
* credentials. RFC 1731 doesn't specify what to do, and since this
* support is only for authentication, we'll assume the server knows
@@ -257,6 +254,14 @@ imap_auth_res_t imap_auth_gss (IMAP_DATA* idata)
return IMAP_AUTH_SUCCESS;
}
+ else
+ goto bail;
+
+ err_abort_cmd:
+ mutt_socket_write (idata->conn, "*\r\n");
+ do
+ rc = imap_cmd_step (idata);
+ while (rc == IMAP_CMD_CONTINUE);
bail:
mutt_error _("GSSAPI authentication failed.");
diff --git a/imap/auth_sasl.c b/imap/auth_sasl.c
index 7eb78131..640e434f 100644
--- a/imap/auth_sasl.c
+++ b/imap/auth_sasl.c
@@ -110,6 +110,7 @@ imap_auth_res_t imap_auth_sasl (IMAP_DATA* idata)
}
if (!client_start)
+ {
do
{
rc = sasl_client_step (saslconn, buf, len, &interaction, &pc, &olen);
@@ -117,6 +118,7 @@ imap_auth_res_t imap_auth_sasl (IMAP_DATA* idata)
mutt_sasl_interact (interaction);
}
while (rc == SASL_INTERACT);
+ }
else
client_start = 0;
@@ -144,6 +146,7 @@ imap_auth_res_t imap_auth_sasl (IMAP_DATA* idata)
if (rc < 0)
{
mutt_socket_write (idata->conn, "*\r\n");
+ dprint (1, (debugfile, "imap_auth_sasl: sasl_client_step error %d\n",rc));
}
}
diff --git a/imap/imap.c b/imap/imap.c
index 8f911dc3..7d9c9d77 100644
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -66,7 +66,6 @@ int imap_access (const char* path, int flags)
FREE (&mx.mbox);
return -1;
}
-
imap_fix_path (idata, mx.mbox, mailbox, sizeof (mailbox));
FREE (&mx.mbox);
diff --git a/init.h b/init.h
index 915606b7..9300057a 100644
--- a/init.h
+++ b/init.h
@@ -1492,7 +1492,7 @@ struct option_t MuttVars[] = {
** .pp
** Mutt allows you to indefinitely ``$postpone sending a message'' which
** you are editing. When you choose to postpone a message, Mutt saves it
- ** in the mail folder specified by this variable. Also see the ``$$postpone''
+ ** in the mailbox specified by this variable. Also see the ``$$postpone''
** variable.
*/
#ifdef USE_SOCKET
@@ -2128,6 +2128,20 @@ struct option_t MuttVars[] = {
** by \fIyou\fP. The sixth character is used to indicate when a mail
** was sent to a mailing-list you subscribe to (default: L).
*/
+#ifdef USE_SOCKET
+ { "tunnel", DT_STR, R_NONE, UL &Tunnel, UL 0 },
+ /*
+ ** .pp
+ ** Setting this variable will cause mutt to open a pipe to a command
+ ** instead of a raw socket. You may be able to use this to set up
+ ** preauthenticated connections to your IMAP/POP3 server. Example:
+ ** .pp
+ ** tunnel="ssh -q mailhost.net /usr/local/libexec/imapd"
+ ** .pp
+ ** NOTE: For this example to work you must be able to log in to the remote
+ ** machine without having to enter a password.
+ */
+#endif
{ "use_8bitmime", DT_BOOL, R_NONE, OPTUSE8BITMIME, 0 },
/*
** .pp
diff --git a/m4/gssapi.m4 b/m4/gssapi.m4
new file mode 100644
index 00000000..31382157
--- /dev/null
+++ b/m4/gssapi.m4
@@ -0,0 +1,73 @@
+# gssapi.m4: Find GSSAPI libraries in either Heimdal or MIT implementations
+# Brendan Cully <brendan@kublai.com> 20010529
+
+dnl MUTT_AM_PATH_GSSAPI(PREFIX)
+dnl Search for a GSSAPI implementation in the standard locations plus PREFIX,
+dnl if it is set and not "yes".
+dnl Defines GSSAPI_CFLAGS and GSSAPI_LIBS if found.
+dnl Defines GSSAPI_IMPL to "Heimdal", "MIT", or "OldMIT", or "none" if not found
+AC_DEFUN(MUTT_AM_PATH_GSSAPI,
+[
+ GSSAPI_PREFIX=[$]$1
+ GSSAPI_IMPL="none"
+ dnl First try krb5-config
+ if test "$GSSAPI_PREFIX" != "yes"
+ then
+ krb5_path="$GSSAPI_PREFIX/bin"
+ else
+ krb5_path="$PATH"
+ fi
+ AC_PATH_PROG(KRB5CFGPATH, krb5-config, none, $krb5_path)
+ if test "$KRB5CFGPATH" != "none"
+ then
+ GSSAPI_CFLAGS="$CPPFLAGS `$KRB5CFGPATH --cflags gssapi`"
+ GSSAPI_LIBS="$MUTTLIBS `$KRB5CFGPATH --libs gssapi`"
+ GSSAPI_IMPL="Heimdal"
+ else
+ dnl No krb5-config, run the old code
+ saved_CPPFLAGS="$CPPFLAGS"
+ saved_LDFLAGS="$LDFLAGS"
+ saved_LIBS="$LIBS"
+ if test "$GSSAPI_PREFIX" != "yes"
+ then
+ GSSAPI_CFLAGS="-I$GSSAPI_PREFIX/include"
+ GSSAPI_LDFLAGS="-L$GSSAPI_PREFIX/lib"
+ CPPFLAGS="$CPPFLAGS $GSSAPI_CFLAGS"
+ LDFLAGS="$LDFLAGS $GSSAPI_LDFLAGS"
+ fi
+
+ dnl New MIT kerberos V support
+ AC_CHECK_LIB(gssapi_krb5, gss_init_sec_context, [
+ GSSAPI_IMPL="MIT",
+ GSSAPI_LIBS="$GSSAPI_LDFLAGS -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err"
+ ],, -lkrb5 -lk5crypto -lcom_err)
+
+ dnl Heimdal kerberos V support
+ if test "$GSSAPI_IMPL" = "none"
+ then
+ AC_CHECK_LIB(gssapi, gss_init_sec_context, [
+ GSSAPI_IMPL="Heimdal"
+ GSSAPI_LIBS="$GSSAPI_LDFLAGS -lgssapi -lkrb5 -ldes -lasn1 -lroken"
+ GSSAPI_LIBS="$GSSAPI_LIBS -lcrypt -lcom_err"
+ ],, -lkrb5 -ldes -lasn1 -lroken -lcrypt -lcom_err)
+ fi
+
+ dnl Old MIT Kerberos V
+ dnl Note: older krb5 distributions use -lcrypto instead of
+ dnl -lk5crypto, which collides with OpenSSL. One way of dealing
+ dnl with that is to extract all objects from krb5's libcrypto
+ dnl and from openssl's libcrypto into the same directory, then
+ dnl to create a new libcrypto from these.
+ if test "$GSSAPI_IMPL" = "none"
+ then
+ AC_CHECK_LIB(gssapi_krb5, g_order_init, [
+ GSSAPI_IMPL="OldMIT",
+ GSSAPI_LIBS="$GSSAPI_LDFLAGS -lgssapi_krb5 -lkrb5 -lcrypto -lcom_err"
+ ],, -lkrb5 -lcrypto -lcom_err)
+ fi
+ fi
+
+ CPPFLAGS="$saved_CPPFLAGS"
+ LDFLAGS="$saved_LDFLAGS"
+ LIBS="$saved_LIBS"
+]) \ No newline at end of file
diff --git a/mutt_socket.c b/mutt_socket.c
index 44771459..f00e09f1 100644
--- a/mutt_socket.c
+++ b/mutt_socket.c
@@ -21,6 +21,7 @@
#include "mutt.h"
#include "globals.h"
#include "mutt_socket.h"
+#include "mutt_tunnel.h"
#ifdef USE_SSL
# include "mutt_ssl.h"
#endif
@@ -201,7 +202,9 @@ CONNECTION* mutt_conn_find (const CONNECTION* start, const ACCOUNT* account)
conn->next = Connections;
Connections = conn;
- if (account->flags & M_ACCT_SSL)
+ if (Tunnel && *Tunnel)
+ mutt_tunnel_socket_setup (conn);
+ else if (account->flags & M_ACCT_SSL)
{
#ifdef USE_SSL
ssl_socket_setup (conn);
@@ -226,16 +229,11 @@ CONNECTION* mutt_conn_find (const CONNECTION* start, const ACCOUNT* account)
return conn;
}
-/* socket_connect: set up to connect to a socket fd. Preconnect goes here. */
-static int socket_connect (int fd, struct sockaddr* sa)
+int mutt_socket_preconnect (void)
{
- int sa_size;
int rc;
int save_errno;
- /* old first_try_without_preconnect removed for now. unset $preconnect
- first. */
-
if (mutt_strlen (Preconnect))
{
dprint (1, (debugfile, "Executing preconnect: %s\n", Preconnect));
@@ -251,6 +249,19 @@ static int socket_connect (int fd, struct sockaddr* sa)
}
}
+ return 0;
+}
+
+/* socket_connect: set up to connect to a socket fd. */
+static int socket_connect (int fd, struct sockaddr* sa)
+{
+ int sa_size;
+ int rc;
+ int save_errno;
+
+ if ((rc = mutt_socket_preconnect ()))
+ return rc;
+
if (sa->sa_family == AF_INET)
sa_size = sizeof (struct sockaddr_in);
#ifdef HAVE_GETADDRINFO
diff --git a/mutt_socket.h b/mutt_socket.h
index b20767da..e508ee31 100644
--- a/mutt_socket.h
+++ b/mutt_socket.h
@@ -63,6 +63,9 @@ CONNECTION* mutt_socket_head (void);
void mutt_socket_free (CONNECTION* conn);
CONNECTION* mutt_conn_find (const CONNECTION* start, const ACCOUNT* account);
+/* other methods may call this to try preconnect code */
+int mutt_socket_preconnect (void);
+
int raw_socket_read (CONNECTION *conn);
int raw_socket_write (CONNECTION* conn, const char* buf, size_t count);
int raw_socket_open (CONNECTION *conn);
diff --git a/mutt_tunnel.c b/mutt_tunnel.c
new file mode 100644
index 00000000..0f26e6e7
--- /dev/null
+++ b/mutt_tunnel.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2000 Manoj Kasichainula <manoj@io.com>
+ * Copyright (C) 2001 Brendan Cully <brendan@kublai.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 Place - Suite 330, Boston, MA 02111, USA.
+ */
+
+#include "mutt.h"
+#include "mutt_socket.h"
+#include "mutt_tunnel.h"
+
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+/* -- data types -- */
+typedef struct
+{
+ pid_t pid;
+} TUNNEL_DATA;
+
+/* forward declarations */
+static int tunnel_socket_open (CONNECTION*);
+static int tunnel_socket_close (CONNECTION*);
+
+/* -- public functions -- */
+int mutt_tunnel_socket_setup (CONNECTION *conn)
+{
+ conn->open = tunnel_socket_open;
+ conn->read = raw_socket_read;
+ conn->write = raw_socket_write;
+ conn->close = tunnel_socket_close;
+
+ return 0;
+}
+
+static int tunnel_socket_open (CONNECTION *conn)
+{
+ TUNNEL_DATA* tunnel;
+ int pid;
+ int rc;
+ int sv[2];
+
+ mutt_message (_("Connecting with \"%s\"..."), Tunnel);
+
+ if ((rc = mutt_socket_preconnect ()))
+ return rc;
+
+ rc = socketpair (PF_UNIX, SOCK_STREAM, IPPROTO_IP, sv);
+ if (rc == -1)
+ {
+ mutt_perror ("socketpair");
+ return -1;
+ }
+
+ if ((pid = fork ()) == 0)
+ {
+ mutt_block_signals_system ();
+ if (close (sv[0]) < 0 ||
+ dup2 (sv[1], STDIN_FILENO) < 0 ||
+ dup2 (sv[1], STDOUT_FILENO) < 0 ||
+ close (sv[1]) < 0)
+ _exit (127);
+
+ execl (EXECSHELL, "sh", "-c", Tunnel, NULL);
+ _exit (127);
+ }
+ if (pid == -1)
+ {
+ close (sv[0]);
+ close (sv[1]);
+ mutt_perror ("fork");
+ return -1;
+ }
+ if (close(sv[1]) < 0)
+ mutt_perror ("close");
+
+ conn->fd = sv[0];
+ tunnel = (TUNNEL_DATA*) safe_malloc (sizeof (TUNNEL_DATA));
+ tunnel->pid = pid;
+
+ return 0;
+}
+
+static int tunnel_socket_close (CONNECTION* conn)
+{
+ TUNNEL_DATA* tunnel = (TUNNEL_DATA*) conn->data;
+
+ if (!tunnel)
+ return 0;
+
+ waitpid (tunnel->pid, NULL, 0);
+ close (conn->fd);
+ conn->fd = -1;
+ FREE (&conn->data);
+
+ return 0;
+}
diff --git a/mutt_tunnel.h b/mutt_tunnel.h
new file mode 100644
index 00000000..b6e20afd
--- /dev/null
+++ b/mutt_tunnel.h
@@ -0,0 +1,24 @@
+/*
+ * 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 Place - Suite 330, Boston, MA 02111, USA.
+ */
+
+#ifndef _MUTT_TUNNEL_H_
+#define _MUTT_TUNNEL_H_ 1
+
+#include "mutt_socket.h"
+
+int mutt_tunnel_socket_setup (CONNECTION *);
+
+#endif /* _MUTT_TUNNEL_H_ */