Create necessary table and index where this doesn't exist. Select attributes from the table keyed by station MAC address and request type (auth or acct), parse and apply to a RADIUS message. Signed-off-by: Terry Burton <tez@xxxxxxxxxxxxxxxxx> --- src/ap/ap_config.h | 1 + src/ap/hostapd.c | 35 +++++++++++++++++++++++++ src/ap/hostapd.h | 8 ++++++ src/ap/ieee802_1x.c | 64 +++++++++++++++++++++++++++++++++++++++++++++ src/ap/ieee802_1x.h | 6 +++++ 5 files changed, 114 insertions(+) diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 8b66c8455..2e2e6e4a3 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -301,6 +301,7 @@ struct hostapd_bss_config { int radius_request_cui; struct hostapd_radius_attr *radius_auth_req_attr; struct hostapd_radius_attr *radius_acct_req_attr; + char *radius_req_attr_sqlite; int radius_das_port; unsigned int radius_das_time_window; int radius_das_require_event_timestamp; diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index cc75a7765..4d6a1f945 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -7,6 +7,9 @@ */ #include "utils/includes.h" +#ifdef CONFIG_SQLITE +#include <sqlite3.h> +#endif /* CONFIG_SQLITE */ #include "utils/common.h" #include "utils/eloop.h" @@ -1025,6 +1028,38 @@ hostapd_das_coa(void *ctx, struct radius_das_attrs *attr) #define hostapd_das_coa NULL #endif /* CONFIG_HS20 */ +#ifdef CONFIG_SQLITE +static int db_table_exists(sqlite3 *db, const char *name) +{ + char cmd[128]; + + os_snprintf(cmd, sizeof(cmd), "SELECT 1 FROM %s;", name); + return sqlite3_exec(db, cmd, NULL, NULL, NULL) == SQLITE_OK; +} + + +static int db_table_create_radius_attributes(sqlite3 *db) +{ + char *err = NULL; + const char *sql = + "CREATE TABLE radius_attributes(" + " id INTEGER PRIMARY KEY," + " sta TEXT," + " reqtype TEXT," + " attr TEXT" + ");" + "CREATE INDEX idx_sta_reqtype ON radius_attributes(sta,reqtype);"; + wpa_printf(MSG_DEBUG, "Adding database table for RADIUS attribute information"); + if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) { + wpa_printf(MSG_ERROR, "SQLite error: %s", err); + sqlite3_free(err); + return -1; + } + + return 0; +} +#endif /* CONFIG_SQLITE */ + #endif /* CONFIG_NO_RADIUS */ diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index d90bae4e6..9cfb7d6bc 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -9,6 +9,10 @@ #ifndef HOSTAPD_H #define HOSTAPD_H +#ifdef CONFIG_SQLITE +#include <sqlite3.h> +#endif /* CONFIG_SQLITE */ + #include "common/defs.h" #include "utils/list.h" #include "ap_config.h" @@ -390,6 +394,10 @@ struct hostapd_data { #endif /* CONFIG_AIRTIME_POLICY */ u8 last_1x_eapol_key_replay_counter[8]; + +#ifdef CONFIG_SQLITE + sqlite3 *rad_attr_db; +#endif /* CONFIG_SQLITE */ }; diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c index d62864136..4630bf85c 100644 --- a/src/ap/ieee802_1x.c +++ b/src/ap/ieee802_1x.c @@ -7,6 +7,9 @@ */ #include "utils/includes.h" +#ifdef CONFIG_SQLITE +#include <sqlite3.h> +#endif /* CONFIG_SQLITE */ #include "utils/common.h" #include "utils/eloop.h" @@ -615,6 +618,67 @@ int add_common_radius_attr(struct hostapd_data *hapd, } +int add_sqlite_radius_attr(struct hostapd_data *hapd, + struct sta_info *sta, + struct radius_msg *msg, + RadiusType msg_type) +{ +#ifdef CONFIG_SQLITE + const char *attrtxt; + char addrtxt[3 * ETH_ALEN]; + char *sql; + + if (!hapd->rad_attr_db) + return -1; + + os_snprintf(addrtxt, sizeof(addrtxt), MACSTR, MAC2STR(sta->addr)); + + sql = "SELECT attr FROM radius_attributes WHERE sta=? AND " + "(reqtype=? OR reqtype IS NULL);"; + sqlite3_stmt *stmt = NULL; + if (sqlite3_prepare_v2(hapd->rad_attr_db, sql, os_strlen(sql), &stmt, + NULL) != SQLITE_OK) { + wpa_printf(MSG_ERROR, + "DB: Failed to prepare SQL statement: %s", + sqlite3_errmsg(hapd->rad_attr_db)); + return -1; + } + sqlite3_bind_text(stmt, 1, addrtxt, os_strlen(addrtxt), SQLITE_STATIC); + sqlite3_bind_text(stmt, 2, msg_type == RADIUS_AUTH ? "auth" : "acct", 4, + SQLITE_STATIC); + while (sqlite3_step(stmt) == SQLITE_ROW) + { + struct hostapd_radius_attr *attr = NULL; + attrtxt = (char *) sqlite3_column_text(stmt, 0); + attr = hostapd_parse_radius_attr(attrtxt); + if (attr == NULL) { + wpa_printf(MSG_ERROR, "Skipping invalid attribute from " + "SQL: %s", + attrtxt); + continue; + } + wpa_printf(MSG_DEBUG, "Adding RADIUS attribute from SQL: %s", + attrtxt); + if (!radius_msg_add_attr(msg, attr->type, + wpabuf_head(attr->val), + wpabuf_len(attr->val))) { + wpa_printf(MSG_ERROR, "Could not add RADIUS attribute " + "from SQL"); + continue; + } + } + + sqlite3_reset(stmt); + sqlite3_clear_bindings(stmt); + sqlite3_finalize(stmt); + stmt = NULL; + +#endif /* CONFIG_SQLITE */ + + return 0; +} + + void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd, struct sta_info *sta, const u8 *eap, size_t len) diff --git a/src/ap/ieee802_1x.h b/src/ap/ieee802_1x.h index d771ba526..8e6e60fcf 100644 --- a/src/ap/ieee802_1x.h +++ b/src/ap/ieee802_1x.h @@ -9,6 +9,8 @@ #ifndef IEEE802_1X_H #define IEEE802_1X_H +#include "radius/radius_client.h" + struct hostapd_data; struct sta_info; struct eapol_state_machine; @@ -59,6 +61,10 @@ int add_common_radius_attr(struct hostapd_data *hapd, struct hostapd_radius_attr *req_attr, struct sta_info *sta, struct radius_msg *msg); +int add_sqlite_radius_attr(struct hostapd_data *hapd, + struct sta_info *sta, + struct radius_msg *msg, + RadiusType msg_type); void ieee802_1x_encapsulate_radius(struct hostapd_data *hapd, struct sta_info *sta, const u8 *eap, size_t len); -- 2.20.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap