.tmp as a symlink to a target // they control reading and have our `sudo cp` follow it. $filepath = tempnam('/tmp', 'pistar-edit-'); register_shutdown_function(function() use ($filepath) { @unlink($filepath); }); exec('sudo cp /etc/wpa_supplicant/wpa_supplicant.conf ' . escapeshellarg($filepath)); exec('sudo chown www-data:www-data ' . escapeshellarg($filepath)); exec('sudo chmod 600 ' . escapeshellarg($filepath)); if(isset($_POST['data'])) { // Write submitted data into the staging file. $fh = fopen($filepath, 'w'); fwrite($fh, $_POST['data']); fclose($fh); // Atomic install: mode + owner set in one syscall sequence. // wpa_supplicant.conf carries the WPA PSK in cleartext as // `psk=…hex…` — mode 600 root:root keeps every other local // user (and any sandbox-escape from another service) from // reading it. wpa_supplicant runs as root, so the daemon's // own access is unaffected. exec('sudo mount -o remount,rw /'); exec('sudo install -m 600 -o root -g root ' . escapeshellarg($filepath) . ' /etc/wpa_supplicant/wpa_supplicant.conf'); exec('sudo mount -o remount,ro /'); } // Re-read for the form's textarea. $fh = fopen($filepath, 'r'); $theData = fread($fh, filesize($filepath)); fclose($fh); ?>