diff --git a/README.md b/README.md index f3b83e2..9d7cbe2 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ Add the following to the end of `/etc/sudoers`: ```sh www-data ALL=(ALL) NOPASSWD:/sbin/ifdown wlan0,/sbin/ifup wlan0,/bin/cat /etc/wpa_supplicant/wpa_supplicant.conf,/bin/cp /tmp/wifidata /etc/wpa_supplicant/wpa_supplicant.conf,/sbin/wpa_cli scan_results, /sbin/wpa_cli scan,/bin/cp /tmp/hostapddata /etc/hostapd/hostapd.conf, /etc/init.d/hostapd start,/etc/init.d/hostapd stop,/etc/init.d/dnsmasq start, /etc/init.d/dnsmasq stop,/bin/cp /tmp/dhcpddata /etc/dnsmasq.conf, /sbin/shutdown -h now, /sbin/reboot +www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli reconfigure ``` Once those modifications are done, git clone the files to `/var/www`. diff --git a/dist/js/functions.js b/dist/js/functions.js index 5adf581..e916430 100644 --- a/dist/js/functions.js +++ b/dist/js/functions.js @@ -1,74 +1,9 @@ -function WiFiDown() { - var down = confirm("Take down wlan0 ?"); - if(down) { - } else { - alert("Action cancelled"); - } -} - -function UpdateNetworks() { - var existing = document.getElementById("networkbox").getElementsByTagName('div').length; - document.getElementById("Networks").value = existing; -} - -function AddNetwork() { -// existing = document.getElementById("networkbox").getElementsByTagName('div').length; -// existing++; - Networks++ - var Networks = document.getElementById('Networks').value; - document.getElementById('networkbox').innerHTML += '

Network '+Networks+'

\ -
\ -
\ -
'; - Networks++; - document.getElementById('Networks').value=Networks; - -} - -function AddScanned(network) { - - existing = document.getElementById("networkbox").getElementsByTagName('div').length; - var Networks = document.getElementById('Networks').value; - //if(existing != 0) { - Networks++; - //} - - document.getElementById('Networks').value=Networks; - document.getElementById('networkbox').innerHTML += '

Network '+Networks+'

\ -
\ -
\ -
'; - document.getElementById('ssid'+Networks).value = network; - if(existing == 0) { - Networks++ - document.getElementById('Networks').value = Networks; - } -} - -function CheckSSID(ssid) { - if(ssid.value.length>31) { - ssid.style.background='#FFD0D0'; - document.getElementById('Save').disabled = true; - } else { - ssid.style.background='#D0FFD0' - document.getElementById('Save').disabled = false; - } -} - -function CheckPSK(psk) { - if(psk.value.length < 8) { - psk.style.background='#FFD0D0'; - document.getElementById('Save').disabled = true; - } else { - psk.style.background='#D0FFD0'; - document.getElementById('Save').disabled = false; - } -} - -function DeleteNetwork(network) { - element = document.getElementById('Networkbox'+network); - element.parentNode.removeChild(element); - var Networks = document.getElementById('Networks').value; - Networks-- - document.getElementById('Networks').value = Networks; +function CheckPSK(psk, id) { + if(psk.value.length < 8 || psk.value.length > 63) { + psk.style.background='#FFD0D0'; + document.getElementById(id).disabled = true; + } else { + psk.style.background='#D0FFD0'; + document.getElementById(id).disabled = false; + } } diff --git a/includes/configure_client.php b/includes/configure_client.php new file mode 100755 index 0000000..ba2e9e6 --- /dev/null +++ b/includes/configure_client.php @@ -0,0 +1,213 @@ + false, 'configured' => true, 'connected' => false); + } elseif ($network !== null) { + if (preg_match('/^\s*}\s*$/', $line)) { + $networks[$ssid] = $network; + $network = null; + $ssid = null; + } elseif ($lineArr = preg_split('/\s*=\s*/', trim($line))) { + switch(strtolower($lineArr[0])) { + case 'ssid': + $ssid = trim($lineArr[1], '"'); + break; + case 'psk': + if (array_key_exists('passphrase', $network)) { + break; + } + case '#psk': + $network['protocol'] = 'WPA'; + case 'wep_key0': // Untested + $network['passphrase'] = trim($lineArr[1], '"'); + break; + case 'key_mgmt': + if (! array_key_exists('passphrase', $network) && $lineArr[1] === 'NONE') { + $network['protocol'] = 'Open'; + } + break; + } + } + } + } + + if ( isset($_POST['client_settings']) && CSRFValidate() ) { + $tmp_networks = $networks; + if ($wpa_file = fopen('/tmp/wifidata', 'w')) { + fwrite($wpa_file, 'ctrl_interface=DIR=' . RASPI_WPA_CTRL_INTERFACE . ' GROUP=netdev' . PHP_EOL); + fwrite($wpa_file, 'update_config=1' . PHP_EOL); + + foreach(array_keys($_POST) as $post) { + if (preg_match('/delete(\d+)/', $post, $post_match)) { + unset($tmp_networks[$_POST['ssid' . $post_match[1]]]); + } elseif (preg_match('/update(\d+)/', $post, $post_match)) { + // NB, at the moment, the value of protocol from the form may + // contain HTML line breaks + $tmp_networks[$_POST['ssid' . $post_match[1]]] = array( + 'protocol' => ( $_POST['protocol' . $post_match[1]] === 'Open' ? 'Open' : 'WPA' ), + 'passphrase' => $_POST['passphrase' . $post_match[1]], + 'configured' => true + ); + } + } + + $ok = true; + foreach($tmp_networks as $ssid => $network) { + if ($network['protocol'] === 'Open') { + fwrite($wpa_file, "network={".PHP_EOL); + fwrite($wpa_file, "\tssid=\"".$ssid."\"".PHP_EOL); + fwrite($wpa_file, "\tkey_mgmt=NONE".PHP_EOL); + fwrite($wpa_file, "}".PHP_EOL); + } else { + if (strlen($network['passphrase']) >=8 && strlen($network['passphrase']) <= 63) { + exec( 'wpa_passphrase '.escapeshellarg($ssid). ' ' . escapeshellarg($network['passphrase']),$wpa_passphrase ); + foreach($wpa_passphrase as $line) { + fwrite($wpa_file, $line.PHP_EOL); + } + } else { + $status->addMessage('WPA passphrase must be between 8 and 63 characters', 'danger'); + $ok = false; + + } + } + + } + + if ($ok) { + system( 'sudo cp /tmp/wifidata ' . RASPI_WPA_SUPPLICANT_CONFIG, $returnval ); + if( $returnval == 0 ) { + exec('sudo wpa_cli reconfigure', $reconfigure_out, $reconfigure_return ); + if ($reconfigure_return == 0) { + $status->addMessage('Wifi settings updated successfully', 'success'); + $networks = $tmp_networks; + } else { + $status->addMessage('Wifi settings updated but cannot restart (cannon execute "wpa_cli reconfigure")', 'danger'); + } + } else { + $status->addMessage('Wifi settings failed to be updated', 'danger'); + } + } + } else { + $status->addMessage('Failed to updated wifi settings', 'danger'); + } + } + + exec( 'sudo wpa_cli scan' ); + sleep(3); + exec( 'sudo wpa_cli scan_results',$scan_return ); + for( $shift = 0; $shift < 2; $shift++ ) { + array_shift($scan_return); + } + // display output + foreach( $scan_return as $network ) { + $arrNetwork = preg_split("/[\t]+/",$network); + if (array_key_exists($arrNetwork[4], $networks)) { + $networks[$arrNetwork[4]]['visible'] = true; + $networks[$arrNetwork[4]]['channel'] = ConvertToChannel($arrNetwork[1]); + // TODO What if the security has changed? + } else { + $networks[$arrNetwork[4]] = array( + 'configured' => false, + 'protocol' => ConvertToSecurity($arrNetwork[3]), + 'channel' => ConvertToChannel($arrNetwork[1]), + 'passphrase' => '', + 'visible' => true, + 'connected' => false + ); + } + } + + exec( 'iwconfig wlan0', $iwconfig_return ); + foreach ($iwconfig_return as $line) { + if (preg_match( '/ESSID:\"(.+)\"/i',$line,$iwconfig_ssid )) { + $networks[$iwconfig_ssid[1]]['connected'] = true; + } + } +?> + +
+
+
+
Configure client
+ +
+

showMessages(); ?>

+

Client settings

+ +
+ + + + + + + + + + + + + $network) { ?> + + + + + + + + + + + + + + + + +
SSIDChannelSecurityPassphrase
+ + + + + + + + + + X--- + + +
+ + /> + + /> + + /> +
+
+
+
+ +
+
+
+ diff --git a/includes/functions.php b/includes/functions.php index 9d12869..739ebe1 100755 --- a/includes/functions.php +++ b/includes/functions.php @@ -17,7 +17,12 @@ function CSRFToken() { * */ function CSRFValidate() { - return hash_equals($_POST['csrf_token'], $_SESSION['csrf_token']); + if ( hash_equals($_POST['csrf_token'], $_SESSION['csrf_token']) ) { + return true; + } else { + error_log('CSRF violation'); + return false; + } } /** @@ -85,18 +90,12 @@ function ParseConfig( $arrConfig ) { * @return $channel */ function ConvertToChannel( $freq ) { - - $base = 2412; - $channel = 1; - for( $x = 0; $x < 13; $x++ ) { - if( $freq != $base ) { - $base = $base + 5; - $channel++; - } else { - return $channel; - } - } - return "Invalid Channel"; + $channel = ($freq - 2407)/5; + if ($channel > 0 && $channel < 14) { + return $channel; + } else { + return 'Invalid Channel'; + } } /** @@ -105,36 +104,28 @@ function ConvertToChannel( $freq ) { * @return string */ function ConvertToSecurity( $security ) { - - switch( $security ) { - case "[WPA2-PSK-CCMP][ESS]": - return "WPA2-PSK (AES)"; - break; - case "[WPA2-PSK-TKIP][ESS]": - return "WPA2-PSK (TKIP)"; - break; - case "[WPA2-PSK-CCMP][WPS][ESS]": - return "WPA/WPA2-PSK (TKIP/AES)"; - break; - case "[WPA2-PSK-TKIP+CCMP][WPS][ESS]": - return "WPA2-PSK (TKIP/AES) with WPS"; - break; - case "[WPA-PSK-TKIP+CCMP][WPS][ESS]": - return "WPA-PSK (TKIP/AES) with WPS"; - break; - case "[WPA-PSK-TKIP][WPA2-PSK-CCMP][WPS][ESS]": - return "WPA/WPA2-PSK (TKIP/AES)"; - break; - case "[WPA-PSK-TKIP+CCMP][WPA2-PSK-TKIP+CCMP][ESS]": - return "WPA/WPA2-PSK (TKIP/AES)"; - break; - case "[WPA-PSK-TKIP][ESS]": - return "WPA-PSK (TKIP)"; - break; - case "[WEP][ESS]": - return "WEP"; - break; - } + $options = array(); + preg_match_all('/\[([^\]]+)\]/s', $security, $matches); + foreach($matches[1] as $match) { + if (preg_match('/^(WPA\d?)/', $match, $protocol_match)) { + $protocol = $protocol_match[1]; + $matchArr = explode('-', $match); + if (count($matchArr) > 2) { + $options[] = $protocol . ' ('. $matchArr[2] .')'; + } else { + $options[] = $protocol; + } + } + } + + if (count($options) === 0) { + // This could also be WEP but wpa_supplicant doesn't have a way to determine + // this. + // And you shouldn't be using WEP these days anyway. + return 'Open'; + } else { + return implode('
', $options); + } } /** @@ -281,129 +272,6 @@ function DisplayDashboard(){ -
-
-
-
Configure client -
- -
- -

Client settings

-
-
- - 2 ) { - exec( 'wpa_passphrase '.$ssid. ' ' . $psk,$network ); - foreach($network as $b) { - $config .= "$b -"; - } - } - } - exec( "echo '$config' > /tmp/wifidata", $return ); - system( 'sudo cp /tmp/wifidata ' . RASPI_WPA_SUPPLICANT_CONFIG, $returnval ); - if( $returnval == 0 ) { - echo '
Wifi settings updated successfully -
'; - } else { - echo '
Wifi settings failed to be updated -
'; - } - - // scan networks - } elseif( isset($_POST['Scan']) ) { - $return = ''; - exec( 'sudo wpa_cli scan',$return ); - sleep(3); - exec( 'sudo wpa_cli scan_results',$return ); - for( $shift = 0; $shift < 4; $shift++ ) { - array_shift($return); - } - // display output - echo '
'; - echo '
'; - echo '

Networks found

'; - echo ''; - foreach( $return as $network ) { - $arrNetwork = preg_split("/[\t]+/",$network); - $bssid = $arrNetwork[0]; - $channel = ConvertToChannel($arrNetwork[1]); - $signal = $arrNetwork[2] . " dBm"; - $security = $arrNetwork[3]; - $ssid = $arrNetwork[4]; - echo '"; - } - echo '
SSIDChannelSignalSecurity
' . $ssid . " " . $channel . "" . $signal . "". ConvertToSecurity($security) ."
'; - - } else { - - // default action, output configured network(s) - exec(' sudo cat ' . RASPI_WPA_SUPPLICANT_CONFIG, $return); - $ssid = array(); - $psk = array(); - - foreach($return as $a) { - if(preg_match('/SSID/i',$a)) { - $arrssid = explode("=",$a); - $ssid[] = str_replace('"','',$arrssid[1]); - } - if(preg_match('/psk/i',$a)) { - $arrpsk = explode("=",$a); - $psk[] = str_replace('"','',$arrpsk[1]); - } - } - - $numSSIDs = count($ssid); - $output = '
'; - - if ( $numSSIDs > 0 ) { - for( $ssids = 0; $ssids < $numSSIDs; $ssids++ ) { - $output .= '
-
-
-
-
'; - } - $output .= '
'; - } else { - $status = '
Not connected -
'; - } - $output .= '
'; - $output .= ''; - echo $output; - } - ?> - - -
-
-
-
-