From b99752c4cd9931fe64d42d705068b796d1553900 Mon Sep 17 00:00:00 2001 From: Christian Zeitnitz Date: Fri, 21 May 2021 14:57:14 +0200 Subject: [PATCH] Implement login for Hilink devices --- ajax/networking/save_net_dev_config.php | 28 ++-- config/client_config/info_huawei.sh | 11 +- config/client_config/info_huawei_hilink.sh | 136 +++++++++++--------- config/client_config/onoff_huawei_hilink.sh | 46 +++---- config/config.php | 1 + includes/get_clients.php | 31 +++-- templates/networking.php | 2 +- 7 files changed, 132 insertions(+), 123 deletions(-) diff --git a/ajax/networking/save_net_dev_config.php b/ajax/networking/save_net_dev_config.php index be2c04dd..a95baa50 100644 --- a/ajax/networking/save_net_dev_config.php +++ b/ajax/networking/save_net_dev_config.php @@ -14,19 +14,26 @@ require_once '../../includes/functions.php'; if (isset($_POST['interface'])) { $int = $_POST['interface']; $cfg = []; - $file = $int.".ini"; + $file = $RASPI_MOBILEDATA_CONFIG; $cfgfile="/etc/wvdial.conf"; if ( $int == "mobiledata") { $cfg['pin'] = $_POST["pin-mobile"]; $cfg['apn'] = $_POST["apn-mobile"]; $cfg['apn_user'] = $_POST["apn-user-mobile"]; $cfg['apn_pw'] = $_POST["apn-pw-mobile"]; + $cfg['router_user'] = $cfg['apn_user'] ; + $cfg['router_pw'] = $cfg['apn_pw'] ; if (file_exists($cfgfile)) { if($cfg["pin"] !== "") exec('sudo /bin/sed -i "s/CPIN=\".*\"/CPIN=\"'.$cfg["pin"].'\"/gi" '.$cfgfile); if($cfg["apn"] !== "") exec('sudo /bin/sed -i "s/\"IP\"\,\".*\"/\"IP\"\,\"'.$cfg["apn"].'\"/gi" '.$cfgfile); if($cfg["apn_user"] !== "") exec('sudo /bin/sed -i "s/^username = .*$/Username = '.$cfg["apn_user"].'/gi" '.$cfgfile); if($cfg["apn_pw"] !== "") exec('sudo /bin/sed -i "s/^password = .*$/Password = '.$cfg["apn_pw"].'/gi" '.$cfgfile); } + if (write_php_ini($cfg, RASPI_MOBILEDATA_CONFIG)) { + $jsonData = ['return'=>0,'output'=>['Successfully saved mobile data settings']]; + } else { + $jsonData = ['return'=>1,'output'=>['Error saving mobile data settings']]; + } } else if ( preg_match("/netdevices/",$int)) { if(!isset($_POST['opts']) ) { $jsonData = ['return'=>0,'output'=>['No valid data to add/delete udev rule ']]; @@ -75,26 +82,9 @@ if (isset($_POST['interface'])) { if (!empty($rule)) exec('echo \''.$rule.'\' | sudo /usr/bin/tee -a '.$udevfile); } $jsonData = ['return'=>0,'output'=>['Settings changed for device '.$dev. '
Changes will only be in effect after reconnecting the device' ] ]; - echo json_encode($jsonData); - return; } } else { - $ip = $_POST[$int.'-ipaddress']; - $netmask = mask2cidr($_POST[$int.'-netmask']); - $dns1 = $_POST[$int.'-dnssvr']; - $dns2 = $_POST[$int.'-dnssvralt']; - - $cfg['interface'] = $int; - $cfg['routers'] = $_POST[$int.'-gateway']; - $cfg['ip_address'] = $ip."/".$netmask; - $cfg['domain_name_server'] = $dns1." ".$dns2; - $cfg['static'] = $_POST[$int.'-static']; - $cfg['failover'] = $_POST[$int.'-failover']; - } - if (write_php_ini($cfg, RASPI_CONFIG.'/networking/'.$file)) { - $jsonData = ['return'=>0,'output'=>['Successfully Updated Network Configuration']]; - } else { - $jsonData = ['return'=>1,'output'=>['Error saving network configuration to file']]; + $jsonData = ['return'=>1,'output'=>['Unknown network configuration']]; } } else { $jsonData = ['return'=>2,'output'=>'Unable to detect interface']; diff --git a/config/client_config/info_huawei.sh b/config/client_config/info_huawei.sh index 475767fe..540ede98 100644 --- a/config/client_config/info_huawei.sh +++ b/config/client_config/info_huawei.sh @@ -5,28 +5,31 @@ # $2 : (optional) type - hilink or modem (default: hilink) # $3 : (optional) for hilink: ip address of the device (default: 192.168.8.1) # for modem: tty interface for communication (default: /dev/ttypUSB2) +# $4 : more options can be added for Hilink devices ('-u user -P password -p pin'). These are passed to the corresponding script # # requires: bc # calls the scripts info_huawei_hilink.sh and info_huawei_modem.sh (same path as this script) # # zbchristian 2020 # +path=$(dirname "$0") opt="device" if [ ! -z "$1" ]; then opt=${1,,}; fi type="hilink" if [ ! -z "$2" ]; then type=${2,,}; fi -path=$(dirname "$0") +parms="" if [ "$type" = "hilink" ]; then - connect="192.168.8.1" - if [ ! -z "$3" ]; then connect=$3; fi + connect="-h 192.168.8.1" + if [ ! -z "$3" ]; then connect="-h $3"; fi + if [ ! -z "$4" ]; then parms="$4"; fi script="$path/info_huawei_hilink.sh" else connect="/dev/ttyUSB2" if [ ! -z "$3" ]; then connect=$3; fi script="$path/info_huawei_modem.sh" fi -res=$($script $opt $connect) +res=$($script $opt $connect $parms) # some results require special treatment case $opt in diff --git a/config/client_config/info_huawei_hilink.sh b/config/client_config/info_huawei_hilink.sh index d3b20541..345c1fe5 100644 --- a/config/client_config/info_huawei_hilink.sh +++ b/config/client_config/info_huawei_hilink.sh @@ -1,75 +1,93 @@ #!/bin/bash -# Information about HUAWEI hilink (router) modem -# ---------------------------------------------- +# Information about HUAWEI hilink +# ------------------------------- # get info about the device and signal -# parameter: $1 - see opts list below -# $2 - host ip address for API calls (optional) +# parameter: $1 - "connected", "device", "ipaddress", "mode", "signal" (see case statement below) +# -u,--user - username +# -P,--password - password +# -p,--pin - SIM pin +# -h,--host - host ip address for API calls (optional) # returns the value of the parameter, or "none" if not found or empty # # All device informations are buffered for 5 secs to speed up subsequent calls # -# zbchristian 2020 +# 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 "$1" ]; then echo "none"; exit; fi - -host="192.168.8.1" - -status="no option given" -if [ ! -z "$2" ]; then host="$2"; fi - opt="${1,,}" +shift +while [ -n "$1" ]; do + case "$1" in + -u|--user) username="$2"; shift ;; + -P|--password) password="$2"; shift ;; + -p|--pin) simpin="$2"; shift ;; + -h|--host) hostip="$2"; shift ;; + esac + shift +done + +status="no valid option given" result="none" if [ "$opt" = "connected" ]; then - source /usr/local/sbin/huawei_hilink_api.sh - if ! _initHilinkAPI; then echo "none"; exit; fi - result=$(_getMobileDataStatus) - _closeHilinkAPI -else - info_file="/tmp/huawei_infos_$host.dat" - if [ -f "$info_file" ]; then - age=$(( $(date +%s) - $(stat $info_file -c %Y) )) - if [[ $age -gt 5 ]]; then rm -f $info_file; fi - fi - - if [ -f "$info_file" ]; then - infos=$(cat $info_file) - else - source /usr/local/sbin/huawei_hilink_api.sh - if ! _initHilinkAPI; then echo "none"; exit; fi - infos=$(_getAllInformations) + source /usr/local/sbin/huawei_hilink_api.sh + if ! _initHilinkAPI; then echo "none"; exit; fi + _setAPIParams + result=$(_getMobileDataStatus) _closeHilinkAPI - if [ ! -z "$infos" ]; then echo "$infos" > /tmp/huawei_infos_$host.dat; fi - fi +else + info_file="/tmp/huawei_infos_$host.dat" + if [ -f "$info_file" ]; then + age=$(( $(date +%s) - $(stat $info_file -c %Y) )) + if [[ $age -gt 5 ]]; then rm -f $info_file; fi + fi - case "$opt" in - device|devicename) - key="devicename" - ;; - ipaddress|wanipaddress) - key="wanipaddress" - ;; - mode) - key="workmode" - ;; - telnumber) - key="msisdn" - ;; - imei|imsi|rssi|rsrq|rsrp|sinr|ecio) - key="$opt" - ;; - signal) - key="rsrq" - ;; - operator|fullname) - key="fullname" - ;; - *) - key="" - ;; - esac - if [ -z "$key" ]; then result="none"; fi - result=$(echo "$infos" | sed -rn 's/'$key'=\"([^ \s]*)\"/\1/ip') - if [ -z "$result" ]; then result="none"; fi + if [ -f "$info_file" ]; then + infos=$(cat $info_file) + else + source /usr/local/sbin/huawei_hilink_api.sh + if ! _initHilinkAPI; then echo "none"; exit; fi + _setAPIParams + infos=$(_getAllInformations) + _closeHilinkAPI + if [ ! -z "$infos" ]; then echo "$infos" > /tmp/huawei_infos_$host.dat; fi + fi + + case "$opt" in + device|devicename) + key="devicename" + ;; + ipaddress|wanipaddress) + key="wanipaddress" + ;; + mode) + key="workmode" + ;; + telnumber) + key="msisdn" + ;; + imei|imsi|rssi|rsrq|rsrp|sinr|ecio) + key="$opt" + ;; + signal) + key="rsrq" + ;; + operator|fullname) + key="fullname" + ;; + *) + key="" + ;; + esac + if [ -z "$key" ]; then result="none"; fi + result=$(echo "$infos" | sed -rn 's/'$key'=\"([^ \s]*)\"/\1/ip') + if [ -z "$result" ]; then result="none"; fi fi echo -n "$result" diff --git a/config/client_config/onoff_huawei_hilink.sh b/config/client_config/onoff_huawei_hilink.sh index 65587d01..2ee413d2 100644 --- a/config/client_config/onoff_huawei_hilink.sh +++ b/config/client_config/onoff_huawei_hilink.sh @@ -1,42 +1,30 @@ #!/bin/bash # connect/disconnect Huawei mobile data stick in Hilink mode (e.g. E3372h) # ======================================================================== -# - send xml formatted string via HTTP API to stick -# - Requires session and verification token, which is obtained by an API call # -# options: -l "user":"password" - login data - DOES NOT WORK YET -# -h 192.168.8.1 - host ip address -# -p 1234 - PIN of SIM card -# -c 0/1 - connect - set datamode off/on +# options: -u, --user - user name (default "admin") +# -P, --password - password +# -h, --host - host ip address (default 192.168.8.1) +# -p, --pin - PIN of SIM card +# -c, --connect - connect 0/1 to set datamode off/on +# # required software: curl, base64, sha256sum # # zbchristian 2021 -# include the hilink API +# include the hilink API (defaults: user=admin, host=192.168.8.1) source /usr/local/sbin/huawei_hilink_api.sh -# handle options - -host="192.168.8.1" -pin="" -user="" -pw="" datamode="" - -while getopts ":c:h:l:m:p:" opt; do - case $opt in - h) if [[ $OPTARG =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then host="$OPTARG"; fi - ;; - p) if [[ $OPTARG =~ ^[0-9]{4,8} ]]; then pin="$OPTARG"; fi - ;; - l) if [[ $OPTARG =~ ^[0-9a-zA-Z]*:.*$ ]]; then - user=$(echo "$OPTARG" | cut -d':' -f1); - pw=$(echo "$OPTARG" | cut -d':' -f2); - fi - ;; - c) if [[ $OPTARG == "1" ]]; then datamode=1; else datamode=0; fi - ;; - esac +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 ;; + -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 @@ -44,7 +32,7 @@ echo "Hilink: switch device at $host to mode $datamode" | systemd-cat status="usage: -c 1/0 to disconnect/disconnect" if [ -z "$datamode" ] || [ ! _initHilinkAPI ]; then echo "Hilink: failed - return status: $status"; exit; fi -if ! _switchMobileData "$datamode"; then echo "Hilink: could not switch the data mode on/off . Error: ";_getErrorText; fi +if ! _switchMobileData "$datamode"; then echo -n "Hilink: could not switch the data mode on/off . Error: ";_getErrorText; fi if ! _closeHilinkAPI; then echo -n "Hilink: failed - return status: $status . Error: ";_getErrorText; fi diff --git a/config/config.php b/config/config.php index 8003a320..87b17830 100755 --- a/config/config.php +++ b/config/config.php @@ -28,6 +28,7 @@ define('RASPI_LIGHTTPD_CONFIG', '/etc/lighttpd/lighttpd.conf'); define('RASPI_ACCESS_CHECK_IP', '1.1.1.1'); define('RASPI_ACCESS_CHECK_DNS', 'one.one.one.one'); define('RASPI_CLIENT_CONFIG_PATH', '/etc/raspap/networking/client_udev_prototypes.json'); +define('RASPI_MOBILEDATA_CONFIG', '/etc/raspap/networking/mobiledata.ini'); define('RASPI_CLIENT_SCRIPT_PATH', '/usr/local/sbin'); // Constant for the 5GHz wireless regulatory domain diff --git a/includes/get_clients.php b/includes/get_clients.php index 094cb8bf..11a74e94 100644 --- a/includes/get_clients.php +++ b/includes/get_clients.php @@ -128,23 +128,26 @@ function getClients($simple=true) $cl["device"][$i]["operator"] = $res[0]; break; case "hilink": + $pin=$user=$pw=""; + getMobileLogin($pin,$pw,$user); + $opts=$pin.' '.$user.' '.$pw; unset($res); // exec("ip link show $dev 2> /dev/null | grep -oP ' UP '",$res); exec("ifconfig -a | grep -i $dev -A 1 | grep -oP '(?<=inet )([0-9]{1,3}\.){3}'", $apiadd); $apiadd = !empty($apiadd) ? $apiadd[0]."1" : ""; unset($res); - exec("$path/info_huawei.sh mode hilink $apiadd", $res); + exec("$path/info_huawei.sh mode hilink $apiadd \"$opts\" ", $res); $cl["device"][$i]["mode"] = $res[0]; unset($res); - exec("$path/info_huawei.sh device hilink $apiadd", $res); + exec("$path/info_huawei.sh device hilink $apiadd \"$opts\" ", $res); if ($res[0] != "none" ) { $cl["device"][$i]["model"] = $res[0]; } unset($res); - exec("$path/info_huawei.sh signal hilink $apiadd", $res); + exec("$path/info_huawei.sh signal hilink $apiadd \"$opts\" ", $res); $cl["device"][$i]["signal"] = $res[0]; unset($ipadd); - exec("$path/info_huawei.sh ipaddress hilink $apiadd", $ipadd); + exec("$path/info_huawei.sh ipaddress hilink $apiadd \"$opts\" ", $ipadd); if (!empty($ipadd) && $ipadd[0] !== "none" ) { $cl["device"][$i]["connected"] = "y"; $cl["device"][$i]["wan_ip"] = $ipadd[0]; @@ -153,7 +156,7 @@ function getClients($simple=true) $cl["device"][$i]["wan_ip"] = "-"; } unset($res); - exec("$path/info_huawei.sh operator hilink $apiadd", $res); + exec("$path/info_huawei.sh operator hilink $apiadd \"$opts\" ", $res); $cl["device"][$i]["operator"] = $res[0]; break; case "phone": @@ -194,6 +197,15 @@ function getClientType($dev) { return $type; } +function getMobileLogin(&$pin,&$pw,&$user) { + if (file_exists(($f = RASPI_MOBILEDATA_CONFIG))) { + $dat = parse_ini_file($f); + $pin = (isset($dat["pin"]) && preg_match("/^[0-9]*$/", $dat["pin"])) ? "-p ".$dat["pin"] : ""; + $user = (isset($dat["router_user"]) && !empty($dat["router_user"]) ) ? "-u ".$dat["router_user"] : ""; + $pw = (isset($dat["router_pw"]) && !empty($dat["router_pw"]) ) ? "-P ".$dat["router_pw"] : ""; + } +} + function loadClientConfig() { // load network device config file for UDEV rules into $_SESSION @@ -271,12 +283,9 @@ function setClientState($state) preg_match("/^([0-9]{1,3}\.){3}/", $connected, $ipadd); $ipadd = $ipadd[0].'1'; // ip address of the Hilink api $mode = ($state == "up") ? 1 : 0; - $pin=""; - if (file_exists(($f = RASPI_CONFIG."/networking/mobiledata.ini"))) { - $dat = parse_ini_file($f); - $pin = (isset($dat["pin"]) && preg_match("/^[0-9]*$/", $dat["pin"])) ? $dat["pin"] : ""; - } - exec('sudo '.RASPI_CLIENT_SCRIPT_PATH.'/onoff_huawei_hilink.sh -c '.$mode.' -h '.$ipadd.' -p '.$pin); + $pin=$user=$pw=""; + getMobileLogin($pin,$pw,$user) + exec('sudo '.RASPI_CLIENT_SCRIPT_PATH.'/onoff_huawei_hilink.sh -c '.$mode.' -h '.$ipadd.' '.$pin.' '.$user.' '.$pw); break; case "ppp": if ($state == "up") { diff --git a/templates/networking.php b/templates/networking.php index f497cb28..578495e0 100755 --- a/templates/networking.php +++ b/templates/networking.php @@ -81,7 +81,7 @@ -