[dovecot-cvs] dovecot/src/auth auth-client-connection.c, 1.23,
1.24 mech-anonymous.c, 1.6, 1.7 mech-apop.c, 1.6,
1.7 mech-cram-md5.c, 1.13, 1.14 mech-digest-md5.c, 1.27,
1.28 mech-login.c, 1.4, 1.5 mech-ntlm.c, 1.10,
1.11 mech-plain.c, 1.22, 1.23 mech-rpa.c, 1.9, 1.10 mech.c,
1.51, 1.52 mech.h, 1.29, 1.30 passdb-ldap.c, 1.16,
1.17 passdb-passwd-file.c, 1.12, 1.13 passdb-sql.c, 1.9,
1.10 passdb.c, 1.27, 1.28 passdb.h, 1.17, 1.18
cras at dovecot.org
cras at dovecot.org
Fri Jan 7 19:27:23 EET 2005
Update of /var/lib/cvs/dovecot/src/auth
In directory talvi:/tmp/cvs-serv11214/src/auth
Modified Files:
auth-client-connection.c mech-anonymous.c mech-apop.c
mech-cram-md5.c mech-digest-md5.c mech-login.c mech-ntlm.c
mech-plain.c mech-rpa.c mech.c mech.h passdb-ldap.c
passdb-passwd-file.c passdb-sql.c passdb.c passdb.h
Log Message:
Make FAIL reply contain "temp" parameter if the authentication failed
because of temporary internal error. Also cleaned up the auth code a bit.
Index: auth-client-connection.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-client-connection.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- auth-client-connection.c 1 Nov 2004 13:53:14 -0000 1.23
+++ auth-client-connection.c 7 Jan 2005 17:27:20 -0000 1.24
@@ -89,6 +89,8 @@
str_append_c(str, '\t');
str_append(str, request->extra_fields);
}
+ if (request->internal_failure)
+ str_append(str, "\ttemp");
break;
}
Index: mech-anonymous.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/mech-anonymous.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- mech-anonymous.c 13 Oct 2004 16:38:32 -0000 1.6
+++ mech-anonymous.c 7 Jan 2005 17:27:20 -0000 1.7
@@ -22,7 +22,7 @@
request->callback = callback;
request->user = p_strdup(request->pool, anonymous_username);
- mech_auth_finish(request, NULL, 0, TRUE);
+ mech_auth_success(request, NULL, 0);
}
static void
Index: mech-apop.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/mech-apop.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- mech-apop.c 13 Oct 2004 16:38:32 -0000 1.6
+++ mech-apop.c 7 Jan 2005 17:27:20 -0000 1.7
@@ -31,27 +31,42 @@
unsigned char digest[16];
};
+static int verify_credentials(struct apop_auth_request *request,
+ const char *credentials)
+{
+ unsigned char digest[16];
+ struct md5_context ctx;
+
+ md5_init(&ctx);
+ md5_update(&ctx, request->challenge, strlen(request->challenge));
+ md5_update(&ctx, credentials, strlen(credentials));
+ md5_final(&ctx, digest);
+
+ return memcmp(digest, request->digest, 16) == 0;
+}
+
static void
-apop_credentials_callback(const char *credentials,
+apop_credentials_callback(enum passdb_result result,
+ const char *credentials,
struct auth_request *auth_request)
{
struct apop_auth_request *request =
(struct apop_auth_request *)auth_request;
- unsigned char digest[16];
- struct md5_context ctx;
- int ret = FALSE;
- if (credentials != NULL) {
- md5_init(&ctx);
- md5_update(&ctx, request->challenge,
- strlen(request->challenge));
- md5_update(&ctx, credentials, strlen(credentials));
- md5_final(&ctx, digest);
-
- ret = memcmp(digest, request->digest, 16) == 0;
+ switch (result) {
+ case PASSDB_RESULT_OK:
+ if (verify_credentials(request, credentials))
+ mech_auth_success(auth_request, NULL, 0);
+ else
+ mech_auth_fail(auth_request);
+ break;
+ case PASSDB_RESULT_INTERNAL_FAILURE:
+ mech_auth_internal_failure(auth_request);
+ break;
+ default:
+ mech_auth_fail(auth_request);
+ break;
}
-
- mech_auth_finish(auth_request, NULL, 0, ret);
}
static void
@@ -72,7 +87,7 @@
i_info("apop(%s): no initial respone",
get_log_prefix(auth_request));
}
- mech_auth_finish(auth_request, NULL, 0, FALSE);
+ mech_auth_fail(auth_request);
return;
}
@@ -92,7 +107,7 @@
i_info("apop(%s): invalid challenge",
get_log_prefix(auth_request));
}
- mech_auth_finish(auth_request, NULL, 0, FALSE);
+ mech_auth_fail(auth_request);
return;
}
request->challenge = p_strdup(request->pool, (const char *)data);
@@ -109,7 +124,7 @@
i_info("apop(%s): malformed data",
get_log_prefix(auth_request));
}
- mech_auth_finish(auth_request, NULL, 0, FALSE);
+ mech_auth_fail(auth_request);
return;
}
tmp++;
@@ -120,7 +135,7 @@
i_info("apop(%s): %s",
get_log_prefix(auth_request), error);
}
- mech_auth_finish(auth_request, NULL, 0, FALSE);
+ mech_auth_fail(auth_request);
return;
}
Index: mech-cram-md5.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/mech-cram-md5.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- mech-cram-md5.c 13 Oct 2004 16:38:32 -0000 1.13
+++ mech-cram-md5.c 7 Jan 2005 17:27:20 -0000 1.14
@@ -55,15 +55,15 @@
buffer_t *context_digest_buf;
const char *response_hex;
- if (credentials == NULL)
- return FALSE;
-
context_digest_buf =
buffer_create_data(pool_datastack_create(),
context_digest, sizeof(context_digest));
- if (hex_to_binary(credentials, context_digest_buf) < 0)
+ if (hex_to_binary(credentials, context_digest_buf) < 0) {
+ i_error("cram-md5(%s): passdb credentials are not in hex",
+ get_log_prefix(&request->auth_request));
return FALSE;
+ }
hmac_md5_set_cram_context(&ctx, context_digest);
hmac_md5_update(&ctx, request->challenge, strlen(request->challenge));
@@ -109,20 +109,26 @@
return TRUE;
}
-static void credentials_callback(const char *result,
+static void credentials_callback(enum passdb_result result,
+ const char *credentials,
struct auth_request *auth_request)
{
struct cram_auth_request *request =
(struct cram_auth_request *)auth_request;
- if (verify_credentials(request, result))
- mech_auth_finish(auth_request, NULL, 0, TRUE);
- else {
- if (verbose) {
- i_info("cram-md5(%s): authentication failed",
- get_log_prefix(auth_request));
- }
- mech_auth_finish(auth_request, NULL, 0, FALSE);
+ switch (result) {
+ case PASSDB_RESULT_OK:
+ if (verify_credentials(request, credentials))
+ mech_auth_success(auth_request, NULL, 0);
+ else
+ mech_auth_fail(auth_request);
+ break;
+ case PASSDB_RESULT_INTERNAL_FAILURE:
+ mech_auth_internal_failure(auth_request);
+ break;
+ default:
+ mech_auth_fail(auth_request);
+ break;
}
}
@@ -154,9 +160,7 @@
if (verbose)
i_info("cram-md5(%s): %s", get_log_prefix(auth_request), error);
-
- /* failed */
- mech_auth_finish(auth_request, NULL, 0, FALSE);
+ mech_auth_fail(auth_request);
}
static void
Index: mech-digest-md5.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/mech-digest-md5.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- mech-digest-md5.c 7 Nov 2004 18:06:02 -0000 1.27
+++ mech-digest-md5.c 7 Jan 2005 17:27:20 -0000 1.28
@@ -118,13 +118,19 @@
int i;
/* get the MD5 password */
- if (credentials == NULL || strlen(credentials) != sizeof(digest)*2)
+ if (strlen(credentials) != sizeof(digest)*2) {
+ i_error("digest-md5(%s): passdb credentials' length is wrong",
+ get_log_prefix(&request->auth_request));
return FALSE;
+ }
digest_buf = buffer_create_data(pool_datastack_create(),
digest, sizeof(digest));
- if (hex_to_binary(credentials, digest_buf) < 0)
+ if (hex_to_binary(credentials, digest_buf) < 0) {
+ i_error("digest-md5(%s): passdb credentials are not in hex",
+ get_log_prefix(&request->auth_request));
return FALSE;
+ }
/*
response =
@@ -508,20 +514,31 @@
return !failed;
}
-static void credentials_callback(const char *result,
+static void credentials_callback(enum passdb_result result,
+ const char *credentials,
struct auth_request *auth_request)
{
struct digest_auth_request *request =
(struct digest_auth_request *)auth_request;
- if (!verify_credentials(request, result)) {
- mech_auth_finish(auth_request, NULL, 0, FALSE);
- return;
- }
+ switch (result) {
+ case PASSDB_RESULT_OK:
+ if (!verify_credentials(request, credentials)) {
+ mech_auth_fail(auth_request);
+ return;
+ }
- request->authenticated = TRUE;
- auth_request->callback(auth_request, AUTH_CLIENT_RESULT_CONTINUE,
- request->rspauth, strlen(request->rspauth));
+ request->authenticated = TRUE;
+ auth_request->callback(auth_request, AUTH_CLIENT_RESULT_CONTINUE,
+ request->rspauth, strlen(request->rspauth));
+ break;
+ case PASSDB_RESULT_INTERNAL_FAILURE:
+ mech_auth_internal_failure(auth_request);
+ break;
+ default:
+ mech_auth_fail(auth_request);
+ break;
+ }
}
static void
@@ -536,7 +553,7 @@
if (request->authenticated) {
/* authentication is done, we were just waiting the last
word from client */
- mech_auth_finish(auth_request, NULL, 0, TRUE);
+ mech_auth_success(auth_request, NULL, 0);
return;
}
@@ -566,7 +583,7 @@
get_log_prefix(auth_request), error);
}
- mech_auth_finish(auth_request, NULL, 0, FALSE);
+ mech_auth_fail(auth_request);
}
static void
Index: mech-login.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/mech-login.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- mech-login.c 13 Oct 2004 16:38:32 -0000 1.4
+++ mech-login.c 7 Jan 2005 17:27:20 -0000 1.5
@@ -17,7 +17,17 @@
static void verify_callback(enum passdb_result result,
struct auth_request *request)
{
- mech_auth_finish(request, NULL, 0, result == PASSDB_RESULT_OK);
+ switch (result) {
+ case PASSDB_RESULT_OK:
+ mech_auth_success(request, NULL, 0);
+ break;
+ case PASSDB_RESULT_INTERNAL_FAILURE:
+ mech_auth_internal_failure(request);
+ break;
+ default:
+ mech_auth_fail(request);
+ break;
+ }
}
static void
@@ -38,7 +48,7 @@
i_info("login(%s): %s",
get_log_prefix(request), error);
}
- mech_auth_finish(request, NULL, 0, FALSE);
+ mech_auth_fail(request);
return;
}
Index: mech-ntlm.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/mech-ntlm.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- mech-ntlm.c 29 Nov 2004 02:30:14 -0000 1.10
+++ mech-ntlm.c 7 Jan 2005 17:27:20 -0000 1.11
@@ -33,64 +33,77 @@
struct ntlmssp_response *response;
};
-static void
-lm_credentials_callback(const char *credentials,
- struct auth_request *auth_request)
+static int lm_verify_credentials(struct ntlm_auth_request *request,
+ const char *credentials)
{
- struct ntlm_auth_request *request =
- (struct ntlm_auth_request *)auth_request;
const unsigned char *client_response;
unsigned char lm_response[LM_RESPONSE_SIZE];
unsigned char hash[LM_HASH_SIZE];
unsigned int response_length;
buffer_t *hash_buffer;
- int ret;
response_length =
ntlmssp_buffer_length(request->response, lm_response);
client_response = ntlmssp_buffer_data(request->response, lm_response);
- if (credentials == NULL || response_length < LM_RESPONSE_SIZE) {
- mech_auth_finish(auth_request, NULL, 0, FALSE);
- return;
+ if (response_length < LM_RESPONSE_SIZE) {
+ i_error("ntlm(%s): passdb credentials' length is too small",
+ get_log_prefix(&request->auth_request));
+ return FALSE;
}
- hash_buffer = buffer_create_data(auth_request->pool,
+ hash_buffer = buffer_create_data(request->auth_request.pool,
hash, sizeof(hash));
- hex_to_binary(credentials, hash_buffer);
+ if (hex_to_binary(credentials, hash_buffer) < 0) {
+ i_error("ntlm(%s): passdb credentials are not in hex",
+ get_log_prefix(&request->auth_request));
+ return FALSE;
+ }
ntlmssp_v1_response(hash, request->challenge, lm_response);
-
- ret = memcmp(lm_response, client_response, LM_RESPONSE_SIZE) == 0;
-
- mech_auth_finish(auth_request, NULL, 0, ret);
+ return memcmp(lm_response, client_response, LM_RESPONSE_SIZE) == 0;
}
static void
-ntlm_credentials_callback(const char *credentials,
- struct auth_request *auth_request)
+lm_credentials_callback(enum passdb_result result,
+ const char *credentials,
+ struct auth_request *auth_request)
{
struct ntlm_auth_request *request =
(struct ntlm_auth_request *)auth_request;
+
+ switch (result) {
+ case PASSDB_RESULT_OK:
+ if (lm_verify_credentials(request, credentials))
+ mech_auth_success(auth_request, NULL, 0);
+ else
+ mech_auth_fail(auth_request);
+ break;
+ case PASSDB_RESULT_INTERNAL_FAILURE:
+ mech_auth_internal_failure(auth_request);
+ break;
+ default:
+ mech_auth_fail(auth_request);
+ break;
+ }
+}
+
+static int ntlm_verify_credentials(struct ntlm_auth_request *request,
+ const char *credentials)
+{
+ struct auth_request *auth_request = &request->auth_request;
const unsigned char *client_response;
unsigned char hash[NTLMSSP_HASH_SIZE];
unsigned int response_length;
buffer_t *hash_buffer;
- int ret;
response_length =
ntlmssp_buffer_length(request->response, ntlm_response);
client_response = ntlmssp_buffer_data(request->response, ntlm_response);
- if (credentials == NULL || response_length == 0) {
- /* We can't use LM authentication if NTLM2 was negotiated */
- if (request->ntlm2_negotiated)
- mech_auth_finish(auth_request, NULL, 0, FALSE);
- else
- passdb->lookup_credentials(auth_request,
- PASSDB_CREDENTIALS_LANMAN,
- lm_credentials_callback);
- return;
+ if (response_length == 0) {
+ /* try LM authentication unless NTLM2 was negotiated */
+ return request->ntlm2_negotiated ? -1 : 0;
}
hash_buffer = buffer_create_data(auth_request->pool,
@@ -112,8 +125,8 @@
response_length - NTLMSSP_V2_RESPONSE_SIZE,
ntlm_v2_response);
- ret = memcmp(ntlm_v2_response, client_response,
- NTLMSSP_V2_RESPONSE_SIZE) == 0;
+ return memcmp(ntlm_v2_response, client_response,
+ NTLMSSP_V2_RESPONSE_SIZE) == 0 ? 1 : -1;
} else {
unsigned char ntlm_response[NTLMSSP_RESPONSE_SIZE];
const unsigned char *client_lm_response =
@@ -127,11 +140,43 @@
ntlmssp_v1_response(hash, request->challenge,
ntlm_response);
- ret = memcmp(ntlm_response, client_response,
- NTLMSSP_RESPONSE_SIZE) == 0;
+ return memcmp(ntlm_response, client_response,
+ NTLMSSP_RESPONSE_SIZE) == 0 ? 1 : -1;
}
+}
- mech_auth_finish(auth_request, NULL, 0, ret);
+static void
+ntlm_credentials_callback(enum passdb_result result,
+ const char *credentials,
+ struct auth_request *auth_request)
+{
+ struct ntlm_auth_request *request =
+ (struct ntlm_auth_request *)auth_request;
+ int ret;
+
+ switch (result) {
+ case PASSDB_RESULT_OK:
+ ret = ntlm_verify_credentials(request, credentials);
+ if (ret > 0) {
+ mech_auth_success(auth_request, NULL, 0);
+ return;
+ }
+ if (ret < 0) {
+ mech_auth_fail(auth_request);
+ return;
+ }
+ break;
+ case PASSDB_RESULT_INTERNAL_FAILURE:
+ mech_auth_internal_failure(auth_request);
+ return;
+ default:
+ break;
+ }
+
+ /* NTLM credentials not found or didn't want to use them,
+ try with LM credentials */
+ passdb->lookup_credentials(auth_request, PASSDB_CREDENTIALS_LANMAN,
+ lm_credentials_callback);
}
static void
@@ -158,7 +203,7 @@
get_log_prefix(auth_request),
error);
}
- mech_auth_finish(auth_request, NULL, 0, FALSE);
+ mech_auth_fail(auth_request);
return;
}
@@ -183,7 +228,7 @@
get_log_prefix(auth_request),
error);
}
- mech_auth_finish(auth_request, NULL, 0, FALSE);
+ mech_auth_fail(auth_request);
return;
}
@@ -199,7 +244,7 @@
i_info("ntlm(%s): %s",
get_log_prefix(auth_request), error);
}
- mech_auth_finish(auth_request, NULL, 0, FALSE);
+ mech_auth_fail(auth_request);
return;
}
Index: mech-plain.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/mech-plain.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- mech-plain.c 13 Oct 2004 16:38:32 -0000 1.22
+++ mech-plain.c 7 Jan 2005 17:27:20 -0000 1.23
@@ -8,7 +8,17 @@
static void verify_callback(enum passdb_result result,
struct auth_request *request)
{
- mech_auth_finish(request, NULL, 0, result == PASSDB_RESULT_OK);
+ switch (result) {
+ case PASSDB_RESULT_OK:
+ mech_auth_success(request, NULL, 0);
+ break;
+ case PASSDB_RESULT_INTERNAL_FAILURE:
+ mech_auth_internal_failure(request);
+ break;
+ default:
+ mech_auth_fail(request);
+ break;
+ }
}
static void
@@ -48,7 +58,7 @@
i_info("plain(%s): invalid input",
get_log_prefix(request));
}
- mech_auth_finish(request, NULL, 0, FALSE);
+ mech_auth_fail(request);
} else {
/* split and save user/realm */
if (strchr(authenid, '@') == NULL && default_realm != NULL) {
@@ -65,7 +75,7 @@
i_info("plain(%s): %s",
get_log_prefix(request), error);
}
- mech_auth_finish(request, NULL, 0, FALSE);
+ mech_auth_fail(request);
} else {
passdb->verify_plain(request, pass, verify_callback);
}
Index: mech-rpa.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/mech-rpa.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- mech-rpa.c 29 Nov 2004 02:30:14 -0000 1.9
+++ mech-rpa.c 7 Jan 2005 17:27:20 -0000 1.10
@@ -29,7 +29,7 @@
int phase;
/* cached: */
- unsigned char *pwd_md5;
+ unsigned char pwd_md5[16];
size_t service_len;
const unsigned char *service_ucs2be;
size_t username_len;
@@ -399,36 +399,48 @@
return buffer_free_without_data(buf);
}
-static void
-rpa_credentials_callback(const char *credentials,
- struct auth_request *auth_request)
+static int verify_credentials(struct rpa_auth_request *request,
+ const char *credentials)
{
- struct rpa_auth_request *request =
- (struct rpa_auth_request *)auth_request;
unsigned char response[16];
buffer_t *hash_buffer;
- const unsigned char *token4;
- size_t token4_size;
- if (credentials == NULL) {
- mech_auth_finish(auth_request, NULL, 0, FALSE);
- return;
- }
-
- request->pwd_md5 = p_malloc(request->pool, 16);
hash_buffer = buffer_create_data(request->pool, request->pwd_md5, 16);
hex_to_binary(credentials, hash_buffer);
rpa_user_response(request, response);
- if (memcmp(response, request->user_response, 16) != 0) {
- mech_auth_finish(auth_request, NULL, 0, FALSE);
- return;
- }
+ return memcmp(response, request->user_response, 16) == 0;
+}
- token4 = mech_rpa_build_token4(request, &token4_size);
- auth_request->callback(auth_request, AUTH_CLIENT_RESULT_CONTINUE,
- token4, token4_size);
- request->phase = 2;
+static void
+rpa_credentials_callback(enum passdb_result result,
+ const char *credentials,
+ struct auth_request *auth_request)
+{
+ struct rpa_auth_request *request =
+ (struct rpa_auth_request *)auth_request;
+ const unsigned char *token4;
+ size_t token4_size;
+
+ switch (result) {
+ case PASSDB_RESULT_OK:
+ if (!verify_credentials(request, credentials))
+ mech_auth_fail(auth_request);
+ else {
+ token4 = mech_rpa_build_token4(request, &token4_size);
+ auth_request->callback(auth_request,
+ AUTH_CLIENT_RESULT_CONTINUE,
+ token4, token4_size);
+ request->phase = 2;
+ }
+ break;
+ case PASSDB_RESULT_INTERNAL_FAILURE:
+ mech_auth_internal_failure(auth_request);
+ break;
+ default:
+ mech_auth_fail(auth_request);
+ break;
+ }
}
static void
@@ -446,7 +458,7 @@
i_info("rpa(%s): invalid token 1, %s",
get_log_prefix(auth_request), error);
}
- mech_auth_finish(auth_request, NULL, 0, FALSE);
+ mech_auth_fail(auth_request);
return;
}
@@ -478,7 +490,7 @@
i_info("rpa(%s): invalid token 3, %s",
get_log_prefix(auth_request), error);
}
- mech_auth_finish(auth_request, NULL, 0, FALSE);
+ mech_auth_fail(auth_request);
return;
}
@@ -487,7 +499,7 @@
i_info("rpa(%s): %s",
get_log_prefix(auth_request), error);
}
- mech_auth_finish(auth_request, NULL, 0, FALSE);
+ mech_auth_fail(auth_request);
return;
}
@@ -500,7 +512,6 @@
const unsigned char *data, size_t data_size)
{
static const unsigned char client_ack[3] = { 0x60, 0x01, 0x00 };
- int ret = TRUE;
if ((data_size != sizeof(client_ack)) ||
(memcmp(data, client_ack, sizeof(client_ack)) != 0)) {
@@ -508,10 +519,10 @@
i_info("rpa(%s): invalid token 5 or client rejects us",
get_log_prefix(auth_request));
}
- ret = FALSE;
+ mech_auth_fail(auth_request);
+ } else {
+ mech_auth_success(auth_request, NULL, 0);
}
-
- mech_auth_finish(auth_request, NULL, 0, ret);
}
static void
@@ -535,7 +546,7 @@
mech_rpa_auth_phase3(auth_request, data, data_size);
break;
default:
- mech_auth_finish(auth_request, NULL, 0, FALSE);
+ mech_auth_fail(auth_request);
break;
}
}
Index: mech.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/mech.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- mech.c 8 Dec 2004 22:35:50 -0000 1.51
+++ mech.c 7 Jan 2005 17:27:20 -0000 1.52
@@ -127,37 +127,9 @@
auth_request_unref(request);
}
-void mech_auth_finish(struct auth_request *request,
- const void *data, size_t data_size, int success)
+void mech_auth_success(struct auth_request *request,
+ const void *data, size_t data_size)
{
- if (!success) {
- if (request->no_failure_delay) {
- /* passdb specifically requested to to delay the
- reply. */
- request->callback(request, AUTH_CLIENT_RESULT_FAILURE,
- NULL, 0);
- auth_request_destroy(request);
- return;
- }
-
- /* failure. don't announce it immediately to avoid
- a) timing attacks, b) flooding */
- if (auth_failures_buf->used > 0) {
- const struct auth_request *const *requests;
-
- requests = auth_failures_buf->data;
- requests += auth_failures_buf->used/sizeof(*requests)-1;
- i_assert(*requests != request);
- }
-
- buffer_append(auth_failures_buf, &request, sizeof(request));
-
- /* make sure the request isn't found anymore */
- auth_request_ref(request);
- auth_request_destroy(request);
- return;
- }
-
request->successful = TRUE;
if (request->conn != NULL) {
request->callback(request, AUTH_CLIENT_RESULT_SUCCESS,
@@ -172,6 +144,38 @@
}
}
+void mech_auth_fail(struct auth_request *request)
+{
+ if (request->no_failure_delay) {
+ /* passdb specifically requested to to delay the reply. */
+ request->callback(request, AUTH_CLIENT_RESULT_FAILURE, NULL, 0);
+ auth_request_destroy(request);
+ return;
+ }
+
+ /* failure. don't announce it immediately to avoid
+ a) timing attacks, b) flooding */
+ if (auth_failures_buf->used > 0) {
+ const struct auth_request *const *requests;
+
+ requests = auth_failures_buf->data;
+ requests += auth_failures_buf->used/sizeof(*requests)-1;
+ i_assert(*requests != request);
+ }
+
+ buffer_append(auth_failures_buf, &request, sizeof(request));
+
+ /* make sure the request isn't found anymore */
+ auth_request_ref(request);
+ auth_request_destroy(request);
+}
+
+void mech_auth_internal_failure(struct auth_request *request)
+{
+ request->internal_failure = TRUE;
+ mech_auth_fail(request);
+}
+
int mech_fix_username(char *username, const char **error_r)
{
unsigned char *p;
Index: mech.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/mech.h,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- mech.h 8 Dec 2004 22:35:50 -0000 1.29
+++ mech.h 7 Jan 2005 17:27:20 -0000 1.30
@@ -35,6 +35,7 @@
mech_callback_t *callback;
unsigned int successful:1;
+ unsigned int internal_failure:1;
unsigned int accept_input:1;
unsigned int no_failure_delay:1;
unsigned int no_login:1;
@@ -81,8 +82,10 @@
const string_t *auth_mechanisms_get_list(void);
-void mech_auth_finish(struct auth_request *request,
- const void *data, size_t data_size, int success);
+void mech_auth_success(struct auth_request *request,
+ const void *data, size_t data_size);
+void mech_auth_fail(struct auth_request *request);
+void mech_auth_internal_failure(struct auth_request *request);
int mech_fix_username(char *username, const char **error_r);
Index: passdb-ldap.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-ldap.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- passdb-ldap.c 6 Jan 2005 15:41:53 -0000 1.16
+++ passdb-ldap.c 7 Jan 2005 17:27:20 -0000 1.17
@@ -54,12 +54,14 @@
struct passdb_ldap_request *ldap_request =
(struct passdb_ldap_request *) request;
struct auth_request *auth_request = request->context;
+ enum passdb_result result;
LDAPMessage *entry;
BerElement *ber;
char *attr, **vals;
const char *user, *password, *scheme;
int ret;
+ result = PASSDB_RESULT_USER_UNKNOWN;
user = auth_request->user;
password = NULL;
@@ -69,6 +71,8 @@
i_error("ldap(%s): ldap_search() failed: %s",
get_log_prefix(auth_request),
ldap_err2string(ret));
+
+ result = PASSDB_RESULT_INTERNAL_FAILURE;
res = NULL;
}
}
@@ -105,7 +109,7 @@
}
}
- /* LDAP result is free'd now. we can check if auth_request is
+ /* LDAP result is freed now. we can check if auth_request is
even needed anymore */
if (!auth_request_unref(auth_request))
return;
@@ -117,7 +121,7 @@
}
if (ldap_request->credentials != -1) {
- passdb_handle_credentials(ldap_request->credentials,
+ passdb_handle_credentials(result, ldap_request->credentials,
password, scheme,
ldap_request->callback.lookup_credentials,
auth_request);
@@ -126,8 +130,7 @@
/* verify plain */
if (password == NULL) {
- ldap_request->callback.verify_plain(PASSDB_RESULT_USER_UNKNOWN,
- auth_request);
+ ldap_request->callback.verify_plain(result, auth_request);
return;
}
@@ -219,7 +222,9 @@
scheme = passdb_ldap_conn->conn->set.
default_pass_scheme;
}
- passdb_handle_credentials(credentials, result, scheme,
+ passdb_handle_credentials(result != NULL ? PASSDB_RESULT_OK :
+ PASSDB_RESULT_USER_UNKNOWN,
+ credentials, result, scheme,
callback, request);
return;
}
Index: passdb-passwd-file.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-passwd-file.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- passdb-passwd-file.c 6 Dec 2004 16:39:02 -0000 1.12
+++ passdb-passwd-file.c 7 Jan 2005 17:27:20 -0000 1.13
@@ -56,14 +56,14 @@
pu = db_passwd_file_lookup(passdb_pwf, request);
if (pu == NULL) {
- callback(NULL, request);
+ callback(PASSDB_RESULT_USER_UNKNOWN, NULL, request);
return;
}
crypted_pass = pu->password;
scheme = password_get_scheme(&crypted_pass);
- passdb_handle_credentials(credentials, crypted_pass,
+ passdb_handle_credentials(PASSDB_RESULT_OK, credentials, crypted_pass,
scheme, callback, request);
}
Index: passdb-sql.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-sql.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- passdb-sql.c 6 Jan 2005 15:41:53 -0000 1.9
+++ passdb-sql.c 7 Jan 2005 17:27:20 -0000 1.10
@@ -57,9 +57,11 @@
{
struct passdb_sql_request *sql_request = context;
struct auth_request *auth_request = sql_request->auth_request;
+ enum passdb_result passdb_result;
const char *user, *password, *scheme;
int ret, idx;
+ passdb_result = PASSDB_RESULT_USER_UNKNOWN;
user = auth_request->user;
password = NULL;
@@ -68,6 +70,7 @@
i_error("sql(%s): Password query failed: %s",
get_log_prefix(auth_request),
sql_result_get_error(result));
+ passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
} else if (ret == 0) {
if (verbose) {
i_info("sql(%s): Unknown user",
@@ -101,8 +104,8 @@
}
if (sql_request->credentials != -1) {
- passdb_handle_credentials(sql_request->credentials,
- password, scheme,
+ passdb_handle_credentials(passdb_result,
+ sql_request->credentials, password, scheme,
sql_request->callback.lookup_credentials,
auth_request);
i_free(sql_request);
@@ -111,8 +114,7 @@
/* verify plain */
if (password == NULL) {
- sql_request->callback.verify_plain(PASSDB_RESULT_USER_UNKNOWN,
- auth_request);
+ sql_request->callback.verify_plain(passdb_result, auth_request);
i_free(sql_request);
return;
}
@@ -129,8 +131,8 @@
}
sql_request->callback.verify_plain(ret > 0 ? PASSDB_RESULT_OK :
- PASSDB_RESULT_PASSWORD_MISMATCH,
- auth_request);
+ PASSDB_RESULT_PASSWORD_MISMATCH,
+ auth_request);
i_free(sql_request);
}
@@ -186,7 +188,9 @@
&result, &scheme)) {
if (scheme == NULL)
scheme = passdb_sql_conn->set.default_pass_scheme;
- passdb_handle_credentials(credentials, result, scheme,
+ passdb_handle_credentials(result != NULL ? PASSDB_RESULT_OK :
+ PASSDB_RESULT_USER_UNKNOWN,
+ credentials, result, scheme,
callback, request);
return;
}
Index: passdb.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- passdb.c 6 Dec 2004 16:42:12 -0000 1.27
+++ passdb.c 7 Jan 2005 17:27:20 -0000 1.28
@@ -71,44 +71,49 @@
return "??";
}
-void passdb_handle_credentials(enum passdb_credentials credentials,
+void passdb_handle_credentials(enum passdb_result result,
+ enum passdb_credentials credentials,
const char *password, const char *scheme,
lookup_credentials_callback_t *callback,
struct auth_request *auth_request)
{
const char *wanted_scheme;
+ if (result != PASSDB_RESULT_OK) {
+ callback(result, NULL, auth_request);
+ return;
+ }
+ i_assert(password != NULL);
+
if (credentials == PASSDB_CREDENTIALS_CRYPT) {
/* anything goes */
- if (password != NULL)
- password = t_strdup_printf("{%s}%s", scheme, password);
- callback(password, auth_request);
+ password = t_strdup_printf("{%s}%s", scheme, password);
+ callback(result, password, auth_request);
return;
}
- if (password != NULL) {
- wanted_scheme = passdb_credentials_to_str(credentials);
- if (strcasecmp(scheme, wanted_scheme) != 0) {
- if (strcasecmp(scheme, "PLAIN") == 0 ||
- strcasecmp(scheme, "CLEARTEXT") == 0) {
- /* we can generate anything out of plaintext
- passwords */
- password = password_generate(password,
- auth_request->user,
- wanted_scheme);
- } else {
- if (verbose) {
- i_info("password(%s): Requested %s "
- "scheme, but we have only %s",
- auth_request->user,
- wanted_scheme, scheme);
- }
- password = NULL;
+ wanted_scheme = passdb_credentials_to_str(credentials);
+ if (strcasecmp(scheme, wanted_scheme) != 0) {
+ if (strcasecmp(scheme, "PLAIN") != 0 &&
+ strcasecmp(scheme, "CLEARTEXT") != 0) {
+ if (verbose) {
+ i_info("password(%s): Requested %s "
+ "scheme, but we have only %s",
+ auth_request->user,
+ wanted_scheme, scheme);
}
+ callback(PASSDB_RESULT_SCHEME_NOT_AVAILABLE,
+ NULL, auth_request);
+ return;
}
+
+ /* we can generate anything out of plaintext passwords */
+ password = password_generate(password, auth_request->user,
+ wanted_scheme);
+ i_assert(password != NULL);
}
- callback(password, auth_request);
+ callback(PASSDB_RESULT_OK, password, auth_request);
}
void passdb_preinit(void)
Index: passdb.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- passdb.h 6 Dec 2004 16:39:02 -0000 1.17
+++ passdb.h 7 Jan 2005 17:27:20 -0000 1.18
@@ -22,6 +22,7 @@
PASSDB_RESULT_USER_UNKNOWN = -1,
PASSDB_RESULT_USER_DISABLED = -2,
PASSDB_RESULT_INTERNAL_FAILURE = -3,
+ PASSDB_RESULT_SCHEME_NOT_AVAILABLE = -4,
PASSDB_RESULT_PASSWORD_MISMATCH = 0,
PASSDB_RESULT_OK = 1,
@@ -29,7 +30,8 @@
typedef void verify_plain_callback_t(enum passdb_result result,
struct auth_request *request);
-typedef void lookup_credentials_callback_t(const char *result,
+typedef void lookup_credentials_callback_t(enum passdb_result result,
+ const char *credentials,
struct auth_request *request);
struct passdb_module {
@@ -50,7 +52,8 @@
lookup_credentials_callback_t *callback);
};
-void passdb_handle_credentials(enum passdb_credentials credentials,
+void passdb_handle_credentials(enum passdb_result result,
+ enum passdb_credentials credentials,
const char *password, const char *scheme,
lookup_credentials_callback_t *callback,
struct auth_request *auth_request);
More information about the dovecot-cvs
mailing list