diff options
| author | Sam Varshavchik | 2018-07-14 22:29:39 -0400 |
|---|---|---|
| committer | Sam Varshavchik | 2018-07-16 21:20:25 -0400 |
| commit | 60a63d31b29fea54441fa72e59d5712ca31eb01e (patch) | |
| tree | f5d2d712e79c10c52685310a7b38c67d68b14547 /imap | |
| parent | 2ad535262c59ff73743547594dc6c152d195d07c (diff) | |
| download | courier-libs-60a63d31b29fea54441fa72e59d5712ca31eb01e.tar.bz2 | |
courier-imap: enforce UTF8-correctness as per RFC-6855.
Diffstat (limited to 'imap')
| -rw-r--r-- | imap/imapd.c | 97 | ||||
| -rw-r--r-- | imap/imaplogin.c | 3 | ||||
| -rw-r--r-- | imap/imaptoken.c | 57 |
3 files changed, 126 insertions, 31 deletions
diff --git a/imap/imapd.c b/imap/imapd.c index 001dfcb..cf31af4 100644 --- a/imap/imapd.c +++ b/imap/imapd.c @@ -603,17 +603,17 @@ char *mailbox; curtoken->tokentype != IT_ATOM && curtoken->tokentype != IT_QUOTED_STRING) { - mailbox=0; + writes(tag); + writes(" BAD Invalid command\r\n"); + return (0); } - else - { - if (ok_hierarchy && (mailbox=strrchr(curtoken->tokenbuf, - HIERCH)) && mailbox[1] == 0) - *mailbox=0; - mailbox=decode_valid_mailbox(curtoken->tokenbuf, - autosubscribe); - } + if (ok_hierarchy && (mailbox=strrchr(curtoken->tokenbuf, + HIERCH)) && mailbox[1] == 0) + *mailbox=0; + + mailbox=decode_valid_mailbox(curtoken->tokenbuf, + autosubscribe); if ( mailbox == 0) { @@ -3162,8 +3162,9 @@ static int aclcmd(const char *tag) curtoken->tokentype != IT_ATOM && curtoken->tokentype != IT_NUMBER) { - errno=EINVAL; - return -1; + writes(tag); + writes(" BAD Invalid command\r\n"); + return 0; } p=imap_foldername_to_filename(enabled_utf8, @@ -3211,6 +3212,10 @@ static int aclcmd(const char *tag) free_tempmailboxlist(mblist); } break; + case IT_ERROR: + writes(tag); + writes(" BAD Invalid command\r\n"); + return 0; } rc=0; @@ -4305,7 +4310,11 @@ int uid=0; if (curtoken->tokentype != IT_QUOTED_STRING && curtoken->tokentype != IT_ATOM && curtoken->tokentype != IT_NUMBER) - return (-1); + { + writes(tag); + writes(" BAD Invalid command\r\n"); + return (0); + } reference=imap_foldername_to_filename (enabled_utf8, curtoken->tokenbuf); if (!reference) @@ -4320,12 +4329,20 @@ int uid=0; if (curtoken->tokentype != IT_QUOTED_STRING && curtoken->tokentype != IT_ATOM && curtoken->tokentype != IT_NUMBER) - return (-1); + { + free(reference); + writes(tag); + writes(" BAD Invalid command\r\n"); + return(0); + } name=imap_foldername_to_filename(enabled_utf8, curtoken->tokenbuf); if (!name) + { + free(reference); return -1; + } } if (nexttoken()->tokentype != IT_EOL) return (-1); @@ -4366,7 +4383,11 @@ int uid=0; if (tok->tokentype != IT_NUMBER && tok->tokentype != IT_ATOM && tok->tokentype != IT_QUOTED_STRING) - return (-1); + { + writes(tag); + writes(" BAD Invalid command\r\n"); + return (0); + } mailbox=imap_foldername_to_filename(enabled_utf8, tok->tokenbuf); @@ -4439,7 +4460,11 @@ int uid=0; if (curtoken->tokentype != IT_NUMBER && curtoken->tokentype != IT_ATOM && curtoken->tokentype != IT_QUOTED_STRING) - return (-1); + { + writes(tag); + writes(" BAD Invalid command\r\n"); + return (0); + } mailbox=imap_foldername_to_filename(enabled_utf8, curtoken->tokenbuf); @@ -4716,7 +4741,11 @@ int uid=0; if (curtoken->tokentype != IT_NUMBER && curtoken->tokentype != IT_ATOM && curtoken->tokentype != IT_QUOTED_STRING) - return (-1); + { + writes(tag); + writes(" BAD Invalid command\r\n"); + return 0; + } isdummy=0; @@ -4877,7 +4906,11 @@ int uid=0; if (curtoken->tokentype != IT_NUMBER && curtoken->tokentype != IT_ATOM && curtoken->tokentype != IT_QUOTED_STRING) - return (-1); + { + writes(tag); + writes(" BAD Invalid command\r\n"); + return (0); + } p=strrchr(curtoken->tokenbuf, HIERCH); if (p && p[1] == '\0') /* Ignore hierarchy DELETE */ @@ -4981,7 +5014,7 @@ int uid=0; curtoken->tokentype != IT_QUOTED_STRING) { writes(tag); - writes(" NO Invalid mailbox\r\n"); + writes(" BAD Invalid command\r\n"); return (0); } @@ -5034,7 +5067,9 @@ int uid=0; curtoken->tokentype != IT_QUOTED_STRING) { maildir_info_destroy(&mi1); - return (-1); + writes(tag); + writes(" BAD Invalid command\r\n"); + return (0); } if ((p=strrchr(curtoken->tokenbuf, HIERCH)) && p[1] == 0) @@ -5206,7 +5241,11 @@ int uid=0; if (curtoken->tokentype != IT_NUMBER && curtoken->tokentype != IT_ATOM && curtoken->tokentype != IT_QUOTED_STRING) - return (-1); + { + writes(tag); + writes(" BAD Invalid command\r\n"); + return (0); + } p=strrchr(curtoken->tokenbuf, HIERCH); if (p && p[1] == '\0') /* Ignore hierarchy DELETE */ @@ -5286,7 +5325,11 @@ int uid=0; if (curtoken->tokentype != IT_NUMBER && curtoken->tokentype != IT_ATOM && curtoken->tokentype != IT_QUOTED_STRING) - return (-1); + { + writes(tag); + writes(" BAD Invalid command\r\n"); + return (0); + } p=strrchr(curtoken->tokenbuf, HIERCH); if (p && p[1] == '\0') /* Ignore hierarchy DELETE */ @@ -5930,6 +5973,14 @@ int uid=0; if (curtoken->tokentype == IT_ATOM && strcmp(curtoken->tokenbuf, "CHARSET") == 0) { + if (enabled_utf8) + { + writes(tag); + writes(" NO CHARSET is not valid in UTF8 mode " + "as per RFC 6855\r\n"); + return (0); + } + curtoken=nexttoken(); if (curtoken->tokentype != IT_ATOM && curtoken->tokentype != IT_QUOTED_STRING) @@ -6279,7 +6330,9 @@ int uid=0; curtoken->tokentype != IT_QUOTED_STRING) { free(msgset); - return (-1); + writes(tag); + writes(" BAD Invalid command\r\n"); + return (0); } mailbox=decode_valid_mailbox(curtoken->tokenbuf, 1); diff --git a/imap/imaplogin.c b/imap/imaplogin.c index a445a35..8e2f9c9 100644 --- a/imap/imaplogin.c +++ b/imap/imaplogin.c @@ -37,7 +37,7 @@ #include "tcpd/spipe.h" #include "numlib/numlib.h" #include "tcpd/tlsclient.h" - +#include "imapd.h" FILE *debugfile=0; extern void initcapability(); @@ -47,6 +47,7 @@ extern int have_starttls(); extern int tlsrequired(); extern int authenticate(const char *, char *, int); unsigned long header_count=0, body_count=0; /* Dummies */ +int enabled_utf8=0; extern unsigned long bytes_received_count; /* counter for received bytes (imaptoken.c) */ extern unsigned long bytes_sent_count; /* counter for sent bytes (imapwrite.c) */ diff --git a/imap/imaptoken.c b/imap/imaptoken.c index 7df8846..82dda7c 100644 --- a/imap/imaptoken.c +++ b/imap/imaptoken.c @@ -1,5 +1,5 @@ /* -** Copyright 1998 - 2005 Double Precision, Inc. +** Copyright 1998 - 2018 Double Precision, Inc. ** See COPYING for distribution information. */ @@ -16,6 +16,8 @@ #include <sys/types.h> #include <sys/time.h> #include "numlib/numlib.h" +#include "imapd.h" +#include <courier-unicode.h> #if HAVE_UNISTD_H #include <unistd.h> #endif @@ -222,6 +224,11 @@ void smap_readline(char *buffer, size_t bufsize) #endif +static int ignore_output_func(const char *ptr, size_t cnt, void *ignore) +{ + return 0; +} + static struct imaptoken *do_readtoken(int touc) { int c=0; @@ -269,6 +276,8 @@ unsigned l; if (c == '"') { + int bit8=0; + l=0; while ((c=READ()) != '"') { @@ -280,13 +289,45 @@ unsigned l; curtoken.tokentype=IT_ERROR; return (&curtoken); } - if (l < 8192) + if (l >= 8192) { - appendch(c); + fprintf(stderr, "ERR: Quoted string literal " + "overflow, ip=[%s]\n", + getenv("TCPREMOTEIP")); + curtoken.tokentype=IT_ERROR; } + if (c & 0x80) + bit8=1; + appendch(c); } appendch(0); curtoken.tokentype=IT_QUOTED_STRING; + + /* + ** Strings must be valid UTF-8. Shortcut check. + */ + + if (bit8) + { + int errptr=0; + + unicode_convert_handle_t h= + unicode_convert_init("utf-8", + unicode_u_ucs4_native, + ignore_output_func, + (void *)0); + + if (unicode_convert(h, curtoken.tokenbuf, + strlen(curtoken.tokenbuf))) + { + curtoken.tokentype=IT_ERROR; + } + + if (unicode_convert_deinit(h, &errptr) || errptr) + { + curtoken.tokentype=IT_ERROR; + } + } return (&curtoken); } @@ -339,9 +380,10 @@ unsigned l; } while (c != '\r' && c != '\n' - && !isspace((int)(unsigned char)c) - && c != '\\' && c != '"' && c != LPAREN_CHAR && c != RPAREN_CHAR - && c != '{' && c != '}' && c != LBRACKET_CHAR && c != RBRACKET_CHAR) + && !isspace((int)(unsigned char)c) + && (((unsigned char)c) & 0x80) == 0 + && c != '\\' && c != '"' && c != LPAREN_CHAR && c != RPAREN_CHAR + && c != '{' && c != '}' && c != LBRACKET_CHAR && c != RBRACKET_CHAR) { curtoken.tokentype=IT_ATOM; if (l < IT_MAX_ATOM_SIZE) @@ -352,7 +394,7 @@ unsigned l; } else { - write_error_exit("max atom size too small"); + write_error_exit("max atom size too small"); } c=READ(); } @@ -564,4 +606,3 @@ int ismsgset_str(const char *p) if (*p) return (0); return (1); } - |
