diff options
author | Werner Koch <wk@gnupg.org> | 2015-03-20 15:39:49 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2015-03-20 15:40:09 +0100 |
commit | a0eb2e4e8cef9ca6a5dfbae6440fa6cd583d0805 (patch) | |
tree | 257f7ad8c0a7169def38fc5012859f109d8c2e30 /common | |
parent | gpg: Find keys using mail addresses with garbage after the '>' (diff) | |
download | gnupg2-a0eb2e4e8cef9ca6a5dfbae6440fa6cd583d0805.tar.xz gnupg2-a0eb2e4e8cef9ca6a5dfbae6440fa6cd583d0805.zip |
common: Add function is_valid_mailbox_mem.
* common/mbox-util.c (mem_count_chr): New.
(my_memstr): New.
(has_invalid_email_chars): Change args to work on a buffer.
(is_valid_mailbox_mem): New.
(is_valid_mailbox): Rewrite to use is_valid_mailbox_mem.
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/mbox-util.c | 105 | ||||
-rw-r--r-- | common/mbox-util.h | 3 |
2 files changed, 82 insertions, 26 deletions
diff --git a/common/mbox-util.c b/common/mbox-util.c index 0885f0e6f..2029324f2 100644 --- a/common/mbox-util.c +++ b/common/mbox-util.c @@ -50,6 +50,47 @@ string_count_chr (const char *string, int c) return count; } +static int +mem_count_chr (const void *buffer, int c, size_t length) +{ + const char *s = buffer; + int count; + + for (count=0; length; length--, s++) + if (*s == c) + count++; + return count; +} + + +/* This is a case-sensitive version of our memistr. I wonder why no + standard function memstr exists but I better do not use the name + memstr to avoid future conflicts. */ +static const char * +my_memstr (const void *buffer, size_t buflen, const char *sub) +{ + const unsigned char *buf = buffer; + const unsigned char *t = (const unsigned char *)buf; + const unsigned char *s = (const unsigned char *)sub; + size_t n = buflen; + + for ( ; n ; t++, n-- ) + { + if (*t == *s) + { + for (buf = t++, buflen = n--, s++; n && *t ==*s; t++, s++, n--) + ; + if (!*s) + return (const char*)buf; + t = (const unsigned char *)buf; + s = (const unsigned char *)sub ; + n = buflen; + } + } + return NULL; +} + + static int string_has_ctrl_or_space (const char *string) @@ -74,52 +115,66 @@ has_dotdot_after_at (const char *string) } -/* Check whether the string has characters not valid in an RFC-822 - address. To cope with OpenPGP we ignore non-ascii characters - so that for example umlauts are legal in an email address. An - OpenPGP user ID must be utf-8 encoded but there is no strict - requirement for RFC-822. Thus to avoid IDNA encoding we put the - address verbatim as utf-8 into the user ID under the assumption - that mail programs handle IDNA at a lower level and take OpenPGP - user IDs as utf-8. Note that we can't do an utf-8 encoding - checking here because in keygen.c this function is called with the - native encoding and native to utf-8 encoding is only done later. */ +/* Check whether BUFFER has characters not valid in an RFC-822 + address. LENGTH gives the length of BUFFER. + + To cope with OpenPGP we ignore non-ascii characters so that for + example umlauts are legal in an email address. An OpenPGP user ID + must be utf-8 encoded but there is no strict requirement for + RFC-822. Thus to avoid IDNA encoding we put the address verbatim + as utf-8 into the user ID under the assumption that mail programs + handle IDNA at a lower level and take OpenPGP user IDs as utf-8. + Note that we can't do an utf-8 encoding checking here because in + keygen.c this function is called with the native encoding and + native to utf-8 encoding is only done later. */ int -has_invalid_email_chars (const char *s) +has_invalid_email_chars (const void *buffer, size_t length) { + const unsigned char *s = buffer; int at_seen=0; const char *valid_chars= "01234567890_-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - for ( ; *s; s++ ) + for ( ; length && *s; length--, s++ ) { - if ( (*s & 0x80) ) + if ((*s & 0x80)) continue; /* We only care about ASCII. */ - if ( *s == '@' ) + if (*s == '@') at_seen=1; - else if ( !at_seen && !(strchr (valid_chars, *s) - || strchr ("!#$%&'*+/=?^`{|}~", *s))) + else if (!at_seen && !(strchr (valid_chars, *s) + || strchr ("!#$%&'*+/=?^`{|}~", *s))) return 1; - else if ( at_seen && !strchr( valid_chars, *s ) ) + else if (at_seen && !strchr (valid_chars, *s)) return 1; } return 0; } +/* Same as is_valid_mailbox (see below) but operates on non-nul + terminated buffer. */ +int +is_valid_mailbox_mem (const void *name_arg, size_t namelen) +{ + const char *name = name_arg; + + return !( !name + || !namelen + || has_invalid_email_chars (name, namelen) + || mem_count_chr (name, '@', namelen) != 1 + || *name == '@' + || name[namelen-1] == '@' + || name[namelen-1] == '.' + || my_memstr (name, namelen, "..")); +} + + /* Check whether NAME represents a valid mailbox according to RFC822. Returns true if so. */ int is_valid_mailbox (const char *name) { - return !( !name - || !*name - || has_invalid_email_chars (name) - || string_count_chr (name,'@') != 1 - || *name == '@' - || name[strlen(name)-1] == '@' - || name[strlen(name)-1] == '.' - || strstr (name, "..") ); + return name? is_valid_mailbox_mem (name, strlen (name)) : 0; } diff --git a/common/mbox-util.h b/common/mbox-util.h index b9a3bda6b..4dd48ecd5 100644 --- a/common/mbox-util.h +++ b/common/mbox-util.h @@ -29,8 +29,9 @@ #ifndef GNUPG_COMMON_MBOX_UTIL_H #define GNUPG_COMMON_MBOX_UTIL_H -int has_invalid_email_chars (const char *s); +int has_invalid_email_chars (const void *buffer, size_t length); int is_valid_mailbox (const char *name); +int is_valid_mailbox_mem (const void *buffer, size_t length); char *mailbox_from_userid (const char *userid); int is_valid_user_id (const char *uid); |