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