diff --git a/check.php b/check.php new file mode 100644 index 0000000..a0e92db --- /dev/null +++ b/check.php @@ -0,0 +1,158 @@ + true, + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_SSL_VERIFYHOST => 0, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HEADER => true, + CURLOPT_HTTPHEADER => [ + 'Sec-Fetch-Site: none', + ], +]; + +define('COOKIE_FILE', sys_get_temp_dir() . '/cookie-' . random_bytes(16) . '.txt'); + +function curlTest($path, $args) { + $req = curl_init(); + curl_setopt_array($req, COMMON_OPT); + curl_setopt_array($req, [ + CURLOPT_URL => URL . $path, + CURLOPT_COOKIEFILE => COOKIE_FILE, + CURLOPT_COOKIEJAR => COOKIE_FILE, + CURLOPT_POSTFIELDS => $args, + ]); + var_dump(curl_error($req)); + $status_code = curl_getinfo($req, CURLINFO_RESPONSE_CODE); + if ($status_code >= 400) { + var_dump(curl_exec($req)); + exit($path . ' test failed with status code ' . $status_code . LF); + } + return curl_exec($req); +} + +// AUTH TEST + +$username = 'check-' . bin2hex(random_bytes(16)); +$password = bin2hex(random_bytes(16)); + +curlTest('/auth/register', [ + 'username' => $username, + 'password' => $password, +]); + +curlTest('/auth/logout', []); + +curlTest('/auth/login', [ + 'username' => $username, + 'password' => $password, +]); + +$new_password = bin2hex(random_bytes(16)); +curlTest('/auth/password', [ + 'current-password' => $password, + 'new-password' => $new_password, +]); +$password = $new_password; + +curlTest('/auth/username', [ + 'current-password' => $password, + 'new-username' => $username . '2', +]); + +curlTest('/auth/username', [ + 'current-password' => $password, + 'new-username' => $username, +]); + +echo 'Created account with username "' . $username . '" and password "' . $password . '".' . LF; + +// REG TEST + +$subdomain = bin2hex(random_bytes(16)); +var_dump($subdomain); +curlTest('/reg/register', [ + 'subdomain' => $subdomain, + 'suffix' => SUFFIX, +]); + +curlTest('/reg/ns', [ + 'action' => 'add', + 'domain' => $subdomain . '.' . SUFFIX, + 'ns' => 'ns1.servnest.invalid.', +]); + +exec(CONF['dns']['kdig_path'] . ' @' . CONF['reg']['address'] . ' ' . $subdomain . '.' . SUFFIX . ' NS', $output2, $return_code); +if (preg_match('/[ \t]+ns1.servnest.invalid.$/Dm', implode(LF, $output2)) !== 1) + exit('Error: /reg/ns: NS record not set'); + +// HT TEST + +curlTest('/ht/', []); + +define('TEST_CONTENT', 'test-' . random_bytes(4)); + +file_put_contents(sys_get_temp_dir() . '/index.html', TEST_CONTENT); + +file_put_contents(sys_get_temp_dir() . '/exec.txt', 'mkdir /_site0- +put ' . sys_get_temp_dir() . '/index.html /_site0-/index.html +exit +'); + +$process = proc_open(SSHPASS . ' ' . SFTP . ' -o BatchMode=no -b ' . sys_get_temp_dir() . '/exec.txt -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -P ' . CONF['ht']['public_sftp_port'] . ' ' . $username . '@' . CONF['ht']['sftp_domain'], [0 => ['pipe', 'r']], $pipes); +if (is_resource($process) !== true) + exit('Can\'t spawn sftp with sshpass.'); +fwrite($pipes[0], $password); +fclose($pipes[0]); +if (proc_close($process) !== 0) + exit('File not sent successfully.'); + +$html = curlTest('/ht/add-onion', [ + 'dir' => '_site0-' +]); +var_dump($html); +if (preg_match('#\http\://(?[0-9a-z]{56})\.onion/\#D', $html, $matches) !== 1) + exit('Can\'t find onion address.'); + +sleep(10); + +$req = curl_init(); +curl_setopt_array($req, [ + CURLOPT_PROXY => TOR_PROXY, + CURLOPT_URL => 'http://' . $matches['onion'] . '.onion/', + CURLOPT_RETURNTRANSFER => true, +]); +var_dump(curl_error($req)); +if (curl_exec($req) !== TEST_CONTENT) { + var_dump(curl_exec($req)); + exit('Unexpected onion service response (status:' . $status_code . ') (' . $matches['onion'] . '.onion)' . LF); +} + +// STOP + +curlTest('/auth/unregister', [ + 'current-password' => $password, + 'delete' => 'on', +]); + +unlink(COOKIE_FILE); diff --git a/router.php b/router.php index d4d3a26..c0fafbc 100644 --- a/router.php +++ b/router.php @@ -136,7 +136,8 @@ if ($_POST !== []) { if (isset($_SERVER['HTTP_SEC_FETCH_SITE']) !== true) output(403, 'The Sec-Fetch-Site HTTP header is required when submitting a POST request to prevent Cross-Site Request Forgery (CSRF).'); if ($_SERVER['HTTP_SEC_FETCH_SITE'] !== 'same-origin') - output(403, 'The Sec-Fetch-Site HTTP header must be same-origin when submitting a POST request to prevent Cross-Site Request Forgery (CSRF).'); + if (!in_array($_SERVER['HTTP_SEC_FETCH_SITE'], ['none', 'same-origin'], true)) + output(403, 'The Sec-Fetch-Site HTTP header must be same-origin or none when submitting a POST request to prevent Cross-Site Request Forgery (CSRF).'); if (PAGE_METADATA['require-login'] ?? true !== false) { if (isset($_SESSION['id']) !== true)