PREAUTH support from Oswald Buddenhagen <ossi@kde.org>

Added Tunnel directive to allow the user to specify a shell command to run
to set up an IMAP connection in place of a TCP socket (eg., to run over
an SSH session).
This commit is contained in:
Michael Elkins 2002-04-19 19:43:00 +00:00
parent 6267139b71
commit fe438026b0
7 changed files with 630 additions and 532 deletions

View File

@ -230,6 +230,13 @@ load_config (const char *where)
else else
global.copy_deleted_to = strdup (val); global.copy_deleted_to = strdup (val);
} }
else if (!strcasecmp ("Tunnel", cmd))
{
if (*cur)
(*cur)->tunnel = strdup (val);
else
global.tunnel = strdup (val);
}
else if (!strcasecmp ("Expunge", cmd)) else if (!strcasecmp ("Expunge", cmd))
{ {
if (*cur) if (*cur)

View File

@ -1,5 +1,5 @@
AC_INIT(isync.h) AC_INIT(isync.h)
AM_INIT_AUTOMAKE(isync,0.8) AM_INIT_AUTOMAKE(isync,0.9)
AM_PROG_CC_STDC AM_PROG_CC_STDC
AC_ARG_WITH(ssl-dir, [ --with-ssl-dir=DIR location where openssl is insalled], AC_ARG_WITH(ssl-dir, [ --with-ssl-dir=DIR location where openssl is insalled],
[if test -d $withval/lib; then [if test -d $withval/lib; then

95
imap.c
View File

@ -179,7 +179,7 @@ socket_read (Socket_t * sock, char *buf, size_t len)
if (sock->use_ssl) if (sock->use_ssl)
return SSL_read (sock->ssl, buf, len); return SSL_read (sock->ssl, buf, len);
#endif #endif
return read (sock->fd, buf, len); return read (sock->rdfd, buf, len);
} }
static int static int
@ -189,7 +189,7 @@ socket_write (Socket_t * sock, char *buf, size_t len)
if (sock->use_ssl) if (sock->use_ssl)
return SSL_write (sock->ssl, buf, len); return SSL_write (sock->ssl, buf, len);
#endif #endif
return write (sock->fd, buf, len); return write (sock->wrfd, buf, len);
} }
static void static void
@ -455,8 +455,8 @@ imap_exec (imap_t * imap, const char *fmt, ...)
imap->ns_shared = parse_list (cmd, 0); imap->ns_shared = parse_list (cmd, 0);
} }
else if (!strcmp ("OK", arg) || !strcmp ("BAD", arg) || else if (!strcmp ("OK", arg) || !strcmp ("BAD", arg) ||
!strcmp ("NO", arg) || !strcmp ("PREAUTH", arg) || !strcmp ("NO", arg) || !strcmp ("BYE", arg) ||
!strcmp ("BYE", arg)) !strcmp ("PREAUTH", arg))
{ {
parse_response_code (imap, cmd); parse_response_code (imap, cmd);
} }
@ -554,13 +554,15 @@ imap_exec (imap_t * imap, const char *fmt, ...)
* mailbox. * mailbox.
*/ */
imap_t * imap_t *
imap_open (config_t * box, unsigned int minuid, imap_t * imap) imap_open (config_t * box, unsigned int minuid, imap_t * imap, int flags)
{ {
int ret; int ret;
int s; int s;
struct sockaddr_in addr; struct sockaddr_in addr;
struct hostent *he; struct hostent *he;
char *arg, *rsp;
int reuse = 0; int reuse = 0;
int preauth = 0;
#if HAVE_LIBSSL #if HAVE_LIBSSL
int use_ssl = 0; int use_ssl = 0;
#endif #endif
@ -611,6 +613,47 @@ imap_open (config_t * box, unsigned int minuid, imap_t * imap)
{ {
/* open connection to IMAP server */ /* open connection to IMAP server */
if (box->tunnel)
{
int a[2];
int b[2];
printf ("Executing: %s...", box->tunnel);
fflush (stdout);
if (pipe (a))
{
}
if (pipe (b))
{
}
if (fork () == 0)
{
if (dup2 (a[0],0))
{
_exit(127);
}
close (a[1]);
if (dup2 (b[1],1))
{
_exit (127);
}
close (b[0]);
execl ("/bin/sh","sh","-c", box->tunnel);
_exit (127);
}
close (a[0]);
close (b[1]);
imap->sock->rdfd = b[0];
imap->sock->wrfd = a[1];
puts ("ok");
}
else
{
memset (&addr, 0, sizeof (addr)); memset (&addr, 0, sizeof (addr));
addr.sin_port = htons (box->port); addr.sin_port = htons (box->port);
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
@ -639,11 +682,38 @@ imap_open (config_t * box, unsigned int minuid, imap_t * imap)
} }
puts ("ok"); puts ("ok");
imap->sock->fd = s; imap->sock->rdfd = s;
imap->sock->wrfd = s;
}
} }
do do
{ {
/* read the greeting string */
if (buffer_gets (imap->buf, &rsp))
{
puts ("Error, no greeting response");
ret = -1;
break;
}
if (Verbose)
puts (rsp);
arg = next_arg (&rsp);
if (!arg || *arg != '*' || (arg = next_arg (&rsp)) == NULL)
{
puts ("Error, invalid greeting response");
ret = -1;
break;
}
if (!strcmp ("PREAUTH", arg))
preauth = 1;
else if (strcmp ("OK", arg) != 0)
{
puts ("Error, unknown greeting response");
ret = -1;
break;
}
/* if we are reusing the existing connection, we can skip the /* if we are reusing the existing connection, we can skip the
* authentication steps. * authentication steps.
*/ */
@ -691,7 +761,7 @@ imap_open (config_t * box, unsigned int minuid, imap_t * imap)
} }
imap->sock->ssl = SSL_new (SSLContext); imap->sock->ssl = SSL_new (SSLContext);
SSL_set_fd (imap->sock->ssl, imap->sock->fd); SSL_set_fd (imap->sock->ssl, imap->sock->rdfd);
ret = SSL_connect (imap->sock->ssl); ret = SSL_connect (imap->sock->ssl);
if (ret <= 0) if (ret <= 0)
{ {
@ -721,6 +791,8 @@ imap_open (config_t * box, unsigned int minuid, imap_t * imap)
break; break;
#endif #endif
if (!preauth)
{
puts ("Logging in..."); puts ("Logging in...");
#if HAVE_LIBSSL #if HAVE_LIBSSL
if (imap->have_cram) if (imap->have_cram)
@ -754,6 +826,7 @@ imap_open (config_t * box, unsigned int minuid, imap_t * imap)
break; break;
} }
} }
}
/* get NAMESPACE info */ /* get NAMESPACE info */
if (box->use_namespace && imap->have_namespace) if (box->use_namespace && imap->have_namespace)
@ -773,9 +846,7 @@ imap_open (config_t * box, unsigned int minuid, imap_t * imap)
fputs ("Selecting mailbox... ", stdout); fputs ("Selecting mailbox... ", stdout);
fflush (stdout); fflush (stdout);
if ( if ((ret = imap_exec (imap, "SELECT \"%s%s\"", imap->prefix, box->box)))
(ret =
imap_exec (imap, "SELECT \"%s%s\"", imap->prefix, box->box)))
break; break;
printf ("%d messages, %d recent\n", imap->count, imap->recent); printf ("%d messages, %d recent\n", imap->count, imap->recent);
@ -804,7 +875,9 @@ imap_close (imap_t * imap)
if (imap) if (imap)
{ {
imap_exec (imap, "LOGOUT"); imap_exec (imap, "LOGOUT");
close (imap->sock->fd); close (imap->sock->rdfd);
if (imap->sock->rdfd != imap->sock->wrfd)
close (imap->sock->wrfd);
free (imap->sock); free (imap->sock);
free (imap->buf); free (imap->buf);
free_message (imap->msgs); free_message (imap->msgs);

View File

@ -16,7 +16,7 @@
\" along with this program; if not, write to the Free Software \" along with this program; if not, write to the Free Software
\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
.. ..
.TH isync 1 "2002 Jan 16" .TH isync 1 "2002 Apr 19"
.. ..
.SH NAME .SH NAME
isync - synchronize IMAP4 and maildir mailboxes isync - synchronize IMAP4 and maildir mailboxes
@ -224,6 +224,11 @@ is 0, the maximum file size is
.B unlimited. .B unlimited.
.. ..
.TP .TP
\fBTunnel\fR \fIcommand\fR
Specify a command to run to establish a connection rather than opening a TCP
socket. This allows you to run an IMAP session over an SSH tunnel, for
example.
.TP
\fBUseNamespace\fR \fIyes|no\fR \fBUseNamespace\fR \fIyes|no\fR
Selects whether Selects whether
.B isync .B isync

View File

@ -30,7 +30,8 @@
typedef struct typedef struct
{ {
int fd; int rdfd; /* read filedes */
int wrfd; /* write filedes */
#if HAVE_LIBSSL #if HAVE_LIBSSL
SSL *ssl; SSL *ssl;
unsigned int use_ssl:1; unsigned int use_ssl:1;
@ -61,6 +62,7 @@ struct config
char *box; char *box;
char *alias; char *alias;
char *copy_deleted_to; char *copy_deleted_to;
char *tunnel;
unsigned int max_messages; unsigned int max_messages;
off_t max_size; off_t max_size;
config_t *next; config_t *next;
@ -119,7 +121,8 @@ typedef struct _list list_t;
#define NIL (void*)0x1 #define NIL (void*)0x1
#define LIST (void*)0x2 #define LIST (void*)0x2
struct _list { struct _list
{
char *val; char *val;
list_t *next; list_t *next;
list_t *child; list_t *child;
@ -187,7 +190,7 @@ int imap_copy_message (imap_t * imap, unsigned int uid, const char *mailbox);
int imap_fetch_message (imap_t *, unsigned int, int); int imap_fetch_message (imap_t *, unsigned int, int);
int imap_set_flags (imap_t *, unsigned int, unsigned int); int imap_set_flags (imap_t *, unsigned int, unsigned int);
int imap_expunge (imap_t *); int imap_expunge (imap_t *);
imap_t *imap_open (config_t *, unsigned int, imap_t *); imap_t *imap_open (config_t *, unsigned int, imap_t *, int);
int imap_append_message (imap_t *, int, message_t *); int imap_append_message (imap_t *, int, message_t *);
mailbox_t *maildir_open (const char *, int flags); mailbox_t *maildir_open (const char *, int flags);

View File

@ -40,3 +40,13 @@ Host host.play.com
# use a non-default port for this connection # use a non-default port for this connection
Port 6789 Port 6789
Alias personal Alias personal
###
### Remote mailbox over a SSH tunnel
###
Mailbox /home/me/Mail/remote
Host host.remote.com
Tunnel "ssh -q host.remote.com /usr/sbin/imapd"
Alias remote

2
main.c
View File

@ -292,7 +292,7 @@ main (int argc, char **argv)
break; break;
} }
imap = imap_open (box, fast ? mail->maxuid + 1 : 1, imap); imap = imap_open (box, fast ? mail->maxuid + 1 : 1, imap, 0);
if (!imap) if (!imap)
{ {
fprintf (stderr, "%s: skipping mailbox due to IMAP error\n", fprintf (stderr, "%s: skipping mailbox due to IMAP error\n",