Blame SOURCES/0501-configuration-support-for-CHAP-algorithms.patch

6b208b
From 62741fb13c64bfe41ea45b353b1223a501d36c27 Mon Sep 17 00:00:00 2001
6b208b
From: Chris Leech <cleech@redhat.com>
6b208b
Date: Sun, 24 Nov 2019 13:51:09 -0800
6b208b
Subject: [PATCH] configuration support for CHAP algorithms
6b208b
6b208b
Introduces support for preference lists in configuration files, and uses
6b208b
that for the 'node.session.auth.chap_algs' setting.
6b208b
6b208b
This is also re-used for discovery authentication, rather than have two
6b208b
different configurations.
6b208b
6b208b
(cherry picked from commit d3daa7a2bc3f5bca874d3efd072b34a657c4d492)
6b208b
---
6b208b
 etc/iscsid.conf        |   7 +++
6b208b
 usr/auth.c             |  64 ++++++++++++++-------
6b208b
 usr/auth.h             |   3 +
6b208b
 usr/config.h           |   1 +
6b208b
 usr/idbm.c             | 126 ++++++++++++++++++++++++++++++++++++-----
6b208b
 usr/idbm.h             |   2 +
6b208b
 usr/idbm_fields.h      |   1 +
6b208b
 usr/initiator.h        |   1 +
6b208b
 usr/initiator_common.c |   2 +
6b208b
 usr/login.c            |  11 ++++
6b208b
 10 files changed, 186 insertions(+), 32 deletions(-)
6b208b
6b208b
diff --git a/etc/iscsid.conf b/etc/iscsid.conf
6b208b
index 1af8ed2..82cc7d0 100644
6b208b
--- a/etc/iscsid.conf
6b208b
+++ b/etc/iscsid.conf
6b208b
@@ -56,6 +56,13 @@ node.leading_login = No
6b208b
 # to CHAP. The default is None.
6b208b
 #node.session.auth.authmethod = CHAP
6b208b
 
6b208b
+# To configure which CHAP algorithms to enable set
6b208b
+# node.session.auth.chap_algs to a comma seperated list.
6b208b
+# The algorithms should be listen with most prefered first.
6b208b
+# Valid values are MD5, SHA1, SHA256, and SHA3-256.
6b208b
+# The default is MD5.
6b208b
+#node.session.auth.chap_algs = SHA3-256,SHA256,SHA1,MD5
6b208b
+
6b208b
 # To set a CHAP username and password for initiator
6b208b
 # authentication by the target(s), uncomment the following lines:
6b208b
 #node.session.auth.username = username
6b208b
diff --git a/usr/auth.c b/usr/auth.c
6b208b
index afb4ea3..ec934e6 100644
6b208b
--- a/usr/auth.c
6b208b
+++ b/usr/auth.c
6b208b
@@ -1806,7 +1806,7 @@ acl_chk_chap_alg_list(unsigned int option_count, const int *option_list)
6b208b
 	return 0;
6b208b
 }
6b208b
 
6b208b
-static int
6b208b
+int
6b208b
 acl_set_chap_alg_list(struct iscsi_acl *client, unsigned int option_count,
6b208b
 		      const int *option_list)
6b208b
 {
6b208b
@@ -1819,22 +1819,54 @@ acl_set_chap_alg_list(struct iscsi_acl *client, unsigned int option_count,
6b208b
 }
6b208b
 
6b208b
 int
6b208b
-acl_init_chap_digests(int *value_list) {
6b208b
+acl_init_chap_digests(int *value_list, unsigned *chap_algs, int conf_count) {
6b208b
 	EVP_MD_CTX *context = EVP_MD_CTX_new();
6b208b
 	int i = 0;
6b208b
 
6b208b
-	if (EVP_DigestInit_ex(context, EVP_sha3_256(), NULL)) {
6b208b
-		value_list[i++] = AUTH_CHAP_ALG_SHA3_256;
6b208b
-	}
6b208b
-	if (EVP_DigestInit_ex(context, EVP_sha256(), NULL)) {
6b208b
-		value_list[i++] = AUTH_CHAP_ALG_SHA256;
6b208b
-	}
6b208b
-	if (EVP_DigestInit_ex(context, EVP_sha1(), NULL)) {
6b208b
-		value_list[i++] = AUTH_CHAP_ALG_SHA1;
6b208b
-	}
6b208b
-	if (EVP_DigestInit_ex(context, EVP_md5(), NULL)) {
6b208b
-		value_list[i++] = AUTH_CHAP_ALG_MD5;
6b208b
+	for (int j = 0; j < conf_count; j++) {
6b208b
+		switch (chap_algs[j]) {
6b208b
+		case AUTH_CHAP_ALG_MD5:
6b208b
+			if (EVP_DigestInit_ex(context, EVP_md5(), NULL)) {
6b208b
+				value_list[i++] = AUTH_CHAP_ALG_MD5;
6b208b
+			} else {
6b208b
+				log_warning("Ignoring CHAP algorthm request for "
6b208b
+				            "MD5 due to crypto lib configuration");
6b208b
+			}
6b208b
+			break;
6b208b
+		case AUTH_CHAP_ALG_SHA1:
6b208b
+			if (EVP_DigestInit_ex(context, EVP_sha1(), NULL)) {
6b208b
+				value_list[i++] = AUTH_CHAP_ALG_SHA1;
6b208b
+			} else {
6b208b
+				log_warning("Ignoring CHAP algorthm request for "
6b208b
+				            "SHA1 due to crypto lib configuration");
6b208b
+			}
6b208b
+			break;
6b208b
+		case AUTH_CHAP_ALG_SHA256:
6b208b
+			if (EVP_DigestInit_ex(context, EVP_sha256(), NULL)) {
6b208b
+				value_list[i++] = AUTH_CHAP_ALG_SHA256;
6b208b
+			} else {
6b208b
+				log_warning("Ignoring CHAP algorthm request for "
6b208b
+				            "SHA256 due to crypto lib configuration");
6b208b
+			}
6b208b
+			break;
6b208b
+		case AUTH_CHAP_ALG_SHA3_256:
6b208b
+			if (EVP_DigestInit_ex(context, EVP_sha3_256(), NULL)) {
6b208b
+				value_list[i++] = AUTH_CHAP_ALG_SHA3_256;
6b208b
+			} else {
6b208b
+				log_warning("Ignoring CHAP algorthm request for "
6b208b
+				            "SHA3-256 due to crypto lib configuration");
6b208b
+			}
6b208b
+			break;
6b208b
+		case ~0:
6b208b
+			/* unset value in array, just ignore */
6b208b
+			break;
6b208b
+		default:
6b208b
+			log_warning("Ignoring unknown CHAP algorithm request "
6b208b
+				    "'%d'", chap_algs[j]);
6b208b
+			break;
6b208b
+		}
6b208b
 	}
6b208b
+
6b208b
 	return i;
6b208b
 }
6b208b
 
6b208b
@@ -1924,12 +1956,6 @@ acl_init(int node_type, int buf_desc_count, struct auth_buffer_desc *buff_desc)
6b208b
 		return AUTH_STATUS_ERROR;
6b208b
 	}
6b208b
 
6b208b
-	if (acl_set_chap_alg_list(client, acl_init_chap_digests(value_list),
6b208b
-					value_list) != AUTH_STATUS_NO_ERROR) {
6b208b
-		client->phase = AUTH_PHASE_ERROR;
6b208b
-		return AUTH_STATUS_ERROR;
6b208b
-	}
6b208b
-
6b208b
 	return AUTH_STATUS_NO_ERROR;
6b208b
 }
6b208b
 
6b208b
diff --git a/usr/auth.h b/usr/auth.h
6b208b
index f6dbbe4..16cdb24 100644
6b208b
--- a/usr/auth.h
6b208b
+++ b/usr/auth.h
6b208b
@@ -271,6 +271,9 @@ extern int acl_send_transit_bit(struct iscsi_acl *client, int *value);
6b208b
 extern int acl_set_user_name(struct iscsi_acl *client, const char *username);
6b208b
 extern int acl_set_passwd(struct iscsi_acl *client,
6b208b
 			  const unsigned char *pw_data, unsigned int pw_len);
6b208b
+extern int acl_set_chap_alg_list(struct iscsi_acl *client, unsigned int option_count,
6b208b
+		      const int *option_list);
6b208b
+extern int acl_init_chap_digests(int *value_list, unsigned int *chap_algs, int count);
6b208b
 extern int acl_set_auth_rmt(struct iscsi_acl *client, int auth_rmt);
6b208b
 extern int acl_set_ip_sec(struct iscsi_acl *client, int ip_sec);
6b208b
 extern int acl_get_dbg_status(struct iscsi_acl *client, int *value);
6b208b
diff --git a/usr/config.h b/usr/config.h
6b208b
index 8807c07..dfa4991 100644
6b208b
--- a/usr/config.h
6b208b
+++ b/usr/config.h
6b208b
@@ -58,6 +58,7 @@ struct iscsi_auth_config {
6b208b
 	char username_in[AUTH_STR_MAX_LEN];
6b208b
 	unsigned char password_in[AUTH_STR_MAX_LEN];
6b208b
 	unsigned int password_in_length;
6b208b
+	unsigned int chap_algs[AUTH_CHAP_ALG_MAX_COUNT];
6b208b
 };
6b208b
 
6b208b
 /* all per-connection timeouts go in this structure.
6b208b
diff --git a/usr/idbm.c b/usr/idbm.c
6b208b
index f47ff28..a9c7b40 100644
6b208b
--- a/usr/idbm.c
6b208b
+++ b/usr/idbm.c
6b208b
@@ -49,6 +49,8 @@
6b208b
 
6b208b
 static struct idbm *db;
6b208b
 
6b208b
+#define ARRAY_LEN(x) ( sizeof(x) / sizeof((x)[0]) )
6b208b
+
6b208b
 #define __recinfo_str(_key, _info, _rec, _name, _show, _n, _mod) do { \
6b208b
 	_info[_n].type = TYPE_STR; \
6b208b
 	strlcpy(_info[_n].name, _key, NAME_MAXVAL); \
6b208b
@@ -163,6 +165,42 @@ static struct idbm *db;
6b208b
 	_n++; \
6b208b
 } while(0)
6b208b
 
6b208b
+#define __recinfo_int_list(_key,_info,_rec,_name,_show,_tbl,_n,_mod) do { \
6b208b
+	_info[_n].type = TYPE_INT_LIST; \
6b208b
+	strlcpy(_info[_n].name, _key, NAME_MAXVAL); \
6b208b
+	for(int _i = 0; _i < ARRAY_LEN(_rec->_name); _i++) { \
6b208b
+		if (_rec->_name[_i] != ~0) { \
6b208b
+			for (int _j = 0; _j < ARRAY_LEN(_tbl); _j++) { \
6b208b
+				if (_tbl[_j].value == _rec->_name[_i]) { \
6b208b
+					strcat(_info[_n].value, _tbl[_j].name); \
6b208b
+					strcat(_info[_n].value, ","); \
6b208b
+					break; \
6b208b
+				} \
6b208b
+			} \
6b208b
+		} \
6b208b
+	} \
6b208b
+	/* delete trailing ',' */ \
6b208b
+	if (strrchr(_info[_n].value, ',')) \
6b208b
+		*strrchr(_info[_n].value, ',') = '\0'; \
6b208b
+	_info[_n].data = &_rec->_name; \
6b208b
+	_info[_n].data_len = sizeof(_rec->_name); \
6b208b
+	_info[_n].visible = _show; \
6b208b
+	_info[_n].opts[0] = (void *)&_tbl; \
6b208b
+	_info[_n].numopts = ARRAY_LEN(_tbl); \
6b208b
+	_info[_n].can_modify = _mod; \
6b208b
+	_n++; \
6b208b
+} while (0)
6b208b
+
6b208b
+static struct int_list_tbl {
6b208b
+	const char *name;
6b208b
+	int value;
6b208b
+} chap_algs [] = {
6b208b
+	{ "MD5", AUTH_CHAP_ALG_MD5 },
6b208b
+	{ "SHA1", AUTH_CHAP_ALG_SHA1 },
6b208b
+	{ "SHA256", AUTH_CHAP_ALG_SHA256 },
6b208b
+	{ "SHA3-256", AUTH_CHAP_ALG_SHA3_256 },
6b208b
+};
6b208b
+
6b208b
 static int idbm_remove_disc_to_node_link(node_rec_t *rec, char *portal);
6b208b
 
6b208b
 static void
6b208b
@@ -197,6 +235,10 @@ idbm_recinfo_discovery(discovery_rec_t *r, recinfo_t *ri)
6b208b
 		__recinfo_int(DISC_ST_PASSWORD_IN_LEN, ri, r,
6b208b
 			u.sendtargets.auth.password_in_length, IDBM_HIDE,
6b208b
 			num, 1);
6b208b
+		/* reusing SESSION_CHAP_ALGS */
6b208b
+		__recinfo_int_list(SESSION_CHAP_ALGS, ri, r,
6b208b
+				   u.sendtargets.auth.chap_algs,
6b208b
+				   IDBM_SHOW, chap_algs, num, 1);
6b208b
 		__recinfo_int(DISC_ST_LOGIN_TMO, ri, r,
6b208b
 			u.sendtargets.conn_timeo.login_timeout,
6b208b
 			IDBM_SHOW, num, 1);
6b208b
@@ -427,6 +469,8 @@ idbm_recinfo_node(node_rec_t *r, recinfo_t *ri)
6b208b
 		      session.auth.password_in, IDBM_MASKED, num, 1);
6b208b
 	__recinfo_int(SESSION_PASSWORD_IN_LEN, ri, r,
6b208b
 		      session.auth.password_in_length, IDBM_HIDE, num, 1);
6b208b
+	__recinfo_int_list(SESSION_CHAP_ALGS, ri, r,
6b208b
+			   session.auth.chap_algs, IDBM_SHOW, chap_algs, num, 1);
6b208b
 	__recinfo_int(SESSION_REPLACEMENT_TMO, ri, r,
6b208b
 		      session.timeo.replacement_timeout,
6b208b
 		      IDBM_SHOW, num, 1);
6b208b
@@ -932,6 +976,9 @@ idbm_discovery_setup_defaults(discovery_rec_t *rec, discovery_type_e type)
6b208b
 		rec->u.sendtargets.auth.authmethod = 0;
6b208b
 		rec->u.sendtargets.auth.password_length = 0;
6b208b
 		rec->u.sendtargets.auth.password_in_length = 0;
6b208b
+		/* TYPE_INT_LIST fields should be initialized to ~0 to indicate unset values */
6b208b
+		memset(rec->u.sendtargets.auth.chap_algs, ~0, sizeof(rec->u.sendtargets.auth.chap_algs));
6b208b
+		rec->u.sendtargets.auth.chap_algs[0] = AUTH_CHAP_ALG_MD5;
6b208b
 		rec->u.sendtargets.conn_timeo.login_timeout=15;
6b208b
 		rec->u.sendtargets.conn_timeo.auth_timeout = 45;
6b208b
 		rec->u.sendtargets.conn_timeo.active_timeout=30;
6b208b
@@ -965,59 +1012,109 @@ int idbm_rec_update_param(recinfo_t *info, char *name, char *value,
6b208b
 	int i;
6b208b
 	int passwd_done = 0;
6b208b
 	char passwd_len[8];
6b208b
+	char *tmp_value, *token;
6b208b
+	bool *found;
6b208b
+	int *tmp_data;
6b208b
 
6b208b
 setup_passwd_len:
6b208b
 	for (i=0; i
6b208b
 		if (!strcmp(name, info[i].name)) {
6b208b
-			int j;
6b208b
+			int j,k;
6b208b
+			struct int_list_tbl *tbl;
6b208b
 
6b208b
 			log_debug(7, "updated '%s', '%s' => '%s'", name,
6b208b
 				  info[i].value, value);
6b208b
 			/* parse recinfo by type */
6b208b
-			if (info[i].type == TYPE_INT) {
6b208b
+			switch (info[i].type) {
6b208b
+			case TYPE_INT:
6b208b
 				if (!info[i].data)
6b208b
 					continue;
6b208b
 
6b208b
 				*(int*)info[i].data =
6b208b
 					strtoul(value, NULL, 10);
6b208b
 				goto updated;
6b208b
-			} else if (info[i].type == TYPE_UINT8) {
6b208b
+			case TYPE_UINT8:
6b208b
 				if (!info[i].data)
6b208b
 					continue;
6b208b
 
6b208b
 				*(uint8_t *)info[i].data =
6b208b
 					strtoul(value, NULL, 10);
6b208b
 				goto updated;
6b208b
-			} else if (info[i].type == TYPE_UINT16) {
6b208b
+			case TYPE_UINT16:
6b208b
 				if (!info[i].data)
6b208b
 					continue;
6b208b
 
6b208b
 				*(uint16_t *)info[i].data =
6b208b
 					strtoul(value, NULL, 10);
6b208b
 				goto updated;
6b208b
-			} else if (info[i].type == TYPE_UINT32) {
6b208b
+			case TYPE_UINT32:
6b208b
 				if (!info[i].data)
6b208b
 					continue;
6b208b
 
6b208b
 				*(uint32_t *)info[i].data =
6b208b
 					strtoul(value, NULL, 10);
6b208b
 				goto updated;
6b208b
-			} else if (info[i].type == TYPE_STR) {
6b208b
+			case TYPE_STR:
6b208b
 				if (!info[i].data)
6b208b
 					continue;
6b208b
 
6b208b
 				strlcpy((char*)info[i].data,
6b208b
 					value, info[i].data_len);
6b208b
 				goto updated;
6b208b
-			}
6b208b
-			for (j=0; j
6b208b
-				if (!strcmp(value, info[i].opts[j])) {
6b208b
-					if (!info[i].data)
6b208b
+			case TYPE_INT_O:
6b208b
+				for (j=0; j
6b208b
+					if (!strcmp(value, info[i].opts[j])) {
6b208b
+						if (!info[i].data)
6b208b
+							continue;
6b208b
+
6b208b
+						*(int*)info[i].data = j;
6b208b
+						goto updated;
6b208b
+					}
6b208b
+				}
6b208b
+			case TYPE_INT_LIST:
6b208b
+				if (!info[i].data)
6b208b
+					continue;
6b208b
+				tbl = (void *)info[i].opts[0];
6b208b
+				/* strsep is destructive, make a copy to work with */
6b208b
+				tmp_value = strdup(value);
6b208b
+				k = 0;
6b208b
+				tmp_data = malloc(info[i].data_len);
6b208b
+				memset(tmp_data, ~0, info[i].data_len);
6b208b
+				found = calloc(info[i].numopts, sizeof(bool));
6b208b
+
6b208b
+next_token:			while ((token = strsep(&tmp_value, ", \n"))) {
6b208b
+					if (!strlen(token))
6b208b
 						continue;
6b208b
-
6b208b
-					*(int*)info[i].data = j;
6b208b
-					goto updated;
6b208b
+					if ((k * (int)sizeof(int)) >= (info[i].data_len)) {
6b208b
+						log_warning("Too many values set for '%s'"
6b208b
+						            ", continuing without processing them all",
6b208b
+						            info[i].name);
6b208b
+						break;
6b208b
+					}
6b208b
+					for (j = 0; j < info[i].numopts; j++) {
6b208b
+						if (!strcmp(token, tbl[j].name)) {
6b208b
+							if ((found[j])) {
6b208b
+								log_warning("Ignoring repeated "
6b208b
+								            "value '%s' "
6b208b
+								            "for '%s'", token,
6b208b
+								            info[i].name);
6b208b
+								goto next_token;
6b208b
+							}
6b208b
+							((int*)tmp_data)[k++] = tbl[j].value;
6b208b
+							found[j] = true;
6b208b
+							goto next_token;
6b208b
+						}
6b208b
+					}
6b208b
+					log_warning("Ignoring unknown value '%s'"
6b208b
+					            " for '%s'", token, info[i].name);
6b208b
 				}
6b208b
+				memcpy(info[i].data, tmp_data, info[i].data_len);
6b208b
+				free(tmp_value);
6b208b
+				free(tmp_data);
6b208b
+				tmp_value = NULL;
6b208b
+				tmp_data = NULL;
6b208b
+				token = NULL;
6b208b
+				goto updated;
6b208b
 			}
6b208b
 			if (line_number) {
6b208b
 				log_warning("config file line %d contains "
6b208b
@@ -3098,6 +3195,9 @@ void idbm_node_setup_defaults(node_rec_t *rec)
6b208b
 	rec->session.initial_login_retry_max = DEF_INITIAL_LOGIN_RETRIES_MAX;
6b208b
 	rec->session.reopen_max = 32;
6b208b
 	rec->session.auth.authmethod = 0;
6b208b
+	/* TYPE_INT_LIST fields should be initialized to ~0 to indicate unset values */
6b208b
+	memset(rec->session.auth.chap_algs, ~0, sizeof(rec->session.auth.chap_algs));
6b208b
+	rec->session.auth.chap_algs[0] = AUTH_CHAP_ALG_MD5;
6b208b
 	rec->session.auth.password_length = 0;
6b208b
 	rec->session.auth.password_in_length = 0;
6b208b
 	rec->session.err_timeo.abort_timeout = DEF_ABORT_TIMEO;
6b208b
diff --git a/usr/idbm.h b/usr/idbm.h
6b208b
index cb5dd8f..65ea876 100644
6b208b
--- a/usr/idbm.h
6b208b
+++ b/usr/idbm.h
6b208b
@@ -46,6 +46,8 @@
6b208b
 #define TYPE_UINT8	3
6b208b
 #define TYPE_UINT16	4
6b208b
 #define TYPE_UINT32	5
6b208b
+#define TYPE_INT_LIST	6
6b208b
+
6b208b
 #define MAX_KEYS	256   /* number of keys total(including CNX_MAX) */
6b208b
 #define NAME_MAXVAL	128   /* the maximum length of key name */
6b208b
 #define VALUE_MAXVAL	256   /* the maximum length of 223 bytes in the RFC. */
6b208b
diff --git a/usr/idbm_fields.h b/usr/idbm_fields.h
6b208b
index 4a92758..8749ef7 100644
6b208b
--- a/usr/idbm_fields.h
6b208b
+++ b/usr/idbm_fields.h
6b208b
@@ -30,6 +30,7 @@
6b208b
 #define SESSION_USERNAME_IN	"node.session.auth.username_in"
6b208b
 #define SESSION_PASSWORD_IN	"node.session.auth.password_in"
6b208b
 #define SESSION_PASSWORD_IN_LEN	"node.session.auth.password_in_length"
6b208b
+#define SESSION_CHAP_ALGS	"node.session.auth.chap_algs"
6b208b
 #define SESSION_REPLACEMENT_TMO	"node.session.timeo.replacement_timeout"
6b208b
 #define SESSION_ABORT_TMO	"node.session.err_timeo.abort_timeout"
6b208b
 #define SESSION_LU_RESET_TMO	"node.session.err_timeo.lu_reset_timeout"
6b208b
diff --git a/usr/initiator.h b/usr/initiator.h
6b208b
index 3ee1454..01caf3f 100644
6b208b
--- a/usr/initiator.h
6b208b
+++ b/usr/initiator.h
6b208b
@@ -243,6 +243,7 @@ typedef struct iscsi_session {
6b208b
 	char username_in[AUTH_STR_MAX_LEN];
6b208b
 	uint8_t password_in[AUTH_STR_MAX_LEN];
6b208b
 	int password_in_length;
6b208b
+	unsigned int chap_algs[AUTH_CHAP_ALG_MAX_COUNT];
6b208b
 	iscsi_conn_t conn[ISCSI_CONN_MAX];
6b208b
 	uint64_t param_mask;
6b208b
 
6b208b
diff --git a/usr/initiator_common.c b/usr/initiator_common.c
6b208b
index d00bd9e..7cb45bc 100644
6b208b
--- a/usr/initiator_common.c
6b208b
+++ b/usr/initiator_common.c
6b208b
@@ -94,6 +94,8 @@ int iscsi_setup_authentication(struct iscsi_session *session,
6b208b
 		memcpy(session->password_in, auth_cfg->password_in,
6b208b
 		       session->password_in_length);
6b208b
 
6b208b
+	memcpy(session->chap_algs, auth_cfg->chap_algs, sizeof(auth_cfg->chap_algs));
6b208b
+
6b208b
 	if (session->password_length || session->password_in_length) {
6b208b
 		/* setup the auth buffers */
6b208b
 		session->auth_buffers[0].address = &session->auth_client_block;
6b208b
diff --git a/usr/login.c b/usr/login.c
6b208b
index d7dad21..1251e61 100644
6b208b
--- a/usr/login.c
6b208b
+++ b/usr/login.c
6b208b
@@ -1262,6 +1262,17 @@ check_for_authentication(iscsi_session_t *session,
6b208b
 		goto end;
6b208b
 	}
6b208b
 
6b208b
+	int value_list[AUTH_CHAP_ALG_MAX_COUNT];
6b208b
+
6b208b
+	if (acl_set_chap_alg_list(auth_client,
6b208b
+				acl_init_chap_digests(value_list,
6b208b
+					session->chap_algs,
6b208b
+					AUTH_CHAP_ALG_MAX_COUNT),
6b208b
+				value_list) != AUTH_STATUS_NO_ERROR) {
6b208b
+		log_error("Couldn't set CHAP algorithm list");
6b208b
+		goto end;
6b208b
+	}
6b208b
+
6b208b
 	if (acl_set_ip_sec(auth_client, 1) != AUTH_STATUS_NO_ERROR) {
6b208b
 		log_error("Couldn't set IPSec");
6b208b
 		goto end;
6b208b
-- 
6b208b
2.21.3
6b208b