summaryrefslogtreecommitdiff
path: root/mailbox/xscript-stream.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-09-07 18:06:11 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-09-07 22:48:23 +0300
commitf08e6e0842bae2dd575b085a8182cdd0f0d55cc5 (patch)
treee3f8db0cf4c735771eee74a4239914a62106683a /mailbox/xscript-stream.c
parent817286698ccc3f262cd0003401becef6c11050ae (diff)
downloadmailutils-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.c166
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);

Return to:

Send suggestions and report system problems to the System administrator.