diff --git a/var/www/common.php b/var/www/common.php
index c47b24e..7e7686a 100644
--- a/var/www/common.php
+++ b/var/www/common.php
@@ -4,7 +4,7 @@ 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=3; //database layout version
+const DBVERSION=4; //database layout version
const CAPTCHA=0; // Captcha difficulty (0=off, 1=simple, 2=moderate, 3=extreme)
const ADDRESS='dhosting4okcs22v.onion'; // our own address
const SERVERS=[ //servers and ports we are running on
diff --git a/var/www/cron.php b/var/www/cron.php
index bb372f9..f33a82f 100644
--- a/var/www/cron.php
+++ b/var/www/cron.php
@@ -8,10 +8,10 @@ try{
$reload=[];
//add new accounts
-$del=$db->prepare("DELETE FROM new_account WHERE onion=?;");
+$del=$db->prepare("DELETE FROM new_account WHERE user_id=?;");
$update_priv=$db->prepare("UPDATE users SET private_key=? WHERE onion=?;");
$approval = REQUIRE_APPROVAL ? 'WHERE new_account.approved=1': '';
-$stmt=$db->query("SELECT new_account.onion, users.username, new_account.password, users.private_key, users.php, users.autoindex FROM new_account INNER JOIN users ON (users.onion=new_account.onion) $approval LIMIT 100;");
+$stmt=$db->query("SELECT users.onion, users.username, new_account.password, users.private_key, users.php, users.autoindex, users.id FROM new_account INNER JOIN users ON (users.id=new_account.user_id) $approval LIMIT 100;");
while($id=$stmt->fetch(PDO::FETCH_NUM)){
$onion=$id[0];
$firstchar=substr($onion, 0, 1);
@@ -116,10 +116,10 @@ php_admin_value[session.save_path] = /home/$onion.onion/tmp
chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/private_key", "_tor-$firstchar");
//add hidden service to torrc
$torrc=file_get_contents("/etc/tor/instances/$firstchar/torrc");
- $torrc.="HiddenServiceDir /var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/\nHiddenServicePort 80 unix:/var/run/nginx/$onion\nHiddenServicePort 25 127.0.0.1:25\n";
+ $torrc.="HiddenServiceDir /var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/\nHiddenServicePort 80 unix:/var/run/nginx/$onion\nHiddenServicePort 25\n";
file_put_contents("/etc/tor/instances/$firstchar/torrc", $torrc);
//remove from to-add queue
- $del->execute([$onion]);
+ $del->execute([$id[6]]);
}
//delete old accounts
@@ -142,7 +142,7 @@ foreach($onions as $onion){
unlink("/etc/nginx/sites-enabled/$onion[0].onion");
//clean torrc from user
$torrc=file_get_contents("/etc/tor/instances/$firstchar/torrc");
- $torrc=str_replace("HiddenServiceDir /var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/\nHiddenServicePort 80 unix:/var/run/nginx/$onion[0]\nHiddenServicePort 25 127.0.0.1:25\n", '', $torrc);
+ $torrc=str_replace("HiddenServiceDir /var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/\nHiddenServicePort 80 unix:/var/run/nginx/$onion[0]\nHiddenServicePort 25\n", '', $torrc);
file_put_contents("/etc/tor/instances/$firstchar/torrc", $torrc);
//delete hidden service from tor
if(file_exists("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/")){
@@ -180,9 +180,9 @@ foreach($onions as $onion){
}
// update passwords
-$stmt=$db->query("SELECT onion, password FROM pass_change LIMIT 100;");
-$del=$db->prepare("DELETE FROM pass_change WHERE onion=?;");
+$stmt=$db->query("SELECT users.onion, pass_change.password, users.id FROM pass_change INNER JOIN users ON (users.id=pass_change.user_id) LIMIT 100;");
+$del=$db->prepare("DELETE FROM pass_change WHERE user_id=?;");
while($onion=$stmt->fetch(PDO::FETCH_NUM)){
exec('usermod -p '. escapeshellarg($onion[1]) . " $onion[0].onion");
- $del->execute([$onion[0]]);
+ $del->execute([$onion[2]]);
}
diff --git a/var/www/html/admin.php b/var/www/html/admin.php
index 39098e3..3513575 100644
--- a/var/www/html/admin.php
+++ b/var/www/html/admin.php
@@ -27,7 +27,7 @@ if(empty($_SESSION['logged_in'])){
echo "
';
if($error){
echo "$error
";
@@ -59,13 +59,13 @@ if(empty($_SESSION['logged_in'])){
echo '';
}elseif($_REQUEST['action']==='approve'){
if(!empty($_POST['onion'])){
- $stmt=$db->prepare('UPDATE new_account SET approved=1 WHERE onion=?;');
+ $stmt=$db->prepare('UPDATE new_account INNER JOIN users ON (users.id=new_account.user_id) SET new_account.approved=1 WHERE users.onion=?;');
$stmt->execute([$_POST['onion']]);
echo 'Successfully approved
';
}
echo '';
echo 'Username | Onion address | Action |
';
- $stmt=$db->query('SELECT users.username, users.onion FROM users INNER JOIN new_account ON (users.onion=new_account.onion) WHERE new_account.approved=0 ORDER BY users.username;');
+ $stmt=$db->query('SELECT users.username, users.onion FROM users INNER JOIN new_account ON (users.id=new_account.user_id) WHERE new_account.approved=0 ORDER BY users.username;');
while($tmp=$stmt->fetch(PDO::FETCH_NUM)){
echo "";
}
diff --git a/var/www/html/login.php b/var/www/html/login.php
index 2fb75e8..bcd90ad 100644
--- a/var/www/html/login.php
+++ b/var/www/html/login.php
@@ -33,7 +33,7 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
if($tmp){
$username=$tmp[0];
$password=$tmp[1];
- $stmt=$db->prepare('SELECT approved FROM new_account WHERE onion=?;');
+ $stmt=$db->prepare('SELECT new_account.approved FROM new_account INNER JOIN users ON (users.id=new_account.user_id) WHERE users.onion=?;');
$stmt->execute([$tmp[2]]);
if($tmp=$stmt->fetch(PDO::FETCH_NUM)){
if(REQUIRE_APPROVAL && !$tmp[0]){
diff --git a/var/www/html/password.php b/var/www/html/password.php
index 1f5699b..7627c7d 100644
--- a/var/www/html/password.php
+++ b/var/www/html/password.php
@@ -23,9 +23,9 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
$stmt->execute([$hash, $user['username']]);
$msg.='Successfully changed account password.
';
}elseif($_REQUEST['type']==='sys'){
- $stmt=$db->prepare('INSERT INTO pass_change (onion, password) VALUES (?, ?);');
+ $stmt=$db->prepare('INSERT INTO pass_change (user_id, password) VALUES (?, ?);');
$hash=get_system_hash($_POST['newpass']);
- $stmt->execute([$user['onion'], $hash]);
+ $stmt->execute([$user['id'], $hash]);
$msg.='Successfully changed system account password, change will take affect within the next minute.
';
}elseif($_REQUEST['type']==='sql'){
$stmt=$db->prepare("SET PASSWORD FOR '$user[onion].onion'@'%'=PASSWORD(?);");
diff --git a/var/www/html/register.php b/var/www/html/register.php
index 27d24ab..3d19a6f 100644
--- a/var/www/html/register.php
+++ b/var/www/html/register.php
@@ -104,13 +104,16 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
}elseif($ok){
$stmt=$db->prepare('INSERT INTO users (username, password, onion, private_key, dateadded, public, php, autoindex) VALUES (?, ?, ?, ?, ?, ?, ?, ?);');
$stmt->execute([$_POST['username'], $hash, $onion, $priv_key, time(), $public, $php, $autoindex]);
+ $stmt=$db->prepare('SELECT id FROM users WHERE username=?;');
+ $stmt->execute([$_POST['username']]);
+ $user_id=$stmt->fetch(PDO::FETCH_NUM)[0];
$create_user=$db->prepare("CREATE USER '$onion.onion'@'%' IDENTIFIED BY ?;");
$create_user->execute([$_POST['pass']]);
$db->exec("CREATE DATABASE IF NOT EXISTS `$onion`;");
$db->exec("GRANT ALL PRIVILEGES ON `$onion`.* TO '$onion.onion'@'%';");
$db->exec('FLUSH PRIVILEGES;');
- $stmt=$db->prepare('INSERT INTO new_account (onion, password) VALUES (?, ?);');
- $stmt->execute([$onion, get_system_hash($_POST['pass'])]);
+ $stmt=$db->prepare('INSERT INTO new_account (user_id, password) VALUES (?, ?);');
+ $stmt->execute([$user_id, get_system_hash($_POST['pass'])]);
if(EMAIL_TO!==''){
$title="A new hidden service $onion has been created";
$msg="A new hidden service http://$onion.onion has been created";
diff --git a/var/www/setup.php b/var/www/setup.php
index e4eaafe..f624343 100644
--- a/var/www/setup.php
+++ b/var/www/setup.php
@@ -22,9 +22,9 @@ $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 (onion char(16) COLLATE latin1_bin NOT NULL PRIMARY KEY, username varchar(50) COLLATE latin1_bin NOT NULL UNIQUE, password varchar(255) COLLATE latin1_bin NOT NULL, private_key varchar(1000) COLLATE latin1_bin NOT NULL, dateadded int(10) unsigned NOT NULL, public tinyint(3) unsigned NOT NULL, php tinyint(1) unsigned NOT NULL, autoindex tinyint(1) unsigned NOT NULL, todelete tinyint(1) UNSIGNED NOT NULL, KEY public (public), KEY dateadded (dateadded), KEY todelete (todelete)) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;');
- $db->exec('CREATE TABLE new_account (onion char(16) COLLATE latin1_bin NOT NULL PRIMARY KEY, password varchar(255) COLLATE latin1_bin NOT NULL, approved tinyint(1) UNSIGNED NOT NULL, CONSTRAINT new_account_ibfk_1 FOREIGN KEY (onion) REFERENCES users (onion) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;');
- $db->exec('CREATE TABLE pass_change (onion char(16) COLLATE latin1_bin NOT NULL PRIMARY KEY, password varchar(255) COLLATE latin1_bin NOT NULL, CONSTRAINT pass_change_ibfk_1 FOREIGN KEY (onion) REFERENCES users (onion) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;');
+ $db->exec('CREATE TABLE users (id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, onion char(16) COLLATE latin1_bin NOT NULL UNIQUE, username varchar(50) COLLATE latin1_bin NOT NULL UNIQUE, password varchar(255) COLLATE latin1_bin NOT NULL, private_key varchar(1000) COLLATE latin1_bin NOT NULL, dateadded int(10) unsigned NOT NULL, public tinyint(3) unsigned NOT NULL, php tinyint(1) unsigned NOT NULL, autoindex tinyint(1) unsigned NOT NULL, todelete tinyint(1) UNSIGNED NOT NULL, KEY public (public), KEY dateadded (dateadded), KEY todelete (todelete)) 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, 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 settings (setting varchar(50) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL PRIMARY KEY, value text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;');
$stmt=$db->prepare("INSERT INTO settings (setting, value) VALUES ('version', ?);");
$stmt->execute([DBVERSION]);
@@ -50,6 +50,21 @@ if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';"))
exec('service nginx reload');
exec("service tor reload");
}
+ if($version<4){
+ $db->exec('ALTER TABLE new_account DROP FOREIGN KEY new_account_ibfk_1;');
+ $db->exec('ALTER TABLE pass_change DROP FOREIGN KEY pass_change_ibfk_1;');
+ $db->exec('ALTER TABLE users DROP PRIMARY KEY;');
+ $db->exec('ALTER TABLE users ADD id int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST;');
+ $db->exec('ALTER TABLE users ADD UNIQUE (onion);');
+ $db->exec('RENAME TABLE new_account TO copy_new_account;');
+ $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, 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('INSERT INTO new_account SELECT users.id, copy_new_account.password, copy_new_account.approved FROM copy_new_account INNER JOIN users ON (users.onion=copy_new_account.onion);');
+ $db->exec('DROP TABLE copy_new_account;');
+ $db->exec('RENAME TABLE pass_change TO copy_pass_change;');
+ $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('INSERT INTO pass_change SELECT users.id, copy_pass_change.password FROM copy_pass_change INNER JOIN users ON (users.onion=copy_pass_change.onion);');
+ $db->exec('DROP TABLE copy_pass_change;');
+ }
$stmt=$db->prepare("UPDATE settings SET value=? WHERE setting='version';");
$stmt->execute([DBVERSION]);
if(DBVERSION!=$version){