Matthew Hodgson wrote:

Looking at the process_recipient() code in lmtpengine.c, I'm not sure that the quote-string parsing has been updated fully to reflect
> virtual domains - so I've fiddled around and come up with a version
> based on the existing code, and also a complete rewrite.
> I enclose the latter as a patch here; it hasn't been rigorously
> tested (at all), but has fixed my particular problem.

Hm, a bit of peer review & common sense later, i enclose a copy of said patch which hopefully takes terminal cases better into account and avoids buffer overruns...

M.

______________________________________________________________
Matthew Hodgson   [EMAIL PROTECTED]   Tel: +44 845 6667778
                  Systems Analyst, MX Telecom Ltd.

Index: lmtpengine.c
===================================================================
RCS file: /cvs/src/cyrus/imap/lmtpengine.c,v
retrieving revision 1.96
diff -u -r1.96 lmtpengine.c
--- lmtpengine.c        10 Nov 2003 16:42:14 -0000      1.96
+++ lmtpengine.c        7 Jan 2004 20:15:40 -0000
@@ -754,6 +754,7 @@
     char *dest;
     char *user;
     int r, sl;
+    int inusername, inquoted;
     address_data_t *ret = (address_data_t *) xmalloc(sizeof(address_data_t));
     int forcedowncase = config_getswitch(IMAPOPT_LMTP_DOWNCASE_RCPT);
 
@@ -781,40 +782,34 @@
        addr++;
     }
     
-    if (*addr == '\"') {
-       addr++;
-       while (*addr && *addr != '\"') {
-           if (*addr == '\\') addr++;
-           *dest++ = *addr++;
-       }
-    }
-    else {
-       if(forcedowncase) {
-           /* We should downcase the localpart up to the first + */
-           while(*addr != '@' && *addr != '>' && *addr != '+') {
-               if(*addr == '\\') addr++;
-               *dest++ = TOLOWER(*addr++);
-           }
-           if (*addr == '+') {
-             while(*addr != '@' && *addr != '>') {
-               if(*addr == '\\') addr++;
-               *dest++ = *addr++;
-             }
-           }
-           while ((config_virtdomains || *addr != '@') && *addr != '>') {
-               if(*addr == '\\') addr++;
-               *dest++ = TOLOWER(*addr++);
-           }
-       } else {
-         /* Now finish the remainder of the localpart */
-         while ((config_virtdomains || *addr != '@') && *addr != '>') {
-             if (*addr == '\\') addr++;
-             *dest++ = *addr++;
-         }
-       }
+    inusername = 1;
+    inquoted = 0;
+    
+    while(*addr && (inquoted || ((config_virtdomains || *addr != '@') && *addr != 
'>'))) {
+        if (*addr == '\\' && inquoted) {
+             addr++;
+             if (!*addr) { break; }
+        }
+                
+        if (*addr == '\"') {
+            inquoted = inquoted ? 0 : 1;
+            addr++;
+            continue;
+        }
+        if (*addr == '+' && inusername) {
+            inusername = 0;
+        }
+        
+        if (forcedowncase && inusername) {
+            *dest++ = TOLOWER(*addr++);
+        }
+        else {
+            *dest++ = *addr++;
+        }
     }
+    
     *dest = '\0';
-       
+    
     r = verify_user(user, ignorequota ? -1 : msg->size, msg->authstate);
     if (r) {
        /* we lost */

Reply via email to