dovecot-2.2: checkpassword: Escape transferred extra fields prop...
dovecot at dovecot.org
dovecot at dovecot.org
Sun May 20 03:26:27 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/e5ed29ef593e
changeset: 14314:e5ed29ef593e
user: Timo Sirainen <tss at iki.fi>
date: Sat Mar 10 14:11:32 2012 +0200
description:
checkpassword: Escape transferred extra fields properly.
diffstat:
src/auth/auth-request.c | 30 ++++++++++++++++++------------
src/auth/auth-request.h | 3 +++
src/auth/checkpassword-reply.c | 14 +++++++++++---
src/auth/db-checkpassword.c | 20 ++++++++++----------
src/auth/db-checkpassword.h | 1 +
src/auth/passdb-checkpassword.c | 5 ++++-
src/auth/userdb-checkpassword.c | 8 ++++++++
7 files changed, 55 insertions(+), 26 deletions(-)
diffs (240 lines):
diff -r e3c1f3f93add -r e5ed29ef593e src/auth/auth-request.c
--- a/src/auth/auth-request.c Sat Mar 10 13:49:12 2012 +0200
+++ b/src/auth/auth-request.c Sat Mar 10 14:11:32 2012 +0200
@@ -1287,25 +1287,31 @@
}
}
+void auth_request_set_field_keyvalue(struct auth_request *request,
+ const char *field,
+ const char *default_scheme)
+{
+ const char *key, *value;
+
+ value = strchr(field, '=');
+ if (value == NULL) {
+ key = field;
+ value = "";
+ } else {
+ key = t_strdup_until(field, value);
+ value++;
+ }
+ auth_request_set_field(request, key, value, default_scheme);
+}
+
void auth_request_set_fields(struct auth_request *request,
const char *const *fields,
const char *default_scheme)
{
- const char *key, *value;
-
for (; *fields != NULL; fields++) {
if (**fields == '\0')
continue;
-
- value = strchr(*fields, '=');
- if (value == NULL) {
- key = *fields;
- value = "";
- } else {
- key = t_strdup_until(*fields, value);
- value++;
- }
- auth_request_set_field(request, key, value, default_scheme);
+ auth_request_set_field_keyvalue(request, *fields, default_scheme);
}
}
diff -r e3c1f3f93add -r e5ed29ef593e src/auth/auth-request.h
--- a/src/auth/auth-request.h Sat Mar 10 13:49:12 2012 +0200
+++ b/src/auth/auth-request.h Sat Mar 10 14:11:32 2012 +0200
@@ -171,6 +171,9 @@
void auth_request_set_field(struct auth_request *request,
const char *name, const char *value,
const char *default_scheme);
+void auth_request_set_field_keyvalue(struct auth_request *request,
+ const char *field,
+ const char *default_scheme);
void auth_request_set_fields(struct auth_request *request,
const char *const *fields,
const char *default_scheme);
diff -r e3c1f3f93add -r e5ed29ef593e src/auth/checkpassword-reply.c
--- a/src/auth/checkpassword-reply.c Sat Mar 10 13:49:12 2012 +0200
+++ b/src/auth/checkpassword-reply.c Sat Mar 10 14:11:32 2012 +0200
@@ -2,6 +2,7 @@
#include "lib.h"
#include "str.h"
+#include "strescape.h"
#include "write-full.h"
#include <stdlib.h>
@@ -23,7 +24,9 @@
i_error("checkpassword: USER contains TAB");
return 1;
}
- str_printfa(str, "user=%s\t", user);
+ str_printfa(str, "user=");
+ str_tabescape_write(str, user);
+ str_append_c(str, '\t');
}
home = getenv("HOME");
@@ -32,7 +35,9 @@
i_error("checkpassword: HOME contains TAB");
return 1;
}
- str_printfa(str, "userdb_home=%s\t", home);
+ str_printfa(str, "userdb_home=");
+ str_tabescape_write(str, home);
+ str_append_c(str, '\t');
}
extra_env = getenv("EXTRA");
@@ -45,7 +50,10 @@
uid_found = TRUE;
else if (strcmp(key, "userdb_gid") == 0)
gid_found = TRUE;
- str_printfa(str, "%s=%s\t", key, value);
+ str_tabescape_write(str, key);
+ str_append_c(str, '=');
+ str_tabescape_write(str, value);
+ str_append_c(str, '\t');
}
}
}
diff -r e3c1f3f93add -r e5ed29ef593e src/auth/db-checkpassword.c
--- a/src/auth/db-checkpassword.c Sat Mar 10 13:49:12 2012 +0200
+++ b/src/auth/db-checkpassword.c Sat Mar 10 14:11:32 2012 +0200
@@ -12,6 +12,7 @@
#include "execv-const.h"
#include "env-util.h"
#include "safe-memset.h"
+#include "strescape.h"
#include "child-wait.h"
#include "var-expand.h"
#include "db-checkpassword.h"
@@ -107,9 +108,13 @@
enum db_checkpassword_status status)
{
struct chkpw_auth_request *request = *_request;
+ const char *const *extra_fields;
*_request = NULL;
- request->callback(request->request, status, request->context);
+
+ extra_fields = t_strsplit_tabescaped(str_c(request->input_buf));
+ request->callback(request->request, status, extra_fields,
+ request->context);
checkpassword_request_free(&request);
}
@@ -148,9 +153,6 @@
checkpassword_internal_failure(&request);
break;
}
-
- auth_request_set_fields(request->request,
- t_strsplit(str_c(request->input_buf), "\t"), NULL);
checkpassword_finish(&request, DB_CHECKPASSWORD_STATUS_OK);
break;
case 2:
@@ -192,9 +194,6 @@
checkpassword_internal_failure(&request);
break;
}
-
- auth_request_set_fields(request->request,
- t_strsplit(str_c(request->input_buf), "\t"), NULL);
checkpassword_finish(&request, DB_CHECKPASSWORD_STATUS_OK);
break;
default:
@@ -457,7 +456,8 @@
auth_request_log_info(request, "checkpassword",
"Username+password combination too long (%u bytes)",
output_len);
- callback(request, DB_CHECKPASSWORD_STATUS_FAILURE, context);
+ callback(request, DB_CHECKPASSWORD_STATUS_FAILURE,
+ NULL, context);
return;
}
@@ -470,7 +470,7 @@
(void)close(fd_in[1]);
}
callback(request, DB_CHECKPASSWORD_STATUS_INTERNAL_FAILURE,
- context);
+ NULL, context);
return;
}
@@ -483,7 +483,7 @@
(void)close(fd_out[0]);
(void)close(fd_out[1]);
callback(request, DB_CHECKPASSWORD_STATUS_INTERNAL_FAILURE,
- context);
+ NULL, context);
return;
}
diff -r e3c1f3f93add -r e5ed29ef593e src/auth/db-checkpassword.h
--- a/src/auth/db-checkpassword.h Sat Mar 10 13:49:12 2012 +0200
+++ b/src/auth/db-checkpassword.h Sat Mar 10 14:11:32 2012 +0200
@@ -12,6 +12,7 @@
typedef void db_checkpassword_callback_t(struct auth_request *request,
enum db_checkpassword_status status,
+ const char *const *extra_fields,
void *context);
struct db_checkpassword *
diff -r e3c1f3f93add -r e5ed29ef593e src/auth/passdb-checkpassword.c
--- a/src/auth/passdb-checkpassword.c Sat Mar 10 13:49:12 2012 +0200
+++ b/src/auth/passdb-checkpassword.c Sat Mar 10 14:11:32 2012 +0200
@@ -14,7 +14,9 @@
static void
auth_checkpassword_callback(struct auth_request *request,
- enum db_checkpassword_status status, void *context)
+ enum db_checkpassword_status status,
+ const char *const *extra_fields,
+ void *context)
{
verify_plain_callback_t *callback = context;
@@ -26,6 +28,7 @@
callback(PASSDB_RESULT_PASSWORD_MISMATCH, request);
break;
case DB_CHECKPASSWORD_STATUS_OK:
+ auth_request_set_fields(request, extra_fields, NULL);
callback(PASSDB_RESULT_OK, request);
break;
}
diff -r e3c1f3f93add -r e5ed29ef593e src/auth/userdb-checkpassword.c
--- a/src/auth/userdb-checkpassword.c Sat Mar 10 13:49:12 2012 +0200
+++ b/src/auth/userdb-checkpassword.c Sat Mar 10 14:11:32 2012 +0200
@@ -15,9 +15,11 @@
static void
userdb_checkpassword_callback(struct auth_request *request,
enum db_checkpassword_status status,
+ const char *const *extra_fields,
void *context)
{
userdb_callback_t *callback = context;
+ unsigned int i;
switch (status) {
case DB_CHECKPASSWORD_STATUS_INTERNAL_FAILURE:
@@ -27,6 +29,12 @@
callback(USERDB_RESULT_USER_UNKNOWN, request);
break;
case DB_CHECKPASSWORD_STATUS_OK:
+ for (i = 0; extra_fields[i] != NULL; i++) {
+ if (strncmp(extra_fields[i], "userdb_", 7) != 0)
+ continue;
+ auth_request_set_field_keyvalue(request,
+ extra_fields[i], NULL);
+ }
callback(USERDB_RESULT_OK, request);
break;
}
More information about the dovecot-cvs
mailing list