dovecot-2.2: scram-sha1: Support authzid field. Check fields' co...

dovecot at dovecot.org dovecot at dovecot.org
Wed Mar 20 21:45:49 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/0af0def22533
changeset: 16072:0af0def22533
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Feb 26 09:05:09 2013 +0200
description:
scram-sha1: Support authzid field. Check fields' correctness better.

diffstat:

 src/auth/mech-scram-sha1.c |  64 +++++++++++++++++++++++++++++++++++++--------
 1 files changed, 52 insertions(+), 12 deletions(-)

diffs (106 lines):

diff -r fa9387588430 -r 0af0def22533 src/auth/mech-scram-sha1.c
--- a/src/auth/mech-scram-sha1.c	Mon Feb 25 17:23:25 2013 +0200
+++ b/src/auth/mech-scram-sha1.c	Tue Feb 26 09:05:09 2013 +0200
@@ -150,40 +150,75 @@
 				     const unsigned char *data, size_t size,
 				     const char **error_r)
 {
-	const char *const *fields;
+	const char *const *fields, *login_username = NULL;
+	const char *gs2_cbind_flag, *authzid, *username, *nonce;
 
 	fields = t_strsplit(t_strndup(data, size), ",");
 	if (str_array_length(fields) < 4) {
 		*error_r = "Invalid initial client message";
 		return FALSE;
 	}
+	gs2_cbind_flag = fields[0];
+	authzid = fields[1];
+	username = fields[2];
+	nonce = fields[3];
 
-	switch (fields[0][0]) {
+	/* Order of fields is fixed:
+
+	   client-first-message = gs2-header client-first-message-bare
+	   gs2-header      = gs2-cbind-flag "," [ authzid ] ","
+	   gs2-cbind-flag  = ("p=" cb-name) / "n" / "y"
+
+	   client-first-message-bare = [reserved-mext ","]
+                                       username "," nonce ["," extensions]
+	   reserved-mext   = "m=" 1*(value-char)
+
+	   username        = "n=" saslname
+	   nonce           = "r=" c-nonce [s-nonce]
+
+	   extensions      = attr-val *("," attr-val)
+			       ;; All extensions are optional,
+			       ;; i.e., unrecognized attributes
+			       ;; not defined in this document
+			       ;; MUST be ignored.
+	   attr-val        = ALPHA "=" value
+
+	   */
+	switch (gs2_cbind_flag[0]) {
 	case 'p':
 		*error_r = "Channel binding not supported";
 		return FALSE;
 	case 'y':
 	case 'n':
-		request->gs2_cbind_flag = p_strdup(request->pool, fields[0]);
+		request->gs2_cbind_flag =
+			p_strdup(request->pool, gs2_cbind_flag);
 		break;
 	default:
 		*error_r = "Invalid GS2 header";
 		return FALSE;
 	}
 
-	if (fields[1][0] != '\0') {
-		*error_r = "authzid not supported";
+	if (authzid[0] == '\0')
+		;
+	else if (authzid[0] == 'a' && authzid[1] == '=') {
+		/* Unescape authzid */
+		login_username = scram_unescape_username(authzid + 2);
+
+		if (login_username == NULL) {
+			*error_r = "authzid escaping is invalid";
+			return FALSE;
+		}
+	} else {
+		*error_r = "Invalid authzid field";
 		return FALSE;
 	}
-	if (fields[2][0] == 'm') {
+	if (username[0] == 'm') {
 		*error_r = "Mandatory extension(s) not supported";
 		return FALSE;
 	}
-	if (fields[2][0] == 'n') {
+	if (username[0] == 'n' && username[1] == '=') {
 		/* Unescape username */
-		const char *username =
-			scram_unescape_username(fields[2] + 2);
-
+		username = scram_unescape_username(username + 2);
 		if (username == NULL) {
 			*error_r = "Username escaping is invalid";
 			return FALSE;
@@ -195,9 +230,14 @@
 		*error_r = "Invalid username field";
 		return FALSE;
 	}
+	if (login_username != NULL) {
+		if (!auth_request_set_login_username(&request->auth_request,
+						     login_username, error_r))
+			return FALSE;
+	}
 
-	if (fields[3][0] == 'r')
-		request->cnonce = p_strdup(request->pool, fields[3]+2);
+	if (nonce[0] == 'r' && nonce[1] == '=')
+		request->cnonce = p_strdup(request->pool, nonce+2);
 	else {
 		*error_r = "Invalid client nonce";
 		return FALSE;


More information about the dovecot-cvs mailing list