Structure changes for future features

This commit is contained in:
Daniel Winzen
2018-10-20 18:20:27 +02:00
parent 96efd92ab1
commit 2cee59dc6f
47 changed files with 186 additions and 355 deletions

View File

@ -2,4 +2,4 @@ user = hosting
password = MY_PASSWORD password = MY_PASSWORD
hosts = localhost hosts = localhost
dbname = hosting dbname = hosting
query = SELECT '%d@dhosting4okcs22v.onion' FROM users WHERE '%d' = CONCAT(onion, '.onion') query = SELECT '%d@dhosting4okcs22v.onion' FROM users WHERE '%d' = system_account

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -1,7 +0,0 @@
ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6

View File

@ -4,12 +4,12 @@ const DBUSER='hosting'; // Database user
const DBPASS='MY_PASSWORD'; // Database password const DBPASS='MY_PASSWORD'; // Database password
const DBNAME='hosting'; // Database const DBNAME='hosting'; // Database
const PERSISTENT=true; // Use persistent database conection true/false const PERSISTENT=true; // Use persistent database conection true/false
const DBVERSION=5; //database layout version const DBVERSION=6; //database layout version
const CAPTCHA=0; // Captcha difficulty (0=off, 1=simple, 2=moderate, 3=extreme) const CAPTCHA=0; // Captcha difficulty (0=off, 1=simple, 2=moderate, 3=extreme)
const ADDRESS='dhosting4okcs22v.onion'; // our own address const ADDRESS='dhosting4okcs22v.onion'; // our own address
const SERVERS=[ //servers and ports we are running on const SERVERS=[ //servers and ports we are running on
'dhosting4okcs22v.onion'=>['sftp'=>22, 'ftp'=>21, 'pop3'=>'110', 'imap'=>'143', 'smtp'=>'25'], 'dhosting4okcs22v.onion'=>['sftp'=>22, 'ftp'=>21, 'pop3'=>'110', 'imap'=>'143', 'smtp'=>'25'],
'danwin1210.me'=>['sftp'=>22, 'ftp'=>21, 'pop3'=>'', 'imap'=>'', 'smtp'=>''] 'hosting.danwin1210.me'=>['sftp'=>222, 'ftp'=>21, 'pop3'=>'1995', 'imap'=>'1993', 'smtp'=>'1465']
]; ];
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 considdered as unchanged for deletion
@ -200,3 +200,28 @@ function check_captcha_error(){
} }
return false; return false;
} }
function rewrite_torrc(PDO $db, string $key){
$torrc="ClientUseIPv6 1
ClientUseIPv4 1
SOCKSPort 0
MaxClientCircuitsPending 1024
NumEntryGuards 6
NumDirectoryGuards 6
NumPrimaryGuards 6
";
$stmt=$db->prepare('SELECT onions.onion, users.system_account, onions.num_intros, onions.enable_smtp, onions.version FROM onions INNER JOIN users ON (users.id=onions.user_id) WHERE onions.onion LIKE ? AND enabled=1;');
$stmt->execute(["$key%"]);
while($tmp=$stmt->fetch(PDO::FETCH_NUM)){
$torrc.="HiddenServiceDir /var/lib/tor-instances/$key/hidden_service_$tmp[0].onion/
HiddenServiceNumIntroductionPoints $tmp[2]
HiddenServiceVersion $tmp[4]
HiddenServicePort 80 unix:/var/run/nginx/$tmp[1]
";
if($tmp[3]){
$torrc.="HiddenServicePort 25\n";
}
}
file_put_contents("/etc/tor/instances/$key/torrc", $torrc);
exec("service tor@$key reload");
}

View File

@ -9,12 +9,13 @@ $reload=[];
//add new accounts //add new accounts
$del=$db->prepare("DELETE FROM new_account WHERE user_id=?;"); $del=$db->prepare("DELETE FROM new_account WHERE user_id=?;");
$update_priv=$db->prepare("UPDATE users SET private_key=? WHERE onion=?;"); $update_priv=$db->prepare("UPDATE onions SET private_key=? WHERE user_id=?;");
$approval = REQUIRE_APPROVAL ? 'WHERE new_account.approved=1': ''; $approval = REQUIRE_APPROVAL ? 'WHERE new_account.approved=1': '';
$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;"); $stmt=$db->query("SELECT users.system_account, users.username, new_account.password, onions.private_key, 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;");
while($id=$stmt->fetch(PDO::FETCH_NUM)){ while($id=$stmt->fetch(PDO::FETCH_NUM)){
$onion=$id[0]; $onion=$id[7];
$firstchar=substr($onion, 0, 1); $system_account=$id[0];
$firstchar=substr($system_account, 0, 1);
$reload[$firstchar]=true; $reload[$firstchar]=true;
//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($id[3]); $pkey=openssl_pkey_get_private($id[3]);
@ -22,21 +23,21 @@ while($id=$stmt->fetch(PDO::FETCH_NUM)){
openssl_pkey_free($pkey); openssl_pkey_free($pkey);
$priv_key=shell_exec('openssl rsa < key.tmp'); $priv_key=shell_exec('openssl rsa < key.tmp');
unlink('key.tmp'); unlink('key.tmp');
$update_priv->execute([$priv_key, $onion]); $update_priv->execute([$priv_key, $id[6]]);
//add and manage rights of system user //add and manage rights of system user
exec('useradd -l -p '. escapeshellarg($id[2]) . " -g www-data -k /var/www/skel -m -s /usr/sbin/nologin $onion.onion"); exec('useradd -l -p ' . escapeshellarg($id[2]) . ' -g www-data -k /var/www/skel -m -s /usr/sbin/nologin ' . escapeshellarg($system_account));
chown("/home/$onion.onion", 'root'); chown("/home/$system_account", 'root');
chgrp("/home/$onion.onion", 'www-data'); chgrp("/home/$system_account", 'www-data');
chmod("/home/$onion.onion", 0550); chmod("/home/$system_account", 0550);
foreach(['.ssh', 'data', 'Maildir', 'tmp'] as $dir){ foreach(['.ssh', 'data', 'Maildir', 'tmp'] as $dir){
mkdir("/home/$onion.onion/$dir", 0700); mkdir("/home/$system_account/$dir", 0700);
chown("/home/$onion.onion/$dir", "$onion.onion"); chown("/home/$system_account/$dir", $system_account);
chgrp("/home/$onion.onion/$dir", 'www-data'); chgrp("/home/$system_account/$dir", 'www-data');
} }
foreach(['logs'] as $dir){ foreach(['logs']){
mkdir("/home/$onion.onion/$dir", 0550); mkdir("/home/$system_account/$dir", 0550);
chown("/home/$onion.onion/$dir", "$onion.onion"); chown("/home/$system_account/$dir", $system_account);
chgrp("/home/$onion.onion/$dir", 'www-data'); chgrp("/home/$system_account/$dir", 'www-data');
} }
//configuration for services //configuration for services
@ -45,13 +46,13 @@ if($id[4]>0){
$php_location=" $php_location="
location ~ [^/]\.php(/|\$) { location ~ [^/]\.php(/|\$) {
include snippets/fastcgi-php.conf; include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/$onion; fastcgi_pass unix:/run/php/$system_account;
} }
"; ";
}else{ }else{
$php_location=''; $php_location='';
} }
if($id[5]!=0){ if($id[5]){
$autoindex='on'; $autoindex='on';
}else{ }else{
$autoindex='off'; $autoindex='off';
@ -59,14 +60,14 @@ if($id[5]!=0){
$nginx="server { $nginx="server {
listen [::]:80; listen [::]:80;
listen unix:/var/run/nginx/$onion; listen unix:/var/run/nginx/$system_account;
root /home/$onion.onion/www; root /home/$system_account/www;
server_name $onion.onion *.$onion.onion; server_name $onion.onion *.$onion.onion;
access_log /var/log/nginx/access_$onion.onion.log custom buffer=16k flush=1m; access_log /var/log/nginx/access_$system_account.log custom buffer=8k flush=1m;
access_log /home/$onion.onion/logs/access.log custom buffer=16k flush=1m; access_log /home/$system_account/logs/access.log custom buffer=8k flush=1m;
error_log /var/log/nginx/error_$onion.onion.log notice; error_log /var/log/nginx/error_$system_account.log notice;
error_log /home/$onion.onion/logs/error.log notice; error_log /home/$system_account/logs/error.log notice;
disable_symlinks on from=/home/$onion.onion/www; disable_symlinks on from=/home/$system_account;
autoindex $autoindex; autoindex $autoindex;
location / { location / {
try_files \$uri \$uri/ =404;$php_location try_files \$uri \$uri/ =404;$php_location
@ -74,33 +75,33 @@ $nginx="server {
} }
"; ";
$php="[$onion] $php="[$system_account]
user = $onion.onion user = $system_account
group = www-data group = www-data
listen = /run/php/$onion listen = /run/php/$system_account
listen.owner = www-data listen.owner = www-data
listen.group = www-data listen.group = www-data
listen.mode = 0660 listen.mode = 0660
pm = ondemand pm = ondemand
pm.max_children = 20 pm.max_children = 20
pm.process_idle_timeout = 10s; pm.process_idle_timeout = 10s;
php_admin_value[sendmail_path] = '/usr/bin/php /var/www/sendmail_wrapper.php \"$onion.onion <$onion.onion@" . ADDRESS . ">\" | /usr/sbin/sendmail -t -i' php_admin_value[sendmail_path] = '/usr/bin/php /var/www/sendmail_wrapper.php \"$system_account <$system_account@" . ADDRESS . ">\" | /usr/sbin/sendmail -t -i'
php_admin_value[memory_limit] = 256M php_admin_value[memory_limit] = 256M
php_admin_value[disable_functions] = exec,link,passthru,pcntl_alarm,pcntl_async_signals,pcntl_exec,pcntl_fork,pcntl_get_last_error,pcntl_getpriority,pcntl_setpriority,pcntl_signal,pcntl_signal_dispatch,pcntl_signal_get_handler,pcntl_sigprocmask,pcntl_sigtimedwait,pcntl_sigwaitinfo,pcntl_strerror,pcntl_waitpid,pcntl_wait,pcntl_wexitstatus,pcntl_wifcontinued,pcntl_wifexited,pcntl_wifsignaled,pcntl_wifstopped,pcntl_wstopsig,pcntl_wtermsig,popen,posix_ctermid,posix_getgrgid,posix_getgrnam,posix_getpgid,posix_getpwnam,posix_getpwuid,posix_getrlimit,posix_getsid,posix_kill,posix_setegid,posix_seteuid,posix_setgid,posix_setpgid,posix_setrlimit,posix_setuid,posix_ttyname,posix_uname,proc_open,putenv,shell_exec,socket_listen,socket_create_listen,socket_bind,stream_socket_server,symlink,system php_admin_value[disable_functions] = exec,link,passthru,pcntl_alarm,pcntl_async_signals,pcntl_exec,pcntl_fork,pcntl_get_last_error,pcntl_getpriority,pcntl_setpriority,pcntl_signal,pcntl_signal_dispatch,pcntl_signal_get_handler,pcntl_sigprocmask,pcntl_sigtimedwait,pcntl_sigwaitinfo,pcntl_strerror,pcntl_waitpid,pcntl_wait,pcntl_wexitstatus,pcntl_wifcontinued,pcntl_wifexited,pcntl_wifsignaled,pcntl_wifstopped,pcntl_wstopsig,pcntl_wtermsig,popen,posix_ctermid,posix_getgrgid,posix_getgrnam,posix_getpgid,posix_getpwnam,posix_getpwuid,posix_getrlimit,posix_getsid,posix_kill,posix_setegid,posix_seteuid,posix_setgid,posix_setpgid,posix_setrlimit,posix_setuid,posix_ttyname,posix_uname,proc_open,putenv,shell_exec,socket_listen,socket_create_listen,socket_bind,stream_socket_server,symlink,system
php_admin_value[open_basedir] = /home/$onion.onion php_admin_value[open_basedir] = /home/$system_account
php_admin_value[upload_tmp_dir] = /home/$onion.onion/tmp php_admin_value[upload_tmp_dir] = /home/$system_account/tmp
php_admin_value[soap.wsdl_cache_dir] = /home/$onion.onion/tmp php_admin_value[soap.wsdl_cache_dir] = /home/$system_account/tmp
php_admin_value[session.save_path] = /home/$onion.onion/tmp php_admin_value[session.save_path] = /home/$system_account/tmp
"; ";
//save configuration files //save configuration files
file_put_contents("/etc/nginx/sites-enabled/$onion.onion", $nginx); file_put_contents("/etc/nginx/sites-enabled/$system_account", $nginx);
if($id[4]==1){ if($id[4]==1){
file_put_contents("/etc/php/7.0/fpm/pool.d/$firstchar/$onion.conf", $php); file_put_contents("/etc/php/7.0/fpm/pool.d/$firstchar/$system_account.conf", $php);
}elseif($id[4]==2){ }elseif($id[4]==2){
file_put_contents("/etc/php/7.1/fpm/pool.d/$firstchar/$onion.conf", $php); file_put_contents("/etc/php/7.1/fpm/pool.d/$firstchar/$system_account.conf", $php);
}elseif($id[4]==3){ }elseif($id[4]==3){
file_put_contents("/etc/php/7.2/fpm/pool.d/$firstchar/$onion.conf", $php); file_put_contents("/etc/php/7.2/fpm/pool.d/$firstchar/$system_account.conf", $php);
} }
//save hidden service //save hidden service
mkdir("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion", 0700); mkdir("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion", 0700);
@ -114,42 +115,41 @@ php_admin_value[session.save_path] = /home/$onion.onion/tmp
chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/", "_tor-$firstchar"); chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/", "_tor-$firstchar");
chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/hostname", "_tor-$firstchar"); chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/hostname", "_tor-$firstchar");
chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/private_key", "_tor-$firstchar"); 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\n";
file_put_contents("/etc/tor/instances/$firstchar/torrc", $torrc);
//remove from to-add queue //remove from to-add queue
$del->execute([$id[6]]); $del->execute([$id[6]]);
} }
//delete old accounts //delete old accounts
$del=$db->prepare("DELETE FROM users WHERE onion=?"); $del=$db->prepare("DELETE FROM users WHERE id=?;");
$stmt=$db->query("SELECT onion, id, mysql_user FROM users WHERE todelete=1 LIMIT 100;"); $stmt=$db->query("SELECT system_account, id, mysql_user FROM users WHERE todelete=1 LIMIT 100;");
$onions=$stmt->fetchAll(PDO::FETCH_NUM); $onions=$stmt->fetchAll(PDO::FETCH_NUM);
$stmt=$db->prepare('SELECT onion FROM onions WHERE user_id=?;');
$del_onions=$db->prepare('DELETE FROM onions WHERE user_id=?;');
foreach($onions as $onion){ foreach($onions as $onion){
$firstchar=substr($onion[0], 0, 1); $firstchar=substr($onion[0], 0, 1);
$reload[$firstchar]=true; $reload[$firstchar]=true;
//delete config files //delete config files
if(file_exists("/etc/php/7.0/fpm/pool.d/$firstchar/$onion[0].conf")){ foreach(['7.0', '7.1', '7.2'] as $v){
unlink("/etc/php/7.0/fpm/pool.d/$firstchar/$onion[0].conf"); // new naming schema
if(file_exists("/etc/php/$v/fpm/pool.d/$firstchar/$onion[0].conf")){
unlink("/etc/php/$v/fpm/pool.d/$firstchar/$onion[0].conf");
} }
if(file_exists("/etc/php/7.1/fpm/pool.d/$firstchar/$onion[0].conf")){ // old naming schema
unlink("/etc/php/7.1/fpm/pool.d/$firstchar/$onion[0].conf"); if(file_exists("/etc/php/$v/fpm/pool.d/$firstchar/".substr($onion[0], 0, 16).".conf")){
unlink("/etc/php/$v/fpm/pool.d/$firstchar/".substr($onion[0], 0, 16).".conf");
} }
if(file_exists("/etc/php/7.2/fpm/pool.d/$firstchar/$onion[0].conf")){
unlink("/etc/php/7.2/fpm/pool.d/$firstchar/$onion[0].conf");
} }
unlink("/etc/nginx/sites-enabled/$onion[0].onion"); unlink("/etc/nginx/sites-enabled/$onion[0]");
//clean torrc from user $stmt->execute([$onion[1]]);
$torrc=file_get_contents("/etc/tor/instances/$firstchar/torrc"); while($tmp=$stmt->fetch(PDO::FETCH_NUM)){
$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 //delete hidden service from tor
if(file_exists("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/")){ if(file_exists("/var/lib/tor-instances/$firstchar/hidden_service_$tmp[0].onion/")){
unlink("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/hostname"); unlink("/var/lib/tor-instances/$firstchar/hidden_service_$tmp[0].onion/hostname");
unlink("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/private_key"); unlink("/var/lib/tor-instances/$firstchar/hidden_service_$tmp[0].onion/private_key");
rmdir("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/"); rmdir("/var/lib/tor-instances/$firstchar/hidden_service_$tmp[0].onion/");
} }
}
$del_onions->execute([$onion[1]]);
} }
//reload services //reload services
@ -160,18 +160,29 @@ foreach($reload as $key => $val){
exec("service php7.0-fpm@$key restart"); exec("service php7.0-fpm@$key restart");
exec("service php7.1-fpm@$key restart"); exec("service php7.1-fpm@$key restart");
exec("service php7.2-fpm@$key restart"); exec("service php7.2-fpm@$key restart");
exec("service tor@$key reload"); rewrite_torrc($db, $key);
} }
//continue deleting old accounts //continue deleting old accounts
$stmt=$db->prepare('SELECT mysql_database FROM mysql_databases WHERE user_id=?;'); $stmt=$db->prepare('SELECT mysql_database FROM mysql_databases WHERE user_id=?;');
foreach($onions as $onion){ foreach($onions as $onion){
//kill processes of the user to allow deleting system users //kill processes of the user to allow deleting system users
exec("skill -u $onion[0].onion"); exec('skill -u ' . escapeshellarg($onion[0]));
//delete user and group //delete user and group
exec("userdel -rf $onion[0].onion"); exec('userdel -rf ' . escapeshellarg($onion[0]));
//delete all log files //delete all log files
exec("rm -f /var/log/nginx/*$onion[0].onion.log*"); if(file_exists("/var/log/nginx/access_$onion[0].log")){
unlink("/var/log/nginx/access_$onion[0].log");
}
if(file_exists("/var/log/nginx/access_$onion[0].log.1")){
unlink("/var/log/nginx/access_$onion[0].log.1");
}
if(file_exists("/var/log/nginx/error_$onion[0].log")){
unlink("/var/log/nginx/error_$onion[0].log");
}
if(file_exists("/var/log/nginx/error_$onion[0].log.1")){
unlink("/var/log/nginx/error_$onion[0].log.1");
}
//delete user from database //delete user from database
$db->exec("DROP USER '$onion[2]'@'%';"); $db->exec("DROP USER '$onion[2]'@'%';");
$stmt->execute([$onion[1]]); $stmt->execute([$onion[1]]);
@ -180,13 +191,13 @@ foreach($onions as $onion){
} }
$db->exec('FLUSH PRIVILEGES;'); $db->exec('FLUSH PRIVILEGES;');
//delete user from user database //delete user from user database
$del->execute([$onion[0]]); $del->execute([$onion[1]]);
} }
// update passwords // update passwords
$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;"); $stmt=$db->query("SELECT users.system_account, 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=?;"); $del=$db->prepare("DELETE FROM pass_change WHERE user_id=?;");
while($onion=$stmt->fetch(PDO::FETCH_NUM)){ while($onion=$stmt->fetch(PDO::FETCH_NUM)){
exec('usermod -p '. escapeshellarg($onion[1]) . " $onion[0].onion"); exec('usermod -p '. escapeshellarg($onion[1]) . ' ' . escapeshellarg($onion[0]));
$del->execute([$onion[2]]); $del->execute([$onion[2]]);
} }

View File

@ -7,30 +7,28 @@ try{
} }
//delete tmp files older than 24 hours //delete tmp files older than 24 hours
exec('find /home -path "/home/*.onion/tmp/*" -cmin +1440 -delete'); exec('find /home -path "/home/*/tmp/*" -cmin +1440 -delete');
//delete unused accounts older than 30 days //delete unused accounts older than 30 days
$del=$db->prepare('UPDATE users SET todelete=1 WHERE onion=?;'); $del=$db->prepare('UPDATE users SET todelete=1 WHERE id=?;');
$stmt=$db->prepare('SELECT onion FROM users WHERE dateadded<?;'); $stmt=$db->prepare('SELECT system_account, id FROM users WHERE dateadded<?;');
$stmt->execute([time()-60*60*24*30]); $stmt->execute([time()-60*60*24*30]);
$all=$stmt->fetchAll(PDO::FETCH_NUM); $all=$stmt->fetchAll(PDO::FETCH_NUM);
foreach($all as $tmp){ foreach($all as $tmp){
$tmp=$tmp[0].'.onion'; if(filemtime("/home/$tmp[0]")>time()-60*60*24*30){
if(filemtime("/home/$tmp")>time()-60*60*24*30){
continue; continue;
} }
$count_www=count(scandir("/home/$tmp/www/")); $count_www=count(scandir("/home/$tmp[0]/www/"));
//check data empty and www no more than 1 file //check data empty and www no more than 1 file
if($count_www>3 || count(scandir("/home/$tmp/data/"))>2){ if($count_www>3 || count(scandir("/home/$tmp[0]/data/"))>2){
continue; continue;
} }
//check www empty or index unmodified //check www empty or index unmodified
if($count_www===3){ if($count_www===3){
if(!file_exists("/home/$tmp/www/index.hosting.html") || !in_array(md5_file("/home/$tmp/www/index.hosting.html"), INDEX_MD5S)){ if(!file_exists("/home/$tmp[0]/www/index.hosting.html") || !in_array(md5_file("/home/$tmp[0]/www/index.hosting.html"), INDEX_MD5S)){
continue; continue;
} }
} }
//no data found, safe to delete //no data found, safe to delete
// $del->execute([substr($tmp, 0, 16)]); $del->execute([substr($tmp[1], 0, 16)]);
var_dump($tmp);
} }

View File

@ -52,7 +52,7 @@ if(empty($_SESSION['logged_in'])){
}elseif($_REQUEST['action']==='list'){ }elseif($_REQUEST['action']==='list'){
echo '<table border="1">'; echo '<table border="1">';
echo '<tr><td>Onion link</td></tr>'; echo '<tr><td>Onion link</td></tr>';
$stmt=$db->query('SELECT onion FROM users WHERE public=0 ORDER BY onion;'); $stmt=$db->query('SELECT onions.onion FROM users INNER JOIN onions ON (onions.user_id=users.id) WHERE users.public=0 ORDER BY onions.onion;');
while($tmp=$stmt->fetch(PDO::FETCH_NUM)){ while($tmp=$stmt->fetch(PDO::FETCH_NUM)){
echo "<tr><td><a href=\"http://$tmp[0].onion\" target=\"_blank\">$tmp[0].onion</a></td></tr>"; echo "<tr><td><a href=\"http://$tmp[0].onion\" target=\"_blank\">$tmp[0].onion</a></td></tr>";
} }
@ -65,7 +65,7 @@ if(empty($_SESSION['logged_in'])){
} }
echo '<table border="1">'; echo '<table border="1">';
echo '<tr><td>Username</td><td>Onion address</td><td>Action</td></tr>'; echo '<tr><td>Username</td><td>Onion address</td><td>Action</td></tr>';
$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;'); $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;');
while($tmp=$stmt->fetch(PDO::FETCH_NUM)){ while($tmp=$stmt->fetch(PDO::FETCH_NUM)){
echo "<form action=\"$_SERVER[SCRIPT_NAME]\" method=\"POST\"><input type=\"hidden\" name=\"onion\" value=\"$tmp[1]\"><tr><td>$tmp[0]</td><td>$tmp[1].onion</td><td><input type=\"submit\" name=\"action\" value=\"approve\"><input type=\"submit\" name=\"action\" value=\"delete\"></td></tr></form>"; echo "<form action=\"$_SERVER[SCRIPT_NAME]\" method=\"POST\"><input type=\"hidden\" name=\"onion\" value=\"$tmp[1]\"><tr><td>$tmp[0]</td><td>$tmp[1].onion</td><td><input type=\"submit\" name=\"action\" value=\"approve\"><input type=\"submit\" name=\"action\" value=\"delete\"></td></tr></form>";
} }
@ -81,11 +81,11 @@ if(empty($_SESSION['logged_in'])){
echo '<input type="submit" name="action" value="delete"></form><br>'; echo '<input type="submit" name="action" value="delete"></form><br>';
if(!empty($_POST['onion'])){ if(!empty($_POST['onion'])){
if(preg_match('~^([a-z2-7]{16})(\.onion)?$~', $_POST['onion'], $match)){ if(preg_match('~^([a-z2-7]{16})(\.onion)?$~', $_POST['onion'], $match)){
$stmt=$db->prepare('SELECT null FROM users WHERE onion=?;'); $stmt=$db->prepare('SELECT user_id FROM onions WHERE onion=?;');
$stmt->execute([$match[1]]);
if($stmt->fetch(PDO::FETCH_NUM)){
$stmt=$db->prepare('UPDATE users SET todelete=1 WHERE onion=?;');
$stmt->execute([$match[1]]); $stmt->execute([$match[1]]);
if($user_id=$stmt->fetch(PDO::FETCH_NUM)){
$stmt=$db->prepare('UPDATE users SET todelete=1 WHERE id=?;');
$stmt->execute($user_id);
echo "<p style=\"color:green;\">Successfully queued for deletion!</p>"; echo "<p style=\"color:green;\">Successfully queued for deletion!</p>";
}else{ }else{
echo "<p style=\"color:red;\">Onion address not hosted by us!</p>"; echo "<p style=\"color:red;\">Onion address not hosted by us!</p>";

View File

@ -12,8 +12,8 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
if(!isset($_POST['pass']) || !password_verify($_POST['pass'], $user['password'])){ if(!isset($_POST['pass']) || !password_verify($_POST['pass'], $user['password'])){
$msg.='<p style="color:red;">Wrong password.</p>'; $msg.='<p style="color:red;">Wrong password.</p>';
}else{ }else{
$stmt=$db->prepare('UPDATE users SET todelete=1 WHERE onion=?;'); $stmt=$db->prepare('UPDATE users SET todelete=1 WHERE id=?;');
$stmt->execute([$user['onion']]); $stmt->execute([$user['id']]);
session_destroy(); session_destroy();
header('Location: login.php'); header('Location: login.php');
exit; exit;

View File

@ -15,7 +15,7 @@ if(empty($_SESSION['ftp_pass'])){
exit; exit;
} }
$ftp=ftp_connect('127.0.0.1') or die ('No Connection to FTP server!'); $ftp=ftp_connect('127.0.0.1') or die ('No Connection to FTP server!');
if(@!ftp_login($ftp, "$user[onion].onion", $_SESSION['ftp_pass'])){ if(@!ftp_login($ftp, $user[system_account], $_SESSION['ftp_pass'])){
send_login(); send_login();
exit; exit;
} }

View File

@ -15,22 +15,34 @@ echo '<meta name="author" content="Daniel Winzen">';
echo '<meta name="viewport" content="width=device-width, initial-scale=1">'; echo '<meta name="viewport" content="width=device-width, initial-scale=1">';
echo '</head><body>'; echo '</head><body>';
echo "<p>Logged in as $user[username] <a href=\"logout.php\">Logout</a> | <a href=\"password.php\">Change passwords</a> | <a target=\"_blank\" href=\"files.php\">FileManager</a> | <a href=\"delete.php\">Delete account</a></p>"; echo "<p>Logged in as $user[username] <a href=\"logout.php\">Logout</a> | <a href=\"password.php\">Change passwords</a> | <a target=\"_blank\" href=\"files.php\">FileManager</a> | <a href=\"delete.php\">Delete account</a></p>";
echo "<p>Enter system account password to check your $user[onion].onion@" . ADDRESS . " mail:</td><td><form action=\"squirrelmail/src/redirect.php\" method=\"post\" target=\"_blank\"><input type=\"hidden\" name=\"login_username\" value=\"$user[onion].onion\"><input type=\"password\" name=\"secretkey\"><input type=\"submit\" value=\"Login to webmail\"></form></p>"; echo "<p>Enter system account password to check your $user[system_account]@" . ADDRESS . " mail:</td><td><form action=\"squirrelmail/src/redirect.php\" method=\"post\" target=\"_blank\"><input type=\"hidden\" name=\"login_username\" value=\"$user[system_account]\"><input type=\"password\" name=\"secretkey\"><input type=\"submit\" value=\"Login to webmail\"></form></p>";
echo '<h3>Domain</h3>'; echo '<h3>Domains</h3>';
echo '<table border="1">'; echo '<table border="1">';
echo '<tr><th>Onion</th><th>Private key</th></tr>'; echo '<tr><th>Onion</th><th>Private key</th><th>Enabled</th><th>SMTP enabled</th><th>Nr. of intros</th></tr>';
echo "<tr><td><a href=\"http://$user[onion].onion\" target=\"_blank\">$user[onion].onion</a></td><td>"; $stmt=$db->prepare('SELECT onion, private_key, enabled, enable_smtp, num_intros FROM onions WHERE user_id=?;');
if(isset($_REQUEST['show_priv'])){ $stmt->execute([$user['id']]);
echo "<pre>$user[private_key]</pre>"; while($onion=$stmt->fetch(PDO::FETCH_ASSOC)){
}else{ echo "<tr><td><a href=\"http://$onion[onion].onion\" target=\"_blank\">$onion[onion].onion</a></td><td>";
if(isset($_REQUEST['show_priv'])){
echo "<pre>$onion[private_key]</pre>";
}else{
echo '<a href="home.php?show_priv=1">Show private key</a>'; echo '<a href="home.php?show_priv=1">Show private key</a>';
}
echo '</td><td>';
echo $onion['enabled'] ? 'Yes' : 'No';
echo '</td><td>';
echo $onion['enable_smtp'] ? 'Yes' : 'No';
echo "</td><td>$onion[num_intros]</td></tr>";
} }
echo '</td></tr>';
echo '</table>'; echo '</table>';
echo '<h3>MySQL Database</h3>'; echo '<h3>MySQL Database</h3>';
echo '<table border="1">'; echo '<table border="1">';
echo '<tr><th>Database</th><th>Host</th><th>User</th></tr>'; echo '<tr><th>Database</th><th>Host</th><th>User</th></tr>';
echo "<tr><td>$user[onion]</td><td>localhost</td><td>$user[onion].onion</td></tr>"; $stmt=$db->prepare('SELECT mysql_database FROM mysql_databases WHERE user_id=?;');
$stmt->execute([$user['id']]);
while($mysql=$stmt->fetch(PDO::FETCH_ASSOC)){
echo "<tr><td>$mysql[mysql_database]</td><td>localhost</td><td>$user[mysql_user]</td></tr>";
}
echo '</table>'; echo '</table>';
echo '<p><a href="password.php?type=sql">Change MySQL password</a></p>'; echo '<p><a href="password.php?type=sql">Change MySQL password</a></p>';
echo '<p>You can use <a href="/phpmyadmin/" target="_blank">PHPMyAdmin</a> and <a href="/adminer/" target="_blank">Adminer</a> for web based database administration.</p>'; echo '<p>You can use <a href="/phpmyadmin/" target="_blank">PHPMyAdmin</a> and <a href="/adminer/" target="_blank">Adminer</a> for web based database administration.</p>';
@ -38,7 +50,7 @@ echo '<h3>System Account</h3>';
echo '<table border="1">'; echo '<table border="1">';
echo '<tr><th>Username</th><th>Host</th><th>FTP Port</th><th>SFTP Port</th><th>POP3 Port</th><th>IMAP Port</th><th>SMTP port</th></tr>'; echo '<tr><th>Username</th><th>Host</th><th>FTP Port</th><th>SFTP Port</th><th>POP3 Port</th><th>IMAP Port</th><th>SMTP port</th></tr>';
foreach(SERVERS as $server=>$tmp){ foreach(SERVERS as $server=>$tmp){
echo "<tr><td>$user[onion].onion</td><td>$server</td><td>$tmp[ftp]</td><td>$tmp[sftp]</td><td>$tmp[pop3]</td><td>$tmp[imap]</td><td>$tmp[smtp]</td></tr>"; echo "<tr><td>$user[system_account]</td><td>$server</td><td>$tmp[ftp]</td><td>$tmp[sftp]</td><td>$tmp[pop3]</td><td>$tmp[imap]</td><td>$tmp[smtp]</td></tr>";
} }
echo '</table>'; echo '</table>';
echo '<p><a href="password.php?type=sys">Change system account password</a></p>'; echo '<p><a href="password.php?type=sys">Change system account password</a></p>';

View File

@ -31,7 +31,7 @@ if(isset($_SERVER['HTTP_HOST']) && preg_match('/danwin1210\.(i2p|me)$/', $_SERVE
<li>Web-based file management</li> <li>Web-based file management</li>
<li>FTP access</li> <li>FTP access</li>
<li>SFTP access</li> <li>SFTP access</li>
<li>No disk quota</li> <li>No disk quota, but please be fair about your disk usage</li>
<li>mail() can send e-mails from your.onion@<?php echo ADDRESS; ?> (your.onion@hosting.danwin1210.me for clearnet)</li> <li>mail() can send e-mails from your.onion@<?php echo ADDRESS; ?> (your.onion@hosting.danwin1210.me for clearnet)</li>
<li>Webmail and IMAP, POP3 and SMTP access to your mail account</li> <li>Webmail and IMAP, POP3 and SMTP access to your mail account</li>
<li>Mail sent to anything@your.onion gets automatically redirected to your inbox</li> <li>Mail sent to anything@your.onion gets automatically redirected to your inbox</li>
@ -53,5 +53,6 @@ if(isset($_SERVER['HTTP_HOST']) && preg_match('/danwin1210\.(i2p|me)$/', $_SERVE
<li>No proxy scripts! (You are already using TOR and this will just burden the network)</li> <li>No proxy scripts! (You are already using TOR and this will just burden the network)</li>
<li>No IP logger or similar de-anonymizer sites!</li> <li>No IP logger or similar de-anonymizer sites!</li>
<li>I preserve the right to delete any site for violating these rules and adding new rules at any time.</li> <li>I preserve the right to delete any site for violating these rules and adding new rules at any time.</li>
<li>Should you not honor these rules, I will (have to) work together with Law Enfocements!</li>
</ul> </ul>
</body></html> </body></html>

View File

@ -21,9 +21,9 @@ $hidden=$stmt->fetch(PDO::FETCH_NUM);
echo "<p>Here a list of $count[0] public hosted sites ($hidden[0] sites hidden):</p>"; echo "<p>Here a list of $count[0] public hosted sites ($hidden[0] sites hidden):</p>";
echo '<table border="1">'; echo '<table border="1">';
echo '<tr><td>Onion link</td></tr>'; echo '<tr><td>Onion link</td></tr>';
$stmt=$db->query('SELECT username, onion FROM users WHERE public=1 ORDER BY onion;'); $stmt=$db->query('SELECT onions.onion FROM users INNER JOIN onions ON (onions.user_id=users.id) WHERE users.public=1 ORDER BY onions.onion;');
while($tmp=$stmt->fetch(PDO::FETCH_NUM)){ while($tmp=$stmt->fetch(PDO::FETCH_NUM)){
echo "<tr><td><a href=\"http://$tmp[1].onion\" target=\"_blank\">$tmp[1].onion</a></td></tr>"; echo "<tr><td><a href=\"http://$tmp[0].onion\" target=\"_blank\">$tmp[0].onion</a></td></tr>";
} }
echo '</table>'; echo '</table>';
echo '</body></html>'; echo '</body></html>';

View File

@ -22,6 +22,6 @@ header("Content-disposition: filename=\"$type.log\"");
header('Pragma: no-cache'); header('Pragma: no-cache');
header('Cache-Control: no-cache, no-store, must-revalidate, max-age=0'); header('Cache-Control: no-cache, no-store, must-revalidate, max-age=0');
header('Expires: 0'); header('Expires: 0');
if(file_exists("/var/log/nginx/{$type}_$user[onion].onion.log$old")){ if(file_exists("/var/log/nginx/{$type}_$user[system_account].log$old")){
header("X-Accel-Redirect: /nginx/{$type}_$user[onion].onion.log$old"); header("X-Accel-Redirect: /nginx/{$type}_$user[system_account].log$old");
} }

View File

@ -22,18 +22,18 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
$msg.='<p style="color:red;">Error: username may not be empty.</p>'; $msg.='<p style="color:red;">Error: username may not be empty.</p>';
$ok=false; $ok=false;
}else{ }else{
$stmt=$db->prepare('SELECT username, password, onion FROM users WHERE username=?;'); $stmt=$db->prepare('SELECT username, password, id FROM users WHERE username=?;');
$stmt->execute([$_POST['username']]); $stmt->execute([$_POST['username']]);
$tmp=[]; $tmp=[];
if(($tmp=$stmt->fetch(PDO::FETCH_NUM))===false && preg_match('/^([2-7a-z]{16}).onion$/', $_POST['username'], $match)){ if(($tmp=$stmt->fetch(PDO::FETCH_NUM))===false && preg_match('/^([2-7a-z]{16}).onion$/', $_POST['username'], $match)){
$stmt=$db->prepare('SELECT username, password, onion FROM users WHERE onion=?;'); $stmt=$db->prepare('SELECT users.username, users.password, users.id FROM users INNER JOIN onions ON (onions.user_id=users.id) WHERE onions.onion=?;');
$stmt->execute([$match[1]]); $stmt->execute([$match[1]]);
$tmp=$stmt->fetch(PDO::FETCH_NUM); $tmp=$stmt->fetch(PDO::FETCH_NUM);
} }
if($tmp){ if($tmp){
$username=$tmp[0]; $username=$tmp[0];
$password=$tmp[1]; $password=$tmp[1];
$stmt=$db->prepare('SELECT new_account.approved FROM new_account INNER JOIN users ON (users.id=new_account.user_id) WHERE users.onion=?;'); $stmt=$db->prepare('SELECT new_account.approved FROM new_account INNER JOIN users ON (users.id=new_account.user_id) WHERE users.id=?;');
$stmt->execute([$tmp[2]]); $stmt->execute([$tmp[2]]);
if($tmp=$stmt->fetch(PDO::FETCH_NUM)){ if($tmp=$stmt->fetch(PDO::FETCH_NUM)){
if(REQUIRE_APPROVAL && !$tmp[0]){ if(REQUIRE_APPROVAL && !$tmp[0]){

View File

@ -19,8 +19,8 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
}else{ }else{
if($_REQUEST['type']==='acc'){ if($_REQUEST['type']==='acc'){
$hash=password_hash($_POST['newpass'], PASSWORD_DEFAULT); $hash=password_hash($_POST['newpass'], PASSWORD_DEFAULT);
$stmt=$db->prepare('UPDATE users SET password=? WHERE username=?;'); $stmt=$db->prepare('UPDATE users SET password=? WHERE id=?;');
$stmt->execute([$hash, $user['username']]); $stmt->execute([$hash, $user['id']]);
$msg.='<p style="color:green;">Successfully changed account password.</p>'; $msg.='<p style="color:green;">Successfully changed account password.</p>';
}elseif($_REQUEST['type']==='sys'){ }elseif($_REQUEST['type']==='sys'){
$stmt=$db->prepare('INSERT INTO pass_change (user_id, password) VALUES (?, ?);'); $stmt=$db->prepare('INSERT INTO pass_change (user_id, password) VALUES (?, ?);');
@ -28,7 +28,7 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
$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 affect within the next minute.</p>';
}elseif($_REQUEST['type']==='sql'){ }elseif($_REQUEST['type']==='sql'){
$stmt=$db->prepare("SET PASSWORD FOR '$user[onion].onion'@'%'=PASSWORD(?);"); $stmt=$db->prepare("SET PASSWORD FOR '$user[mysql_user]'@'%'=PASSWORD(?);");
$stmt->execute([$_POST['newpass']]); $stmt->execute([$_POST['newpass']]);
$db->exec('FLUSH PRIVILEGES;'); $db->exec('FLUSH PRIVILEGES;');
$msg.='<p style="color:green;">Successfully changed sql password.</p>'; $msg.='<p style="color:green;">Successfully changed sql password.</p>';

View File

@ -54,7 +54,7 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
} }
} }
if($ok){ if($ok){
$check=$db->prepare('SELECT null FROM users WHERE onion=?;'); $check=$db->prepare('SELECT null FROM onions WHERE onion=?;');
if(isset($_REQUEST['private_key']) && !empty(trim($_REQUEST['private_key']))){ if(isset($_REQUEST['private_key']) && !empty(trim($_REQUEST['private_key']))){
$priv_key=trim($_REQUEST['private_key']); $priv_key=trim($_REQUEST['private_key']);
if(($pkey=openssl_pkey_get_private($priv_key))!==false){ if(($pkey=openssl_pkey_get_private($priv_key))!==false){
@ -102,13 +102,15 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
echo '<p style="color:red;">To prevent abuse a site can only be registered every 60 seconds, but one has already been registered within the last 60 seconds. Please try again.</p>'; echo '<p style="color:red;">To prevent abuse a site can only be registered every 60 seconds, but one has already been registered within the last 60 seconds. Please try again.</p>';
$ok=false; $ok=false;
}elseif($ok){ }elseif($ok){
$stmt=$db->prepare('INSERT INTO users (username, password, onion, private_key, dateadded, public, php, autoindex, mysql_user) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);'); $stmt=$db->prepare('INSERT INTO users (username, system_account, password, dateadded, public, php, autoindex, mysql_user) VALUES (?, ?, ?, ?, ?, ?, ?, ?);');
$stmt->execute([$_POST['username'], $hash, $onion, $priv_key, time(), $public, $php, $autoindex, "$onion.onion"]); $stmt->execute([$_POST['username'], "$onion.onion", $hash, time(), $public, $php, $autoindex, "$onion.onion"]);
$stmt=$db->prepare('SELECT id FROM users WHERE username=?;'); $stmt=$db->prepare('SELECT id FROM users WHERE username=?;');
$stmt->execute([$_POST['username']]); $stmt->execute([$_POST['username']]);
$user_id=$stmt->fetch(PDO::FETCH_NUM)[0]; $user_id=$stmt->fetch(PDO::FETCH_NUM)[0];
$stmt=$db->prepare('INSERT INTO mysql_databases (user_id, mysql_database) VALUES (?, ?);'); $stmt=$db->prepare('INSERT INTO mysql_databases (user_id, mysql_database) VALUES (?, ?);');
$stmt->execute([$user_id, $onion]); $stmt->execute([$user_id, $onion]);
$stmt=$db->prepare('INSERT INTO onions (user_id, onion, private_key, version) VALUES (?, ?, ?, ?);');
$stmt->execute([$user_id, $onion, $priv_key, 2]);
$create_user=$db->prepare("CREATE USER '$onion.onion'@'%' IDENTIFIED BY ?;"); $create_user=$db->prepare("CREATE USER '$onion.onion'@'%' IDENTIFIED BY ?;");
$create_user->execute([$_POST['pass']]); $create_user->execute([$_POST['pass']]);
$db->exec("CREATE DATABASE IF NOT EXISTS `$onion`;"); $db->exec("CREATE DATABASE IF NOT EXISTS `$onion`;");

View File

@ -22,11 +22,12 @@ $version;
if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';")){ if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';")){
//create tables //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 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, 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, mysql_user varchar(32) NOT NULL, KEY public (public), KEY dateadded (dateadded), KEY todelete (todelete)) 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, 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 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 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 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 KEY, mysql_database varchar(64) COLLATE latin1_bin NOT NULL, 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 mysql_databases (user_id int(11) NOT NULL, mysql_database varchar(64) COLLATE latin1_bin NOT NULL, KEY 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 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;'); $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;');
$db->exec("CREATE TABLE onions (user_id int(11) NOT 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', KEY user_id (user_id), KEY enabled (enabled), CONSTRAINT onions_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;");
$stmt=$db->prepare("INSERT INTO settings (setting, value) VALUES ('version', ?);"); $stmt=$db->prepare("INSERT INTO settings (setting, value) VALUES ('version', ?);");
$stmt->execute([DBVERSION]); $stmt->execute([DBVERSION]);
echo "Database has successfully been set up\n"; echo "Database has successfully been set up\n";
@ -37,20 +38,6 @@ if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';"))
$db->exec('ALTER TABLE new_account ADD approved tinyint(1) UNSIGNED NOT NULL;'); $db->exec('ALTER TABLE new_account ADD approved tinyint(1) UNSIGNED NOT NULL;');
$db->exec('DROP TABLE del_account;'); $db->exec('DROP TABLE del_account;');
} }
if($version<3){
$stmt=$db->query("SELECT onion FROM users;");
while($id=$stmt->fetch(PDO::FETCH_NUM)){
$onion=$id[0];
$firstchar=substr($onion, 0, 1);
$replace=str_replace("listen unix:/var/run/nginx.sock;", "listen unix:/var/run/nginx/$onion backlog=2048;", file_get_contents("/etc/nginx/sites-enabled/$onion.onion"));
file_put_contents("/etc/nginx/sites-enabled/$onion.onion", $replace);
$torrc=file_get_contents("/etc/tor/instances/$firstchar/torrc");
$torrc=str_replace("$onion.onion/\nHiddenServicePort 80 unix:/var/run/nginx.sock", "$onion.onion/\nHiddenServicePort 80 unix:/var/run/nginx/$onion", $torrc);
file_put_contents("/etc/tor/instances/$firstchar/torrc", $torrc);
}
exec('service nginx reload');
exec("service tor reload");
}
if($version<4){ if($version<4){
$db->exec('ALTER TABLE new_account DROP FOREIGN KEY new_account_ibfk_1;'); $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 pass_change DROP FOREIGN KEY pass_change_ibfk_1;');
@ -72,6 +59,25 @@ if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';"))
$db->exec('CREATE TABLE mysql_databases (user_id int(11) NOT NULL KEY, mysql_database varchar(64) COLLATE latin1_bin NOT NULL, 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 mysql_databases (user_id int(11) NOT NULL KEY, mysql_database varchar(64) COLLATE latin1_bin NOT NULL, 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("INSERT INTO mysql_databases (user_id, mysql_database) SELECT id, onion FROM users;"); $db->exec("INSERT INTO mysql_databases (user_id, mysql_database) SELECT id, onion FROM users;");
} }
if($version<6){
$db->exec('ALTER TABLE mysql_databases DROP PRIMARY KEY, ADD INDEX user_id (user_id);');
$db->exec("CREATE TABLE onions (user_id int(11) NOT 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', KEY user_id (user_id), KEY enabled (enabled), CONSTRAINT onions_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 onions (user_id, onion, private_key, version) SELECT id, onion, private_key, 2 FROM users;");
$db->exec('ALTER TABLE users DROP private_key;');
$db->exec('ALTER TABLE users CHANGE onion system_account varchar(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL;');
$db->exec("UPDATE users SET system_account = CONCAT(system_account, '.onion');");
$stmt=$db->query("SELECT system_account FROM users;");
while($id=$stmt->fetch(PDO::FETCH_NUM)){
$system_account=$id[0];
$onion=substr($id[0], 0, 16);
$replace=preg_replace("~listen\sunix:/var/run/nginx(/[a-z2-7]{16}|\.sock)(\sbacklog=2048)?;~", "listen unix:/var/run/nginx/$system_account backlog=2048;", file_get_contents("/etc/nginx/sites-enabled/$system_account"));
file_put_contents("/etc/nginx/sites-enabled/$system_account", $replace);
}
foreach(['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'] as $key){
rewrite_torrc($db, $key);
}
exec('service nginx reload');
}
$stmt=$db->prepare("UPDATE settings SET value=? WHERE setting='version';"); $stmt=$db->prepare("UPDATE settings SET value=? WHERE setting='version';");
$stmt->execute([DBVERSION]); $stmt->execute([DBVERSION]);
if(DBVERSION!=$version){ if(DBVERSION!=$version){