diff --git a/README.md b/README.md index f3b83e2f..9d7cbe2f 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/includes/configure_client.php b/includes/configure_client.php index 7e8d3478..62331951 100755 --- a/includes/configure_client.php +++ b/includes/configure_client.php @@ -8,122 +8,128 @@ function DisplayWPAConfig(){ $status = new StatusMessages(); $scanned_networks = array(); - if( isset($_POST['SaveWPAPSKSettings']) ) { - - $config = 'ctrl_interface=DIR='. RASPI_WPA_CTRL_INTERFACE .' GROUP=netdev -update_config=1 -'; - $networks = $_POST['Networks']; - for( $x = 0; $x < $networks; $x++ ) { - $network = ''; - $ssid = escapeshellarg( $_POST['ssid'.$x] ); - $protocol = $_POST['protocol'.$x]; - if ($protocol === 'Open') { - $config .= "network={".PHP_EOL; - $config .= "\tssid=\"".$ssid."\"".PHP_EOL; - $config .= "\tkey_mgmt=NONE".PHP_EOL; - $config .= "}".PHP_EOL; - } else { - $psk = escapeshellarg( $_POST['psk'.$x] ); - - if ( strlen($psk) >2 ) { - exec( 'wpa_passphrase '.$ssid. ' ' . $psk,$network ); - foreach($network as $b) { - $config .= "$b -"; - } - } - } - error_log($config); - } - exec( "echo '$config' > /tmp/wifidata", $return ); - system( 'sudo cp /tmp/wifidata ' . RASPI_WPA_SUPPLICANT_CONFIG, $returnval ); - if( $returnval == 0 ) { - $status->addMessage('Wifi settings updated successfully', 'success'); - } else { - $status->addMessage('Wifi settings failed to be updated', 'danger'); - } - } 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 - foreach( $return as $network ) { - $arrNetwork = preg_split("/[\t]+/",$network); - $scanned_networks[] = array( - 'bssid' => $arrNetwork[0], - 'channel' => ConvertToChannel($arrNetwork[1]), - 'signal' => $arrNetwork[2] . " dBm", - 'security' => ConvertToSecurity($arrNetwork[3]), - 'ssid' => $arrNetwork[4] - ); - } - echo ''; - } - -// // default action, output configured network(s) -// exec(' sudo cat ' . RASPI_WPA_SUPPLICANT_CONFIG, $supplicant_return); -// $ssid = array(); -// $psk = array(); -// -// foreach($supplicant_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); - - - - - // Find currently configured networks$ + // Find currently configured networks exec(' sudo cat ' . RASPI_WPA_SUPPLICANT_CONFIG, $known_return); - $known_networks = array(); - $network_id = null; + $network = null; + $ssid = null; foreach($known_return as $line) { - error_log($line); if (preg_match('/network\s*=/', $line)) { - $known_networks[] = array(); - $network_id = count($known_networks) - 1; - } elseif ($network_id !== null) { + $network = array('visible' => false, 'configured' => true); + } elseif ($network !== null) { if (preg_match('/^\s*}\s*$/', $line)) { - $network_id = null; + $networks[$ssid] = $network; + $network = null; + $ssid = null; } elseif ($lineArr = preg_split('/\s*=\s*/', trim($line))) { switch(strtolower($lineArr[0])) { case 'ssid': - $known_networks[$network_id]['ssid'] = trim($lineArr[1], '"'); + $ssid = trim($lineArr[1], '"'); break; case 'psk': - if (array_key_exists('passphrase', $known_networks[$network_id])) { + if (array_key_exists('passphrase', $network)) { break; } case '#psk': - $known_networks[$network_id]['protocol'] = 'WPA'; + $network['protocol'] = 'WPA'; case 'wep_key0': // Untested - $known_networks[$network_id]['passphrase'] = trim($lineArr[1], '"'); + $network['passphrase'] = trim($lineArr[1], '"'); break; case 'key_mgmt': - if (! array_key_exists('passphrase', $known_networks[$network_id]) &&$lineArr[1] === 'NONE') { - $known_networks[$network_id]['protocol'] = 'Open'; - $known_networks[$network_id]['passphrase'] = '(Open)'; + 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 + ); + } + } ?>
@@ -134,98 +140,59 @@ update_config=1

showMessages(); ?>

Client settings

-
-
-
- -
-
-
- - - + + + + + + + + + + + + + + $network) { ?> + + + + + + + + + + + + + + + + + + + + +
SSIDChannelSecurityPassphrase
+ + + X--- + + +
+ + /> + + + + />
- -

Networks found

-
- - - - - - - - - - - - - - - - - - - - - -
SSIDChannelSignalSecurity
-
- - - - -
-
-
- -
- -
-
-
- -
-
-
-
- - -
-
-
-
- - -
-
- -
-
- - -
-
- -
-
- -
-
- -
-
-
- - - - -
-
- -
+
+
+
diff --git a/includes/functions.php b/includes/functions.php index 6538f579..739ebe18 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; + } } /** diff --git a/installers/common.sh b/installers/common.sh index dbf1695e..917f3e43 100644 --- a/installers/common.sh +++ b/installers/common.sh @@ -97,7 +97,7 @@ function move_config_file() { function patch_system_files() { install_log "Patching system sudoers file" # patch /etc/sudoers file - sudo bash -c 'echo "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" | (EDITOR="tee -a" visudo)' \ + sudo bash -c 'echo "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,/sbin/wpa_cli reconfigure:/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" | (EDITOR="tee -a" visudo)' \ || install_error "Unable to patch /etc/sudoers" } @@ -124,4 +124,4 @@ function install_raspap() { move_config_file patch_system_files install_complete -} \ No newline at end of file +}