diff --git a/hs20/server/spp_server.c b/hs20/server/spp_server.c index 51c1d9638..c3681ee0c 100644 --- a/hs20/server/spp_server.c +++ b/hs20/server/spp_server.c @@ -57,19 +57,26 @@ static int db_add_session(struct hs20_svc *ctx, const char *user, const char *realm, const char *sessionid, const char *pw, const char *redirect_uri, - enum hs20_session_operation operation) + enum hs20_session_operation operation, + const u8 *mac_addr) { char *sql; int ret = 0; + char addr[20]; + if (mac_addr) + snprintf(addr, sizeof(addr), MACSTR, MAC2STR(mac_addr)); + else + addr[0] = '\0'; sql = sqlite3_mprintf("INSERT INTO sessions(timestamp,id,user,realm," - "operation,password,redirect_uri) " + "operation,password,redirect_uri,mac_addr) " "VALUES " "(strftime('%%Y-%%m-%%d %%H:%%M:%%f','now')," - "%Q,%Q,%Q,%d,%Q,%Q)", + "%Q,%Q,%Q,%d,%Q,%Q,%Q)", sessionid, user ? user : "", realm ? realm : "", operation, pw ? pw : "", - redirect_uri ? redirect_uri : ""); + redirect_uri ? redirect_uri : "", + addr); if (sql == NULL) return -1; debug_print(ctx, 1, "DB: %s", sql); @@ -742,7 +749,7 @@ static xml_node_t * build_sub_rem_resp(struct hs20_svc *ctx, debug_print(ctx, 1, "Request DB password update on success " "notification"); db_add_session(ctx, user, realm, session_id, new_pw, NULL, - UPDATE_PASSWORD); + UPDATE_PASSWORD, NULL); } return spp_node; @@ -771,7 +778,7 @@ static xml_node_t * policy_remediation(struct hs20_svc *ctx, "requires policy remediation", NULL); db_add_session(ctx, user, realm, session_id, NULL, NULL, - POLICY_REMEDIATION); + POLICY_REMEDIATION, NULL); policy = build_policy(ctx, user, realm, dmacc); if (!policy) { @@ -844,7 +851,7 @@ static xml_node_t * user_remediation(struct hs20_svc *ctx, const char *user, return NULL; db_add_session(ctx, user, realm, session_id, NULL, redirect_uri, - USER_REMEDIATION); + USER_REMEDIATION, NULL); snprintf(uri, sizeof(uri), "%s%s", val, session_id); os_free(val); @@ -866,7 +873,7 @@ static xml_node_t * free_remediation(struct hs20_svc *ctx, return NULL; db_add_session(ctx, user, realm, session_id, NULL, redirect_uri, - FREE_REMEDIATION); + FREE_REMEDIATION, NULL); snprintf(uri, sizeof(uri), "%s%s", val, session_id); os_free(val); @@ -1033,7 +1040,8 @@ static xml_node_t * hs20_policy_update(struct hs20_svc *ctx, "No update available at this time", NULL); } - db_add_session(ctx, user, realm, session_id, NULL, NULL, POLICY_UPDATE); + db_add_session(ctx, user, realm, session_id, NULL, NULL, POLICY_UPDATE, + NULL); status = "Update complete, request sppUpdateResponse"; spp_node = build_post_dev_data_response(ctx, &ns, session_id, status, @@ -1146,14 +1154,15 @@ static xml_node_t * spp_exec_upload_mo(struct hs20_svc *ctx, static xml_node_t * hs20_subscription_registration(struct hs20_svc *ctx, const char *realm, const char *session_id, - const char *redirect_uri) + const char *redirect_uri, + const u8 *mac_addr) { xml_namespace_t *ns; xml_node_t *spp_node, *exec_node; char uri[300], *val; if (db_add_session(ctx, NULL, realm, session_id, NULL, redirect_uri, - SUBSCRIPTION_REGISTRATION) < 0) + SUBSCRIPTION_REGISTRATION, mac_addr) < 0) return NULL; val = db_get_osu_config_val(ctx, realm, "signup_url"); if (val == NULL) @@ -1606,11 +1615,12 @@ static xml_node_t * hs20_spp_post_dev_data(struct hs20_svc *ctx, char *req_reason_buf = NULL; char str[200]; xml_node_t *ret = NULL, *devinfo = NULL, *devdetail = NULL; - xml_node_t *mo; + xml_node_t *mo, *macaddr; char *version; int valid; char *supp, *pos; char *err; + u8 wifi_mac_addr[ETH_ALEN]; version = xml_node_get_attr_value_ns(ctx->xml, node, SPP_NS_URI, "sppVersion"); @@ -1716,6 +1726,29 @@ static xml_node_t * hs20_spp_post_dev_data(struct hs20_svc *ctx, goto out; } os_free(err); + + os_memset(wifi_mac_addr, 0, ETH_ALEN); + macaddr = get_node(ctx->xml, devdetail, + "Ext/org.wi-fi/Wi-Fi/Wi-FiMACAddress"); + if (macaddr) { + char *addr, buf[50]; + + addr = xml_node_get_text(ctx->xml, macaddr); + if (addr && hwaddr_compact_aton(addr, wifi_mac_addr) == 0) { + snprintf(buf, sizeof(buf), "DevDetail MAC address: " + MACSTR, MAC2STR(wifi_mac_addr)); + hs20_eventlog(ctx, user, realm, session_id, buf, NULL); + xml_node_get_text_free(ctx->xml, addr); + } else { + hs20_eventlog(ctx, user, realm, session_id, + "Could not extract MAC address from DevDetail", + NULL); + } + } else { + hs20_eventlog(ctx, user, realm, session_id, + "No MAC address in DevDetail", NULL); + } + if (user) db_update_mo(ctx, user, realm, "devdetail", devdetail); @@ -1762,7 +1795,7 @@ static xml_node_t * hs20_spp_post_dev_data(struct hs20_svc *ctx, else oper = NO_OPERATION; if (db_add_session(ctx, user, realm, session_id, NULL, - NULL, oper) < 0) + NULL, oper, NULL) < 0) goto out; ret = spp_exec_upload_mo(ctx, session_id, @@ -1799,7 +1832,8 @@ static xml_node_t * hs20_spp_post_dev_data(struct hs20_svc *ctx, if (strcasecmp(req_reason, "Subscription registration") == 0) { ret = hs20_subscription_registration(ctx, realm, session_id, - redirect_uri); + redirect_uri, + wifi_mac_addr); hs20_eventlog_node(ctx, user, realm, session_id, "subscription registration response", ret); @@ -1948,13 +1982,15 @@ static int add_subscription(struct hs20_svc *ctx, const char *session_id) goto out; } - sql = sqlite3_mprintf("INSERT INTO users(identity,realm,phase2," - "methods,cert,cert_pem,machine_managed) VALUES " - "(%Q,%Q,1,%Q,%Q,%Q,%d)", + str = db_get_session_val(ctx, NULL, NULL, session_id, "mac_addr"); + + sql = sqlite3_mprintf("INSERT INTO users(identity,realm,phase2,methods,cert,cert_pem,machine_managed,mac_addr) VALUES (%Q,%Q,1,%Q,%Q,%Q,%d,%Q)", user, realm, cert ? "TLS" : "TTLS-MSCHAPV2", fingerprint ? fingerprint : "", cert_pem ? cert_pem : "", - pw_mm && atoi(pw_mm) ? 1 : 0); + pw_mm && atoi(pw_mm) ? 1 : 0, + str ? str : ""); + free(str); if (sql == NULL) goto out; debug_print(ctx, 1, "DB: %s", sql); @@ -1996,6 +2032,32 @@ static int add_subscription(struct hs20_svc *ctx, const char *session_id) free(str); } + if (cert && user) { + const char *serialnum; + + str = db_get_session_val(ctx, NULL, NULL, session_id, + "mac_addr"); + + if (os_strncmp(user, "cert-", 5) == 0) + serialnum = user + 5; + else + serialnum = ""; + sql = sqlite3_mprintf("INSERT OR REPLACE INTO cert_enroll (mac_addr,user,realm,serialnum) VALUES(%Q,%Q,%Q,%Q)", + str ? str : "", user, realm ? realm : "", + serialnum); + free(str); + if (sql) { + debug_print(ctx, 1, "DB: %s", sql); + if (sqlite3_exec(ctx->db, sql, NULL, NULL, NULL) != + SQLITE_OK) { + debug_print(ctx, 1, + "Failed to add cert_enroll entry into sqlite database: %s", + sqlite3_errmsg(ctx->db)); + } + sqlite3_free(sql); + } + } + if (ret == 0) { hs20_eventlog(ctx, user, realm, session_id, "completed subscription registration", NULL); diff --git a/hs20/server/sql.txt b/hs20/server/sql.txt index 74d9f4aa2..2ecd9c23c 100644 --- a/hs20/server/sql.txt +++ b/hs20/server/sql.txt @@ -22,7 +22,8 @@ CREATE TABLE sessions( devinfo TEXT, devdetail TEXT, cert TEXT, - cert_pem TEXT + cert_pem TEXT, + mac_addr TEXT ); CREATE index sessions_id_index ON sessions(id); @@ -51,7 +52,8 @@ CREATE TABLE users( shared INTEGER, cert TEXT, cert_pem TEXT, - t_c_timestamp INTEGER + t_c_timestamp INTEGER, + mac_addr TEXT ); CREATE TABLE wildcards( @@ -81,3 +83,10 @@ CREATE TABLE current_sessions( waiting_coa_ack BOOLEAN, coa_ack_received BOOLEAN ); + +CREATE TABLE cert_enroll( + mac_addr TEXT PRIMARY KEY, + user TEXT, + realm TEXT, + serialnum TEXT +); diff --git a/hs20/server/www/users.php b/hs20/server/www/users.php index c2653727c..b6c62980b 100644 --- a/hs20/server/www/users.php +++ b/hs20/server/www/users.php @@ -314,7 +314,7 @@ echo "[Eventlog] "; echo "
\n"; echo "\n"; -echo "
UserRealmRemediationPolicyAccount typePhase 2 method(s)DevIdT&C\n"; +echo "
UserRealmRemediationPolicyAccount typePhase 2 method(s)DevIdMAC AddressT&C\n"; $res = $db->query('SELECT rowid,* FROM users WHERE phase2=1'); foreach ($res as $row) { @@ -349,6 +349,7 @@ foreach ($res as $row) { break; } } + echo "" . $row['mac_addr']; echo "" . $row['t_c_timestamp']; echo "\n"; }