diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-09-07 18:06:11 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-09-07 22:48:23 +0300 |
commit | f08e6e0842bae2dd575b085a8182cdd0f0d55cc5 (patch) | |
tree | e3f8db0cf4c735771eee74a4239914a62106683a /mailbox/xscript-stream.c | |
parent | 817286698ccc3f262cd0003401becef6c11050ae (diff) | |
download | mailutils-f08e6e0842bae2dd575b085a8182cdd0f0d55cc5.tar.gz mailutils-f08e6e0842bae2dd575b085a8182cdd0f0d55cc5.tar.bz2 |
Improve transcript stream.
* include/mailutils/stream.h (MU_IOCTL_LEVEL): New ioctl op.
(XSCRIPT_NORMAL, XSCRIPT_SECURE, XSCRIPT_PAYLOAD): New constants.
* include/mailutils/sys/xscript-stream.h (_mu_xscript_stream)
<level>: New member.
* mailbox/xscript-stream.c (TRANS_DISABLED): New flag.
(print_transcript): Amount of output varies depending on the
current output level. For secure data, try to recognize passwords
and to replace them with *** on output.
(_xscript_ctl): Support MU_IOCTL_LEVEL.
* pop3d/extra.c (set_xscript_level): New function.
* pop3d/pop3d.h (set_xscript_level): New proto.
* pop3d/retr.c (pop3d_retr): Set XSCRIPT_PAYLOAD level before
sending actual data and reset it to XSCRIPT_NORMAL afterwards.
* pop3d/top.c (pop3d_top): Likewise.
* pop3d/user.c: Set XSCRIPT_SECURE level while expecting the
PASS command.
* imap4d/fetch.c (imap4d_fetch): Run imap4d_fetch0 in XSCRIPT_PAYLOAD
level.
* imap4d/uid.c (imap4d_uid): Likewise.
* imap4d/imap4d.c (imap4d_mainloop): Unless started in preauth mode,
select XSCRIPT_SECURE mode until authentication has been passed.
* imap4d/imap4d.h (set_xscript_level): New proto.
* imap4d/io.c (io_format_completion_response): Switch to XSCRIPT_NORMAL
level when changing to the authenticated state.
(imap4d_readline): Read literals in XSCRIPT_PAYLOAD level.
* imap4d/util.c (set_xscript_level): New function.
* include/mailutils/pop3.h (mu_pop3_trace_mask): New prototype.
(MU_POP3_XSCRIPT_MASK): New macro.
(_mu_pop3_xscript_level): New proto.
* libproto/pop/pop3_pass.c (mu_pop3_pass): Set XSCRIPT_SECURE
while sending the password.
* libproto/pop/pop3_retr.c (mu_pop3_retr): Set XSCRIPT_PAYLOAD before
going to MU_POP3_RETR_RX state.
* libproto/pop/pop3_stream.c (_pop3_event_cb): Set XSCRIPT_NORMAL.
* libproto/pop/pop3_top.c (mu_pop3_top): Set XSCRIPT_PAYLOAD before
going to MU_POP3_TOP_RX state.
* libproto/pop/pop3_trace.c (mu_pop3_trace_mask)
(_mu_pop3_xscript_level): New functions.
* libproto/pop/mbox.c (pop_open): Set trace masks depending on the
trace6 and trace7 debug levels.
* examples/pop3client.c (com_verbose): Allow to mask/unmask transcript
levels.
Diffstat (limited to 'mailbox/xscript-stream.c')
-rw-r--r-- | mailbox/xscript-stream.c | 166 |
1 files changed, 132 insertions, 34 deletions
diff --git a/mailbox/xscript-stream.c b/mailbox/xscript-stream.c index 993047560..054ced12c 100644 --- a/mailbox/xscript-stream.c +++ b/mailbox/xscript-stream.c @@ -30,6 +30,8 @@ #include <mailutils/stream.h> #include <mailutils/sys/stream.h> #include <mailutils/sys/xscript-stream.h> +#include <mailutils/cctype.h> +#include <mailutils/cstr.h> /* A "transcript stream" transparently writes data to and reads data from an underlying transport stream, writing each lineful of data to a "log @@ -38,47 +40,131 @@ RFCs -- "S: ", for data written ("Server"), and "C: ", for data read ("Client"). */ -#define TRANS_READ 0x1 -#define TRANS_WRITE 0x2 +#define TRANS_READ 0x1 +#define TRANS_WRITE 0x2 +#define TRANS_DISABLED 0x4 #define FLAG_TO_PFX(c) ((c) - 1) +static int +word_match (const char *buf, size_t len, int n, const char *word, + size_t *pos) +{ + size_t i = 0; + size_t wl = strlen (word); + + for (;; n--) + { + /* Skip whitespace separator */ + for (; i < len && mu_isspace (buf[i]); i++) + ; + + if (n == 0) + break; + + /* Skip the argument */ + if (buf[i] == '"') + { + for (i++; i < len && buf[i] != '"'; i++) + if (buf[i] == '\'') + i++; + } + else + { + for (; i < len && !mu_isspace (buf[i]); i++) + ; + } + } + + if (i + wl <= len && + mu_c_strncasecmp (buf + i, word, wl) == 0 && + mu_isblank (buf[i + wl])) + { + *pos = i + wl; + return 1; + } + + return 0; +} + static void print_transcript (struct _mu_xscript_stream *str, int flag, const char *buf, size_t size) { - while (size) - { - const char *p; - size_t len; - - if (str->flags & flag) - { - mu_stream_write (str->logstr, - str->prefix[FLAG_TO_PFX(flag)], - strlen (str->prefix[FLAG_TO_PFX (flag)]), - NULL); - str->flags &= ~flag; - } - p = memchr (buf, '\n', size); - if (p) - { - len = p - buf; - if (p > buf && p[-1] == '\r') - len--; + while (size) + { + const char *p; + size_t len; + + if (str->flags & flag) + { + mu_stream_write (str->logstr, + str->prefix[FLAG_TO_PFX(flag)], + strlen (str->prefix[FLAG_TO_PFX (flag)]), + NULL); + str->flags &= ~(flag | TRANS_DISABLED); + } + + if (str->flags & TRANS_DISABLED) + return; + + if (str->level == XSCRIPT_PAYLOAD) + { + mu_stream_printf (str->logstr, "(data...)\n"); + str->flags |= TRANS_DISABLED; + return; + } + + p = memchr (buf, '\n', size); + if (p) + { + len = p - buf; + if (p > buf && p[-1] == '\r') + len--; + + if (str->level == XSCRIPT_SECURE) + { + size_t i; + + if (word_match (buf, len, 0, "PASS", &i)) + mu_stream_printf (str->logstr, "PASS ***"); + else if (word_match (buf, len, 1, "LOGIN", &i)) + { + /* Skip the whitespace separator */ + for (; i < len && mu_isspace (buf[i]); i++) + ; + /* Skip the first argument (presumably the user name) */ + if (buf[i] == '"') + { + for (i++; i < len && buf[i] != '"'; i++) + if (buf[i] == '\'') + i++; + } + else + { + for (; i < len && !mu_isspace (buf[i]); i++) + ; + } + mu_stream_write (str->logstr, buf, i, NULL); + mu_stream_write (str->logstr, " \"***\"", 6, NULL); + } + else + mu_stream_write (str->logstr, buf, len, NULL); + } + else mu_stream_write (str->logstr, buf, len, NULL); - mu_stream_write (str->logstr, "\n", 1, NULL); - str->flags |= flag; - - len = p - buf + 1; - buf = p + 1; - size -= len; - } - else - { - mu_stream_write (str->logstr, buf, size, NULL); - break; - } - } + mu_stream_write (str->logstr, "\n", 1, NULL); + str->flags |= flag; + + len = p - buf + 1; + buf = p + 1; + size -= len; + } + else + { + mu_stream_write (str->logstr, buf, size, NULL); + break; + } + } } static int @@ -228,6 +314,18 @@ _xscript_ctl (struct _mu_stream *str, int op, void *arg) status = 0; } break; + + case MU_IOCTL_LEVEL: + if (!arg) + return EINVAL; + else + { + int oldlev = sp->level; + sp->level = *(int*)arg; + sp->flags = TRANS_READ | TRANS_WRITE; + *(int*)arg = oldlev; + } + break; default: return mu_stream_ioctl (sp->transport, op, arg); |