diff src/auth/auth-request.c @ 13728:9a6aa717bc46

auth: Don't allow auth clients to set internal auth request fields. This could have allowed attacker to bypass authentication if login process was first successfully attacked to allow arbitrary code execution.
author Timo Sirainen <tss@iki.fi>
date Fri, 18 Nov 2011 22:07:16 +0200
parents c9894346b1a3
children f2608c3a64ee
line wrap: on
line diff
--- a/src/auth/auth-request.c	Fri Nov 18 21:37:34 2011 +0200
+++ b/src/auth/auth-request.c	Fri Nov 18 22:07:16 2011 +0200
@@ -207,25 +207,11 @@
 		auth_stream_reply_add(reply, "mech", request->mech_name);
 }
 
-bool auth_request_import(struct auth_request *request,
-			 const char *key, const char *value)
+bool auth_request_import_info(struct auth_request *request,
+			      const char *key, const char *value)
 {
-	if (strcmp(key, "user") == 0)
-		request->user = p_strdup(request->pool, value);
-	else if (strcmp(key, "master_user") == 0)
-		request->master_user = p_strdup(request->pool, value);
-	else if (strcmp(key, "original_username") == 0)
-		request->original_username = p_strdup(request->pool, value);
-	else if (strcmp(key, "requested_login_user") == 0)
-		request->requested_login_user = p_strdup(request->pool, value);
-	else if (strcmp(key, "cert_username") == 0) {
-		if (request->set->ssl_username_from_cert) {
-			/* get username from SSL certificate. it overrides
-			   the username given by the auth mechanism. */
-			request->user = p_strdup(request->pool, value);
-			request->cert_username = TRUE;
-		}
-	} else if (strcmp(key, "service") == 0)
+	/* authentication and user lookups may set these */
+	if (strcmp(key, "service") == 0)
 		request->service = p_strdup(request->pool, value);
 	else if (strcmp(key, "lip") == 0)
 		net_addr2ip(value, &request->local_ip);
@@ -235,14 +221,54 @@
 		request->local_port = atoi(value);
 	else if (strcmp(key, "rport") == 0)
 		request->remote_port = atoi(value);
-	else if (strcmp(key, "secured") == 0)
+	else
+		return FALSE;
+	return TRUE;
+}
+
+bool auth_request_import_auth(struct auth_request *request,
+			      const char *key, const char *value)
+{
+	if (auth_request_import_info(request, key, value))
+		return TRUE;
+
+	/* auth client may set these */
+	if (strcmp(key, "secured") == 0)
 		request->secured = TRUE;
+	else if (strcmp(key, "no-penalty") == 0)
+		request->no_penalty = TRUE;
+	else if (strcmp(key, "valid-client-cert") == 0)
+		request->valid_client_cert = TRUE;
+	else if (strcmp(key, "cert_username") == 0) {
+		if (request->set->ssl_username_from_cert) {
+			/* get username from SSL certificate. it overrides
+			   the username given by the auth mechanism. */
+			request->user = p_strdup(request->pool, value);
+			request->cert_username = TRUE;
+		}
+	} else {
+		return FALSE;
+	}
+	return TRUE;
+}
+
+bool auth_request_import(struct auth_request *request,
+			 const char *key, const char *value)
+{
+	if (auth_request_import_auth(request, key, value))
+		return TRUE;
+
+	/* for communication between auth master and worker processes */
+	if (strcmp(key, "user") == 0)
+		request->user = p_strdup(request->pool, value);
+	else if (strcmp(key, "master_user") == 0)
+		request->master_user = p_strdup(request->pool, value);
+	else if (strcmp(key, "original_username") == 0)
+		request->original_username = p_strdup(request->pool, value);
+	else if (strcmp(key, "requested_login_user") == 0)
+		request->requested_login_user = p_strdup(request->pool, value);
 	else if (strcmp(key, "nologin") == 0)
 		request->no_login = TRUE;
-	else if (strcmp(key, "valid-client-cert") == 0)
-		request->valid_client_cert = TRUE;
-	else if (strcmp(key, "no-penalty") == 0)
-		request->no_penalty = TRUE;
 	else if (strcmp(key, "successful") == 0)
 		request->successful = TRUE;
 	else if (strcmp(key, "skip_password_check") == 0) {