Please see attached message

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
--- Begin Message ---
Hi!

I've been trying to send this to the cyrus-info mailing list, but my 
mails seem to get lost (seems strange - CMU may have to check their 
servers). 

E.g. folder name &wfrr4+Dw8ero- (which is OK) cannot pass the 
mboxname_policycheck (it seems to find out there is an invalid BASE64 
character, which is not correct). We are migrating to Cyrus from latest 
courier-imap, but we require this functionality (and used to use it with 
success). That's why we created this patch. We like the function that 
checks for correct utf7 in the PHP function imap_utf7_decode so we 
didn't write the code from scratch but used it. 

The patch is working fine on our production servers for a week now and I 
felt that although the list seems not to want my mail :) someone should 
send the patch to the list or you can even patch the current CVS tree :) 

We are correcting a function that has not changed since 2.0 and the 
difference is only slight from 1.6, but this is not a problem that has 
been overseen - lots of people are complaining about it in Russian and 
Bulgarian mailing lists. We think we have solved the problem (at least 
here - on our servers) and we hope this might help.

If you have any influence, I will be grateful if I can also send to the 
list :) Today a question was asked which I wanted to answer, but the 
mail seems lost again.

Regards,
Momchil

_______________________________________________
Momchil Shumackov
mail.bG                  __   _      powered by
Stefan Karadja 12B      / /  (_)__  __ ____  __
Sofia BG-1000          / /__/ / _ \/ // /\ \/ /
Tel: +359 2 9885007   /____/_/_//_/\_,_/ /_/\_\

__________________________________________
12MB-POP3-WAP-SMS-AHTÈCÏAM--TOBA-E-mail.bG
------------------------------------------
HOB ÁEÇÏËATEH AÄPEC - http://mail.bg/new/
------------------------------------------
--- mboxname.c.old      2002-01-24 18:39:28.000000000 +0200
+++ mboxname.c  2003-01-05 12:03:19.000000000 +0200
@@ -453,21 +453,53 @@
 
 /*
  * Apply site policy restrictions on mailbox names.
- * Restrictions are hardwired for now.
+ *
+ * cannibalized from PHP source and adapted for cyrus by: 
+ * Angel Sinigerski <[EMAIL PROTECTED]> and
+ * Momchil Shumackov <[EMAIL PROTECTED]>
+ * original author: Andrew Skalski <[EMAIL PROTECTED]>
+ *
  */
-#define GOODCHARS " 
+,-.0123456789:=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"
+
+/* tests `c' and returns true if it is a special character */
+#define SPECIAL(c) ((c) <= 0x1f || (c) >= 0x7f)
+
+/* validate a modified-base64 character */
+#define B64CHAR(c) (isalnum(c) || (c) == '+' || (c) == ',')
+
+/* map the low 64 bits of `n' to the modified-base64 characters */
+#define B64(n)  ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
+                "abcdefghijklmnopqrstuvwxyz0123456789+,"[(n) & 0x3f])
+
+/* map the modified-base64 character `c' to its 64 bit value */
+#define UNB64(c)        ((c) == '+' ? 62 : (c) == ',' ? 63 : (c) >= 'a' ? \
+                        (c) - 71 : (c) >= 'A' ? (c) - 65 : (c) + 4)
+
 int mboxname_policycheck(char *name)
 {
-    int i;
+    /* author: Andrew Skalski <[EMAIL PROTECTED]> */
+    const unsigned char *inp, *endp;
+    unsigned char *out, *outp;
+    int inlen, outlen, i;
     struct glob *g;
-    int sawutf7 = 0;
-    unsigned c1, c2, c3, c4, c5, c6, c7, c8;
-    int ucs4;
+    enum {
+        ST_NORMAL,  /* printable text */
+        ST_DECODE0, /* encoded text rotation... */
+        ST_DECODE1,
+        ST_DECODE2,
+        ST_DECODE3
+    } state;
+
     int unixsep;
 
     unixsep = config_getswitch("unixhierarchysep", 0);
 
-    if (strlen(name) > MAX_MAILBOX_NAME) return IMAP_MAILBOX_BADNAME;
+    inlen = strlen( name );
+
+    if ( inlen > MAX_MAILBOX_NAME ) {
+        /* Name too long */
+        return IMAP_MAILBOX_BADNAME;
+    }
     for (i = 0; i < NUM_BADMBOXPATTERNS; i++) {
        g = glob_init(badmboxpatterns[i], 0);
        if (GLOB_TEST(g, name) != -1) {
@@ -477,81 +509,63 @@
        glob_free(&g);
     }
 
-    if (*name == '~') return IMAP_MAILBOX_BADNAME;
-    while (*name) {
-       if (*name == '&') {
-           /* Modified UTF-7 */
-           name++;
-           while (*name != '-') {
-               if (sawutf7) {
-                   /* Two adjacent utf7 sequences */
+    /* validate and compute length of output string */
+    outlen = 0;
+    state = ST_NORMAL;
+    for (endp = (inp = name) + inlen; inp < endp; inp++) {
+        if (state == ST_NORMAL) {
+            /* process printable character */
+            if( *inp == '.' && (!unixsep) )
+            {
                    return IMAP_MAILBOX_BADNAME;
                }
-
-               if ((c1 = CHARMOD64(*name++)) == XX ||
-                   (c2 = CHARMOD64(*name++)) == XX ||
-                   (c3 = CHARMOD64(*name++)) == XX) {
-                   /* Non-base64 character */
+            if (SPECIAL(*inp)) {
+                               /* Invalid modified UTF-7 character */
                    return IMAP_MAILBOX_BADNAME;
-               }
-               ucs4 = (c1 << 10) | (c2 << 4) | (c3 >> 2);
-               if ((ucs4 & 0xff80) == 0 || (ucs4 & 0xf800) == 0xd800) {
-                   /* US-ASCII or multi-word character */
+            } else if (*inp != '&') {
+                outlen++;
+            } else if (inp + 1 == endp) {
+                /* Unexpected end of string */
                    return IMAP_MAILBOX_BADNAME;
+            } else if (inp[1] != '-') {
+                state = ST_DECODE0;
+            } else {
+                outlen++;
+                inp++;
                }
-               if (*name == '-') {
-                   /* Trailing bits not zero */
-                   if (c3 & 0x03) return IMAP_MAILBOX_BADNAME;
-
-                   /* End of UTF-7 sequence */
-                   break;
-               }
-
-               if ((c4 = CHARMOD64(*name++)) == XX ||
-                   (c5 = CHARMOD64(*name++)) == XX ||
-                   (c6 = CHARMOD64(*name++)) == XX) {
-                   /* Non-base64 character */
+        } else if (*inp == '-') {
+            /* return to NORMAL mode */
+            if (state == ST_DECODE1) {
+                /* Stray modified base64 character */
                    return IMAP_MAILBOX_BADNAME;
                }
-               ucs4 = ((c3 & 0x03) << 14) | (c4 << 8) | (c5 << 2) | (c6 >> 4);
-               if ((ucs4 & 0xff80) == 0 || (ucs4 & 0xf800) == 0xd800) {
-                   /* US-ASCII or multi-word character */
+            state = ST_NORMAL;
+        } else if (!B64CHAR(*inp)) {
+            /* Invalid modified base64 character */
                    return IMAP_MAILBOX_BADNAME;
-               }
-               if (*name == '-') {
-                   /* Trailing bits not zero */
-                   if (c6 & 0x0f) return IMAP_MAILBOX_BADNAME;
-
-                   /* End of UTF-7 sequence */
+        } else {
+            switch (state) {
+                case ST_DECODE3:
+                    outlen++;
+                    state = ST_DECODE0;
+                    break;
+                case ST_DECODE2:
+                case ST_DECODE1:
+                    outlen++;
+                case ST_DECODE0:
+                    state++;
+                case ST_NORMAL:
                    break;
                }
-
-               if ((c7 = CHARMOD64(*name++)) == XX ||
-                   (c8 = CHARMOD64(*name++)) == XX) {
-                   /* Non-base64 character */
-                   return IMAP_MAILBOX_BADNAME;
-               }
-               ucs4 = ((c6 & 0x0f) << 12) | (c7 << 6) | c8;
-               if ((ucs4 & 0xff80) == 0 || (ucs4 & 0xf800) == 0xd800) {
-                   /* US-ASCII or multi-word character */
-                   return IMAP_MAILBOX_BADNAME;
                }
            }
 
-           if (name[-1] == '&') sawutf7 = 0; /* '&-' is sequence for '&' */
-           else sawutf7 = 1;
-
-           name++;             /* Skip over terminating '-' */
-       }
-       else {
-           if (!strchr(GOODCHARS, *name) &&
-               /* If we're using unixhierarchysep, DOTCHAR is allowed */
-               !(unixsep && *name == DOTCHAR))
+    /* enforce end state */
+    if (state != ST_NORMAL) {
+        /* Unexpected end of string */
                return IMAP_MAILBOX_BADNAME;
-           name++;
-           sawutf7 = 0;
-       }
     }
+
     return 0;
 }
 
--- End Message ---

Reply via email to