Mercurial > dovecot > original-hg > dovecot-1.2
changeset 1330:7cde19dbe754 HEAD
Moved auth_username_chars from db-pgsql to generic for all. Some other
auth code cleanups.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 02 Apr 2003 05:09:41 +0300 |
parents | ae229b7acb4c |
children | d55cf9c28062 |
files | doc/dovecot-pgsql.conf dovecot-example.conf src/auth/db-ldap.c src/auth/db-pgsql.c src/auth/db-pgsql.h src/auth/mech-digest-md5.c src/auth/mech-plain.c src/auth/mech.c src/auth/mech.h src/auth/passdb-pgsql.c src/auth/userdb-pgsql.c src/master/auth-process.c src/master/master-settings.c src/master/master-settings.h |
diffstat | 14 files changed, 103 insertions(+), 62 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/dovecot-pgsql.conf Wed Apr 02 05:05:38 2003 +0300 +++ b/doc/dovecot-pgsql.conf Wed Apr 02 05:09:41 2003 +0300 @@ -67,11 +67,3 @@ # user_query = SELECT home, 501 AS uid, 501 AS gid FROM users WHERE userid = '%u' # #user_query = SELECT home, uid, gid FROM users WHERE userid = '%u' - -# Allowable characters. -# -# If the user-provided data contains any characters besides what is listed -# here, authentication will automatically fail. This prevents SQL quoting -# escapes and other possible vulnerabilities. -# -#allowed_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-@
--- a/dovecot-example.conf Wed Apr 02 05:05:38 2003 +0300 +++ b/dovecot-example.conf Wed Apr 02 05:09:41 2003 +0300 @@ -393,6 +393,13 @@ # Number of authentication processes to create #auth_count = 1 +# List of allowed characters in username. If the user-given username contains +# a character not listed in here, the login automatically fails. This is just +# an extra check to make sure user can't exploit any potential quote escaping +# vulnerabilities with SQL/LDAP databases. If you want to allow all characters, +# set this value to empty. +#auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@ + # More verbose logging. Useful for figuring out why authentication isn't # working. #auth_verbose = no
--- a/src/auth/db-ldap.c Wed Apr 02 05:05:38 2003 +0300 +++ b/src/auth/db-ldap.c Wed Apr 02 05:09:41 2003 +0300 @@ -266,27 +266,31 @@ } } +#define IS_LDAP_ESCAPED_CHAR(c) \ + ((c) == '*' || (c) == '(' || (c) == ')' || (c) == '\\') + const char *ldap_escape(const char *str) { - string_t *s; const char *p; + string_t *ret; for (p = str; *p != '\0'; p++) { - if (strchr("*()\\", *p) != NULL) + if (IS_LDAP_ESCAPED_CHAR(*p)) break; } if (*p == '\0') return str; - s = t_str_new(64); - str_append_n(s, str, (size_t) (p-str)); + ret = t_str_new((size_t) (p - str) + 64); + str_append_n(ret, str, (size_t) (p - str)); + for (; *p != '\0'; p++) { - if (strchr("*()\\", *p) != NULL) - str_append_c(s, '\\'); - str_append_c(s, *p); + if (IS_LDAP_ESCAPED_CHAR(*p)) + str_append_c(ret, '\\'); + str_append_c(ret, *p); } - return str_c(s); + return str_c(ret); } static const char *parse_setting(const char *key, const char *value,
--- a/src/auth/db-pgsql.c Wed Apr 02 05:05:38 2003 +0300 +++ b/src/auth/db-pgsql.c Wed Apr 02 05:09:41 2003 +0300 @@ -19,7 +19,6 @@ DEF(SET_STR, connect), DEF(SET_STR, password_query), DEF(SET_STR, user_query), - DEF(SET_STR, allowed_chars), DEF(SET_STR, default_pass_scheme) }; @@ -27,7 +26,6 @@ MEMBER(connect) "dbname=virtual user=virtual", MEMBER(password_query) "SELECT password FROM users WHERE userid = '%u'", MEMBER(user_query) "SELECT home, uid, gid FROM users WHERE userid = '%u'", - MEMBER(allowed_chars) "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-@", MEMBER(default_pass_scheme) "PLAIN-MD5" }; @@ -36,19 +34,6 @@ static int pgsql_conn_open(struct pgsql_connection *conn); static void pgsql_conn_close(struct pgsql_connection *conn); -int db_pgsql_is_valid_username(struct pgsql_connection *conn, - const char *username) -{ - const char *p; - - for (p = username; *p != '\0'; p++) { - if (strchr(conn->set.allowed_chars, *p) == NULL) - return FALSE; - } - - return TRUE; -} - void db_pgsql_query(struct pgsql_connection *conn, const char *query, struct pgsql_request *request) {
--- a/src/auth/db-pgsql.h Wed Apr 02 05:05:38 2003 +0300 +++ b/src/auth/db-pgsql.h Wed Apr 02 05:09:41 2003 +0300 @@ -37,9 +37,6 @@ void *context; }; -int db_pgsql_is_valid_username(struct pgsql_connection *conn, - const char *username); - void db_pgsql_query(struct pgsql_connection *conn, const char *query, struct pgsql_request *request);
--- a/src/auth/mech-digest-md5.c Wed Apr 02 05:05:38 2003 +0300 +++ b/src/auth/mech-digest-md5.c Wed Apr 02 05:09:41 2003 +0300 @@ -578,16 +578,22 @@ realm, NULL); } - passdb->lookup_credentials(&auth->auth_request, - PASSDB_CREDENTIALS_DIGEST_MD5, - credentials_callback); - return TRUE; + if (mech_is_valid_username(auth_request->user)) { + passdb->lookup_credentials(&auth->auth_request, + PASSDB_CREDENTIALS_DIGEST_MD5, + credentials_callback); + return TRUE; + } + + error = "invalid username"; } if (error == NULL) error = "Authentication failed"; - else if (verbose) - i_info("digest-md5: %s", error); + else if (verbose) { + i_info("digest-md5(%s): %s", + auth->username == NULL ? "" : auth->username, error); + } /* failed */ reply.result = AUTH_LOGIN_RESULT_FAILURE;
--- a/src/auth/mech-plain.c Wed Apr 02 05:05:38 2003 +0300 +++ b/src/auth/mech-plain.c Wed Apr 02 05:09:41 2003 +0300 @@ -44,6 +44,8 @@ if (authenid == NULL) { /* invalid input */ + if (verbose) + i_info("mech-plain: no username given"); mech_auth_finish(auth_request, NULL, 0, FALSE); } else { /* split and save user/realm */ @@ -56,7 +58,17 @@ authenid); } - passdb->verify_plain(auth_request, pass, verify_callback); + if (!mech_is_valid_username(auth_request->user)) { + /* invalid username */ + if (verbose) { + i_info("mech-plain(%s): invalid username", + auth_request->user); + } + mech_auth_finish(auth_request, NULL, 0, FALSE); + } else { + passdb->verify_plain(auth_request, pass, + verify_callback); + } /* make sure it's cleared */ safe_memset(pass, 0, strlen(pass));
--- a/src/auth/mech.c Wed Apr 02 05:05:38 2003 +0300 +++ b/src/auth/mech.c Wed Apr 02 05:09:41 2003 +0300 @@ -18,6 +18,7 @@ enum auth_mech auth_mechanisms; const char *const *auth_realms; const char *default_realm; +char username_chars[256]; static int set_use_cyrus_sasl; static struct mech_module_list *mech_modules; @@ -186,6 +187,18 @@ } } +int mech_is_valid_username(const char *username) +{ + const unsigned char *p; + + for (p = (const unsigned char *)username; *p != '\0'; p++) { + if (username_chars[*p & 0xff] == 0) + return FALSE; + } + + return TRUE; +} + extern struct mech_module mech_plain; extern struct mech_module mech_digest_md5; @@ -234,6 +247,16 @@ if (default_realm != NULL && *default_realm == '\0') default_realm = NULL; + env = getenv("USERNAME_CHARS"); + if (env == NULL || *env == '\0') { + /* all chars are allowed */ + memset(username_chars, 0xff, sizeof(username_chars)); + } else { + memset(username_chars, 0, sizeof(username_chars)); + for (; *env != '\0'; env++) + username_chars[((unsigned char)*env) & 0xff] = 0xff; + } + set_use_cyrus_sasl = getenv("USE_CYRUS_SASL") != NULL; #ifdef USE_CYRUS_SASL2
--- a/src/auth/mech.h Wed Apr 02 05:05:38 2003 +0300 +++ b/src/auth/mech.h Wed Apr 02 05:09:41 2003 +0300 @@ -38,6 +38,7 @@ extern enum auth_mech auth_mechanisms; extern const char *const *auth_realms; extern const char *default_realm; +extern char username_chars[256]; void mech_register_module(struct mech_module *module); void mech_unregister_module(struct mech_module *module); @@ -59,6 +60,8 @@ void mech_auth_finish(struct auth_request *auth_request, const void *data, size_t data_size, int success); +int mech_is_valid_username(const char *username); + void mech_cyrus_sasl_init_lib(void); struct auth_request *mech_cyrus_sasl_new(struct login_connection *conn, struct auth_login_request_new *request,
--- a/src/auth/passdb-pgsql.c Wed Apr 02 05:05:38 2003 +0300 +++ b/src/auth/passdb-pgsql.c Wed Apr 02 05:09:41 2003 +0300 @@ -7,6 +7,7 @@ #include "common.h" #include "str.h" +#include "strescape.h" #include "var-expand.h" #include "password-scheme.h" #include "db-pgsql.h" @@ -103,21 +104,14 @@ string_t *str; str = t_str_new(512); - var_expand(str, conn->set.password_query, auth_request->user, NULL); + var_expand(str, conn->set.password_query, + str_escape(auth_request->user), NULL); query = str_c(str); pgsql_request->callback = pgsql_handle_request; pgsql_request->context = auth_request; - if (db_pgsql_is_valid_username(conn, auth_request->user)) - db_pgsql_query(conn, query, pgsql_request); - else { - if (verbose) { - i_error("pgsql(%s): Invalid username", - auth_request->user); - } - pgsql_handle_request(conn, pgsql_request, NULL); - } + db_pgsql_query(conn, query, pgsql_request); } static void
--- a/src/auth/userdb-pgsql.c Wed Apr 02 05:05:38 2003 +0300 +++ b/src/auth/userdb-pgsql.c Wed Apr 02 05:09:41 2003 +0300 @@ -7,6 +7,7 @@ #include "common.h" #include "str.h" +#include "strescape.h" #include "var-expand.h" #include "db-pgsql.h" #include "userdb.h" @@ -84,7 +85,7 @@ string_t *str; str = t_str_new(512); - var_expand(str, conn->set.user_query, user, NULL); + var_expand(str, conn->set.user_query, str_escape(user), NULL); query = str_c(str); request = i_new(struct userdb_pgsql_request, 1); @@ -92,13 +93,7 @@ request->request.context = context; request->userdb_callback = callback; - if (db_pgsql_is_valid_username(conn, user)) - db_pgsql_query(conn, query, &request->request); - else { - if (verbose) - i_info("pgsql(%s): Invalid username", user); - pgsql_handle_request(conn, &request->request, NULL); - } + db_pgsql_query(conn, query, &request->request); } static void userdb_pgsql_init(const char *args)
--- a/src/master/auth-process.c Wed Apr 02 05:05:38 2003 +0300 +++ b/src/master/auth-process.c Wed Apr 02 05:09:41 2003 +0300 @@ -316,6 +316,7 @@ env_put(t_strconcat("DEFAULT_REALM=", group->set->default_realm, NULL)); env_put(t_strconcat("USERDB=", group->set->userdb, NULL)); env_put(t_strconcat("PASSDB=", group->set->passdb, NULL)); + env_put(t_strconcat("USERNAME_CHARS=", group->set->username_chars, NULL)); if (group->set->use_cyrus_sasl) env_put("USE_CYRUS_SASL=1");
--- a/src/master/master-settings.c Wed Apr 02 05:05:38 2003 +0300 +++ b/src/master/master-settings.c Wed Apr 02 05:09:41 2003 +0300 @@ -207,6 +207,27 @@ MEMBER(uid) 0 /* generated */ }; +struct auth_settings default_auth_settings = { + MEMBER(next) NULL, + + MEMBER(name) NULL, + MEMBER(mechanisms) "plain", + MEMBER(realms) NULL, + MEMBER(default_realm) NULL, + MEMBER(userdb) "passwd", + MEMBER(passdb) "pam", + MEMBER(executable) PKG_LIBEXECDIR"/dovecot-auth", + MEMBER(user) "root", + MEMBER(chroot) NULL, + MEMBER(username_chars) "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@", + + MEMBER(use_cyrus_sasl) FALSE, + MEMBER(verbose) FALSE, + + MEMBER(count) 1, + MEMBER(process_size) 256 +}; + static pool_t settings_pool; struct settings *set = NULL; @@ -402,10 +423,10 @@ struct auth_settings *auth; auth = p_new(settings_pool, struct auth_settings, 1); + + /* copy defaults */ + *auth = default_auth_settings; auth->name = p_strdup(settings_pool, name); - auth->executable = p_strdup(settings_pool, - PKG_LIBEXECDIR"/dovecot-auth"); - auth->count = 1; auth->next = set->auths; set->auths = auth;