Browse code

tls: disable kerberos more thoroughly [fix]

Older openssl versions (< 0.9.8e release) have a bug in the
kerberos code (it uses the wrong malloc, for more details see
openssl bug # 1467). While there is already a workaround for this
openssl bug in the sr code (see commits 36cb8f & 560a42), in some
situations this workaround causes another bug (crash on connection
opening when openssl is compiled with kerberos support and
kerberos is enabled for key exchange).
The current fix will disable automatically all the ciphers containing
KRB5 if the openssl version is < 0.9.8e beta1 or it is between
0.9.9-dev and 0.9.9-beta1.
It iss equivalent to setting cipher_list to "<prev. value>:!KRB5".

Impact: this fix is needed only if openssl is compiled with
kerberos support and the version is < 0.9.8e. It also affects at
least CentOS users with openssl-0.9.8e-12.el5_4.1 (in the centos
openssl package they play some strange games with the version and
report 0.9.8b via SSLeay).

Tested-by: Klaus Darilion klaus.mailinglists at pernau.at
Reported-by: Klaus Darilion klaus.mailinglists at pernau.at
Reported-by: Andreas Rehbein rehbein at e-technik.org
Reported-by: Martin Koenig koenig starface.de

Andrei Pelinescu-Onciul authored on 23/02/2010 15:10:21
Showing 1 changed files
... ...
@@ -271,6 +271,10 @@ static int load_ca_list(tls_domain_t* d)
271 271
 	return 0;
272 272
 }
273 273
 
274
+#define C_DEF_NO_KRB5 "DEFAULT:!KRB5"
275
+#define C_DEF_NO_KRB5_LEN (sizeof(C_DEF_NO_KRB5)-1)
276
+#define C_NO_KRB5_SUFFIX ":!KRB5"
277
+#define C_NO_KRB5_SUFFIX_LEN (sizeof(C_NO_KRB5_SUFFIX)-1)
274 278
 
275 279
 /* 
276 280
  * Configure cipher list 
... ...
@@ -279,12 +283,35 @@ static int set_cipher_list(tls_domain_t* d)
279 283
 {
280 284
 	int i;
281 285
 	int procs_no;
282
-
283
-	if (!d->cipher_list.s) return 0;
286
+	char* cipher_list;
287
+
288
+	cipher_list=d->cipher_list.s;
289
+#ifdef TLS_KSSL_WORKARROUND
290
+	if (openssl_kssl_malloc_bug) { /* is openssl bug #1467 present ? */
291
+		if (d->cipher_list.s==0) {
292
+			/* use "DEFAULT:!KRB5" */
293
+			cipher_list="DEFAULT:!KRB5";
294
+		} else {
295
+			/* append ":!KRB5" */
296
+			cipher_list=shm_malloc(d->cipher_list.len+C_NO_KRB5_SUFFIX_LEN+1);
297
+			if (cipher_list) {
298
+				memcpy(cipher_list, d->cipher_list.s, d->cipher_list.len);
299
+				memcpy(cipher_list+d->cipher_list.len, C_NO_KRB5_SUFFIX,
300
+						C_NO_KRB5_SUFFIX_LEN);
301
+				cipher_list[d->cipher_list.len+C_NO_KRB5_SUFFIX_LEN]=0;
302
+				shm_free(d->cipher_list.s);
303
+				d->cipher_list.s=cipher_list;
304
+				d->cipher_list.len+=C_NO_KRB5_SUFFIX_LEN;
305
+			}
306
+		}
307
+	}
308
+#endif /* TLS_KSSL_WORKARROUND */
309
+	if (!cipher_list) return 0;
284 310
 	procs_no=get_max_procs();
285 311
 	for(i = 0; i < procs_no; i++) {
286
-		if (SSL_CTX_set_cipher_list(d->ctx[i], d->cipher_list.s) == 0 ) {
287
-			ERR("%s: Failure to set SSL context cipher list\n", tls_domain_str(d));
312
+		if (SSL_CTX_set_cipher_list(d->ctx[i], cipher_list) == 0 ) {
313
+			ERR("%s: Failure to set SSL context cipher list \"%s\"\n",
314
+					tls_domain_str(d), cipher_list);
288 315
 			return -1;
289 316
 		}
290 317
 	}