[Dovecot] Trim trailing whitespace from username
Recently we changed Postfix to use Dovecot for our SASL authentication and we ran into trouble with some of our clients having extraneous spaces at the end of their usernames. The quick fix was to add a space to username_chars. The slightly longer fix was a pretty simple patch to Dovecot. I put the trimming in auth_request_fix_username. I didn't think it warranted a full strfuncs function. If there is a better way to do this I'm all ears. I don't really like patching with my own code, even if I did essentially steal if from the kernel's strstrip(). diff -u dovecot-1.1.rc5/src/auth/auth-request.c dovecot-1.1.rc5-patched/src/auth/auth-request.c --- dovecot-1.1.rc5/src/auth/auth-request.c 2008-05-04 15:01:52.000000000 -0700 +++ dovecot-1.1.rc5-patched/src/auth/auth-request.c 2008-05-16 00:44:15.000000000 -0700 @@ -22,6 +22,7 @@ #include <stdlib.h> #include <sys/stat.h> +#include <ctype.h> struct auth_request * auth_request_new(struct auth *auth, const struct mech_module *mech, @@ -750,6 +751,7 @@ { unsigned char *p; char *user; + size_t size; if (strchr(username, '@') == NULL && request->auth->default_realm != NULL) { @@ -759,6 +761,16 @@ user = p_strdup(request->pool, username); } + /* Trim trailing whitespace from the username */ + size = strlen((unsigned char*)user); + if(size) { + p = user + size - 1; + while (p != user && isspace(*p)) + p--; + *(p + 1) = '\0'; + p = NULL; + } + for (p = (unsigned char *)user; *p != '\0'; p++) { if (request->auth->username_translation[*p & 0xff] != 0) *p = request->auth->username_translation[*p & 0xff];
On Fri, 2008-05-16 at 00:48 -0700, David Jonas wrote:
Recently we changed Postfix to use Dovecot for our SASL authentication and we ran into trouble with some of our clients having extraneous spaces at the end of their usernames. The quick fix was to add a space to username_chars. The slightly longer fix was a pretty simple patch to Dovecot. I put the trimming in auth_request_fix_username. I didn't think it warranted a full strfuncs function.
If there is a better way to do this I'm all ears. I don't really like patching with my own code, even if I did essentially steal if from the kernel's strstrip().
How about this: http://hg.dovecot.org/dovecot-1.1/rev/15ddb7513e2d
Then you can use auth_username_format = %Tu
Timo Sirainen wrote:
On Fri, 2008-05-16 at 00:48 -0700, David Jonas wrote:
Recently we changed Postfix to use Dovecot for our SASL authentication and we ran into trouble with some of our clients having extraneous spaces at the end of their usernames. The quick fix was to add a space to username_chars. The slightly longer fix was a pretty simple patch to Dovecot. I put the trimming in auth_request_fix_username. I didn't think it warranted a full strfuncs function.
If there is a better way to do this I'm all ears. I don't really like patching with my own code, even if I did essentially steal if from the kernel's strstrip().
How about this: http://hg.dovecot.org/dovecot-1.1/rev/15ddb7513e2d
Then you can use auth_username_format = %Tu
Ah, a much better place to put it. Applied cleaningly, seems to be working well. Thanks! I've added it to the wiki, http://wiki.dovecot.org/Variables
Timo Sirainen wrote:
On Fri, 2008-05-16 at 00:48 -0700, David Jonas wrote:
Recently we changed Postfix to use Dovecot for our SASL authentication and we ran into trouble with some of our clients having extraneous spaces at the end of their usernames. The quick fix was to add a space to username_chars. The slightly longer fix was a pretty simple patch to Dovecot. I put the trimming in auth_request_fix_username. I didn't think it warranted a full strfuncs function.
If there is a better way to do this I'm all ears. I don't really like patching with my own code, even if I did essentially steal if from the kernel's strstrip().
How about this: http://hg.dovecot.org/dovecot-1.1/rev/15ddb7513e2d
Then you can use auth_username_format = %Tu
I spoke too soon. Dovecot still complains about the invalid character. While testing I had forgotten to update to remove <space> from username_chars. I should have known really, since the invalid chars check is done before var_expand() in auth_request_fix_username().
Any other ideas? Adding <space> to the username_chars list doesn't seem like a security threat, but honestly I don't know much about that.
David
### From the log:
dovecot: auth(default): client in: AUTH 1 LOGIN service=smtp resp=ZGpvbmFzQHZpdGFsd2Vya3MuY29tIA== dovecot: auth(default): auth(?): Invalid username: djonas@vitalwerks.com dovecot: auth(default): login(?): Username contains disallowed character: 0x20 dovecot: auth(default): client out: FAIL 1
# dovecot -n # 1.1.rc5: /usr/local/dovecot-1.1/etc/dovecot-auth.conf ... disable_plaintext_auth: no ... auth default: mechanisms: login plain cram-md5 ... username_chars: abcdefghijklmnopqrstuvwxyzDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@ABC username_translation: %@ username_format: %LTu verbose: yes debug: yes debug_passwords: yes passdb: driver: sql args: /usr/local/dovecot-1.1/etc/dovecot-sql.conf userdb: driver: prefetch socket: type: listen client: path: /var/spool/postfix-smtp-auth/private/auth mode: 432 user: postfix group: postfix
If you're using MySQL for your database driver you can easily use the TRIM() function in your query to strip off leading and ending whitespace characters. I do that and a "LCASE()" to force<http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_trim>the usernames to lowercase in the query.
I spoke too soon. Dovecot still complains about the invalid character. While
testing I had forgotten to update to remove <space> from username_chars. I should have known really, since the invalid chars check is done before var_expand() in auth_request_fix_username().
Any other ideas? Adding <space> to the username_chars list doesn't seem like a security threat, but honestly I don't know much about that.
David
### From the log:
dovecot: auth(default): client in: AUTH 1 LOGIN service=smtp resp=ZGpvbmFzQHZpdGFsd2Vya3MuY29tIA== dovecot: auth(default): auth(?): Invalid username: djonas@vitalwerks.com dovecot: auth(default): login(?): Username contains disallowed character: 0x20 dovecot: auth(default): client out: FAIL 1
# dovecot -n # 1.1.rc5: /usr/local/dovecot-1.1/etc/dovecot-auth.conf ... disable_plaintext_auth: no ... auth default: mechanisms: login plain cram-md5 ... username_chars: abcdefghijklmnopqrstuvwxyzDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@ABC username_translation: %@ username_format: %LTu verbose: yes debug: yes debug_passwords: yes passdb: driver: sql args: /usr/local/dovecot-1.1/etc/dovecot-sql.conf userdb: driver: prefetch socket: type: listen client: path: /var/spool/postfix-smtp-auth/private/auth mode: 432 user: postfix group: postfix
Cassidy Larson wrote:
If you're using MySQL for your database driver you can easily use the TRIM() function in your query to strip off leading and ending whitespace characters. I do that and a "LCASE()" to force<http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_trim>the usernames to lowercase in the query.
Yes, I tried that. MySQL(4.x) actually returns the same for
SELECT * WHERE user='this@that ' and SELECT * WHERE user='this@that'
so TRIM() is only necessary if the values are CONCAT'd.
This is really just an issue with invalid chars in the username. And it's a rather small issue, but for some reason a ton of our clients who use Exchange all have spaces at the end of their usernames.
As long as having a <space> in username_chars isn't going to open me up to any exploits (I can't imagine how) I'll stick with it.
I spoke too soon. Dovecot still complains about the invalid character. While
testing I had forgotten to update to remove <space> from username_chars. I should have known really, since the invalid chars check is done before var_expand() in auth_request_fix_username().
Any other ideas? Adding <space> to the username_chars list doesn't seem like a security threat, but honestly I don't know much about that.
David
### From the log:
dovecot: auth(default): client in: AUTH 1 LOGIN service=smtp resp=ZGpvbmFzQHZpdGFsd2Vya3MuY29tIA== dovecot: auth(default): auth(?): Invalid username: djonas@vitalwerks.com dovecot: auth(default): login(?): Username contains disallowed character: 0x20 dovecot: auth(default): client out: FAIL 1
# dovecot -n # 1.1.rc5: /usr/local/dovecot-1.1/etc/dovecot-auth.conf ... disable_plaintext_auth: no ... auth default: mechanisms: login plain cram-md5 ... username_chars: abcdefghijklmnopqrstuvwxyzDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@ABC username_translation: %@ username_format: %LTu verbose: yes debug: yes debug_passwords: yes passdb: driver: sql args: /usr/local/dovecot-1.1/etc/dovecot-sql.conf userdb: driver: prefetch socket: type: listen client: path: /var/spool/postfix-smtp-auth/private/auth mode: 432 user: postfix group: postfix
-- No-IP.com
On Wed, 2008-05-28 at 15:40 -0700, David Jonas wrote:
I spoke too soon. Dovecot still complains about the invalid character. While testing I had forgotten to update to remove <space> from username_chars. I should have known really, since the invalid chars check is done before var_expand() in auth_request_fix_username().
Any other ideas? Adding <space> to the username_chars list doesn't seem like a security threat, but honestly I don't know much about that.
The default auth_username_chars contain only the ones that are commonly used. There should be no problems allowing most non-control characters. In future I'm going to fix also Dovecot's handling of control characters.
participants (3)
-
Cassidy Larson
-
David Jonas
-
Timo Sirainen