From 851a3103bed87553e332e3054353ca6c6a978c48 Mon Sep 17 00:00:00 2001 From: Daniel Winzen Date: Thu, 20 Jun 2019 18:53:30 +0200 Subject: [PATCH] Added canonical tag and store tor/php instance responsibility in db --- var/www/common.php | 27 +++++++++++++---- var/www/cron.php | 64 +++++++++++++++++++-------------------- var/www/html/admin.php | 27 ++++++++--------- var/www/html/delete.php | 1 + var/www/html/faq.php | 1 + var/www/html/files.php | 2 ++ var/www/html/home.php | 19 ++++++------ var/www/html/index.php | 16 +++------- var/www/html/list.php | 1 + var/www/html/login.php | 1 + var/www/html/password.php | 1 + var/www/html/register.php | 8 ++--- var/www/setup.php | 12 ++++++-- 13 files changed, 99 insertions(+), 81 deletions(-) diff --git a/var/www/common.php b/var/www/common.php index 88f0811..b8426e0 100644 --- a/var/www/common.php +++ b/var/www/common.php @@ -5,9 +5,10 @@ const DBUSER='hosting'; // Database user const DBPASS='MY_PASSWORD'; // Database password const DBNAME='hosting'; // Database const PERSISTENT=true; // Use persistent database conection true/false -const DBVERSION=13; //database layout version +const DBVERSION=14; //database layout version const CAPTCHA=0; // Captcha difficulty (0=off, 1=simple, 2=moderate, 3=extreme) const ADDRESS='dhosting4xxoydyaivckq7tsmtgi4wfs3flpeyitekkmqwu4v4r46syd.onion'; // our own address +const CANONICAL_URL='https://hosting.danwin1210.me'; // our preferred domain for search engines const SERVERS=[ //servers and ports we are running on 'dhosting4xxoydyaivckq7tsmtgi4wfs3flpeyitekkmqwu4v4r46syd.onion'=>['sftp'=>22, 'ftp'=>21, 'pop3'=>'110', 'imap'=>'143', 'smtp'=>'25'], 'hosting.danwin1210.me'=>['sftp'=>22, 'ftp'=>21, 'pop3'=>'995', 'imap'=>'993', 'smtp'=>'465'] @@ -21,7 +22,7 @@ const INDEX_MD5S=[ //MD5 sums of index.hosting.html files that should be considd const REQUIRE_APPROVAL=false; //require admin approval of new sites? true/false const ENABLE_SHELL_ACCESS=true; //allows users to login via ssh, when disabled only (s)ftp is allowed - run setup.php to migrate existing accounts const ADMIN_PASSWORD='MY_PASSWORD'; //password for admin interface -const SERVICE_INSTANCES=['2', '3', '4', '5', '6', '7', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; +const SERVICE_INSTANCES=['2', '3', '4', '5', '6', '7', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; //one character per instance - run multiple tor+php-fpm instances for load balancing, remove all but one instance if you expect less than 100 accounts. Adding new instances is always possible at a later time, just removing one takes some manual cleanup for now - run setup.php after change const DISABLED_PHP_VERSIONS=[]; //php versions still installed on the system but no longer offered for new accounts const PHP_VERSIONS=[4 => '7.3']; //currently active php versions const DEFAULT_PHP_VERSION='7.3'; //default php version @@ -316,8 +317,8 @@ NumEntryGuards 6 NumDirectoryGuards 6 NumPrimaryGuards 6 "; - $stmt=$db->prepare('SELECT onions.onion, users.system_account, onions.num_intros, onions.enable_smtp, onions.version, onions.max_streams, onions.enabled FROM onions LEFT JOIN users ON (users.id=onions.user_id) WHERE onions.onion LIKE ? AND onions.enabled IN (1, -2) AND users.id NOT IN (SELECT user_id FROM new_account) AND users.todelete!=1;'); - $stmt->execute(["$key%"]); + $stmt=$db->prepare('SELECT onions.onion, users.system_account, onions.num_intros, onions.enable_smtp, onions.version, onions.max_streams, onions.enabled FROM onions LEFT JOIN users ON (users.id=onions.user_id) WHERE onions.instance = ? AND onions.enabled IN (1, -2) AND users.id NOT IN (SELECT user_id FROM new_account) AND users.todelete!=1;'); + $stmt->execute([$key]); while($tmp=$stmt->fetch(PDO::FETCH_NUM)){ if($tmp[6]==1){ $socket=$tmp[1]; @@ -507,9 +508,9 @@ function rewrite_nginx_config(PDO $db){ } function rewrite_php_config(PDO $db, string $key){ - $stmt=$db->prepare("SELECT system_account FROM users WHERE system_account LIKE ? 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){ - $stmt->execute(["$key%", $php_key]); + $stmt->execute([$key, $php_key]); $php = "[www] user = www-data group = www-data @@ -595,6 +596,11 @@ function del_user_db(PDO $db, int $user_id, string $mysql_db) { } } +function add_user_onion(PDO $db, int $user_id, string $onion, string $priv_key, int $onion_version) { + $stmt=$db->prepare('INSERT INTO onions (user_id, onion, private_key, version, enabled, instance) VALUES (?, ?, ?, ?, 2, ?);'); + $stmt->execute([$user_id, $onion, $priv_key, $onion_version, SERVICE_INSTANCES[array_rand(SERVICE_INSTANCES)]]); +} + function del_user_onion(PDO $db, int $user_id, string $onion) { $stmt = $db->prepare('SELECT null FROM onions WHERE user_id = ? AND onion = ? AND enabled IN (0, 1);'); $stmt->execute([$user_id, $onion]); @@ -646,3 +652,12 @@ function check_csrf_error(){ } return false; } + +function enqueue_instance_reload($db, $instance = null){ + if($instance === null){ + $stmt=$db->prepare('UPDATE service_instances SET reload = 1 LIMIT 1;'); + }else{ + $stmt=$db->prepare('UPDATE service_instances SET reload = 1 WHERE id = ?;'); + $stmt->execute([$instance]); + } +} diff --git a/var/www/cron.php b/var/www/cron.php index 095433c..f9a8744 100644 --- a/var/www/cron.php +++ b/var/www/cron.php @@ -18,12 +18,12 @@ $db->query('UPDATE service_instances SET reload=0 WHERE reload=1;'); $del=$db->prepare("DELETE FROM new_account WHERE user_id=?;"); $enable_onion=$db->prepare("UPDATE onions SET enabled=2 WHERE onion=?;"); $approval = REQUIRE_APPROVAL ? 'WHERE new_account.approved=1': ''; -$stmt=$db->query("SELECT users.system_account, users.username, new_account.password, users.php, users.autoindex, users.id, onions.onion FROM new_account INNER JOIN users ON (users.id=new_account.user_id) INNER JOIN onions ON (onions.user_id=users.id) $approval LIMIT 100;"); +$stmt=$db->query("SELECT users.system_account, users.username, new_account.password, users.php, users.autoindex, users.id, onions.onion, users.instance FROM new_account INNER JOIN users ON (users.id=new_account.user_id) INNER JOIN onions ON (onions.user_id=users.id) $approval LIMIT 100;"); while($id=$stmt->fetch(PDO::FETCH_NUM)){ $onion=$id[6]; $system_account=$id[0]; - $firstchar=substr($system_account, 0, 1); - $reload[$firstchar]=true; + $instance=$id[7]; + $reload[$instance]=true; $enable_onion->execute([$id[6]]); //add and manage rights of system user $shell = ENABLE_SHELL_ACCESS ? '/bin/bash' : '/usr/sbin/nologin'; @@ -46,11 +46,11 @@ while($id=$stmt->fetch(PDO::FETCH_NUM)){ //add hidden services to tor $update_onion=$db->prepare('UPDATE onions SET private_key=?, enabled=1 WHERE onion=?;'); -$stmt=$db->query('SELECT onion, private_key, version FROM onions WHERE enabled=2;'); +$stmt=$db->query('SELECT onion, private_key, version, instance FROM onions WHERE enabled=2;'); $onions=$stmt->fetchAll(PDO::FETCH_NUM); foreach($onions as $onion){ - $firstchar=substr($onion[0], 0, 1); - $reload[$firstchar]=true; + $instance = $onion[3]; + $reload[$instance] = true; if($onion[2]==2){ //php openssl implementation has some issues, re-export using native openssl $pkey=openssl_pkey_get_private($onion[1]); @@ -58,57 +58,57 @@ foreach($onions as $onion){ openssl_pkey_free($pkey); $priv_key=shell_exec('echo ' . escapeshellarg($exported) . ' | openssl rsa'); //save hidden service - mkdir("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion", 0700); - file_put_contents("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/private_key", $priv_key); - chmod("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/private_key", 0600); - chown("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/", "_tor-$firstchar"); - chown("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/private_key", "_tor-$firstchar"); - chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/", "_tor-$firstchar"); - chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/private_key", "_tor-$firstchar"); + mkdir("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion", 0700); + file_put_contents("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/private_key", $priv_key); + chmod("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/private_key", 0600); + chown("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/", "_tor-$instance"); + chown("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/private_key", "_tor-$instance"); + chgrp("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/", "_tor-$instance"); + chgrp("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/private_key", "_tor-$instance"); $update_onion->execute([$priv_key, $onion[0]]); }elseif($onion[2]==3){ $priv_key=base64_decode($onion[1]); //save hidden service - mkdir("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion", 0700); - file_put_contents("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/hs_ed25519_secret_key", $priv_key); - chmod("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/hs_ed25519_secret_key", 0600); - chown("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/", "_tor-$firstchar"); - chown("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/hs_ed25519_secret_key", "_tor-$firstchar"); - chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/", "_tor-$firstchar"); - chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/hs_ed25519_secret_key", "_tor-$firstchar"); + mkdir("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion", 0700); + file_put_contents("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/hs_ed25519_secret_key", $priv_key); + chmod("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/hs_ed25519_secret_key", 0600); + chown("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/", "_tor-$instance"); + chown("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/hs_ed25519_secret_key", "_tor-$instance"); + chgrp("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/", "_tor-$instance"); + chgrp("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/hs_ed25519_secret_key", "_tor-$instance"); $update_onion->execute([$onion[1], $onion[0]]); } } //delete old accounts $del=$db->prepare("DELETE FROM users WHERE id=?;"); -$stmt=$db->query("SELECT system_account, id, mysql_user FROM users WHERE todelete=1 LIMIT 100;"); +$stmt=$db->query("SELECT system_account, id, mysql_user, instance FROM users WHERE todelete=1 LIMIT 100;"); $accounts=$stmt->fetchAll(PDO::FETCH_NUM); $mark_onions=$db->prepare('UPDATE onions SET enabled=-1 WHERE user_id=? AND enabled!=-2;'); foreach($accounts as $account){ - $firstchar=substr($account[0], 0, 1); - $reload[$firstchar]=true; + $instance=$account[3]; + $reload[$instance]=true; $mark_onions->execute([$account[1]]); } //delete hidden services from tor $del_onions=$db->prepare('DELETE FROM onions WHERE onion=?;'); -$stmt=$db->query('SELECT onion FROM onions WHERE enabled=-1;'); +$stmt=$db->query('SELECT onion, instance FROM onions WHERE enabled=-1;'); $onions=$stmt->fetchAll(PDO::FETCH_NUM); foreach($onions as $onion){ - $firstchar=substr($onion[0], 0, 1); - $reload[$firstchar]=true; - if(file_exists("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/")){ - if(file_exists("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/authorized_clients/")){ - foreach(glob("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/authorized_clients/*") as $file){ + $instance = $onion[1]; + $reload[$instance] = true; + if(file_exists("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/")){ + if(file_exists("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/authorized_clients/")){ + foreach(glob("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/authorized_clients/*") as $file){ unlink($file); } - rmdir("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/authorized_clients"); + rmdir("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/authorized_clients"); } - foreach(glob("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/*") as $file){ + foreach(glob("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/*") as $file){ unlink($file); } - rmdir("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/"); + rmdir("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/"); } $del_onions->execute([$onion[0]]); } diff --git a/var/www/html/admin.php b/var/www/html/admin.php index 6da576e..a00280c 100644 --- a/var/www/html/admin.php +++ b/var/www/html/admin.php @@ -15,6 +15,7 @@ echo 'Daniel\'s Hosting - Admin panel'; echo ''; echo ''; echo ''; +echo ''; echo ''; echo '

Hosting - Admin panel

'; $error=false; @@ -25,7 +26,7 @@ if($_SERVER['REQUEST_METHOD']==='POST' && isset($_POST['pass']) && $_POST['pass' } } if(empty($_SESSION['logged_in'])){ - echo '
'; + echo '
'; echo ""; send_captcha(); echo ""; @@ -41,17 +42,17 @@ if(empty($_SESSION['logged_in'])){ if(REQUIRE_APPROVAL){ $stmt=$db->query('SELECT COUNT(*) FROM new_account WHERE approved=0;'); $cnt=$stmt->fetch(PDO::FETCH_NUM)[0]; - echo 'Approve pending sites ($cnt) | "; + echo 'Approve pending sites ($cnt) | "; } - echo 'List of accounts | Delete accounts | Suspend hidden services | Edit hidden services | Logout

'; + echo 'List of accounts | Delete accounts | Suspend hidden services | Edit hidden services | Logout

'; if(empty($_REQUEST['action']) || $_REQUEST['action']==='login'){ echo '

Welcome to the admin panel!

'; }elseif($_REQUEST['action'] === 'logout'){ session_destroy(); - header('Location: ' . basename(__FILE__)); + header('Location: ' . $_SERVER['SCRIPT_NAME']); exit; }elseif($_REQUEST['action'] === 'list'){ - echo '"; + echo '"; echo '
Password
'; echo ''; $stmt=$db->query('SELECT users.username, onions.onion FROM users INNER JOIN onions ON (onions.user_id=users.id) ORDER BY users.username;'); @@ -84,7 +85,7 @@ if(empty($_SESSION['logged_in'])){ echo '

Successfully approved

'; } } - echo '"; + echo '"; echo '
UsernameOnion linkAction
'; echo ''; $stmt=$db->query('SELECT users.username, onions.onion FROM users INNER JOIN new_account ON (users.id=new_account.user_id) INNER JOIN onions ON (onions.user_id=users.id) WHERE new_account.approved=0 ORDER BY users.username;'); @@ -100,7 +101,7 @@ if(empty($_SESSION['logged_in'])){ $onion = substr($_REQUEST['action'], 7); } echo '

Delete accouts:

'; - echo ''; + echo ''; echo ''; echo '

Onion address: '; + echo ''; echo ''; echo '

Onion address: Successfully queued for suspension!

"; - $stmt=$db->prepare('UPDATE service_instances SET reload = 1 WHERE id=?'); - $stmt->execute([substr($match[1], 0, 1)]); + enqueue_instance_reload($db, substr($match[1], 0, 1)); }else{ echo "

Onion address not hosted by us!

"; } @@ -164,7 +164,7 @@ if(empty($_SESSION['logged_in'])){ $onion = substr($_REQUEST['action'], 5); } echo '

Edit hidden service:

'; - echo ''; + echo ''; echo ''; echo '

Onion address: Changes successfully saved!

"; } } $stmt=$db->prepare('SELECT onion, enabled, enable_smtp, num_intros, max_streams, version FROM onions WHERE onion=?;'); $stmt->execute([$match[1]]); if($onion=$stmt->fetch(PDO::FETCH_NUM)){ - echo ''; + echo ''; echo ''; echo '
UsernameOnion addressAction
'; echo ''; diff --git a/var/www/html/delete.php b/var/www/html/delete.php index 609f4e9..48ffef0 100644 --- a/var/www/html/delete.php +++ b/var/www/html/delete.php @@ -28,6 +28,7 @@ header('Content-Type: text/html; charset=UTF-8'); +

This will delete your account and all data asociated with it. It can't be un-done. Are you sure?

diff --git a/var/www/html/faq.php b/var/www/html/faq.php index 3c18507..559c101 100644 --- a/var/www/html/faq.php +++ b/var/www/html/faq.php @@ -7,6 +7,7 @@ header('Content-Type: text/html; charset=UTF-8'); +

Hosting - Info

Info | Register | Login | List of hosted sites | FAQ

diff --git a/var/www/html/files.php b/var/www/html/files.php index c20327a..2001bf6 100644 --- a/var/www/html/files.php +++ b/var/www/html/files.php @@ -286,6 +286,7 @@ $dir=htmlspecialchars($dir); +Daniel's Hosting - FileManager - Index of <?php echo $dir; ?>'; echo ''; echo "

Logged in as $user[username] Logout | Change passwords | FileManager | Delete account

"; diff --git a/var/www/html/index.php b/var/www/html/index.php index b320e04..c47651c 100644 --- a/var/www/html/index.php +++ b/var/www/html/index.php @@ -1,21 +1,13 @@ Daniel's Hosting +

Hosting - Info

Info | Register | Login | List of hosted sites | FAQ

@@ -36,9 +28,9 @@ if(isset($_SERVER['HTTP_HOST']) && preg_match('/danwin1210\.(i2p|me)$/', $_SERVE
  • mail() can send e-mails from your.onion@ (your.onion@hosting.danwin1210.me for clearnet) - not yet working but will return in future, use https://github.com/PHPMailer/PHPMailer or similar for now
  • Webmail and IMAP, POP3 and SMTP access to your mail account
  • Mail sent to anything@your.onion gets automatically redirected to your inbox
  • -
  • Your own .onion domain
  • -
  • On request your own clearnet domain or a free subdomain of danwin1210.me. I can setup an I2P domain as well.
  • -
  • There is a missing feature or you need a special configuration? Just ">contact me and I'll see what I can do.
  • +
  • Your own .onion domains
  • +
  • Clearnet domains or a free subdomain of danwin1210.me
  • +
  • There is a missing feature or you need a special configuration? Just ">contact me and I'll see what I can do.
  • Empty/Unused accounts will be automatically deleted after a month of inactivity
  • More to come…
  • diff --git a/var/www/html/list.php b/var/www/html/list.php index bebf9fe..fcb7f25 100644 --- a/var/www/html/list.php +++ b/var/www/html/list.php @@ -11,6 +11,7 @@ echo 'Daniel\'s Hosting - List of hosted sites'; echo ''; echo ''; echo ''; +echo ''; echo ''; echo '

    Hosting - List of hosted sites

    '; echo '

    Info | Register | Login | List of hosted sites | FAQ

    '; diff --git a/var/www/html/login.php b/var/www/html/login.php index 53d70f3..ccd24c0 100644 --- a/var/www/html/login.php +++ b/var/www/html/login.php @@ -64,6 +64,7 @@ echo 'Daniel\'s Hosting - Login'; echo ''; echo ''; echo ''; +echo ''; echo ''; echo '

    Hosting - Login

    '; echo '

    Info | Register | Login | List of hosted sites | FAQ

    '; diff --git a/var/www/html/password.php b/var/www/html/password.php index 2fea245..3de7e4d 100644 --- a/var/www/html/password.php +++ b/var/www/html/password.php @@ -46,6 +46,7 @@ echo 'Daniel\'s Hosting - Change password'; echo ''; echo ''; echo ''; +echo ''; echo ''; echo $msg; echo '
    OnionEnabledSMTP enabledNr. of introsMax streams per rend circuitSave
    '; diff --git a/var/www/html/register.php b/var/www/html/register.php index e6050b3..33cdf79 100644 --- a/var/www/html/register.php +++ b/var/www/html/register.php @@ -17,6 +17,7 @@ if(!empty($_SESSION['hosting_username'])){ +

    Hosting - Register

    @@ -106,11 +107,10 @@ if($_SERVER['REQUEST_METHOD']==='POST'){ $ok=false; }elseif($ok){ $mysql_user = add_mysql_user($db, $_POST['pass']); - $stmt=$db->prepare('INSERT INTO users (username, system_account, password, dateadded, public, php, autoindex, mysql_user) VALUES (?, ?, ?, ?, ?, ?, ?, ?);'); - $stmt->execute([$_POST['username'], substr("$onion.onion", 0, 32), $hash, time(), $public_list, $php, $autoindex, $mysql_user]); + $stmt=$db->prepare('INSERT INTO users (username, system_account, password, dateadded, public, php, autoindex, mysql_user, instance) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);'); + $stmt->execute([$_POST['username'], substr("$onion.onion", 0, 32), $hash, time(), $public_list, $php, $autoindex, $mysql_user, SERVICE_INSTANCES[array_rand(SERVICE_INSTANCES)]]); $user_id = $db->lastInsertId(); - $stmt=$db->prepare('INSERT INTO onions (user_id, onion, private_key, version) VALUES (?, ?, ?, ?);'); - $stmt->execute([$user_id, $onion, $priv_key, $onion_version]); + add_user_onion($db, $user_id, $onion, $priv_key, $onion_version); add_user_db($db, $user_id); $stmt=$db->prepare('INSERT INTO new_account (user_id, password) VALUES (?, ?);'); $stmt->execute([$user_id, get_system_hash($_POST['pass'])]); diff --git a/var/www/setup.php b/var/www/setup.php index 88d4ff7..79a5832 100644 --- a/var/www/setup.php +++ b/var/www/setup.php @@ -22,13 +22,13 @@ $version; if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';")){ //create tables $db->exec('CREATE TABLE captcha (id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, time int(11) NOT NULL, code char(5) COLLATE latin1_bin NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;'); - $db->exec("CREATE TABLE users (id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, system_account varchar(32) COLLATE latin1_bin NOT NULL UNIQUE, username varchar(50) COLLATE latin1_bin NOT NULL UNIQUE, password varchar(255) COLLATE latin1_bin NOT NULL, dateadded int(10) unsigned NOT NULL, public tinyint(1) unsigned NOT NULL, php tinyint(1) unsigned NOT NULL, autoindex tinyint(1) unsigned NOT NULL, todelete tinyint(1) UNSIGNED NOT NULL DEFAULT '0', mysql_user varchar(32) NOT NULL, KEY dateadded (dateadded), KEY public (public), KEY todelete (todelete)) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;"); + $db->exec("CREATE TABLE service_instances (id char(1) NOT NULL PRIMARY KEY, reload tinyint(1) UNSIGNED NOT NULL DEFAULT '0', KEY reload (reload)) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;"); + $db->exec("CREATE TABLE users (id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, system_account varchar(32) COLLATE latin1_bin NOT NULL UNIQUE, username varchar(50) COLLATE latin1_bin NOT NULL UNIQUE, password varchar(255) COLLATE latin1_bin NOT NULL, dateadded int(10) unsigned NOT NULL, public tinyint(1) unsigned NOT NULL, php tinyint(1) unsigned NOT NULL, autoindex tinyint(1) unsigned NOT NULL, todelete tinyint(1) UNSIGNED NOT NULL DEFAULT '0', mysql_user varchar(32) NOT NULL, instance char(1) NOT NULL DEFAULT '2', KEY dateadded (dateadded), KEY public (public), KEY todelete (todelete), KEY instance (instance), CONSTRAINT instance_ibfk_2 FOREIGN KEY (instance) REFERENCES service_instances (id) ON DELETE RESTRICT ON UPDATE RESTRICT) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;"); $db->exec("CREATE TABLE new_account (user_id int(11) NOT NULL PRIMARY KEY, password varchar(255) COLLATE latin1_bin NOT NULL, approved tinyint(1) UNSIGNED NOT NULL DEFAULT '0', CONSTRAINT new_account_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;"); $db->exec('CREATE TABLE pass_change (user_id int(11) NOT NULL PRIMARY KEY, password varchar(255) COLLATE latin1_bin NOT NULL, CONSTRAINT pass_change_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;'); $db->exec('CREATE TABLE mysql_databases (user_id int(11) NOT NULL, mysql_database varchar(64) COLLATE latin1_bin NOT NULL, KEY user_id (user_id), CONSTRAINT mysql_database_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;'); - $db->exec("CREATE TABLE onions (user_id int(11) NULL, onion varchar(56) COLLATE latin1_bin NOT NULL PRIMARY KEY, private_key varchar(1000) COLLATE latin1_bin NOT NULL, version tinyint(1) NOT NULL, enabled tinyint(1) NOT NULL DEFAULT '1', num_intros tinyint(3) NOT NULL DEFAULT '3', enable_smtp tinyint(1) NOT NULL DEFAULT '1', max_streams tinyint(3) unsigned NOT NULL DEFAULT '20', KEY user_id (user_id), KEY enabled (enabled), CONSTRAINT onions_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE SET NULL ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;"); + $db->exec("CREATE TABLE onions (user_id int(11) NULL, onion varchar(56) COLLATE latin1_bin NOT NULL PRIMARY KEY, private_key varchar(1000) COLLATE latin1_bin NOT NULL, version tinyint(1) NOT NULL, enabled tinyint(1) NOT NULL DEFAULT '1', num_intros tinyint(3) NOT NULL DEFAULT '3', enable_smtp tinyint(1) NOT NULL DEFAULT '1', max_streams tinyint(3) unsigned NOT NULL DEFAULT '20', instance char(1) NOT NULL DEFAULT '2', KEY user_id (user_id), KEY enabled (enabled), KEY instance(instance), CONSTRAINT onions_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE SET NULL ON UPDATE CASCADE, CONSTRAINT instance_ibfk_1 FOREIGN KEY (instance) REFERENCES service_instances (id) ON DELETE RESTRICT ON UPDATE RESTRICT) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;"); $db->exec("CREATE TABLE domains (user_id int(11) NULL, domain varchar(255) COLLATE latin1_bin NOT NULL PRIMARY KEY, enabled tinyint(1) NOT NULL DEFAULT '1', KEY user_id (user_id), KEY enabled (enabled), CONSTRAINT domains_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;"); - $db->exec("CREATE TABLE service_instances (id char(1) NOT NULL PRIMARY KEY, reload tinyint(1) UNSIGNED NOT NULL DEFAULT '0', KEY reload (reload)) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;"); $stmt=$db->prepare('INSERT INTO service_instances (id) VALUES (?);'); foreach(SERVICE_INSTANCES as $key){ $stmt->execute([$key]); @@ -142,6 +142,12 @@ if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';")) if($version<13){ $db->exec("CREATE TABLE domains (user_id int(11) NULL, domain varchar(255) COLLATE latin1_bin NOT NULL PRIMARY KEY, enabled tinyint(1) NOT NULL DEFAULT '1', KEY user_id (user_id), KEY enabled (enabled), CONSTRAINT domains_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;"); } + if($version<14){ + $db->exec("ALTER TABLE onions ADD instance char(1) NOT NULL DEFAULT '2', ADD KEY instance(instance), ADD CONSTRAINT instance_ibfk_1 FOREIGN KEY (instance) REFERENCES service_instances (id) ON DELETE RESTRICT ON UPDATE RESTRICT;"); + $db->exec('UPDATE onions SET instance = SUBSTR(onion, 1, 1);'); + $db->exec("ALTER TABLE users ADD instance char(1) NOT NULL DEFAULT '2', ADD KEY instance(instance), ADD CONSTRAINT instance_ibfk_2 FOREIGN KEY (instance) REFERENCES service_instances (id) ON DELETE RESTRICT ON UPDATE RESTRICT;"); + $db->exec('UPDATE users SET instance = SUBSTR(system_account, 1, 1);'); + } $stmt=$db->prepare("UPDATE settings SET value=? WHERE setting='version';"); $stmt->execute([DBVERSION]); }