diff --git a/var/www/common.php b/var/www/common.php index cd4af4f..a32f4a8 100644 --- a/var/www/common.php +++ b/var/www/common.php @@ -16,6 +16,8 @@ const INDEX_MD5S=[ //MD5 sums of index.hosting.html files that should be considd 'd41d8cd98f00b204e9800998ecf8427e', //empty file '7ae7e9bac6be76f00e0d95347111f037' //default file ]; +const REQUIRE_APPROVAL=false; //require admin approval of new sites? true/false +const ADMIN_PASSWORD='MY_PASSWORD'; //password for admin interface function get_onion($pkey){ $keyData = openssl_pkey_get_details($pkey); @@ -51,7 +53,7 @@ function base32_encode($input) { function send_captcha(){ global $db; - if(CAPTCHA===0 || !extension_loaded('gd')){ + if(!CAPTCHA || !extension_loaded('gd')){ return; } $captchachars='ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789'; @@ -172,3 +174,29 @@ function get_system_hash($pass){ } return crypt($pass, '$6$'.$salt.'$'); } + +function check_captcha_error(){ + global $db; + if(CAPTCHA){ + if(!isset($_REQUEST['challenge'])){ + return 'Error: Wrong Captcha'; + }else{ + $stmt=$db->prepare('SELECT code FROM captcha WHERE id=?;'); + $stmt->execute([$_REQUEST['challenge']]); + $stmt->bindColumn(1, $code); + if(!$stmt->fetch(PDO::FETCH_BOUND)){ + return 'Error: Captcha expired'; + }else{ + $time=time(); + $stmt=$db->prepare('DELETE FROM captcha WHERE id=? OR timeexecute([$_REQUEST['challenge'], $time-3600]); + if($_REQUEST['captcha']!==$code){ + if(strrev($_REQUEST['captcha'])!==$code){ + return 'Error: Wrong captcha'; + } + } + } + } + } + return false; +} diff --git a/var/www/cron.php b/var/www/cron.php index af4b561..f5a87b6 100644 --- a/var/www/cron.php +++ b/var/www/cron.php @@ -10,7 +10,8 @@ $reload=[]; //add new accounts $del=$db->prepare("DELETE FROM new_account WHERE onion=?;"); $update_priv=$db->prepare("UPDATE users SET private_key=? WHERE onion=?;"); -$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) LIMIT 100;"); +$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;"); while($id=$stmt->fetch(PDO::FETCH_NUM)){ $onion=$id[0]; $firstchar=substr($onion, 0, 1); @@ -113,7 +114,7 @@ php_admin_value[session.save_path] = /home/$onion.onion/tmp //delete old accounts $del=$db->prepare("DELETE FROM users WHERE onion=?"); -$stmt=$db->query("SELECT onion FROM del_account LIMIT 100;"); +$stmt=$db->query("SELECT onion FROM users WHERE todelete=1 LIMIT 100;"); $onions=$stmt->fetchAll(PDO::FETCH_NUM); foreach($onions as $onion){ $firstchar=substr($onion[0], 0, 1); @@ -134,9 +135,11 @@ foreach($onions as $onion){ $torrc=str_replace("HiddenServiceDir /var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/\nHiddenServicePort 80 unix:/var/run/nginx.sock\nHiddenServicePort 25 127.0.0.1:25\n", '', $torrc); file_put_contents("/etc/tor/instances/$firstchar/torrc", $torrc); //delete hidden service from tor - unlink("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/hostname"); - unlink("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/private_key"); - rmdir("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/"); + if(file_exists("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/")){ + unlink("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/hostname"); + unlink("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/private_key"); + rmdir("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/"); + } } //reload services diff --git a/var/www/find_old.php b/var/www/find_old.php index 97764bc..7b3c738 100644 --- a/var/www/find_old.php +++ b/var/www/find_old.php @@ -11,7 +11,7 @@ exec('find /home -path "/home/*.onion/tmp/*" -cmin +1440 -delete'); //delete unused accounts older than 30 days $all=scandir('/home'); -$stmt=$db->prepare('INSERT INTO del_account (onion) VALUES (?);'); +$stmt=$db->prepare('UPDATE users SET todelete=1 WHERE onion=?;'); foreach($all as $tmp){ if(!preg_match('~^[a-z2-7]{16}\.onion$~', $tmp)){ continue; diff --git a/var/www/html/admin.php b/var/www/html/admin.php new file mode 100644 index 0000000..c4b15c9 --- /dev/null +++ b/var/www/html/admin.php @@ -0,0 +1,99 @@ +PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>PERSISTENT]); +}catch(PDOException $e){ + die('No Connection to MySQL database!'); +} +header('Content-Type: text/html; charset=UTF-8'); +session_start(['name'=>'hosting_admin']); +if($_SERVER['REQUEST_METHOD']==='HEAD'){ + exit; // headers sent, no further processing needed +} +echo ''; +echo 'Daniel\'s Hosting - Login'; +echo ''; +echo ''; +echo ''; +echo ''; +echo '

Hosting - Admin panel

'; +$error=false; +if($_SERVER['REQUEST_METHOD']==='POST' && isSet($_POST['pass']) && $_POST['pass']===ADMIN_PASSWORD){ + if(!($error=check_captcha_error())){ + $_SESSION['logged_in']=true; + } +} +if(empty($_SESSION['logged_in'])){ + echo "
"; + echo ""; + send_captcha(); + echo ""; + echo '
Password
'; + if($error){ + echo "

$error

"; + }elseif(isSet($_POST['pass'])){ + echo "

Wrong password!

"; + } + echo '

If you disabled cookies, please re-enable them. You can\'t log in without!

'; +}else{ + echo '

'; + if(REQUIRE_APPROVAL){ + $db->query('SELECT COUNT(*) FROM new_account WHERE approved=0;'); + $cnt=$db->fetch(PDO::FETCH_NUM)[0]; + echo "Approve pending sites ($cnt) | "; + } + echo "List of hidden hosted sites | Delete accounts | Logout

"; + if(empty($_REQUEST['action'])){ + echo '

Welcome to the admin panel!

'; + }elseif($_REQUEST['action']==='logout'){ + session_destroy(); + header("Location: $_SERVER[SCRIPT_NAME]"); + exit; + }elseif($_REQUEST['action']==='list'){ + echo ''; + echo ''; + $stmt=$db->query('SELECT onion FROM users WHERE public=0 ORDER BY onion;'); + while($tmp=$stmt->fetch(PDO::FETCH_NUM)){ + echo ""; + } + echo '
Onion link
$tmp[0].onion
'; + }elseif($_REQUEST['action']==='approve'){ + if(!empty($_POST['onion'])){ + $stmt=$db->prepare('UPDATE new_account SET approved=1 WHERE onion=?;'); + $stmt->execute([$_POST['onion']]); + echo '

Successfully approved

'; + } + echo ''; + echo ''; + $stmt=$db->query('SELECT username, onion FROM users INNER JOIN new_account ON (user.onion=new_account.onion) WHERE new_account.approved=0 ORDER BY users.username;'); + while($tmp=$stmt->fetch(PDO::FETCH_NUM)){ + echo ""; + } + echo '
UsernameOnion addressAction
$tmp[0]$tmp[1].onion
'; + }elseif($_REQUEST['action']==='delete'){ + echo '

Delete accouts:

'; + echo "
"; + echo '

Onion address:

'; + echo '

'; + if(!empty($_POST['onion'])){ + if(preg_match('~^([a-z2-7]{16})(\.onion)?$~', $_POST['onion'], $match)){ + $stmt=$db->prepare('SELECT null FROM users 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]]); + echo "

Successfully queued for deletion!

"; + }else{ + echo "

Onion address not hosted by us!

"; + } + }else{ + echo "

Invalid onion address!

"; + } + } + } +} +echo ''; diff --git a/var/www/html/delete.php b/var/www/html/delete.php index bb5227d..8ceecee 100644 --- a/var/www/html/delete.php +++ b/var/www/html/delete.php @@ -12,7 +12,7 @@ if($_SERVER['REQUEST_METHOD']==='POST'){ if(!isset($_POST['pass']) || !password_verify($_POST['pass'], $user['password'])){ $msg.='

Wrong password.

'; }else{ - $stmt=$db->prepare('INSERT INTO del_account (onion) VALUES (?);'); + $stmt=$db->prepare('UPDATE users SET todelete=1 WHERE onion=?;'); $stmt->execute([$user['onion']]); session_destroy(); header('Location: login.php'); diff --git a/var/www/html/faq.php b/var/www/html/faq.php index da81172..4aa4f1e 100644 --- a/var/www/html/faq.php +++ b/var/www/html/faq.php @@ -1,22 +1,33 @@ Daniel's Hosting - FAQ - + + +

Hosting - Info

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

- - + + - - - - + + + +
QuestionAnswer
Your rules are so strict. Can't you make an exception for my site?No, I will not make exceptions for any site and neither am I curruptibly by offering me money. Once I start making an exception for your site, I would have to for every other site as well which is the same as if the rules didn't exist.
I have an .htaccess file, but it doesn't work. How can I fix it?.htaccess files are meant for Apache2 webservers. My server is based on NginX, which is much faster due to using static configuration files and not reading files like .htaccess at runtime. You can contact me and tell me your sites address where the .htaccess file is. I will then check your .htaccess and convert the rules to NginX rules and apply those.
I just uploaded my page, but it's broken. HELPMost likely your site makes use of rewriting rules, which are typically located in an .htaccess file or are mentioned in a readme file. Just contact me in this case. Also see previous question.
I have an .htaccess file, but it doesn't work. How can I fix it?.htaccess files are meant for Apache2 webservers. My server is based on NginX, which is much faster due to using static configuration files and not reading files like .htaccess at runtime. You can ">contact me and tell me your sites address where the .htaccess file is. I will then check your .htaccess and convert the rules to NginX rules and apply those.
I just uploaded my page, but it's broken. HELPMost likely your site makes use of rewriting rules, which are typically located in an .htaccess file or are mentioned in a readme file. Just ">contact me in this case. Also see previous question.
Can I host a porn site?Yes as long as your content is legal you may upload adult content.
What is the directory structure for when I connect via (s)ftp?There are several directories you on the server for your account:
Maildir - used to store your mails in (don't touch it)
data - You can store application data here that should not be accessible via your site. E.g. configuration or database files.
tmp - anything saved here will automatically be deleted after about 24 hours
www - this is where you upload your website which becomes then available under your domain.
My application is very ressource intensive or I want to host a different service e.g. my own tor relay. Can you get me a VPS?Yes, if you have special requirements, want a dedicated VPS for your application or just want to anonymously support the TOR network (or other networks) without having to deal with server setup etc. I can offer you a managed VPS hosting. However this will not be for free. It depends on which server you want me to get. For details, contact me
I want to also publish my site on clearnet. Can you offer a clearnet relay?Yes, I can offer you a subdomain on my server, e.g. yoursite.danwin1210.me or if you have your own domain use that. Just contact me for setting up a clearnet gateway for your site.
Can you make my website also available via I2P?Sure I can. Just contact me to set it up for you.
What is the directory structure for when I connect via (s)ftp?There are several directories you on the server for your account:
Maildir - used to store your mails in (don't touch it)
data - You can store application data here that should not be accessible via your site. E.g. configuration or database files.
tmp - anything saved here will automatically be deleted after about 24 hours
www - this is where you upload your website which becomes then available under your domain.
logs - you will find webserver logs here
.ssh - by uploading your ssh public key as authorzed_keys in this folder, you can authenticate to sftp using your ssh key, without a password
My application is very ressource intensive or I want to host a different service e.g. my own tor relay. Can you get me a VPS?Yes, if you have special requirements, want a dedicated VPS for your application or just want to anonymously support the TOR network (or other networks) without having to deal with server setup etc. I can offer you a managed VPS hosting. However this will not be for free. It depends on which server you want me to get. For details, ">contact me
I want to also publish my site on clearnet. Can you offer a clearnet relay?Yes, I can offer you a subdomain on my server, e.g. yoursite.danwin1210.me or if you have your own domain use that. Just ">contact me for setting up a clearnet gateway for your site.
Can you make my website also available via I2P?Sure I can. Just ">contact me to set it up for you.
diff --git a/var/www/html/files.php b/var/www/html/files.php index 4957eec..72b480c 100644 --- a/var/www/html/files.php +++ b/var/www/html/files.php @@ -173,10 +173,16 @@ if(!empty($_POST['unzip']) && !empty($_POST['files'])){ continue; } $tmpfile='/tmp/'.uniqid().'.zip'; - ftp_get($ftp, $tmpfile, $file, FTP_BINARY); + if(!ftp_get($ftp, $tmpfile, $file, FTP_BINARY)){ + continue; + } //prevent zip-bombs $size=0; $resource=zip_open($tmpfile); + if(!is_resource($resource)){ + unlink($tmpfile); + continue; + } while($dir_resource=zip_read($resource)) { $size+=zip_entry_filesize($dir_resource); } @@ -198,8 +204,10 @@ if(!empty($_POST['unzip']) && !empty($_POST['files'])){ if(!empty($_FILES['files'])){ $c=count($_FILES['files']['name']); for($i=0; $i<$c; ++$i){ - ftp_put($ftp, $dir.$_FILES['files']['name'][$i], $_FILES['files']['tmp_name'][$i], FTP_BINARY); - unlink($_FILES['files']['tmp_name'][$i]); + if($_FILES['files']['error'][$i]===UPLOAD_ERR_OK){ + ftp_put($ftp, $dir.$_FILES['files']['name'][$i], $_FILES['files']['tmp_name'][$i], FTP_BINARY); + unlink($_FILES['files']['tmp_name'][$i]); + } } } diff --git a/var/www/html/home.php b/var/www/html/home.php index fae26fd..aa336fc 100644 --- a/var/www/html/home.php +++ b/var/www/html/home.php @@ -11,15 +11,11 @@ header('Content-Type: text/html; charset=UTF-8'); echo ''; echo 'Daniel\'s Hosting - Dashboard'; echo ''; -echo ''; +echo ''; +echo ''; echo ''; -echo "

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

"; -$mail=0; -if(file_exists("/home/$user[onion].onion/Maildir/new/")){ - $mail=count(scandir("/home/$user[onion].onion/Maildir/new/"))-2; -} -echo "

Enter system account password to check your $user[onion].onion@" . ADDRESS . " mail ($mail new):

"; +echo "

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

"; +echo "

Enter system account password to check your $user[onion].onion@" . ADDRESS . " mail:

"; echo '

Domain

'; echo ''; echo ''; diff --git a/var/www/html/index.php b/var/www/html/index.php index 94e4354..9dd2d0b 100644 --- a/var/www/html/index.php +++ b/var/www/html/index.php @@ -17,6 +17,7 @@ if(isset($_SERVER['HTTP_HOST']) && preg_match('/danwin1210\.(i2p|me)$/', $_SERVE +

Hosting - Info

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

Here you can get yourself a hosting account on my server.

What you will get:

@@ -46,9 +47,8 @@ if(isset($_SERVER['HTTP_HOST']) && preg_match('/danwin1210\.(i2p|me)$/', $_SERVE
  • No terroristic propaganda!
  • No illegal content according to German law!
  • No malware! (e.g. botnets)
  • -
  • No phishing!
  • -
  • No scams!
  • -
  • No spam!
  • +
  • No phishing, scams or spam!
  • +
  • No mining without explicit user permission! (e.g. using coinhive)
  • No shops, markets or any other sites dedicated to making money! (This is a FREE hosting!)
  • No proxy scripts! (You are already using TOR and this will just burden the network)
  • No IP logger or similar de-anonymizer sites!
  • diff --git a/var/www/html/list.php b/var/www/html/list.php index d9e3ab7..0f39c38 100644 --- a/var/www/html/list.php +++ b/var/www/html/list.php @@ -9,8 +9,10 @@ try{ echo ''; 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

    '; $stmt=$db->query('SELECT COUNT(*) FROM users WHERE public=1;'); $count=$stmt->fetch(PDO::FETCH_NUM); diff --git a/var/www/html/login.php b/var/www/html/login.php index 77be4e1..779037b 100644 --- a/var/www/html/login.php +++ b/var/www/html/login.php @@ -15,32 +15,11 @@ $msg=''; $username=''; if($_SERVER['REQUEST_METHOD']==='POST'){ $ok=true; - if(CAPTCHA){ - if(!isset($_REQUEST['challenge'])){ - $msg.='

    Error: Wrong Captcha

    '; - $ok=false; - }else{ - $stmt=$db->prepare('SELECT code FROM captcha WHERE id=?;'); - $stmt->execute([$_REQUEST['challenge']]); - $stmt->bindColumn(1, $code); - if(!$stmt->fetch(PDO::FETCH_BOUND)){ - $msg.='

    Error: Captcha expired

    '; - $ok=false; - }else{ - $time=time(); - $stmt=$db->prepare('DELETE FROM captcha WHERE id=? OR timeexecute([$_REQUEST['challenge'], $time-3600]); - if($_REQUEST['captcha']!==$code){ - if(strrev($_REQUEST['captcha'])!==$code){ - $msg.='

    Error: Wrong captcha

    '; - $ok=false; - } - } - } - } - } - if(!isset($_POST['username']) || $_POST['username']===''){ - $msg.='

    Error, username may not be empty.

    '; + if($error=check_captcha_error()){ + $msg.="

    $error

    "; + $ok=false; + }elseif(!isset($_POST['username']) || $_POST['username']===''){ + $msg.='

    Error: username may not be empty.

    '; $ok=false; }else{ $stmt=$db->prepare('SELECT username, password FROM users WHERE username=?;'); @@ -53,13 +32,13 @@ if($_SERVER['REQUEST_METHOD']==='POST'){ } if($tmp){ if(!isset($_POST['pass']) || !password_verify($_POST['pass'], $tmp[1])){ - $msg.='

    Error, wrong password.

    '; + $msg.='

    Error: wrong password.

    '; $ok=false; }else{ $username=$tmp[0]; } }else{ - $msg.='

    Error, username was not found. If you forgot it, you can enter youraccount.onion instead.

    '; + $msg.='

    Error: username was not found. If you forgot it, you can enter youraccount.onion instead.

    '; $ok=false; } } @@ -76,6 +55,7 @@ echo ''; echo ''; echo ''; echo ''; +echo '

    Hosting - Login

    '; echo '

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

    '; echo $msg; echo '
    OnionPrivate key
    '; @@ -85,10 +65,8 @@ if(isset($_POST['username'])){ } echo '" required autofocus>'; echo ''; -if(CAPTCHA){ - send_captcha(); -} +send_captcha(); echo ''; echo '
    Password
    '; -echo '

    If you disabled cookies, please re-enable them. You currently can\'t log in without

    '; +echo '

    If you disabled cookies, please re-enable them. You can\'t log in without!

    '; echo ''; diff --git a/var/www/html/register.php b/var/www/html/register.php index 62bd4a2..e381d99 100644 --- a/var/www/html/register.php +++ b/var/www/html/register.php @@ -17,6 +17,7 @@ echo ''; echo ''; echo ''; echo ''; +echo '

    Hosting - Register

    '; echo '

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

    '; if($_SERVER['REQUEST_METHOD']==='POST'){ $ok=true; @@ -26,85 +27,63 @@ if($_SERVER['REQUEST_METHOD']==='POST'){ $autoindex=0; $hash=''; $priv_key=''; - if(empty($_POST['pass'])){ - echo '

    Error, password empty.

    '; + if($error=check_captcha_error()){ + echo "

    $error

    "; + $ok=false; + }elseif(empty($_POST['pass'])){ + echo '

    Error: password empty.

    '; $ok=false; }elseif(empty($_POST['passconfirm']) || $_POST['pass']!==$_POST['passconfirm']){ - echo '

    Error, password confirmation does not match.

    '; + echo '

    Error: password confirmation does not match.

    '; $ok=false; - } - if(empty($_POST['username'])){ - echo '

    Error, username empty.

    '; + }elseif(empty($_POST['username'])){ + echo '

    Error: username empty.

    '; $ok=false; }elseif(preg_match('/[^a-z0-9\-_\.]/', $_POST['username'])){ - echo '

    Error, username may only contain characters that are in the rage of a-z (lower case) - . _ and 0-9.

    '; + echo '

    Error: username may only contain characters that are in the rage of a-z (lower case) - . _ and 0-9.

    '; $ok=false; }elseif(strlen($_POST['username'])>50){ - echo '

    Error, username may not be longer than 50 characters.

    '; + echo '

    Error: username may not be longer than 50 characters.

    '; $ok=false; }else{ $stmt=$db->prepare('SELECT null FROM users WHERE username=?;'); $stmt->execute([$_POST['username']]); if($stmt->fetch(PDO::FETCH_NUM)){ - echo '

    Error, this username is already registered.

    '; + echo '

    Error: this username is already registered.

    '; $ok=false; } } - if(CAPTCHA){ - if(!isset($_REQUEST['challenge'])){ - echo '

    Error: Wrong Captcha

    '; - $ok=false; - }else{ - $stmt=$db->prepare('SELECT code FROM captcha WHERE id=?;'); - $stmt->execute([$_REQUEST['challenge']]); - $stmt->bindColumn(1, $code); - if(!$stmt->fetch(PDO::FETCH_BOUND)){ - echo '

    Error: Captcha expired

    '; - $ok=false; - }else{ - $time=time(); - $stmt=$db->prepare('DELETE FROM captcha WHERE id=? OR timeexecute([$_REQUEST['challenge'], $time-3600]); - if($_REQUEST['captcha']!==$code){ - if(strrev($_REQUEST['captcha'])!==$code){ - echo '

    Error: Wrong captcha

    '; + if($ok){ + $check=$db->prepare('SELECT null FROM users WHERE onion=?;'); + if(isset($_REQUEST['private_key']) && !empty(trim($_REQUEST['private_key']))){ + $priv_key=trim($_REQUEST['private_key']); + if(($pkey=openssl_pkey_get_private($priv_key))!==false){ + $details=openssl_pkey_get_details($pkey); + if($details['bits']!==1024){ + echo '

    Error: private key not of bitsize 1024.

    '; + $ok=false; + }else{ + $onion=get_onion($pkey); + $check->execute([$onion]); + if($check->fetch(PDO::FETCH_NUM)){ + echo '

    Error onion already exists.

    '; $ok=false; } } - } - } - } - $check=$db->prepare('SELECT null FROM users WHERE onion=?;'); - if(isset($_REQUEST['private_key']) && !empty(trim($_REQUEST['private_key']))){ - $priv_key=trim($_REQUEST['private_key']); - if(($pkey=openssl_pkey_get_private($priv_key))!==false){ - $details=openssl_pkey_get_details($pkey); - if($details['bits']!==1024){ - echo '

    Error, private key not of bitsize 1024.

    '; - $ok=false; + openssl_pkey_free($pkey); }else{ - $onion=get_onion($pkey); - $check->execute([$onion]); - if($check->fetch(PDO::FETCH_NUM)){ - echo '

    Error onion already exists.

    '; - $ok=false; - } + echo '

    Error: private key invalid.

    '; + $ok=false; } - openssl_pkey_free($pkey); }else{ - echo '

    Error, private key invalid.

    '; - $ok=false; + do{ + $pkey=openssl_pkey_new(['private_key_bits'=>1024, 'private_key_type'=>OPENSSL_KEYTYPE_RSA]); + openssl_pkey_export($pkey, $priv_key); + $onion=get_onion($pkey); + openssl_pkey_free($pkey); + $check->execute([$onion]); + }while($check->fetch(PDO::FETCH_NUM)); } - }else{ - do{ - $pkey=openssl_pkey_new(['private_key_bits'=>1024, 'private_key_type'=>OPENSSL_KEYTYPE_RSA]); - openssl_pkey_export($pkey, $priv_key); - $onion=get_onion($pkey); - openssl_pkey_free($pkey); - $check->execute([$onion]); - }while($check->fetch(PDO::FETCH_NUM)); - } - if($ok){ if(isset($_POST['public']) && $_POST['public']==1){ $public=1; } @@ -119,7 +98,7 @@ if($_SERVER['REQUEST_METHOD']==='POST'){ } $check=$db->prepare('SELECT null FROM users WHERE dateadded>?;'); $check->execute([time()-60]); - if($check->fetch(PDO::FETCH_NUM)){ + if($ok && $check->fetch(PDO::FETCH_NUM)){ echo '

    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.

    '; $ok=false; }elseif($ok){ @@ -149,9 +128,7 @@ if(isset($_POST['username'])){ echo '" required autofocus>'; echo 'Password'; echo 'Confirm password'; -if(CAPTCHA){ - send_captcha(); -} +send_captcha(); if($_SERVER['REQUEST_METHOD']!=='POST' || (isset($_POST['public']) && $_POST['public']==1)){ $public=' checked'; }else{ diff --git a/var/www/sendmail_wrapper.php b/var/www/sendmail_wrapper.php index fdfcf58..63a5953 100644 --- a/var/www/sendmail_wrapper.php +++ b/var/www/sendmail_wrapper.php @@ -1,7 +1,7 @@ query('SELECT null FROM settings LIMIT 1;')){ +$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, KEY public (public), KEY dateadded (dateadded)) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;'); - $db->exec('CREATE TABLE del_account (onion char(16) COLLATE latin1_bin NOT NULL PRIMARY KEY, CONSTRAINT del_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 new_account (onion char(16) COLLATE latin1_bin NOT NULL PRIMARY KEY, password varchar(255) COLLATE latin1_bin 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 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 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]); echo "Database has successfully been set up\n"; +}else{ + $version=$version->fetch(PDO::FETCH_NUM)[0]; + if($version<2){ + $db->exec('ALTER TABLE users ADD todelete tinyint(1) UNSIGNED NOT NULL, ADD INDEX(todelete);'); + $db->exec('ALTER TABLE new_account ADD approved tinyint(1) UNSIGNED NOT NULL;'); + $db->exec('DROP TABLE del_account;'); + } + $stmt=$db->prepare("UPDATE settings SET value=? WHERE setting='version';"); + $stmt->execute([DBVERSION]); + if(DBVERSION!=$version){ + echo "Database has successfully been updated to the latest version\n"; + }else{ + echo "Database already up-to-date\n"; + } } -?>