Add return type declarations and minor bug fixes

This commit is contained in:
2023-01-21 12:14:24 +01:00
parent 0d382462f2
commit c81ef18f5f
11 changed files with 99 additions and 72 deletions

View File

@ -14,10 +14,11 @@ const SERVERS=[ //servers and ports we are running on
'hosting.danwin1210.me'=>['sftp'=>22, 'pop3'=>'995', 'imap'=>'993', 'smtp'=>'465'] 'hosting.danwin1210.me'=>['sftp'=>22, 'pop3'=>'995', 'imap'=>'993', 'smtp'=>'465']
]; ];
const EMAIL_TO=''; //Send email notifications about new registrations to this address const EMAIL_TO=''; //Send email notifications about new registrations to this address
const INDEX_MD5S=[ //MD5 sums of index.hosting.html files that should be considdered as unchanged for deletion const INDEX_MD5S=[ //MD5 sums of index.hosting.html files that should be considered as unchanged for deletion
'd41d8cd98f00b204e9800998ecf8427e', //empty file 'd41d8cd98f00b204e9800998ecf8427e', //empty file
'7ae7e9bac6be76f00e0d95347111f037', //default file '7ae7e9bac6be76f00e0d95347111f037', //old default file
'703fac6634bf637f942db8906092d0ab', //new default file '703fac6634bf637f942db8906092d0ab', //old default file
'3cf6df544184b2b1831de38fa31f813f', //new default file
'e109a5a44969c2a109aee0ea3565529e', //TOR HTML Site 'e109a5a44969c2a109aee0ea3565529e', //TOR HTML Site
'31ff0d6a1d280d610a700f3c1ec6d857', //MyHacker test page '31ff0d6a1d280d610a700f3c1ec6d857', //MyHacker test page
]; ];
@ -66,7 +67,7 @@ const NGINX_DEFAULT = 'server {
listen unix:/var/run/nginx/suspended backlog=4096 proxy_protocol; listen unix:/var/run/nginx/suspended backlog=4096 proxy_protocol;
add_header Content-Type text/html; add_header Content-Type text/html;
location / { location / {
return 200 \'<html><head><title>Suspended</title></head><body>This domain has been suspended due to violation of our <a href="http://' . ADDRESS . '">hosting rules</a>.</body></html>\'; return 200 \'<html lang="en" dir="ltr"><head><title>Suspended</title></head><body>This domain has been suspended due to violation of our <a href="http://' . ADDRESS . '">hosting rules</a>.</body></html>\';
} }
} }
server { server {
@ -188,7 +189,8 @@ function base32_encode(string $input) : string {
return $base32; return $base32;
} }
function send_captcha() { function send_captcha(): void
{
if(!CAPTCHA || !extension_loaded('gd')){ if(!CAPTCHA || !extension_loaded('gd')){
return; return;
} }
@ -286,7 +288,7 @@ function send_captcha() {
echo "<td><input type=\"hidden\" name=\"challenge\" value=\"$randid\"><input type=\"text\" name=\"captcha\" autocomplete=\"off\"></td></tr>"; echo "<td><input type=\"hidden\" name=\"challenge\" value=\"$randid\"><input type=\"text\" name=\"captcha\" autocomplete=\"off\"></td></tr>";
} }
function check_login(){ function check_login() : array {
session_start(); session_start();
if(empty($_SESSION['csrf_token'])){ if(empty($_SESSION['csrf_token'])){
$_SESSION['csrf_token']=sha1(uniqid()); $_SESSION['csrf_token']=sha1(uniqid());
@ -308,7 +310,8 @@ function check_login(){
return $user; return $user;
} }
function get_system_hash($pass) { function get_system_hash($pass): string
{
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./'; $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./';
$salt = ''; $salt = '';
for($i = 0; $i < 16; ++$i){ for($i = 0; $i < 16; ++$i){
@ -317,7 +320,8 @@ function get_system_hash($pass) {
return crypt($pass, '$6$' . $salt . '$'); return crypt($pass, '$6$' . $salt . '$');
} }
function check_captcha_error() { function check_captcha_error(): false|string
{
if(CAPTCHA){ if(CAPTCHA){
if(!isset($_REQUEST['challenge'])){ if(!isset($_REQUEST['challenge'])){
return 'Error: Wrong Captcha'; return 'Error: Wrong Captcha';
@ -343,7 +347,8 @@ function check_captcha_error() {
return false; return false;
} }
function rewrite_torrc(string $instance){ function rewrite_torrc(string $instance): void
{
$db = get_db_instance(); $db = get_db_instance();
$update_onion=$db->prepare('UPDATE onions SET private_key=? WHERE onion=?;'); $update_onion=$db->prepare('UPDATE onions SET private_key=? WHERE onion=?;');
$torrc='ClientUseIPv6 1 $torrc='ClientUseIPv6 1
@ -367,7 +372,6 @@ NumPrimaryGuards '.NUM_GUARDS.'
//php openssl implementation has some issues, re-export using native openssl //php openssl implementation has some issues, re-export using native openssl
$pkey=openssl_pkey_get_private($tmp['private_key']); $pkey=openssl_pkey_get_private($tmp['private_key']);
openssl_pkey_export($pkey, $exported); openssl_pkey_export($pkey, $exported);
openssl_pkey_free($pkey);
$priv_key=shell_exec('echo ' . escapeshellarg($exported) . ' | openssl rsa'); $priv_key=shell_exec('echo ' . escapeshellarg($exported) . ' | openssl rsa');
//save hidden service //save hidden service
mkdir("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion", 0700); mkdir("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion", 0700);
@ -455,16 +459,15 @@ function private_key_to_onion(string $priv_key) : array {
$message = 'Error: dmq1 invalid'; $message = 'Error: dmq1 invalid';
$ok = false; $ok = false;
}elseif(gmp_cmp($iqmp, gmp_invert($q, $p) ) !==0 ){ }elseif(gmp_cmp($iqmp, gmp_invert($q, $p) ) !==0 ){
$sessage = 'Error: iqmp not inverse of q'; $message = 'Error: iqmp not inverse of q';
$ok = false; $ok = false;
}else{ }else{
$onion = get_onion_v2($pkey); $onion = get_onion_v2($pkey);
} }
openssl_pkey_free($pkey);
return ['ok' => $ok, 'message' => $message, 'onion' => $onion, 'version' => $version]; return ['ok' => $ok, 'message' => $message, 'onion' => $onion, 'version' => $version];
} elseif(($priv = base64_decode($priv_key, true)) !== false){ } elseif(($priv = base64_decode($priv_key, true)) !== false){
$version = 3; $version = 3;
if(strpos($priv, '== ed25519v1-secret: type0 ==' . hex2bin('000000')) !== 0 || strlen($priv) !== 96){ if( ! str_starts_with( $priv, '== ed25519v1-secret: type0 ==' . hex2bin( '000000' ) ) || strlen($priv) !== 96){
$message = 'Error: v3 secret key invalid.'; $message = 'Error: v3 secret key invalid.';
$ok = false; $ok = false;
} else { } else {
@ -484,7 +487,6 @@ function generate_new_onion(int $version = 3) : array {
$pkey = openssl_pkey_new(['private_key_bits' => 1024, 'private_key_type' => OPENSSL_KEYTYPE_RSA]); $pkey = openssl_pkey_new(['private_key_bits' => 1024, 'private_key_type' => OPENSSL_KEYTYPE_RSA]);
openssl_pkey_export($pkey, $priv_key); openssl_pkey_export($pkey, $priv_key);
$onion = get_onion_v2($pkey); $onion = get_onion_v2($pkey);
openssl_pkey_free($pkey);
} else { } else {
$seed = random_bytes(32); $seed = random_bytes(32);
$sk = ed25519_seckey_expand($seed); $sk = ed25519_seckey_expand($seed);
@ -502,7 +504,8 @@ function ed25519_seckey_expand(string $seed) : string {
return $sk; return $sk;
} }
function rewrite_nginx_config(){ function rewrite_nginx_config(): void
{
$db = get_db_instance(); $db = get_db_instance();
$nginx=''; $nginx='';
$rewrites = []; $rewrites = [];
@ -634,7 +637,8 @@ function rewrite_nginx_config(){
exec('systemctl reload nginx'); exec('systemctl reload nginx');
} }
function rewrite_php_config(string $key){ function rewrite_php_config(string $key): void
{
$db = get_db_instance(); $db = get_db_instance();
$stmt=$db->prepare("SELECT system_account FROM users WHERE instance = ? AND php=? AND todelete!=1 AND id NOT IN (SELECT user_id FROM new_account);"); $stmt=$db->prepare("SELECT system_account FROM users WHERE instance = ? AND php=? AND todelete!=1 AND id NOT IN (SELECT user_id FROM new_account);");
foreach(array_replace(PHP_VERSIONS, DISABLED_PHP_VERSIONS) as $php_key => $version){ foreach(array_replace(PHP_VERSIONS, DISABLED_PHP_VERSIONS) as $php_key => $version){
@ -721,7 +725,8 @@ function add_user_db(int $user_id) : ?string {
return $mysql_db; return $mysql_db;
} }
function del_user_db(int $user_id, string $mysql_db) { function del_user_db(int $user_id, string $mysql_db): void
{
$db = get_db_instance(); $db = get_db_instance();
$stmt = $db->prepare('SELECT mysql_user FROM users WHERE id = ?;'); $stmt = $db->prepare('SELECT mysql_user FROM users WHERE id = ?;');
$stmt->execute([$user_id]); $stmt->execute([$user_id]);
@ -747,7 +752,8 @@ function get_new_tor_instance(string $type = 'onion') : string {
return $stmt->fetch(PDO::FETCH_NUM)[0]; return $stmt->fetch(PDO::FETCH_NUM)[0];
} }
function add_user_onion(int $user_id, string $onion, string $priv_key, int $onion_version) { function add_user_onion(int $user_id, string $onion, string $priv_key, int $onion_version): void
{
$db = get_db_instance(); $db = get_db_instance();
$stmt=$db->prepare('INSERT INTO onions (user_id, onion, private_key, version, enabled, enable_smtp, instance) VALUES (?, ?, ?, ?, 1, 0, ?);'); $stmt=$db->prepare('INSERT INTO onions (user_id, onion, private_key, version, enabled, enable_smtp, instance) VALUES (?, ?, ?, ?, 1, 0, ?);');
$instance = get_new_tor_instance(); $instance = get_new_tor_instance();
@ -755,7 +761,8 @@ function add_user_onion(int $user_id, string $onion, string $priv_key, int $onio
enqueue_instance_reload($instance); enqueue_instance_reload($instance);
} }
function del_user_onion(int $user_id, string $onion) { function del_user_onion(int $user_id, string $onion): void
{
$db = get_db_instance(); $db = get_db_instance();
$stmt = $db->prepare('SELECT null FROM onions WHERE user_id = ? AND onion = ? AND enabled IN (0, 1);'); $stmt = $db->prepare('SELECT null FROM onions WHERE user_id = ? AND onion = ? AND enabled IN (0, 1);');
$stmt->execute([$user_id, $onion]); $stmt->execute([$user_id, $onion]);
@ -794,7 +801,8 @@ function add_user_domain(int $user_id, string $domain) : string {
return ''; return '';
} }
function del_user_domain(int $user_id, string $domain) { function del_user_domain(int $user_id, string $domain): void
{
$db = get_db_instance(); $db = get_db_instance();
$stmt = $db->prepare('SELECT null FROM domains WHERE user_id = ? AND domain = ? AND enabled IN (0, 1);'); $stmt = $db->prepare('SELECT null FROM domains WHERE user_id = ? AND domain = ? AND enabled IN (0, 1);');
$stmt->execute([$user_id, $domain]); $stmt->execute([$user_id, $domain]);
@ -805,14 +813,16 @@ function del_user_domain(int $user_id, string $domain) {
} }
} }
function check_csrf_error(){ function check_csrf_error(): false|string
{
if(empty($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']){ if(empty($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']){
return 'Invalid CSRF token, please try again.'; return 'Invalid CSRF token, please try again.';
} }
return false; return false;
} }
function enqueue_instance_reload($instance = null){ function enqueue_instance_reload($instance = null): void
{
$db = get_db_instance(); $db = get_db_instance();
if($instance === null){ if($instance === null){
$db->exec('UPDATE service_instances SET reload = 1 LIMIT 1;'); $db->exec('UPDATE service_instances SET reload = 1 LIMIT 1;');
@ -822,20 +832,19 @@ function enqueue_instance_reload($instance = null){
} }
} }
function get_db_instance(){ function get_db_instance() : PDO {
static $db = null; static $db = null;
if($db !== null){ if($db === null){
return $db; try{
} $db=new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>PERSISTENT]);
try{ }catch(PDOException $e){
$db=new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>PERSISTENT]); die('No Connection to MySQL database!');
}catch(PDOException $e){ }
die('No Connection to MySQL database!');
} }
return $db; return $db;
} }
function coinpayments_create_transaction(string $currency, int $price, string $payment_for, $user_id = null){ function coinpayments_create_transaction(string $currency, int $price, string $payment_for, $user_id = null) : false|array {
$query=[]; $query=[];
$query['currency1'] = 'USD'; $query['currency1'] = 'USD';
$query['currency2'] = $currency; $query['currency2'] = $currency;
@ -870,7 +879,7 @@ function coinpayments_create_transaction(string $currency, int $price, string $p
return $json['result']; return $json['result'];
} }
function coinpayments_get_rates(){ function coinpayments_get_rates() : false|array {
$query=[]; $query=[];
$query['accepted'] = '1'; $query['accepted'] = '1';
$query['short'] = '0'; $query['short'] = '0';
@ -900,7 +909,8 @@ function coinpayments_get_rates(){
return $json['result']; return $json['result'];
} }
function payment_status_update(string $txid){ function payment_status_update(string $txid): void
{
$db = get_db_instance(); $db = get_db_instance();
$stmt = $db->prepare('SELECT * FROM payments WHERE txn_id = ?;'); $stmt = $db->prepare('SELECT * FROM payments WHERE txn_id = ?;');
$stmt->execute([$txid]); $stmt->execute([$txid]);
@ -929,7 +939,8 @@ function payment_status_update(string $txid){
} }
} }
function add_disk_quota(int $user_id, int $kb){ function add_disk_quota(int $user_id, int $kb): void
{
$db = get_db_instance(); $db = get_db_instance();
$stmt = $db->prepare('SELECT quota_size FROM disk_quota WHERE user_id = ?;'); $stmt = $db->prepare('SELECT quota_size FROM disk_quota WHERE user_id = ?;');
$stmt->execute([$user_id]); $stmt->execute([$user_id]);
@ -938,7 +949,8 @@ function add_disk_quota(int $user_id, int $kb){
$stmt->execute([$tmp['quota_size'] + $kb, $user_id]); $stmt->execute([$tmp['quota_size'] + $kb, $user_id]);
} }
function add_files_quota(int $user_id, int $number){ function add_files_quota(int $user_id, int $number): void
{
$db = get_db_instance(); $db = get_db_instance();
$stmt = $db->prepare('SELECT quota_files FROM disk_quota WHERE user_id = ?;'); $stmt = $db->prepare('SELECT quota_files FROM disk_quota WHERE user_id = ?;');
$stmt->execute([$user_id]); $stmt->execute([$user_id]);
@ -957,14 +969,14 @@ function bytes_to_human_readable(int $bytes) : string {
} }
} }
function setup_chroot(string $account, string $last_account){ function setup_chroot(string $account, string $last_account): void
{
$system_account = sanitize_system_account($account); $system_account = sanitize_system_account($account);
if($system_account === false){ if($system_account === false){
echo "ERROR: Account $account looks strange\n"; echo "ERROR: Account $account looks strange\n";
return; return;
} }
$last_account = sanitize_system_account($last_account); $last_account = sanitize_system_account($last_account);
$shell = ENABLE_SHELL_ACCESS ? '/bin/bash' : '/usr/sbin/nologin';
$user = posix_getpwnam($system_account); $user = posix_getpwnam($system_account);
$passwd_line = "$user[name]:$user[passwd]:$user[uid]:$user[gid]:$user[gecos]:/:$user[shell]"; $passwd_line = "$user[name]:$user[passwd]:$user[uid]:$user[gid]:$user[gecos]:/:$user[shell]";
exec('/var/www/setup_chroot.sh ' . escapeshellarg("/home/$system_account")); exec('/var/www/setup_chroot.sh ' . escapeshellarg("/home/$system_account"));
@ -1000,7 +1012,8 @@ function setup_chroot(string $account, string $last_account){
} }
} }
function update_system_user_password(string $user, string $password){ function update_system_user_password(string $user, string $password): void
{
$system_account = sanitize_system_account($user); $system_account = sanitize_system_account($user);
if($system_account === false){ if($system_account === false){
echo "ERROR: Account $user looks strange\n"; echo "ERROR: Account $user looks strange\n";
@ -1021,7 +1034,7 @@ function update_system_user_password(string $user, string $password){
rewind($fp); rewind($fp);
ftruncate($fp, 0); ftruncate($fp, 0);
foreach($lines as $line){ foreach($lines as $line){
if(strpos($line, "$user:")===0){ if( str_starts_with( $line, "$user:" ) ){
$line = preg_replace("~$user:([^:]*):~", str_replace('$', '\$', "$user:$password:"), $line); $line = preg_replace("~$user:([^:]*):~", str_replace('$', '\$', "$user:$password:"), $line);
} }
fwrite($fp, $line); fwrite($fp, $line);
@ -1031,7 +1044,8 @@ function update_system_user_password(string $user, string $password){
fclose($fp); fclose($fp);
} }
function sanitize_system_account(string $system_account){ function sanitize_system_account(string $system_account): false|string
{
$account = basename($system_account); $account = basename($system_account);
$user = posix_getpwnam($account); $user = posix_getpwnam($account);
if(empty($system_account) || $account !== $system_account || $user === false || $user['gid'] !== 33 || $user['uid'] < 1000){ if(empty($system_account) || $account !== $system_account || $user === false || $user['gid'] !== 33 || $user['uid'] < 1000){
@ -1040,7 +1054,8 @@ function sanitize_system_account(string $system_account){
return $account; return $account;
} }
function main_menu(string $current_site){ function main_menu(string $current_site): void
{
echo '<p>'; echo '<p>';
$sites = [ $sites = [
'index.php' => 'Info', 'index.php' => 'Info',
@ -1069,7 +1084,8 @@ function main_menu(string $current_site){
echo '</p>'; echo '</p>';
} }
function dashboard_menu(array $user, string $current_site){ function dashboard_menu(array $user, string $current_site): void
{
echo '<p>Logged in as ' . htmlspecialchars($user['username']); echo '<p>Logged in as ' . htmlspecialchars($user['username']);
$sites = [ $sites = [
'logout.php' => 'Logout', 'logout.php' => 'Logout',
@ -1089,7 +1105,8 @@ function dashboard_menu(array $user, string $current_site){
echo '</p>'; echo '</p>';
} }
function print_header(string $sub_title, string $style = '', string $base_target = '_self'){ function print_header(string $sub_title, string $style = '', string $base_target = '_self'): void
{
?> ?>
<!DOCTYPE html><html><head> <!DOCTYPE html><html><head>
<title><?php echo htmlspecialchars(SITE_NAME) . ' - ' . htmlspecialchars($sub_title); ?></title> <title><?php echo htmlspecialchars(SITE_NAME) . ' - ' . htmlspecialchars($sub_title); ?></title>
@ -1099,7 +1116,7 @@ function print_header(string $sub_title, string $style = '', string $base_target
<link rel="canonical" href="<?php echo CANONICAL_URL . $_SERVER['SCRIPT_NAME']; ?>"> <link rel="canonical" href="<?php echo CANONICAL_URL . $_SERVER['SCRIPT_NAME']; ?>">
<?php <?php
if(!empty($style)){ if(!empty($style)){
echo "<style type=\"text/css\">$style</style>"; echo "<style>$style</style>";
} }
echo "<base rel=\"noopener\" target=\"$base_target\">"; echo "<base rel=\"noopener\" target=\"$base_target\">";
?> ?>

View File

@ -1,6 +1,14 @@
{ {
"require": { "require": {
"paragonie/sodium_compat": "^1.17", "paragonie/sodium_compat": "^v1.19",
"chillerlan/php-qrcode": "^4.3" "chillerlan/php-qrcode": "^4.3",
"ext-pdo": "*",
"ext-openssl": "*",
"ext-gmp": "*",
"ext-curl": "*",
"ext-posix": "*",
"ext-gnupg": "*",
"ext-ssh2": "*",
"ext-fileinfo": "*"
} }
} }

View File

@ -13,7 +13,7 @@ print_header('FAQ');
<tr><td>I just uploaded my page, but it's broken. HELP!</td><td>Most likely your site makes use of rewriting rules, which are typically located in an .htaccess file or are mentioned in a README file. Just <a href="https://danwin1210.me/contact.php">contact me</a> in this case. Also see the previous question.</td></tr> <tr><td>I just uploaded my page, but it's broken. HELP!</td><td>Most likely your site makes use of rewriting rules, which are typically located in an .htaccess file or are mentioned in a README file. Just <a href="https://danwin1210.me/contact.php">contact me</a> in this case. Also see the previous question.</td></tr>
<tr><td>Can I host a porn site?</td><td>Yes as long as your content is legal you may upload adult content.</td></tr> <tr><td>Can I host a porn site?</td><td>Yes as long as your content is legal you may upload adult content.</td></tr>
<tr><td>What is the directory structure for when I connect via sftp?</td><td>There are several directories you on the server for your account:<br><b>Maildir</b> - used to store your mails in (don't touch it)<br><b>data</b> - You can store application data here that should not be accessible via your site. E.g. configuration or database files.<br><b>tmp</b> - anything saved here will automatically be deleted after about 24 hours<br><b>www</b> - this is where you upload your website which becomes then available under your domain.<br><b>logs</b> - you will find webserver logs here<br><b>.ssh</b> - by uploading your ssh public key as authorzed_keys in this folder, you can authenticate to sftp using your ssh key, without a password</td></tr> <tr><td>What is the directory structure for when I connect via sftp?</td><td>There are several directories you on the server for your account:<br><b>Maildir</b> - used to store your mails in (don't touch it)<br><b>data</b> - You can store application data here that should not be accessible via your site. E.g. configuration or database files.<br><b>tmp</b> - anything saved here will automatically be deleted after about 24 hours<br><b>www</b> - this is where you upload your website which becomes then available under your domain.<br><b>logs</b> - you will find webserver logs here<br><b>.ssh</b> - by uploading your ssh public key as authorzed_keys in this folder, you can authenticate to sftp using your ssh key, without a password</td></tr>
<tr><td>My application is very ressource intensive or I want to host a different service e.g. my own tor relay. Can you get me a VPS?</td><td>Yes, if you have special requirements, want a dedicated VPS for your application or just want to anonymously support the TOR network (or other networks) without having to deal with server setup etc. I can offer you a managed VPS hosting. However this will not be for free. It depends on which server you want me to get. For details, <a href="https://danwin1210.me/contact.php">contact me</a></td></tr> <tr><td>My application is very ressource intensive, or I want to host a different service e.g. my own tor relay. Can you get me a VPS?</td><td>Yes, if you have special requirements, want a dedicated VPS for your application or just want to anonymously support the TOR network (or other networks) without having to deal with server setup etc. I can offer you a managed VPS hosting. However, this will not be for free. It depends on which server you want me to get. For details, <a href="https://danwin1210.me/contact.php">contact me</a></td></tr>
<tr><td>I want to also publish my site on clearnet. Can you offer a clearnet relay?</td><td>Yes, I can offer you a free subdomain on my server, e.g. yoursite.danwin1210.me, which you can configure in your dashboard. Or if you have your own domain you can use that one, point your DNS settings to the IPs given in your dashboard and <a href="https://danwin1210.me/contact.php">contact me</a> for setting up an SSL certificate for your domain.</td></tr> <tr><td>I want to also publish my site on clearnet. Can you offer a clearnet relay?</td><td>Yes, I can offer you a free subdomain on my server, e.g. yoursite.danwin1210.me, which you can configure in your dashboard. Or if you have your own domain you can use that one, point your DNS settings to the IPs given in your dashboard and <a href="https://danwin1210.me/contact.php">contact me</a> for setting up an SSL certificate for your domain.</td></tr>
<tr><td>I'm using CloudFlare, but when I open my site, it shows too many redirects.</td><td>By default CloudFlare makes unencrypted requests to the backend server, but my server tells any client that wants an insecure connection to upgrade to a secure connection and use https:// instead of http://. CloudFlare just forwards this redirection to the client, which then again asks CloudFlare for the same thing again, but CloudFlare still connects to my server via an insecure http:// connection. To fix this, go to your CloudFlare dashboard and manage your domains settings. Under "Crypto" you can find settings for SSL. Change the setting from Flexible to Full, which makes CloudFlare use a secure https:// connection when talking to my server.</td></tr> <tr><td>I'm using CloudFlare, but when I open my site, it shows too many redirects.</td><td>By default CloudFlare makes unencrypted requests to the backend server, but my server tells any client that wants an insecure connection to upgrade to a secure connection and use https:// instead of http://. CloudFlare just forwards this redirection to the client, which then again asks CloudFlare for the same thing again, but CloudFlare still connects to my server via an insecure http:// connection. To fix this, go to your CloudFlare dashboard and manage your domains settings. Under "Crypto" you can find settings for SSL. Change the setting from Flexible to Full, which makes CloudFlare use a secure https:// connection when talking to my server.</td></tr>
</table> </table>

View File

@ -320,8 +320,8 @@ foreach($list as $element){
<script> <script>
document.getElementById('checkAllParent').innerHTML = '<input type="checkbox" onclick="toggle(this);">'; document.getElementById('checkAllParent').innerHTML = '<input type="checkbox" onclick="toggle(this);">';
function toggle(source) { function toggle(source) {
checkboxes = document.getElementsByClassName('fileCheck'); let checkboxes = document.getElementsByClassName('fileCheck');
for(var i=0, n=checkboxes.length;i<n;i++) { for(let i=0, n=checkboxes.length;i<n;i++) {
checkboxes[i].checked = source.checked; checkboxes[i].checked = source.checked;
} }
} }
@ -329,21 +329,19 @@ function toggle(source) {
</body></html> </body></html>
<?php <?php
function get_properties($name, &$icon, &$size){ function get_properties($name, &$icon, &$size): void
if(substr($name, -1, 1)==='/'){ {
if( str_ends_with( $name, '/' ) ){
$icon='dir'; $icon='dir';
}else{ }else{
$extension=strtolower(substr($name, strrpos($name, '.')+1)); $extension=strtolower(substr($name, strrpos($name, '.')+1));
if(isset(TYPES[$extension])){ $icon = TYPES[ $extension ] ?? 'ukwn';
$icon=TYPES[$extension];
}else{
$icon='ukwn';
}
$size = bytes_to_human_readable($size); $size = bytes_to_human_readable($size);
} }
} }
function send_not_found(){ function send_not_found(): void
{
header("HTTP/1.1 404 Not Found"); header("HTTP/1.1 404 Not Found");
print_header('FileManager - 404 Not Found'); print_header('FileManager - 404 Not Found');
echo '<p>The requested file '.htmlspecialchars($_REQUEST['path']).' was not found on your account.</p>'; echo '<p>The requested file '.htmlspecialchars($_REQUEST['path']).' was not found on your account.</p>';
@ -351,7 +349,8 @@ function send_not_found(){
echo '</body></html>'; echo '</body></html>';
} }
function send_login(){ function send_login(): void
{
print_header('FileManager - Login'); print_header('FileManager - Login');
?> ?>
<p>Please type in your system account password: <form action="files.php" method="post"><input name="sftp_pass" type="password" autofocus><input type="submit" value="Login"></form></p> <p>Please type in your system account password: <form action="files.php" method="post"><input name="sftp_pass" type="password" autofocus><input type="submit" value="Login"></form></p>
@ -360,7 +359,8 @@ function send_login(){
<?php <?php
} }
function sftp_recursive_delete($sftp, $dir, $file){ function sftp_recursive_delete($sftp, $dir, $file): void
{
if(is_dir("ssh2.sftp://$sftp$dir/$file")){ if(is_dir("ssh2.sftp://$sftp$dir/$file")){
$dir_handle = opendir("ssh2.sftp://$sftp$dir/$file"); $dir_handle = opendir("ssh2.sftp://$sftp$dir/$file");
while(($list = readdir($dir_handle)) !== false){ while(($list = readdir($dir_handle)) !== false){
@ -376,7 +376,8 @@ function sftp_recursive_delete($sftp, $dir, $file){
} }
} }
function send_rename($dir){ function send_rename($dir): void
{
print_header('FileManager - Rename file'); print_header('FileManager - Rename file');
echo '<form action="files.php" method="post">'; echo '<form action="files.php" method="post">';
echo '<input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'">'; echo '<input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'">';
@ -391,7 +392,8 @@ function send_rename($dir){
echo '</body></html>'; echo '</body></html>';
} }
function send_edit($sftp, $dir){ function send_edit($sftp, $dir): void
{
print_header('FileManager - Edit file'); print_header('FileManager - Edit file');
echo '<form action="files.php" method="post">'; echo '<form action="files.php" method="post">';
echo '<input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'">'; echo '<input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'">';

View File

@ -208,7 +208,7 @@ if($count_onions<MAX_NUM_USER_ONIONS){
echo "<form action=\"home.php\" method=\"post\"><input type=\"hidden\" name=\"csrf_token\" value=\"$_SESSION[csrf_token]\">"; echo "<form action=\"home.php\" method=\"post\"><input type=\"hidden\" name=\"csrf_token\" value=\"$_SESSION[csrf_token]\">";
echo '<tr><td colspan="6">Add additional hidden service:<br>'; echo '<tr><td colspan="6">Add additional hidden service:<br>';
echo '<label><input type="radio" name="onion_type" value="3"'; echo '<label><input type="radio" name="onion_type" value="3"';
echo (!isset($_POST['onion_type']) || isset($_POST['onion_type']) && $_POST['onion_type']==3) ? ' checked' : ''; echo (!isset($_POST['onion_type']) || $_POST['onion_type']==3) ? ' checked' : '';
echo '>Random v3 Address</label>'; echo '>Random v3 Address</label>';
echo '<label><input type="radio" name="onion_type" value="2"'; echo '<label><input type="radio" name="onion_type" value="2"';
echo isset($_POST['onion_type']) && $_POST['onion_type']==2 ? ' checked' : ''; echo isset($_POST['onion_type']) && $_POST['onion_type']==2 ? ' checked' : '';
@ -301,7 +301,7 @@ $usage_files_text = "$quota[quota_files_used] of $quota[quota_files] - " . roun
<h3>Logs</h3> <h3>Logs</h3>
<table border="1"> <table border="1">
<tr><th>Date</th><th>access.log</th><th>error.log</th></tr> <tr><th>Date</th><th>access.log</th><th>error.log</th></tr>
<tr><td>Today</td><td><a href="log.php?type=access&amp;old=0" target="_blank">access.log</log></td><td><a href="log.php?type=error&amp;old=0" target="_blank">error.log</a></td></tr> <tr><td>Today</td><td><a href="log.php?type=access&amp;old=0" target="_blank">access.log</a></td><td><a href="log.php?type=error&amp;old=0" target="_blank">error.log</a></td></tr>
<tr><td>Yesterday</td><td><a href="log.php?type=access&amp;old=1" target="_blank">access.log</log></td><td><a href="log.php?type=error&amp;old=1" target="_blank">error.log</a></td></tr> <tr><td>Yesterday</td><td><a href="log.php?type=access&amp;old=1" target="_blank">access.log</a></td><td><a href="log.php?type=error&amp;old=1" target="_blank">error.log</a></td></tr>
</table> </table>
</body></html> </body></html>

View File

@ -24,8 +24,8 @@ print_header('Info');
<li>Your own .onion domains</li> <li>Your own .onion domains</li>
<li>Clearnet domains or a free subdomain of danwin1210.me</li> <li>Clearnet domains or a free subdomain of danwin1210.me</li>
<li>Empty/Unused accounts will be automatically deleted after a month of inactivity</li> <li>Empty/Unused accounts will be automatically deleted after a month of inactivity</li>
<li>PGP based Two Factor Authentication (2FA)</li> <li>PGP based Two-Factor Authentication (2FA)</li>
<li>There is a missing feature or you need a special configuration? Just <a href="https://danwin1210.me/contact.php">contact me</a> and I'll see what I can do.</li> <li>There is a missing feature, or you need a special configuration? Just <a href="https://danwin1210.me/contact.php">contact me</a> and I'll see what I can do.</li>
<li>More to come…</li> <li>More to come…</li>
</ul> </ul>
<h2>Rules</h2> <h2>Rules</h2>

View File

@ -24,7 +24,7 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
$stmt=$db->prepare('INSERT INTO pass_change (user_id, password) VALUES (?, ?);'); $stmt=$db->prepare('INSERT INTO pass_change (user_id, password) VALUES (?, ?);');
$hash=get_system_hash($_POST['newpass']); $hash=get_system_hash($_POST['newpass']);
$stmt->execute([$user['id'], $hash]); $stmt->execute([$user['id'], $hash]);
$msg.='<p style="color:green;">Successfully changed system account password, change will take affect within the next minute.</p>'; $msg.='<p style="color:green;">Successfully changed system account password, change will take effect within the next minute.</p>';
}elseif($_REQUEST['type']==='sql'){ }elseif($_REQUEST['type']==='sql'){
$stmt=$db->prepare("SET PASSWORD FOR '$user[mysql_user]'@'%'=PASSWORD(?);"); $stmt=$db->prepare("SET PASSWORD FOR '$user[mysql_user]'@'%'=PASSWORD(?);");
$stmt->execute([$_POST['newpass']]); $stmt->execute([$_POST['newpass']]);

View File

@ -147,7 +147,7 @@ foreach(PHP_VERSIONS as $key => $version){
<tr><td colspan=2><label><input type="checkbox" name="public" value="1"<?php echo $public_list; ?>>Publish site on list of hosted sites</label></td></tr> <tr><td colspan=2><label><input type="checkbox" name="public" value="1"<?php echo $public_list; ?>>Publish site on list of hosted sites</label></td></tr>
<tr><td colspan=2><label><input type="checkbox" name="autoindex" value="1"<?php echo $autoindex; ?>>Enable autoindex (listing of files)</label></td></tr> <tr><td colspan=2><label><input type="checkbox" name="autoindex" value="1"<?php echo $autoindex; ?>>Enable autoindex (listing of files)</label></td></tr>
<tr><td colspan=2>Type of hidden service:<br> <tr><td colspan=2>Type of hidden service:<br>
<label><input type="radio" name="onion_type" value="3"<?php echo (!isset($_POST['onion_type']) || isset($_POST['onion_type']) && $_POST['onion_type']==3) ? ' checked' : ''; ?>>Random v3 Address</label> <label><input type="radio" name="onion_type" value="3"<?php echo (!isset($_POST['onion_type']) || $_POST['onion_type']==3) ? ' checked' : ''; ?>>Random v3 Address</label>
<label><input type="radio" name="onion_type" value="2"<?php echo isset($_POST['onion_type']) && $_POST['onion_type']==2 ? ' checked' : ''; ?>>Random v2 Address</label> <label><input type="radio" name="onion_type" value="2"<?php echo isset($_POST['onion_type']) && $_POST['onion_type']==2 ? ' checked' : ''; ?>>Random v2 Address</label>
<label><input id="custom_onion" type="radio" name="onion_type" value="custom"<?php echo isset($_POST['onion_type']) && $_POST['onion_type']==='custom' ? ' checked' : ''; ?>>Custom private key <label><input id="custom_onion" type="radio" name="onion_type" value="custom"<?php echo isset($_POST['onion_type']) && $_POST['onion_type']==='custom' ? ' checked' : ''; ?>>Custom private key
<textarea id="private_key" name="private_key" rows="5" cols="28"> <textarea id="private_key" name="private_key" rows="5" cols="28">

View File

@ -14,7 +14,7 @@ print_header('Upgrade account', 'td{padding:5px;}');
<?php <?php
$rates = coinpayments_get_rates(); $rates = coinpayments_get_rates();
if($rates === false){ if($rates === false){
echo '<p>An error occured talking to coinpayments</p>'; echo '<p>An error occurred talking to coinpayments</p>';
}else{ }else{
?> ?>
<form action="upgrade.php" method="post"> <form action="upgrade.php" method="post">
@ -56,7 +56,7 @@ if(isset($_POST['currency']) && isset($_POST['upgrade'])){
$db = get_db_instance(); $db = get_db_instance();
$transaction = coinpayments_create_transaction($_POST['currency'], ACCOUNT_UPGRADES[$_POST['upgrade']]['usd_price'], $_POST['upgrade'], $user['id']); $transaction = coinpayments_create_transaction($_POST['currency'], ACCOUNT_UPGRADES[$_POST['upgrade']]['usd_price'], $_POST['upgrade'], $user['id']);
if($transaction === false){ if($transaction === false){
echo "<p>An error occured creating the transaction, please try again</p>"; echo "<p>An error occurred creating the transaction, please try again</p>";
}else{ }else{
echo "<p>Please pay $transaction[amount] $_POST[currency] to $transaction[address]</p>"; echo "<p>Please pay $transaction[amount] $_POST[currency] to $transaction[address]</p>";
echo '<img src="'.(new QRCode(new QROptions(['outputType' => QRCode::OUTPUT_IMAGE_PNG, 'eccLevel' => QRCode::ECC_H])))->render($transaction['address']).'" alt="QR Code">'; echo '<img src="'.(new QRCode(new QROptions(['outputType' => QRCode::OUTPUT_IMAGE_PNG, 'eccLevel' => QRCode::ECC_H])))->render($transaction['address']).'" alt="QR Code">';

View File

@ -105,7 +105,7 @@ if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';"))
listen unix:/var/run/nginx/suspended backlog=4096; listen unix:/var/run/nginx/suspended backlog=4096;
add_header Content-Type text/html; add_header Content-Type text/html;
location / { location / {
return 200 \'<html><head><title>Suspended</title></head><body>This domain has been suspended due to violation of <a href="http://' . ADDRESS . '">hosting rules</a>.</body></html>\'; return 200 \'<html lang="en" dir="ltr"><head><title>Suspended</title></head><body>This domain has been suspended due to violation of <a href="http://' . ADDRESS . '">hosting rules</a>.</body></html>\';
} }
} }
'; ';

View File

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="en" dir="ltr">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Site hosted by Daniel's hosting service</title> <title>Site hosted by Daniel's hosting service</title>