summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-09-05 02:26:51 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-09-05 02:26:51 +0300
commita08bf28c50373eb68b18f7537d8eac8746da4097 (patch)
treeab8687dde737d3526f3d091e2d8c828676e2a18a
parent566cb796939c33fd7cec50cf56eee8390118eac5 (diff)
downloadmailutils-a08bf28c50373eb68b18f7537d8eac8746da4097.tar.gz
mailutils-a08bf28c50373eb68b18f7537d8eac8746da4097.tar.bz2
Re-implement pop3 client functions.
* include/mailutils/filter.h (mu_filter_io) <eof>: New member. * mailbox/fltstream.c (init_iobuf): Initialize eof to 0. (filter_read): Break the loop if the decoder has set eof. * mailbox/xscript-stream.c (_xscript_ctl) <MU_IOCTL_SWAP_STREAM>: Handle a special case when the transport does not support stream swapping. * include/mailutils/pop3.h (mu_pop3_set_debug): Remove. (MU_POP3_TRACE_CLR, MU_POP3_TRACE_SET, MU_POP3_TRACE_QRY): New macros. (mu_pop3_trace): New proto. (mu_pop3_readline): Remove. (mu_pop3_getline): New proto. (mu_pop3_capa): Change signature. * include/mailutils/sys/pop3.h (mu_pop3_state): Remove the *_ACK states. (mu_pop3_work_buf): Remove. (MU_POP3_ACK, MU_POP3_TRACE): New defines. (_mu_pop3): Rewrite the structure. (mu_pop3_debug_cmd, mu_pop3_debug_ack): Remove functions. (MU_POP3_FISSET, MU_POP3_FSET, MU_POP3_FCLR): New macros. (_mu_pop3_trace_enable, _mu_pop3_trace_disable) (_mu_pop3_init): New protos. * include/mailutils/tls.h (mu_tls_stream_ctl_fn) (mu_tls_writeline_fn): Change typedefs. * libmu_auth/tls.c (mu_tls_begin): Update function calls accordingly. * libproto/pop/pop3_debug.c: Remove. * libproto/pop/pop3_trace.c: New function. * libproto/pop/Makefile.am (libmu_pop_la_SOURCES): Temporarly comment out folder.c, mbox.c and url.c. Remove pop3_debug.c. Add pop3_trace.c. * libproto/pop/pop3_capa.c: Rewrite. * libproto/pop/pop3_create.c: Rewrite. * libproto/pop/pop3_iterator.c: Rewrite. * libproto/pop/pop3_response.c: Rewrite. * libproto/pop/pop3_sendline.c: Rewrite. * libproto/pop/pop3_stls.c: Rewrite. * libproto/pop/pop3_stream.c: Rewrite. * libproto/pop/pop3_apop.c: Reflect changes to the pop3 framework. * libproto/pop/pop3_carrier.c: Likewise. * libproto/pop/pop3_connect.c: Likewise. * libproto/pop/pop3_dele.c: Likewise. * libproto/pop/pop3_destroy.c: Likewise. * libproto/pop/pop3_disconnect.c: Likewise. * libproto/pop/pop3_list.c: Likewise. * libproto/pop/pop3_lista.c: Likewise. * libproto/pop/pop3_noop.c: Likewise. * libproto/pop/pop3_pass.c: Likewise. * libproto/pop/pop3_quit.c: Likewise. * libproto/pop/pop3_retr.c: Likewise. * libproto/pop/pop3_readline.c: Likewise. * libproto/pop/pop3_rset.c: Likewise. * libproto/pop/pop3_stat.c: Likewise. * libproto/pop/pop3_top.c: Likewise. * libproto/pop/pop3_uidl.c: Likewise. * libproto/pop/pop3_uidla.c: Likewise. * libproto/pop/pop3_user.c: Likewise. * examples/pop3client.c: Implement the stls comand. (main) [WITH_TLS]: Call mu_init_tls_libs. (com_verbose): Redo verbose support. (com_capa): Implement "reread" option.
-rw-r--r--examples/pop3client.c45
-rw-r--r--include/mailutils/filter.h3
-rw-r--r--include/mailutils/pop3.h74
-rw-r--r--include/mailutils/sys/pop3.h166
-rw-r--r--include/mailutils/tls.h11
-rw-r--r--libmu_auth/tls.c45
-rw-r--r--libproto/pop/Makefile.am8
-rw-r--r--libproto/pop/pop3_apop.c28
-rw-r--r--libproto/pop/pop3_capa.c80
-rw-r--r--libproto/pop/pop3_carrier.c4
-rw-r--r--libproto/pop/pop3_connect.c30
-rw-r--r--libproto/pop/pop3_create.c40
-rw-r--r--libproto/pop/pop3_debug.c51
-rw-r--r--libproto/pop/pop3_dele.c11
-rw-r--r--libproto/pop/pop3_destroy.c13
-rw-r--r--libproto/pop/pop3_disconnect.c9
-rw-r--r--libproto/pop/pop3_iterator.c71
-rw-r--r--libproto/pop/pop3_list.c14
-rw-r--r--libproto/pop/pop3_lista.c14
-rw-r--r--libproto/pop/pop3_noop.c11
-rw-r--r--libproto/pop/pop3_pass.c14
-rw-r--r--libproto/pop/pop3_quit.c12
-rw-r--r--libproto/pop/pop3_readline.c149
-rw-r--r--libproto/pop/pop3_response.c47
-rw-r--r--libproto/pop/pop3_retr.c12
-rw-r--r--libproto/pop/pop3_rset.c11
-rw-r--r--libproto/pop/pop3_sendline.c80
-rw-r--r--libproto/pop/pop3_stat.c14
-rw-r--r--libproto/pop/pop3_stls.c73
-rw-r--r--libproto/pop/pop3_stream.c276
-rw-r--r--libproto/pop/pop3_top.c15
-rw-r--r--libproto/pop/pop3_trace.c118
-rw-r--r--libproto/pop/pop3_uidl.c69
-rw-r--r--libproto/pop/pop3_uidla.c14
-rw-r--r--libproto/pop/pop3_user.c11
-rw-r--r--mailbox/fltstream.c10
-rw-r--r--mailbox/xscript-stream.c31
37 files changed, 862 insertions, 822 deletions
diff --git a/examples/pop3client.c b/examples/pop3client.c
index b8f3db2b2..3751c0a0e 100644
--- a/examples/pop3client.c
+++ b/examples/pop3client.c
@@ -48,6 +48,7 @@
#include <mailutils/argcv.h>
#include <mailutils/cctype.h>
#include <mailutils/cstr.h>
+#include <mailutils/tls.h>
/* A structure which contains information on the commands this program
can understand. */
@@ -80,6 +81,7 @@ int com_uidl (char *);
int com_user (char *);
int com_verbose (char *);
int com_prompt (char *);
+int com_stls (char *);
void initialize_readline (void);
COMMAND *find_command (char *);
@@ -106,6 +108,7 @@ COMMAND commands[] = {
{ "retr", com_retr, "Dowload message: RETR msgno" },
{ "rset", com_rset, "Unmark all messages: RSET" },
{ "stat", com_stat, "Get the size and count of mailbox : STAT [msgno]" },
+ { "stls", com_stls, "Start TLS negotiation" },
{ "top", com_top, "Get the header of message: TOP msgno [lines]" },
{ "uidl", com_uidl, "Get the unique id of message: UIDL [msgno]" },
{ "user", com_user, "send login: USER user" },
@@ -310,7 +313,9 @@ main (int argc MU_ARG_UNUSED, char **argv)
mu_set_program_name (argv[0]);
prompt = strdup (DEFAULT_PROMPT);
initialize_readline (); /* Bind our completer. */
-
+#ifdef WITH_TLS
+ mu_init_tls_libs ();
+#endif
/* Loop reading and executing lines until the user quits. */
while (!done)
{
@@ -393,16 +398,9 @@ com_verbose (char *arg)
if (pop3 != NULL)
{
if (verbose == 1)
- {
- mu_debug_t debug;
- mu_debug_create (&debug, NULL);
- mu_debug_set_level (debug, MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT));
- status = mu_pop3_set_debug (pop3, debug);
- }
+ mu_pop3_trace (pop3, MU_POP3_TRACE_SET);
else
- {
- status = mu_pop3_set_debug (pop3, NULL);
- }
+ mu_pop3_trace (pop3, MU_POP3_TRACE_CLR);
}
return status;
}
@@ -442,10 +440,24 @@ com_apop (char *arg)
}
int
-com_capa (char *arg MU_ARG_UNUSED)
+com_capa (char *arg)
{
mu_iterator_t iterator = NULL;
- int status = mu_pop3_capa (pop3, &iterator);
+ int status;
+ int reread = 0;
+
+ if (arg && *arg)
+ {
+ if (strcmp (arg, "reread") == 0)
+ reread = 1;
+ else
+ {
+ mu_error ("%s: unknown argument", "capa");
+ return 0;
+ }
+ }
+
+ status = mu_pop3_capa (pop3, reread, &iterator);
if (status == 0)
{
@@ -609,6 +621,12 @@ com_stat (char *arg MU_ARG_UNUSED)
}
int
+com_stls (char *arg MU_ARG_UNUSED)
+{
+ return mu_pop3_stls (pop3);
+}
+
+int
com_dele (char *arg)
{
unsigned msgno;
@@ -799,8 +817,7 @@ com_connect (char *arg)
if (verbose)
com_verbose ("on");
- status =
- mu_tcp_stream_create (&tcp, argv[0], n, MU_STREAM_READ);
+ status = mu_tcp_stream_create (&tcp, argv[0], n, MU_STREAM_READ);
if (status == 0)
{
mu_pop3_set_carrier (pop3, tcp);
diff --git a/include/mailutils/filter.h b/include/mailutils/filter.h
index 03c43c2b0..2490f8bf1 100644
--- a/include/mailutils/filter.h
+++ b/include/mailutils/filter.h
@@ -42,6 +42,7 @@ struct mu_filter_io
char *output;
size_t osize;
int errcode;
+ int eof;
};
enum mu_filter_command
@@ -57,7 +58,7 @@ enum mu_filter_result
mu_filter_ok,
mu_filter_falure,
mu_filter_moreinput,
- mu_filter_moreoutput,
+ mu_filter_moreoutput
};
typedef int (*mu_filter_new_data_t) (void **, int, void *);
diff --git a/include/mailutils/pop3.h b/include/mailutils/pop3.h
index d1c7db5da..f815be883 100644
--- a/include/mailutils/pop3.h
+++ b/include/mailutils/pop3.h
@@ -29,7 +29,7 @@ extern "C" {
#endif
struct _mu_pop3;
-typedef struct _mu_pop3* mu_pop3_t;
+typedef struct _mu_pop3 *mu_pop3_t;
#define MU_POP3_DEFAULT_PORT 110
@@ -45,23 +45,28 @@ extern int mu_pop3_disconnect (mu_pop3_t pop3);
extern int mu_pop3_set_timeout (mu_pop3_t pop3, int timeout);
extern int mu_pop3_get_timeout (mu_pop3_t pop3, int *timeout);
-extern int mu_pop3_set_debug (mu_pop3_t pop3, mu_debug_t debug);
+#define MU_POP3_TRACE_CLR 0
+#define MU_POP3_TRACE_SET 1
+#define MU_POP3_TRACE_QRY 2
+extern int mu_pop3_trace (mu_pop3_t pop3, int op);
extern int mu_pop3_apop (mu_pop3_t pop3, const char *name, const char *digest);
extern int mu_pop3_stls (mu_pop3_t pop3);
-/* It is the responsability of the caller to call mu_iterator_destroy() when done
- with the iterator. The items return by the iterator are of type "const char *",
- no processing is done on the item except the removal of the trailing newline. */
-extern int mu_pop3_capa (mu_pop3_t pop3, mu_iterator_t *iterator);
+/* It is the responsability of the caller to call mu_iterator_destroy() when
+ done with the iterator. The items returned by the iterator are of type
+ "const char *", no processing is done on the item except the removal of
+ the trailing newline. */
+extern int mu_pop3_capa (mu_pop3_t pop3, int reread,
+ mu_iterator_t *piter);
extern int mu_pop3_dele (mu_pop3_t pop3, unsigned int mesgno);
extern int mu_pop3_list (mu_pop3_t pop3, unsigned int mesgno, size_t *mesg_octet);
-/* An iterator is return with the multi-line answer. It is the responsability of
- the caller to call mu_iterator_destroy() to dispose of the iterator. */
+/* An iterator is return with the multi-line answer. It is the responsability
+ of the caller to call mu_iterator_destroy() to dispose of the iterator. */
extern int mu_pop3_list_all (mu_pop3_t pop3, mu_iterator_t *piterator);
extern int mu_pop3_noop (mu_pop3_t pop3);
@@ -70,49 +75,44 @@ extern int mu_pop3_pass (mu_pop3_t pop3, const char *pass);
extern int mu_pop3_quit (mu_pop3_t pop3);
-/* A stream is return with the multi-line answer. It is the responsability of
- the caller to call mu_stream_destroy() to dipose of the stream. */
-extern int mu_pop3_retr (mu_pop3_t pop3, unsigned int mesgno, mu_stream_t *pstream);
+/* A stream is returned with the multi-line answer. It is the responsability
+ of the caller to call mu_stream_destroy() to dipose of the stream. */
+extern int mu_pop3_retr (mu_pop3_t pop3, unsigned int mesgno,
+ mu_stream_t *pstream);
extern int mu_pop3_rset (mu_pop3_t pop3);
-extern int mu_pop3_stat (mu_pop3_t pop3, unsigned int *count, size_t *octets);
-
-/* A stream is return with the multi-line answer. It is the responsability of
- the caller to call mu_stream_destroy() to dipose of the stream. */
-extern int mu_pop3_top (mu_pop3_t pop3, unsigned int mesgno, unsigned int lines, mu_stream_t *pstream);
-
-/* The uidl is malloc and return in puidl, it is the responsability of caller
- to free() the uild when done. */
-extern int mu_pop3_uidl (mu_pop3_t pop3, unsigned int mesgno, char **puidl);
-/* An iterator is return with the multi-line answer. It is the responsability of
- the caller to call mu_iterator_destroy() to dispose of the iterator. */
+extern int mu_pop3_stat (mu_pop3_t pop3, unsigned int *count,
+ size_t *octets);
+
+/* A stream is returned with the multi-line answer. It is the responsability
+ of the caller to call mu_stream_destroy() to dipose of the stream. */
+extern int mu_pop3_top (mu_pop3_t pop3, unsigned int mesgno,
+ unsigned int lines, mu_stream_t *pstream);
+
+/* The uidl is malloc'ed and returned in puidl; it is the responsability of
+ the caller to free() the uild when done. */
+extern int mu_pop3_uidl (mu_pop3_t pop3, unsigned int mesgno,
+ char **puidl);
+/* An iterator is returned with the multi-line answer. It is the
+ responsability of the caller to call mu_iterator_destroy() to dispose of
+ the iterator. */
extern int mu_pop3_uidl_all (mu_pop3_t pop3, mu_iterator_t *piterator);
extern int mu_pop3_user (mu_pop3_t pop3, const char *user);
-/* Reads the multi-line response of the server, nread will be 0 when the termination octets
- are detected. Clients should not use this function unless they are sending direct command. */
-extern int mu_pop3_readline (mu_pop3_t pop3, char *buffer, size_t buflen, size_t *nread);
-/* Returns the last command acknowledge. If the server supports RESP-CODE, the message
- could be retrieve, but it is up the caller to do the parsing. */
-extern int mu_pop3_response (mu_pop3_t pop3, char *buffer, size_t buflen, size_t *nread);
+/* Returns the last command acknowledge. If the server supports RESP-CODE,
+ the message could be retrieved, but it is up to the caller to do the
+ parsing. */
+extern int mu_pop3_response (mu_pop3_t pop3, size_t *nread);
-/* pop3_writeline copies the line in the internal buffer, a mu_pop3_send() is
- needed to do the actual transmission. */
extern int mu_pop3_writeline (mu_pop3_t pop3, const char *format, ...)
MU_PRINTFLIKE(2,3);
-/* mu_pop3_sendline() is equivalent to:
- mu_pop3_writeline (pop3, line);
- mu_pop3_send (pop3);
- */
extern int mu_pop3_sendline (mu_pop3_t pop3, const char *line);
-
-/* Transmit via the carrier the internal buffer data. */
-extern int mu_pop3_send (mu_pop3_t pop3);
+extern int mu_pop3_getline (mu_pop3_t pop3);
#ifdef __cplusplus
}
diff --git a/include/mailutils/sys/pop3.h b/include/mailutils/sys/pop3.h
index 35b116522..1c81579d0 100644
--- a/include/mailutils/sys/pop3.h
+++ b/include/mailutils/sys/pop3.h
@@ -37,115 +37,111 @@ enum mu_pop3_state
{
MU_POP3_NO_STATE,
MU_POP3_CONNECT, MU_POP3_GREETINGS,
- MU_POP3_APOP, MU_POP3_APOP_ACK,
- MU_POP3_AUTH, MU_POP3_AUTH_ACK,
- MU_POP3_CAPA, MU_POP3_CAPA_ACK, MU_POP3_CAPA_RX,
- MU_POP3_DELE, MU_POP3_DELE_ACK,
- MU_POP3_LIST, MU_POP3_LIST_ACK, MU_POP3_LIST_RX,
- MU_POP3_NOOP, MU_POP3_NOOP_ACK,
- MU_POP3_PASS, MU_POP3_PASS_ACK,
- MU_POP3_QUIT, MU_POP3_QUIT_ACK,
- MU_POP3_RETR, MU_POP3_RETR_ACK, MU_POP3_RETR_RX,
- MU_POP3_RSET, MU_POP3_RSET_ACK,
- MU_POP3_STAT, MU_POP3_STAT_ACK,
- MU_POP3_STLS, MU_POP3_STLS_ACK, MU_POP3_STLS_CONNECT,
- MU_POP3_TOP, MU_POP3_TOP_ACK, MU_POP3_TOP_RX,
- MU_POP3_UIDL, MU_POP3_UIDL_ACK, MU_POP3_UIDL_RX,
- MU_POP3_USER, MU_POP3_USER_ACK,
- MU_POP3_DONE, MU_POP3_UNKNOWN, MU_POP3_ERROR
- };
-
-/* Structure holding the data necessary to do proper buffering. */
-struct mu_pop3_work_buf
- {
- char *buf;
- char *ptr;
- char *nl;
- size_t len;
+ MU_POP3_APOP,
+ MU_POP3_AUTH,
+ MU_POP3_CAPA, MU_POP3_CAPA_RX,
+ MU_POP3_DELE,
+ MU_POP3_LIST, MU_POP3_LIST_RX,
+ MU_POP3_NOOP,
+ MU_POP3_PASS,
+ MU_POP3_QUIT,
+ MU_POP3_RETR, MU_POP3_RETR_RX,
+ MU_POP3_RSET,
+ MU_POP3_STAT,
+ MU_POP3_STLS, MU_POP3_STLS_CONNECT,
+ MU_POP3_TOP, MU_POP3_TOP_RX,
+ MU_POP3_UIDL, MU_POP3_UIDL_RX,
+ MU_POP3_USER,
+ MU_POP3_DONE,
+ MU_POP3_UNKNOWN,
+ MU_POP3_ERROR
};
+#define MU_POP3_ACK 0x01
+#define MU_POP3_TRACE 0x02
+
/* Structure to hold things general to POP3 mailbox, like its state, etc ... */
struct _mu_pop3
{
- /* Working I/O buffer.
- io.buf: Working io buffer
- io.ptr: Points to the end of the buffer, the non consumed chars
- io.nl: Points to the '\n' char in the string
- io.len: Len of io_buf. */
- struct mu_pop3_work_buf io;
-
- /* Holds the first line response of the last command, i.e the ACK:
- ack.buf: Buffer for the ack
- ack.ptr: Working pointer, indicate the start of the non consumed chars
- ack.len: Size 512 according to RFC2449. */
- struct mu_pop3_work_buf ack;
- int acknowledge;
-
- char *timestamp; /* For apop, if supported. */
- unsigned timeout; /* Default is 10 minutes. */
-
- mu_debug_t debug; /* debugging trace. */
-
- enum mu_pop3_state state; /* Indicate the state of the running command. */
-
- mu_stream_t carrier; /* TCP Connection. */
+ int flags;
+
+ /* Holds the first line response of the last command, i.e the ACK */
+ char *ackbuf;
+ size_t acksize;
+
+ char *rdbuf;
+ size_t rdsize;
+
+ char *timestamp; /* For apop, if supported. */
+ unsigned timeout; /* Default is 10 minutes. */
+
+ enum mu_pop3_state state; /* Indicate the state of the running
+ command. */
+ mu_list_t capa; /* Capabilities. */
+ mu_stream_t carrier; /* TCP Connection. */
};
-extern int mu_pop3_debug_cmd (mu_pop3_t);
-extern int mu_pop3_debug_ack (mu_pop3_t);
+#define MU_POP3_FSET(p,f) ((p)->flags |= (f))
+#define MU_POP3_FISSET(p,f) ((p)->flags & (f))
+#define MU_POP3_FCLR(p,f) ((p)->flags &= ~(f))
+
extern int mu_pop3_iterator_create (mu_pop3_t pop3, mu_iterator_t *piterator);
extern int mu_pop3_stream_create (mu_pop3_t pop3, mu_stream_t *pstream);
-extern int mu_pop3_carrier_is_ready (mu_stream_t carrier, int flag, int timeout);
+extern int mu_pop3_carrier_is_ready (mu_stream_t carrier, int flag,
+ int timeout);
+
+int _mu_pop3_trace_enable (mu_pop3_t pop3);
+int _mu_pop3_trace_disable (mu_pop3_t pop3);
+int _mu_pop3_init (mu_pop3_t pop3);
+
/* Check for non recoverable error.
The error is consider not recoverable if not part of the signal set:
EAGAIN, EINPROGRESS, EINTR.
For unrecoverable error we reset, by moving the working ptr
to the begining of the buffer and setting the state to error.
*/
-#define MU_POP3_CHECK_EAGAIN(pop3, status) \
-do \
- { \
- if (status != 0) \
- { \
- if (status != EAGAIN && status != EINPROGRESS && status != EINTR) \
- { \
- pop3->io.ptr = pop3->io.buf; \
- pop3->state = MU_POP3_ERROR; \
- } \
- return status; \
- } \
- } \
-while (0)
+#define MU_POP3_CHECK_EAGAIN(pop3, status) \
+ do \
+ { \
+ if (status != 0) \
+ { \
+ if (status != EAGAIN && status != EINPROGRESS && status != EINTR) \
+ { \
+ pop3->state = MU_POP3_ERROR; \
+ } \
+ return status; \
+ } \
+ } \
+ while (0)
/* If error return.
Check status an reset(see MU_POP2_CHECK_EAGAIN) the buffer.
*/
-#define MU_POP3_CHECK_ERROR(pop3, status) \
-do \
- { \
- if (status != 0) \
- { \
- pop3->io.ptr = pop3->io.buf; \
- pop3->state = MU_POP3_ERROR; \
- return status; \
- } \
- } \
-while (0)
+#define MU_POP3_CHECK_ERROR(pop3, status) \
+ do \
+ { \
+ if (status != 0) \
+ { \
+ pop3->state = MU_POP3_ERROR; \
+ return status; \
+ } \
+ } \
+ while (0)
/* Check if we got "+OK".
In POP3 protocol and ack of "+OK" means the command was successfull.
*/
-#define MU_POP3_CHECK_OK(pop3) \
-do \
- { \
- if (mu_c_strncasecmp (pop3->ack.buf, "+OK", 3) != 0) \
- { \
- pop3->state = MU_POP3_NO_STATE; \
- return EACCES; \
- } \
- } \
-while (0)
+#define MU_POP3_CHECK_OK(pop3) \
+ do \
+ { \
+ if (mu_c_strncasecmp (pop3->ackbuf, "+OK", 3) != 0) \
+ { \
+ pop3->state = MU_POP3_NO_STATE; \
+ return EACCES; \
+ } \
+ } \
+ while (0)
#ifdef __cplusplus
}
diff --git a/include/mailutils/tls.h b/include/mailutils/tls.h
index 856e474d7..41a5234f4 100644
--- a/include/mailutils/tls.h
+++ b/include/mailutils/tls.h
@@ -47,10 +47,13 @@ extern int mu_check_tls_environment (void);
extern int mu_init_tls_libs (void);
extern void mu_deinit_tls_libs (void);
-typedef int (*mu_tls_readline_fn) (void *iodata);
-typedef int (*mu_tls_writeline_fn) (void *iodata, char *buf);
-typedef void (*mu_tls_stream_ctl_fn) (void *iodata, mu_stream_t *pold,
- mu_stream_t __new);
+typedef int (*mu_tls_readline_fn) (void *iodata, int n);
+typedef int (*mu_tls_writeline_fn) (void *iodata, char *buf);
+
+#define MU_TLS_SESS_GET_STREAMS 0
+#define MU_TLS_SESS_SET_STREAMS 1
+typedef int (*mu_tls_stream_ctl_fn) (void *iodata, int __op,
+ mu_stream_t *pstr);
extern int mu_tls_begin (void *iodata, mu_tls_readline_fn reader,
mu_tls_writeline_fn writer,
diff --git a/libmu_auth/tls.c b/libmu_auth/tls.c
index 4ad23be6e..3b89baca1 100644
--- a/libmu_auth/tls.c
+++ b/libmu_auth/tls.c
@@ -115,11 +115,23 @@ mu_check_tls_environment (void)
int mu_tls_enable = 0;
+#if 0
+void
+_mu_gtls_logger(int level, const char *text)
+{
+ mu_diag_output (MU_DIAG_DEBUG, "GnuTLS(%d): %s", level, text);
+}
+#endif
+
int
mu_init_tls_libs (void)
{
if (mu_tls_module_config.enable && !mu_tls_enable)
mu_tls_enable = !gnutls_global_init (); /* Returns 1 on success */
+#if 0
+ gnutls_global_set_log_function (_mu_gtls_logger);
+ gnutls_global_set_log_level (110);
+#endif
return mu_tls_enable;
}
@@ -161,7 +173,7 @@ mu_tls_begin (void *iodata,
{
int i = 0;
int status;
- mu_stream_t oldstr, newstr;
+ mu_stream_t streams[2], newstr;
if (keywords == NULL)
return EINVAL;
@@ -181,19 +193,23 @@ mu_tls_begin (void *iodata,
return status;
}
- status = reader (iodata);
+ status = reader (iodata, i);
if (status != 0)
{
mu_error ("mu_tls_begin: reader (0): %s", mu_strerror (status));
return status;
}
- stream_ctl (iodata, &oldstr, NULL);
- status = mu_tls_client_stream_create (&newstr, oldstr, oldstr, 0);
+ status = stream_ctl (iodata, MU_TLS_SESS_GET_STREAMS, streams);
+ if (status)
+ return status;
+ status = mu_tls_client_stream_create (&newstr,
+ streams[0], streams[1], 0);
if (status != 0)
{
mu_error ("mu_tls_begin: mu_tls_client_stream_create(0): %s",
mu_strerror (status));
+ stream_ctl (iodata, MU_TLS_SESS_SET_STREAMS, streams);
return status;
}
@@ -202,10 +218,13 @@ mu_tls_begin (void *iodata,
{
mu_error ("mu_tls_begin: mu_stream_open (0): %s",
mu_strerror (status));
+ stream_ctl (iodata, MU_TLS_SESS_SET_STREAMS, streams);
return status;
}
- stream_ctl (iodata, NULL, newstr);
+ streams[0] = streams[1] = newstr;
+ stream_ctl (iodata, MU_TLS_SESS_SET_STREAMS, streams);
+ /* FIXME: Unref newstr */
break;
case 1:
@@ -219,7 +238,7 @@ mu_tls_begin (void *iodata,
return status;
}
- status = reader (iodata);
+ status = reader (iodata, i);
if (status != 0)
{
mu_error ("mu_tls_begin: reader (1): %s", mu_strerror (status));
@@ -402,7 +421,7 @@ _tls_stream_pull (gnutls_transport_ptr fd, void *buf, size_t size)
while ((rc = mu_stream_read (stream, buf, size, &rdbytes)) == EAGAIN)
;
-
+
if (rc)
return -1;
return rdbytes;
@@ -420,6 +439,7 @@ _tls_stream_push (gnutls_transport_ptr fd, const void *buf, size_t size)
mu_error ("_tls_stream_push: %s", mu_strerror (rc)); /* FIXME */
return -1;
}
+
mu_stream_flush (stream);
return size;
}
@@ -475,9 +495,11 @@ _tls_server_open (mu_stream_t stream)
}
static int
-prepare_client_session (struct _mu_tls_stream *sp)
+prepare_client_session (mu_stream_t stream)
{
+ struct _mu_tls_stream *sp = (struct _mu_tls_stream *) stream;
int rc;
+ mu_transport_t transport[2];
static int protocol_priority[] = {GNUTLS_TLS1, GNUTLS_SSL3, 0};
static int kx_priority[] = {GNUTLS_KX_RSA, 0};
static int cipher_priority[] = {GNUTLS_CIPHER_3DES_CBC,
@@ -508,9 +530,10 @@ prepare_client_session (struct _mu_tls_stream *sp)
gnutls_credentials_set (sp->session, GNUTLS_CRD_CERTIFICATE, x509_cred);
+ mu_stream_ioctl (stream, MU_IOCTL_GET_TRANSPORT, transport);
gnutls_transport_set_ptr2 (sp->session,
- (gnutls_transport_ptr) sp->transport[0],
- (gnutls_transport_ptr) sp->transport[1]);
+ (gnutls_transport_ptr) transport[0],
+ (gnutls_transport_ptr) transport[1]);
gnutls_transport_set_pull_function (sp->session, _tls_stream_pull);
gnutls_transport_set_push_function (sp->session, _tls_stream_push);
@@ -532,7 +555,7 @@ _tls_client_open (mu_stream_t stream)
/* FALLTHROUGH */
case state_init:
- prepare_client_session (sp);
+ prepare_client_session (stream);
rc = gnutls_handshake (sp->session);
if (rc < 0)
{
diff --git a/libproto/pop/Makefile.am b/libproto/pop/Makefile.am
index 3f0564a9c..b4bf3a8a8 100644
--- a/libproto/pop/Makefile.am
+++ b/libproto/pop/Makefile.am
@@ -24,17 +24,16 @@ lib_LTLIBRARIES = libmu_pop.la
libmu_pop_la_LDFLAGS=-version-info @VI_CURRENT@:@VI_REVISION@:@VI_AGE@
libmu_pop_la_LIBADD = ${MU_LIB_AUTH} ${MU_LIB_MAILUTILS} @INTLLIBS@
+# folder.c\
+# mbox.c\
+# url.c
libmu_pop_la_SOURCES = \
- folder.c\
- mbox.c\
- url.c \
\
pop3_apop.c \
pop3_capa.c \
pop3_carrier.c \
pop3_connect.c \
pop3_create.c \
- pop3_debug.c \
pop3_dele.c \
pop3_destroy.c \
pop3_disconnect.c \
@@ -54,6 +53,7 @@ libmu_pop_la_SOURCES = \
pop3_stream.c \
pop3_timeout.c \
pop3_top.c \
+ pop3_trace.c \
pop3_uidla.c \
pop3_uidl.c \
pop3_user.c
diff --git a/libproto/pop/pop3_apop.c b/libproto/pop/pop3_apop.c
index 454c3e51e..c358b935e 100644
--- a/libproto/pop/pop3_apop.c
+++ b/libproto/pop/pop3_apop.c
@@ -39,15 +39,11 @@ mu_pop3_apop (mu_pop3_t pop3, const char *user, const char *secret)
/* Sanity checks. */
if (pop3 == NULL || user == NULL || secret == NULL)
- {
- return EINVAL;
- }
+ return EINVAL;
/* The server did not offer a timestamp in the greeting, bailout early. */
if (pop3->timestamp == NULL)
- {
- return ENOTSUP;
- }
+ return ENOTSUP;
switch (pop3->state)
{
@@ -61,35 +57,25 @@ mu_pop3_apop (mu_pop3_t pop3, const char *user, const char *secret)
size_t n;
mu_md5_init_ctx (&md5context);
- mu_md5_process_bytes (pop3->timestamp, strlen (pop3->timestamp), &md5context);
+ mu_md5_process_bytes (pop3->timestamp, strlen (pop3->timestamp),
+ &md5context);
mu_md5_process_bytes (secret, strlen (secret), &md5context);
mu_md5_finish_ctx (&md5context, md5digest);
for (tmp = digest, n = 0; n < 16; n++, tmp += 2)
- {
- sprintf (tmp, "%02x", md5digest[n]);
- }
+ sprintf (tmp, "%02x", md5digest[n]);
*tmp = '\0';
status = mu_pop3_writeline (pop3, "APOP %s %s\r\n", user, digest);
/* Obscure the digest, for security reasons. */
memset (digest, '\0', sizeof digest);
MU_POP3_CHECK_ERROR (pop3, status);
- mu_pop3_debug_cmd (pop3);
+ MU_POP3_FCLR (pop3, MU_POP3_ACK);
pop3->state = MU_POP3_APOP;
}
case MU_POP3_APOP:
- status = mu_pop3_send (pop3);
- MU_POP3_CHECK_EAGAIN (pop3, status);
- /* Obscure the digest, for security reasons. */
- memset (pop3->io.buf, '\0', pop3->io.len);
- pop3->acknowledge = 0;
-