xref: /wlan-dirver/utils/sigma-dut/server.c (revision fc9a2f78a2e413f176c944059e0af06e8613f7f8)
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_serial(struct sigma_dut *dut, const char *serial)
158 {
159 	sqlite3 *db;
160 	int res = -1;
161 	char *sql = NULL;
162 	const char *realm = "wi-fi.org";
163 	const char *methods = "TLS";
164 	int phase2 = 0;
165 	int machine_managed = 1;
166 	const char *remediation = "";
167 	int fetch_pps = 0;
168 	const char *osu_user = NULL;
169 	const char *osu_password = NULL;
170 	const char *policy = NULL;
171 	char user[128];
172 
173 	snprintf(user, sizeof(user), "cert-%s", serial);
174 	sigma_dut_print(dut, DUT_MSG_DEBUG, "Reset user %s (serial number: %s)",
175 			user, serial);
176 
177 	if (sqlite3_open(SERVER_DB, &db)) {
178 		sigma_dut_print(dut, DUT_MSG_ERROR,
179 				"Failed to open SQLite database %s",
180 				SERVER_DB);
181 		return -1;
182 	}
183 
184 	if (strcmp(serial, "1046") == 0) {
185 		remediation = "machine";
186 	} else if (strcmp(serial, "1047") == 0) {
187 		remediation = "user";
188 	} else {
189 		sigma_dut_print(dut, DUT_MSG_INFO,
190 				"Unsupported serial number '%s'", serial);
191 		goto fail;
192 	}
193 
194 	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 			      user, realm, methods,
196 			      phase2, machine_managed, remediation, fetch_pps,
197 			      osu_user, osu_password, policy);
198 
199 	if (!sql)
200 		goto fail;
201 
202 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
203 
204 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
205 		sigma_dut_print(dut, DUT_MSG_ERROR, "SQL operation failed: %s",
206 				sqlite3_errmsg(db));
207 	} else {
208 		res = 0;
209 	}
210 
211 	sqlite3_free(sql);
212 
213 fail:
214 	sqlite3_close(db);
215 
216 	return res;
217 }
218 
219 
220 static int server_reset_cert_enroll(struct sigma_dut *dut, const char *addr)
221 {
222 	sqlite3 *db;
223 	char *sql;
224 
225 	sigma_dut_print(dut, DUT_MSG_DEBUG,
226 			"Reset certificate enrollment status for %s", addr);
227 
228 	if (sqlite3_open(SERVER_DB, &db)) {
229 		sigma_dut_print(dut, DUT_MSG_ERROR,
230 				"Failed to open SQLite database %s",
231 				SERVER_DB);
232 		return -1;
233 	}
234 	sql = sqlite3_mprintf("DELETE FROM cert_enroll WHERE mac_addr=%Q",
235 			      addr);
236 	if (!sql) {
237 		sqlite3_close(db);
238 		return -1;
239 	}
240 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
241 
242 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
243 		sigma_dut_print(dut, DUT_MSG_ERROR,
244 				"SQL operation failed: %s",
245 				sqlite3_errmsg(db));
246 		sqlite3_free(sql);
247 		sqlite3_close(db);
248 		return -1;
249 	}
250 
251 	sqlite3_free(sql);
252 	sqlite3_close(db);
253 
254 	return 0;
255 }
256 
257 
258 static int cmd_server_reset_default(struct sigma_dut *dut,
259 				    struct sigma_conn *conn,
260 				    struct sigma_cmd *cmd)
261 {
262 	const char *var;
263 	enum sigma_program prog;
264 
265 	var = get_param(cmd, "Program");
266 	if (!var) {
267 		send_resp(dut, conn, SIGMA_ERROR,
268 			  "errorCode,Missing program parameter");
269 		return 0;
270 	}
271 
272 	prog = sigma_program_to_enum(var);
273 	if (prog != PROGRAM_HS2_R2 && prog != PROGRAM_HS2_R3) {
274 		send_resp(dut, conn, SIGMA_ERROR,
275 			  "errorCode,Unsupported program");
276 		return 0;
277 	}
278 
279 	var = get_param(cmd, "UserName");
280 	if (var && server_reset_user(dut, var) < 0) {
281 		send_resp(dut, conn, SIGMA_ERROR,
282 			  "errorCode,Failed to reset user account to defaults");
283 		return 0;
284 	}
285 
286 	var = get_param(cmd, "SerialNo");
287 	if (var && server_reset_serial(dut, var)) {
288 		send_resp(dut, conn, SIGMA_ERROR,
289 			  "errorCode,Failed to reset user account to defaults");
290 		return 0;
291 		sigma_dut_print(dut, DUT_MSG_DEBUG, "Reset serial number %s",
292 				var);
293 		/* TODO */
294 	}
295 
296 	var = get_param(cmd, "ClientMACAddr");
297 	if (var && server_reset_cert_enroll(dut, var) < 0) {
298 		send_resp(dut, conn, SIGMA_ERROR,
299 			  "errorCode,Failed to reset cert enroll to defaults");
300 		return 0;
301 	}
302 
303 	return 1;
304 }
305 
306 
307 static int get_last_msk_cb(void *ctx, int argc, char *argv[], char *col[])
308 {
309 	char **last_msk = ctx;
310 
311 	if (argc < 1 || !argv[0])
312 		return 0;
313 
314 	free(*last_msk);
315 	*last_msk = strdup(argv[0]);
316 
317 	return 0;
318 }
319 
320 
321 static char * get_last_msk(struct sigma_dut *dut, sqlite3 *db,
322 			   const char *username)
323 {
324 	char *sql, *last_msk = NULL;
325 
326 	sql = sqlite3_mprintf("SELECT last_msk FROM users WHERE identity=%Q",
327 			      username);
328 	if (!sql)
329 		return NULL;
330 
331 	if (sqlite3_exec(db, sql, get_last_msk_cb, &last_msk, NULL) !=
332 	    SQLITE_OK) {
333 		sigma_dut_print(dut, DUT_MSG_ERROR,
334 				"SQL operation to fetch last_msk failed: %s",
335 				sqlite3_errmsg(db));
336 		sqlite3_free(sql);
337 		return NULL;
338 	}
339 
340 	sqlite3_free(sql);
341 
342 	return last_msk;
343 }
344 
345 
346 static int aaa_auth_status(struct sigma_dut *dut, struct sigma_conn *conn,
347 			   struct sigma_cmd *cmd, const char *username,
348 			   int timeout)
349 {
350 	sqlite3 *db;
351 	char *sql = NULL;
352 	int i;
353 	char resp[500];
354 
355 	if (sqlite3_open(SERVER_DB, &db)) {
356 		sigma_dut_print(dut, DUT_MSG_ERROR,
357 				"Failed to open SQLite database %s",
358 				SERVER_DB);
359 		return -1;
360 	}
361 
362 	sql = sqlite3_mprintf("UPDATE users SET last_msk=NULL WHERE identity=%Q",
363 			      username);
364 	if (!sql) {
365 		sqlite3_close(db);
366 		return -1;
367 	}
368 
369 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
370 		sigma_dut_print(dut, DUT_MSG_ERROR,
371 				"SQL operation to clear last_msk failed: %s",
372 				sqlite3_errmsg(db));
373 		sqlite3_free(sql);
374 		sqlite3_close(db);
375 		return -1;
376 	}
377 
378 	sqlite3_free(sql);
379 
380 	if (sqlite3_changes(db) < 1) {
381 		sigma_dut_print(dut, DUT_MSG_ERROR,
382 				"No DB rows modified (specified user not found)");
383 		sqlite3_close(db);
384 		return -1;
385 	}
386 
387 	snprintf(resp, sizeof(resp), "AuthStatus,TIMEOUT,MSK,NULL");
388 
389 	for (i = 0; i < timeout; i++) {
390 		char *last_msk;
391 
392 		last_msk = get_last_msk(dut, db, username);
393 		if (last_msk) {
394 			if (strcmp(last_msk, "FAIL") == 0) {
395 				snprintf(resp, sizeof(resp),
396 					 "AuthStatus,FAIL,MSK,NULL");
397 			} else {
398 				snprintf(resp, sizeof(resp),
399 					 "AuthStatus,SUCCESS,MSK,%s", last_msk);
400 			}
401 			free(last_msk);
402 			break;
403 		}
404 		sleep(1);
405 	}
406 
407 	sqlite3_close(db);
408 
409 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
410 	return 0;
411 }
412 
413 
414 static int get_last_serial_cb(void *ctx, int argc, char *argv[], char *col[])
415 {
416 	char **last_serial = ctx;
417 
418 	if (argc < 1 || !argv[0])
419 		return 0;
420 
421 	free(*last_serial);
422 	*last_serial = strdup(argv[0]);
423 
424 	return 0;
425 }
426 
427 
428 static char * get_last_serial(struct sigma_dut *dut, sqlite3 *db,
429 			      const char *addr)
430 {
431 	char *sql, *last_serial = NULL;
432 
433 	sql = sqlite3_mprintf("SELECT serialnum FROM cert_enroll WHERE mac_addr=%Q",
434 			      addr);
435 	if (!sql)
436 		return NULL;
437 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
438 
439 	if (sqlite3_exec(db, sql, get_last_serial_cb, &last_serial, NULL) !=
440 	    SQLITE_OK) {
441 		sigma_dut_print(dut, DUT_MSG_ERROR,
442 				"SQL operation to fetch last_serial failed: %s",
443 				sqlite3_errmsg(db));
444 		sqlite3_free(sql);
445 		return NULL;
446 	}
447 
448 	sqlite3_free(sql);
449 
450 	return last_serial;
451 }
452 
453 
454 static int osu_cert_enroll_status(struct sigma_dut *dut,
455 				  struct sigma_conn *conn,
456 				  struct sigma_cmd *cmd, const char *addr,
457 				  int timeout)
458 {
459 	sqlite3 *db;
460 	int i;
461 	char resp[500];
462 
463 	if (sqlite3_open(SERVER_DB, &db)) {
464 		sigma_dut_print(dut, DUT_MSG_ERROR,
465 				"Failed to open SQLite database %s",
466 				SERVER_DB);
467 		return -1;
468 	}
469 
470 	snprintf(resp, sizeof(resp), "OSUStatus,TIMEOUT");
471 
472 	for (i = 0; i < timeout; i++) {
473 		char *last_serial;
474 
475 		last_serial = get_last_serial(dut, db, addr);
476 		if (last_serial) {
477 			if (strcmp(last_serial, "FAIL") == 0) {
478 				snprintf(resp, sizeof(resp),
479 					 "OSUStatus,FAIL");
480 			} else if (strlen(last_serial) > 0) {
481 				snprintf(resp, sizeof(resp),
482 					 "OSUStatus,SUCCESS,SerialNo,%s",
483 					 last_serial);
484 			}
485 			free(last_serial);
486 			break;
487 		}
488 		sleep(1);
489 	}
490 
491 	sqlite3_close(db);
492 
493 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
494 	return 0;
495 }
496 
497 
498 static int get_user_field_cb(void *ctx, int argc, char *argv[], char *col[])
499 {
500 	char **val = ctx;
501 
502 	if (argc < 1 || !argv[0])
503 		return 0;
504 
505 	free(*val);
506 	*val = strdup(argv[0]);
507 
508 	return 0;
509 }
510 
511 
512 static char * get_user_field_helper(struct sigma_dut *dut, sqlite3 *db,
513 				    const char *id_field,
514 				    const char *identity, const char *field)
515 {
516 	char *sql, *val = NULL;
517 
518 	sql = sqlite3_mprintf("SELECT %s FROM users WHERE %s=%Q",
519 			      field, id_field, identity);
520 	if (!sql)
521 		return NULL;
522 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
523 
524 	if (sqlite3_exec(db, sql, get_user_field_cb, &val, NULL) != SQLITE_OK) {
525 		sigma_dut_print(dut, DUT_MSG_ERROR,
526 				"SQL operation to fetch user field failed: %s",
527 				sqlite3_errmsg(db));
528 		sqlite3_free(sql);
529 		return NULL;
530 	}
531 
532 	sqlite3_free(sql);
533 
534 	return val;
535 }
536 
537 
538 static char * get_user_field(struct sigma_dut *dut, sqlite3 *db,
539 			     const char *identity, const char *field)
540 {
541 	return get_user_field_helper(dut, db, "identity", identity, field);
542 }
543 
544 
545 static char * get_user_dmacc_field(struct sigma_dut *dut, sqlite3 *db,
546 				   const char *identity, const char *field)
547 {
548 	return get_user_field_helper(dut, db, "osu_user", identity, field);
549 }
550 
551 
552 static int osu_remediation_status(struct sigma_dut *dut,
553 				  struct sigma_conn *conn, int timeout,
554 				  const char *username, const char *serialno)
555 {
556 	sqlite3 *db;
557 	int i;
558 	char resp[500];
559 	char name[100];
560 	char *remediation = NULL;
561 	int dmacc = 0;
562 
563 	if (!username && !serialno)
564 		return -1;
565 	if (!username) {
566 		snprintf(name, sizeof(name), "cert-%s", serialno);
567 		username = name;
568 	}
569 
570 	if (sqlite3_open(SERVER_DB, &db)) {
571 		sigma_dut_print(dut, DUT_MSG_ERROR,
572 				"Failed to open SQLite database %s",
573 				SERVER_DB);
574 		return -1;
575 	}
576 
577 	remediation = get_user_field(dut, db, username, "remediation");
578 	if (!remediation) {
579 		remediation = get_user_dmacc_field(dut, db, username,
580 						   "remediation");
581 		dmacc = 1;
582 	}
583 	if (!remediation) {
584 		snprintf(resp, sizeof(resp),
585 			 "RemediationStatus,User entry not found");
586 		goto done;
587 	}
588 	if (remediation[0] == '\0') {
589 		snprintf(resp, sizeof(resp),
590 			 "RemediationStatus,User was not configured to need remediation");
591 		goto done;
592 	}
593 
594 	snprintf(resp, sizeof(resp), "RemediationStatus,TIMEOUT");
595 
596 	for (i = 0; i < timeout; i++) {
597 		sleep(1);
598 		free(remediation);
599 		if (dmacc)
600 			remediation = get_user_dmacc_field(dut, db, username,
601 							   "remediation");
602 		else
603 			remediation = get_user_field(dut, db, username,
604 						     "remediation");
605 		if (!remediation || (remediation && remediation[0] == '\0')) {
606 			snprintf(resp, sizeof(resp),
607 				 "RemediationStatus,Remediation Complete");
608 			break;
609 		}
610 	}
611 
612 done:
613 	free(remediation);
614 	sqlite3_close(db);
615 
616 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
617 	return 0;
618 }
619 
620 
621 static int osu_polupd_status(struct sigma_dut *dut,
622 			     struct sigma_conn *conn, int timeout,
623 			     const char *username, const char *serialno)
624 {
625 	sqlite3 *db;
626 	char *sql;
627 	int i;
628 	char resp[500];
629 	char name[100];
630 	char *policy = NULL;
631 	int dmacc = 0;
632 
633 	if (!username && !serialno)
634 		return -1;
635 	if (!username) {
636 		snprintf(name, sizeof(name), "cert-%s", serialno);
637 		username = name;
638 	}
639 
640 	if (sqlite3_open(SERVER_DB, &db)) {
641 		sigma_dut_print(dut, DUT_MSG_ERROR,
642 				"Failed to open SQLite database %s",
643 				SERVER_DB);
644 		return -1;
645 	}
646 
647 	policy = get_user_field(dut, db, username, "policy");
648 	if (!policy) {
649 		policy = get_user_dmacc_field(dut, db, username, "policy");
650 		dmacc = 1;
651 	}
652 	if (!policy) {
653 		snprintf(resp, sizeof(resp),
654 			 "PolicyUpdateStatus,User entry not found");
655 		goto done;
656 	}
657 	if (policy[0] == '\0') {
658 		snprintf(resp, sizeof(resp),
659 			 "PolicyUpdateStatus,User was not configured to need policy update");
660 		goto done;
661 	}
662 
663 	sql = sqlite3_mprintf("UPDATE users SET polupd_done=0 WHERE %s=%Q",
664 			      (dmacc ? "osu_user" : "identity"),
665 			      username);
666 	if (!sql) {
667 		snprintf(resp, sizeof(resp),
668 			 "PolicyUpdateStatus,Internal error");
669 		goto done;
670 	}
671 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
672 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
673 		sigma_dut_print(dut, DUT_MSG_ERROR,
674 				"SQL operation to fetch user field failed: %s",
675 				sqlite3_errmsg(db));
676 		sqlite3_free(sql);
677 		goto done;
678 	}
679 	sqlite3_free(sql);
680 
681 	snprintf(resp, sizeof(resp), "PolicyUpdateStatus,TIMEOUT");
682 
683 	for (i = 0; i < timeout; i++) {
684 		sleep(1);
685 		free(policy);
686 		if (dmacc)
687 			policy = get_user_dmacc_field(dut, db, username,
688 						      "polupd_done");
689 		else
690 			policy = get_user_field(dut, db, username,
691 						"polupd_done");
692 		if (policy && atoi(policy)) {
693 			snprintf(resp, sizeof(resp),
694 				 "PolicyUpdateStatus,UpdateComplete");
695 			break;
696 		}
697 	}
698 
699 done:
700 	free(policy);
701 	sqlite3_close(db);
702 
703 	send_resp(dut, conn, SIGMA_COMPLETE, resp);
704 	return 0;
705 }
706 
707 
708 static int cmd_server_request_status(struct sigma_dut *dut,
709 				     struct sigma_conn *conn,
710 				     struct sigma_cmd *cmd)
711 {
712 	const char *var, *username, *serialno, *imsi, *addr, *status;
713 	int osu, timeout;
714 	char resp[500];
715 	enum sigma_program prog;
716 
717 	var = get_param(cmd, "Program");
718 	if (!var) {
719 		send_resp(dut, conn, SIGMA_ERROR,
720 			  "errorCode,Missing program parameter");
721 		return 0;
722 	}
723 
724 	prog = sigma_program_to_enum(var);
725 	if (prog != PROGRAM_HS2_R2 && prog != PROGRAM_HS2_R3) {
726 		send_resp(dut, conn, SIGMA_ERROR,
727 			  "errorCode,Unsupported program");
728 		return 0;
729 	}
730 
731 	var = get_param(cmd, "Device");
732 	if (!var ||
733 	    (strcasecmp(var, "AAAServer") != 0 &&
734 	     strcasecmp(var, "OSUServer") != 0)) {
735 		send_resp(dut, conn, SIGMA_ERROR,
736 			  "errorCode,Unsupported device type");
737 		return 0;
738 	}
739 	osu = strcasecmp(var, "OSUServer") == 0;
740 
741 	var = get_param(cmd, "Timeout");
742 	if (!var) {
743 		send_resp(dut, conn, SIGMA_ERROR,
744 			  "errorCode,Missing timeout");
745 		return 0;
746 	}
747 	timeout = atoi(var);
748 	sigma_dut_print(dut, DUT_MSG_DEBUG, "timeout: %d", timeout);
749 
750 	username = get_param(cmd, "UserName");
751 	if (username)
752 		sigma_dut_print(dut, DUT_MSG_DEBUG, "UserName: %s", username);
753 	serialno = get_param(cmd, "SerialNo");
754 	if (serialno)
755 		sigma_dut_print(dut, DUT_MSG_DEBUG, "SerialNo: %s", serialno);
756 	imsi = get_param(cmd, "imsi_val");
757 	if (imsi)
758 		sigma_dut_print(dut, DUT_MSG_DEBUG, "imsi_val: %s", imsi);
759 	addr = get_param(cmd, "ClientMACAddr");
760 	if (addr)
761 		sigma_dut_print(dut, DUT_MSG_DEBUG, "ClientMACAddr: %s", addr);
762 	status = get_param(cmd, "Status");
763 	if (status)
764 		sigma_dut_print(dut, DUT_MSG_DEBUG, "Status: %s", status);
765 
766 	if (osu && status && strcasecmp(status, "Remediation") == 0)
767 		return osu_remediation_status(dut, conn, timeout, username,
768 					      serialno);
769 
770 	if (osu && status && strcasecmp(status, "PolicyUpdate") == 0)
771 		return osu_polupd_status(dut, conn, timeout, username,
772 					 serialno);
773 
774 	if (!osu && status && strcasecmp(status, "Authentication") == 0 &&
775 	    username)
776 		return aaa_auth_status(dut, conn, cmd, username, timeout);
777 
778 	if (!osu && status && strcasecmp(status, "Authentication") == 0 &&
779 	    serialno) {
780 		snprintf(resp, sizeof(resp), "cert-%s", serialno);
781 		return aaa_auth_status(dut, conn, cmd, resp, timeout);
782 	}
783 
784 	if (osu && status && strcasecmp(status, "OSU") == 0 && addr)
785 		return osu_cert_enroll_status(dut, conn, cmd, addr, timeout);
786 
787 	return 1;
788 }
789 
790 
791 static int osu_set_cert_reenroll(struct sigma_dut *dut, const char *serial,
792 				 int enable)
793 {
794 	sqlite3 *db;
795 	char *sql;
796 	char id[100];
797 	int ret = -1;
798 
799 	if (sqlite3_open(SERVER_DB, &db)) {
800 		sigma_dut_print(dut, DUT_MSG_ERROR,
801 				"Failed to open SQLite database %s",
802 				SERVER_DB);
803 		return -1;
804 	}
805 
806 	snprintf(id, sizeof(id), "cert-%s", serial);
807 	sql = sqlite3_mprintf("UPDATE users SET remediation=%Q WHERE lower(identity)=lower(%Q)",
808 			      enable ? "reenroll" : "", id);
809 	if (!sql)
810 		goto fail;
811 	sigma_dut_print(dut, DUT_MSG_DEBUG, "SQL: %s", sql);
812 	if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) {
813 		sigma_dut_print(dut, DUT_MSG_ERROR, "SQL operation failed: %s",
814 				sqlite3_errmsg(db));
815 		goto fail;
816 	}
817 
818 	if (sqlite3_changes(db) < 1) {
819 		sigma_dut_print(dut, DUT_MSG_ERROR, "No DB rows modified (specified serial number not found)");
820 		goto fail;
821 	}
822 
823 	ret = 0;
824 fail:
825 	sqlite3_close(db);
826 
827 	return ret;
828 }
829 
830 
831 static int cmd_server_set_parameter(struct sigma_dut *dut,
832 				    struct sigma_conn *conn,
833 				    struct sigma_cmd *cmd)
834 {
835 	const char *var, *root_ca, *inter_ca, *osu_cert, *issuing_arch, *name;
836 	const char *reenroll, *serial;
837 	int osu, timeout = -1;
838 	enum sigma_program prog;
839 
840 	var = get_param(cmd, "Program");
841 	if (!var) {
842 		send_resp(dut, conn, SIGMA_ERROR,
843 			  "errorCode,Missing program parameter");
844 		return 0;
845 	}
846 
847 	prog = sigma_program_to_enum(var);
848 	if (prog != PROGRAM_HS2_R2 && prog != PROGRAM_HS2_R3) {
849 		send_resp(dut, conn, SIGMA_ERROR,
850 			  "errorCode,Unsupported program");
851 		return 0;
852 	}
853 
854 	var = get_param(cmd, "Device");
855 	if (!var ||
856 	    (strcasecmp(var, "AAAServer") != 0 &&
857 	     strcasecmp(var, "OSUServer") != 0)) {
858 		send_resp(dut, conn, SIGMA_ERROR,
859 			  "errorCode,Unsupported device type");
860 		return 0;
861 	}
862 	osu = strcasecmp(var, "OSUServer") == 0;
863 
864 	var = get_param(cmd, "Timeout");
865 	if (var)
866 		timeout = atoi(var);
867 
868 	var = get_param(cmd, "ProvisioningProto");
869 	if (var && strcasecmp(var, "SOAP") != 0) {
870 		send_resp(dut, conn, SIGMA_ERROR,
871 			  "errorCode,Unsupported ProvisioningProto");
872 		return 0;
873 	}
874 
875 	reenroll = get_param(cmd, "CertReEnroll");
876 	serial = get_param(cmd, "SerialNo");
877 	if (reenroll && serial) {
878 		int enable;
879 
880 		if (strcasecmp(reenroll, "Enable") == 0) {
881 			enable = 1;
882 		} else if (strcasecmp(reenroll, "Disable") == 0) {
883 			enable = 0;
884 		} else {
885 			send_resp(dut, conn, SIGMA_ERROR,
886 				  "errorCode,Invalid CertReEnroll value");
887 			return 0;
888 		}
889 
890 		if (osu_set_cert_reenroll(dut, serial, enable) < 0) {
891 			send_resp(dut, conn, SIGMA_ERROR,
892 				  "errorCode,Failed to update certificate reenrollment state");
893 			return 0;
894 		}
895 	}
896 
897 	name = get_param(cmd, "Name");
898 	root_ca = get_param(cmd, "TrustRootCACert");
899 	inter_ca = get_param(cmd, "InterCACert");
900 	osu_cert = get_param(cmd, "OSUServerCert");
901 	issuing_arch = get_param(cmd, "Issuing_Arch");
902 
903 	if (timeout > -1) {
904 		/* TODO */
905 	}
906 
907 	if (osu && name && root_ca && inter_ca && osu_cert && issuing_arch) {
908 		const char *srv;
909 		char buf[500];
910 		char buf2[500];
911 		int col;
912 
913 		sigma_dut_print(dut, DUT_MSG_DEBUG,
914 				"Update server certificate setup");
915 
916 		if (strcasecmp(name, "ruckus") == 0) {
917 			srv = "RKS";
918 		} else if (strcasecmp(name, "aruba") == 0) {
919 			srv = "ARU";
920 		} else {
921 			send_resp(dut, conn, SIGMA_ERROR,
922 				  "errorCode,Unsupported Name value");
923 			return 0;
924 		}
925 
926 		if (strcasecmp(issuing_arch, "col2") == 0) {
927 			col = 2;
928 		} else if (strcasecmp(issuing_arch, "col4") == 0) {
929 			col = 4;
930 		} else {
931 			send_resp(dut, conn, SIGMA_ERROR,
932 				  "errorCode,Unsupported Issuing_Arch value");
933 			return 0;
934 		}
935 
936 		if (strcasecmp(root_ca, "ID-T") == 0) {
937 			sigma_dut_print(dut, DUT_MSG_DEBUG,
938 					"OSU trust root: NetworkFX");
939 			if (system("cp " CERT_DIR "/IDT-cert-RootCA.pem "
940 				   CERT_DIR "/cacert.pem") < 0)
941 				return -2;
942 		} else if (strcasecmp(root_ca, "ID-Y") == 0) {
943 			sigma_dut_print(dut, DUT_MSG_DEBUG,
944 					"OSU trust root: NetworkFX");
945 			if (system("cp " CERT_DIR "/IDY-cert-RootCA.pem "
946 				   CERT_DIR "/cacert.pem") < 0)
947 				return -2;
948 		} else {
949 			send_resp(dut, conn, SIGMA_ERROR,
950 				  "errorCode,Unsupported TrustRootCACert value");
951 			return 0;
952 		}
953 
954 		if (strcasecmp(inter_ca, "ID-Z.2") == 0) {
955 			sigma_dut_print(dut, DUT_MSG_DEBUG,
956 					"OSU intermediate CA: NetworkFX (col2)");
957 			if (system("cat " CERT_DIR "/IDZ2-cert-InterCA.pem >> "
958 				   CERT_DIR "/cacert.pem") < 0)
959 				return -2;
960 		} else if (strcasecmp(inter_ca, "ID-Z.4") == 0) {
961 			sigma_dut_print(dut, DUT_MSG_DEBUG,
962 					"OSU intermediate CA: DigiCert (col2)");
963 			if (system("cat " CERT_DIR "/IDZ4-cert-InterCA.pem >> "
964 				   CERT_DIR "/cacert.pem") < 0)
965 				return -2;
966 		} else if (strcasecmp(inter_ca, "ID-Z.6") == 0) {
967 			sigma_dut_print(dut, DUT_MSG_DEBUG,
968 					"OSU intermediate CA: NetworkFX (col4)");
969 			if (system("cat " CERT_DIR "/IDZ6-cert-InterCA.pem >> "
970 				   CERT_DIR "/cacert.pem") < 0)
971 				return -2;
972 		} else if (strcasecmp(inter_ca, "ID-Z.8") == 0) {
973 			sigma_dut_print(dut, DUT_MSG_DEBUG,
974 					"OSU intermediate CA: DigiCert (col4)");
975 			if (system("cat " CERT_DIR "/IDZ8-cert-InterCA.pem >> "
976 				   CERT_DIR "/cacert.pem") < 0)
977 				return -2;
978 		} else {
979 			send_resp(dut, conn, SIGMA_ERROR,
980 				  "errorCode,Unsupported InterCACert value");
981 			return 0;
982 		}
983 
984 		if (strcasecmp(osu_cert, "ID-Q") == 0) {
985 			sigma_dut_print(dut, DUT_MSG_DEBUG,
986 					"OSU server cert: NetworkFX col%d",
987 					col);
988 			snprintf(buf, sizeof(buf),
989 				 "cp " CERT_DIR "/IDQ-cert-c%d-%s.pem "
990 				 CERT_DIR "/server.pem",
991 				 col, srv);
992 			snprintf(buf2, sizeof(buf2),
993 				 "cp " CERT_DIR "/IDQ-key-%s.pem "
994 				 CERT_DIR "/server.key", srv);
995 		} else if (strcasecmp(osu_cert, "ID-W") == 0) {
996 			sigma_dut_print(dut, DUT_MSG_DEBUG,
997 					"OSU server cert: DigiCert col%d",
998 					col);
999 			snprintf(buf, sizeof(buf),
1000 				 "cp " CERT_DIR "/IDW-cert-c%d-%s.pem "
1001 				 CERT_DIR "/server.pem",
1002 				 col, srv);
1003 			snprintf(buf2, sizeof(buf2),
1004 				 "cp " CERT_DIR "/IDW-key-%s.pem "
1005 				 CERT_DIR "/server.key", srv);
1006 		} else if (strcasecmp(osu_cert, "ID-R.2") == 0) {
1007 			sigma_dut_print(dut, DUT_MSG_DEBUG,
1008 					"OSU server cert: NetworkFX revoked col%d",
1009 					col);
1010 			snprintf(buf, sizeof(buf),
1011 				 "cp " CERT_DIR "/IDR2-cert-c%d-%s.pem "
1012 				 CERT_DIR "/server.pem",
1013 				 col, srv);
1014 			snprintf(buf2, sizeof(buf2),
1015 				 "cp " CERT_DIR "/IDR2-key-%s.pem "
1016 				 CERT_DIR "/server.key", srv);
1017 		} else if (strcasecmp(osu_cert, "ID-R.4") == 0) {
1018 			sigma_dut_print(dut, DUT_MSG_DEBUG,
1019 					"OSU server cert: DigiCert revoked col%d",
1020 					col);
1021 			snprintf(buf, sizeof(buf),
1022 				 "cp " CERT_DIR "/IDR4-cert-c%d-%s.pem "
1023 				 CERT_DIR "/server.pem",
1024 				 col, srv);
1025 			snprintf(buf2, sizeof(buf2),
1026 				 "cp " CERT_DIR "/IDR4-key-%s.pem "
1027 				 CERT_DIR "/server.key", srv);
1028 		} else {
1029 			send_resp(dut, conn, SIGMA_ERROR,
1030 				  "errorCode,Unsupported OSUServerCert value");
1031 			return 0;
1032 		}
1033 
1034 		if (system(buf) < 0 || system(buf2) < 0)
1035 			return -2;
1036 
1037 		if (system("service apache2 reload") < 0) {
1038 			send_resp(dut, conn, SIGMA_ERROR,
1039 				  "errorCode,Failed to restart Apache");
1040 			return 0;
1041 		}
1042 	}
1043 
1044 	/* TODO */
1045 	return 1;
1046 }
1047 
1048 
1049 void server_register_cmds(void)
1050 {
1051 	sigma_dut_reg_cmd("server_ca_get_version", NULL,
1052 			  cmd_server_ca_get_version);
1053 	sigma_dut_reg_cmd("server_get_info", NULL,
1054 			  cmd_server_get_info);
1055 	sigma_dut_reg_cmd("server_reset_default", NULL,
1056 			  cmd_server_reset_default);
1057 	sigma_dut_reg_cmd("server_request_status", NULL,
1058 			  cmd_server_request_status);
1059 	sigma_dut_reg_cmd("server_set_parameter", NULL,
1060 			  cmd_server_set_parameter);
1061 }
1062