Skip to content

Commit

Permalink
Merge pull request #435 from nodogsplash/4.2.1beta
Browse files Browse the repository at this point in the history
FAS: Introduce hash_id mode.
  • Loading branch information
bluewavenet committed Sep 22, 2019
2 parents ce413ea + 22637a4 commit 15333b1
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 33 deletions.
28 changes: 13 additions & 15 deletions forward_authentication_service/PreAuth/demo-preauth.sh
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#!/bin/sh
#Copyright © The Nodogsplash Contributors 2004-2019
#Copyright © Blue Wave Projects and Services 2015-2019
#Copyright (C) The Nodogsplash Contributors 2004-2019
#Copyright (C) Blue Wave Projects and Services 2015-2019
#This software is released under the GNU GPL license.

# Get the urlencoded querystring and user_agent
query_enc="$1"
user_agent_enc="$2"

# The query string is sent to us from NDS in a urlencoded form,
# so we must decode it here so we can parse it:
query=$(printf "${query_enc//%/\\x}")
# we can decode it or parts of it using something like the following:
# query=$(printf "${query_enc//%/\\x}")

# The User Agent string is sent urlencoded also:
user_agent=$(printf "${user_agent_enc//%/\\x}")
Expand Down Expand Up @@ -64,19 +64,16 @@ user_agent=$(printf "${user_agent_enc//%/\\x}")


# Parse for the system variables always sent by NDS:
clientip="$(echo $query | awk -F ', ' '{print $1;}' | awk -F 'clientip=' '{print $2;}')"
gatewayname="$(echo $query | awk -F ', ' '{print $2;}' | awk -F 'gatewayname=' '{print $2;}')"
queryvarlist="clientip gatewayname hid redir status username emailaddr"

# The third system variable is either the originally requested url:
requested="$(echo $query | awk -F ', ' '{print $3;}' | awk -F 'redir=' '{print $2;}')"

# or it is a status message:
status="$(echo $query | awk -F ', ' '{print $3;}' | awk -F 'status=' '{print $2;}')"

# Parse for additional variables we define in this script, in this case username and emailaddr
username="$(echo $query | awk -F ', ' '{print $4;}' | awk -F 'username=' '{print $2;}')"
emailaddr="$(echo $query | awk -F ', ' '{print $5;}' | awk -F 'emailaddr=' '{print $2;}')"
for var in $queryvarlist; do
eval $var=$(echo "$query_enc" | awk -F "$var%3d" '{print $2}' | awk -F "%2c%20" '{print $1}')
done

# URL decode vars that need it:
requested=$(printf "${redir//%/\\x}")
username=$(printf "${username//%/\\x}")
emailaddr=$(printf "${emailaddr//%/\\x}")

# Define some common html as the first part of the page to be served by NDS
#
Expand Down Expand Up @@ -138,6 +135,7 @@ login_form="
<form action=\"/nodogsplash_preauth/\" method=\"get\">
<input type=\"hidden\" name=\"clientip\" value=\"$clientip\">
<input type=\"hidden\" name=\"gatewayname\" value=\"$gatewayname\">
<input type=\"hidden\" name=\"hid\" value=\"$hid\">
<input type=\"hidden\" name=\"redir\" value=\"$requested\">
<input type=\"text\" name=\"username\" value=\"$username\" autocomplete=\"on\" ><br>Name<br><br>
<input type=\"email\" name=\"emailaddr\" value=\"$emailaddr\" autocomplete=\"on\" ><br>Email<br><br>
Expand Down
1 change: 1 addition & 0 deletions src/conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ config_init(void)
config.fas_remotefqdn = NULL;
config.fas_url = NULL;
config.fas_ssl = NULL;
config.fas_hid = NULL;
config.fas_path = DEFAULT_FASPATH;
config.webroot = safe_strdup(DEFAULT_WEBROOT);
config.splashpage = safe_strdup(DEFAULT_SPLASHPAGE);
Expand Down
1 change: 1 addition & 0 deletions src/conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ typedef struct {
char *fas_remotefqdn; /**< @brief FQDN of a remote FAS */
char *fas_url; /**< @brief URL of a remote FAS */
char *fas_ssl; /**< @brief SSL provider for FAS */
char *fas_hid; /**< @brief Hash provider for FAS */
char *webroot; /**< @brief Directory containing splash pages, etc. */
char *splashpage; /**< @brief Name of main splash page */
char *statuspage; /**< @brief Name of info status page */
Expand Down
72 changes: 56 additions & 16 deletions src/http_microhttpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static int serve_file(struct MHD_Connection *connection, t_client *client, const
static int show_splashpage(struct MHD_Connection *connection, t_client *client);
static int show_statuspage(struct MHD_Connection *connection, t_client *client);
static int show_preauthpage(struct MHD_Connection *connection, const char *query);
static int encode_and_redirect_to_splashpage(struct MHD_Connection *connection, const char *originurl, const char *querystr);
static int encode_and_redirect_to_splashpage(struct MHD_Connection *connection, t_client *client, const char *originurl, const char *querystr);
static int redirect_to_splashpage(struct MHD_Connection *connection, t_client *client, const char *host, const char *url);
static int send_error(struct MHD_Connection *connection, int error);
static int send_redirect_temp(struct MHD_Connection *connection, const char *url);
Expand Down Expand Up @@ -406,6 +406,9 @@ static int try_to_authenticate(struct MHD_Connection *connection, t_client *clie
{
s_config *config;
const char *tok;
char hid[128] = {0};
char rhid[128] = {0};
char *rhidraw = NULL;

/* a successful auth looks like
* http://192.168.42.1:2050/nodogsplash_auth/?redir=http%3A%2F%2Fberlin.freifunk.net%2F&tok=94c4cdd2
Expand All @@ -418,9 +421,23 @@ static int try_to_authenticate(struct MHD_Connection *connection, t_client *clie
tok = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "tok");
debug(LOG_DEBUG, "client->token=%s tok=%s ", client->token, tok );

if (tok && !strcmp(client->token, tok)) {
/* Token is valid */
return 1;
//Check if token (tok) or hash_id (hid) mode
if (strlen(tok) > 8) {
// hid mode
hash_str(hid, sizeof(hid), client->token);
safe_asprintf(&rhidraw, "%s%s", hid, config->fas_key);
hash_str(rhid, sizeof(rhid), rhidraw);
free (rhidraw);
if (tok && !strcmp(rhid, tok)) {
/* rhid is valid */
return 1;
}
} else {
// tok mode
if (tok && !strcmp(client->token, tok)) {
/* Token is valid */
return 1;
}
}
}

Expand Down Expand Up @@ -475,7 +492,7 @@ static int authenticate_client(struct MHD_Connection *connection,
debug(LOG_DEBUG, "redirect_url_enc after binauth deny: %s", redirect_url_enc);

querystr=construct_querystring(client, redirect_url_enc, querystr);
ret = encode_and_redirect_to_splashpage(connection, redirect_url_enc, querystr);
ret = encode_and_redirect_to_splashpage(connection, client, redirect_url_enc, querystr);
return ret;
}
rc = auth_client_auth(client->id, "client_auth");
Expand Down Expand Up @@ -643,10 +660,11 @@ static int preauthenticated(struct MHD_Connection *connection,
{
const char *host = NULL;
const char *redirect_url;
char *querystr = NULL;
char query_str[QUERYMAXLEN] = {0};
char *query = query_str;
char *querystr = query_str;
char portstr[MAX_HOSTPORTLEN] = {0};
char originurl[QUERYMAXLEN] = {0};

int ret;
s_config *config = config_get_config();
Expand Down Expand Up @@ -683,7 +701,7 @@ static int preauthenticated(struct MHD_Connection *connection,
debug(LOG_DEBUG, "Preauthenticated - splash.css or authdir detected");
} else {
if (strstr(host, portstr) != NULL) {
debug(LOG_DEBUG, "Preauthenticated - 403 Direct Access Fobidden");
debug(LOG_DEBUG, "Preauthenticated - 403 Direct Access Forbidden");
ret = send_error(connection, 403);
return ret;
}
Expand Down Expand Up @@ -721,7 +739,9 @@ static int preauthenticated(struct MHD_Connection *connection,

if (!try_to_authenticate(connection, client, host, url)) {
/* user used an invalid token, redirect to splashpage but hold query "redir" intact */
return encode_and_redirect_to_splashpage(connection, redirect_url, querystr);
uh_urlencode(originurl, sizeof(originurl), redirect_url, strlen(redirect_url));
querystr=construct_querystring(client, originurl, querystr);
return encode_and_redirect_to_splashpage(connection, client, originurl, querystr);
}

return authenticate_client(connection, redirect_url, client);
Expand All @@ -742,7 +762,7 @@ static int preauthenticated(struct MHD_Connection *connection,
* @param originurl
* @return
*/
static int encode_and_redirect_to_splashpage(struct MHD_Connection *connection, const char *originurl, const char *querystr)
static int encode_and_redirect_to_splashpage(struct MHD_Connection *connection, t_client *client, const char *originurl, const char *querystr)
{
char msg[QUERYMAXLEN] = {0};
char *splashpageurl = NULL;
Expand All @@ -759,8 +779,8 @@ static int encode_and_redirect_to_splashpage(struct MHD_Connection *connection,
safe_asprintf(&splashpageurl, "%s?authaction=http://%s/%s/%s&redir=%s",
config->fas_url, config->gw_address, config->authdir, querystr, originurl);
} else if (config->fas_secure_enabled == 1) {
safe_asprintf(&splashpageurl, "%s%s&redir=%s",
config->fas_url, querystr, originurl);
safe_asprintf(&splashpageurl, "%s%s&redir=%s",
config->fas_url, querystr, originurl);
} else if (config->fas_secure_enabled == 2) {
safe_asprintf(&phpcmd,
"echo '<?php \n"
Expand Down Expand Up @@ -799,7 +819,7 @@ static int encode_and_redirect_to_splashpage(struct MHD_Connection *connection,
config->gw_address, config->splashpage, originurl);
}

debug(LOG_DEBUG, "splashpageurl: %s", splashpageurl);
debug(LOG_INFO, "splashpageurl: %s", splashpageurl);

ret = send_redirect_temp(connection, splashpageurl);
free(splashpageurl);
Expand Down Expand Up @@ -838,7 +858,7 @@ static int redirect_to_splashpage(struct MHD_Connection *connection, t_client *c
debug(LOG_DEBUG, "originurl: %s", originurl);

querystr=construct_querystring(client, originurl, querystr);
ret = encode_and_redirect_to_splashpage(connection, originurl, querystr);
ret = encode_and_redirect_to_splashpage(connection, client, originurl, querystr);
free(originurl_raw);
return ret;
}
Expand All @@ -850,12 +870,23 @@ static int redirect_to_splashpage(struct MHD_Connection *connection, t_client *c
*/
static char *construct_querystring(t_client *client, char *originurl, char *querystr ) {

char hash[128] = {0};

s_config *config = config_get_config();

if (config->fas_secure_enabled == 0) {
snprintf(querystr, QUERYMAXLEN, "?clientip=%s&gatewayname=%s&tok=%s", client->ip, config->gw_name, client->token);

} else if (config->fas_secure_enabled == 1) {
snprintf(querystr, QUERYMAXLEN, "?clientip=%s&gatewayname=%s", client->ip, config->gw_name);

if (config->fas_hid) {
hash_str(hash, sizeof(hash), client->token);
debug(LOG_INFO, "hid=%s", hash);
snprintf(querystr, QUERYMAXLEN, "?clientip=%s&gatewayname=%s&hid=%s", client->ip, config->gw_name, hash);
} else {
snprintf(querystr, QUERYMAXLEN, "?clientip=%s&gatewayname=%s", client->ip, config->gw_name);
}

} else if (config->fas_secure_enabled == 2) {
snprintf(querystr, QUERYMAXLEN,
"clientip=%s%sclientmac=%s%sgatewayname=%s%stok=%s%sgatewayaddress=%s%sauthdir=%s%soriginurl=%s",
Expand All @@ -866,6 +897,7 @@ static char *construct_querystring(t_client *client, char *originurl, char *quer
config->gw_address, QUERYSEPARATOR,
config->authdir, QUERYSEPARATOR,
originurl);

} else {
snprintf(querystr, QUERYMAXLEN, "?clientip=%s&gatewayname=%s", client->ip, config->gw_name);
}
Expand Down Expand Up @@ -901,15 +933,23 @@ int send_redirect_temp(struct MHD_Connection *connection, const char *url)
char *redirect = NULL;

const char *redirect_body = "<html><head></head><body><a href='%s'>Click here to continue to<br>%s</a></body></html>";

safe_asprintf(&redirect, redirect_body, url, url);

response = MHD_create_response_from_buffer(strlen(redirect), redirect, MHD_RESPMEM_MUST_FREE);
response = MHD_create_response_from_buffer(strlen(redirect), redirect, MHD_RESPMEM_MUST_COPY);
free (redirect);

if (!response) {
return send_error(connection, 503);
}

// MHD_set_response_options(response, MHD_RF_HTTP_VERSION_1_0_ONLY, MHD_RO_END);
MHD_add_response_header(response, "Location", url);
ret = MHD_add_response_header(response, "Location", url);

if (ret == MHD_NO) {
debug(LOG_DEBUG, "Error adding Location header");
}

MHD_add_response_header(response, "Connection", "close");
ret = MHD_queue_response(connection, MHD_HTTP_TEMPORARY_REDIRECT, response);
MHD_destroy_response(response);
Expand Down
18 changes: 16 additions & 2 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ main_loop(void)
char msg[255] = {0};
char *fasurl = NULL;
char *fasssl = NULL;
char *fashid = NULL;
char *phpcmd = NULL;
char *preauth_dir = NULL;
time_t sysuptime;
Expand Down Expand Up @@ -284,7 +285,6 @@ main_loop(void)
//override all other FAS settings
config->fas_remoteip = safe_strdup(config->gw_ip);
config->fas_remotefqdn = NULL;
config->fas_key = NULL;
config->fas_port = config->gw_port;
safe_asprintf(&preauth_dir, "/%s/", config->preauthdir);
config->fas_path = safe_strdup(preauth_dir);
Expand All @@ -310,7 +310,21 @@ main_loop(void)
}
}

if (config->fas_key) {
if (config->fas_key && config->fas_secure_enabled == 1) {
/* Check sha256sum command is available */
if (execute_ret_url_encoded(msg, sizeof(msg) - 1, "printf 'test' | sha256sum") == 0) {
safe_asprintf(&fashid, "sha256sum");
debug(LOG_NOTICE, "sha256sum provider is available");
} else {
debug(LOG_ERR, "sha256sum provider not available - please install package to provide it");
debug(LOG_ERR, "Exiting...");
exit(1);
}
config->fas_hid = safe_strdup(fashid);
free(fashid);
}

if (config->fas_key && config->fas_secure_enabled == 2) {
/* PHP cli command can be php or php-cli depending on Linux version. */
if (execute_ret(msg, sizeof(msg) - 1, "php -v") == 0) {
safe_asprintf(&fasssl, "php");
Expand Down
21 changes: 21 additions & 0 deletions src/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,27 @@ extern int created_httpd_threads;
extern int current_httpd_threads;


int hash_str(char* hash, int hash_len, const char *src)
{
char *hashcmd = NULL;

s_config *config = config_get_config();

safe_asprintf(&hashcmd, "printf '%s' | %s | awk -F' ' '{printf $1}'", src, config->fas_hid);

if (execute_ret_url_encoded(hash, hash_len - 1, hashcmd) == 0) {
debug(LOG_DEBUG, "Source string: %s", src);
debug(LOG_DEBUG, "Hashed string: %s", hash);
} else {
debug(LOG_ERR, "Failed to hash string");
free (hashcmd);
return -1;
}
free (hashcmd);
return 0;
}


static int _execute_ret(char* msg, int msg_len, const char *cmd)
{
struct sigaction sa, oldsa;
Expand Down
5 changes: 5 additions & 0 deletions src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,19 @@ int is_addr(const char* addr);
/* @brief Returns System Uptime in seconds */
time_t get_system_uptime();

/* @brief Returns the hash of a string */
int hash_str(char *buf, int hash_len, const char *src);

/*
* @brief Mallocs and returns nodogsplash uptime string
*/
char *get_uptime_string(char buf[64]);

/*
* @brief Writes a human-readable paragraph of the status of the nodogsplash process
*/
void ndsctl_status(FILE *fp);

/*
* @brief Writes a machine-readable dump of currently connected clients
*/
Expand Down

0 comments on commit 15333b1

Please sign in to comment.