xref: /wlan-dirver/utils/sigma-dut/server.c (revision e926583bf1d4b67792b6ff714525076fb2810215)
1 /*
2  * Sigma Control API DUT (server)
3  * Copyright (c) 2014, Qualcomm Atheros, Inc.
4  * Copyright (c) 2018, The Linux Foundation
5  * All Rights Reserved.
6  * Licensed under the Clear BSD license. See README for more details.
7  */
8 
9 #include "sigma_dut.h"
10 #include <sqlite3.h>
11 
12 #ifndef SERVER_DB
13 #define SERVER_DB "/home/user/hs20-server/AS/DB/eap_user.db"
14 #endif /* SERVER_DB */
15 
16 #ifndef CERT_DIR
17 #define CERT_DIR "/home/user/hs20-server/certs"
18 #endif /* CERT_DIR */
19 
20 
21 static int cmd_server_ca_get_version(struct sigma_dut *dut,
22 				     struct sigma_conn *conn,
23 				     struct sigma_cmd *cmd)
24 {
25 	send_resp(dut, conn, SIGMA_COMPLETE, "version,1.0");
26 	return 0;
27 }
28 
29 
30 static int cmd_server_get_info(struct sigma_dut *dut,
31 			       struct sigma_conn *conn,
32 			       struct sigma_cmd *cmd)
33 {
34 	send_resp(dut, conn, SIGMA_COMPLETE, "vendor,OSU,model,OS,version,1.0");
35 	return 0;
36 }
37 
38 
39 static int server_reset_user(struct sigma_dut *dut, const char *user)
40 {
41 	sqlite3 *db;
42 	int res = -1;
43 	char *sql = NULL;
44 	const char *realm = "wi-fi.org";
45 	const char *methods = "TTLS-MSCHAPV2";
46 	const char *password = "ChangeMe";
47 	int phase2 = 1;
48 	int machine_managed = 1;
49 	const char *remediation = "";
50 	int fetch_pps = 0;
51 	const char *osu_user = NULL;
52 	const char *osu_password = NULL;
53 	const char *policy = NULL;
54 
55 	sigma_dut_print(dut, DUT_MSG_DEBUG, "Reset user %s", user);
56 
57 	if (sqlite3_open(SERVER_DB, &db)) {
58 		sigma_dut_print(dut, DUT_MSG_ERROR,
59 				"Failed to open SQLite database %s",
60 				SERVER_DB);
61 		return -1;
62 	}
63 
64 	if (strcmp(user, "test01") == 0) {
65 		remediation = "machine";
66 	} else if (strcmp(user, "test02") == 0) {
67 		remediation = "user";
68 		machine_managed = 0;
69 	} else if (strcmp(user, "test03") == 0) {
70 		/* UpdateInterval-based client trigger for policy update */
71 		policy = "ruckus130";
72 	} else if (strcmp(user, "test04") == 0) {
73 	} else if (strcmp(user, "test05") == 0) {
74 	} else if (strcmp(user, "test06") == 0) {
75 		realm = "example.com";
76 	} else if (strcmp(user, "test07") == 0) {
77 	} else if (strcmp(user, "test08") == 0) {
78 		remediation = "machine";
79 		osu_user = "testdmacc08";
80 		osu_password = "P@ssw0rd";
81 	} else if (strcmp(user, "test09") == 0) {
82 		/* UpdateInterval-based client trigger for policy update */
83 		policy = "ruckus130";
84 		osu_user = "testdmacc09";
85 		osu_password = "P@ssw0rd";
86 	} else if (strcmp(user, "test10") == 0) {
87 		remediation = "machine";
88 		methods = "TLS";
89 	} else if (strcmp(user, "test11") == 0) {
90 	} else if (strcmp(user, "test12") == 0) {
91 		remediation = "user";
92 		methods = "TLS";
93 	} else if (strcmp(user, "test20") == 0) {
94 	} else if (strcmp(user, "test26") == 0) {
95 		/* TODO: Cred01 with username/password? */
96 		user = "1310026000000001";
97 		methods = "SIM";
98 	} else if (strcmp(user, "test30") == 0) {
99 		osu_user = "testdmacc30";
100 		osu_password = "P@ssw0rd";
101 	} else if (strcmp(user, "test31") == 0) {
102 		osu_user = "testdmacc31";
103 		osu_password = "P@ssw0rd";
104 	} else if (strcmp(user, "test32") == 0) {
105 		osu_user = "testdmacc32";
106 		osu_password = "P@ssw0rd";
107 	} else if (strcmp(user, "test33") == 0) {
108 		osu_user = "testdmacc33";
109 		osu_password = "P@ssw0rd";
110 	} else if (strcmp(user, "test34") == 0) {
111 		osu_user = "testdmacc34";
112 		osu_password = "P@ssw0rd";
113 	} else if (strcmp(user, "test35") == 0) {
114 		osu_user = "testdmacc35";
115 		osu_password = "P@ssw0rd";
116 	} else if (strcmp(user, "test36") == 0) {
117 	} else if (strcmp(user, "test37") == 0) {
118 		osu_user = "testdmacc37";
119 		osu_password = "P@ssw0rd";
120 	} else if (strcmp(user, "testdmacc08") == 0 ||
121 		   strcmp(user, "testdmacc09") == 0) {
122 		/* No need to set anything separate for testdmacc* users */
123 		sqlite3_close(db);
124 		return 0;
125 	} else {
126 		sigma_dut_print(dut, DUT_MSG_INFO, "Unsupported username '%s'",
127 				user);
128 		goto fail;
129 	}
130 
131 	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)",
132 			      user, realm, methods, password,
133 			      phase2, machine_managed, remediation, fetch_pps,
134 			      osu_user, osu_password, policy);
135 
136 	if (!sql)
137 		goto fail;
138 
139 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
140 
141 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
142 		sigma_dut_print(dut, DUT_MSG_ERROR, "SQL operation failed: %s",
143 				sqlite3_errmsg(db));
144 	} else {
145 		res = 0;
146 	}
147 
148 	sqlite3_free(sql);
149 
150 fail:
151 	sqlite3_close(db);
152 
153 	return res;
154 }
155 
156 
157 static int server_reset_cert_enroll(struct sigma_dut *dut, const char *addr)
158 {
159 	sqlite3 *db;
160 	char *sql;
161 
162 	sigma_dut_print(dut, DUT_MSG_DEBUG,
163 			"Reset certificate enrollment status for %s", addr);
164 
165 	if (sqlite3_open(SERVER_DB, &db)) {
166 		sigma_dut_print(dut, DUT_MSG_ERROR,
167 				"Failed to open SQLite database %s",
168 				SERVER_DB);
169 		return -1;
170 	}
171 	sql = sqlite3_mprintf("DELETE FROM cert_enroll WHERE mac_addr=%Q",
172 			      addr);
173 	if (!sql) {
174 		sqlite3_close(db);
175 		return -1;
176 	}
177 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
178 
179 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
180 		sigma_dut_print(dut, DUT_MSG_ERROR,
181 				"SQL operation failed: %s",
182 				sqlite3_errmsg(db));
183 		sqlite3_free(sql);
184 		sqlite3_close(db);
185 		return -1;
186 	}
187 
188 	sqlite3_free(sql);
189 	sqlite3_close(db);
190 
191 	return 0;
192 }
193 
194 
195 static int cmd_server_reset_default(struct sigma_dut *dut,
196 				    struct sigma_conn *conn,
197 				    struct sigma_cmd *cmd)
198 {
199 	const char *var;
200 	enum sigma_program prog;
201 
202 	var = get_param(cmd, "Program");
203 	if (!var) {
204 		send_resp(dut, conn, SIGMA_ERROR,
205 			  "errorCode,Missing program parameter");
206 		return 0;
207 	}
208 
209 	prog = sigma_program_to_enum(var);
210 	if (prog != PROGRAM_HS2_R2 && prog != PROGRAM_HS2_R3) {
211 		send_resp(dut, conn, SIGMA_ERROR,
212 			  "errorCode,Unsupported program");
213 		return 0;
214 	}
215 
216 	var = get_param(cmd, "UserName");
217 	if (var && server_reset_user(dut, var) < 0) {
218 		send_resp(dut, conn, SIGMA_ERROR,
219 			  "errorCode,Failed to reset user account to defaults");
220 		return 0;
221 	}
222 
223 	var = get_param(cmd, "SerialNo");
224 	if (var) {
225 		sigma_dut_print(dut, DUT_MSG_DEBUG, "Reset serial number %s",
226 				var);
227 		/* TODO */
228 	}
229 
230 	var = get_param(cmd, "ClientMACAddr");
231 	if (var && server_reset_cert_enroll(dut, var) < 0) {
232 		send_resp(dut, conn, SIGMA_ERROR,
233 			  "errorCode,Failed to reset cert enroll to defaults");
234 		return 0;
235 	}
236 
237 	return 1;
238 }
239 
240 
241 static int get_last_msk_cb(void *ctx, int argc, char *argv[], char *col[])
242 {
243 	char **last_msk = ctx;
244 
245 	if (argc < 1 || !argv[0])
246 		return 0;
247 
248 	free(*last_msk);
249 	*last_msk = strdup(argv[0]);
250 
251 	return 0;
252 }
253 
254 
255 static char * get_last_msk(struct sigma_dut *dut, sqlite3 *db,
256 			   const char *username)
257 {
258 	char *sql, *last_msk = NULL;
259 
260 	sql = sqlite3_mprintf("SELECT last_msk FROM users WHERE identity=%Q",
261 			      username);
262 	if (!sql)
263 		return NULL;
264 
265 	if (sqlite3_exec(db, sql, get_last_msk_cb, &last_msk, NULL) !=
266 	    SQLITE_OK) {
267 		sigma_dut_print(dut, DUT_MSG_ERROR,
268 				"SQL operation to fetch last_msk failed: %s",
269 				sqlite3_errmsg(db));
270 		sqlite3_free(sql);
271 		return NULL;
272 	}
273 
274 	sqlite3_free(sql);
275 
276 	return last_msk;
277 }
278 
279 
280 static int aaa_auth_status(struct sigma_dut *dut, struct sigma_conn *conn,
281 			   struct sigma_cmd *cmd, const char *username,
282 			   int timeout)
283 {
284 	sqlite3 *db;
285 	char *sql = NULL;
286 	int i;
287 	char resp[500];
288 
289 	if (sqlite3_open(SERVER_DB, &db)) {
290 		sigma_dut_print(dut, DUT_MSG_ERROR,
291 				"Failed to open SQLite database %s",
292 				SERVER_DB);
293 		return -1;
294 	}
295 
296 	sql = sqlite3_mprintf("UPDATE users SET last_msk=NULL WHERE identity=%Q",
297 			      username);
298 	if (!sql) {
299 		sqlite3_close(db);
300 		return -1;
301 	}
302 
303 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
304 		sigma_dut_print(dut, DUT_MSG_ERROR,
305 				"SQL operation to clear last_msk failed: %s",
306 				sqlite3_errmsg(db));
307 		sqlite3_free(sql);
308 		sqlite3_close(db);
309 		return -1;
310 	}
311 
312 	sqlite3_free(sql);
313 
314 	if (sqlite3_changes(db) < 1) {
315 		sigma_dut_print(dut, DUT_MSG_ERROR,
316 				"No DB rows modified (specified user not found)");
317 		sqlite3_close(db);
318 		return -1;
319 	}
320 
321 	snprintf(resp, sizeof(resp), "AuthStatus,TIMEOUT,MSK,NULL");
322 
323 	for (i = 0; i < timeout; i++) {
324 		char *last_msk;
325 
326 		last_msk = get_last_msk(dut, db, username);
327 		if (last_msk) {
328 			if (strcmp(last_msk, "FAIL") == 0) {
329 				snprintf(resp, sizeof(resp),
330 					 "AuthStatus,FAIL,MSK,NULL");
331 			} else {
332 				snprintf(resp, sizeof(resp),
333 					 "AuthStatus,SUCCESS,MSK,%s", last_msk);
334 			}
335 			free(last_msk);
336 			break;
337 		}
338 		sleep(1);
339 	}
340 
341 	sqlite3_close(db);
342 
343 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
344 	return 0;
345 }
346 
347 
348 static int get_last_serial_cb(void *ctx, int argc, char *argv[], char *col[])
349 {
350 	char **last_serial = ctx;
351 
352 	if (argc < 1 || !argv[0])
353 		return 0;
354 
355 	free(*last_serial);
356 	*last_serial = strdup(argv[0]);
357 
358 	return 0;
359 }
360 
361 
362 static char * get_last_serial(struct sigma_dut *dut, sqlite3 *db,
363 			      const char *addr)
364 {
365 	char *sql, *last_serial = NULL;
366 
367 	sql = sqlite3_mprintf("SELECT serialnum FROM cert_enroll WHERE mac_addr=%Q",
368 			      addr);
369 	if (!sql)
370 		return NULL;
371 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
372 
373 	if (sqlite3_exec(db, sql, get_last_serial_cb, &last_serial, NULL) !=
374 	    SQLITE_OK) {
375 		sigma_dut_print(dut, DUT_MSG_ERROR,
376 				"SQL operation to fetch last_serial failed: %s",
377 				sqlite3_errmsg(db));
378 		sqlite3_free(sql);
379 		return NULL;
380 	}
381 
382 	sqlite3_free(sql);
383 
384 	return last_serial;
385 }
386 
387 
388 static int osu_cert_enroll_status(struct sigma_dut *dut,
389 				  struct sigma_conn *conn,
390 				  struct sigma_cmd *cmd, const char *addr,
391 				  int timeout)
392 {
393 	sqlite3 *db;
394 	int i;
395 	char resp[500];
396 
397 	if (sqlite3_open(SERVER_DB, &db)) {
398 		sigma_dut_print(dut, DUT_MSG_ERROR,
399 				"Failed to open SQLite database %s",
400 				SERVER_DB);
401 		return -1;
402 	}
403 
404 	snprintf(resp, sizeof(resp), "OSUStatus,TIMEOUT");
405 
406 	for (i = 0; i < timeout; i++) {
407 		char *last_serial;
408 
409 		last_serial = get_last_serial(dut, db, addr);
410 		if (last_serial) {
411 			if (strcmp(last_serial, "FAIL") == 0) {
412 				snprintf(resp, sizeof(resp),
413 					 "OSUStatus,FAIL");
414 			} else if (strlen(last_serial) > 0) {
415 				snprintf(resp, sizeof(resp),
416 					 "OSUStatus,SUCCESS,SerialNo,%s",
417 					 last_serial);
418 			}
419 			free(last_serial);
420 			break;
421 		}
422 		sleep(1);
423 	}
424 
425 	sqlite3_close(db);
426 
427 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
428 	return 0;
429 }
430 
431 
432 static int get_user_field_cb(void *ctx, int argc, char *argv[], char *col[])
433 {
434 	char **val = ctx;
435 
436 	if (argc < 1 || !argv[0])
437 		return 0;
438 
439 	free(*val);
440 	*val = strdup(argv[0]);
441 
442 	return 0;
443 }
444 
445 
446 static char * get_user_field_helper(struct sigma_dut *dut, sqlite3 *db,
447 				    const char *id_field,
448 				    const char *identity, const char *field)
449 {
450 	char *sql, *val = NULL;
451 
452 	sql = sqlite3_mprintf("SELECT %s FROM users WHERE %s=%Q",
453 			      field, id_field, identity);
454 	if (!sql)
455 		return NULL;
456 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
457 
458 	if (sqlite3_exec(db, sql, get_user_field_cb, &val, NULL) != SQLITE_OK) {
459 		sigma_dut_print(dut, DUT_MSG_ERROR,
460 				"SQL operation to fetch user field failed: %s",
461 				sqlite3_errmsg(db));
462 		sqlite3_free(sql);
463 		return NULL;
464 	}
465 
466 	sqlite3_free(sql);
467 
468 	return val;
469 }
470 
471 
472 static char * get_user_field(struct sigma_dut *dut, sqlite3 *db,
473 			     const char *identity, const char *field)
474 {
475 	return get_user_field_helper(dut, db, "identity", identity, field);
476 }
477 
478 
479 static char * get_user_dmacc_field(struct sigma_dut *dut, sqlite3 *db,
480 				   const char *identity, const char *field)
481 {
482 	return get_user_field_helper(dut, db, "osu_user", identity, field);
483 }
484 
485 
486 static int osu_remediation_status(struct sigma_dut *dut,
487 				  struct sigma_conn *conn, int timeout,
488 				  const char *username, const char *serialno)
489 {
490 	sqlite3 *db;
491 	int i;
492 	char resp[500];
493 	char name[100];
494 	char *remediation = NULL;
495 	int dmacc = 0;
496 
497 	if (!username && !serialno)
498 		return -1;
499 	if (!username) {
500 		snprintf(name, sizeof(name), "cert-%s", serialno);
501 		username = name;
502 	}
503 
504 	if (sqlite3_open(SERVER_DB, &db)) {
505 		sigma_dut_print(dut, DUT_MSG_ERROR,
506 				"Failed to open SQLite database %s",
507 				SERVER_DB);
508 		return -1;
509 	}
510 
511 	remediation = get_user_field(dut, db, username, "remediation");
512 	if (!remediation) {
513 		remediation = get_user_dmacc_field(dut, db, username,
514 						   "remediation");
515 		dmacc = 1;
516 	}
517 	if (!remediation) {
518 		snprintf(resp, sizeof(resp),
519 			 "RemediationStatus,User entry not found");
520 		goto done;
521 	}
522 	if (remediation[0] == '\0') {
523 		snprintf(resp, sizeof(resp),
524 			 "RemediationStatus,User was not configured to need remediation");
525 		goto done;
526 	}
527 
528 	snprintf(resp, sizeof(resp), "RemediationStatus,TIMEOUT");
529 
530 	for (i = 0; i < timeout; i++) {
531 		sleep(1);
532 		free(remediation);
533 		if (dmacc)
534 			remediation = get_user_dmacc_field(dut, db, username,
535 							   "remediation");
536 		else
537 			remediation = get_user_field(dut, db, username,
538 						     "remediation");
539 		if (remediation && remediation[0] == '\0') {
540 			snprintf(resp, sizeof(resp),
541 				 "RemediationStatus,Remediation Complete");
542 			break;
543 		}
544 	}
545 
546 done:
547 	free(remediation);
548 	sqlite3_close(db);
549 
550 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
551 	return 0;
552 }
553 
554 
555 static int osu_polupd_status(struct sigma_dut *dut,
556 			     struct sigma_conn *conn, int timeout,
557 			     const char *username, const char *serialno)
558 {
559 	sqlite3 *db;
560 	char *sql;
561 	int i;
562 	char resp[500];
563 	char name[100];
564 	char *policy = NULL;
565 	int dmacc = 0;
566 
567 	if (!username && !serialno)
568 		return -1;
569 	if (!username) {
570 		snprintf(name, sizeof(name), "cert-%s", serialno);
571 		username = name;
572 	}
573 
574 	if (sqlite3_open(SERVER_DB, &db)) {
575 		sigma_dut_print(dut, DUT_MSG_ERROR,
576 				"Failed to open SQLite database %s",
577 				SERVER_DB);
578 		return -1;
579 	}
580 
581 	policy = get_user_field(dut, db, username, "policy");
582 	if (!policy) {
583 		policy = get_user_dmacc_field(dut, db, username, "policy");
584 		dmacc = 1;
585 	}
586 	if (!policy) {
587 		snprintf(resp, sizeof(resp),
588 			 "PolicyUpdateStatus,User entry not found");
589 		goto done;
590 	}
591 	if (policy[0] == '\0') {
592 		snprintf(resp, sizeof(resp),
593 			 "PolicyUpdateStatus,User was not configured to need policy update");
594 		goto done;
595 	}
596 
597 	sql = sqlite3_mprintf("UPDATE users SET polupd_done=0 WHERE %s=%Q",
598 			      (dmacc ? "osu_user" : "identity"),
599 			      username);
600 	if (!sql) {
601 		snprintf(resp, sizeof(resp),
602 			 "PolicyUpdateStatus,Internal error");
603 		goto done;
604 	}
605 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
606 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
607 		sigma_dut_print(dut, DUT_MSG_ERROR,
608 				"SQL operation to fetch user field failed: %s",
609 				sqlite3_errmsg(db));
610 		sqlite3_free(sql);
611 		goto done;
612 	}
613 	sqlite3_free(sql);
614 
615 	snprintf(resp, sizeof(resp), "PolicyUpdateStatus,TIMEOUT");
616 
617 	for (i = 0; i < timeout; i++) {
618 		sleep(1);
619 		free(policy);
620 		if (dmacc)
621 			policy = get_user_dmacc_field(dut, db, username,
622 						      "polupd_done");
623 		else
624 			policy = get_user_field(dut, db, username,
625 						"polupd_done");
626 		if (policy && atoi(policy)) {
627 			snprintf(resp, sizeof(resp),
628 				 "PolicyUpdateStatus,UpdateComplete");
629 			break;
630 		}
631 	}
632 
633 done:
634 	free(policy);
635 	sqlite3_close(db);
636 
637 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
638 	return 0;
639 }
640 
641 
642 static int cmd_server_request_status(struct sigma_dut *dut,
643 				     struct sigma_conn *conn,
644 				     struct sigma_cmd *cmd)
645 {
646 	const char *var, *username, *serialno, *imsi, *addr, *status;
647 	int osu, timeout;
648 	char resp[500];
649 	enum sigma_program prog;
650 
651 	var = get_param(cmd, "Program");
652 	if (!var) {
653 		send_resp(dut, conn, SIGMA_ERROR,
654 			  "errorCode,Missing program parameter");
655 		return 0;
656 	}
657 
658 	prog = sigma_program_to_enum(var);
659 	if (prog != PROGRAM_HS2_R2 && prog != PROGRAM_HS2_R3) {
660 		send_resp(dut, conn, SIGMA_ERROR,
661 			  "errorCode,Unsupported program");
662 		return 0;
663 	}
664 
665 	var = get_param(cmd, "Device");
666 	if (!var ||
667 	    (strcasecmp(var, "AAAServer") != 0 &&
668 	     strcasecmp(var, "OSUServer") != 0)) {
669 		send_resp(dut, conn, SIGMA_ERROR,
670 			  "errorCode,Unsupported device type");
671 		return 0;
672 	}
673 	osu = strcasecmp(var, "OSUServer") == 0;
674 
675 	var = get_param(cmd, "Timeout");
676 	if (!var) {
677 		send_resp(dut, conn, SIGMA_ERROR,
678 			  "errorCode,Missing timeout");
679 		return 0;
680 	}
681 	timeout = atoi(var);
682 	sigma_dut_print(dut, DUT_MSG_DEBUG, "timeout: %d", timeout);
683 
684 	username = get_param(cmd, "UserName");
685 	if (username)
686 		sigma_dut_print(dut, DUT_MSG_DEBUG, "UserName: %s", username);
687 	serialno = get_param(cmd, "SerialNo");
688 	if (serialno)
689 		sigma_dut_print(dut, DUT_MSG_DEBUG, "SerialNo: %s", serialno);
690 	imsi = get_param(cmd, "imsi_val");
691 	if (imsi)
692 		sigma_dut_print(dut, DUT_MSG_DEBUG, "imsi_val: %s", imsi);
693 	addr = get_param(cmd, "ClientMACAddr");
694 	if (addr)
695 		sigma_dut_print(dut, DUT_MSG_DEBUG, "ClientMACAddr: %s", addr);
696 	status = get_param(cmd, "Status");
697 	if (status)
698 		sigma_dut_print(dut, DUT_MSG_DEBUG, "Status: %s", status);
699 
700 	if (osu && status && strcasecmp(status, "Remediation") == 0)
701 		return osu_remediation_status(dut, conn, timeout, username,
702 					      serialno);
703 
704 	if (osu && status && strcasecmp(status, "PolicyUpdate") == 0)
705 		return osu_polupd_status(dut, conn, timeout, username,
706 					 serialno);
707 
708 	if (!osu && status && strcasecmp(status, "Authentication") == 0 &&
709 	    username)
710 		return aaa_auth_status(dut, conn, cmd, username, timeout);
711 
712 	if (!osu && status && strcasecmp(status, "Authentication") == 0 &&
713 	    serialno) {
714 		snprintf(resp, sizeof(resp), "cert-%s", serialno);
715 		return aaa_auth_status(dut, conn, cmd, resp, timeout);
716 	}
717 
718 	if (osu && status && strcasecmp(status, "OSU") == 0 && addr)
719 		return osu_cert_enroll_status(dut, conn, cmd, addr, timeout);
720 
721 	return 1;
722 }
723 
724 
725 static int osu_set_cert_reenroll(struct sigma_dut *dut, const char *serial,
726 				 int enable)
727 {
728 	sqlite3 *db;
729 	char *sql;
730 	char id[100];
731 	int ret = -1;
732 
733 	if (sqlite3_open(SERVER_DB, &db)) {
734 		sigma_dut_print(dut, DUT_MSG_ERROR,
735 				"Failed to open SQLite database %s",
736 				SERVER_DB);
737 		return -1;
738 	}
739 
740 	snprintf(id, sizeof(id), "cert-%s", serial);
741 	sql = sqlite3_mprintf("UPDATE users SET remediation=%Q WHERE lower(identity)=lower(%Q)",
742 			      enable ? "machine" : "", id);
743 	if (!sql)
744 		goto fail;
745 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
746 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
747 		sigma_dut_print(dut, DUT_MSG_ERROR, "SQL operation failed: %s",
748 				sqlite3_errmsg(db));
749 		goto fail;
750 	}
751 
752 	if (sqlite3_changes(db) < 1) {
753 		sigma_dut_print(dut, DUT_MSG_ERROR, "No DB rows modified (specified serial number not found)");
754 		goto fail;
755 	}
756 
757 	ret = 0;
758 fail:
759 	sqlite3_close(db);
760 
761 	return ret;
762 }
763 
764 
765 static int cmd_server_set_parameter(struct sigma_dut *dut,
766 				    struct sigma_conn *conn,
767 				    struct sigma_cmd *cmd)
768 {
769 	const char *var, *root_ca, *inter_ca, *osu_cert, *issuing_arch, *name;
770 	const char *reenroll, *serial;
771 	int osu, timeout = -1;
772 	enum sigma_program prog;
773 
774 	var = get_param(cmd, "Program");
775 	if (!var) {
776 		send_resp(dut, conn, SIGMA_ERROR,
777 			  "errorCode,Missing program parameter");
778 		return 0;
779 	}
780 
781 	prog = sigma_program_to_enum(var);
782 	if (prog != PROGRAM_HS2_R2 && prog != PROGRAM_HS2_R3) {
783 		send_resp(dut, conn, SIGMA_ERROR,
784 			  "errorCode,Unsupported program");
785 		return 0;
786 	}
787 
788 	var = get_param(cmd, "Device");
789 	if (!var ||
790 	    (strcasecmp(var, "AAAServer") != 0 &&
791 	     strcasecmp(var, "OSUServer") != 0)) {
792 		send_resp(dut, conn, SIGMA_ERROR,
793 			  "errorCode,Unsupported device type");
794 		return 0;
795 	}
796 	osu = strcasecmp(var, "OSUServer") == 0;
797 
798 	var = get_param(cmd, "Timeout");
799 	if (var)
800 		timeout = atoi(var);
801 
802 	var = get_param(cmd, "ProvisioningProto");
803 	if (var && strcasecmp(var, "SOAP") != 0) {
804 		send_resp(dut, conn, SIGMA_ERROR,
805 			  "errorCode,Unsupported ProvisioningProto");
806 		return 0;
807 	}
808 
809 	reenroll = get_param(cmd, "CertReEnroll");
810 	serial = get_param(cmd, "SerialNo");
811 	if (reenroll && serial) {
812 		int enable;
813 
814 		if (strcasecmp(reenroll, "Enable") == 0) {
815 			enable = 1;
816 		} else if (strcasecmp(reenroll, "Disable") == 0) {
817 			enable = 0;
818 		} else {
819 			send_resp(dut, conn, SIGMA_ERROR,
820 				  "errorCode,Invalid CertReEnroll value");
821 			return 0;
822 		}
823 
824 		if (osu_set_cert_reenroll(dut, serial, enable) < 0) {
825 			send_resp(dut, conn, SIGMA_ERROR,
826 				  "errorCode,Failed to update certificate reenrollment state");
827 			return 0;
828 		}
829 	}
830 
831 	name = get_param(cmd, "Name");
832 	root_ca = get_param(cmd, "TrustRootCACert");
833 	inter_ca = get_param(cmd, "InterCACert");
834 	osu_cert = get_param(cmd, "OSUServerCert");
835 	issuing_arch = get_param(cmd, "Issuing_Arch");
836 
837 	if (timeout > -1) {
838 		/* TODO */
839 	}
840 
841 	if (osu && name && root_ca && inter_ca && osu_cert && issuing_arch) {
842 		const char *srv;
843 		char buf[500];
844 		char buf2[500];
845 		int col;
846 
847 		sigma_dut_print(dut, DUT_MSG_DEBUG,
848 				"Update server certificate setup");
849 
850 		if (strcasecmp(name, "ruckus") == 0) {
851 			srv = "RKS";
852 		} else if (strcasecmp(name, "aruba") == 0) {
853 			srv = "ARU";
854 		} else {
855 			send_resp(dut, conn, SIGMA_ERROR,
856 				  "errorCode,Unsupported Name value");
857 			return 0;
858 		}
859 
860 		if (strcasecmp(issuing_arch, "col2") == 0) {
861 			col = 2;
862 		} else if (strcasecmp(issuing_arch, "col4") == 0) {
863 			col = 4;
864 		} else {
865 			send_resp(dut, conn, SIGMA_ERROR,
866 				  "errorCode,Unsupported Issuing_Arch value");
867 			return 0;
868 		}
869 
870 		if (strcasecmp(root_ca, "ID-T") == 0) {
871 			sigma_dut_print(dut, DUT_MSG_DEBUG,
872 					"OSU trust root: NetworkFX");
873 			if (system("cp " CERT_DIR "/IDT-cert-RootCA.pem "
874 				   CERT_DIR "/cacert.pem") < 0)
875 				return -2;
876 		} else if (strcasecmp(root_ca, "ID-Y") == 0) {
877 			sigma_dut_print(dut, DUT_MSG_DEBUG,
878 					"OSU trust root: NetworkFX");
879 			if (system("cp " CERT_DIR "/IDY-cert-RootCA.pem "
880 				   CERT_DIR "/cacert.pem") < 0)
881 				return -2;
882 		} else {
883 			send_resp(dut, conn, SIGMA_ERROR,
884 				  "errorCode,Unsupported TrustRootCACert value");
885 			return 0;
886 		}
887 
888 		if (strcasecmp(inter_ca, "ID-Z.2") == 0) {
889 			sigma_dut_print(dut, DUT_MSG_DEBUG,
890 					"OSU intermediate CA: NetworkFX (col2)");
891 			if (system("cat " CERT_DIR "/IDZ2-cert-InterCA.pem >> "
892 				   CERT_DIR "/cacert.pem") < 0)
893 				return -2;
894 		} else if (strcasecmp(inter_ca, "ID-Z.4") == 0) {
895 			sigma_dut_print(dut, DUT_MSG_DEBUG,
896 					"OSU intermediate CA: DigiCert (col2)");
897 			if (system("cat " CERT_DIR "/IDZ4-cert-InterCA.pem >> "
898 				   CERT_DIR "/cacert.pem") < 0)
899 				return -2;
900 		} else if (strcasecmp(inter_ca, "ID-Z.6") == 0) {
901 			sigma_dut_print(dut, DUT_MSG_DEBUG,
902 					"OSU intermediate CA: NetworkFX (col4)");
903 			if (system("cat " CERT_DIR "/IDZ6-cert-InterCA.pem >> "
904 				   CERT_DIR "/cacert.pem") < 0)
905 				return -2;
906 		} else if (strcasecmp(inter_ca, "ID-Z.8") == 0) {
907 			sigma_dut_print(dut, DUT_MSG_DEBUG,
908 					"OSU intermediate CA: DigiCert (col4)");
909 			if (system("cat " CERT_DIR "/IDZ8-cert-InterCA.pem >> "
910 				   CERT_DIR "/cacert.pem") < 0)
911 				return -2;
912 		} else {
913 			send_resp(dut, conn, SIGMA_ERROR,
914 				  "errorCode,Unsupported InterCACert value");
915 			return 0;
916 		}
917 
918 		if (strcasecmp(osu_cert, "ID-Q") == 0) {
919 			sigma_dut_print(dut, DUT_MSG_DEBUG,
920 					"OSU server cert: NetworkFX col%d",
921 					col);
922 			snprintf(buf, sizeof(buf),
923 				 "cp " CERT_DIR "/IDQ-cert-c%d-%s.pem "
924 				 CERT_DIR "/server.pem",
925 				 col, srv);
926 			snprintf(buf2, sizeof(buf2),
927 				 "cp " CERT_DIR "/IDQ-key-%s.pem "
928 				 CERT_DIR "/server.key", srv);
929 		} else if (strcasecmp(osu_cert, "ID-W") == 0) {
930 			sigma_dut_print(dut, DUT_MSG_DEBUG,
931 					"OSU server cert: DigiCert col%d",
932 					col);
933 			snprintf(buf, sizeof(buf),
934 				 "cp " CERT_DIR "/IDW-cert-c%d-%s.pem "
935 				 CERT_DIR "/server.pem",
936 				 col, srv);
937 			snprintf(buf2, sizeof(buf2),
938 				 "cp " CERT_DIR "/IDW-key-%s.pem "
939 				 CERT_DIR "/server.key", srv);
940 		} else if (strcasecmp(osu_cert, "ID-R.2") == 0) {
941 			sigma_dut_print(dut, DUT_MSG_DEBUG,
942 					"OSU server cert: NetworkFX revoked col%d",
943 					col);
944 			snprintf(buf, sizeof(buf),
945 				 "cp " CERT_DIR "/IDR2-cert-c%d-%s.pem "
946 				 CERT_DIR "/server.pem",
947 				 col, srv);
948 			snprintf(buf2, sizeof(buf2),
949 				 "cp " CERT_DIR "/IDR2-key-%s.pem "
950 				 CERT_DIR "/server.key", srv);
951 		} else if (strcasecmp(osu_cert, "ID-R.4") == 0) {
952 			sigma_dut_print(dut, DUT_MSG_DEBUG,
953 					"OSU server cert: DigiCert revoked col%d",
954 					col);
955 			snprintf(buf, sizeof(buf),
956 				 "cp " CERT_DIR "/IDR4-cert-c%d-%s.pem "
957 				 CERT_DIR "/server.pem",
958 				 col, srv);
959 			snprintf(buf2, sizeof(buf2),
960 				 "cp " CERT_DIR "/IDR4-key-%s.pem "
961 				 CERT_DIR "/server.key", srv);
962 		} else {
963 			send_resp(dut, conn, SIGMA_ERROR,
964 				  "errorCode,Unsupported OSUServerCert value");
965 			return 0;
966 		}
967 
968 		if (system(buf) < 0 || system(buf2) < 0)
969 			return -2;
970 
971 		if (system("service apache2 reload") < 0) {
972 			send_resp(dut, conn, SIGMA_ERROR,
973 				  "errorCode,Failed to restart Apache");
974 			return 0;
975 		}
976 	}
977 
978 	/* TODO */
979 	return 1;
980 }
981 
982 
983 void server_register_cmds(void)
984 {
985 	sigma_dut_reg_cmd("server_ca_get_version", NULL,
986 			  cmd_server_ca_get_version);
987 	sigma_dut_reg_cmd("server_get_info", NULL,
988 			  cmd_server_get_info);
989 	sigma_dut_reg_cmd("server_reset_default", NULL,
990 			  cmd_server_reset_default);
991 	sigma_dut_reg_cmd("server_request_status", NULL,
992 			  cmd_server_request_status);
993 	sigma_dut_reg_cmd("server_set_parameter", NULL,
994 			  cmd_server_set_parameter);
995 }
996