Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 189 additions & 18 deletions packages/ns-don/files/don
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ rsa_key="$base_dir/rsa_key"
ecdsa_key="$base_dir/ecdsa_key"
socket="$base_dir/management"
credentials="$base_dir/credentials"
session_start="$base_dir/session_start"
session_extended="$base_dir/session_extended"
cleanup_lock="$base_dir/.cleanup_lock"
crontab_file="/etc/crontabs/root"
user="nethsupport"
password=""
ca=$(uci -q get don.config.ca)
Expand All @@ -27,8 +31,48 @@ if [ "$2" == "-j" ]; then
json_output=1
fi

function log_message
{
# Log to /var/log/messages using logger (syslog)
logger -t "don" -p daemon.info "$1"
}

function log_error
{
# Log errors to syslog
logger -t "don" -p daemon.err "$1"
}

function add_cron_expiration
{
# Add cron job to check expiration every hour
if ! grep -q "/usr/sbin/don expire" "$crontab_file" 2>/dev/null; then
echo "0 * * * * sleep \$(( RANDOM % 60 )); /usr/sbin/don expire" >> "$crontab_file"
[ -x /etc/init.d/cron ] && /etc/init.d/cron restart
log_message "Expiration cron job added"
fi
}

function remove_cron_expiration
{
# Remove cron job for expiration checking
if [ -f "$crontab_file" ]; then
sed -i '\|/usr/sbin/don expire|d' "$crontab_file"
[ -x /etc/init.d/cron ] && /etc/init.d/cron restart
fi
}

function cleanup
{
# Use lock file to prevent concurrent cleanup calls
if [ -f "$cleanup_lock" ]; then
# Another cleanup is already running, skip
return
fi
# Create lock to prevent concurrent executions
touch "$cleanup_lock"
# Remove expiration cron job
remove_cron_expiration
# stop demons
[ -f "$sshd_pid" ] && kill "$(cat $sshd_pid)"
[ -f "$vpn_pid" ] && kill "$(cat $vpn_pid)" && sleep 3 && [ -f "$vpn_pid" ] && kill -9 "$(cat $vpn_pid)"
Expand All @@ -40,19 +84,64 @@ function cleanup
# destroy ubus sessions
session=$(ubus call session list | jq -r '.ubus_rpc_session as $parent | .data.username | select(. == "nethsupport") | $parent')
if [ "$session" != "" ]; then
ubus call session destroy '{"ubus_rpc_session": "'$session'"}'
ubus call session destroy '{"ubus_rpc_session": "'"$session"'"}'
fi
log_message "Remote support session stopped"
}

function show_credentials
function get_session_info
{
local extra_status="$1"
# Both session_start and credentials must be present for a valid session
if [ ! -f "$session_start" ] || [ ! -f "$credentials" ]; then
if [ "$json_output" == 1 ]; then
echo "null"
fi
return 1
fi

# Read credentials file into array
mapfile -t creds < "$credentials"
local server_id="${creds[0]}"
local session_id="${creds[1]}"

local session_start_time
session_start_time=$(cat "$session_start")
local session_expiry

# Use extended expiry if available, otherwise use start + 24 hours
if [ -f "$session_extended" ]; then
local extension_duration
extension_duration=$(cat "$session_extended")
session_expiry=$((session_start_time + extension_duration))
else
session_expiry=$((session_start_time + 86400))
fi

local current_time
current_time=$(date +%s)
local time_remaining=$((session_expiry - current_time))

if [ "$json_output" == 1 ]; then
echo "{\"server_id\": \"$(sed -n '1{p;q}' $credentials)\", \"session_id\": \"$(sed -n '2{p;q}' $credentials)\"}"
local status_field=""
if [ "$extra_status" == "already_extended" ]; then
status_field=", \"status\": \"$extra_status\""
fi
if [ "$time_remaining" -gt 0 ]; then
echo "{\"server_id\": \"$server_id\", \"session_id\": \"$session_id\", \"expires_in_seconds\": $time_remaining$status_field}"
else
echo "{\"server_id\": \"$server_id\", \"session_id\": \"$session_id\", \"status\": \"expired\"}"
fi
else
echo -n "Server ID:"
echo -e "\t"$(sed -n '1{p;q}' $credentials)
echo -n "Session ID:"
echo -e "\t"$(sed -n '2{p;q}' $credentials)
local hours_remaining=$((time_remaining / 3600))
local minutes_remaining=$(( (time_remaining % 3600) / 60 ))
echo "Server ID:$(printf '\t')$server_id"
echo "Session ID:$(printf '\t')$session_id"
if [ "$time_remaining" -gt 0 ]; then
echo "Session expires in: ${hours_remaining}h ${minutes_remaining}m"
else
echo "Session EXPIRED"
fi
fi
}

Expand All @@ -67,11 +156,13 @@ start)
system_id=$(uci -q get ns-plug.config.system_id)
fi
if [ -z "$system_id" ]; then
log_error "Remote support session failed: system_id not configured"
exit 2
fi

cn=$(openssl x509 -noout -subject -in $ca | cut -d= -f 2- | sed 's/ = /=/g')
cn=$(openssl x509 -noout -subject -in "$ca" | cut -d= -f 2- | sed 's/ = /=/g')
if [ -z "$cn" ]; then
log_error "Remote support session failed: invalid CA certificate"
exit 3
fi

Expand Down Expand Up @@ -162,38 +253,118 @@ AuthorizedKeysFile $auth_keys
StrictModes no
EOF

mkdir -m 0700 -p /var/empty
/usr/sbin/sshd -f $sshd_conf
cat $(uci -q get don.config.ssh_key) > $auth_keys
mkdir -p /var/empty
chmod 700 /var/empty
/usr/sbin/sshd -f "$sshd_conf"
cat "$(uci -q get don.config.ssh_key)" > "$auth_keys"

# Enable UI access
uci set rpcd.ns_don=login
uci set rpcd.ns_don.username=$user
uci set rpcd.ns_don.password=$(echo $password | mkpasswd)
uci set rpcd.ns_don.password="$(echo "$password" | mkpasswd)"
uci add_list rpcd.ns_don.read='*'
uci add_list rpcd.ns_don.write='*'
# commit rpcd changes
uci commit rpcd

show_credentials
# Save session start time
date +%s > "$session_start"
# Mark as not extended initially
rm -f $session_extended

# Add expiration cron job
add_cron_expiration

log_message "Remote support session started"

get_session_info
;;
stop)
cleanup
;;
status)
if [ -f $credentials ]; then
show_credentials
exit 0
if [ -f "$credentials" ]; then
get_session_info
exit $?
else
if [ "$json_output" == 1 ]; then
echo null
else
echo "don is not running"
fi
exit 1
exit 1
fi
;;
expire)
# Check if session has expired - requires both files to be present
if [ ! -f "$session_start" ] || [ ! -f "$credentials" ]; then
if [ "$json_output" == 1 ]; then
echo "{\"status\": \"no_session\"}"
else
echo "No session running"
fi
exit 0
fi

session_start_time=$(cat "$session_start")
# Use extended expiry if available, otherwise use start + 24 hours
if [ -f "$session_extended" ]; then
extension_duration=$(cat "$session_extended")
session_expiry=$((session_start_time + extension_duration))
else
session_expiry=$((session_start_time + 86400))
fi

current_time=$(date +%s)
time_remaining=$((session_expiry - current_time))

if [ $time_remaining -le 0 ]; then
# Session has expired - STOP IT NOW
if [ "$json_output" == 1 ]; then
echo "{\"status\": \"expired\", \"action\": \"stopping\"}"
else
echo "Session expired - stopping don service"
fi
log_error "Remote support session expired - auto-disabling"
cleanup
fi
;;
extend)
# Extend session by 7 days
if [ ! -f "$session_start" ] || [ ! -f "$credentials" ]; then
if [ "$json_output" == 1 ]; then
echo "{\"status\": \"no_session\"}"
else
echo "No session running"
fi
exit 0
fi

# Only extend once: if already extended, do nothing
if [ -f "$session_extended" ]; then
if [ "$json_output" != 1 ]; then
echo "Session already extended"
echo ""
fi
get_session_info "already_extended"
exit $?
fi

# Extend: store 24h + 7 days as total duration relative to session_start
echo "$((86400 + 604800))" > "$session_extended"

# Log the extension
log_message "Remote support session extended by 7 days"

if [ "$json_output" != 1 ]; then
echo "Session extended by 7 days"
echo ""
fi

# Show updated session info
get_session_info
;;
*)
echo "Usage: $0 {start|stop|status} [-j]"
echo "Usage: $0 {start|stop|status|expire|extend} [-j]"
exit 2
esac
Loading