Blame SOURCES/cyrus-sasl-2.1.26-prefer-SCRAM-SHA-1-over-PLAIN.patch

bfd35c
commit 26dcfb2d7176b78e70757aa5d01951a28ca217c7
bfd35c
Author: Alexey Melnikov <alexey.melnikov@isode.com>
bfd35c
Date:   Fri Jul 5 16:37:59 2013 +0100
bfd35c
bfd35c
    Treat SCRAM-SHA-1/DIGEST-MD5 as more secure than PLAIN when selecting the best client side SASL mechanism
bfd35c
    
bfd35c
    Both SCRAM-SHA-1 & DIGEST-MD5 are lacking SASL_SEC_PASS_CREDENTIALS security
bfd35c
    flag, which prevented them from being chosen over PLAIN when PLAIN is selected
bfd35c
    as the best mechanism first. For example the problem can be observed when
bfd35c
    the server advertises "PLAIN DIGEST-MD5 SCRAM-SHA-1" (PLAIN just has to be
bfd35c
    returned before SCRAM/DIGEST.)
bfd35c
    
bfd35c
    Cyrus SASL bug # 3793
bfd35c
bfd35c
diff --git a/lib/client.c b/lib/client.c
bfd35c
index 62dfb0b..31fe346 100644
bfd35c
--- a/lib/client.c
bfd35c
+++ b/lib/client.c
bfd35c
@@ -658,6 +658,20 @@ _sasl_cbinding_disp(sasl_client_params_t *cparams,
bfd35c
     return SASL_OK;
bfd35c
 }
bfd35c
 
bfd35c
+static int
bfd35c
+_sasl_are_current_security_flags_worse_then_best(unsigned best_security_flags,
bfd35c
+						 unsigned current_security_flags)
bfd35c
+{
bfd35c
+    /* We don't qualify SASL_SEC_PASS_CREDENTIALS as "secure" flag */
bfd35c
+    best_security_flags &= ~SASL_SEC_PASS_CREDENTIALS;
bfd35c
+
bfd35c
+    if ((current_security_flags ^ best_security_flags) & best_security_flags) {
bfd35c
+	return 1;
bfd35c
+    } else {
bfd35c
+	return 0;
bfd35c
+    }
bfd35c
+}
bfd35c
+
bfd35c
 /* select a mechanism for a connection
bfd35c
  *  mechlist      -- mechanisms server has available (punctuation ignored)
bfd35c
  *  secret        -- optional secret from previous session
bfd35c
@@ -823,8 +837,9 @@ int sasl_client_start(sasl_conn_t *conn,
bfd35c
 	     */
bfd35c
 
bfd35c
 	    if (bestm &&
bfd35c
-		((m->m.plug->security_flags ^ bestm->m.plug->security_flags) &
bfd35c
-		 bestm->m.plug->security_flags)) {
bfd35c
+		_sasl_are_current_security_flags_worse_then_best(
bfd35c
+		    bestm->m.plug->security_flags,
bfd35c
+		    m->m.plug->security_flags)) {
bfd35c
 		break;
bfd35c
 	    }
bfd35c