From 0625fcc5ef4ac2e6e085628df059b3028eda5034 Mon Sep 17 00:00:00 2001 From: Christian Zeitnitz Date: Fri, 18 Jun 2021 14:04:56 +0200 Subject: [PATCH] Add raspap_helpers.sh --- config/client_config/huawei_hilink_api.sh | 281 ++++++++++-------- config/client_config/info_huawei_hilink.sh | 12 +- config/client_config/onoff_huawei_hilink.sh | 28 +- config/client_config/raspap_helpers.sh | 51 ++++ ...k.service => start_huawei_hilink@.service} | 2 +- config/client_config/switchClientState.sh | 36 --- config/client_udev_prototypes.json | 4 +- installers/raspap.sudoers | 1 - 8 files changed, 233 insertions(+), 182 deletions(-) create mode 100644 config/client_config/raspap_helpers.sh rename config/client_config/{start_huawei_hilink.service => start_huawei_hilink@.service} (76%) delete mode 100644 config/client_config/switchClientState.sh diff --git a/config/client_config/huawei_hilink_api.sh b/config/client_config/huawei_hilink_api.sh index 5c9fd809..6dc439f4 100644 --- a/config/client_config/huawei_hilink_api.sh +++ b/config/client_config/huawei_hilink_api.sh @@ -6,15 +6,16 @@ # - send a standard http request with a xml formatted string to the device (default IP 192.169.8.1) # - Howto: # o "source" this script in your own script from the command line -# o if host ip/name differs, set "host=192.168.178.1" before calling any function -# o if the device is locked by a password, set user="admin"; pw="1234secret" -# _login is called automaticallcall -# Password types 3 and 4 are supported -# o if the SIM is requiring a PIN, set "pin=1234" +# o if hilink_host ip/name differs, set "hilink_host=192.168.178.1" before calling any function +# o if the device is locked by a password, set hilink_user="admin"; hilink_password"1234secret" +# _login is called automatically +# only password type 4 is supported +# o if the SIM is requiring a PIN, set "hilink_pin=1234" # o connect device to network: _switchMobileData ON ( or 1 ) # o disconnect device: _switchMobileData OFF ( or 0 ) # o get informations about the device: _getDeviceInformation and _getStatus and _getNetProvider # all functions return XML formatted data in $response. +# o _getAllInformations: returns all available informations as key/value pairs (outputs text) # o Check if device is connected: "if _isConnected; then .... fi" # o $response can be parsed by calling _valueFromResponse # e.g "_valueFromResponse msisdn" to get the phone number after a call to _getDeviceInformation @@ -29,6 +30,7 @@ # # required software: curl, base64, sha256sum, sed # +# ToDo: improve error handling # # zbchristian 2021 # @@ -36,65 +38,73 @@ # Initialization procedure # ======================== # -# host=$host_default # ip address of device -# user="admin" # user name if locked (default admin) -# pw="1234Secret" # password if locked -# pin="1234" # PIN of SIM -# _initHilinkAPI # initialize the API +# hilink_host=192.168.8.1 # ip address of device +# hilink_user="admin" # user name if locked (default admin) +# hilink_password="1234Secret" # password if locked +# hilink_pin="1234" # PIN of SIM +# _initHilinkAPI # initialize the API # # Termination # =========== # cleanup the API before quitting the shell # _closeHilinkAPI (optional: add parameter "save" to save the session/token data for subsequent calls. Valid for a few minutes.) +# +# BE AWARE, THAT THE API USES SOME GLOBAL VARIABLES : hilink_host, user, password, pin, response, status +# USE THESE ONLY TO COMMUNICATE WITH THE API. +# DO NOT USE THE VARIABLE PRE_FIX "hilink_" FOR YOUR OWN VARIABLES +# -host_default="192.168.8.1" -save_file="/tmp/hilink_api_saved.dat" -save_age=60 -header_file="/tmp/hilink_login_hdr.txt" +hilink_host_default="192.168.8.1" +hilink_save_file="/tmp/hilink_api_saved.dat" +hilink_save_age=60 +hilink_header_file="/tmp/hilink_login_hdr.txt" # initialize function _initHilinkAPI() { - if [ -z "$host" ]; then host=$host_default; fi + local age + if [ -z "$hilink_host" ]; then hilink_host=$hilink_host_default; fi if ! _hostReachable; then return 1; fi - if [ -f $save_file ]; then # found file with saved data + if [ -f $hilink_save_file ]; then # found file with saved data _getSavedData - age=$(( $(date +%s) - $(stat $save_file -c %Y) )) - if [[ $age -gt $save_age ]]; then - rm -f $save_file + age=$(( $(date +%s) - $(stat $hilink_save_file -c %Y) )) + if [[ $age -gt $hilink_save_age ]]; then + rm -f $hilink_save_file _logout _sessToken fi fi - if [ -z "$sessID" ] || [ -z "$token" ]; then _sessToken; fi + if [ -z "$hilink_sessID" ] || [ -z "$hilink_token" ]; then _sessToken; fi _login return $? } function _getSavedData() { - if [ -f $save_file ]; then # restore saved session data - dat=$(cat $save_file) - sessID=$(echo "$dat" | sed -nr 's/sessionid: ([a-z0-9]*)/\1/ip') - token=$(echo "$dat" | sed -nr 's/token: ([a-z0-9]*)/\1/ip') - tokenlist=( $(echo "$dat" | sed -nr 's/tokenlist: ([a-z0-9 ]*)/\1/ip') ) + local dat + if [ -f $hilink_save_file ]; then # restore saved session data + dat=$(cat $hilink_save_file) + hilink_sessID=$(echo "$dat" | sed -nr 's/sessionid: ([a-z0-9]*)/\1/ip') + hilink_token=$(echo "$dat" | sed -nr 's/token: ([a-z0-9]*)/\1/ip') + hilink_tokenlist=( $(echo "$dat" | sed -nr 's/tokenlist: ([a-z0-9 ]*)/\1/ip') ) fi } # Cleanup # parameter: "save" - will store sessionid and tokens in file function _closeHilinkAPI() { - if [ -z "$host" ]; then host=$host_default; fi + local opt + if [ -z "$hilink_host" ]; then hilink_host=$hilink_host_default; fi if ! _hostReachable; then return 1; fi - rm -f $save_file + rm -f $hilink_save_file [ ! -z "$1" ] && opt="${1,,}" if [ ! -z "$opt" ] && [ "$opt" = "save" ]; then - echo "sessionid: $sessID" > $save_file - echo "token: $token" >> $save_file - echo "tokenlist: ${tokenlist[@]}" >> $save_file + echo "sessionid: $hilink_sessID" > $hilink_save_file + echo "token: $hilink_token" >> $hilink_save_file + echo "tokenlist: ${hilink_tokenlist[@]}" >> $hilink_save_file fi _logout - tokenlist="" - sessID="" - token="" + hilink_tokenlist="" + hilink_sessID="" + hilink_token="" return 0 } @@ -111,6 +121,7 @@ function _getStatus() { } function _isConnected() { + local conn conn=$(_getStatus "connectionstatus") status="NO" if [ ! -z "$conn" ] && [ $conn -eq 901 ]; then @@ -176,7 +187,7 @@ function _getMobileDataStatus() { } -# PIN of SIM can be passed either as $pin, or as parameter +# PIN of SIM can be passed either as $hilink_pin, or as parameter # parameter: PIN number of SIM card function _enableSIM() { #SimState: @@ -187,14 +198,15 @@ function _enableSIM() { #259 - check PIN, #260 - PIN required, #261 - PUK required - if [ ! -z "$1" ]; then pin="$1"; fi + local simstate + if [ ! -z "$1" ]; then hilink_pin="$1"; fi if ! _login; then return 1; fi if _sendRequest "api/pin/status"; then - simstate=`echo $response | sed -rn 's/.*([0-9]*)<\/simstate>.*/\1/pi'` + simstate=$(echo $response | sed -rn 's/.*([0-9]*)<\/simstate>.*/\1/pi') if [[ $simstate -eq 257 ]]; then status="SIM ready"; return 0; fi if [[ $simstate -eq 260 ]]; then - status="PIN required" - if [ ! -z "$pin" ]; then _setPIN "$pin"; fi + status="PIN required" + if [ ! -z "$hilink_pin" ]; then _setPIN "$hilink_pin"; fi return $? fi if [[ $simstate -eq 255 ]]; then status="NO SIM"; return 1; fi @@ -202,20 +214,20 @@ function _enableSIM() { return 1 } -# obtain session and verification token - stored in vars $sessID and $token +# obtain session and verification token - stored in vars $hilink_sessID and $token # parameter: none function _sessToken() { - tokenlist="" - token="" - sessID="" - response=$(curl -s http://$host/api/webserver/SesTokInfo -m 5 2> /dev/null) - if [ -z "$response" ]; then echo "No access to device at $host"; return 1; fi + hilink_tokenlist="" + hilink_token="" + hilink_sessID="" + response=$(curl -s http://$hilink_host/api/webserver/SesTokInfo -m 5 2> /dev/null) + if [ -z "$response" ]; then echo "No access to device at $hilink_host"; return 1; fi status=$(echo "$response" | sed -nr 's/.*([0-9]*)<\/code>.*/\1/ip') if [ -z "$status" ]; then - token=`echo $response | sed -r 's/.*(.*)<\/TokInfo>.*/\1/'` - sessID=`echo $response | sed -r 's/.*(.*)<\/SesInfo>.*/\1/'` - if [ ! -z "$sessID" ] && [ ! -z "$token" ]; then - sessID="SessionID=$sessID" + hilink_token=$(echo $response | sed -r 's/.*(.*)<\/TokInfo>.*/\1/') + hilink_sessID=$(echo $response | sed -r 's/.*(.*)<\/SesInfo>.*/\1/') + if [ ! -z "$hilink_sessID" ] && [ ! -z "$hilink_token" ]; then + hilink_sessID="SessionID=$hilink_sessID" return 0 fi fi @@ -223,38 +235,39 @@ function _sessToken() { } # unlock device (if locked) with user name and password -# requires stored user="admin"; pw="1234secret";host=$host_default +# requires stored hilink_user="admin"; hilink_password"1234secret";hilink_host=$hilink_host_default # parameter: none function _login() { + local ret encpw pwtype pwtype3 hashedpw pwtype4 if _loginState; then return 0; fi # login not required, or already done _sessToken # get password type if ! _sendRequest "api/user/state-login"; then return 1; fi pwtype=$(echo "$response" | sed -rn 's/.*([0-9])<\/password_type>.*/\1/pi') if [ -z "$pwtype" ];then pwtype=4; fi # fallback is type 4 - ret=1 - if [[ ! -z "$user" ]] && [[ ! -z "$pw" ]]; then + ret=1 + if [[ ! -z "$hilink_user" ]] && [[ ! -z "$hilink_password" ]]; then # password encoding # type 3 : base64(pw) encoded # type 4 : base64(sha256sum(user + base64(sha256sum(pw)) + token)) - pwtype3=$(echo -n "$pw" | base64 --wrap=0) - hashedpw=$(echo -n "$pw" | sha256sum -b | sed -nr 's/^([0-9a-z]*).*$/\1/ip' ) + pwtype3=$(echo -n "$hilink_password" | base64 --wrap=0) + hashedpw=$(echo -n "$hilink_password" | sha256sum -b | sed -nr 's/^([0-9a-z]*).*$/\1/ip' ) hashedpw=$(echo -n "$hashedpw" | base64 --wrap=0) - pwtype4=$(echo -n "$user$hashedpw$token" | sha256sum -b | sed -nr 's/^([0-9a-z]*).*$/\1/ip' ) + pwtype4=$(echo -n "$hilink_user$hashedpw$hilink_token" | sha256sum -b | sed -nr 's/^([0-9a-z]*).*$/\1/ip' ) encpw=$(echo -n "$pwtype4" | base64 --wrap=0) if [ $pwtype -ne 4 ]; then encpw=$pwtype3; fi - xmldata="$user$encpw$pwtype" - xtraopts="--dump-header $header_file" - rm -f $header_file + hilink_xmldata="$hilink_user$encpw$pwtype" + hilink_xtraopts="--dump-header $hilink_header_file" + rm -f $hilink_header_file _sendRequest "api/user/login" if [ ! -z "$status" ] && [ "$status" = "OK" ]; then # store the list of 30 tokens. Each token is valid for a single request - tokenlist=( $(cat $header_file | sed -rn 's/^__RequestVerificationToken:\s*([0-9a-z#]*).*$/\1/pi' | sed 's/#/ /g') ) + hilink_tokenlist=( $(cat $hilink_header_file | sed -rn 's/^__RequestVerificationToken:\s*([0-9a-z#]*).*$/\1/pi' | sed 's/#/ /g') ) _getToken - sessID=$(cat $header_file | grep -ioP 'SessionID=([a-z0-9]*)') - if [ ! -z "$sessID" ] && [ ! -z "$token" ]; then ret=0; fi + hilink_sessID=$(cat $hilink_header_file | grep -ioP 'SessionID=([a-z0-9]*)') + if [ ! -z "$hilink_sessID" ] && [ ! -z "$hilink_token" ]; then ret=0; fi fi - rm -f $header_file + rm -f $hilink_header_file fi return $ret } @@ -263,12 +276,12 @@ function _login() { # parameter: none function _logout() { if _loginState; then - xmldata="1" + hilink_xmldata="1" if _sendRequest "api/user/logout"; then - tokenlist="" - sessID="" - token="" - login_enabled="" + hilink_tokenlist="" + hilink_sessID="" + hilink_token="" + hilink_login_enabled="" fi return $? fi @@ -277,41 +290,44 @@ function _logout() { # parameter: none function _loginState() { - status="OK" - if [ -z "$login_enabled" ]; then _checkLoginEnabled; fi - if [ $login_enabled -eq 1 ]; then return 0; fi # login is disabled - _sendRequest "api/user/state-login" - state=`echo "$response" | sed -rn 's/.*(.*)<\/state>.*/\1/pi'` - if [ ! -z "$state" ] && [ $state -eq 0 ]; then # already logged in - return 0 - fi - return 1 + local state + status="OK" + if [ -z "$hilink_login_enabled" ]; then _checkLoginEnabled; fi + if [ $hilink_login_enabled -eq 1 ]; then return 0; fi # login is disabled + _sendRequest "api/user/state-login" + state=`echo "$response" | sed -rn 's/.*(.*)<\/state>.*/\1/pi'` + if [ ! -z "$state" ] && [ $state -eq 0 ]; then # already logged in + return 0 + fi + return 1 } function _checkLoginEnabled() { + local state if _sendRequest "api/user/hilink_login"; then - login_enabled=0 - state=$(echo $response | sed -rn 's/.*(.*)<\/hilink_login>.*/\1/pi') - if [ ! -z "$state" ] && [ $state -eq 0 ]; then # no login enabled - login_enabled=1 - fi - else - login_enabled="" - fi + hilink_login_enabled=0 + state=$(echo $response | sed -rn 's/.*(.*)<\/hilink_login>.*/\1/pi') + if [ ! -z "$state" ] && [ $state -eq 0 ]; then # no login enabled + hilink_login_enabled=1 + fi + else + hilink_login_enabled="" + fi } # switch mobile data on/off 1/0 -# if SIM is locked, $pin has to be set +# if SIM is locked, $hilink_pin has to be set # parameter: state - ON/OFF or 1/0 function _switchMobileData() { + local mode if [ -z "$1" ]; then return 1; fi _login mode="${1,,}" [ "$mode" = "on" ] && mode=1 [ "$mode" = "off" ] && mode=0 if [[ $mode -ge 0 ]]; then - if _enableSIM "$pin"; then - xmldata="$mode" + if _enableSIM "$hilink_pin"; then + hilink_xmldata="$mode" _sendRequest "api/dialup/mobile-dataswitch" return $? fi @@ -321,31 +337,33 @@ function _switchMobileData() { # parameter: PIN of SIM card function _setPIN() { + local pin if [ -z "$1" ]; then return 1; fi pin="$1" - xmldata="0$pin" + hilink_xmldata="0$pin" _sendRequest "api/pin/operate" return $? } -# Send request to host at http://$host/$apiurl -# data in $xmldata and options in $xtraopts +# Send request to host at http://$hilink_host/$apiurl +# data in $hilink_xmldata and options in $hilink_xtraopts # parameter: apiurl (e.g. "api/user/login") function _sendRequest() { + local ret apiurl status="ERROR" if [ -z "$1" ]; then return 1; fi apiurl="$1" ret=1 - if [ -z "$sessID" ] || [ -z "$token" ]; then _sessToken; fi - if [ -z "$xmldata" ];then - response=$(curl -s http://$host/$apiurl -m 10 \ - -H "Cookie: $sessID") + if [ -z "$hilink_sessID" ] || [ -z "$hilink_token" ]; then _sessToken; fi + if [ -z "$hilink_xmldata" ];then + response=$(curl -s http://$hilink_host/$apiurl -m 10 \ + -H "Cookie: $hilink_sessID") else - response=$(curl -s -X POST http://$host/$apiurl -m 10 \ + response=$(curl -s -X POST http://$hilink_host/$apiurl -m 10 \ -H "Content-Type: text/xml" \ - -H "Cookie: $sessID" \ - -H "__RequestVerificationToken: $token" \ - -d "$xmldata" $xtraopts 2> /dev/null) + -H "Cookie: $hilink_sessID" \ + -H "__RequestVerificationToken: $hilink_token" \ + -d "$hilink_xmldata" $hilink_xtraopts 2> /dev/null) _getToken fi if [ ! -z "$response" ];then @@ -363,28 +381,29 @@ function _sendRequest() { status="ERROR" fi if [[ "$status" =~ ERROR ]]; then _handleError; fi - xtraopts="" - xmldata="" + hilink_xtraopts="" + hilink_xmldata="" return $ret } # handle the list of tokens available after login # parameter: none function _getToken() { - if [ ! -z "$tokenlist" ] && [ ${#tokenlist[@]} -gt 0 ]; then - token=${tokenlist[0]} # get first token in list - tokenlist=("${tokenlist[@]:1}") # remove used token from list - if [ ${#tokenlist[@]} -eq 0 ]; then + if [ ! -z "$hilink_tokenlist" ] && [ ${#hilink_tokenlist[@]} -gt 0 ]; then + hilink_token=${hilink_tokenlist[0]} # get first token in list + hilink_tokenlist=("${hilink_tokenlist[@]:1}") # remove used token from list + if [ ${#hilink_tokenlist[@]} -eq 0 ]; then _logout # use the last token to logout fi - else - _sessToken # old token has been used - need new session + else + _sessToken # old token has been used - need new session fi } # Analyse $status for error code # return error text in $status function _handleError() { + local ret txt txt=$(_getErrorText) if [ -z "$code" ]; then return 1; fi ret=0 @@ -407,20 +426,21 @@ function _handleError() { return "$ret" } -declare -A err_hilink_api -err_hilink_api[101]="Unable to get session ID/token" -err_hilink_api[108001]="Invalid username/password" -err_hilink_api[108002]=${errors[108001]} -err_hilink_api[108006]=${errors[108001]} -err_hilink_api[108003]="User already logged in - need to wait a bit" -err_hilink_api[108007]="Too many login attempts - need to wait a bit" -err_hilink_api[125001]="Invalid session/request token" -err_hilink_api[125002]=${errors[125001]} -err_hilink_api[125003]=${errors[125001]} +declare -A hilink_err_api +hilink_err_api[101]="Unable to get session ID/token" +hilink_err_api[108001]="Invalid username/password" +hilink_err_api[108002]=${hilink_err_api[108001]} +hilink_err_api[108006]=${hilink_err_api[108001]} +hilink_err_api[108003]="User already logged in - need to wait a bit" +hilink_err_api[108007]="Too many login attempts - need to wait a bit" +hilink_err_api[125001]="Invalid session/request token" +hilink_err_api[125002]=${hilink_err_api[125001]} +hilink_err_api[125003]=${hilink_err_api[125001]} # check error and return error text # status passsed in $status, or $1 function _getErrorText() { + local err code errortext err="$status" code="0" if [ ! -z "$1" ]; then err="$1"; fi @@ -428,8 +448,8 @@ function _getErrorText() { errortext="$err" if [[ "$err" =~ ERROR\ *([0-9]*) ]] && [ ! -z "${BASH_REMATCH[1]}" ]; then code=${BASH_REMATCH[1]} - if [ ! -z "$code" ] && [ ! -z "${err_hilink_api[$code]}" ]; then - errortext="${err_hilink_api[$code]}" + if [ ! -z "$code" ] && [ ! -z "${hilink_err_api[$code]}" ]; then + errortext="${hilink_err_api[$code]}" fi fi echo $errortext @@ -437,8 +457,10 @@ function _getErrorText() { } function _hostReachable() { - avail=`timeout 0.5 ping -c 1 $host | sed -rn 's/.*time=.*/1/p'` - if [ -z "$avail" ]; then return 1; fi + local avail + avail=$( timeout 0.5 ping -c 1 $hilink_host | sed -rn 's/.*time=.*/1/p' ) + if [ -z "$avail" ]; then status="ERROR: Not reachable"; return 1; fi + status="OK" return 0; } @@ -446,6 +468,7 @@ function _hostReachable() { # call another function first! # parameter: tag-name function _valueFromResponse() { + local par value if [ -z "$response" ] || [ -z "$1" ]; then return 1; fi par="$1" value=$(echo $response | sed -rn 's/.*<'$par'>(.*)<\/'$par'>.*/\1/pi') @@ -468,15 +491,15 @@ function _keyValuePairs() { return 0 } -host=$host_default -user="admin" -pw="" -token="" -tokenlist="" -sessID="" -xmldata="" -xtraopts="" +hilink_token="" +hilink_tokenlist="" +hilink_sessID="" +hilink_xmldata="" +hilink_xtraopts="" +hilink_host=$hilink_host_default +hilink_user="admin" +hilink_password="" +hilink_pin="" response="" status="" -pwtype=-1 - + \ No newline at end of file diff --git a/config/client_config/info_huawei_hilink.sh b/config/client_config/info_huawei_hilink.sh index 32b27954..c98ee9fe 100644 --- a/config/client_config/info_huawei_hilink.sh +++ b/config/client_config/info_huawei_hilink.sh @@ -14,10 +14,10 @@ # zbchristian 2021 function _setAPIParams() { - if [ ! -z "$hostip" ]; then host="$hostip"; fi - if [ ! -z "$username" ]; then user="$username"; fi - if [ ! -z "$password" ]; then pw="$password"; fi - if [ ! -z "$simpin" ]; then pin="$simpin"; fi + if [ ! -z "$hostip" ]; then hilink_host="$hostip"; fi + if [ ! -z "$username" ]; then hilink_user="$username"; fi + if [ ! -z "$password" ]; then hilink_password="$password"; fi + if [ ! -z "$simpin" ]; then hilink_pin="$simpin"; fi } if [ -z "$1" ]; then echo "none"; exit; fi @@ -44,7 +44,7 @@ if [ "$opt" = "connected" ]; then result=$(_getMobileDataStatus) _closeHilinkAPI else - info_file="/tmp/huawei_infos_${hostip}_${id -u}.dat" + info_file="/tmp/huawei_infos_${hostip}_$(id -u).dat" if [ -f "$info_file" ]; then age=$(( $(date +%s) - $(stat $info_file -c %Y) )) if [[ $age -gt 10 ]]; then rm -f $info_file; fi @@ -75,7 +75,7 @@ else key="msisdn" ;; imei|imsi|rssi|rsrq|rsrp|sinr|ecio) - key="$opt" + key="$property" ;; signal) key="rsrq" diff --git a/config/client_config/onoff_huawei_hilink.sh b/config/client_config/onoff_huawei_hilink.sh index 2ee413d2..cd050016 100644 --- a/config/client_config/onoff_huawei_hilink.sh +++ b/config/client_config/onoff_huawei_hilink.sh @@ -5,6 +5,7 @@ # options: -u, --user - user name (default "admin") # -P, --password - password # -h, --host - host ip address (default 192.168.8.1) +# -d, --devname - device name (IP is extracted using default route) # -p, --pin - PIN of SIM card # -c, --connect - connect 0/1 to set datamode off/on # @@ -12,24 +13,37 @@ # # zbchristian 2021 -# include the hilink API (defaults: user=admin, host=192.168.8.1) +# include the hilink API (defaults: hilink_user=admin, hilink_host=192.168.8.1) source /usr/local/sbin/huawei_hilink_api.sh +# include the raspap helper functions +source /usr/local/sbin/raspap_helpers.sh + datamode="" +devname="" while [ -n "$1" ]; do case "$1" in - -u|--user) user="$2"; shift ;; - -P|--password) pw="$2"; shift ;; - -p|--pin) if [[ $2 =~ ^[0-9]{4,8} ]]; then pin="$2"; fi; shift ;; - -h|--host) host="$2"; shift ;; + -u|--user) hilink_user="$2"; shift ;; + -P|--password) hilink_password="$2"; shift ;; + -p|--pin) if [[ $2 =~ ^[0-9]{4,8} ]]; then hilink_pin="$2"; fi; shift ;; + -h|--host) hilink_host="$2"; shift ;; + -d|--devname) devname="$2"; shift ;; -c|--connect) if [ "$2" = "1" ]; then datamode=1; else datamode=0; fi; shift ;; esac shift done -echo "Hilink: switch device at $host to mode $datamode" | systemd-cat +if [ ! _loginState ] && [ -z "$hilink_password" ] || [ -z "$hilink_pin" ]; then _getAuthRouter; fi -status="usage: -c 1/0 to disconnect/disconnect" +if [ ! -z "$devname" ]; then # get host IP for given device name + gw=$(ip route list | sed -rn "s/default via (([0-9]{1,3}\.){3}[0-9]{1,3}).*dev $devname.*/\1/p") + if [ -z "$gw" ]; then exit; fi # device name not found in routing list -> abort + hilink_host="$gw" +fi + +echo "Hilink: switch device at $hilink_host to mode $datamode" | systemd-cat + +status="usage: -c 1/0 to disconnect/connect" if [ -z "$datamode" ] || [ ! _initHilinkAPI ]; then echo "Hilink: failed - return status: $status"; exit; fi if ! _switchMobileData "$datamode"; then echo -n "Hilink: could not switch the data mode on/off . Error: ";_getErrorText; fi diff --git a/config/client_config/raspap_helpers.sh b/config/client_config/raspap_helpers.sh new file mode 100644 index 00000000..a20ba309 --- /dev/null +++ b/config/client_config/raspap_helpers.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# +# Helper functions to extract informations from RaspAP config/settings +# +# zbchristian 2021 +# +# get the values of a RaspAP config variable +# call: _getRaspapConfig RASPAP_MOBILEDATA_CONFIG + +raspap_webroot="/var/www/html" + +function _getWebRoot() { + local path + path=$(cat /etc/lighttpd/lighttpd.conf | sed -rn "s/server.document-root \s*= \"([^ \s]*)\"/\1/p") + if [ ! -z "$path" ]; then raspap_webroot="$path"; fi + if [ -z "$path" ]; then return 1; else return 0; fi +} + +# expand an RaspAP config variable utilizing PHP +function _getRaspapConfig() { + local conf var + raspap_config="" + var="$1" + if [ ! -z "$var" ]; then + if ! _getWebRoot; then return 1; fi + conf="$raspap_webroot/includes/config.php" + if [ -f "$conf" ]; then + conf=$(php -r 'include "'$conf'"; echo '$var';' 2> /dev/null) + if [ ! -z "$conf" ] && [ -d ${conf%/*} ]; then raspap_config="$conf"; fi + fi + fi + if [ -z "$raspap_config" ]; then return 1; else return 0; fi +} + +# Username and password for mobile data devices is stored in a file (RASPAP_MOBILEDATA_CONFIG) +function _getAuthRouter() { + local mfile mdata pin user pw + if ! _getRaspapConfig "RASPI_MOBILEDATA_CONFIG"; then return 1; fi + mfile="$raspap_config" + if [ -f $mfile ]; then + mdata=$(cat "$mfile") + pin=$(echo "$mdata" | sed -rn 's/pin = ([^ \s]*)/\1/ip') + if [ ! -z "$pin" ]; then raspap_pin="$pin"; fi + user=$(echo "$mdata" | sed -rn 's/router_user = ([^ \s]*)/\1/ip') + if [ ! -z "$user" ]; then raspap_user="$user"; fi + pw=$(echo "$mdata" | sed -rn 's/router_pw = ([^ \s]*)/\1/ip') + if [ ! -z "$pw" ]; then raspap_password="$pw"; fi + return 0 + fi + return 1 +} diff --git a/config/client_config/start_huawei_hilink.service b/config/client_config/start_huawei_hilink@.service similarity index 76% rename from config/client_config/start_huawei_hilink.service rename to config/client_config/start_huawei_hilink@.service index 19d775d0..b735b1b1 100644 --- a/config/client_config/start_huawei_hilink.service +++ b/config/client_config/start_huawei_hilink@.service @@ -5,7 +5,7 @@ Description=Bring up HUAWEI mobile hilink device Type=oneshot RemainAfterExit=no ExecStart=/bin/sleep 15 -ExecStart=/usr/local/sbin/switchClientState.sh up +ExecStart=/usr/local/sbin/onoff_huawei_hilink.sh -c 1 -d %i [Install] Alias=start_ltemodem.service diff --git a/config/client_config/switchClientState.sh b/config/client_config/switchClientState.sh deleted file mode 100644 index acdd2892..00000000 --- a/config/client_config/switchClientState.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -# start with "sudo" -# parameters: up or on -# -# switch client state to UP -# the actual code is in PHP - -# get webroot -webroot=$(cat /etc/lighttpd/lighttpd.conf | sed -rn 's/server.document-root\s*=\s*\"(.*)\"\s*$/\1/p') -webuser=$(cat /etc/lighttpd/lighttpd.conf | sed -rn 's/server.username\s*=\s*\"(.*)\"\s*$/\1/p') -if [ -z "$webroot" ] || [ ! -d "$webroot" ] || [ -z "$webuser" ]; then - echo "$0 : Problem to obtain webroot directory and/or web user - exit" | systemd-cat - exit -fi -cd $webroot - -state="" -if [ ! -z $1 ] && [[ $1 =~ ^(up|on|UP|ON)$ ]]; then - state="up" -elif [ ! -z $1 ] && [[ $1 =~ ^(down|off|DOWN|OFF)$ ]]; then - state="down" -fi - -[ -z "$state" ] && exit - -sudo -u $webuser php << _EOF_ - -_EOF_ - - diff --git a/config/client_udev_prototypes.json b/config/client_udev_prototypes.json index a147e776..bd49f419 100644 --- a/config/client_udev_prototypes.json +++ b/config/client_udev_prototypes.json @@ -39,10 +39,10 @@ "type": "hilink", "type_info": "Huawei Hilink", "clientid": 4, - "comment": "Huawei mobile data device in router mode. Control via HTTP", + "comment": "Huawei mobile data device in router mode. Control via HTTP. Device is connecting via service", "name_prefix": "hilink", "default_ip": "192.168.8.1", - "udev_rule": "SUBSYSTEM==\"net\", ACTION==\"add\", SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"$IDVENDOR$\", ATTRS{idProduct}==\"$IDPRODUCT$\", NAME=\"$DEVNAME$\", ENV{raspapType}=\"hilink\", TAG+=\"systemd\", ENV{SYSTEMD_WANTS}=\"start start_huawei_hilink.service\" " + "udev_rule": "SUBSYSTEM==\"net\", ACTION==\"add\", SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"$IDVENDOR$\", ATTRS{idProduct}==\"$IDPRODUCT$\", NAME=\"$DEVNAME$\", ENV{raspapType}=\"hilink\", TAG+=\"systemd\", ENV{SYSTEMD_WANTS}=\"start start_huawei_hilink@hilink%n.service\" " }, { "type": "phone", diff --git a/installers/raspap.sudoers b/installers/raspap.sudoers index 355fd8eb..fc692e1c 100644 --- a/installers/raspap.sudoers +++ b/installers/raspap.sudoers @@ -53,7 +53,6 @@ www-data ALL=(ALL) NOPASSWD:/usr/local/sbin/onoff_huawei_hilink.sh * www-data ALL=(ALL) NOPASSWD:/bin/sed -i * /etc/wvdial.conf www-data ALL=(ALL) NOPASSWD:/bin/sed -i * /etc/udev/rules.d/80-raspap-net-devices.rules www-data ALL=(ALL) NOPASSWD:/usr/bin/tee -a /etc/udev/rules.d/80-raspap-net-devices.rules -www-data ALL=(ALL) NOPASSWD:/usr/local/sbin/switchClientState.sh * www-data ALL=(ALL) NOPASSWD:/usr/bin/tee /tmp/wireguard.log www-data ALL=(ALL) NOPASSWD:/bin/systemctl * wg-quick@wg0 www-data ALL=(ALL) NOPASSWD:/usr/bin/wg