summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2015-03-20 15:39:49 +0100
committerWerner Koch <wk@gnupg.org>2015-03-20 15:40:09 +0100
commita0eb2e4e8cef9ca6a5dfbae6440fa6cd583d0805 (patch)
tree257f7ad8c0a7169def38fc5012859f109d8c2e30 /common
parentgpg: Find keys using mail addresses with garbage after the '>' (diff)
downloadgnupg2-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.c105
-rw-r--r--common/mbox-util.h3
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);