Merge pull request #701 from openNDS/10.4.0beta

10.4.0beta
This commit is contained in:
Rob White
2025-06-20 08:27:09 +01:00
committed by GitHub
22 changed files with 448 additions and 200 deletions

View File

@@ -104,14 +104,14 @@ click_to_continue() {
#########################################
# Set length of session in minutes (eg 24 hours is 1440 minutes - if set to 0 then defaults to global sessiontimeout value):
# eg for 100 mins:
# session_length="100"
# sessiontimeout="100"
#
# eg for 20 hours:
# session_length=$((20*60))
# sessiontimeout=$((20*60))
#
# eg for 20 hours and 30 minutes:
# session_length=$((20*60+30))
session_length="0"
# sessiontimeout=$((20*60+30))
sessiontimeout="0"
# Set Rate and Quota values for the client
# The session length, rate and quota values could be determined by this script, on a per client basis.
@@ -121,7 +121,7 @@ download_rate="0"
upload_quota="0"
download_quota="0"
quotas="$session_length $upload_rate $download_rate $upload_quota $download_quota"
quotas="$sessiontimeout $upload_rate $download_rate $upload_quota $download_quota"
# Define the list of Parameters we expect to be sent sent from openNDS ($ndsparamlist):
# Note you can add custom parameters to the config file and to read them you must also add them here.

View File

@@ -130,7 +130,7 @@ check_voucher() {
# "Punch" the voucher by setting the timestamp to now
voucher_expiration=$(($current_time + $voucher_time_limit * 60))
# Override session length according to voucher
session_length=$voucher_time_limit
sessiontimeout=$voucher_time_limit
sed -i -r "s/($voucher.*,)(0)/\1$current_time/" $voucher_roll
return 0
else
@@ -142,7 +142,7 @@ check_voucher() {
time_remaining=$(( ($voucher_expiration - $current_time) / 60 ))
#echo "Voucher is still valid - You have $time_remaining minutes left <br>"
# Override session length according to voucher
session_length=$time_remaining
sessiontimeout=$time_remaining
# Nothing to change in the roll
return 0
else
@@ -169,7 +169,7 @@ voucher_validation() {
#echo "Voucher is Valid, click Continue to finish login<br>"
# Refresh quotas with ones imported from the voucher roll.
quotas="$session_length $upload_rate $download_rate $upload_quota $download_quota"
quotas="$sessiontimeout $upload_rate $download_rate $upload_quota $download_quota"
# Set voucher used (useful if for accounting reasons you track who received which voucher)
userinfo="$title - $voucher"
@@ -185,7 +185,7 @@ voucher_validation() {
</big-red>
<hr>
</p>
This voucher is valid for $session_length minutes.
This voucher is valid for $sessiontimeout minutes.
<hr>
<p>
<italic-black>
@@ -451,14 +451,14 @@ display_terms() {
#########################################
# Set length of session in minutes (eg 24 hours is 1440 minutes - if set to 0 then defaults to global sessiontimeout value):
# eg for 100 mins:
# session_length="100"
# sessiontimeout="100"
#
# eg for 20 hours:
# session_length=$((20*60))
# sessiontimeout=$((20*60))
#
# eg for 20 hours and 30 minutes:
# session_length=$((20*60+30))
session_length="0"
# sessiontimeout=$((20*60+30))
sessiontimeout="0"
# Set Rate and Quota values for the client
# The session length, rate and quota values could be determined by this script, on a per client basis.
@@ -468,7 +468,7 @@ download_rate="0"
upload_quota="0"
download_quota="0"
quotas="$session_length $upload_rate $download_rate $upload_quota $download_quota"
quotas="$sessiontimeout $upload_rate $download_rate $upload_quota $download_quota"
# Define the list of Parameters we expect to be sent sent from openNDS ($ndsparamlist):
# Note you can add custom parameters to the config file and to read them you must also add them here.

View File

@@ -415,14 +415,14 @@ display_terms() {
#########################################
# Set length of session in minutes (eg 24 hours is 1440 minutes - if set to 0 then defaults to global sessiontimeout value):
# eg for 100 mins:
# session_length="100"
# sessiontimeout="100"
#
# eg for 20 hours:
# session_length=$((20*60))
# sessiontimeout=$((20*60))
#
# eg for 20 hours and 30 minutes:
# session_length=$((20*60+30))
session_length="0"
# sessiontimeout=$((20*60+30))
sessiontimeout="0"
# Set Rate and Quota values for the client
# The session length, rate and quota values could be determined by this script, on a per client basis.
@@ -432,7 +432,7 @@ download_rate="0"
upload_quota="0"
download_quota="0"
quotas="$session_length $upload_rate $download_rate $upload_quota $download_quota"
quotas="$sessiontimeout $upload_rate $download_rate $upload_quota $download_quota"
# Define the list of Parameters we expect to be sent sent from openNDS ($ndsparamlist):
# Note you can add custom parameters to the config file and to read them you must also add them here.

View File

@@ -470,14 +470,14 @@ display_terms() {
#########################################
# Set length of session in minutes (eg 24 hours is 1440 minutes - if set to 0 then defaults to global sessiontimeout value):
# eg for 100 mins:
# session_length="100"
# sessiontimeout="100"
#
# eg for 20 hours:
# session_length=$((20*60))
# sessiontimeout=$((20*60))
#
# eg for 20 hours and 30 minutes:
# session_length=$((20*60+30))
session_length="0"
# sessiontimeout=$((20*60+30))
sessiontimeout="0"
# Set Rate and Quota values for the client
# The session length, rate and quota values could be determined by this script, on a per client basis.
@@ -487,7 +487,7 @@ download_rate="0"
upload_quota="0"
download_quota="0"
quotas="$session_length $upload_rate $download_rate $upload_quota $download_quota"
quotas="$sessiontimeout $upload_rate $download_rate $upload_quota $download_quota"
# Define the list of Parameters we expect to be sent sent from openNDS ($ndsparamlist):
# Note you can add custom parameters to the config file and to read them you must also add them here.

View File

@@ -428,14 +428,14 @@ display_terms() {
#########################################
# Set length of session in minutes (eg 24 hours is 1440 minutes - if set to 0 then defaults to global sessiontimeout value):
# eg for 100 mins:
# session_length="100"
# sessiontimeout="100"
#
# eg for 20 hours:
# session_length=$((20*60))
# sessiontimeout=$((20*60))
#
# eg for 20 hours and 30 minutes:
# session_length=$((20*60+30))
session_length="0"
# sessiontimeout=$((20*60+30))
sessiontimeout="0"
# Set Rate and Quota values for the client
# The session length, rate and quota values could be determined by this script, on a per client basis.
@@ -445,7 +445,7 @@ download_rate="0"
upload_quota="0"
download_quota="0"
quotas="$session_length $upload_rate $download_rate $upload_quota $download_quota"
quotas="$sessiontimeout $upload_rate $download_rate $upload_quota $download_quota"
# Define the list of Parameters we expect to be sent sent from openNDS ($ndsparamlist):
# Note you can add custom parameters to the config file and to read them you must also add them here.

View File

@@ -487,14 +487,14 @@ display_terms() {
#########################################
# Set length of session in minutes (eg 24 hours is 1440 minutes - if set to 0 then defaults to global sessiontimeout value):
# eg for 100 mins:
# session_length="100"
# sessiontimeout="100"
#
# eg for 20 hours:
# session_length=$((20*60))
# sessiontimeout=$((20*60))
#
# eg for 20 hours and 30 minutes:
# session_length=$((20*60+30))
session_length="0"
# sessiontimeout=$((20*60+30))
sessiontimeout="0"
# Set Rate and Quota values for the client
# The session length, rate and quota values could be determined by this script, on a per client basis.
@@ -504,7 +504,7 @@ download_rate="0"
upload_quota="0"
download_quota="0"
quotas="$session_length $upload_rate $download_rate $upload_quota $download_quota"
quotas="$sessiontimeout $upload_rate $download_rate $upload_quota $download_quota"
# Define the list of Parameters we expect to be sent sent from openNDS ($ndsparamlist):
# Note you can add custom parameters to the config file and to read them you must also add them here.

View File

@@ -3,15 +3,20 @@
#Copyright (C) BlueWave Projects and Services 2015-2025
#This software is released under the GNU GPL license.
# This is an example script for BinAuth
# It writes a local log and can override authentication requests and quotas.
#
# The client User Agent string is forwarded to this script.
#
# If BinAuth is enabled, NDS will call this script as soon as it has received an authentication, deauthentication or shutdown request
#
##################
########################################################################
# WARNING - DO NOT edit this file unless you know what you are doing! #
# #
# WARNING - DO NOT delete or rename this file #
########################################################################
###########################################################################################################################
#
# This is the authentication, deauthentication or shutdown request processing and logging script
# It writes a local log and can override authentication requests and quotas as defined in the included custombinauth script
#
###########################################################################################################################
# functions:
get_client_zone () {
@@ -22,6 +27,12 @@ get_client_zone () {
if [ -z "$client_zone" ]; then
client_mac=$clientmac
if [ -z "$client_mac" ]; then
client_zone=""
return 0
fi
client_if_string=$(/usr/lib/opennds/get_client_interface.sh $client_mac)
failcheck=$(echo "$client_if_string" | grep "get_client_interface")
@@ -126,6 +137,10 @@ write_log () {
/usr/lib/opennds/libopennds.sh "write_log" "$loginfo" "$logname" "$date_inhibit"
}
write_to_syslog () {
/usr/lib/opennds/libopennds.sh "write_to_syslog" "$syslogmessage" "$debuglevel"
}
#### end of functions ####
@@ -140,6 +155,15 @@ write_log () {
configure_log_location
# Default Values for quotas and session length. These can be overridden.
# exitlevel can also be set in the custonbinauth.sh script (0=allow, 1=deny)
sessiontimeout=0
upload_rate=0
download_rate=0
upload_quota=0
download_quota=0
exitlevel=0
#
# Get the action method from NDS ie the first command line argument.
#
@@ -157,7 +181,13 @@ configure_log_location
#
action=$1
if [ $action = "auth_client" ]; then
if [ -z "$action" ]; then
exit 1
fi
/usr/lib/opennds/libopennds.sh syslog "binauth action [ $action ]" "debug"
if [ "$action" = "auth_client" ]; then
# Arguments passed are as follows
# $1 method
# $2 client mac
@@ -190,7 +220,7 @@ else
customdata=$8
# Build the log entry:
loginfo="method=$1, clientmac=$2, bytes_incoming=$3, bytes_outgoing=$4, session_start=$5, session_end=$6, token=$7, custom=$customdata"
loginfo="method=\"$1\", clientmac=\"$2\", timestamp=$(date +%s), bytes_incoming=$3, bytes_outgoing=$4, session_start=$5, session_end=$6, token=$7, custom=\"$customdata\""
action=$(echo "$1" | awk -F"_" '{printf("%s", $NF)}')
@@ -228,14 +258,14 @@ fi
# advert1_htm
# Parse the database by client mac ($2):
cidfile=$(grep -r "$2" "$mountpoint/ndscids" | awk -F 'ndscids/' '{print $2}' | awk -F ':' '{printf $1}')
cidfile=$(grep -r "$2" "$mountpoint/ndscids" | tail -n 1 | awk -F 'ndscids/' '{print $2}' | awk -F ':' '{printf $1}')
if [ ! -z "$cidfile" ]; then
# populate the local variables:
. $mountpoint/ndscids/$cidfile
# Add a selection of client data variables to the log entry
loginfo="$loginfo, client_type=$client_type, gatewayname=$gatewayname, ndsversion=$version, originurl=$originurl"
loginfo="$loginfo, client_type=\"$client_type\", gatewayname=\"$gatewayname\", ndsversion=\"$version\", originurl=\"$originurl\""
else
clientmac=$2
fi
@@ -245,7 +275,26 @@ fi
get_client_zone
# Add client_zone to the log entry
loginfo="$loginfo, client_zone=$client_zone"
loginfo="$loginfo, client_zone=\"$client_zone\""
if [ "$action" = "auth_client" ]; then
custom=$7
else
custom=$8
fi
# Include custom binauth script
custombinauthpath=$(uci get opennds.setup.custombinauth 2> /dev/null)
if [ ! -z "$custombinauthpath" ] && [ -e "$custombinauthpath" ]; then
. $custombinauthpath
elif [ ! -z "$custombinauthpath" ] && [ ! -e "$custombinauthpath" ]; then
/usr/lib/opennds/libopennds.sh syslog "custom binauth script [ $custombinauthpath ] not found" "error"
fi
# Add client quota variables to the log entry
loginfo="$loginfo, sessiontimeout=$sessiontimeout, upload_rate=$upload_rate, download_rate=$download_rate, upload_quota=$upload_quota, download_quota=$download_quota"
# Append to the log.
logname="$fulllog"
@@ -274,36 +323,26 @@ if [ "$action" = "auth_client" ] || [ "$action" = "auth" ]; then
write_log &> /dev/null
fi
# Values for quotas and session length can be overridden here if action=auth_client, and passed in the custom string.
# The custom string must be parsed in custombinauth.sh script for the required values.
# exitlevel can also be set in the custonbinauth.sh script (0=allow, 1=deny)
session_length=0
upload_rate=0
download_rate=0
upload_quota=0
download_quota=0
exitlevel=0
if [ "$action" = "auth_client" ]; then
custom=$7
else
custom=$8
fi
# Include custom binauth script
custombinauthpath="/usr/lib/opennds/custombinauth.sh"
if [ -e "$custombinauthpath" ]; then
. $custombinauthpath
fi
# Finally before exiting, output the session length, upload rate, download rate, upload quota and download quota (only effective for auth_client).
# The custom binauth script migh change these values
echo "$session_length $upload_rate $download_rate $upload_quota $download_quota"
# The custom binauth script might change these values
echo "$sessiontimeout $upload_rate $download_rate $upload_quota $download_quota"
# Exit, setting level (only effective for auth_client)
# For other methods, write the values to the client cid file
/usr/lib/opennds/libopennds.sh syslog "cid [ $mountpoint/ndscids/$cidfile ]" "debug"
if [ ! -z "$cidfile" ] && [ -z "$binauth_quotas" ]; then
/usr/lib/opennds/libopennds.sh syslog "binauth appending [ $mountpoint/ndscids/$cidfile ]" "debug"
echo "binauth_quotas=1" >> $mountpoint/ndscids/$cidfile
echo "sessiontimeout=$sessiontimeout" >> $mountpoint/ndscids/$cidfile
echo "upload_rate=$upload_rate" >> $mountpoint/ndscids/$cidfile
echo "download_rate=$download_rate" >> $mountpoint/ndscids/$cidfile
echo "upload_quota=$upload_quota" >> $mountpoint/ndscids/$cidfile
echo "download_quota=$download_quota" >> $mountpoint/ndscids/$cidfile
fi
# Exit, setting level
#
# exit 0 tells NDS it is ok to allow the client to have access (default).
# exit 1 would tell NDS to deny access.
# The custom binauth script might change this value
# The custom binauth script might have changed this value
exit $exitlevel

View File

@@ -3,11 +3,56 @@
#Copyright (C) BlueWave Projects and Services 2015-2025
#This software is released under the GNU GPL license.
# This is a stub for a custom binauth script
# It is included by the default binauth_log.sh script when it runs
#
# This is a stub for a custom binauth script.
# It is included by the default binauth_log.sh script when it runs.
# By default, it does nothing as it is a template.
# This included script can override:
# exitlevel, session length, upload rate, download rate, upload quota and download quota.
# exitlevel, sessiontimeout, upload rate, download rate, upload quota and download quota.
# The following variables are initialised with valid information by the openNDS daemon and can be used in any custom code added below:
# HOSTNAME
# action
# authlog
# cidfile
# client_if
# client_if_string
# client_mac
# client_meshnode
# client_type
# client_zone
# clientif
# clientip
# clientmac
# cpi_query
# custom
# custombinauthpath
# customdata
# download_quota
# download_rate
# exitlevel
# fulllog
# gatewayaddress
# gatewaymac
# gatewayname
# gatewayurl
# hid
# local_mesh_if
# log_mountpoint
# logdir
# loginfo
# mountpoint
# ndspid
# originurl
# sessiontimeout
# themespec
# upload_quota
# upload_rate
# version
# BinAuth Descriptors:
custombinauth_title="Template"
custombinauth_description="Custom BinAuth Template"
# Add custom code after this line:

View File

@@ -0,0 +1,59 @@
#!/bin/sh
#Copyright (C) The openNDS Contributors 2004-2022
#Copyright (C) BlueWave Projects and Services 2015-2025
#This software is released under the GNU GPL license.
#
# A list of variables that are initialised with valid information by the openNDS daemon and can be used in any custom code added below can be seen in the custombinauth.sh stub/template.
# BinAuth Descriptors:
custombinauth_title="reauth_interval"
custombinauth_description="Set minimum time between deauthentication and reauthentication"
#Define a function
parse_timestamp() {
local action="$1"
eval $(grep "$clientmac" "$logdir""binauthlog.log" | grep "$action" | awk -F", " '{print $4}' | tail -n 1)
syslogmessage="clientmac [$clientmac] action [$action] timestamp [$timestamp]"
debuglevel="debug"
write_to_syslog
}
# Get the reauth_interval in seconds
option="reauth_interval"
get_option_from_config
If [ -z "$reauth_interval" ] || [ "$reauth_interval" -eq 0 ]; then
# Reauth interval checking is disabled.
exitlevel=0 #allow
else
syslogmessage="reauth_interval clientmac [$clientmac] action [ $action ]"
debuglevel="debug"
write_to_syslog
if [ "$action" = "auth" ]; then
parse_timestamp "_deauth"
last_deauth=$timestamp
if [ -z "$last_deauth" ]; then
# Client has never been deauthed so we can let them re-auth
exitlevel=0 #allow
else
time_now=$(date +%s)
re_auth_min_time=$((last_deauth + reauth_interval))
syslogmessage="clientmac [$clientmac] re_auth_min_time [ $re_auth_min_time ]"
debuglevel="debug"
write_to_syslog
if [ "$re_auth_min_time" -lt "$time_now" ]; then
exitlevel=0 #allow
else
exitlevel=1 #deny
syslogmessage="clientmac [$clientmac] attempted login before reauth interval expired"
debuglevel="debug"
write_to_syslog
fi
fi
fi
fi

View File

@@ -274,7 +274,7 @@ body() {
pagebody="
<h1>To login, click or tap the Continue button</h1>
<form action=\"$url/login\" method=\"get\" target=\"_blank\">
<form action=\"$url/login\" method=\"get\" target=\"_self\">
<input type=\"submit\" value=\"Continue\" >
</form>
"

View File

@@ -41,6 +41,8 @@ ipset_to_nftset () {
}
delete_114s() {
cpidconfig=$(echo "get dhcp.$network_zone.dhcp_option_force" | uci batch 2>/dev/null)
dellist="del_list dhcp.$network_zone.dhcp_option_force="
if [ ! -z "$cpidconfig" ]; then
@@ -162,24 +164,15 @@ elif [ "$setconf" = "cpidconf" ]; then
network_zone=$(uci show network | grep "device='$gwif'" | awk -F "." '{printf "%s", $2}')
if [ ! -z "$network_zone" ]; then
cpidconfig=$(uci get dhcp.lan.dhcp_option_force 2>/dev/null)
dellist="del_list dhcp.$network_zone.dhcp_option_force='114,http://$gatewayfqdn'"
if [ -z "$gatewayfqdn" ]; then
delete_114s
printf "%s" "done"
exit 0
fi
delete_114s
addlist="add_list dhcp.$network_zone.dhcp_option_force='114,http://$gatewayfqdn'"
if [ -z "$cpidconfig" ]; then
echo $addlist | uci batch
elif [ "$cpidconfig" != "114,http://$gatewayfqdn" ]; then
delete_114s
echo $addlist | uci batch
fi
echo $addlist | uci batch
fi
fi

View File

@@ -1058,6 +1058,10 @@ get_option_from_config() {
type uci &> /dev/null
uci_status=$?
if [ -z "$option" ]; then
return 1
fi
if [ $uci_status -eq 0 ]; then
param=$(uci export opennds | grep -w "option" | grep -w "$option" | awk -F"'" 'NF > 1 {printf "%s ", $2}')
else
@@ -1716,6 +1720,7 @@ auth_restore () {
exit 1
fi
# Scan authlog for clients to re-auth:
while read -r client; do
b64mac="$(echo "$client" | awk -F"=" '{printf("%s", $1)}')""=="
client_mac=$(ndsctl b64decode "$b64mac")
@@ -1762,9 +1767,11 @@ auth_restore () {
if [ $reauth -eq 1 ]; then
mac="$client_mac"
custom="auth_restore"
authstr="$mac, $sessiontimeout, $uploadrate, $downloadrate, $uploadquota, $downloadquota, preemptivemac-$mac"
macstr=$(echo "$mac" | awk -F":" '{printf "%s%s%s%s%s%s", $1, $2, $3, $4, $5, $6}')
# Create a file for OpenNDS to use for pre-emptive logins - gets deleted once processed
echo "$authstr" > "$preemptive_auth/$macstr"
fi
@@ -1999,7 +2006,7 @@ send_post_data () {
option="fas_secure_enabled"
get_option_from_config
if [ "$fas_secure_enabled" -ge 3 ] && [ -f "$mountpoint/ndscids/authmonargs" ]; then
if [ ! -z "$fas_secure_enabled" ] && [ "$fas_secure_enabled" -ge 3 ] && [ -f "$mountpoint/ndscids/authmonargs" ]; then
. $mountpoint/ndscids/ndsinfo
. $mountpoint/ndscids/authmonargs
@@ -2159,6 +2166,47 @@ convert_from_la() {
mac_from_la="$octet:$p2:$p3:$p4:$p5:$p6"
}
get_quotas_by_mac() {
quotas="0 0 0 0 0"
configure_log_location
cidfile=$(grep -r "$clientmac" "$mountpoint/ndscids" | tail -n 1 | awk -F 'ndscids/' '{print $2}' | awk -F ':' '{printf $1}')
if [ ! -z "$cidfile" ]; then
if [ -e "$mountpoint/ndscids/$cidfile" ]; then
. $mountpoint/ndscids/$cidfile
fi
if [ ! -z "$binauth_quotas" ] && [ "$binauth_quotas" -eq 1 ]; then
quotas="$sessiontimeout $upload_rate $download_rate $upload_quota $download_quota"
fi
else
# Override quotas for the client from the binauth log if client was shutdown_deauth
eval $(grep "$clientmac" "$mountpoint/ndslog/binauthlog.log" | awk -F"method=" '{print $2}' | grep "shutdown_deauth" | tail -1 | awk -F ", " '{printf "%s; %s; %s; %s; %s", $11, $12, $13, $14, $15}')
if [ -z "$sessiontimeout" ]; then
sessiontimeout=0
fi
if [ -z "$upload_rate" ]; then
upload_rate=0
fi
if [ -z "$download_rate" ]; then
download_rate=0
fi
if [ -z "$upload_quota" ]; then
upload_quota=0
fi
if [ -z "$download_quota" ]; then
download_quota=0
fi
quotas="$sessiontimeout $upload_rate $download_rate $upload_quota $download_quota"
fi
}
#### end of functions ####
@@ -2208,14 +2256,14 @@ if [ "$query_type" = "%3ffas%3d" ]; then
#########################################
# Set length of session in minutes (eg 24 hours is 1440 minutes - if set to 0 then defaults to global sessiontimeout value):
# eg for 100 mins:
# session_length="100"
# sessiontimeout="100"
#
# eg for 20 hours:
# session_length=$((20*60))
# sessiontimeout=$((20*60))
#
# eg for 20 hours and 30 minutes:
# session_length=$((20*60+30))
session_length="0"
# sessiontimeout=$((20*60+30))
sessiontimeout="0"
# Set Rate and Quota values for the client
# The session length, rate and quota values could be determined by this script, on a per client basis.
@@ -2225,7 +2273,7 @@ if [ "$query_type" = "%3ffas%3d" ]; then
upload_quota="0"
download_quota="0"
quotas="$session_length $upload_rate $download_rate $upload_quota $download_quota"
quotas="$sessiontimeout $upload_rate $download_rate $upload_quota $download_quota"
#########################################
# The list of Parameters sent from openNDS:
@@ -2318,8 +2366,9 @@ elif [ "$1" = "get_option_from_config" ]; then
# $2 contains the option to get
option=$2
get_option_from_config
status=$?
printf "%s" "$param"
exit 0
exit $status
elif [ "$1" = "get_list_from_config" ]; then
# Get the config list value(s)
@@ -3313,6 +3362,15 @@ elif [ "$1" = "ipv6_routing" ]; then
exit 0
elif [ "$1" = "get_quotas_by_mac" ]; then
clientmac="$2"
get_quotas_by_mac
syslogmessage="quotas for client [ $clientmac ] [ $quotas ]"
debugtype=debug
write_to_syslog
echo "$quotas"
exit 0
fi
########################################################################

View File

@@ -1,5 +1,5 @@
config opennds
config opennds 'setup'
# enabled
# Default: 1 (enabled)
# Set to 0 to disable opennds

View File

@@ -64,7 +64,7 @@ client_auth(char *arg)
t_client *client;
unsigned id;
int rc = -1;
int seconds = 60 * config->session_timeout;
int seconds = 60 * config->sessiontimeout;
int custom_seconds;
int uploadrate = config->upload_rate;
int downloadrate = config->download_rate;
@@ -72,6 +72,7 @@ client_auth(char *arg)
unsigned long long int downloadquota = config->download_quota;
char *libcmd;
char *msg;
char *msg2;
char *customdata;
char *argcopy;
const char *arg2;
@@ -179,21 +180,21 @@ client_auth(char *arg)
// check if client ip is on our subnet
safe_asprintf(&libcmd, "/usr/lib/opennds/libopennds.sh get_interface_by_ip \"%s\"", ipclient);
msg = safe_calloc(64);
rc = execute_ret_url_encoded(msg, 64 - 1, libcmd);
msg2 = safe_calloc(64);
rc = execute_ret_url_encoded(msg2, 64 - 1, libcmd);
free(libcmd);
if (rc == 0) {
if (strcmp(config->gw_interface, msg) == 0) {
debug(LOG_DEBUG, "Pre-emptive Authentication: Client [%s] is on our subnet using interface [%s]", ipclient, msg);
if (strcmp(config->gw_interface, msg2) == 0) {
debug(LOG_DEBUG, "Pre-emptive Authentication: Client [%s] is on our subnet using interface [%s]", ipclient, msg2);
client = client_list_add_client(macclient, ipclient);
if (client) {
id = client ? client->id : 0;
debug(LOG_DEBUG, "client id: [%d]", id);
client->client_type = "preemptive";
client->client_type = safe_strdup("preemptive");
// log the preemptive authentication
safe_asprintf(&libcmd,
@@ -203,8 +204,10 @@ client_auth(char *arg)
client->client_type
);
msg = safe_calloc(64);
rc = execute_ret_url_encoded(msg, 64 - 1, libcmd);
// Reuse msg2
free(msg2);
msg2 = safe_calloc(64);
rc = execute_ret_url_encoded(msg2, 64 - 1, libcmd);
free(libcmd);
}
@@ -217,6 +220,7 @@ client_auth(char *arg)
}
}
free(msg);
free(msg2);
} else {
debug(LOG_DEBUG, "Client connection not found: Continuing...");
@@ -262,18 +266,20 @@ client_auth(char *arg)
}
static void binauth_action(t_client *client, const char *reason, const char *customdata)
static int binauth_action(t_client *client, const char *reason, const char *customdata)
{
s_config *config = config_get_config();
time_t now = time(NULL);
int seconds = 60 * config->session_timeout;
int seconds = 60 * config->sessiontimeout;
unsigned long int sessionstart;
unsigned long int sessionend;
char *deauth = "deauth";
char *client_auth = "client_auth";
char *ndsctl_auth = "ndsctl_auth";
char *customdata_enc;
char *binauthcmd;
int ret = 1;
int rc = 0;
if (config->binauth) {
debug(LOG_DEBUG, "client->custom=%s", client->custom);
@@ -316,7 +322,8 @@ static void binauth_action(t_client *client, const char *reason, const char *cus
debug(LOG_DEBUG, "BinAuth %s - client session end time: [ %lu ]", reason, sessionend);
execute("%s %s %s %llu %llu %lu %lu %s %s",
binauthcmd = safe_calloc(STATUS_BUF);
safe_snprintf(binauthcmd, STATUS_BUF, "%s %s %s %llu %llu %lu %lu %s %s",
config->binauth,
reason ? reason : "unknown",
client->mac,
@@ -328,44 +335,112 @@ static void binauth_action(t_client *client, const char *reason, const char *cus
customdata_enc
);
rc = system(binauthcmd);
free(binauthcmd);
free(customdata_enc);
if (WIFEXITED(rc)) {
rc = WEXITSTATUS(rc);
}
debug(LOG_DEBUG, "binauth return code %d", rc);
if (strstr(reason, deauth) == NULL && strstr(reason, ndsctl_auth) == NULL) {
// unlock ndsctl
if (ret == 0) {
ndsctl_unlock();
}
}
return rc;
}
// No binauth configured, so good to go
return 0;
}
static int auth_change_state(t_client *client, const unsigned int new_state, const char *reason, const char *customdata)
{
s_config *config = config_get_config();
const unsigned int state = client->fw_connection_state;
const time_t now = time(NULL);
char *libcmd;
char *msg;
int action;
s_config *config = config_get_config();
int exitcode;
time_t sessionseconds_binauth;
time_t sessionseconds_config = 60 * config->sessiontimeout;
unsigned long long int upload_rate; /**< @brief Client Upload rate limit, kb/s */
unsigned long long int download_rate; /**< @brief Client Download rate limit, kb/s */
unsigned long long int uprate; /**< @brief Current Client Upload rate, kb/s */
unsigned long long int downrate; /**< @brief Client Download rate, kb/s */
unsigned long long int upload_quota; /**< @brief Client Upload quota, kB */
unsigned long long int download_quota; /**< @brief Client Download quota, kB */
if (state == new_state) {
return -1;
} else if (state == FW_MARK_PREAUTHENTICATED) {
if (new_state == FW_MARK_AUTHENTICATED) {
exitcode = binauth_action(client, reason, customdata);
if (exitcode != 0) {
return 1;
}
iptables_fw_authenticate(client);
if (client->upload_rate == 0) {
// Get parameters assigned by binauth, default to 0 if none assigned
libcmd = safe_calloc(SMALL_BUF);
safe_snprintf(libcmd, SMALL_BUF, "/usr/lib/opennds/libopennds.sh get_quotas_by_mac \"%s\"", client->mac );
msg = safe_calloc(SMALL_BUF);
execute_ret_url_encoded(msg, SMALL_BUF, libcmd);
free(libcmd);
debug(LOG_DEBUG, "assigned parameters [ %s ]", msg);
sessionseconds_binauth = 60 * atoi(strtok(msg, " "));
debug(LOG_DEBUG, "sessionseconds_binauth [ %d ]", sessionseconds_binauth);
client->session_end = now + sessionseconds_config;
if (sessionseconds_binauth == 0) {
client->session_end = sessionseconds_config + now;
} else {
client->session_end = sessionseconds_binauth + now;
}
//
upload_rate = atoi(strtok(NULL, " "));
if (upload_rate == 0) {
client->upload_rate = config->upload_rate;
} else {
client->upload_rate = upload_rate;
}
if (client->download_rate == 0) {
//
download_rate = atoi(strtok(NULL, " "));
if (download_rate == 0) {
client->download_rate = config->download_rate;
} else {
client->download_rate = download_rate;
}
if (client->upload_quota == 0) {
//
upload_quota = atoi(strtok(NULL, " "));
if (upload_quota == 0) {
client->upload_quota = config->upload_quota;
} else {
client->upload_quota = upload_quota;
}
if (client->download_quota == 0) {
//
download_quota = atoi(strtok(NULL, " "));
if (download_quota == 0) {
client->download_quota = config->download_quota;
} else {
client->download_quota = download_quota;
}
debug(LOG_DEBUG, "auth_change_state > authenticated - download_rate [%llu] upload_rate [%llu] ",
@@ -383,7 +458,7 @@ static int auth_change_state(t_client *client, const unsigned int new_state, con
if (customdata && strlen(customdata) > 0) {
client->custom = safe_strdup(customdata);
} else {
client->custom = "bmE=";
client->custom = safe_strdup("bmE=");
}
debug(LOG_DEBUG, "auth_change_state: client->custom=%s ", client->custom);
@@ -409,9 +484,10 @@ static int auth_change_state(t_client *client, const unsigned int new_state, con
client->rate_exceeded = client->rate_exceeded^2;
}
binauth_action(client, reason, customdata);
client->fw_connection_state = new_state;
free(msg);
} else if (new_state == FW_MARK_TRUSTED) {
return -1;
} else {
@@ -421,9 +497,10 @@ static int auth_change_state(t_client *client, const unsigned int new_state, con
if (new_state == FW_MARK_PREAUTHENTICATED) {
// we now delete the client instead of changing state to preauthenticated
debug(LOG_DEBUG, "Deleting client [ %s ] [ %s ]", client->cid, reason);
iptables_fw_deauthenticate(client);
binauth_action(client, reason, customdata);
client_reset(client);
client_list_delete(client);
} else if (new_state == FW_MARK_AUTH_BLOCKED) {
@@ -568,6 +645,13 @@ fw_refresh_client_list(void)
if (conn_state == FW_MARK_PREAUTHENTICATED) {
debug(LOG_DEBUG, "last_updated [ %lu ], now [ %lu ], preauth_idle_timeout_secs [ %lu ]",
last_updated,
now,
preauth_idle_timeout_secs
);
// Preauthenticated client reached Idle Timeout without authenticating so delete from the client list
if (preauth_idle_timeout_secs > 0
&& conn_state == FW_MARK_PREAUTHENTICATED

View File

@@ -95,6 +95,7 @@ client_list_init(void)
static t_client *
_client_list_append(const char mac[], const char ip[])
{
char *hash;
t_client *client, *prevclient;
s_config *config;
@@ -116,9 +117,15 @@ _client_list_append(const char mac[], const char ip[])
client->mac = safe_strdup(mac);
client->ip = safe_strdup(ip);
client->counters.last_updated = time(NULL);
// Reset volatile fields and create new token
client_reset(client);
// Create new token and hid
hash = safe_calloc(STATUS_BUF);
client->token = safe_calloc(STATUS_BUF);
safe_snprintf(client->token, STATUS_BUF, "%04hx%04hx", rand16(), rand16());
hash_str(hash, STATUS_BUF, client->token);
client->hid = safe_strdup(hash);
free(hash);
// Trusted client does not trigger the splash page.
if (is_trusted_mac(mac)) {
@@ -146,59 +153,6 @@ _client_list_append(const char mac[], const char ip[])
return client;
}
/** @internal
* Reset volatile fields
*/
void client_reset(t_client *client)
{
char *hash;
char *msg;
char *cidinfo;
debug(LOG_DEBUG, "Resetting client [%s]", client->mac);
// Reset traffic counters
client->counters.incoming = 0;
client->counters.outgoing = 0;
client->counters.last_updated = time(NULL);
// Reset session time
client->session_start = 0;
client->session_end = 0;
// Reset token and hid
hash = safe_calloc(STATUS_BUF);
client->token = safe_calloc(STATUS_BUF);
safe_snprintf(client->token, STATUS_BUF, "%04hx%04hx", rand16(), rand16());
hash_str(hash, STATUS_BUF, client->token);
client->hid = safe_strdup(hash);
free(hash);
// Reset custom, client_type and cpi_query
client->custom = safe_calloc(MID_BUF);
client->client_type = safe_calloc(STATUS_BUF);
if (!client->cpi_query) {
client->cpi_query = safe_calloc(STATUS_BUF);
}
//Reset cid and remove cidfile using rmcid
if (client->cid) {
if (strlen(client->cid) > 0) {
msg = safe_calloc(SMALL_BUF);
cidinfo = safe_calloc(MID_BUF);
safe_snprintf(cidinfo, MID_BUF, "cid=\"%s\"", client->cid);
write_client_info(msg, SMALL_BUF, "rmcid", client->cid, cidinfo);
free(msg);
free(cidinfo);
}
}
free(client->cid);
client->cid = safe_calloc(SMALL_BUF);
}
/**
* Given an IP address, add a client corresponding to that IP to client list.
* Return a pointer to the new client list entry, or to an existing entry
@@ -215,7 +169,7 @@ client_list_add_client(const char mac[], const char ip[])
char *msg;
if (!check_mac_format(mac)) {
// Inappropriate format in IP address
// Inappropriate format in MAC address
debug(LOG_NOTICE, "Illegal MAC format [%s]", mac);
return NULL;
}
@@ -420,6 +374,8 @@ _client_list_free_node(t_client *client)
char *msg;
char *cidinfo;
debug(LOG_DEBUG, "Freeing client node [ %lu ] [ %s ]", client, client->mac);
if (client->cid) {
// Remove any existing cidfile:
@@ -441,10 +397,11 @@ _client_list_free_node(t_client *client)
free(client->custom);
free(client->client_type);
if (strcmp(client->cpi_query, "") == 0) {
if (client->cpi_query) {
free(client->cpi_query);
}
debug(LOG_DEBUG, "Client node [ %lu ] freed", client);
free(client);
}

View File

@@ -110,9 +110,6 @@ t_client *client_list_find_by_mac(const char mac[]); /* needed by ndsctl_thread.
/** @brief Finds a client by its token */
t_client *client_list_find_by_token(const char token[]);
/** @brief Reset volatile client fields */
void client_reset(t_client *client);
/** @brief Deletes a client from the client list */
void client_list_delete(t_client *client);

View File

@@ -215,7 +215,9 @@ config_init(int argc, char **argv)
config.preauthdir = safe_strdup(set_option_str("preauthdir", DEFAULT_PREAUTHDIR, debug_level));
config.ndsctl_sock = safe_strdup(set_option_str("ndsctl_sock", DEFAULT_NDSCTL_SOCK, debug_level));
config.authentication_mark = safe_strdup(set_option_str("authentication_mark", DEFAULT_AUTHENTICATION_MARK, debug_level));
config.binauth = safe_strdup(set_option_str("binauth", DEFAULT_BINAUTH, debug_level));
// Setting binauth in config is deprecated. Use DEFAULT_BINAUTH only.
config.binauth = safe_strdup(set_option_str("binauth_deprecated", DEFAULT_BINAUTH, "0"));
config.custombinauth = safe_strdup(set_option_str("custombinauth", DEFAULT_CUSTOMBINAUTH, debug_level));
config.fas_path = safe_strdup(set_option_str("faspath", DEFAULT_FASPATH, debug_level));
config.themespec_path = safe_strdup(set_option_str("themespec_path", DEFAULT_THEMESPEC_PATH, debug_level));
config.fas_remoteip = safe_strdup(set_option_str("fasremoteip", DEFAULT_FAS_REMOTEIP, debug_level));
@@ -248,7 +250,7 @@ config_init(int argc, char **argv)
free(msg);
//
sscanf(set_option_str("sessiontimeout", DEFAULT_SESSION_TIMEOUT, debug_level), "%u", &config.session_timeout);
sscanf(set_option_str("sessiontimeout", DEFAULT_SESSIONTIMEOUT, debug_level), "%u", &config.sessiontimeout);
sscanf(set_option_str("preauthidletimeout", DEFAULT_PREAUTH_IDLE_TIMEOUT, debug_level), "%u", &config.preauth_idle_timeout);
sscanf(set_option_str("authidletimeout", DEFAULT_AUTH_IDLE_TIMEOUT, debug_level), "%u", &config.auth_idle_timeout);
sscanf(set_option_str("maxclients", DEFAULT_MAXCLIENTS, debug_level), "%u", &config.maxclients);

View File

@@ -30,7 +30,7 @@
#ifndef _CONF_H_
#define _CONF_H_
#define VERSION "10.3.2beta"
#define VERSION "10.4.0beta"
/*
* Defines how many times should we try detecting the interface with the default route (in seconds).
@@ -71,8 +71,9 @@
#define DEFAULT_FASPATH "/"
#define DEFAULT_FASKEY ""
#define DEFAULT_BINAUTH "/usr/lib/opennds/binauth_log.sh"
#define DEFAULT_CUSTOMBINAUTH "/usr/lib/opennds/custombinauth.sh"
#define DEFAULT_CHECKINTERVAL "15"
#define DEFAULT_SESSION_TIMEOUT "1440"
#define DEFAULT_SESSIONTIMEOUT "1440"
#define DEFAULT_PREAUTH_IDLE_TIMEOUT "30"
#define DEFAULT_AUTH_IDLE_TIMEOUT "120"
#define DEFAULT_REMOTES_REFRESH_INTERVAL "0"
@@ -234,7 +235,7 @@ typedef struct {
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 sessiontimeout; //@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 remotes_refresh_interval; //@brief Minutes before remote files will be refreshed
@@ -272,6 +273,7 @@ typedef struct {
unsigned int fw_mark_trusted; //@brief nftables mark for trusted packets
int ip6; //@brief enable IPv6
char *binauth; //@brief external postauthentication program
char *custombinauth; //@brief external custom postauthentication program
char *preauth; //@brief external preauthentication program
int lockfd; //@brief ndsctl lockfile file descriptor
} s_config;

View File

@@ -209,7 +209,7 @@ static int do_binauth(
if (rc != 0) {
debug(LOG_DEBUG, "BinAuth script failed to execute");
free(msg);
return 0;
return rc;
}
rc = sscanf(msg, "%d %llu %llu %llu %llu", &seconds, &upload_rate, &download_rate, &upload_quota, &download_quota);
@@ -582,7 +582,7 @@ static int authenticate_client(struct MHD_Connection *connection,
{
s_config *config = config_get_config();
time_t now = time(NULL);
int seconds = 60 * config->session_timeout;
int seconds = 60 * config->sessiontimeout;
unsigned long long int uploadrate = 0;
unsigned long long int downloadrate = 0;
unsigned long long int uploadquota = 0;
@@ -666,12 +666,12 @@ static int authenticate_client(struct MHD_Connection *connection,
// override remaining client values that might have been set by binauth
if (seconds == 0) {
seconds = (60 * config->session_timeout);
seconds = (60 * config->sessiontimeout);
}
debug(LOG_DEBUG, "timeout seconds: %d", seconds);
if (seconds != (60 * config->session_timeout)) {
if (seconds != (60 * config->sessiontimeout)) {
client->session_end = (client->session_start + seconds);
}
@@ -1131,7 +1131,7 @@ static int preauthenticated(struct MHD_Connection *connection, const char *url,
// check if this is an RFC8910 login request
if (strcmp(url, "/login") == 0) {
debug(LOG_INFO, "preauthenticated: RFC8910 login request received from client at [%s] [%s]", client->ip, client->mac);
client->client_type = "cpi_url";
client->client_type = safe_strdup("cpi_url");
return redirect_to_splashpage(connection, client, host, "/login");
}
@@ -1147,7 +1147,7 @@ static int preauthenticated(struct MHD_Connection *connection, const char *url,
debug(LOG_DEBUG, "preauthenticated: Accept header [%s]", accept);
debug(LOG_NOTICE, "preauthenticated: RFC 8908 captive+json request received from client at [%s] [%s]", client->ip, client->mac);
client->client_type = "cpi_api";
client->client_type = safe_strdup("cpi_api");
originurl_raw = safe_calloc(REDIRECT_URL);
@@ -1409,7 +1409,6 @@ static char *construct_querystring(struct MHD_Connection *connection, t_client *
char *query_str_b64;
char *msg;
char *cidinfo;
char *cidfile;
char *gw_url_raw;
char *gw_url;
char *phpcmd;

View File

@@ -303,6 +303,8 @@ setup_from_config(void)
char *preauth_dir = NULL;
char *debuglevel = NULL;
char libscript[] = "/usr/lib/opennds/libopennds.sh";
char themespec1[] = "/usr/lib/opennds/theme_click-to-continue.sh";
char themespec2[] = "/usr/lib/opennds/theme_user-email-login-basic.sh";
char gw_name_entityencoded[256] = {0};
char gw_name_urlencoded[256] = {0};
struct stat sb;
@@ -587,9 +589,17 @@ setup_from_config(void)
if (config->login_option_enabled >= 1) {
debug(LOG_NOTICE, "Login option is Enabled using mode %d.\n", config->login_option_enabled);
config->preauth = safe_strdup(libscript);
if (config->login_option_enabled == 1) {
config->themespec_path = safe_strdup(themespec1);
} else if (config->login_option_enabled == 2) {
config->themespec_path = safe_strdup(themespec2);
}
} else if (config->login_option_enabled == 0 && config->fas_port == 0 && config->preauth == NULL) {
debug(LOG_NOTICE, "Click to Continue option is Enabled.\n");
config->preauth = safe_strdup(libscript);
config->themespec_path = safe_strdup(themespec1);
} else if (config->login_option_enabled == 0 && config->fas_port >= 1 ) {
debug(LOG_NOTICE, "FAS Enabled.\n");
config->preauth = NULL;

View File

@@ -284,7 +284,7 @@ ndsctl_auth(FILE *fp, char *arg)
t_client *client;
unsigned id;
int rc = -1;
int seconds = 60 * config->session_timeout;
int seconds = 60 * config->sessiontimeout;
int custom_seconds;
int uploadrate = config->upload_rate;
int downloadrate = config->download_rate;
@@ -292,6 +292,7 @@ ndsctl_auth(FILE *fp, char *arg)
unsigned long long int downloadquota = config->download_quota;
char *libcmd;
char *msg;
char *msg2;
char *customdata;
char *argcopy;
const char *arg2;
@@ -399,21 +400,21 @@ ndsctl_auth(FILE *fp, char *arg)
// check if client ip is on our subnet
safe_asprintf(&libcmd, "/usr/lib/opennds/libopennds.sh get_interface_by_ip \"%s\"", ipclient);
msg = safe_calloc(64);
rc = execute_ret_url_encoded(msg, 64 - 1, libcmd);
msg2 = safe_calloc(64);
rc = execute_ret_url_encoded(msg2, 64 - 1, libcmd);
free(libcmd);
if (rc == 0) {
if (strcmp(config->gw_interface, msg) == 0) {
debug(LOG_DEBUG, "Pre-emptive Authentication: Client [%s] is on our subnet using interface [%s]", ipclient, msg);
if (strcmp(config->gw_interface, msg2) == 0) {
debug(LOG_DEBUG, "Pre-emptive Authentication: Client [%s] is on our subnet using interface [%s]", ipclient, msg2);
client = client_list_add_client(macclient, ipclient);
if (client) {
id = client ? client->id : 0;
debug(LOG_DEBUG, "client id: [%d]", id);
client->client_type = "preemptive";
client->client_type = safe_strdup("preemptive");
// log the preemptive authentication
safe_asprintf(&libcmd,
@@ -423,8 +424,9 @@ ndsctl_auth(FILE *fp, char *arg)
client->client_type
);
msg = safe_calloc(64);
rc = execute_ret_url_encoded(msg, 64 - 1, libcmd);
free(msg2);
msg2 = safe_calloc(64);
rc = execute_ret_url_encoded(msg2, 64 - 1, libcmd);
free(libcmd);
}
@@ -435,6 +437,7 @@ ndsctl_auth(FILE *fp, char *arg)
} else {
debug(LOG_DEBUG, "ip subnet test failed: Continuing...");
}
free(msg2);
}
free(msg);

View File

@@ -922,10 +922,10 @@ ndsctl_status(FILE *fp)
fprintf(fp, "Preemptive Authentication is Disabled\n");
}
if (config->binauth) {
fprintf(fp, "Binauth Script: %s\n", config->binauth);
if (config->custombinauth) {
fprintf(fp, "Custom Binauth Script: %s\n", config->custombinauth);
} else {
fprintf(fp, "Binauth: Disabled\n");
fprintf(fp, "Custom Binauth: Disabled\n");
}
if (config->preauth) {