Add Support for ThemeSpecPath, FasCustomParametersList, FasCustomVariablesList, FasCustomImagesList

Signed-off-by: rob <rob@blue-wave.net>
This commit is contained in:
rob
2021-04-12 20:11:51 +01:00
parent 69a3941599
commit 2838810cd5
4 changed files with 275 additions and 67 deletions

View File

@@ -84,6 +84,7 @@ typedef enum {
oFasURL,
oFasSSL,
oLoginOptionEnabled,
oThemeSpecPath,
oAllowLegacySplash,
oUseOutdatedMHD,
oUnescapeCallbackEnabled,
@@ -121,7 +122,9 @@ typedef enum {
oPreAuth,
oWalledGardenFqdnList,
oWalledGardenPortList,
oFasCustomParametersList
oFasCustomParametersList,
oFasCustomVariablesList,
oFasCustomImagesList
} OpCodes;
/** @internal
@@ -150,6 +153,7 @@ static const struct {
{ "fasurl", oFasURL },
{ "fasssl", oFasSSL },
{ "login_option_enabled", oLoginOptionEnabled },
{ "themespec_path", oThemeSpecPath },
{ "allow_legacy_splash", oAllowLegacySplash },
{ "use_outdated_mhd", oUseOutdatedMHD },
{ "unescape_callback_enabled", oUnescapeCallbackEnabled },
@@ -188,6 +192,8 @@ static const struct {
{ "walledgarden_fqdn_list", oWalledGardenFqdnList },
{ "walledgarden_port_list", oWalledGardenPortList },
{ "fas_custom_parameters_list", oFasCustomParametersList },
{ "fas_custom_variables_list", oFasCustomVariablesList },
{ "fas_custom_images_list", oFasCustomImagesList },
{ NULL, oBadOption },
};
@@ -236,6 +242,7 @@ config_init(void)
config.fas_port = DEFAULT_FASPORT;
config.fas_key = safe_strdup(DEFAULT_FASKEY);
config.login_option_enabled = DEFAULT_LOGIN_OPTION_ENABLED;
config.themespec_path = NULL;
config.allow_legacy_splash = DEFAULT_ALLOW_LEGACY_SPLASH;
config.use_outdated_mhd = DEFAULT_USE_OUTDATED_MHD;
config.unescape_callback_enabled = DEFAULT_UNESCAPE_CALLBACK_ENABLED;
@@ -246,6 +253,8 @@ config_init(void)
config.fas_ssl = NULL;
config.fas_hid = NULL;
config.custom_params = NULL;
config.custom_vars = NULL;
config.custom_images = NULL;
config.fas_path = DEFAULT_FASPATH;
config.webroot = safe_strdup(DEFAULT_WEBROOT);
config.splashpage = safe_strdup(DEFAULT_SPLASHPAGE);
@@ -824,6 +833,15 @@ config_read(const char *filename)
exit(1);
}
break;
case oThemeSpecPath:
config.themespec_path = safe_strdup(p1);
if (!((stat(p1, &sb) == 0) && S_ISREG(sb.st_mode) && (sb.st_mode & S_IXUSR))) {
debug(LOG_ERR, "ThemeSpec program does not exist or is not executeable: %s", p1);
debug(LOG_ERR, "Exiting...");
exit(1);
}
debug(LOG_NOTICE, "Added ThemeSpec [%s]", p1);
break;
case oAllowLegacySplash:
if (sscanf(p1, "%d", &config.allow_legacy_splash) < 1) {
debug(LOG_ERR, "Bad arg %s to option %s on line %d in %s", p1, s, linenum, filename);
@@ -904,6 +922,12 @@ config_read(const char *filename)
case oFasCustomParametersList:
parse_fas_custom_parameters_list(p1);
break;
case oFasCustomVariablesList:
parse_fas_custom_variables_list(p1);
break;
case oFasCustomImagesList:
parse_fas_custom_images_list(p1);
break;
case oMACmechanism:
if (!strcasecmp("allow", p1)) {
config.macmechanism = MAC_ALLOW;
@@ -1167,6 +1191,40 @@ int add_to_fas_custom_parameters_list(const char possibleparam[])
return 0;
}
int add_to_fas_custom_variables_list(const char possiblevar[])
{
char var[128];
t_FASVAR *p = NULL;
sscanf(possiblevar, "%s", var);
// Add Variable to head of list
p = safe_malloc(sizeof(t_FASVAR));
p->fasvar = safe_strdup(var);
p->next = config.fas_custom_variables_list;
config.fas_custom_variables_list = p;
debug(LOG_NOTICE, "Added Custom Variable [%s]", possiblevar);
return 0;
}
int add_to_fas_custom_images_list(const char possibleimage[])
{
char image[128];
t_FASIMG *p = NULL;
sscanf(possibleimage, "%s", image);
// Add Image to head of list
p = safe_malloc(sizeof(t_FASIMG));
p->fasimg = safe_strdup(image);
p->next = config.fas_custom_images_list;
config.fas_custom_images_list = p;
debug(LOG_NOTICE, "Added Custom Image [%s]", possibleimage);
return 0;
}
int add_to_trusted_mac_list(const char possiblemac[])
{
char mac[18];
@@ -1614,7 +1672,7 @@ void parse_fas_custom_parameters_list(const char ptr[])
debug(LOG_DEBUG, "[%s] is the urlencoded Custom FAS Parameter", possibleparam_urlencoded);
safe_asprintf(&cmd,
"echo \"%s\" | awk -F'%s' 'NF==2 && $1!=\"\" && $2!=\"\" {printf \"%s\",$0}'",
"echo \"%s\" | awk -F'%s' 'NF>1 && $1!=\"\" && $2!=\"\" {printf \"%s\",$0}'",
possibleparam_urlencoded,
CUSTOM_SEPARATOR,
FORMAT_SPECIFIER
@@ -1633,6 +1691,94 @@ void parse_fas_custom_parameters_list(const char ptr[])
}
}
/* Given a pointer to a comma or whitespace delimited sequence of
* Custom FAS Variables, add each parameter to config.fas_custom_variables_list
*/
void parse_fas_custom_variables_list(const char ptr[])
{
char *ptrcopy = NULL;
char *possiblevar = NULL;
char msg[128] = {0};
char *cmd = NULL;
char possiblevar_urlencoded[256] = {0};
debug(LOG_INFO, "Parsing list [%s] for Custom FAS Variables", ptr);
// strsep modifies original, so let's make a copy
ptrcopy = safe_strdup(ptr);
while ((possiblevar = strsep(&ptrcopy, ", \t"))) {
if (strlen(possiblevar) > 0) {
// URL encode Variable before parsing
memset(possiblevar_urlencoded, 0, sizeof(possiblevar_urlencoded));
uh_urlencode(possiblevar_urlencoded, sizeof(possiblevar_urlencoded), possiblevar, strlen(possiblevar));
debug(LOG_DEBUG, "[%s] is the urlencoded Custom FAS Variable", possiblevar_urlencoded);
safe_asprintf(&cmd,
"echo \"%s\" | awk -F'%s' 'NF>1 && $1!=\"\" && $2!=\"\" {printf \"%s\",$0}'",
possiblevar_urlencoded,
CUSTOM_SEPARATOR,
FORMAT_SPECIFIER
);
debug(LOG_DEBUG, "Parse command [%s]", cmd);
memset(msg, 0, sizeof(msg));
execute_ret_url_encoded(msg, sizeof(msg) - 1, cmd);
free(cmd);
if (strcmp(msg, possiblevar_urlencoded) == 0) {
debug(LOG_INFO, "Adding variable [%s] [%s]", possiblevar, msg);
add_to_fas_custom_variables_list(possiblevar);
} else {
debug(LOG_WARNING, "Invalid Custom Variable [%s] [%s] - skipping", possiblevar, msg);
}
}
}
}
/* Given a pointer to a comma or whitespace delimited sequence of
* Custom FAS Images, add each image to config.fas_custom_images_list
*/
void parse_fas_custom_images_list(const char ptr[])
{
char *ptrcopy = NULL;
char *possibleimage = NULL;
char msg[128] = {0};
char *cmd = NULL;
char possibleimage_urlencoded[256] = {0};
debug(LOG_INFO, "Parsing list [%s] for Custom FAS Images", ptr);
// strsep modifies original, so let's make a copy
ptrcopy = safe_strdup(ptr);
while ((possibleimage = strsep(&ptrcopy, ", \t"))) {
if (strlen(possibleimage) > 0) {
// URL encode Image before parsing
memset(possibleimage_urlencoded, 0, sizeof(possibleimage_urlencoded));
uh_urlencode(possibleimage_urlencoded, sizeof(possibleimage_urlencoded), possibleimage, strlen(possibleimage));
debug(LOG_DEBUG, "[%s] is the urlencoded Custom FAS Image", possibleimage_urlencoded);
safe_asprintf(&cmd,
"echo \"%s\" | awk -F'%s' 'NF>1 && $1!=\"\" && $2!=\"\" {printf \"%s\",$0}'",
possibleimage_urlencoded,
CUSTOM_SEPARATOR,
FORMAT_SPECIFIER
);
debug(LOG_DEBUG, "Parse command [%s]", cmd);
memset(msg, 0, sizeof(msg));
execute_ret_url_encoded(msg, sizeof(msg) - 1, cmd);
free(cmd);
if (strcmp(msg, possibleimage_urlencoded) == 0) {
debug(LOG_INFO, "Adding image [%s] [%s]", possibleimage, msg);
add_to_fas_custom_images_list(possibleimage);
} else {
debug(LOG_WARNING, "Invalid Custom Image [%s] [%s] - skipping", possibleimage, msg);
}
}
}
}
/** Set the debug log level. See syslog.h
* Return 0 on success.

View File

@@ -153,74 +153,92 @@ typedef struct _FASPARAM_t {
struct _FASPARAM_t *next;
} t_FASPARAM;
// Custom FAS Variables
typedef struct _FASVAR_t {
char *fasvar;
struct _FASVAR_t *next;
} t_FASVAR;
// Custom FAS Images
typedef struct _FASIMG_t {
char *fasimg;
struct _FASIMG_t *next;
} t_FASIMG;
// Configuration structure
typedef struct {
char configfile[255]; //@brief name of the config file
char *ndsctl_sock; //@brief ndsctl path to socket
char *internal_sock; //@brief internal path to socket
int daemon; //@brief if daemon > 0, use daemon mode
char configfile[255]; //@brief name of the config file
char *ndsctl_sock; //@brief ndsctl path to socket
char *internal_sock; //@brief internal path to socket
int daemon; //@brief if daemon > 0, use daemon mode
int debuglevel; //@brief Debug information verbosity
int maxclients; //@brief Maximum number of clients allowed
char *gw_name; //@brief Name of the gateway; e.g. its SSID or a unique identifier for use in a remote FAS
char *http_encoded_gw_name; //@brief http encoded name of the gateway, used as a templated variable in splash.htm
char *url_encoded_gw_name; //@brief url encoded name of the gateway used as variable in Preauth
char *gw_interface; //@brief Interface we will manage
char *gw_iprange; //@brief IP range on gw_interface we will manage
char *gw_ip; //@brief Internal IP (v4 or v6) for our web server
char *gw_address; //@brief Internal IP with port for our web server
char *gw_mac; //@brief MAC address of the interface we manage
char *gw_fqdn; //@brief FQDN of the client status page
unsigned int gw_port; //@brief Port the webserver will run on
unsigned int fas_port; //@brief Port the fas server will run on
int login_option_enabled; //@brief Use default PreAuth Login script
int allow_legacy_splash; //@brief Allow use of legacy html splash page
int use_outdated_mhd; //@brief Use outdated libmicrohttpd
int unescape_callback_enabled; //@brief Enable external MHD unescape callback script
char *gw_name; //@brief Name of the gateway; e.g. its SSID or a unique identifier for use in a remote FAS
char *http_encoded_gw_name; //@brief http encoded name of the gateway, used as a templated variable in splash.htm
char *url_encoded_gw_name; //@brief url encoded name of the gateway used as variable in Preauth
char *gw_interface; //@brief Interface we will manage
char *gw_iprange; //@brief IP range on gw_interface we will manage
char *gw_ip; //@brief Internal IP (v4 or v6) for our web server
char *gw_address; //@brief Internal IP with port for our web server
char *gw_mac; //@brief MAC address of the interface we manage
char *gw_fqdn; //@brief FQDN of the client status page
unsigned int gw_port; //@brief Port the webserver will run on
unsigned int fas_port; //@brief Port the fas server will run on
int login_option_enabled; //@brief Use default PreAuth Login script
int allow_legacy_splash; //@brief Allow use of legacy html splash page
int use_outdated_mhd; //@brief Use outdated libmicrohttpd
int unescape_callback_enabled; //@brief Enable external MHD unescape callback script
int fas_secure_enabled; //@brief Enable Secure FAS
char *fas_path; //@brief Path to forward authentication page of FAS
char *fas_key; //@brief AES key for FAS
char *fas_remoteip; //@brief IP addess of a remote FAS
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
char *redirectURL; //@brief URL to direct client to after authentication
char *authdir; //@brief Notional relative dir for authentication URL
char *denydir; //@brief Notional relative dir for denial URL
char *preauthdir; //@brief Notional relative dir for preauth URL
int session_timeout; //@brief Minutes of the default session length
int preauth_idle_timeout; //@brief Minutes a preauthenticated client will be kept in the system
int auth_idle_timeout; //@brief Minutes an authenticated client will be kept in the system
int checkinterval; //@brief Period the the client timeout check thread will run, in seconds
int set_mss; //@brief boolean, whether to set mss
int mss_value; //@brief int, mss value; <= 0 clamp to pmtu
int traffic_control; //@brief boolean, whether to do tc
int rate_check_window; //@brief window size in multiples of checkinterval for rate check moving average
unsigned long long int download_rate; //@brief Download rate, kb/s
unsigned long long int upload_rate; //@brief Upload rate, kb/s
unsigned long long int download_quota; //@brief Download quota, kB
unsigned long long int upload_quota; //@brief Upload quota, kB
char *fas_key; //@brief AES key for FAS
char *fas_remoteip; //@brief IP addess of a remote FAS
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 *themespec_path; //@brief Path to the ThemeSpec file to use for login_option_enabled = 3
char *webroot; //@brief Directory containing splash pages, etc.
char *splashpage; //@brief Name of main splash page
char *statuspage; //@brief Name of info status page
char *redirectURL; //@brief URL to direct client to after authentication
char *authdir; //@brief Notional relative dir for authentication URL
char *denydir; //@brief Notional relative dir for denial URL
char *preauthdir; //@brief Notional relative dir for preauth URL
int session_timeout; //@brief Minutes of the default session length
int preauth_idle_timeout; //@brief Minutes a preauthenticated client will be kept in the system
int auth_idle_timeout; //@brief Minutes an authenticated client will be kept in the system
int checkinterval; //@brief Period the the client timeout check thread will run, in seconds
int set_mss; //@brief boolean, whether to set mss
int mss_value; //@brief int, mss value; <= 0 clamp to pmtu
int traffic_control; //@brief boolean, whether to do tc
int rate_check_window; //@brief window size in multiples of checkinterval for rate check moving average
unsigned long long int download_rate; //@brief Download rate, kb/s
unsigned long long int upload_rate; //@brief Upload rate, kb/s
unsigned long long int download_quota; //@brief Download quota, kB
unsigned long long int upload_quota; //@brief Upload quota, kB
int upload_ifb; //@brief Number of IFB handling upload
int log_syslog; //@brief boolean, whether to log to syslog
int syslog_facility; //@brief facility to use when using syslog for logging
int macmechanism; //@brief mechanism wrt MAC addrs
t_firewall_ruleset *rulesets; //@brief firewall rules
t_MAC *trustedmaclist; //@brief list of trusted macs
t_MAC *blockedmaclist; //@brief list of blocked macs
t_MAC *allowedmaclist; //@brief list of allowed macs
t_WGP *walledgarden_port_list; //@brief list of Walled Garden Ports
t_WGFQDN *walledgarden_fqdn_list; //@brief list of Walled Garden FQDNs
int syslog_facility; //@brief facility to use when using syslog for logging
int macmechanism; //@brief mechanism wrt MAC addrs
t_firewall_ruleset *rulesets; //@brief firewall rules
t_MAC *trustedmaclist; //@brief list of trusted macs
t_MAC *blockedmaclist; //@brief list of blocked macs
t_MAC *allowedmaclist; //@brief list of allowed macs
t_WGP *walledgarden_port_list; //@brief list of Walled Garden Ports
t_WGFQDN *walledgarden_fqdn_list; //@brief list of Walled Garden FQDNs
t_FASPARAM *fas_custom_parameters_list; //@brief list of Custom FAS parameters
char *custom_params; //@brief FAS custom parameter string
unsigned int fw_mark_authenticated; //@brief iptables mark for authenticated packets
unsigned int fw_mark_blocked; //@brief iptables mark for blocked packets
unsigned int fw_mark_trusted; //@brief iptables mark for trusted packets
int ip6; //@brief enable IPv6
char *binauth; //@brief external authentication program
char *preauth; //@brief external preauthentication program
t_FASVAR *fas_custom_variables_list; //@brief list of Custom FAS variables
t_FASIMG *fas_custom_images_list; //@brief list of Custom FAS images
char *custom_params; //@brief FAS custom parameter string
char *custom_vars; //@brief FAS custom variable string
char *custom_images; //@brief FAS custom image string
unsigned int fw_mark_authenticated; //@brief iptables mark for authenticated packets
unsigned int fw_mark_blocked; //@brief iptables mark for blocked packets
unsigned int fw_mark_trusted; //@brief iptables mark for trusted packets
int ip6; //@brief enable IPv6
char *binauth; //@brief external authentication program
char *preauth; //@brief external preauthentication program
} s_config;
// @brief Get the current gateway configuration
@@ -259,6 +277,8 @@ void parse_allowed_mac_list(const char[]);
void parse_walledgarden_fqdn_list(const char[]);
void parse_walledgarden_port_list(const char[]);
void parse_fas_custom_parameters_list(const char[]);
void parse_fas_custom_variables_list(const char[]);
void parse_fas_custom_images_list(const char[]);
int is_blocked_mac(const char *mac);
int is_allowed_mac(const char *mac);

View File

@@ -1103,7 +1103,7 @@ static char *construct_querystring(t_client *client, char *originurl, char *quer
debug(LOG_INFO, "clientif: [%s] url_encoded_gw_name: [%s]", clientif, config->url_encoded_gw_name);
snprintf(query_str, QUERYMAXLEN,
"clientip=%s%sclientmac=%s%sgatewayname=%s%sversion=%s%shid=%s%sgatewayaddress=%s%sgatewaymac=%s%sauthdir=%s%soriginurl=%s%sclientif=%s%s%s",
"clientip=%s%sclientmac=%s%sgatewayname=%s%sversion=%s%shid=%s%sgatewayaddress=%s%sgatewaymac=%s%sauthdir=%s%soriginurl=%s%sclientif=%s%sthemespec=%s%s%s%s%s",
client->ip, QUERYSEPARATOR,
client->mac, QUERYSEPARATOR,
config->url_encoded_gw_name, QUERYSEPARATOR,
@@ -1113,9 +1113,11 @@ static char *construct_querystring(t_client *client, char *originurl, char *quer
config->gw_mac, QUERYSEPARATOR,
config->authdir, QUERYSEPARATOR,
originurl, QUERYSEPARATOR,
clientif,
QUERYSEPARATOR,
config->custom_params
clientif, QUERYSEPARATOR,
config->themespec_path, QUERYSEPARATOR,
config->custom_params,
config->custom_vars,
config->custom_images
);
b64_encode(query_str_b64, sizeof(query_str_b64), query_str, strlen(query_str));
@@ -1139,7 +1141,7 @@ static char *construct_querystring(t_client *client, char *originurl, char *quer
get_client_interface(clientif, sizeof(clientif), client->mac);
debug(LOG_INFO, "clientif: [%s]", clientif);
snprintf(querystr, QUERYMAXLEN,
"clientip=%s%sclientmac=%s%sgatewayname=%s%sversion=%s%shid=%s%sgatewayaddress=%s%sgatewaymac=%s%sauthdir=%s%soriginurl=%s%sclientif=%s%s%s",
"clientip=%s%sclientmac=%s%sgatewayname=%s%sversion=%s%shid=%s%sgatewayaddress=%s%sgatewaymac=%s%sauthdir=%s%soriginurl=%s%sclientif=%s%sthemespec=%s%s%s%s%s",
client->ip, QUERYSEPARATOR,
client->mac, QUERYSEPARATOR,
config->url_encoded_gw_name, QUERYSEPARATOR,
@@ -1150,7 +1152,10 @@ static char *construct_querystring(t_client *client, char *originurl, char *quer
config->authdir, QUERYSEPARATOR,
originurl, QUERYSEPARATOR,
clientif, QUERYSEPARATOR,
config->custom_params
config->themespec_path, QUERYSEPARATOR,
config->custom_params,
config->custom_vars,
config->custom_images
);
} else {

View File

@@ -347,6 +347,43 @@ setup_from_config(void)
debug(LOG_DEBUG, "Custom FAS parameter string [%s]", config->custom_params);
}
// Setup custom FAS variables if configured
char fasvar[512] = {0};
t_FASVAR *fas_fasvar;
if (config->fas_custom_parameters_list) {
for (fas_fasvar = config->fas_custom_variables_list; fas_fasvar != NULL; fas_fasvar = fas_fasvar->next) {
// Make sure we don't have a buffer overflow
if ((sizeof(fasvar) - strlen(fasvar)) > (strlen(fas_fasvar->fasvar) + 4)) {
strcat(fasvar, fas_fasvar->fasvar);
strcat(fasvar, QUERYSEPARATOR);
} else {
break;
}
}
config->custom_vars = safe_strdup(fasvar);
debug(LOG_DEBUG, "Custom FAS variables string [%s]", config->custom_vars);
}
// Setup custom FAS images if configured
char fasimage[512] = {0};
t_FASIMG *fas_fasimage;
if (config->fas_custom_images_list) {
for (fas_fasimage = config->fas_custom_images_list; fas_fasimage != NULL; fas_fasimage = fas_fasimage->next) {
// Make sure we don't have a buffer overflow
if ((sizeof(fasimage) - strlen(fasimage)) > (strlen(fas_fasimage->fasimg) + 4)) {
strcat(fasimage, fas_fasimage->fasimg);
strcat(fasimage, QUERYSEPARATOR);
} else {
break;
}
}
config->custom_images = safe_strdup(fasimage);
debug(LOG_DEBUG, "Custom FAS images string [%s]", config->custom_images);
}
if (config->gw_fqdn || config->walledgarden_fqdn_list) {
// For Client status Page - configure the hosts file
if (config->gw_fqdn) {