commit-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Mailutils branch, stream-cleanup, updated. rel-2_1-131-g420212


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, stream-cleanup, updated. rel-2_1-131-g420212a
Date: Tue, 07 Sep 2010 19:58:07 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Mailutils".

http://git.savannah.gnu.org/cgit/mailutils.git/commit/?id=420212a69bba00b4474b26d8da66ee338b8f771f

The branch, stream-cleanup has been updated
       via  420212a69bba00b4474b26d8da66ee338b8f771f (commit)
       via  f08e6e0842bae2dd575b085a8182cdd0f0d55cc5 (commit)
      from  817286698ccc3f262cd0003401becef6c11050ae (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 420212a69bba00b4474b26d8da66ee338b8f771f
Author: Sergey Poznyakoff <address@hidden>
Date:   Tue Sep 7 22:54:40 2010 +0300

    Rename XSCRIPT_ macros to MU_XSCRIPT.

commit f08e6e0842bae2dd575b085a8182cdd0f0d55cc5
Author: Sergey Poznyakoff <address@hidden>
Date:   Tue Sep 7 18:06:11 2010 +0300

    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.

-----------------------------------------------------------------------

Summary of changes:
 examples/pop3client.c                  |  127 +++++++++++++++++++++----
 imap4d/fetch.c                         |    3 +-
 imap4d/imap4d.c                        |    5 +-
 imap4d/imap4d.h                        |    4 +-
 imap4d/io.c                            |    8 ++-
 imap4d/uid.c                           |    6 +-
 imap4d/util.c                          |   19 ++++
 include/mailutils/pop3.h               |    1 +
 include/mailutils/stream.h             |    9 ++
 include/mailutils/sys/pop3.h           |    3 +
 include/mailutils/sys/xscript-stream.h |    1 +
 libproto/pop/mbox.c                    |   10 ++-
 libproto/pop/pop3_pass.c               |    5 +-
 libproto/pop/pop3_retr.c               |    2 +
 libproto/pop/pop3_stream.c             |    1 +
 libproto/pop/pop3_top.c                |    2 +
 libproto/pop/pop3_trace.c              |   32 ++++++
 mailbox/xscript-stream.c               |  166 +++++++++++++++++++++++++-------
 pop3d/extra.c                          |   20 ++++
 pop3d/pop3d.h                          |    2 +
 pop3d/retr.c                           |    4 +
 pop3d/top.c                            |    5 +
 pop3d/user.c                           |    5 +-
 23 files changed, 378 insertions(+), 62 deletions(-)

diff --git a/examples/pop3client.c b/examples/pop3client.c
index 677cd88..c924638 100644
--- a/examples/pop3client.c
+++ b/examples/pop3client.c
@@ -131,8 +131,8 @@ COMMAND commands[] = {
     "Get the unique id of message: UIDL [msgno]" },
   { "user",       2, 2, com_user,
     "send login: USER user" },
-  { "verbose",    1, 2, com_verbose,
-    "Enable Protocol tracing: verbose [on|off]" },
+  { "verbose",    1, 4, com_verbose,
+    "Enable Protocol tracing: verbose [on|off|mask|unmask] [x1 [x2]]" },
 #ifdef WITH_READLINE
   { "history",    1, 1, com_history,
     "Show command history" },
@@ -145,6 +145,14 @@ mu_pop3_t pop3;
 
 /* Flag if verbosity is needed.  */
 int verbose;
+#define VERBOSE_MASK(n) (1<<((n)+1))
+#define SET_VERBOSE_MASK(n) (verbose |= VERBOSE_MASK (n))
+#define CLR_VERBOSE_MASK(n) (verbose &= VERBOSE_MASK (n))
+#define QRY_VERBOSE_MASK(n) (verbose & VERBOSE_MASK (n))
+#define HAS_VERBOSE_MASK(n) (verbose & ~1)
+#define SET_VERBOSE() (verbose |= 1)
+#define CLR_VERBOSE() (verbose &= ~1)
+#define QRY_VERBOSE() (verbose & 1)
 
 /* When non-zero, this global means the user is done using this program. */
 int done;
@@ -408,10 +416,8 @@ get_bool (const char *str, int *pb)
       || mu_c_strcasecmp (str, "false") == 0)
     *pb = 0;
   else
-    {
-      mu_error ("not a boolean: %s", str);
-      return 1;
-    }
+    return 1;
+
   return 0;
 }
 
@@ -509,13 +515,91 @@ find_command (char *name)
   return NULL;
 }
 
+static int
+string_to_xlev (const char *name, int *pv)
+{
+  if (strcmp (name, "secure") == 0)
+    *pv = MU_XSCRIPT_SECURE;
+  else if (strcmp (name, "payload") == 0)
+    *pv = MU_XSCRIPT_PAYLOAD;
+  else
+    return 1;
+  return 0;
+}
+
+static int
+change_verbose_mask (int set, int argc, char **argv)
+{
+  int i;
+  
+  for (i = 0; i < argc; i++)
+    {
+      int lev;
+      
+      if (string_to_xlev (argv[i], &lev))
+       {
+         mu_error ("unknown level: %s", argv[i]);
+         return 1;
+       }
+      if (set)
+       SET_VERBOSE_MASK (lev);
+      else
+       CLR_VERBOSE_MASK (lev);
+    }
+  return 0;
+}
+
+void
+set_verbose (mu_pop3_t p)
+{
+  if (p)
+    {
+      if (QRY_VERBOSE ())
+       {
+         mu_pop3_trace (p, MU_POP3_TRACE_SET);
+       }
+      else
+       mu_pop3_trace (p, MU_POP3_TRACE_CLR);
+    }
+}
+
+void
+set_verbose_mask (mu_pop3_t p)
+{
+  if (p)
+    {
+      mu_pop3_trace_mask (p, QRY_VERBOSE_MASK (MU_XSCRIPT_SECURE)
+                                 ? MU_POP3_TRACE_SET : MU_POP3_TRACE_CLR,
+                             MU_XSCRIPT_SECURE);
+      mu_pop3_trace_mask (p, QRY_VERBOSE_MASK (MU_XSCRIPT_PAYLOAD)
+                                 ? MU_POP3_TRACE_SET : MU_POP3_TRACE_CLR,
+                             MU_XSCRIPT_PAYLOAD);
+    }
+}
+
 int
 com_verbose (int argc, char **argv)
 {
   if (argc == 1)
     {
-      if (verbose)
-       printf ("verbose is on\n");
+      if (QRY_VERBOSE ())
+       {
+         printf ("verbose is on");
+         if (HAS_VERBOSE_MASK ())
+           {
+             char *delim = " (";
+           
+             if (QRY_VERBOSE_MASK (MU_XSCRIPT_SECURE))
+               {
+                 printf("%ssecure", delim);
+                 delim = ", ";
+               }
+             if (QRY_VERBOSE_MASK (MU_XSCRIPT_PAYLOAD))
+               printf("%spayload", delim);
+             printf (")");
+           }
+         printf ("\n");
+       }
       else
        printf ("verbose is off\n");
     }
@@ -525,16 +609,20 @@ com_verbose (int argc, char **argv)
 
       if (get_bool (argv[1], &bv) == 0)
        {
-         verbose = bv;
-         if (pop3 != NULL)
-           {
-             if (verbose == 1)
-               mu_pop3_trace (pop3, MU_POP3_TRACE_SET);
-             else
-               mu_pop3_trace (pop3, MU_POP3_TRACE_CLR);
-           }
+         verbose |= bv;
+         if (argc > 2)
+           change_verbose_mask (verbose, argc - 2, argv + 2);
+         set_verbose (pop3);
        }
+      else if (strcmp (argv[1], "mask") == 0)
+       change_verbose_mask (1, argc - 2, argv + 2);
+      else if (strcmp (argv[1], "unmask") == 0)
+       change_verbose_mask (0, argc - 2, argv + 2);
+      else
+       mu_error ("unknown subcommand");
+      set_verbose_mask (pop3);
     }
+
   return 0;
 }
 
@@ -929,8 +1017,11 @@ com_connect (int argc, char **argv)
     {
       mu_stream_t tcp;
 
-      if (verbose)
-       mu_pop3_trace (pop3, MU_POP3_TRACE_SET);
+      if (QRY_VERBOSE ())
+       {
+         set_verbose (pop3);
+         set_verbose_mask (pop3);
+       }
       status = mu_tcp_stream_create (&tcp, argv[0], n, MU_STREAM_READ);
       if (status == 0)
        {
diff --git a/imap4d/fetch.c b/imap4d/fetch.c
index 618409b..04cf8c6 100644
--- a/imap4d/fetch.c
+++ b/imap4d/fetch.c
@@ -1688,7 +1688,8 @@ imap4d_fetch (struct imap4d_command *command, 
imap4d_tokbuf_t tok)
 {
   int rc;
   char *err_text = "Completed";
-
+  int xlev = set_xscript_level (MU_XSCRIPT_PAYLOAD);
   rc = imap4d_fetch0 (tok, 0, &err_text);
+  set_xscript_level (xlev);
   return io_completion_response (command, rc, "%s", err_text);
 }
diff --git a/imap4d/imap4d.c b/imap4d/imap4d.c
index 1df3965..a5b29e0 100644
--- a/imap4d/imap4d.c
+++ b/imap4d/imap4d.c
@@ -417,11 +417,14 @@ imap4d_mainloop (int fd, FILE *infile, FILE *outfile)
       return 0;
     }
 
-  /* Greetings.  */
+  /* Greetings. */
   io_untagged_response ((state == STATE_AUTH) ? 
                         RESP_PREAUTH : RESP_OK, "%s", text);
   io_flush ();
 
+  set_xscript_level ((state == STATE_AUTH) ?
+                      MU_XSCRIPT_NORMAL : MU_XSCRIPT_SECURE);
+  
   tokp = imap4d_tokbuf_init ();
   while (1)
     {
diff --git a/imap4d/imap4d.h b/imap4d/imap4d.h
index ba6ef65..7618107 100644
--- a/imap4d/imap4d.h
+++ b/imap4d/imap4d.h
@@ -381,7 +381,9 @@ void util_chdir (const char *homedir);
 int is_atom (const char *s);
 int util_isdelim (const char *str);
 int util_trim_nl (char *s, size_t len);
-  
+
+int set_xscript_level (int xlev);
+
 #ifdef WITH_TLS
 int imap4d_init_tls_server (void);
 #endif /* WITH_TLS */
diff --git a/imap4d/io.c b/imap4d/io.c
index a8b6cb0..726cfaa 100644
--- a/imap4d/io.c
+++ b/imap4d/io.c
@@ -241,7 +241,11 @@ io_format_completion_response (mu_stream_t str,
     new_state = STATE_NONE;
 
   if (new_state != STATE_NONE)
-    state = new_state;
+    {
+      if (new_state == STATE_AUTH)
+       set_xscript_level (MU_XSCRIPT_NORMAL);
+      state = new_state;
+    }
   
   return status;
 }
@@ -570,6 +574,7 @@ imap4d_readline (struct imap4d_tokbuf *tok)
          char *sp = NULL;
          char *buf;
          size_t len;
+         int xlev = set_xscript_level (MU_XSCRIPT_PAYLOAD);
          
          number = strtoul (last_arg + 1, &sp, 10);
          /* Client can ask for non-synchronised literal,
@@ -595,6 +600,7 @@ imap4d_readline (struct imap4d_tokbuf *tok)
          tok->level += len;
          tok->buffer[tok->level++] = 0;
          tok->argp[tok->argc - 1] = off;
+         set_xscript_level (xlev);
        }
       else
        break;
diff --git a/imap4d/uid.c b/imap4d/uid.c
index 739aff9..e4e5859 100644
--- a/imap4d/uid.c
+++ b/imap4d/uid.c
@@ -37,7 +37,11 @@ imap4d_uid (struct imap4d_command *command, imap4d_tokbuf_t 
tok)
   cmd = imap4d_tokbuf_getarg (tok, IMAP4_ARG_1);
   
   if (mu_c_strcasecmp (cmd, "FETCH") == 0)
-    rc = imap4d_fetch0 (tok, 1, &err_text);
+    {
+      int xlev = set_xscript_level (MU_XSCRIPT_PAYLOAD);
+      rc = imap4d_fetch0 (tok, 1, &err_text);
+      set_xscript_level (xlev);
+    }
   else if (mu_c_strcasecmp (cmd, "COPY") == 0)
     rc = imap4d_copy0 (tok, 1, &err_text);
   else if (mu_c_strcasecmp (cmd, "STORE") == 0)
diff --git a/imap4d/util.c b/imap4d/util.c
index a4c5043..73d4031 100644
--- a/imap4d/util.c
+++ b/imap4d/util.c
@@ -672,3 +672,22 @@ is_atom (const char *s)
   return 1;
 }
      
+int
+set_xscript_level (int xlev)
+{
+  if (imap4d_transcript)
+    {
+      if (xlev != MU_XSCRIPT_NORMAL)
+       {
+         mu_log_level_t n = xlev == MU_XSCRIPT_SECURE ?
+                             MU_DEBUG_TRACE6 : MU_DEBUG_TRACE7;
+         
+         if (mu_global_debug_level ("imap4") & MU_DEBUG_LEVEL_MASK (n))
+           return MU_XSCRIPT_NORMAL;
+       }
+
+      if (mu_stream_ioctl (iostream, MU_IOCTL_LEVEL, &xlev) == 0)
+       return xlev;
+    }
+  return 0;
+}
diff --git a/include/mailutils/pop3.h b/include/mailutils/pop3.h
index a6ced10..53d6c16 100644
--- a/include/mailutils/pop3.h
+++ b/include/mailutils/pop3.h
@@ -50,6 +50,7 @@ int  mu_pop3_get_timeout (mu_pop3_t pop3, int *timeout);
 #define MU_POP3_TRACE_SET 1
 #define MU_POP3_TRACE_QRY 2
 int mu_pop3_trace (mu_pop3_t pop3, int op);
+int mu_pop3_trace_mask (mu_pop3_t pop3, int op, int lev);
 
 int  mu_pop3_apop (mu_pop3_t pop3, const char *name, const char *digest);
 
diff --git a/include/mailutils/stream.h b/include/mailutils/stream.h
index e7d04ea..0d50602 100644
--- a/include/mailutils/stream.h
+++ b/include/mailutils/stream.h
@@ -63,6 +63,9 @@ enum mu_buffer_type
 #define MU_IOCTL_SET_TRANSPORT   6
 #define MU_IOCTL_SWAP_STREAM     7
 
+#define MU_IOCTL_LEVEL           8
+
+
 void mu_stream_ref (mu_stream_t stream);
 void mu_stream_unref (mu_stream_t stream);
 void mu_stream_destroy (mu_stream_t *pstream);
@@ -153,9 +156,15 @@ int mu_tcp_stream_create_with_source_host (mu_stream_t 
*stream,
 int mu_tcp_stream_create (mu_stream_t *stream, const char *host, int port,
                          int flags);
 
+/* Transcript output levels */
+#define MU_XSCRIPT_NORMAL  0  /* Normal transcript */
+#define MU_XSCRIPT_SECURE  1  /* Security-related data are being transmitted */
+#define MU_XSCRIPT_PAYLOAD 2  /* Actual payload (may be copious) */
+
 int mu_xscript_stream_create(mu_stream_t *pref, mu_stream_t transport,
                             mu_stream_t logstr,
                             const char *prefix[]);
+
 int mu_iostream_create (mu_stream_t *pref, mu_stream_t in, mu_stream_t out);
 int mu_dbgstream_create(mu_stream_t *pref, mu_debug_t debug,
                        mu_log_level_t level, int flags);
diff --git a/include/mailutils/sys/pop3.h b/include/mailutils/sys/pop3.h
index 1c81579..55bedeb 100644
--- a/include/mailutils/sys/pop3.h
+++ b/include/mailutils/sys/pop3.h
@@ -59,6 +59,7 @@ enum mu_pop3_state
 
 #define MU_POP3_ACK   0x01
 #define MU_POP3_TRACE 0x02  
+#define MU_POP3_XSCRIPT_MASK(n) (1<<((n)+1))
   
 /* Structure to hold things general to POP3 mailbox, like its state, etc ... */
 struct _mu_pop3
@@ -90,6 +91,8 @@ 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);
 
+int _mu_pop3_xscript_level (mu_pop3_t pop3, int xlev);
+
 int _mu_pop3_trace_enable (mu_pop3_t pop3);
 int _mu_pop3_trace_disable (mu_pop3_t pop3);  
 
diff --git a/include/mailutils/sys/xscript-stream.h 
b/include/mailutils/sys/xscript-stream.h
index c6b4538..0f58bb9 100644
--- a/include/mailutils/sys/xscript-stream.h
+++ b/include/mailutils/sys/xscript-stream.h
@@ -27,6 +27,7 @@ struct _mu_xscript_stream
   mu_stream_t transport;
   mu_stream_t logstr;
   int flags;
+  int level;
   char *prefix[2];
 };
 
diff --git a/libproto/pop/mbox.c b/libproto/pop/mbox.c
index ced5126..f513295 100644
--- a/libproto/pop/mbox.c
+++ b/libproto/pop/mbox.c
@@ -161,7 +161,11 @@ pop_open (mu_mailbox_t mbox, int flags)
 
   if (mu_debug_check_level (mbox->debug, MU_DEBUG_PROT))
     mu_pop3_trace (mpd->pop3, MU_POP3_TRACE_SET);
-
+  if (mu_debug_check_level (mbox->debug, MU_DEBUG_TRACE6))
+    mu_pop3_trace_mask (mpd->pop3, MU_POP3_TRACE_SET, MU_XSCRIPT_SECURE);
+  if (mu_debug_check_level (mbox->debug, MU_DEBUG_TRACE7))
+    mu_pop3_trace_mask (mpd->pop3, MU_POP3_TRACE_SET, MU_XSCRIPT_PAYLOAD);
+    
   do
     {
       status = mu_pop3_connect (mpd->pop3);
@@ -214,7 +218,7 @@ pop_destroy (mu_mailbox_t mbox)
     {
        size_t i;
       mu_monitor_wrlock (mbox->monitor);
-      /* Destroy the pop messages and ressources associated to them.  */
+      /* Destroy the pop messages and resources associated to them.  */
       for (i = 0; i < mpd->msg_count; i++)
        {
          if (mpd->msg[i])
@@ -291,7 +295,7 @@ pop_scan (mu_mailbox_t mbox, size_t msgno, size_t *pcount)
       if (mu_observable_notify (mbox->observable, MU_EVT_MESSAGE_ADD,
                                &tmp) != 0)
        break;
-      if (((i +1) % 10) == 0)
+      if (((i + 1) % 10) == 0)
        {
          mu_observable_notify (mbox->observable, MU_EVT_MAILBOX_PROGRESS,
                                NULL);
diff --git a/libproto/pop/pop3_pass.c b/libproto/pop/pop3_pass.c
index 77b860b..d72c511 100644
--- a/libproto/pop/pop3_pass.c
+++ b/libproto/pop/pop3_pass.c
@@ -28,14 +28,17 @@ int
 mu_pop3_pass (mu_pop3_t pop3, const char *passwd)
 {
   int status;
-
+  
   if (pop3 == NULL || passwd == NULL)
     return EINVAL;
 
   switch (pop3->state)
     {
     case MU_POP3_NO_STATE:
+      if (mu_pop3_trace_mask (pop3, MU_POP3_TRACE_QRY, MU_XSCRIPT_SECURE))
+       _mu_pop3_xscript_level (pop3, MU_XSCRIPT_SECURE);
       status = mu_pop3_writeline (pop3, "PASS %s\r\n", passwd);
+      _mu_pop3_xscript_level (pop3, MU_XSCRIPT_NORMAL);
       MU_POP3_CHECK_ERROR (pop3, status);
       /* FIXME: how to obscure the passwd in the stream buffer? */
       MU_POP3_FCLR (pop3, MU_POP3_ACK);
diff --git a/libproto/pop/pop3_retr.c b/libproto/pop/pop3_retr.c
index 2189075..aca24da 100644
--- a/libproto/pop/pop3_retr.c
+++ b/libproto/pop/pop3_retr.c
@@ -50,6 +50,8 @@ mu_pop3_retr (mu_pop3_t pop3, unsigned int msgno, mu_stream_t 
*pstream)
       MU_POP3_CHECK_OK (pop3);
       status = mu_pop3_stream_create (pop3, pstream);
       MU_POP3_CHECK_ERROR (pop3, status);
+      if (mu_pop3_trace_mask (pop3, MU_POP3_TRACE_QRY, MU_XSCRIPT_PAYLOAD))
+       _mu_pop3_xscript_level (pop3, MU_XSCRIPT_PAYLOAD);
       pop3->state = MU_POP3_RETR_RX;
 
     case MU_POP3_RETR_RX:
diff --git a/libproto/pop/pop3_stream.c b/libproto/pop/pop3_stream.c
index 689bec4..25fdba6 100644
--- a/libproto/pop/pop3_stream.c
+++ b/libproto/pop/pop3_stream.c
@@ -185,6 +185,7 @@ _pop3_event_cb (mu_stream_t str, int ev, int flags)
       if (mu_stream_ioctl (str, MU_IOCTL_GET_TRANSPORT, trans) == 0)
        {
          struct mu_pop3_stream *sp = (struct mu_pop3_stream *) trans[0];
+         _mu_pop3_xscript_level (sp->pop3, MU_XSCRIPT_NORMAL);
          sp->pop3->state = MU_POP3_NO_STATE;
        }
     }
diff --git a/libproto/pop/pop3_top.c b/libproto/pop/pop3_top.c
index 93957e5..c060736 100644
--- a/libproto/pop/pop3_top.c
+++ b/libproto/pop/pop3_top.c
@@ -50,6 +50,8 @@ mu_pop3_top (mu_pop3_t pop3, unsigned msgno, unsigned int 
lines,
       MU_POP3_CHECK_OK (pop3);
       status = mu_pop3_stream_create (pop3, pstream);
       MU_POP3_CHECK_ERROR (pop3, status);
+      if (mu_pop3_trace_mask (pop3, MU_POP3_TRACE_QRY, MU_XSCRIPT_PAYLOAD))
+       _mu_pop3_xscript_level (pop3, MU_XSCRIPT_PAYLOAD);
       pop3->state = MU_POP3_TOP_RX;
 
     case MU_POP3_TOP_RX:
diff --git a/libproto/pop/pop3_trace.c b/libproto/pop/pop3_trace.c
index 1a4c27f..5fa3d95 100644
--- a/libproto/pop/pop3_trace.c
+++ b/libproto/pop/pop3_trace.c
@@ -115,4 +115,36 @@ mu_pop3_trace (mu_pop3_t pop3, int op)
   return EINVAL;
 }
 
+int
+mu_pop3_trace_mask (mu_pop3_t pop3, int op, int lev)
+{
+  switch (op)
+    {
+    case MU_POP3_TRACE_SET:
+      pop3->flags |= MU_POP3_XSCRIPT_MASK(lev);
+      break;
+      
+    case MU_POP3_TRACE_CLR:
+      pop3->flags &= ~MU_POP3_XSCRIPT_MASK(lev);
+      break;
+      
+    case MU_POP3_TRACE_QRY:
+      if (pop3->flags & MU_POP3_XSCRIPT_MASK(lev))
+       break;
+      return MU_ERR_NOENT;
+      
+    default:
+      return EINVAL;
+    }
+  return 0;
+}
+
+int
+_mu_pop3_xscript_level (mu_pop3_t pop3, int xlev)
+{
+  if (mu_stream_ioctl (pop3->carrier, MU_IOCTL_LEVEL, &xlev) == 0)
+    return xlev;
+  return MU_XSCRIPT_NORMAL;
+}
+
   
diff --git a/mailbox/xscript-stream.c b/mailbox/xscript-stream.c
index 9930475..41f28ec 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 == MU_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 == MU_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);
diff --git a/pop3d/extra.c b/pop3d/extra.c
index 52bb220..380435d 100644
--- a/pop3d/extra.c
+++ b/pop3d/extra.c
@@ -338,3 +338,23 @@ pop3d_undelete_all ()
        mu_attribute_unset_deleted (attr);
     }
 }
+
+int
+set_xscript_level (int xlev)
+{
+  if (pop3d_transcript)
+    {
+      if (xlev != MU_XSCRIPT_NORMAL)
+       {
+         mu_log_level_t n = xlev == MU_XSCRIPT_SECURE ?
+                             MU_DEBUG_TRACE6 : MU_DEBUG_TRACE7;
+         
+         if (mu_global_debug_level ("pop3") & MU_DEBUG_LEVEL_MASK (n))
+           return MU_XSCRIPT_NORMAL;
+       }
+
+      if (mu_stream_ioctl (iostream, MU_IOCTL_LEVEL, &xlev) == 0)
+       return xlev;
+    }
+  return 0;
+}
diff --git a/pop3d/pop3d.h b/pop3d/pop3d.h
index d10a330..d831a3e 100644
--- a/pop3d/pop3d.h
+++ b/pop3d/pop3d.h
@@ -265,4 +265,6 @@ extern int set_bulletin_source (const char *source);
 extern int pop3d_begin_session (void);
 extern const char *pop3d_error_string (int code);
 
+extern int set_xscript_level (int xlev);
+
 #endif /* _POP3D_H */
diff --git a/pop3d/retr.c b/pop3d/retr.c
index 61908c0..0ffcd24 100644
--- a/pop3d/retr.c
+++ b/pop3d/retr.c
@@ -26,6 +26,7 @@ pop3d_retr (char *arg)
   mu_message_t msg = NULL;
   mu_attribute_t attr = NULL;
   mu_stream_t stream;
+  int xscript_level;
   
   if ((strlen (arg) == 0) || (strchr (arg, ' ') != NULL))
     return ERR_BAD_ARGS;
@@ -46,6 +47,7 @@ pop3d_retr (char *arg)
     return ERR_UNKNOWN;
   
   pop3d_outf ("+OK\n");
+  xscript_level = set_xscript_level (MU_XSCRIPT_PAYLOAD);
   mu_stream_copy (iostream, stream, 0, NULL);
   mu_stream_destroy (&stream);
 
@@ -56,5 +58,7 @@ pop3d_retr (char *arg)
 
   pop3d_outf (".\n");
 
+  set_xscript_level (xscript_level);
+
   return OK;
 }
diff --git a/pop3d/top.c b/pop3d/top.c
index 7e0ce5d..6e295bb 100644
--- a/pop3d/top.c
+++ b/pop3d/top.c
@@ -30,6 +30,7 @@ pop3d_top (char *arg)
   mu_body_t body;
   mu_stream_t stream;
   char *mesgc, *linesc, *p;
+  int xscript_level;
   
   if (strlen (arg) == 0)
     return ERR_BAD_ARGS;
@@ -62,6 +63,8 @@ pop3d_top (char *arg)
     return ERR_UNKNOWN;
   pop3d_outf ("+OK\n");
 
+  xscript_level = set_xscript_level (MU_XSCRIPT_PAYLOAD);
+
   mu_stream_copy (iostream, stream, 0, NULL);
   pop3d_outf ("\n");
   mu_stream_destroy (&stream);
@@ -85,5 +88,7 @@ pop3d_top (char *arg)
 
   pop3d_outf (".\n");
 
+  set_xscript_level (xscript_level);
+
   return OK;
 }
diff --git a/pop3d/user.c b/pop3d/user.c
index cbe8c41..e6801b0 100644
--- a/pop3d/user.c
+++ b/pop3d/user.c
@@ -91,6 +91,7 @@ pop3d_user (char *arg)
 {
   char *buf, *pass, *cmd;
   char buffer[512];
+  int xscript_level;
   
   if (state != AUTHORIZATION)
     return ERR_WRONG_STATE;
@@ -101,9 +102,11 @@ pop3d_user (char *arg)
   pop3d_outf ("+OK\n");
   pop3d_flush_output ();
 
+  xscript_level = set_xscript_level (MU_XSCRIPT_SECURE);
   buf = pop3d_readline (buffer, sizeof (buffer));
   pop3d_parse_command (buf, &cmd, &pass);
-
+  set_xscript_level (xscript_level);
+  
   if (mu_c_strcasecmp (cmd, "PASS") == 0)
     {
       int rc;


hooks/post-receive
-- 
GNU Mailutils



reply via email to

[Prev in Thread] Current Thread [Next in Thread]