summaryrefslogtreecommitdiffstats
path: root/imap
diff options
context:
space:
mode:
authorThomas Roessler <roessler@does-not-exist.org>1999-11-17 19:45:52 +0000
committerThomas Roessler <roessler@does-not-exist.org>1999-11-17 19:45:52 +0000
commit114dce60c1c8d53b57fe761de2b201e05cfd07be (patch)
treecd3cc7183d10263fe2a7a927c87ea5c8ac49873f /imap
parentc42f3d036548d9c814ddb3ab41f5287bbec2b793 (diff)
Tommi Komulainen's IMAP/SSL support patches.
Diffstat (limited to 'imap')
-rw-r--r--imap/Makefile.am9
-rw-r--r--imap/browse.c6
-rw-r--r--imap/imap.c26
-rw-r--r--imap/imap.h2
-rw-r--r--imap/imap_private.h1
-rw-r--r--imap/imap_socket.h12
-rw-r--r--imap/imap_ssl.c263
-rw-r--r--imap/imap_ssl.h29
-rw-r--r--imap/message.c4
-rw-r--r--imap/socket.c67
-rw-r--r--imap/util.c37
11 files changed, 423 insertions, 33 deletions
diff --git a/imap/Makefile.am b/imap/Makefile.am
index 231f1da3..ee2f1f28 100644
--- a/imap/Makefile.am
+++ b/imap/Makefile.am
@@ -2,12 +2,17 @@
AUTOMAKE_OPTIONS = foreign
+if USE_SSL
+SSLSOURCES = imap_ssl.c
+SSLHEADERS = imap_ssl.h
+endif
+
EXTRA_DIST = BUGS README TODO
INCLUDES = -I$(top_srcdir)
noinst_LIBRARIES = libimap.a
-noinst_HEADERS = imap_private.h imap_socket.h md5.h message.h
+noinst_HEADERS = imap_private.h imap_socket.h md5.h message.h $(SSLHEADERS)
libimap_a_SOURCES = auth.c browse.c command.c imap.c imap.h md5c.c message.c \
- socket.c util.c
+ socket.c util.c $(SSLSOURCES)
diff --git a/imap/browse.c b/imap/browse.c
index f48a9d7e..5769ec33 100644
--- a/imap/browse.c
+++ b/imap/browse.c
@@ -60,7 +60,7 @@ int imap_init_browse (char *path, struct browser_state *state)
int noselect;
int noinferiors;
- if (imap_parse_path (path, host, sizeof (host), &port, &ipath))
+ if (imap_parse_path (path, host, sizeof (host), &port, NULL, &ipath))
{
mutt_error ("%s is an invalid IMAP path", path);
return -1;
@@ -255,7 +255,7 @@ static int add_list_result (CONNECTION *conn, const char *seq, const char *cmd,
int noselect;
int noinferiors;
- if (imap_parse_path (state->folder, host, sizeof (host), &port, &curfolder))
+ if (imap_parse_path (state->folder, host, sizeof (host), &port, NULL, &curfolder))
{
dprint (2, (debugfile,
"add_list_result: current folder %s makes no sense\n", state->folder));
@@ -299,7 +299,7 @@ static void imap_add_folder (char delim, char *folder, int noselect,
char *curfolder;
int flen = strlen (folder);
- if (imap_parse_path (state->folder, host, sizeof (host), &port, &curfolder))
+ if (imap_parse_path (state->folder, host, sizeof (host), &port, NULL, &curfolder))
return;
imap_unquote_string (folder);
diff --git a/imap/imap.c b/imap/imap.c
index a9998629..03d1699f 100644
--- a/imap/imap.c
+++ b/imap/imap.c
@@ -405,7 +405,7 @@ int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn)
if (mutt_socket_read_line_d (buf, sizeof (buf), conn) < 0)
{
- close (conn->fd);
+ mutt_socket_close_connection (conn);
idata->state = IMAP_DISCONNECTED;
return (-1);
}
@@ -415,7 +415,7 @@ int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn)
if (imap_check_capabilities(idata) != 0
|| imap_authenticate (idata, conn) != 0)
{
- close (conn->fd);
+ mutt_socket_close_connection (conn);
idata->state = IMAP_DISCONNECTED;
return (-1);
}
@@ -424,7 +424,7 @@ int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn)
{
if (imap_check_capabilities(idata) != 0)
{
- close (conn->fd);
+ mutt_socket_close_connection (conn);
idata->state = IMAP_DISCONNECTED;
return (-1);
}
@@ -432,7 +432,7 @@ int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn)
else
{
imap_error ("imap_open_connection()", buf);
- close (conn->fd);
+ mutt_socket_close_connection (conn);
idata->state = IMAP_DISCONNECTED;
return (-1);
}
@@ -512,8 +512,9 @@ int imap_open_mailbox (CONTEXT *ctx)
int count = 0;
int n;
int port;
+ int socktype;
- if (imap_parse_path (ctx->path, host, sizeof (host), &port, &pc))
+ if (imap_parse_path (ctx->path, host, sizeof (host), &port, &socktype, &pc))
{
mutt_error ("%s is an invalid IMAP path", ctx->path);
return -1;
@@ -530,7 +531,7 @@ int imap_open_mailbox (CONTEXT *ctx)
/* We need to create a new connection, the current one isn't useful */
idata = safe_calloc (1, sizeof (IMAP_DATA));
- conn = mutt_socket_select_connection (host, port, M_NEW_SOCKET);
+ conn = mutt_socket_select_connection (host, port, socktype);
conn->data = idata;
idata->conn = conn;
}
@@ -687,7 +688,7 @@ int imap_select_mailbox (CONTEXT* ctx, const char* path)
strfcpy (curpath, path, sizeof (curpath));
/* check that the target folder makes sense */
- if (imap_parse_path (curpath, host, sizeof (host), &port, &mbox))
+ if (imap_parse_path (curpath, host, sizeof (host), &port, NULL, &mbox))
return -1;
/* and that it's on the same server as the current folder */
@@ -736,8 +737,9 @@ int imap_open_mailbox_append (CONTEXT *ctx)
char *pc;
int r;
int port;
+ int socktype;
- if (imap_parse_path (ctx->path, host, sizeof (host), &port, &pc))
+ if (imap_parse_path (ctx->path, host, sizeof (host), &port, &socktype, &pc))
return (-1);
ctx->magic = M_IMAP;
@@ -831,7 +833,7 @@ int imap_close_connection (CONTEXT *ctx)
while (mutt_strncmp (seq, buf, SEQLEN) != 0);
mutt_clear_error ();
}
- close (CTX_DATA->conn->fd);
+ mutt_socket_close_connection (CTX_DATA->conn);
CTX_DATA->state = IMAP_DISCONNECTED;
CTX_DATA->conn->uses = 0;
CTX_DATA->conn->data = NULL;
@@ -1159,7 +1161,7 @@ int imap_mailbox_check (char *path, int new)
int msgcount = 0;
int port;
- if (imap_parse_path (path, host, sizeof (host), &port, &pc))
+ if (imap_parse_path (path, host, sizeof (host), &port, NULL, &pc))
return -1;
conn = mutt_socket_select_connection (host, port, 0);
@@ -1344,7 +1346,7 @@ int imap_subscribe (char *path, int subscribe)
char *ipath = NULL;
int port;
- if (imap_parse_path (path, host, sizeof (host), &port, &ipath))
+ if (imap_parse_path (path, host, sizeof (host), &port, NULL, &ipath))
return (-1);
conn = mutt_socket_select_connection (host, port, 0);
@@ -1399,7 +1401,7 @@ int imap_complete(char* dest, size_t dlen, char* path) {
int pos = 0;
/* verify passed in path is an IMAP path */
- if (imap_parse_path (path, host, sizeof(host), &port, &mbox))
+ if (imap_parse_path (path, host, sizeof(host), &port, NULL, &mbox))
{
dprint(2, (debugfile, "imap_complete: bad path %s\n", path));
return -1;
diff --git a/imap/imap.h b/imap/imap.h
index 1afecf4f..978fe4bd 100644
--- a/imap/imap.h
+++ b/imap/imap.h
@@ -45,7 +45,7 @@ int imap_fetch_message (MESSAGE* msg, CONTEXT* ctx, int msgno);
/* util.c */
int imap_parse_path (char* path, char* host, size_t hlen, int* port,
- char** mbox);
+ int *socktype, char** mbox);
void imap_qualify_path (char* dest, size_t len, const char* host, int port,
const char* path, const char* name);
diff --git a/imap/imap_private.h b/imap/imap_private.h
index 6a5c3fe7..62b7a58c 100644
--- a/imap/imap_private.h
+++ b/imap/imap_private.h
@@ -25,6 +25,7 @@
/* -- symbols -- */
#define IMAP_PORT 143
+#define IMAP_SSL_PORT 993
/* number of entries in the hash table */
#define IMAP_CACHE_LEN 10
diff --git a/imap/imap_socket.h b/imap/imap_socket.h
index 5b99114d..3fd9d24e 100644
--- a/imap/imap_socket.h
+++ b/imap/imap_socket.h
@@ -32,14 +32,26 @@ typedef struct _connection
int available;
void *data;
struct _connection *next;
+
+ void *sockdata;
+ int (*read) (struct _connection *conn);
+ int (*write) (struct _connection *conn, const char *buf);
+ int (*open) (struct _connection *conn);
+ int (*close) (struct _connection *conn);
} CONNECTION;
+
int mutt_socket_readchar (CONNECTION *conn, char *c);
int mutt_socket_read_line (char *buf, size_t buflen, CONNECTION *conn);
int mutt_socket_read_line_d (char *buf, size_t buflen, CONNECTION *conn);
int mutt_socket_write (CONNECTION *conn, const char *buf);
CONNECTION *mutt_socket_select_connection (char *host, int port, int flags);
int mutt_socket_open_connection (CONNECTION *conn);
+int mutt_socket_close_connection (CONNECTION *conn);
+int raw_socket_read (CONNECTION *conn);
+int raw_socket_write (CONNECTION *conn, const char *buf);
+int raw_socket_open (CONNECTION *conn);
+int raw_socket_close (CONNECTION *conn);
#endif /* _IMAP_SOCKET_H_ */
diff --git a/imap/imap_ssl.c b/imap/imap_ssl.c
new file mode 100644
index 00000000..e6b99c8b
--- /dev/null
+++ b/imap/imap_ssl.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 1999 Tommi Komulainen <Tommi.Komulainen@iki.fi>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <openssl/ssl.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+
+#undef _
+
+#include <string.h>
+
+#include "mutt.h"
+#include "imap_socket.h"
+#include "mutt_menu.h"
+#include "mutt_curses.h"
+#include "imap_ssl.h"
+
+
+char *SslCertFile = NULL;
+
+typedef struct _sslsockdata
+{
+ SSL_CTX *ctx;
+ SSL *ssl;
+ X509 *cert;
+}
+sslsockdata;
+
+
+static int ssl_check_certificate (sslsockdata * data);
+
+
+int ssl_socket_read (CONNECTION * conn)
+{
+ sslsockdata *data = conn->sockdata;
+ return SSL_read (data->ssl, conn->inbuf, LONG_STRING);
+}
+
+int ssl_socket_write (CONNECTION * conn, const char *buf)
+{
+ sslsockdata *data = conn->sockdata;
+ dprint (1, (debugfile, "ssl_socket_write():%s", buf));
+ return SSL_write (data->ssl, buf, mutt_strlen (buf));
+}
+
+int ssl_socket_open (CONNECTION * conn)
+{
+ sslsockdata *data;
+ int err;
+
+ if (raw_socket_open (conn) < 0)
+ return -1;
+
+ data = (sslsockdata *) safe_calloc (1, sizeof (sslsockdata));
+ conn->sockdata = data;
+
+ SSLeay_add_ssl_algorithms ();
+ data->ctx = SSL_CTX_new (SSLv23_client_method ());
+
+ data->ssl = SSL_new (data->ctx);
+ SSL_set_fd (data->ssl, conn->fd);
+
+ if ((err = SSL_connect (data->ssl)) < 0)
+ {
+ ssl_socket_close (conn);
+ return -1;
+ }
+
+ data->cert = SSL_get_peer_certificate (data->ssl);
+ if (!data->cert)
+ {
+ mutt_error (_("Unable to get certificate from peer"));
+ sleep (1);
+ return -1;
+ }
+
+ if (!ssl_check_certificate (data))
+ {
+ ssl_socket_close (conn);
+ return -1;
+ }
+
+ mutt_message (_("SSL connection using %s"), SSL_get_cipher (data->ssl));
+ sleep (1);
+
+ return 0;
+}
+
+int ssl_socket_close (CONNECTION * conn)
+{
+ sslsockdata *data = conn->sockdata;
+ SSL_shutdown (data->ssl);
+
+ X509_free (data->cert);
+ SSL_free (data->ssl);
+ SSL_CTX_free (data->ctx);
+
+ return raw_socket_close (conn);
+}
+
+
+
+static char *x509_get_part (char *line, const char *ndx)
+{
+ static char ret[SHORT_STRING];
+ char *c, *c2;
+
+ strncpy (ret, _("Unknown"), sizeof (ret));
+
+ c = strstr (line, ndx);
+ if (c)
+ {
+ c += strlen (ndx);
+ c2 = strchr (c, '/');
+ if (c2)
+ *c2 = '\0';
+ strncpy (ret, c, sizeof (ret));
+ if (c2)
+ *c2 = '/';
+ }
+
+ return ret;
+}
+
+static void x509_fingerprint (char *s, int l, X509 * cert)
+{
+ unsigned char md[EVP_MAX_MD_SIZE];
+ unsigned int n;
+ int j;
+
+ if (!X509_digest (cert, EVP_md5 (), md, &n))
+ {
+ snprintf (s, l, _("[unable to calculate]"));
+ }
+ else
+ {
+ for (j = 0; j < (int) n; j++)
+ {
+ char ch[8];
+ snprintf (ch, 8, "%02X%s", md[j], (j % 2 ? " " : ""));
+ strncat (s, ch, l);
+ }
+ }
+}
+
+
+static int ssl_check_certificate (sslsockdata * data)
+{
+ char *part[] =
+ {"/CN=", "/Email=", "/O=", "/OU=", "/L=", "/ST=", "/C="};
+ char helpstr[SHORT_STRING];
+ char buf[SHORT_STRING];
+ MUTTMENU *menu;
+ int done, i;
+ FILE *fp;
+ char *line = NULL, *c;
+
+ /* automatic check from user's database */
+ fp = fopen (SslCertFile, "rt");
+ if (fp)
+ {
+ EVP_PKEY *peer = X509_get_pubkey (data->cert);
+ X509 *savedkey = NULL;
+ int pass = 0;
+ while ((savedkey = PEM_read_X509 (fp, &savedkey, NULL)))
+ {
+ if (X509_verify (savedkey, peer))
+ {
+ pass = 1;
+ break;
+ }
+ }
+ fclose (fp);
+ if (pass)
+ return 1;
+ }
+
+ menu = mutt_new_menu ();
+ menu->max = 15;
+ menu->dialog = (char **) safe_calloc (1, menu->max * sizeof (char *));
+ for (i = 0; i < menu->max; i++)
+ menu->dialog[i] = (char *) safe_calloc (1, SHORT_STRING * sizeof (char));
+
+ strncpy (menu->dialog[0], _("This certificate belongs to:"), SHORT_STRING);
+ line = X509_NAME_oneline (X509_get_subject_name (data->cert),
+ buf, sizeof (buf));
+ for (i = 1; i <= 5; i++)
+ {
+ c = x509_get_part (line, part[i - 1]);
+ snprintf (menu->dialog[i], SHORT_STRING, " %s", c);
+ }
+
+ strncpy (menu->dialog[7], _("This certificate was issued by:"), SHORT_STRING);
+ line = X509_NAME_oneline (X509_get_subject_name (data->cert),
+ buf, sizeof (buf));
+ for (i = 8; i <= 12; i++)
+ {
+ c = x509_get_part (line, part[i - 8]);
+ snprintf (menu->dialog[i], SHORT_STRING, " %s", c);
+ }
+
+ buf[0] = '\0';
+ x509_fingerprint (buf, sizeof (buf), data->cert);
+ snprintf (menu->dialog[14], SHORT_STRING, _("Fingerprint: %s"), buf);
+
+ menu->title = _("SSL Certificate check");
+ menu->prompt = _("(r)eject, accept (o)nce, (a)ccept always");
+ menu->keys = _("roa");
+
+ helpstr[0] = '\0';
+ mutt_make_help (buf, sizeof (buf), _("Exit "), MENU_GENERIC, OP_EXIT);
+ strncat (helpstr, buf, sizeof (helpstr));
+ mutt_make_help (buf, sizeof (buf), _("Help"), MENU_GENERIC, OP_HELP);
+ strncat (helpstr, buf, sizeof (helpstr));
+ menu->help = helpstr;
+
+ done = 0;
+ while (!done)
+ {
+ switch (mutt_menuLoop (menu))
+ {
+ case -1: /* abort */
+ case OP_MAX + 1: /* reject */
+ case OP_EXIT:
+ done = 1;
+ break;
+ case OP_MAX + 3: /* accept always */
+ done = 0;
+ fp = fopen (SslCertFile, "w+t");
+ if (fp)
+ {
+ if (PEM_write_X509 (fp, data->cert))
+ done = 1;
+ fclose (fp);
+ }
+ if (!done)
+ mutt_error (_("Warning: Couldn't save certificate"));
+ else
+ mutt_message (_("Certificate saved"));
+ sleep (1);
+ /* fall through */
+ case OP_MAX + 2: /* accept once */
+ done = 2;
+ break;
+ }
+ }
+ mutt_menuDestroy (&menu);
+ return (done == 2);
+}
diff --git a/imap/imap_ssl.h b/imap/imap_ssl.h
new file mode 100644
index 00000000..7e56d40d
--- /dev/null
+++ b/imap/imap_ssl.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 1999 Tommi Komulainen <Tommi.Komulainen@iki.fi>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _MUTT_SSL_H_
+#define _MUTT_SSL_H_ 1
+
+extern char *SslCertFile;
+
+extern int ssl_socket_read (CONNECTION *conn);
+extern int ssl_socket_write (CONNECTION *conn, const char *buf);
+extern int ssl_socket_open (CONNECTION *conn);
+extern int ssl_socket_close (CONNECTION *conn);
+
+#endif
diff --git a/imap/message.c b/imap/message.c
index 9b143259..1b7c16c1 100644
--- a/imap/message.c
+++ b/imap/message.c
@@ -404,7 +404,7 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
size_t len;
int c, last;
- if (imap_parse_path (ctx->path, host, sizeof (host), &port, &pc))
+ if (imap_parse_path (ctx->path, host, sizeof (host), &port, NULL, &pc))
return (-1);
imap_fix_path (CTX_DATA, pc, mailbox, sizeof (mailbox));
@@ -526,7 +526,7 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
int rc;
int n;
- if (imap_parse_path (dest, host, sizeof (host), &port, &pc))
+ if (imap_parse_path (dest, host, sizeof (host), &port, NULL, &pc))
{
dprint (1, (debugfile, "imap_copy_message: bad destination %s\n", dest));
return -1;
diff --git a/imap/socket.c b/imap/socket.c
index bbf1605b..a81bfa38 100644
--- a/imap/socket.c
+++ b/imap/socket.c
@@ -19,6 +19,9 @@
#include "mutt.h"
#include "globals.h"
#include "imap_socket.h"
+#ifdef USE_SSL
+#include "imap_ssl.h"
+#endif
#include <unistd.h>
#include <netinet/in.h>
@@ -32,12 +35,32 @@
static CONNECTION *Connections = NULL;
+
+/* Wrappers */
+int mutt_socket_open_connection (CONNECTION *conn)
+{
+ return conn->open (conn);
+}
+
+int mutt_socket_close_connection (CONNECTION *conn)
+{
+ return conn->close (conn);
+}
+
+int mutt_socket_write (CONNECTION *conn, const char *buf)
+{
+ dprint (1,(debugfile,"> %s", buf));
+ return conn->write (conn, buf);
+}
+
+
+
/* simple read buffering to speed things up. */
int mutt_socket_readchar (CONNECTION *conn, char *c)
{
if (conn->bufpos >= conn->available)
{
- conn->available = read (conn->fd, conn->inbuf, LONG_STRING);
+ conn->available = conn->read (conn);
conn->bufpos = 0;
if (conn->available <= 0)
return conn->available; /* returns 0 for EOF or -1 for other error */
@@ -74,17 +97,15 @@ int mutt_socket_read_line_d (char *buf, size_t buflen, CONNECTION *conn)
return r;
}
-int mutt_socket_write (CONNECTION *conn, const char *buf)
-{
- dprint (1,(debugfile,"> %s", buf));
- return (write (conn->fd, buf, mutt_strlen (buf)));
-}
-
CONNECTION *mutt_socket_select_connection (char *host, int port, int flags)
{
CONNECTION *conn;
+#ifdef USE_SSL
+ if (flags != M_NEW_SOCKET && flags != M_NEW_SSL_SOCKET)
+#else
if (flags != M_NEW_SOCKET)
+#endif
{
conn = Connections;
while (conn)
@@ -104,6 +125,21 @@ CONNECTION *mutt_socket_select_connection (char *host, int port, int flags)
conn->next = Connections;
Connections = conn;
+ conn->read = raw_socket_read;
+ conn->write = raw_socket_write;
+ conn->open = raw_socket_open;
+ conn->close = raw_socket_close;
+
+#ifdef USE_SSL
+ if (flags == M_NEW_SSL_SOCKET)
+ {
+ conn->read = ssl_socket_read;
+ conn->write = ssl_socket_write;
+ conn->open = ssl_socket_open;
+ conn->close = ssl_socket_close;
+ }
+#endif
+
return conn;
}
@@ -131,7 +167,22 @@ static int try_socket_and_connect (CONNECTION *conn, struct sockaddr_in sin,
return 0;
}
-int mutt_socket_open_connection (CONNECTION *conn)
+int raw_socket_close (CONNECTION *conn)
+{
+ return close (conn->fd);
+}
+
+int raw_socket_read (CONNECTION *conn)
+{
+ return read (conn->fd, conn->inbuf, LONG_STRING);
+}
+
+int raw_socket_write (CONNECTION *conn, const char *buf)
+{
+ return write (conn->fd, buf, mutt_strlen (buf));
+}
+
+int raw_socket_open (CONNECTION *conn)
{
struct sockaddr_in sin;
struct hostent *he;
diff --git a/imap/util.c b/imap/util.c
index 5e6d7f71..b02dde96 100644
--- a/imap/util.c
+++ b/imap/util.c
@@ -121,20 +121,22 @@ char *imap_next_word (char *s)
/* imap_parse_path: given an IMAP mailbox name, return host, port
* and a path IMAP servers will recognise. */
int imap_parse_path (char* path, char* host, size_t hlen, int* port,
- char** mbox)
+ int *socktype, char** mbox)
{
int n;
char *pc;
char *pt;
/* set default port */
- *port = IMAP_PORT;
+ *port = 0;
+ if (socktype)
+ *socktype = M_NEW_SOCKET;
pc = path;
if (*pc != '{')
return -1;
pc++;
n = 0;
- while (*pc && *pc != '}' && *pc != ':' && (n < hlen-1))
+ while (*pc && *pc != '}' && *pc != ':' && *pc != '/' && (n < hlen-1))
host[n++] = *pc++;
host[n] = 0;
/* catch NULL hosts */
@@ -147,11 +149,13 @@ int imap_parse_path (char* path, char* host, size_t hlen, int* port,
return -1;
if (*pc == ':')
{
+ char c;
pc++;
pt = pc;
- while (*pc && *pc != '}') pc++;
+ while (*pc && *pc != '}' && *pc != '/') pc++;
if (!*pc)
return -1;
+ c = *pc;
*pc = '\0';
*port = atoi (pt);
if (!port)
@@ -159,10 +163,33 @@ int imap_parse_path (char* path, char* host, size_t hlen, int* port,
dprint (1, (debugfile, "imap_parse_path: bad port in %s\n", path));
return -1;
}
+ *pc = c;
+ }
+ if (*pc == '/')
+ {
+ pc++;
+ pt = pc;
+ while (*pc && *pc != '}') pc++;
+ if (!*pc)
+ return (-1);
+ *pc = '\0';
+#ifdef USE_SSL
+ if (!strcmp (pt, "ssl"))
+ {
+ if (socktype)
+ *socktype = M_NEW_SSL_SOCKET;
+ if (!*port)
+ *port = IMAP_SSL_PORT;
+ } else
+#endif
+ return (-1);
*pc = '}';
}
pc++;
-
+
+ if (!*port)
+ *port = IMAP_PORT;
+
*mbox = pc;
return 0;
}