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 ---