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