Skip to content

Commit

Permalink
feat: add local auth pass
Browse files Browse the repository at this point in the history
Signed-off-by: Dengfeng Liu <[email protected]>
  • Loading branch information
liudf0716 committed Sep 3, 2024
1 parent 550b1ea commit 7bb175f
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 21 deletions.
5 changes: 0 additions & 5 deletions src/client_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,6 @@ static t_offline_client *first_offline_client = NULL;
*/
static volatile unsigned long long client_id = 1;

/**
* Mutex to protect client_id and guarantee uniqueness.
*/
static pthread_mutex_t client_id_mutex = PTHREAD_MUTEX_INITIALIZER;

/** Global mutex to protect access to the client list */
pthread_mutex_t client_list_mutex = PTHREAD_MUTEX_INITIALIZER;

Expand Down
8 changes: 8 additions & 0 deletions src/conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ typedef enum {
oAuthServWsScriptPathFragment,
oAuthServerOfflineFile,
oInternetOfflineFile,
oLocalPortal,
oHTTPDMaxConn,
oHTTPDName,
oHTTPDRealm,
Expand Down Expand Up @@ -165,6 +166,7 @@ static const struct {
"wsscriptpathfragment", oAuthServWsScriptPathFragment}, {
"authserverofflinefile", oAuthServerOfflineFile}, {
"internetofflinefile", oInternetOfflineFile}, {
"localportal", oLocalPortal}, {
"firewallruleset", oFirewallRuleSet}, {
"firewallrule", oFirewallRule}, {
"trustedmaclist", oTrustedMACList}, {
Expand Down Expand Up @@ -273,6 +275,7 @@ config_init(void)
config.htmlredirfile = safe_strdup(DEFAULT_REDIRECTFILE);
config.internet_offline_file = safe_strdup(DEFAULT_INTERNET_OFFLINE_FILE);
config.authserver_offline_file = safe_strdup(DEFAULT_AUTHSERVER_OFFLINE_FILE);
config.local_portal = safe_strdup(DEFAULT_LOCAL_PORTAL);
config.js_redir = 1; // default enable it
config.wired_passed = 1; // default wired device no need login
config.parse_checked = 1; // before parse domain's ip; fping check it
Expand Down Expand Up @@ -1148,6 +1151,11 @@ config_read()
free(config.internet_offline_file);
config.internet_offline_file = safe_strdup(p1);
break;
case oLocalPortal:
if (config.local_portal)
free(config.local_portal);
config.local_portal = safe_strdup(p1);
break;
case oBadOption:
/* FALL THROUGH */
default:
Expand Down
2 changes: 2 additions & 0 deletions src/conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#define DEFAULT_SYSLOG_FACILITY LOG_DAEMON
#define DEFAULT_WDCTL_SOCK "/tmp/wdctl.sock"
#define DEFAULT_INTERNAL_SOCK "/tmp/wifidog.sock"
#define DEFAULT_LOCAL_PORTAL "http://www.wifidogx.online"
#define DEFAULT_AUTHSERVPORT 80
#define DEFAULT_AUTHSERVSSLPORT 443
/** Note that DEFAULT_AUTHSERVSSLAVAILABLE must be 0 or 1, even if the config file syntax is yes or no */
Expand Down Expand Up @@ -303,6 +304,7 @@ typedef struct {
char *htmlredirfile;
char *internet_offline_file;
char *authserver_offline_file;
char *local_portal;
short wired_passed; /** 1 wired device no need to auth */
short parse_checked;
short js_redir; /** boolean, whether to enable javascript to redirect url request to auth server */
Expand Down
22 changes: 7 additions & 15 deletions src/fw4_nft.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,12 +478,6 @@ nft_fw_del_rule_by_ip_and_mac(const char *ip, const char *mac, const char *chain
int
nft_fw_access(fw_access_t type, const char *ip, const char *mac, int tag)
{
// according to type, if type is FW_ACCESS_ALLOW, set the firewall rules to allow the client
// if type is FW_ACCESS_DENY, set the firewall rules to deny the client

// the rules are as the following:
// add rule inet fw4 mangle_prerouting_wifidogx_outgoing ether saddr ab:23:23:ab:23:23 ip saddr
// add rule inet fw4 mangle_postrouting_wifidogx_incoming ether saddr ab:23:23:ab:23:23 ip saddr
switch(type) {
case FW_ACCESS_ALLOW:
run_cmd("nft add rule inet fw4 mangle_prerouting_wifidogx_outgoing ether saddr %s ip saddr %s counter mark set 0x20000 accept", mac, ip);
Expand Down Expand Up @@ -512,27 +506,25 @@ nft_fw_reload_client(int tag)
return 1;
}

// open the file /tmp/nftables_wifidogx_client_list
// define the file /tmp/nftables_wifidogx_client_list as NFT_WIFIDOGX_CLIENT_LIST
FILE *fp = fopen(NFT_WIFIDOGX_CLIENT_LIST, "w");
if (fp == NULL) {
debug(LOG_ERR, "Failed to open %s", NFT_WIFIDOGX_CLIENT_LIST);
return 1;
}
// flush the rules in the chain mangle_prerouting_wifidogx_outgoing
fprintf(fp, "nft flush chain inet fw4 mangle_prerouting_wifidogx_outgoing\n");
// flush the rules in the chain mangle_postrouting_wifidogx_incoming
fprintf(fp, "nft flush chain inet fw4 mangle_postrouting_wifidogx_incoming\n");
// iterate the client_list

t_client *current = first_client;
char line[256] = {0};
do {
snprintf(line, sizeof(line), "nft add rule inet fw4 mangle_prerouting_wifidogx_outgoing ether saddr %s ip saddr %s counter mark set 0x%02x0000/0xff0000 accept\n", current->mac, current->ip, tag&0x000000ff);
// write the line to the file /tmp/nftables_wifidogx_client_list
snprintf(line, sizeof(line),
"nft add rule inet fw4 mangle_prerouting_wifidogx_outgoing ether saddr %s ip saddr %s counter mark set 0x%02x0000/0xff0000 accept\n",
current->mac, current->ip, tag&0x000000ff);
fprintf(fp, "%s", line);
memset(line, 0, sizeof(line));
snprintf(line, sizeof(line), "nft add rule inet fw4 mangle_postrouting_wifidogx_incoming ip daddr %s counter accept\n", current->ip);
// write the line to the file /tmp/nftables_wifidogx_client_list
snprintf(line, sizeof(line),
"nft add rule inet fw4 mangle_postrouting_wifidogx_incoming ip daddr %s counter accept\n",
current->ip);
fprintf(fp, "%s", line);
memset(line, 0, sizeof(line));
current = current->next;
Expand Down
3 changes: 2 additions & 1 deletion src/gateway.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ threads_init(s_config *config)
debug(LOG_INFO, "No auth server available, not starting the following threads");
return;
}

/* Start heartbeat thread */
result = pthread_create(&tid_ping, NULL, (void *)thread_ping, NULL);
if (result != 0) {
Expand Down Expand Up @@ -510,6 +510,7 @@ http_redir_loop(s_config *config)
evhttp_set_cb(http, "/wifidog/auth", ev_http_callback_auth, request_ctx);
//evhttp_set_cb(http, "/wifidog/disconnect", ev_http_callback_disconnect, request_ctx);
evhttp_set_cb(http, "/wifidog/temporary_pass", ev_http_callback_temporary_pass, NULL);
evhttp_set_cb(http, "/wifidog/local_auth", ev_http_callback_local_auth, NULL);

evhttp_set_gencb(http, ev_http_callback_404, NULL);

Expand Down
39 changes: 39 additions & 0 deletions src/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include "wd_util.h"
#include "version.h"
#include "wd_client.h"
#include "fw_iptables.h"

#define APPLE_REDIRECT_MSG "<!DOCTYPE html>" \
"<html>" \
Expand Down Expand Up @@ -544,6 +545,44 @@ ev_http_callback_disconnect(struct evhttp_request *req, void *arg)
}
}

/**
* @brief process client's local pass request
*
* @param req Client's http request
* @param arg useless
*
*/
void
ev_http_callback_local_auth(struct evhttp_request *req, void *arg)
{
s_config *config = config_get_config();
if (config->auth_servers) {
evhttp_send_error(req, HTTP_OK, "Only no auth server configured can use local pass");
return;
}

// get the ip and mac of the client
const char *mac = ev_http_find_query(req, "mac");
const char *ip = ev_http_find_query(req, "ip");
if (!mac || !ip) {
evhttp_send_error(req, HTTP_OK, "MAC and IP need to be specified");
goto END;
}

// fw_allow the client
LOCK_CLIENT_LIST();
iptables_fw_access(FW_ACCESS_ALLOW, ip, mac, 0);
UNLOCK_CLIENT_LIST();

// redirect the client to the internet
ev_http_send_redirect(req, config->local_portal, "Redirect to internet");

END:
if (mac) free((void *)mac);
if (ip) free((void *)ip);
}


/**
* @brief Temporaray allow client to access internet a minute
*
Expand Down
2 changes: 2 additions & 0 deletions src/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,6 @@ void ev_http_replay_wisper(struct evhttp_request *);
/** @brief get query's value according to key */
char *ev_http_find_query(struct evhttp_request *, const char *);

void ev_http_callback_local_auth(struct evhttp_request *, void *);

#endif /* _HTTP_H_ */

0 comments on commit 7bb175f

Please sign in to comment.