xref: /wlan-dirver/utils/sigma-dut/server.c (revision bbe959f9fa72d63d9c53f133b6ec7f195faffda9)
1cd4e3c3eSJouni Malinen /*
2cd4e3c3eSJouni Malinen  * Sigma Control API DUT (server)
3cd4e3c3eSJouni Malinen  * Copyright (c) 2014, Qualcomm Atheros, Inc.
472ac93ccSJouni Malinen  * Copyright (c) 2018, The Linux Foundation
5cd4e3c3eSJouni Malinen  * All Rights Reserved.
6cd4e3c3eSJouni Malinen  * Licensed under the Clear BSD license. See README for more details.
7cd4e3c3eSJouni Malinen  */
8cd4e3c3eSJouni Malinen 
9cd4e3c3eSJouni Malinen #include "sigma_dut.h"
103b17d530SJouni Malinen #include <sqlite3.h>
113b17d530SJouni Malinen 
123b17d530SJouni Malinen #ifndef SERVER_DB
133b17d530SJouni Malinen #define SERVER_DB "/home/user/hs20-server/AS/DB/eap_user.db"
143b17d530SJouni Malinen #endif /* SERVER_DB */
15cd4e3c3eSJouni Malinen 
1693b170b6SJouni Malinen #ifndef CERT_DIR
1793b170b6SJouni Malinen #define CERT_DIR "/home/user/hs20-server/certs"
1893b170b6SJouni Malinen #endif /* CERT_DIR */
1993b170b6SJouni Malinen 
20cd4e3c3eSJouni Malinen 
2172ac93ccSJouni Malinen static int cmd_server_ca_get_version(struct sigma_dut *dut,
2272ac93ccSJouni Malinen 				     struct sigma_conn *conn,
2372ac93ccSJouni Malinen 				     struct sigma_cmd *cmd)
2472ac93ccSJouni Malinen {
2572ac93ccSJouni Malinen 	send_resp(dut, conn, SIGMA_COMPLETE, "version,1.0");
2672ac93ccSJouni Malinen 	return 0;
2772ac93ccSJouni Malinen }
2872ac93ccSJouni Malinen 
2972ac93ccSJouni Malinen 
3072ac93ccSJouni Malinen static int cmd_server_get_info(struct sigma_dut *dut,
3172ac93ccSJouni Malinen 			       struct sigma_conn *conn,
3272ac93ccSJouni Malinen 			       struct sigma_cmd *cmd)
3372ac93ccSJouni Malinen {
3472ac93ccSJouni Malinen 	send_resp(dut, conn, SIGMA_COMPLETE, "vendor,OSU,model,OS,version,1.0");
3572ac93ccSJouni Malinen 	return 0;
3672ac93ccSJouni Malinen }
3772ac93ccSJouni Malinen 
3872ac93ccSJouni Malinen 
393b17d530SJouni Malinen static int server_reset_user(struct sigma_dut *dut, const char *user)
403b17d530SJouni Malinen {
413b17d530SJouni Malinen 	sqlite3 *db;
423b17d530SJouni Malinen 	int res = -1;
433b17d530SJouni Malinen 	char *sql = NULL;
443b17d530SJouni Malinen 	const char *realm = "wi-fi.org";
453b17d530SJouni Malinen 	const char *methods = "TTLS-MSCHAPV2";
463b17d530SJouni Malinen 	const char *password = "ChangeMe";
473b17d530SJouni Malinen 	int phase2 = 1;
483b17d530SJouni Malinen 	int machine_managed = 1;
49657bde6aSJouni Malinen 	const char *remediation = "";
503b17d530SJouni Malinen 	int fetch_pps = 0;
513b17d530SJouni Malinen 	const char *osu_user = NULL;
523b17d530SJouni Malinen 	const char *osu_password = NULL;
537aab205bSJouni Malinen 	const char *policy = NULL;
543b17d530SJouni Malinen 
553b17d530SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "Reset user %s", user);
563b17d530SJouni Malinen 
573b17d530SJouni Malinen 	if (sqlite3_open(SERVER_DB, &db)) {
583b17d530SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
593b17d530SJouni Malinen 				"Failed to open SQLite database %s",
603b17d530SJouni Malinen 				SERVER_DB);
613b17d530SJouni Malinen 		return -1;
623b17d530SJouni Malinen 	}
633b17d530SJouni Malinen 
643b17d530SJouni Malinen 	if (strcmp(user, "test01") == 0) {
65657bde6aSJouni Malinen 		remediation = "machine";
663b17d530SJouni Malinen 	} else if (strcmp(user, "test02") == 0) {
67657bde6aSJouni Malinen 		remediation = "user";
683b17d530SJouni Malinen 		machine_managed = 0;
693b17d530SJouni Malinen 	} else if (strcmp(user, "test03") == 0) {
70657bde6aSJouni Malinen 		/* UpdateInterval-based client trigger for policy update */
717aab205bSJouni Malinen 		policy = "ruckus130";
723b17d530SJouni Malinen 	} else if (strcmp(user, "test04") == 0) {
733b17d530SJouni Malinen 	} else if (strcmp(user, "test05") == 0) {
743b17d530SJouni Malinen 	} else if (strcmp(user, "test06") == 0) {
753b17d530SJouni Malinen 		realm = "example.com";
763b17d530SJouni Malinen 	} else if (strcmp(user, "test07") == 0) {
773b17d530SJouni Malinen 	} else if (strcmp(user, "test08") == 0) {
78657bde6aSJouni Malinen 		remediation = "machine";
793b17d530SJouni Malinen 		osu_user = "testdmacc08";
803b17d530SJouni Malinen 		osu_password = "P@ssw0rd";
813b17d530SJouni Malinen 	} else if (strcmp(user, "test09") == 0) {
82657bde6aSJouni Malinen 		/* UpdateInterval-based client trigger for policy update */
837aab205bSJouni Malinen 		policy = "ruckus130";
84364c0818SJouni Malinen 		osu_user = "testdmacc09";
85364c0818SJouni Malinen 		osu_password = "P@ssw0rd";
863b17d530SJouni Malinen 	} else if (strcmp(user, "test10") == 0) {
87657bde6aSJouni Malinen 		remediation = "machine";
883b17d530SJouni Malinen 		methods = "TLS";
893b17d530SJouni Malinen 	} else if (strcmp(user, "test11") == 0) {
903b17d530SJouni Malinen 	} else if (strcmp(user, "test12") == 0) {
91657bde6aSJouni Malinen 		remediation = "user";
923b17d530SJouni Malinen 		methods = "TLS";
933b17d530SJouni Malinen 	} else if (strcmp(user, "test20") == 0) {
943b17d530SJouni Malinen 	} else if (strcmp(user, "test26") == 0) {
953b17d530SJouni Malinen 		/* TODO: Cred01 with username/password? */
963b17d530SJouni Malinen 		user = "1310026000000001";
973b17d530SJouni Malinen 		methods = "SIM";
983b17d530SJouni Malinen 	} else if (strcmp(user, "test30") == 0) {
993b17d530SJouni Malinen 		osu_user = "testdmacc30";
1003b17d530SJouni Malinen 		osu_password = "P@ssw0rd";
1013b17d530SJouni Malinen 	} else if (strcmp(user, "test31") == 0) {
1023b17d530SJouni Malinen 		osu_user = "testdmacc31";
1033b17d530SJouni Malinen 		osu_password = "P@ssw0rd";
1043b17d530SJouni Malinen 	} else if (strcmp(user, "test32") == 0) {
1053b17d530SJouni Malinen 		osu_user = "testdmacc32";
1063b17d530SJouni Malinen 		osu_password = "P@ssw0rd";
1073b17d530SJouni Malinen 	} else if (strcmp(user, "test33") == 0) {
1083b17d530SJouni Malinen 		osu_user = "testdmacc33";
1093b17d530SJouni Malinen 		osu_password = "P@ssw0rd";
1103b17d530SJouni Malinen 	} else if (strcmp(user, "test34") == 0) {
1113b17d530SJouni Malinen 		osu_user = "testdmacc34";
1123b17d530SJouni Malinen 		osu_password = "P@ssw0rd";
1133b17d530SJouni Malinen 	} else if (strcmp(user, "test35") == 0) {
1143b17d530SJouni Malinen 		osu_user = "testdmacc35";
1153b17d530SJouni Malinen 		osu_password = "P@ssw0rd";
1163b17d530SJouni Malinen 	} else if (strcmp(user, "test36") == 0) {
1173b17d530SJouni Malinen 	} else if (strcmp(user, "test37") == 0) {
1183b17d530SJouni Malinen 		osu_user = "testdmacc37";
1193b17d530SJouni Malinen 		osu_password = "P@ssw0rd";
120364c0818SJouni Malinen 	} else if (strcmp(user, "testdmacc08") == 0 ||
121364c0818SJouni Malinen 		   strcmp(user, "testdmacc09") == 0) {
122364c0818SJouni Malinen 		/* No need to set anything separate for testdmacc* users */
123364c0818SJouni Malinen 		sqlite3_close(db);
124364c0818SJouni Malinen 		return 0;
1253b17d530SJouni Malinen 	} else {
1263b17d530SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_INFO, "Unsupported username '%s'",
1273b17d530SJouni Malinen 				user);
1283b17d530SJouni Malinen 		goto fail;
1293b17d530SJouni Malinen 	}
1303b17d530SJouni Malinen 
1317aab205bSJouni Malinen 	sql = sqlite3_mprintf("INSERT OR REPLACE INTO users(identity,realm,methods,password,phase2,machine_managed,remediation,fetch_pps,osu_user,osu_password,policy) VALUES (%Q,%Q,%Q,%Q,%d,%d,%Q,%d,%Q,%Q,%Q)",
1323b17d530SJouni Malinen 			      user, realm, methods, password,
1333b17d530SJouni Malinen 			      phase2, machine_managed, remediation, fetch_pps,
1347aab205bSJouni Malinen 			      osu_user, osu_password, policy);
1353b17d530SJouni Malinen 
1363b17d530SJouni Malinen 	if (!sql)
1373b17d530SJouni Malinen 		goto fail;
1383b17d530SJouni Malinen 
1393b17d530SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
1403b17d530SJouni Malinen 
1413b17d530SJouni Malinen 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
1423b17d530SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR, "SQL operation failed: %s",
1433b17d530SJouni Malinen 				sqlite3_errmsg(db));
1443b17d530SJouni Malinen 	} else {
1453b17d530SJouni Malinen 		res = 0;
1463b17d530SJouni Malinen 	}
1473b17d530SJouni Malinen 
1483b17d530SJouni Malinen 	sqlite3_free(sql);
1493b17d530SJouni Malinen 
1503b17d530SJouni Malinen fail:
1513b17d530SJouni Malinen 	sqlite3_close(db);
1523b17d530SJouni Malinen 
1533b17d530SJouni Malinen 	return res;
1543b17d530SJouni Malinen }
1553b17d530SJouni Malinen 
1563b17d530SJouni Malinen 
157*bbe959f9SJouni Malinen static int server_reset_serial(struct sigma_dut *dut, const char *serial)
158*bbe959f9SJouni Malinen {
159*bbe959f9SJouni Malinen 	sqlite3 *db;
160*bbe959f9SJouni Malinen 	int res = -1;
161*bbe959f9SJouni Malinen 	char *sql = NULL;
162*bbe959f9SJouni Malinen 	const char *realm = "wi-fi.org";
163*bbe959f9SJouni Malinen 	const char *methods = "TLS";
164*bbe959f9SJouni Malinen 	int phase2 = 0;
165*bbe959f9SJouni Malinen 	int machine_managed = 1;
166*bbe959f9SJouni Malinen 	const char *remediation = "";
167*bbe959f9SJouni Malinen 	int fetch_pps = 0;
168*bbe959f9SJouni Malinen 	const char *osu_user = NULL;
169*bbe959f9SJouni Malinen 	const char *osu_password = NULL;
170*bbe959f9SJouni Malinen 	const char *policy = NULL;
171*bbe959f9SJouni Malinen 	char user[128];
172*bbe959f9SJouni Malinen 
173*bbe959f9SJouni Malinen 	snprintf(user, sizeof(user), "cert-%s", serial);
174*bbe959f9SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "Reset user %s (serial number: %s)",
175*bbe959f9SJouni Malinen 			user, serial);
176*bbe959f9SJouni Malinen 
177*bbe959f9SJouni Malinen 	if (sqlite3_open(SERVER_DB, &db)) {
178*bbe959f9SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
179*bbe959f9SJouni Malinen 				"Failed to open SQLite database %s",
180*bbe959f9SJouni Malinen 				SERVER_DB);
181*bbe959f9SJouni Malinen 		return -1;
182*bbe959f9SJouni Malinen 	}
183*bbe959f9SJouni Malinen 
184*bbe959f9SJouni Malinen 	if (strcmp(serial, "1046") == 0) {
185*bbe959f9SJouni Malinen 		remediation = "machine";
186*bbe959f9SJouni Malinen 	} else if (strcmp(serial, "1047") == 0) {
187*bbe959f9SJouni Malinen 		remediation = "user";
188*bbe959f9SJouni Malinen 	} else {
189*bbe959f9SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_INFO,
190*bbe959f9SJouni Malinen 				"Unsupported serial number '%s'", serial);
191*bbe959f9SJouni Malinen 		goto fail;
192*bbe959f9SJouni Malinen 	}
193*bbe959f9SJouni Malinen 
194*bbe959f9SJouni Malinen 	sql = sqlite3_mprintf("INSERT OR REPLACE INTO users(identity,realm,methods,phase2,machine_managed,remediation,fetch_pps,osu_user,osu_password,policy) VALUES (%Q,%Q,%Q,%d,%d,%Q,%d,%Q,%Q,%Q)",
195*bbe959f9SJouni Malinen 			      user, realm, methods,
196*bbe959f9SJouni Malinen 			      phase2, machine_managed, remediation, fetch_pps,
197*bbe959f9SJouni Malinen 			      osu_user, osu_password, policy);
198*bbe959f9SJouni Malinen 
199*bbe959f9SJouni Malinen 	if (!sql)
200*bbe959f9SJouni Malinen 		goto fail;
201*bbe959f9SJouni Malinen 
202*bbe959f9SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
203*bbe959f9SJouni Malinen 
204*bbe959f9SJouni Malinen 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
205*bbe959f9SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR, "SQL operation failed: %s",
206*bbe959f9SJouni Malinen 				sqlite3_errmsg(db));
207*bbe959f9SJouni Malinen 	} else {
208*bbe959f9SJouni Malinen 		res = 0;
209*bbe959f9SJouni Malinen 	}
210*bbe959f9SJouni Malinen 
211*bbe959f9SJouni Malinen 	sqlite3_free(sql);
212*bbe959f9SJouni Malinen 
213*bbe959f9SJouni Malinen fail:
214*bbe959f9SJouni Malinen 	sqlite3_close(db);
215*bbe959f9SJouni Malinen 
216*bbe959f9SJouni Malinen 	return res;
217*bbe959f9SJouni Malinen }
218*bbe959f9SJouni Malinen 
219*bbe959f9SJouni Malinen 
22005630abeSJouni Malinen static int server_reset_cert_enroll(struct sigma_dut *dut, const char *addr)
22105630abeSJouni Malinen {
22205630abeSJouni Malinen 	sqlite3 *db;
22305630abeSJouni Malinen 	char *sql;
22405630abeSJouni Malinen 
22505630abeSJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG,
22605630abeSJouni Malinen 			"Reset certificate enrollment status for %s", addr);
22705630abeSJouni Malinen 
22805630abeSJouni Malinen 	if (sqlite3_open(SERVER_DB, &db)) {
22905630abeSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
23005630abeSJouni Malinen 				"Failed to open SQLite database %s",
23105630abeSJouni Malinen 				SERVER_DB);
23205630abeSJouni Malinen 		return -1;
23305630abeSJouni Malinen 	}
23405630abeSJouni Malinen 	sql = sqlite3_mprintf("DELETE FROM cert_enroll WHERE mac_addr=%Q",
23505630abeSJouni Malinen 			      addr);
23605630abeSJouni Malinen 	if (!sql) {
23705630abeSJouni Malinen 		sqlite3_close(db);
23805630abeSJouni Malinen 		return -1;
23905630abeSJouni Malinen 	}
24005630abeSJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
24105630abeSJouni Malinen 
24205630abeSJouni Malinen 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
24305630abeSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
24405630abeSJouni Malinen 				"SQL operation failed: %s",
24505630abeSJouni Malinen 				sqlite3_errmsg(db));
24605630abeSJouni Malinen 		sqlite3_free(sql);
24705630abeSJouni Malinen 		sqlite3_close(db);
24805630abeSJouni Malinen 		return -1;
24905630abeSJouni Malinen 	}
25005630abeSJouni Malinen 
25105630abeSJouni Malinen 	sqlite3_free(sql);
25205630abeSJouni Malinen 	sqlite3_close(db);
25305630abeSJouni Malinen 
25405630abeSJouni Malinen 	return 0;
25505630abeSJouni Malinen }
25605630abeSJouni Malinen 
25705630abeSJouni Malinen 
258cd4e3c3eSJouni Malinen static int cmd_server_reset_default(struct sigma_dut *dut,
259cd4e3c3eSJouni Malinen 				    struct sigma_conn *conn,
260cd4e3c3eSJouni Malinen 				    struct sigma_cmd *cmd)
261cd4e3c3eSJouni Malinen {
262cd4e3c3eSJouni Malinen 	const char *var;
26394d7b122SJouni Malinen 	enum sigma_program prog;
264cd4e3c3eSJouni Malinen 
265cd4e3c3eSJouni Malinen 	var = get_param(cmd, "Program");
26694d7b122SJouni Malinen 	if (!var) {
26794d7b122SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
26894d7b122SJouni Malinen 			  "errorCode,Missing program parameter");
26994d7b122SJouni Malinen 		return 0;
27094d7b122SJouni Malinen 	}
27194d7b122SJouni Malinen 
27294d7b122SJouni Malinen 	prog = sigma_program_to_enum(var);
27394d7b122SJouni Malinen 	if (prog != PROGRAM_HS2_R2 && prog != PROGRAM_HS2_R3) {
274cd4e3c3eSJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
275cd4e3c3eSJouni Malinen 			  "errorCode,Unsupported program");
276cd4e3c3eSJouni Malinen 		return 0;
277cd4e3c3eSJouni Malinen 	}
278cd4e3c3eSJouni Malinen 
279cd4e3c3eSJouni Malinen 	var = get_param(cmd, "UserName");
2803b17d530SJouni Malinen 	if (var && server_reset_user(dut, var) < 0) {
2813b17d530SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
2823b17d530SJouni Malinen 			  "errorCode,Failed to reset user account to defaults");
2833b17d530SJouni Malinen 		return 0;
284cd4e3c3eSJouni Malinen 	}
285cd4e3c3eSJouni Malinen 
286cd4e3c3eSJouni Malinen 	var = get_param(cmd, "SerialNo");
287*bbe959f9SJouni Malinen 	if (var && server_reset_serial(dut, var)) {
288*bbe959f9SJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
289*bbe959f9SJouni Malinen 			  "errorCode,Failed to reset user account to defaults");
290*bbe959f9SJouni Malinen 		return 0;
291cd4e3c3eSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG, "Reset serial number %s",
292cd4e3c3eSJouni Malinen 				var);
293cd4e3c3eSJouni Malinen 		/* TODO */
294cd4e3c3eSJouni Malinen 	}
295cd4e3c3eSJouni Malinen 
29605630abeSJouni Malinen 	var = get_param(cmd, "ClientMACAddr");
29705630abeSJouni Malinen 	if (var && server_reset_cert_enroll(dut, var) < 0) {
29805630abeSJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
29905630abeSJouni Malinen 			  "errorCode,Failed to reset cert enroll to defaults");
30005630abeSJouni Malinen 		return 0;
30105630abeSJouni Malinen 	}
30205630abeSJouni Malinen 
303cd4e3c3eSJouni Malinen 	return 1;
304cd4e3c3eSJouni Malinen }
305cd4e3c3eSJouni Malinen 
306cd4e3c3eSJouni Malinen 
3070f1614baSJouni Malinen static int get_last_msk_cb(void *ctx, int argc, char *argv[], char *col[])
3080f1614baSJouni Malinen {
3090f1614baSJouni Malinen 	char **last_msk = ctx;
3100f1614baSJouni Malinen 
3110f1614baSJouni Malinen 	if (argc < 1 || !argv[0])
3120f1614baSJouni Malinen 		return 0;
3130f1614baSJouni Malinen 
3140f1614baSJouni Malinen 	free(*last_msk);
3150f1614baSJouni Malinen 	*last_msk = strdup(argv[0]);
3160f1614baSJouni Malinen 
3170f1614baSJouni Malinen 	return 0;
3180f1614baSJouni Malinen }
3190f1614baSJouni Malinen 
3200f1614baSJouni Malinen 
3210f1614baSJouni Malinen static char * get_last_msk(struct sigma_dut *dut, sqlite3 *db,
3220f1614baSJouni Malinen 			   const char *username)
3230f1614baSJouni Malinen {
3240f1614baSJouni Malinen 	char *sql, *last_msk = NULL;
3250f1614baSJouni Malinen 
3260f1614baSJouni Malinen 	sql = sqlite3_mprintf("SELECT last_msk FROM users WHERE identity=%Q",
3270f1614baSJouni Malinen 			      username);
3280f1614baSJouni Malinen 	if (!sql)
3290f1614baSJouni Malinen 		return NULL;
3300f1614baSJouni Malinen 
3310f1614baSJouni Malinen 	if (sqlite3_exec(db, sql, get_last_msk_cb, &last_msk, NULL) !=
3320f1614baSJouni Malinen 	    SQLITE_OK) {
3330f1614baSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
3340f1614baSJouni Malinen 				"SQL operation to fetch last_msk failed: %s",
3350f1614baSJouni Malinen 				sqlite3_errmsg(db));
3360f1614baSJouni Malinen 		sqlite3_free(sql);
3370f1614baSJouni Malinen 		return NULL;
3380f1614baSJouni Malinen 	}
3390f1614baSJouni Malinen 
3400f1614baSJouni Malinen 	sqlite3_free(sql);
3410f1614baSJouni Malinen 
3420f1614baSJouni Malinen 	return last_msk;
3430f1614baSJouni Malinen }
3440f1614baSJouni Malinen 
3450f1614baSJouni Malinen 
3460f1614baSJouni Malinen static int aaa_auth_status(struct sigma_dut *dut, struct sigma_conn *conn,
3470f1614baSJouni Malinen 			   struct sigma_cmd *cmd, const char *username,
3480f1614baSJouni Malinen 			   int timeout)
3490f1614baSJouni Malinen {
3500f1614baSJouni Malinen 	sqlite3 *db;
3510f1614baSJouni Malinen 	char *sql = NULL;
3520f1614baSJouni Malinen 	int i;
3530f1614baSJouni Malinen 	char resp[500];
3540f1614baSJouni Malinen 
3550f1614baSJouni Malinen 	if (sqlite3_open(SERVER_DB, &db)) {
3560f1614baSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
3570f1614baSJouni Malinen 				"Failed to open SQLite database %s",
3580f1614baSJouni Malinen 				SERVER_DB);
3590f1614baSJouni Malinen 		return -1;
3600f1614baSJouni Malinen 	}
3610f1614baSJouni Malinen 
3620f1614baSJouni Malinen 	sql = sqlite3_mprintf("UPDATE users SET last_msk=NULL WHERE identity=%Q",
3630f1614baSJouni Malinen 			      username);
3640f1614baSJouni Malinen 	if (!sql) {
3650f1614baSJouni Malinen 		sqlite3_close(db);
3660f1614baSJouni Malinen 		return -1;
3670f1614baSJouni Malinen 	}
3680f1614baSJouni Malinen 
3690f1614baSJouni Malinen 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
3700f1614baSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
3710f1614baSJouni Malinen 				"SQL operation to clear last_msk failed: %s",
3720f1614baSJouni Malinen 				sqlite3_errmsg(db));
3730f1614baSJouni Malinen 		sqlite3_free(sql);
3740f1614baSJouni Malinen 		sqlite3_close(db);
3750f1614baSJouni Malinen 		return -1;
3760f1614baSJouni Malinen 	}
3770f1614baSJouni Malinen 
3780f1614baSJouni Malinen 	sqlite3_free(sql);
3790f1614baSJouni Malinen 
38089dfb22eSJouni Malinen 	if (sqlite3_changes(db) < 1) {
38189dfb22eSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
38289dfb22eSJouni Malinen 				"No DB rows modified (specified user not found)");
38389dfb22eSJouni Malinen 		sqlite3_close(db);
38489dfb22eSJouni Malinen 		return -1;
38589dfb22eSJouni Malinen 	}
38689dfb22eSJouni Malinen 
3870f1614baSJouni Malinen 	snprintf(resp, sizeof(resp), "AuthStatus,TIMEOUT,MSK,NULL");
3880f1614baSJouni Malinen 
3890f1614baSJouni Malinen 	for (i = 0; i < timeout; i++) {
3900f1614baSJouni Malinen 		char *last_msk;
3910f1614baSJouni Malinen 
3920f1614baSJouni Malinen 		last_msk = get_last_msk(dut, db, username);
3930f1614baSJouni Malinen 		if (last_msk) {
3940f1614baSJouni Malinen 			if (strcmp(last_msk, "FAIL") == 0) {
3950f1614baSJouni Malinen 				snprintf(resp, sizeof(resp),
3960f1614baSJouni Malinen 					 "AuthStatus,FAIL,MSK,NULL");
3970f1614baSJouni Malinen 			} else {
3980f1614baSJouni Malinen 				snprintf(resp, sizeof(resp),
3990f1614baSJouni Malinen 					 "AuthStatus,SUCCESS,MSK,%s", last_msk);
4000f1614baSJouni Malinen 			}
4010f1614baSJouni Malinen 			free(last_msk);
4020f1614baSJouni Malinen 			break;
4030f1614baSJouni Malinen 		}
4040f1614baSJouni Malinen 		sleep(1);
4050f1614baSJouni Malinen 	}
4060f1614baSJouni Malinen 
4070f1614baSJouni Malinen 	sqlite3_close(db);
4080f1614baSJouni Malinen 
4090f1614baSJouni Malinen 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
4100f1614baSJouni Malinen 	return 0;
4110f1614baSJouni Malinen }
4120f1614baSJouni Malinen 
4130f1614baSJouni Malinen 
41405630abeSJouni Malinen static int get_last_serial_cb(void *ctx, int argc, char *argv[], char *col[])
41505630abeSJouni Malinen {
41605630abeSJouni Malinen 	char **last_serial = ctx;
41705630abeSJouni Malinen 
41805630abeSJouni Malinen 	if (argc < 1 || !argv[0])
41905630abeSJouni Malinen 		return 0;
42005630abeSJouni Malinen 
42105630abeSJouni Malinen 	free(*last_serial);
42205630abeSJouni Malinen 	*last_serial = strdup(argv[0]);
42305630abeSJouni Malinen 
42405630abeSJouni Malinen 	return 0;
42505630abeSJouni Malinen }
42605630abeSJouni Malinen 
42705630abeSJouni Malinen 
42805630abeSJouni Malinen static char * get_last_serial(struct sigma_dut *dut, sqlite3 *db,
42905630abeSJouni Malinen 			      const char *addr)
43005630abeSJouni Malinen {
43105630abeSJouni Malinen 	char *sql, *last_serial = NULL;
43205630abeSJouni Malinen 
43305630abeSJouni Malinen 	sql = sqlite3_mprintf("SELECT serialnum FROM cert_enroll WHERE mac_addr=%Q",
43405630abeSJouni Malinen 			      addr);
43505630abeSJouni Malinen 	if (!sql)
43605630abeSJouni Malinen 		return NULL;
43705630abeSJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
43805630abeSJouni Malinen 
43905630abeSJouni Malinen 	if (sqlite3_exec(db, sql, get_last_serial_cb, &last_serial, NULL) !=
44005630abeSJouni Malinen 	    SQLITE_OK) {
44105630abeSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
44205630abeSJouni Malinen 				"SQL operation to fetch last_serial failed: %s",
44305630abeSJouni Malinen 				sqlite3_errmsg(db));
44405630abeSJouni Malinen 		sqlite3_free(sql);
44505630abeSJouni Malinen 		return NULL;
44605630abeSJouni Malinen 	}
44705630abeSJouni Malinen 
44805630abeSJouni Malinen 	sqlite3_free(sql);
44905630abeSJouni Malinen 
45005630abeSJouni Malinen 	return last_serial;
45105630abeSJouni Malinen }
45205630abeSJouni Malinen 
45305630abeSJouni Malinen 
45405630abeSJouni Malinen static int osu_cert_enroll_status(struct sigma_dut *dut,
45505630abeSJouni Malinen 				  struct sigma_conn *conn,
45605630abeSJouni Malinen 				  struct sigma_cmd *cmd, const char *addr,
45705630abeSJouni Malinen 				  int timeout)
45805630abeSJouni Malinen {
45905630abeSJouni Malinen 	sqlite3 *db;
46005630abeSJouni Malinen 	int i;
46105630abeSJouni Malinen 	char resp[500];
46205630abeSJouni Malinen 
46305630abeSJouni Malinen 	if (sqlite3_open(SERVER_DB, &db)) {
46405630abeSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
46505630abeSJouni Malinen 				"Failed to open SQLite database %s",
46605630abeSJouni Malinen 				SERVER_DB);
46705630abeSJouni Malinen 		return -1;
46805630abeSJouni Malinen 	}
46905630abeSJouni Malinen 
47005630abeSJouni Malinen 	snprintf(resp, sizeof(resp), "OSUStatus,TIMEOUT");
47105630abeSJouni Malinen 
47205630abeSJouni Malinen 	for (i = 0; i < timeout; i++) {
47305630abeSJouni Malinen 		char *last_serial;
47405630abeSJouni Malinen 
47505630abeSJouni Malinen 		last_serial = get_last_serial(dut, db, addr);
47605630abeSJouni Malinen 		if (last_serial) {
47705630abeSJouni Malinen 			if (strcmp(last_serial, "FAIL") == 0) {
47805630abeSJouni Malinen 				snprintf(resp, sizeof(resp),
47905630abeSJouni Malinen 					 "OSUStatus,FAIL");
48005630abeSJouni Malinen 			} else if (strlen(last_serial) > 0) {
48105630abeSJouni Malinen 				snprintf(resp, sizeof(resp),
48205630abeSJouni Malinen 					 "OSUStatus,SUCCESS,SerialNo,%s",
48305630abeSJouni Malinen 					 last_serial);
48405630abeSJouni Malinen 			}
48505630abeSJouni Malinen 			free(last_serial);
48605630abeSJouni Malinen 			break;
48705630abeSJouni Malinen 		}
48805630abeSJouni Malinen 		sleep(1);
48905630abeSJouni Malinen 	}
49005630abeSJouni Malinen 
49105630abeSJouni Malinen 	sqlite3_close(db);
49205630abeSJouni Malinen 
49305630abeSJouni Malinen 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
49405630abeSJouni Malinen 	return 0;
49505630abeSJouni Malinen }
49605630abeSJouni Malinen 
49705630abeSJouni Malinen 
4984ea3acb2SJouni Malinen static int get_user_field_cb(void *ctx, int argc, char *argv[], char *col[])
4994ea3acb2SJouni Malinen {
5004ea3acb2SJouni Malinen 	char **val = ctx;
5014ea3acb2SJouni Malinen 
5024ea3acb2SJouni Malinen 	if (argc < 1 || !argv[0])
5034ea3acb2SJouni Malinen 		return 0;
5044ea3acb2SJouni Malinen 
5054ea3acb2SJouni Malinen 	free(*val);
5064ea3acb2SJouni Malinen 	*val = strdup(argv[0]);
5074ea3acb2SJouni Malinen 
5084ea3acb2SJouni Malinen 	return 0;
5094ea3acb2SJouni Malinen }
5104ea3acb2SJouni Malinen 
5114ea3acb2SJouni Malinen 
512de664c35SJouni Malinen static char * get_user_field_helper(struct sigma_dut *dut, sqlite3 *db,
513de664c35SJouni Malinen 				    const char *id_field,
5144ea3acb2SJouni Malinen 				    const char *identity, const char *field)
5154ea3acb2SJouni Malinen {
5164ea3acb2SJouni Malinen 	char *sql, *val = NULL;
5174ea3acb2SJouni Malinen 
518de664c35SJouni Malinen 	sql = sqlite3_mprintf("SELECT %s FROM users WHERE %s=%Q",
519de664c35SJouni Malinen 			      field, id_field, identity);
5204ea3acb2SJouni Malinen 	if (!sql)
5214ea3acb2SJouni Malinen 		return NULL;
5224ea3acb2SJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
5234ea3acb2SJouni Malinen 
5244ea3acb2SJouni Malinen 	if (sqlite3_exec(db, sql, get_user_field_cb, &val, NULL) != SQLITE_OK) {
5254ea3acb2SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
5264ea3acb2SJouni Malinen 				"SQL operation to fetch user field failed: %s",
5274ea3acb2SJouni Malinen 				sqlite3_errmsg(db));
5284ea3acb2SJouni Malinen 		sqlite3_free(sql);
5294ea3acb2SJouni Malinen 		return NULL;
5304ea3acb2SJouni Malinen 	}
5314ea3acb2SJouni Malinen 
5324ea3acb2SJouni Malinen 	sqlite3_free(sql);
5334ea3acb2SJouni Malinen 
5344ea3acb2SJouni Malinen 	return val;
5354ea3acb2SJouni Malinen }
5364ea3acb2SJouni Malinen 
5374ea3acb2SJouni Malinen 
538de664c35SJouni Malinen static char * get_user_field(struct sigma_dut *dut, sqlite3 *db,
539de664c35SJouni Malinen 			     const char *identity, const char *field)
540de664c35SJouni Malinen {
541de664c35SJouni Malinen 	return get_user_field_helper(dut, db, "identity", identity, field);
542de664c35SJouni Malinen }
543de664c35SJouni Malinen 
544de664c35SJouni Malinen 
545de664c35SJouni Malinen static char * get_user_dmacc_field(struct sigma_dut *dut, sqlite3 *db,
546de664c35SJouni Malinen 				   const char *identity, const char *field)
547de664c35SJouni Malinen {
548de664c35SJouni Malinen 	return get_user_field_helper(dut, db, "osu_user", identity, field);
549de664c35SJouni Malinen }
550de664c35SJouni Malinen 
551de664c35SJouni Malinen 
5524ea3acb2SJouni Malinen static int osu_remediation_status(struct sigma_dut *dut,
5534ea3acb2SJouni Malinen 				  struct sigma_conn *conn, int timeout,
5544ea3acb2SJouni Malinen 				  const char *username, const char *serialno)
5554ea3acb2SJouni Malinen {
5564ea3acb2SJouni Malinen 	sqlite3 *db;
5574ea3acb2SJouni Malinen 	int i;
5584ea3acb2SJouni Malinen 	char resp[500];
5594ea3acb2SJouni Malinen 	char name[100];
5604ea3acb2SJouni Malinen 	char *remediation = NULL;
561de664c35SJouni Malinen 	int dmacc = 0;
5624ea3acb2SJouni Malinen 
5634ea3acb2SJouni Malinen 	if (!username && !serialno)
5644ea3acb2SJouni Malinen 		return -1;
5654ea3acb2SJouni Malinen 	if (!username) {
5664ea3acb2SJouni Malinen 		snprintf(name, sizeof(name), "cert-%s", serialno);
5674ea3acb2SJouni Malinen 		username = name;
5684ea3acb2SJouni Malinen 	}
5694ea3acb2SJouni Malinen 
5704ea3acb2SJouni Malinen 	if (sqlite3_open(SERVER_DB, &db)) {
5714ea3acb2SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
5724ea3acb2SJouni Malinen 				"Failed to open SQLite database %s",
5734ea3acb2SJouni Malinen 				SERVER_DB);
5744ea3acb2SJouni Malinen 		return -1;
5754ea3acb2SJouni Malinen 	}
5764ea3acb2SJouni Malinen 
5774ea3acb2SJouni Malinen 	remediation = get_user_field(dut, db, username, "remediation");
5784ea3acb2SJouni Malinen 	if (!remediation) {
579de664c35SJouni Malinen 		remediation = get_user_dmacc_field(dut, db, username,
580de664c35SJouni Malinen 						   "remediation");
581de664c35SJouni Malinen 		dmacc = 1;
582de664c35SJouni Malinen 	}
583de664c35SJouni Malinen 	if (!remediation) {
5844ea3acb2SJouni Malinen 		snprintf(resp, sizeof(resp),
5854ea3acb2SJouni Malinen 			 "RemediationStatus,User entry not found");
5864ea3acb2SJouni Malinen 		goto done;
5874ea3acb2SJouni Malinen 	}
5884ea3acb2SJouni Malinen 	if (remediation[0] == '\0') {
5894ea3acb2SJouni Malinen 		snprintf(resp, sizeof(resp),
5904ea3acb2SJouni Malinen 			 "RemediationStatus,User was not configured to need remediation");
5914ea3acb2SJouni Malinen 		goto done;
5924ea3acb2SJouni Malinen 	}
5934ea3acb2SJouni Malinen 
5944ea3acb2SJouni Malinen 	snprintf(resp, sizeof(resp), "RemediationStatus,TIMEOUT");
5954ea3acb2SJouni Malinen 
5964ea3acb2SJouni Malinen 	for (i = 0; i < timeout; i++) {
5974ea3acb2SJouni Malinen 		sleep(1);
5984ea3acb2SJouni Malinen 		free(remediation);
599de664c35SJouni Malinen 		if (dmacc)
600de664c35SJouni Malinen 			remediation = get_user_dmacc_field(dut, db, username,
601de664c35SJouni Malinen 							   "remediation");
602de664c35SJouni Malinen 		else
603de664c35SJouni Malinen 			remediation = get_user_field(dut, db, username,
604de664c35SJouni Malinen 						     "remediation");
6054ea3acb2SJouni Malinen 		if (remediation && remediation[0] == '\0') {
6064ea3acb2SJouni Malinen 			snprintf(resp, sizeof(resp),
6074ea3acb2SJouni Malinen 				 "RemediationStatus,Remediation Complete");
6084ea3acb2SJouni Malinen 			break;
6094ea3acb2SJouni Malinen 		}
6104ea3acb2SJouni Malinen 	}
6114ea3acb2SJouni Malinen 
6124ea3acb2SJouni Malinen done:
6134ea3acb2SJouni Malinen 	free(remediation);
6144ea3acb2SJouni Malinen 	sqlite3_close(db);
6154ea3acb2SJouni Malinen 
6164ea3acb2SJouni Malinen 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
6174ea3acb2SJouni Malinen 	return 0;
6184ea3acb2SJouni Malinen }
6194ea3acb2SJouni Malinen 
6204ea3acb2SJouni Malinen 
621e926583bSJouni Malinen static int osu_polupd_status(struct sigma_dut *dut,
622e926583bSJouni Malinen 			     struct sigma_conn *conn, int timeout,
623e926583bSJouni Malinen 			     const char *username, const char *serialno)
624e926583bSJouni Malinen {
625e926583bSJouni Malinen 	sqlite3 *db;
626e926583bSJouni Malinen 	char *sql;
627e926583bSJouni Malinen 	int i;
628e926583bSJouni Malinen 	char resp[500];
629e926583bSJouni Malinen 	char name[100];
630e926583bSJouni Malinen 	char *policy = NULL;
631e926583bSJouni Malinen 	int dmacc = 0;
632e926583bSJouni Malinen 
633e926583bSJouni Malinen 	if (!username && !serialno)
634e926583bSJouni Malinen 		return -1;
635e926583bSJouni Malinen 	if (!username) {
636e926583bSJouni Malinen 		snprintf(name, sizeof(name), "cert-%s", serialno);
637e926583bSJouni Malinen 		username = name;
638e926583bSJouni Malinen 	}
639e926583bSJouni Malinen 
640e926583bSJouni Malinen 	if (sqlite3_open(SERVER_DB, &db)) {
641e926583bSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
642e926583bSJouni Malinen 				"Failed to open SQLite database %s",
643e926583bSJouni Malinen 				SERVER_DB);
644e926583bSJouni Malinen 		return -1;
645e926583bSJouni Malinen 	}
646e926583bSJouni Malinen 
647e926583bSJouni Malinen 	policy = get_user_field(dut, db, username, "policy");
648e926583bSJouni Malinen 	if (!policy) {
649e926583bSJouni Malinen 		policy = get_user_dmacc_field(dut, db, username, "policy");
650e926583bSJouni Malinen 		dmacc = 1;
651e926583bSJouni Malinen 	}
652e926583bSJouni Malinen 	if (!policy) {
653e926583bSJouni Malinen 		snprintf(resp, sizeof(resp),
654e926583bSJouni Malinen 			 "PolicyUpdateStatus,User entry not found");
655e926583bSJouni Malinen 		goto done;
656e926583bSJouni Malinen 	}
657e926583bSJouni Malinen 	if (policy[0] == '\0') {
658e926583bSJouni Malinen 		snprintf(resp, sizeof(resp),
659e926583bSJouni Malinen 			 "PolicyUpdateStatus,User was not configured to need policy update");
660e926583bSJouni Malinen 		goto done;
661e926583bSJouni Malinen 	}
662e926583bSJouni Malinen 
663e926583bSJouni Malinen 	sql = sqlite3_mprintf("UPDATE users SET polupd_done=0 WHERE %s=%Q",
664e926583bSJouni Malinen 			      (dmacc ? "osu_user" : "identity"),
665e926583bSJouni Malinen 			      username);
666e926583bSJouni Malinen 	if (!sql) {
667e926583bSJouni Malinen 		snprintf(resp, sizeof(resp),
668e926583bSJouni Malinen 			 "PolicyUpdateStatus,Internal error");
669e926583bSJouni Malinen 		goto done;
670e926583bSJouni Malinen 	}
671e926583bSJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
672e926583bSJouni Malinen 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
673e926583bSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
674e926583bSJouni Malinen 				"SQL operation to fetch user field failed: %s",
675e926583bSJouni Malinen 				sqlite3_errmsg(db));
676e926583bSJouni Malinen 		sqlite3_free(sql);
677e926583bSJouni Malinen 		goto done;
678e926583bSJouni Malinen 	}
679e926583bSJouni Malinen 	sqlite3_free(sql);
680e926583bSJouni Malinen 
681e926583bSJouni Malinen 	snprintf(resp, sizeof(resp), "PolicyUpdateStatus,TIMEOUT");
682e926583bSJouni Malinen 
683e926583bSJouni Malinen 	for (i = 0; i < timeout; i++) {
684e926583bSJouni Malinen 		sleep(1);
685e926583bSJouni Malinen 		free(policy);
686e926583bSJouni Malinen 		if (dmacc)
687e926583bSJouni Malinen 			policy = get_user_dmacc_field(dut, db, username,
688e926583bSJouni Malinen 						      "polupd_done");
689e926583bSJouni Malinen 		else
690e926583bSJouni Malinen 			policy = get_user_field(dut, db, username,
691e926583bSJouni Malinen 						"polupd_done");
692e926583bSJouni Malinen 		if (policy && atoi(policy)) {
693e926583bSJouni Malinen 			snprintf(resp, sizeof(resp),
694e926583bSJouni Malinen 				 "PolicyUpdateStatus,UpdateComplete");
695e926583bSJouni Malinen 			break;
696e926583bSJouni Malinen 		}
697e926583bSJouni Malinen 	}
698e926583bSJouni Malinen 
699e926583bSJouni Malinen done:
700e926583bSJouni Malinen 	free(policy);
701e926583bSJouni Malinen 	sqlite3_close(db);
702e926583bSJouni Malinen 
703e926583bSJouni Malinen 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
704e926583bSJouni Malinen 	return 0;
705e926583bSJouni Malinen }
706e926583bSJouni Malinen 
707e926583bSJouni Malinen 
708cd4e3c3eSJouni Malinen static int cmd_server_request_status(struct sigma_dut *dut,
709cd4e3c3eSJouni Malinen 				     struct sigma_conn *conn,
710cd4e3c3eSJouni Malinen 				     struct sigma_cmd *cmd)
711cd4e3c3eSJouni Malinen {
712cd4e3c3eSJouni Malinen 	const char *var, *username, *serialno, *imsi, *addr, *status;
713cd4e3c3eSJouni Malinen 	int osu, timeout;
714cd4e3c3eSJouni Malinen 	char resp[500];
7150f1614baSJouni Malinen 	enum sigma_program prog;
716cd4e3c3eSJouni Malinen 
717cd4e3c3eSJouni Malinen 	var = get_param(cmd, "Program");
7180f1614baSJouni Malinen 	if (!var) {
7190f1614baSJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
7200f1614baSJouni Malinen 			  "errorCode,Missing program parameter");
7210f1614baSJouni Malinen 		return 0;
7220f1614baSJouni Malinen 	}
7230f1614baSJouni Malinen 
7240f1614baSJouni Malinen 	prog = sigma_program_to_enum(var);
7250f1614baSJouni Malinen 	if (prog != PROGRAM_HS2_R2 && prog != PROGRAM_HS2_R3) {
726cd4e3c3eSJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
727cd4e3c3eSJouni Malinen 			  "errorCode,Unsupported program");
728cd4e3c3eSJouni Malinen 		return 0;
729cd4e3c3eSJouni Malinen 	}
730cd4e3c3eSJouni Malinen 
731cd4e3c3eSJouni Malinen 	var = get_param(cmd, "Device");
732cd4e3c3eSJouni Malinen 	if (!var ||
733cd4e3c3eSJouni Malinen 	    (strcasecmp(var, "AAAServer") != 0 &&
734cd4e3c3eSJouni Malinen 	     strcasecmp(var, "OSUServer") != 0)) {
735cd4e3c3eSJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
736cd4e3c3eSJouni Malinen 			  "errorCode,Unsupported device type");
737cd4e3c3eSJouni Malinen 		return 0;
738cd4e3c3eSJouni Malinen 	}
739cd4e3c3eSJouni Malinen 	osu = strcasecmp(var, "OSUServer") == 0;
740cd4e3c3eSJouni Malinen 
741cd4e3c3eSJouni Malinen 	var = get_param(cmd, "Timeout");
742cd4e3c3eSJouni Malinen 	if (!var) {
743cd4e3c3eSJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
744cd4e3c3eSJouni Malinen 			  "errorCode,Missing timeout");
745cd4e3c3eSJouni Malinen 		return 0;
746cd4e3c3eSJouni Malinen 	}
747cd4e3c3eSJouni Malinen 	timeout = atoi(var);
748cd4e3c3eSJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "timeout: %d", timeout);
749cd4e3c3eSJouni Malinen 
750cd4e3c3eSJouni Malinen 	username = get_param(cmd, "UserName");
751cd4e3c3eSJouni Malinen 	if (username)
752cd4e3c3eSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG, "UserName: %s", username);
753cd4e3c3eSJouni Malinen 	serialno = get_param(cmd, "SerialNo");
754cd4e3c3eSJouni Malinen 	if (serialno)
755cd4e3c3eSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG, "SerialNo: %s", serialno);
756cd4e3c3eSJouni Malinen 	imsi = get_param(cmd, "imsi_val");
757cd4e3c3eSJouni Malinen 	if (imsi)
758cd4e3c3eSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG, "imsi_val: %s", imsi);
759cd4e3c3eSJouni Malinen 	addr = get_param(cmd, "ClientMACAddr");
760cd4e3c3eSJouni Malinen 	if (addr)
761cd4e3c3eSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG, "ClientMACAddr: %s", addr);
762cd4e3c3eSJouni Malinen 	status = get_param(cmd, "Status");
763cd4e3c3eSJouni Malinen 	if (status)
764cd4e3c3eSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG, "Status: %s", status);
765cd4e3c3eSJouni Malinen 
7664ea3acb2SJouni Malinen 	if (osu && status && strcasecmp(status, "Remediation") == 0)
7674ea3acb2SJouni Malinen 		return osu_remediation_status(dut, conn, timeout, username,
7684ea3acb2SJouni Malinen 					      serialno);
769cd4e3c3eSJouni Malinen 
770e926583bSJouni Malinen 	if (osu && status && strcasecmp(status, "PolicyUpdate") == 0)
771e926583bSJouni Malinen 		return osu_polupd_status(dut, conn, timeout, username,
772e926583bSJouni Malinen 					 serialno);
773e926583bSJouni Malinen 
7740f1614baSJouni Malinen 	if (!osu && status && strcasecmp(status, "Authentication") == 0 &&
7750f1614baSJouni Malinen 	    username)
7760f1614baSJouni Malinen 		return aaa_auth_status(dut, conn, cmd, username, timeout);
7770f1614baSJouni Malinen 
77889dfb22eSJouni Malinen 	if (!osu && status && strcasecmp(status, "Authentication") == 0 &&
77989dfb22eSJouni Malinen 	    serialno) {
78089dfb22eSJouni Malinen 		snprintf(resp, sizeof(resp), "cert-%s", serialno);
78189dfb22eSJouni Malinen 		return aaa_auth_status(dut, conn, cmd, resp, timeout);
78289dfb22eSJouni Malinen 	}
78389dfb22eSJouni Malinen 
78405630abeSJouni Malinen 	if (osu && status && strcasecmp(status, "OSU") == 0 && addr)
78505630abeSJouni Malinen 		return osu_cert_enroll_status(dut, conn, cmd, addr, timeout);
78605630abeSJouni Malinen 
787cd4e3c3eSJouni Malinen 	return 1;
788cd4e3c3eSJouni Malinen }
789cd4e3c3eSJouni Malinen 
790cd4e3c3eSJouni Malinen 
791b8b7e7beSJouni Malinen static int osu_set_cert_reenroll(struct sigma_dut *dut, const char *serial,
792b8b7e7beSJouni Malinen 				 int enable)
793b8b7e7beSJouni Malinen {
794b8b7e7beSJouni Malinen 	sqlite3 *db;
795b8b7e7beSJouni Malinen 	char *sql;
796b8b7e7beSJouni Malinen 	char id[100];
797b8b7e7beSJouni Malinen 	int ret = -1;
798b8b7e7beSJouni Malinen 
799b8b7e7beSJouni Malinen 	if (sqlite3_open(SERVER_DB, &db)) {
800b8b7e7beSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR,
801b8b7e7beSJouni Malinen 				"Failed to open SQLite database %s",
802b8b7e7beSJouni Malinen 				SERVER_DB);
803b8b7e7beSJouni Malinen 		return -1;
804b8b7e7beSJouni Malinen 	}
805b8b7e7beSJouni Malinen 
806b8b7e7beSJouni Malinen 	snprintf(id, sizeof(id), "cert-%s", serial);
807b8b7e7beSJouni Malinen 	sql = sqlite3_mprintf("UPDATE users SET remediation=%Q WHERE lower(identity)=lower(%Q)",
808b8b7e7beSJouni Malinen 			      enable ? "machine" : "", id);
809b8b7e7beSJouni Malinen 	if (!sql)
810b8b7e7beSJouni Malinen 		goto fail;
811b8b7e7beSJouni Malinen 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
812b8b7e7beSJouni Malinen 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
813b8b7e7beSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR, "SQL operation failed: %s",
814b8b7e7beSJouni Malinen 				sqlite3_errmsg(db));
815b8b7e7beSJouni Malinen 		goto fail;
816b8b7e7beSJouni Malinen 	}
817b8b7e7beSJouni Malinen 
818b8b7e7beSJouni Malinen 	if (sqlite3_changes(db) < 1) {
819b8b7e7beSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_ERROR, "No DB rows modified (specified serial number not found)");
820b8b7e7beSJouni Malinen 		goto fail;
821b8b7e7beSJouni Malinen 	}
822b8b7e7beSJouni Malinen 
823b8b7e7beSJouni Malinen 	ret = 0;
824b8b7e7beSJouni Malinen fail:
825b8b7e7beSJouni Malinen 	sqlite3_close(db);
826b8b7e7beSJouni Malinen 
827b8b7e7beSJouni Malinen 	return ret;
828b8b7e7beSJouni Malinen }
829b8b7e7beSJouni Malinen 
830b8b7e7beSJouni Malinen 
831ab8c718fSJouni Malinen static int cmd_server_set_parameter(struct sigma_dut *dut,
832ab8c718fSJouni Malinen 				    struct sigma_conn *conn,
833ab8c718fSJouni Malinen 				    struct sigma_cmd *cmd)
834ab8c718fSJouni Malinen {
83593b170b6SJouni Malinen 	const char *var, *root_ca, *inter_ca, *osu_cert, *issuing_arch, *name;
836b8b7e7beSJouni Malinen 	const char *reenroll, *serial;
837ab8c718fSJouni Malinen 	int osu, timeout = -1;
838ab8c718fSJouni Malinen 	enum sigma_program prog;
839ab8c718fSJouni Malinen 
840ab8c718fSJouni Malinen 	var = get_param(cmd, "Program");
841ab8c718fSJouni Malinen 	if (!var) {
842ab8c718fSJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
843ab8c718fSJouni Malinen 			  "errorCode,Missing program parameter");
844ab8c718fSJouni Malinen 		return 0;
845ab8c718fSJouni Malinen 	}
846ab8c718fSJouni Malinen 
847ab8c718fSJouni Malinen 	prog = sigma_program_to_enum(var);
848ab8c718fSJouni Malinen 	if (prog != PROGRAM_HS2_R2 && prog != PROGRAM_HS2_R3) {
849ab8c718fSJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
850ab8c718fSJouni Malinen 			  "errorCode,Unsupported program");
851ab8c718fSJouni Malinen 		return 0;
852ab8c718fSJouni Malinen 	}
853ab8c718fSJouni Malinen 
854ab8c718fSJouni Malinen 	var = get_param(cmd, "Device");
855ab8c718fSJouni Malinen 	if (!var ||
856ab8c718fSJouni Malinen 	    (strcasecmp(var, "AAAServer") != 0 &&
857ab8c718fSJouni Malinen 	     strcasecmp(var, "OSUServer") != 0)) {
858ab8c718fSJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
859ab8c718fSJouni Malinen 			  "errorCode,Unsupported device type");
860ab8c718fSJouni Malinen 		return 0;
861ab8c718fSJouni Malinen 	}
862ab8c718fSJouni Malinen 	osu = strcasecmp(var, "OSUServer") == 0;
863ab8c718fSJouni Malinen 
864ab8c718fSJouni Malinen 	var = get_param(cmd, "Timeout");
865ab8c718fSJouni Malinen 	if (var)
866ab8c718fSJouni Malinen 		timeout = atoi(var);
867ab8c718fSJouni Malinen 
868ab8c718fSJouni Malinen 	var = get_param(cmd, "ProvisioningProto");
869ab8c718fSJouni Malinen 	if (var && strcasecmp(var, "SOAP") != 0) {
870ab8c718fSJouni Malinen 		send_resp(dut, conn, SIGMA_ERROR,
871ab8c718fSJouni Malinen 			  "errorCode,Unsupported ProvisioningProto");
872ab8c718fSJouni Malinen 		return 0;
873ab8c718fSJouni Malinen 	}
874ab8c718fSJouni Malinen 
875b8b7e7beSJouni Malinen 	reenroll = get_param(cmd, "CertReEnroll");
876b8b7e7beSJouni Malinen 	serial = get_param(cmd, "SerialNo");
877b8b7e7beSJouni Malinen 	if (reenroll && serial) {
878b8b7e7beSJouni Malinen 		int enable;
879b8b7e7beSJouni Malinen 
880b8b7e7beSJouni Malinen 		if (strcasecmp(reenroll, "Enable") == 0) {
881b8b7e7beSJouni Malinen 			enable = 1;
882b8b7e7beSJouni Malinen 		} else if (strcasecmp(reenroll, "Disable") == 0) {
883b8b7e7beSJouni Malinen 			enable = 0;
884b8b7e7beSJouni Malinen 		} else {
885b8b7e7beSJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
886b8b7e7beSJouni Malinen 				  "errorCode,Invalid CertReEnroll value");
887b8b7e7beSJouni Malinen 			return 0;
888b8b7e7beSJouni Malinen 		}
889b8b7e7beSJouni Malinen 
890b8b7e7beSJouni Malinen 		if (osu_set_cert_reenroll(dut, serial, enable) < 0) {
891b8b7e7beSJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
892b8b7e7beSJouni Malinen 				  "errorCode,Failed to update certificate reenrollment state");
893b8b7e7beSJouni Malinen 			return 0;
894b8b7e7beSJouni Malinen 		}
895b8b7e7beSJouni Malinen 	}
896b8b7e7beSJouni Malinen 
89793b170b6SJouni Malinen 	name = get_param(cmd, "Name");
89893b170b6SJouni Malinen 	root_ca = get_param(cmd, "TrustRootCACert");
89993b170b6SJouni Malinen 	inter_ca = get_param(cmd, "InterCACert");
90093b170b6SJouni Malinen 	osu_cert = get_param(cmd, "OSUServerCert");
90193b170b6SJouni Malinen 	issuing_arch = get_param(cmd, "Issuing_Arch");
90293b170b6SJouni Malinen 
903ab8c718fSJouni Malinen 	if (timeout > -1) {
904ab8c718fSJouni Malinen 		/* TODO */
905ab8c718fSJouni Malinen 	}
906ab8c718fSJouni Malinen 
90793b170b6SJouni Malinen 	if (osu && name && root_ca && inter_ca && osu_cert && issuing_arch) {
90893b170b6SJouni Malinen 		const char *srv;
90993b170b6SJouni Malinen 		char buf[500];
91093b170b6SJouni Malinen 		char buf2[500];
91193b170b6SJouni Malinen 		int col;
91293b170b6SJouni Malinen 
91393b170b6SJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG,
91493b170b6SJouni Malinen 				"Update server certificate setup");
91593b170b6SJouni Malinen 
91693b170b6SJouni Malinen 		if (strcasecmp(name, "ruckus") == 0) {
91793b170b6SJouni Malinen 			srv = "RKS";
91893b170b6SJouni Malinen 		} else if (strcasecmp(name, "aruba") == 0) {
91993b170b6SJouni Malinen 			srv = "ARU";
92093b170b6SJouni Malinen 		} else {
92193b170b6SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
92293b170b6SJouni Malinen 				  "errorCode,Unsupported Name value");
92393b170b6SJouni Malinen 			return 0;
92493b170b6SJouni Malinen 		}
92593b170b6SJouni Malinen 
92693b170b6SJouni Malinen 		if (strcasecmp(issuing_arch, "col2") == 0) {
92793b170b6SJouni Malinen 			col = 2;
92893b170b6SJouni Malinen 		} else if (strcasecmp(issuing_arch, "col4") == 0) {
92993b170b6SJouni Malinen 			col = 4;
93093b170b6SJouni Malinen 		} else {
93193b170b6SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
93293b170b6SJouni Malinen 				  "errorCode,Unsupported Issuing_Arch value");
93393b170b6SJouni Malinen 			return 0;
93493b170b6SJouni Malinen 		}
93593b170b6SJouni Malinen 
93693b170b6SJouni Malinen 		if (strcasecmp(root_ca, "ID-T") == 0) {
93793b170b6SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_DEBUG,
93893b170b6SJouni Malinen 					"OSU trust root: NetworkFX");
93993b170b6SJouni Malinen 			if (system("cp " CERT_DIR "/IDT-cert-RootCA.pem "
94093b170b6SJouni Malinen 				   CERT_DIR "/cacert.pem") < 0)
94193b170b6SJouni Malinen 				return -2;
94293b170b6SJouni Malinen 		} else if (strcasecmp(root_ca, "ID-Y") == 0) {
94393b170b6SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_DEBUG,
94493b170b6SJouni Malinen 					"OSU trust root: NetworkFX");
94593b170b6SJouni Malinen 			if (system("cp " CERT_DIR "/IDY-cert-RootCA.pem "
94693b170b6SJouni Malinen 				   CERT_DIR "/cacert.pem") < 0)
94793b170b6SJouni Malinen 				return -2;
94893b170b6SJouni Malinen 		} else {
94993b170b6SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
95093b170b6SJouni Malinen 				  "errorCode,Unsupported TrustRootCACert value");
95193b170b6SJouni Malinen 			return 0;
95293b170b6SJouni Malinen 		}
95393b170b6SJouni Malinen 
95493b170b6SJouni Malinen 		if (strcasecmp(inter_ca, "ID-Z.2") == 0) {
95593b170b6SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_DEBUG,
95693b170b6SJouni Malinen 					"OSU intermediate CA: NetworkFX (col2)");
95793b170b6SJouni Malinen 			if (system("cat " CERT_DIR "/IDZ2-cert-InterCA.pem >> "
95893b170b6SJouni Malinen 				   CERT_DIR "/cacert.pem") < 0)
95993b170b6SJouni Malinen 				return -2;
96093b170b6SJouni Malinen 		} else if (strcasecmp(inter_ca, "ID-Z.4") == 0) {
96193b170b6SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_DEBUG,
96293b170b6SJouni Malinen 					"OSU intermediate CA: DigiCert (col2)");
96393b170b6SJouni Malinen 			if (system("cat " CERT_DIR "/IDZ4-cert-InterCA.pem >> "
96493b170b6SJouni Malinen 				   CERT_DIR "/cacert.pem") < 0)
96593b170b6SJouni Malinen 				return -2;
96693b170b6SJouni Malinen 		} else if (strcasecmp(inter_ca, "ID-Z.6") == 0) {
96793b170b6SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_DEBUG,
96893b170b6SJouni Malinen 					"OSU intermediate CA: NetworkFX (col4)");
96993b170b6SJouni Malinen 			if (system("cat " CERT_DIR "/IDZ6-cert-InterCA.pem >> "
97093b170b6SJouni Malinen 				   CERT_DIR "/cacert.pem") < 0)
97193b170b6SJouni Malinen 				return -2;
97293b170b6SJouni Malinen 		} else if (strcasecmp(inter_ca, "ID-Z.8") == 0) {
97393b170b6SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_DEBUG,
97493b170b6SJouni Malinen 					"OSU intermediate CA: DigiCert (col4)");
97593b170b6SJouni Malinen 			if (system("cat " CERT_DIR "/IDZ8-cert-InterCA.pem >> "
97693b170b6SJouni Malinen 				   CERT_DIR "/cacert.pem") < 0)
97793b170b6SJouni Malinen 				return -2;
97893b170b6SJouni Malinen 		} else {
97993b170b6SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
98093b170b6SJouni Malinen 				  "errorCode,Unsupported InterCACert value");
98193b170b6SJouni Malinen 			return 0;
98293b170b6SJouni Malinen 		}
98393b170b6SJouni Malinen 
98493b170b6SJouni Malinen 		if (strcasecmp(osu_cert, "ID-Q") == 0) {
98593b170b6SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_DEBUG,
98693b170b6SJouni Malinen 					"OSU server cert: NetworkFX col%d",
98793b170b6SJouni Malinen 					col);
98893b170b6SJouni Malinen 			snprintf(buf, sizeof(buf),
98993b170b6SJouni Malinen 				 "cp " CERT_DIR "/IDQ-cert-c%d-%s.pem "
99093b170b6SJouni Malinen 				 CERT_DIR "/server.pem",
99193b170b6SJouni Malinen 				 col, srv);
99293b170b6SJouni Malinen 			snprintf(buf2, sizeof(buf2),
99393b170b6SJouni Malinen 				 "cp " CERT_DIR "/IDQ-key-%s.pem "
99493b170b6SJouni Malinen 				 CERT_DIR "/server.key", srv);
99593b170b6SJouni Malinen 		} else if (strcasecmp(osu_cert, "ID-W") == 0) {
99693b170b6SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_DEBUG,
99793b170b6SJouni Malinen 					"OSU server cert: DigiCert col%d",
99893b170b6SJouni Malinen 					col);
99993b170b6SJouni Malinen 			snprintf(buf, sizeof(buf),
100093b170b6SJouni Malinen 				 "cp " CERT_DIR "/IDW-cert-c%d-%s.pem "
100193b170b6SJouni Malinen 				 CERT_DIR "/server.pem",
100293b170b6SJouni Malinen 				 col, srv);
100393b170b6SJouni Malinen 			snprintf(buf2, sizeof(buf2),
100493b170b6SJouni Malinen 				 "cp " CERT_DIR "/IDW-key-%s.pem "
100593b170b6SJouni Malinen 				 CERT_DIR "/server.key", srv);
100693b170b6SJouni Malinen 		} else if (strcasecmp(osu_cert, "ID-R.2") == 0) {
100793b170b6SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_DEBUG,
100893b170b6SJouni Malinen 					"OSU server cert: NetworkFX revoked col%d",
100993b170b6SJouni Malinen 					col);
101093b170b6SJouni Malinen 			snprintf(buf, sizeof(buf),
101193b170b6SJouni Malinen 				 "cp " CERT_DIR "/IDR2-cert-c%d-%s.pem "
101293b170b6SJouni Malinen 				 CERT_DIR "/server.pem",
101393b170b6SJouni Malinen 				 col, srv);
101493b170b6SJouni Malinen 			snprintf(buf2, sizeof(buf2),
101593b170b6SJouni Malinen 				 "cp " CERT_DIR "/IDR2-key-%s.pem "
101693b170b6SJouni Malinen 				 CERT_DIR "/server.key", srv);
101793b170b6SJouni Malinen 		} else if (strcasecmp(osu_cert, "ID-R.4") == 0) {
101893b170b6SJouni Malinen 			sigma_dut_print(dut, DUT_MSG_DEBUG,
101993b170b6SJouni Malinen 					"OSU server cert: DigiCert revoked col%d",
102093b170b6SJouni Malinen 					col);
102193b170b6SJouni Malinen 			snprintf(buf, sizeof(buf),
102293b170b6SJouni Malinen 				 "cp " CERT_DIR "/IDR4-cert-c%d-%s.pem "
102393b170b6SJouni Malinen 				 CERT_DIR "/server.pem",
102493b170b6SJouni Malinen 				 col, srv);
102593b170b6SJouni Malinen 			snprintf(buf2, sizeof(buf2),
102693b170b6SJouni Malinen 				 "cp " CERT_DIR "/IDR4-key-%s.pem "
102793b170b6SJouni Malinen 				 CERT_DIR "/server.key", srv);
102893b170b6SJouni Malinen 		} else {
102993b170b6SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
103093b170b6SJouni Malinen 				  "errorCode,Unsupported OSUServerCert value");
103193b170b6SJouni Malinen 			return 0;
103293b170b6SJouni Malinen 		}
103393b170b6SJouni Malinen 
103493b170b6SJouni Malinen 		if (system(buf) < 0 || system(buf2) < 0)
103593b170b6SJouni Malinen 			return -2;
103693b170b6SJouni Malinen 
103793b170b6SJouni Malinen 		if (system("service apache2 reload") < 0) {
103893b170b6SJouni Malinen 			send_resp(dut, conn, SIGMA_ERROR,
103993b170b6SJouni Malinen 				  "errorCode,Failed to restart Apache");
104093b170b6SJouni Malinen 			return 0;
104193b170b6SJouni Malinen 		}
1042ab8c718fSJouni Malinen 	}
1043ab8c718fSJouni Malinen 
1044ab8c718fSJouni Malinen 	/* TODO */
1045ab8c718fSJouni Malinen 	return 1;
1046ab8c718fSJouni Malinen }
1047ab8c718fSJouni Malinen 
1048ab8c718fSJouni Malinen 
1049cd4e3c3eSJouni Malinen void server_register_cmds(void)
1050cd4e3c3eSJouni Malinen {
105172ac93ccSJouni Malinen 	sigma_dut_reg_cmd("server_ca_get_version", NULL,
105272ac93ccSJouni Malinen 			  cmd_server_ca_get_version);
105372ac93ccSJouni Malinen 	sigma_dut_reg_cmd("server_get_info", NULL,
105472ac93ccSJouni Malinen 			  cmd_server_get_info);
1055cd4e3c3eSJouni Malinen 	sigma_dut_reg_cmd("server_reset_default", NULL,
1056cd4e3c3eSJouni Malinen 			  cmd_server_reset_default);
1057cd4e3c3eSJouni Malinen 	sigma_dut_reg_cmd("server_request_status", NULL,
1058cd4e3c3eSJouni Malinen 			  cmd_server_request_status);
1059ab8c718fSJouni Malinen 	sigma_dut_reg_cmd("server_set_parameter", NULL,
1060ab8c718fSJouni Malinen 			  cmd_server_set_parameter);
1061cd4e3c3eSJouni Malinen }
1062