Initial commit
This commit is contained in:
170
var/www/common.php
Normal file
170
var/www/common.php
Normal file
@ -0,0 +1,170 @@
|
||||
<?php
|
||||
const DBHOST='localhost'; // Database host
|
||||
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=1; //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
|
||||
'dhosting4okcs22v.onion'=>['sftp'=>22, 'ftp'=>21, 'pop3'=>'110', 'imap'=>'143', 'smtp'=>'25'],
|
||||
'danwin1210.me'=>['sftp'=>22, 'ftp'=>21, 'pop3'=>'', 'imap'=>'', 'smtp'=>'']
|
||||
];
|
||||
|
||||
function get_onion($pkey){
|
||||
$keyData = openssl_pkey_get_details($pkey);
|
||||
return base32_encode(hex2bin(substr(sha1(substr(base64_decode(substr($keyData['key'], 27, -26)), 22)), 0, 20)));
|
||||
}
|
||||
|
||||
function base32_encode($input) {
|
||||
$map = array(
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', // 7
|
||||
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', // 15
|
||||
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', // 23
|
||||
'y', 'z', '2', '3', '4', '5', '6', '7', // 31
|
||||
);
|
||||
if(empty($input)){
|
||||
return '';
|
||||
}
|
||||
$input = str_split($input);
|
||||
$binaryString = '';
|
||||
$c=count($input);
|
||||
for($i = 0; $i < $c; ++$i) {
|
||||
$binaryString .= str_pad(decbin(ord($input[$i])), 8, '0', STR_PAD_LEFT);
|
||||
}
|
||||
$fiveBitBinaryArray = str_split($binaryString, 5);
|
||||
$base32 = '';
|
||||
$i=0;
|
||||
$c=count($fiveBitBinaryArray);
|
||||
while($i < $c) {
|
||||
$base32 .= $map[bindec($fiveBitBinaryArray[$i])];
|
||||
++$i;
|
||||
}
|
||||
return $base32;
|
||||
}
|
||||
|
||||
function send_captcha(){
|
||||
global $db;
|
||||
if(CAPTCHA===0 || !extension_loaded('gd')){
|
||||
return;
|
||||
}
|
||||
$captchachars='ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789';
|
||||
$length=strlen($captchachars)-1;
|
||||
$code='';
|
||||
for($i=0;$i<5;++$i){
|
||||
$code.=$captchachars[mt_rand(0, $length)];
|
||||
}
|
||||
$randid=mt_rand();
|
||||
$time=time();
|
||||
$stmt=$db->prepare('INSERT INTO captcha (id, time, code) VALUES (?, ?, ?);');
|
||||
$stmt->execute([$randid, $time, $code]);
|
||||
echo "<tr><td>Copy: ";
|
||||
if(CAPTCHA===1){
|
||||
$im=imagecreatetruecolor(55, 24);
|
||||
$bg=imagecolorallocate($im, 0, 0, 0);
|
||||
$fg=imagecolorallocate($im, 255, 255, 255);
|
||||
imagefill($im, 0, 0, $bg);
|
||||
imagestring($im, 5, 5, 5, $code, $fg);
|
||||
echo '<img width="55" height="24" src="data:image/gif;base64,';
|
||||
}elseif(CAPTCHA===2){
|
||||
$im=imagecreatetruecolor(55, 24);
|
||||
$bg=imagecolorallocate($im, 0, 0, 0);
|
||||
$fg=imagecolorallocate($im, 255, 255, 255);
|
||||
imagefill($im, 0, 0, $bg);
|
||||
imagestring($im, 5, 5, 5, $code, $fg);
|
||||
$line=imagecolorallocate($im, 255, 255, 255);
|
||||
for($i=0;$i<2;++$i){
|
||||
imageline($im, 0, mt_rand(0, 24), 55, mt_rand(0, 24), $line);
|
||||
}
|
||||
$dots=imagecolorallocate($im, 255, 255, 255);
|
||||
for($i=0;$i<100;++$i){
|
||||
imagesetpixel($im, mt_rand(0, 55), mt_rand(0, 24), $dots);
|
||||
}
|
||||
echo '<img width="55" height="24" src="data:image/gif;base64,';
|
||||
}else{
|
||||
$im=imagecreatetruecolor(150, 200);
|
||||
$bg=imagecolorallocate($im, 0, 0, 0);
|
||||
$fg=imagecolorallocate($im, 255, 255, 255);
|
||||
imagefill($im, 0, 0, $bg);
|
||||
$line=imagecolorallocate($im, 100, 100, 100);
|
||||
for($i=0;$i<5;++$i){
|
||||
imageline($im, 0, mt_rand(0, 200), 150, mt_rand(0, 200), $line);
|
||||
}
|
||||
$dots=imagecolorallocate($im, 200, 200, 200);
|
||||
for($i=0;$i<1000;++$i){
|
||||
imagesetpixel($im, mt_rand(0, 150), mt_rand(0, 200), $dots);
|
||||
}
|
||||
$chars=[];
|
||||
for($i=0;$i<10;++$i){
|
||||
$found=false;
|
||||
while(!$found){
|
||||
$x=mt_rand(10, 140);
|
||||
$y=mt_rand(10, 180);
|
||||
$found=true;
|
||||
foreach($chars as $char){
|
||||
if($char['x']>=$x && ($char['x']-$x)<25){
|
||||
$found=false;
|
||||
}elseif($char['x']<$x && ($x-$char['x'])<25){
|
||||
$found=false;
|
||||
}
|
||||
if(!$found){
|
||||
if($char['y']>=$y && ($char['y']-$y)<25){
|
||||
break;
|
||||
}elseif($char['y']<$y && ($y-$char['y'])<25){
|
||||
break;
|
||||
}else{
|
||||
$found=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$chars[]=['x', 'y'];
|
||||
$chars[$i]['x']=$x;
|
||||
$chars[$i]['y']=$y;
|
||||
if($i<5){
|
||||
imagechar($im, 5, $chars[$i]['x'], $chars[$i]['y'], $captchachars[mt_rand(0, $length)], $fg);
|
||||
}else{
|
||||
imagechar($im, 5, $chars[$i]['x'], $chars[$i]['y'], $code[$i-5], $fg);
|
||||
}
|
||||
}
|
||||
$follow=imagecolorallocate($im, 200, 0, 0);
|
||||
imagearc($im, $chars[5]['x']+4, $chars[5]['y']+8, 16, 16, 0, 360, $follow);
|
||||
for($i=5;$i<9;++$i){
|
||||
imageline($im, $chars[$i]['x']+4, $chars[$i]['y']+8, $chars[$i+1]['x']+4, $chars[$i+1]['y']+8, $follow);
|
||||
}
|
||||
echo '<img width="150" height="200" src="data:image/gif;base64,';
|
||||
}
|
||||
ob_start();
|
||||
imagegif($im);
|
||||
imagedestroy($im);
|
||||
echo base64_encode(ob_get_clean()).'"></td>';
|
||||
echo "<td><input type=\"hidden\" name=\"challenge\" value=\"$randid\"><input type=\"text\" name=\"captcha\" autocomplete=\"off\"></td></tr>";
|
||||
}
|
||||
|
||||
function check_login(){
|
||||
global $db;
|
||||
if(empty($_SESSION['hosting_username'])){
|
||||
header('Location: login.php');
|
||||
session_destroy();
|
||||
exit;
|
||||
}
|
||||
$stmt=$db->prepare('SELECT * FROM users WHERE username=?;');
|
||||
$stmt->execute([$_SESSION['hosting_username']]);
|
||||
if(!$user=$stmt->fetch(PDO::FETCH_ASSOC)){
|
||||
header('Location: login.php');
|
||||
session_destroy();
|
||||
exit;
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
|
||||
function get_system_hash($pass){
|
||||
$chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./';
|
||||
$salt='';
|
||||
for($i=0;$i<16;++$i){
|
||||
$salt.=$chars[random_int(0, strlen($chars)-1)];
|
||||
}
|
||||
return crypt($pass, '$6$'.$salt.'$');
|
||||
}
|
||||
?>
|
166
var/www/cron.php
Normal file
166
var/www/cron.php
Normal file
@ -0,0 +1,166 @@
|
||||
<?php
|
||||
include('common.php');
|
||||
try{
|
||||
$db=new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>PERSISTENT]);
|
||||
}catch(PDOException $e){
|
||||
die('No Connection to MySQL database!');
|
||||
}
|
||||
$reload=false;
|
||||
|
||||
//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;");
|
||||
while($id=$stmt->fetch(PDO::FETCH_NUM)){
|
||||
$reload=true;
|
||||
$onion=$id[0];
|
||||
//php openssl implementation has some issues, re-export using native openssl
|
||||
$pkey=openssl_pkey_get_private($id[3]);
|
||||
openssl_pkey_export_to_file($pkey, 'key.tmp');
|
||||
openssl_pkey_free($pkey);
|
||||
$priv_key=shell_exec('openssl rsa < key.tmp');
|
||||
unlink('key.tmp');
|
||||
$update_priv->execute([$priv_key, $onion]);
|
||||
//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("chown root:www-data /home/$onion.onion");
|
||||
exec("chmod 550 /home/$onion.onion");
|
||||
|
||||
//configuration for services
|
||||
|
||||
if($id[4]>0){
|
||||
$php_location="
|
||||
location ~ [^/]\.php(/|\$) {
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_pass unix:/run/php/$onion;
|
||||
}
|
||||
";
|
||||
}else{
|
||||
$php_location='';
|
||||
}
|
||||
if($id[5]!=0){
|
||||
$autoindex='on';
|
||||
}else{
|
||||
$autoindex='off';
|
||||
}
|
||||
|
||||
$nginx="server {
|
||||
listen 80;
|
||||
root /home/$onion.onion/www;
|
||||
server_name $onion.onion *.$onion.onion;
|
||||
access_log /var/log/nginx/access_$onion.onion.log custom;
|
||||
error_log /var/log/nginx/error_$onion.onion.log notice;
|
||||
disable_symlinks on from=/home/$onion.onion/www;
|
||||
autoindex $autoindex;
|
||||
location / {
|
||||
try_files \$uri \$uri/ =404;$php_location
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
$php="[$onion]
|
||||
user = $onion.onion
|
||||
group = www-data
|
||||
listen = /run/php/$onion
|
||||
listen.owner = www-data
|
||||
listen.group = www-data
|
||||
listen.mode = 0660
|
||||
chdir = /
|
||||
pm = ondemand
|
||||
pm.max_children = 8
|
||||
pm.process_idle_timeout = 10s;
|
||||
php_admin_value[sendmail_path] = '/usr/bin/php /var/www/sendmail_wrapper.php \"Hosting <$onion.onion@" . ADDRESS . ">\" | /usr/sbin/sendmail -t -i'
|
||||
php_admin_value[memory_limit] = 128M
|
||||
php_admin_value[disable_functions] = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,exec,passthru,shell_exec,system,popen,proc_open,socket_listen,socket_create_listen,socket_bind,stream_socket_server,fsockopen,pfsockopen,posix_kill,php_uname,link,symlink,posix_uname
|
||||
php_admin_value[open_basedir] = /home/$onion.onion
|
||||
php_admin_value[upload_tmp_dir] = /home/$onion.onion/tmp
|
||||
php_admin_value[soap.wsdl_cache_dir] = /home/$onion.onion/tmp
|
||||
php_admin_value[session.save_path] = /home/$onion.onion/tmp
|
||||
";
|
||||
|
||||
$firstchar=substr($onion, 0, 1);
|
||||
//save configuration files
|
||||
file_put_contents("/etc/nginx/sites-enabled/$onion.onion", $nginx);
|
||||
if($id[4]==1){
|
||||
file_put_contents("/etc/php/7.0/fpm/pool.d/$firstchar/$onion.conf", $php);
|
||||
}elseif($id[4]==2){
|
||||
file_put_contents("/etc/php/7.1/fpm/pool.d/$firstchar/$onion.conf", $php);
|
||||
}
|
||||
//save hidden service
|
||||
mkdir("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion");
|
||||
file_put_contents("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/hostname", $onion);
|
||||
file_put_contents("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/private_key", $priv_key);
|
||||
chmod("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/", 0700);
|
||||
chmod("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/hostname", 0600);
|
||||
chmod("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/private_key", 0600);
|
||||
chown("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/", "_tor-$firstchar");
|
||||
chown("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/hostname", "_tor-$firstchar");
|
||||
chown("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/private_key", "_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/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 127.0.0.1:80\n";
|
||||
file_put_contents("/etc/tor/instances/$firstchar/torrc", $torrc);
|
||||
//remove from to-add queue
|
||||
$del->execute([$onion]);
|
||||
}
|
||||
|
||||
//delete old accounts
|
||||
$del=$db->prepare("DELETE FROM users WHERE onion=?");
|
||||
$stmt=$db->query("SELECT onion FROM del_account LIMIT 100;");
|
||||
$onions=$stmt->fetchAll(PDO::FETCH_NUM);
|
||||
foreach($onions as $onion){
|
||||
$reload=true;
|
||||
$firstchar=substr($onion[0], 0, 1);
|
||||
//delete config files
|
||||
if(file_exists("/etc/php/7.0/fpm/pool.d/$firstchar/$onion[0].conf")){
|
||||
unlink("/etc/php/7.0/fpm/pool.d/$firstchar/$onion[0].conf");
|
||||
}
|
||||
if(file_exists("/etc/php/7.1/fpm/pool.d/$firstchar/$onion[0].conf")){
|
||||
unlink("/etc/php/7.1/fpm/pool.d/$firstchar/$onion[0].conf");
|
||||
}
|
||||
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 127.0.0.1:80\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/");
|
||||
}
|
||||
|
||||
//reload services
|
||||
if($reload){
|
||||
exec('service nginx reload');
|
||||
exec('service php7.0-fpm reload');
|
||||
exec('service php7.1-fpm reload');
|
||||
exec('service tor reload');
|
||||
}
|
||||
|
||||
//continue deleting old accounts
|
||||
foreach($onions as $onion){
|
||||
//kill processes of the user to allow deleting system users
|
||||
exec("skill -u $onion[0].onion");
|
||||
//delete user and group
|
||||
exec("userdel -rf $onion[0].onion");
|
||||
//delete all log files
|
||||
exec("rm -f /var/log/nginx/*$onion[0].onion.log*");
|
||||
//delete user from database
|
||||
$db->exec("DROP USER IF EXISTS '$onion[0].onion'@'localhost'");
|
||||
$db->exec("DROP DATABASE IF EXISTS `$onion[0]`;");
|
||||
$db->exec('FLUSH PRIVILEGES;');
|
||||
//delete user from user database
|
||||
$del->execute([$onion[0]]);
|
||||
}
|
||||
|
||||
// update passwords
|
||||
$stmt=$db->query("SELECT onion, password FROM pass_change LIMIT 100;");
|
||||
$del=$db->prepare("DELETE FROM pass_change WHERE onion=?;");
|
||||
while($onion=$stmt->fetch(PDO::FETCH_NUM)){
|
||||
exec('usermod -p '. escapeshellarg($onion[1]) . " $onion[0].onion");
|
||||
$del->execute([$onion[0]]);
|
||||
}
|
||||
?>
|
35
var/www/find_old.php
Normal file
35
var/www/find_old.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
include('common.php');
|
||||
try{
|
||||
$db=new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>PERSISTENT]);
|
||||
}catch(PDOException $e){
|
||||
die('No Connection to MySQL database!');
|
||||
}
|
||||
|
||||
//delete tmp files older than 24 hours
|
||||
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 (?);');
|
||||
foreach($all as $tmp){
|
||||
if(!preg_match('~^[a-z2-7]{16}\.onion$~', $tmp)){
|
||||
continue;
|
||||
}
|
||||
if(filemtime("/home/$tmp")>time()-60*60*24*30){
|
||||
continue;
|
||||
}
|
||||
//check data empty and www no more than 1 file
|
||||
if(count(scandir("/home/$tmp/data/"))>2 || count(scandir("/home/$tmp/www/"))>3){
|
||||
continue;
|
||||
}
|
||||
//check www empty or index unmodified
|
||||
if(count(scandir("/home/$tmp/www/"))===3){
|
||||
$md5s=['2ff89413bebfd03f9241b0254ebfd782','d41d8cd98f00b204e9800998ecf8427e', '7ae7e9bac6be76f00e0d95347111f037'];
|
||||
if(!file_exists("/home/$tmp/www/index.hosting.html") || !in_array(md5_file("/home/$tmp/www/index.hosting.html"), $md5s)){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//no data found, safe to delete
|
||||
$stmt->execute([substr($tmp, 0, 16)]);
|
||||
}
|
36
var/www/html/delete.php
Normal file
36
var/www/html/delete.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
include('../common.php');
|
||||
try{
|
||||
$db=new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>PERSISTENT]);
|
||||
}catch(PDOException $e){
|
||||
die('No Connection to MySQL database!');
|
||||
}
|
||||
session_start();
|
||||
$user=check_login();
|
||||
$msg='';
|
||||
if($_SERVER['REQUEST_METHOD']==='POST'){
|
||||
if(!isset($_POST['pass']) || !password_verify($_POST['pass'], $user['password'])){
|
||||
$msg.='<p style="color:red;">Wrong password.</p>';
|
||||
}else{
|
||||
$stmt=$db->prepare('INSERT INTO del_account (onion) VALUES (?);');
|
||||
$stmt->execute([$user['onion']]);
|
||||
session_destroy();
|
||||
header('Location: login.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
echo '<!DOCTYPE html><html><head>';
|
||||
echo '<title>Daniel\'s Hosting - Delete account</title>';
|
||||
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
|
||||
echo '<meta name=viewport content="width=device-width, initial-scale=1">';
|
||||
echo '</head><body>';
|
||||
echo '<p>This will delete your account and all data asociated with it. It can\'t be un-done. Are you sure?</p>';
|
||||
echo $msg;
|
||||
echo '<form method="POST" action="delete.php"><table>';
|
||||
echo '<tr><td>Enter your account password to confirm</td><td><input type="password" name="pass" required autofocus></td></tr>';
|
||||
echo '<tr><td colspan="2"><input type="submit" value="Delete"></td></tr>';
|
||||
echo '</table></form>';
|
||||
echo '<p><a href="home.php">No, don\'t delete.</a></p>';
|
||||
echo '</body></html>';
|
||||
?>
|
BIN
var/www/html/favicon.ico
Normal file
BIN
var/www/html/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
56
var/www/html/home.php
Normal file
56
var/www/html/home.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
include('../common.php');
|
||||
try{
|
||||
$db=new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>PERSISTENT]);
|
||||
}catch(PDOException $e){
|
||||
die('No Connection to MySQL database!');
|
||||
}
|
||||
session_start();
|
||||
$user=check_login();
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
echo '<!DOCTYPE html><html><head>';
|
||||
echo '<title>Daniel\'s Hosting - Dashboard</title>';
|
||||
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
|
||||
echo '<meta name=viewport content="width=device-width, initial-scale=1">';
|
||||
echo '</head><body>';
|
||||
echo "<p>Logged in as $user[username] <a href=\"logout.php\">Logout</a> | <a href=\"password.php\">Change passwords</a> | <a href=\"delete.php\">Delete account</a></p>";
|
||||
$mail=0;
|
||||
if(file_exists("/home/$user[onion].onion/Maildir/new/")){
|
||||
$mail=count(scandir("/home/$user[onion].onion/Maildir/new/"))-2;
|
||||
}
|
||||
echo "<p>Enter system account password to check your $user[onion].onion@" . ADDRESS . " mail ($mail new):</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>There is no Web-based file management yet, you\'ll need to use an FTP client like <a href="https://filezilla-project.org/">FileZilla</a> (<a href="http://tt3j2x4k5ycaa5zt.onion/tutorials/torify-ftp/" target="_blank">Torify FileZilla</a>) for now, to manage files. A web based file manager is planned.</p>';
|
||||
echo '<h3>Domain</h3>';
|
||||
echo '<table border="1">';
|
||||
echo '<tr><th>Onion</th><th>Private key</th></tr>';
|
||||
echo "<tr><td><a href=\"http://$user[onion].onion\" target=\"_blank\">$user[onion].onion</a></td><td>";
|
||||
if(isset($_REQUEST['show_priv'])){
|
||||
echo "<pre>$user[private_key]</pre>";
|
||||
}else{
|
||||
echo '<a href="home.php?show_priv=1">Show private key</a>';
|
||||
}
|
||||
echo '</td></tr>';
|
||||
echo '</table>';
|
||||
echo '<h3>MySQL Database</h3>';
|
||||
echo '<table border="1">';
|
||||
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>";
|
||||
echo '</table>';
|
||||
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 '<h3>System Account</h3>';
|
||||
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>';
|
||||
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 '</table>';
|
||||
echo '<p><a href="password.php?type=sys">Change system account password</a></p>';
|
||||
echo '<h3>Logs</h3>';
|
||||
echo '<table border="1">';
|
||||
echo '<tr><th>Date</th><th>access.log</th><th>error.log</th></tr>';
|
||||
echo '<tr><td>Today</td><td><a href="log.php?type=access&old=0" target="_blank">access.log</log></td><td><a href="log.php?type=error&old=0" target="_blank">error.log</a></td></tr>';
|
||||
echo '<tr><td>Yesterday</td><td><a href="log.php?type=access&old=1" target="_blank">access.log</log></td><td><a href="log.php?type=error&old=1" target="_blank">error.log</a></td></tr>';
|
||||
echo '</table>';
|
||||
echo '</body></html>';
|
||||
?>
|
43
var/www/html/index.php
Normal file
43
var/www/html/index.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
include('../common.php');
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
echo '<!DOCTYPE html><html><head>';
|
||||
echo '<title>Daniel\'s Hosting</title>';
|
||||
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
|
||||
echo '<meta name=viewport content="width=device-width, initial-scale=1">';
|
||||
echo '</head><body>';
|
||||
echo '<p>Info | <a href="register.php">Register</a> | <a href="login.php">Login</a> | <a href="list.php">List of hosted sites</a></p>';
|
||||
echo '<p>Here you can get yourself a hosting account on my server.</p>';
|
||||
echo '<p>What you will get:</p>';
|
||||
echo '<ul>';
|
||||
echo '<li>Chose between PHP 7.0 or 7.1</li>';
|
||||
echo '<li>Nginx Webserver</li>';
|
||||
echo '<li>SQLite support</li>';
|
||||
echo '<li>1 MariaDB (MySQL) database</li>';
|
||||
echo '<li><a href="/phpmyadmin/" target="_blank">PHPMyAdmin</a> and <a href="/adminer/" target="_blank">Adminer</a> for web based database administration</li>';
|
||||
echo '<li><b>No Web-based file management yet, you\'ll need to use an FTP client like <a href="https://filezilla-project.org/">FileZilla</a> (<a href="http://tt3j2x4k5ycaa5zt.onion/tutorials/torify-ftp/" target="_blank">Torify FileZilla</a>) for now, to manage files. A web based file manager is planned.</b></li>';
|
||||
echo '<li>FTP access</li>';
|
||||
echo '<li>SFTP access</li>';
|
||||
echo '<li>No disk quota</li>';
|
||||
echo '<li>mail() can send e-mails from your.onion@' . ADDRESS . ' and you get imap, pop3 and smtp access</li>';
|
||||
echo '<li>Your own .onion address</li>';
|
||||
echo '<li>There is a missing feature or you need a special configuration? Just <a href="http://tt3j2x4k5ycaa5zt.onion/contact.php">contact me</a> and I\'ll see what I can do.</li>';
|
||||
echo '<li>Empty accounts will be deleted after a month</li>';
|
||||
echo '<li>More to come…</li>';
|
||||
echo '</ul>';
|
||||
echo '<h2>Rules</h2>';
|
||||
echo '<ul>';
|
||||
echo '<li>No child pornography!</li>';
|
||||
echo '<li>No terroristic propaganda!</li>';
|
||||
echo '<li>No illegal content according to German law!</li>';
|
||||
echo '<li>No malware! (e.g. botnets)</li>';
|
||||
echo '<li>No phishing!</li>';
|
||||
echo '<li>No scams!</li>';
|
||||
echo '<li>No spam!</li>';
|
||||
echo '<li>No shops! (mostly scams anyway)</li>';
|
||||
echo '<li>No proxy scripts!</li>';
|
||||
echo '<li>No IP logger or similar de-anonymizer sites!</li>';
|
||||
echo '<li>I preserve the right to delete any site for violating these rules and adding new rules at any time.</li>';
|
||||
echo '</ul>';
|
||||
echo '</body></html>';
|
||||
?>
|
28
var/www/html/list.php
Normal file
28
var/www/html/list.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
include_once('../common.php');
|
||||
try{
|
||||
$db=new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>PERSISTENT]);
|
||||
}catch(PDOException $e){
|
||||
die('No Connection to MySQL database!');
|
||||
}
|
||||
echo '<!DOCTYPE html><html><head>';
|
||||
echo '<title>Daniel\'s Hosting - List of hosted sites</title>';
|
||||
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
|
||||
echo '<meta name=viewport content="width=device-width, initial-scale=1">';
|
||||
echo '</head><body>';
|
||||
echo '<p><a href="index.php">Info</a> | <a href="register.php">Register</a> | <a href="login.php">Login</a> | List of hosted sites</p>';
|
||||
$stmt=$db->query('SELECT COUNT(*) FROM users WHERE public=1;');
|
||||
$count=$stmt->fetch(PDO::FETCH_NUM);
|
||||
$stmt=$db->query('SELECT COUNT(*) FROM users WHERE public=0;');
|
||||
$hidden=$stmt->fetch(PDO::FETCH_NUM);
|
||||
echo "<p>Here a list of $count[0] public hosted sites ($hidden[0] sites hidden):</p>";
|
||||
echo '<table border="1">';
|
||||
echo '<tr><td>Onion link</td></tr>';
|
||||
$stmt=$db->query('SELECT username, onion FROM users WHERE public=1 ORDER BY onion;');
|
||||
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 '</table>';
|
||||
echo '</body></html>';
|
||||
?>
|
28
var/www/html/log.php
Normal file
28
var/www/html/log.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
include('../common.php');
|
||||
try{
|
||||
$db=new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>PERSISTENT]);
|
||||
}catch(PDOException $e){
|
||||
die('No Connection to MySQL database!');
|
||||
}
|
||||
session_start();
|
||||
$user=check_login();
|
||||
if(!isset($_REQUEST['old']) || $_REQUEST['old']==0){
|
||||
$old='';
|
||||
}else{
|
||||
$old='.1';
|
||||
}
|
||||
if(!isset($_REQUEST['type']) || $_REQUEST['type']==='access'){
|
||||
$type='access';
|
||||
}else{
|
||||
$type='error';
|
||||
}
|
||||
header('Content-Type: text/plain; charset=UTF-8');
|
||||
header("Content-disposition: filename=\"$type.log\"");
|
||||
header('Pragma: no-cache');
|
||||
header('Cache-Control: no-cache, no-store, must-revalidate, max-age=0');
|
||||
header('Expires: 0');
|
||||
if(file_exists("/var/log/nginx/{$type}_$user[onion].onion.log$old")){
|
||||
readfile("/var/log/nginx/{$type}_$user[onion].onion.log$old");
|
||||
}
|
||||
?>
|
88
var/www/html/login.php
Normal file
88
var/www/html/login.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
include('../common.php');
|
||||
try{
|
||||
$db=new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS, [PDO::ATTR_ERRMODE=>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();
|
||||
if(!empty($_SESSION['hosting_username'])){
|
||||
header('Location: home.php');
|
||||
exit;
|
||||
}
|
||||
$msg='';
|
||||
if($_SERVER['REQUEST_METHOD']==='POST'){
|
||||
$ok=true;
|
||||
if(CAPTCHA){
|
||||
if(!isset($_REQUEST['challenge'])){
|
||||
echo '<p style="color:red;">Error: Wrong Captcha</p>';
|
||||
$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 '<p style="color:red;">Error: Captcha expired</p>';
|
||||
$ok=false;
|
||||
}else{
|
||||
$time=time();
|
||||
$stmt=$db->prepare('DELETE FROM captcha WHERE id=? OR time<?;');
|
||||
$stmt->execute([$_REQUEST['challenge'], $time-3600]);
|
||||
if($_REQUEST['captcha']!==$code){
|
||||
if(strrev($_REQUEST['captcha'])!==$code){
|
||||
echo '<p style="color:red;">Error: Wrong captcha</p>';
|
||||
$ok=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!isset($_POST['username']) || $_POST['username']===''){
|
||||
$msg.='<p style="color:red;">Error, username may not be empty.</p>';
|
||||
$ok=false;
|
||||
}else{
|
||||
$stmt=$db->prepare('SELECT username, password FROM users WHERE username=?;');
|
||||
$stmt->execute([$_POST['username']]);
|
||||
$tmp=[];
|
||||
if(($tmp=$stmt->fetch(PDO::FETCH_NUM))===false && preg_match('/^([2-7a-z]{16}).onion$/', $_POST['username'], $match)){
|
||||
$stmt=$db->prepare('SELECT username, password FROM users WHERE onion=?;');
|
||||
$stmt->execute([$match[1]]);
|
||||
$tmp=$stmt->fetch(PDO::FETCH_NUM);
|
||||
}
|
||||
if($tmp){
|
||||
if(!isset($_POST['pass']) || !password_verify($_POST['pass'], $tmp[1])){
|
||||
$msg.='<p style="color:red;">Error, wrong password.</p>';
|
||||
}else{
|
||||
$_SESSION['hosting_username']=$tmp[0];
|
||||
session_write_close();
|
||||
header('Location: home.php');
|
||||
exit;
|
||||
}
|
||||
}else{
|
||||
$msg.='<p style="color:red;">Error, username was not found. If you forgot it, you can enter youraccount.onion instead.</p>';
|
||||
}
|
||||
}
|
||||
}
|
||||
echo '<!DOCTYPE html><html><head>';
|
||||
echo '<title>Daniel\'s Hosting - Login</title>';
|
||||
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
|
||||
echo '<meta name=viewport content="width=device-width, initial-scale=1">';
|
||||
echo '</head><body>';
|
||||
echo '<p><a href="index.php">Info</a> | <a href="register.php">Register</a> | Login | <a href="list.php">List of hosted sites</a></p>';
|
||||
echo $msg;
|
||||
echo '<form method="POST" action="login.php"><table>';
|
||||
echo '<tr><td>Username</td><td><input type="text" name="username" value="';
|
||||
if(isset($_POST['username'])){
|
||||
echo htmlspecialchars($_POST['username']);
|
||||
}
|
||||
echo '" required autofocus></td></tr>';
|
||||
echo '<tr><td>Password</td><td><input type="password" name="pass" required></td></tr>';
|
||||
if(CAPTCHA){
|
||||
send_captcha();
|
||||
}
|
||||
echo '<tr><td colspan="2"><input type="submit" value="Login"></td></tr>';
|
||||
echo '</table></form>';
|
||||
echo '<p>If you disabled cookies, please re-enable them. You currently can\'t log in without</p>';
|
||||
echo '</body></html>';
|
||||
?>
|
5
var/www/html/logout.php
Normal file
5
var/www/html/logout.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
session_start();
|
||||
session_destroy();
|
||||
header('Location: login.php');
|
||||
?>
|
72
var/www/html/password.php
Normal file
72
var/www/html/password.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
include('../common.php');
|
||||
try{
|
||||
$db=new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>PERSISTENT]);
|
||||
}catch(PDOException $e){
|
||||
die('No Connection to MySQL database!');
|
||||
}
|
||||
session_start();
|
||||
$user=check_login();
|
||||
if(!isset($_REQUEST['type'])){
|
||||
$_REQUEST['type']='acc';
|
||||
}
|
||||
$msg='';
|
||||
if($_SERVER['REQUEST_METHOD']==='POST'){
|
||||
if(!isset($_POST['pass']) || !password_verify($_POST['pass'], $user['password'])){
|
||||
$msg.='<p style="color:red;">Wrong password.</p>';
|
||||
}elseif(!isset($_POST['confirm']) || !isset($_POST['newpass']) || $_POST['newpass']!==$_POST['confirm']){
|
||||
$msg.='<p style="color:red;">Wrong password.</p>';
|
||||
}else{
|
||||
if($_REQUEST['type']==='acc'){
|
||||
$hash=password_hash($_POST['newpass'], PASSWORD_DEFAULT);
|
||||
$stmt=$db->prepare('UPDATE users SET password=? WHERE username=?;');
|
||||
$stmt->execute([$hash, $user['username']]);
|
||||
$msg.='<p style="color:green;">Successfully changed account password.</p>';
|
||||
}elseif($_REQUEST['type']==='sys'){
|
||||
$stmt=$db->prepare('INSERT INTO pass_change (onion, password) VALUES (?, ?);');
|
||||
$hash=get_system_hash($_POST['newpass']);
|
||||
$stmt->execute([$user['onion'], $hash]);
|
||||
$msg.='<p style="color:green;">Successfully changed system account password, change will take affect within the next minute.</p>';
|
||||
}elseif($_REQUEST['type']==='sql'){
|
||||
$stmt=$db->prepare("SET PASSWORD FOR '$user[onion].onion'@'localhost'=PASSWORD(?);");
|
||||
$stmt->execute([$_POST['newpass']]);
|
||||
$db->exec('FLUSH PRIVILEGES;');
|
||||
$msg.='<p style="color:green;">Successfully changed sql password.</p>';
|
||||
}else{
|
||||
$msg.='<p style="color:red;">Couldn\'t update password: Unknown reset type.</p>';
|
||||
}
|
||||
}
|
||||
}
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
echo '<!DOCTYPE html><html><head>';
|
||||
echo '<title>Daniel\'s Hosting - Change password</title>';
|
||||
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
|
||||
echo '<meta name=viewport content="width=device-width, initial-scale=1">';
|
||||
echo '</head><body>';
|
||||
echo $msg;
|
||||
echo '<form method="POST" action="password.php"><table>';
|
||||
echo '<tr><td>Reset type:</td><td><select name="type">';
|
||||
echo '<option value="acc"';
|
||||
if($_REQUEST['type']==='acc'){
|
||||
echo ' selected';
|
||||
}
|
||||
echo '>Account</option>';
|
||||
echo '<option value="sys"';
|
||||
if($_REQUEST['type']==='sys'){
|
||||
echo ' selected';
|
||||
}
|
||||
echo '>System account</option>';
|
||||
echo '<option value="sql"';
|
||||
if($_REQUEST['type']==='sql'){
|
||||
echo ' selected';
|
||||
}
|
||||
echo '>MySQL</option>';
|
||||
echo '</select></td></tr>';
|
||||
echo '<tr><td>Account password:</td><td><input type="password" name="pass" required autofocus></td></tr>';
|
||||
echo '<tr><td>New password:</td><td><input type="password" name="newpass" required></td></tr>';
|
||||
echo '<tr><td>Confirm password:</td><td><input type="password" name="confirm" required></td></tr>';
|
||||
echo '<tr><td colspan="2"><input type="submit" value="Reset"></td></tr>';
|
||||
echo '</table></form>';
|
||||
echo '<p><a href="home.php">Go back to dashboard.</a></p>';
|
||||
echo '</body></html>';
|
||||
?>
|
182
var/www/html/register.php
Normal file
182
var/www/html/register.php
Normal file
@ -0,0 +1,182 @@
|
||||
<?php
|
||||
include('../common.php');
|
||||
try{
|
||||
$db=new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS, [PDO::ATTR_ERRMODE=>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();
|
||||
if(!empty($_SESSION['hosting_username'])){
|
||||
header('Location: home.php');
|
||||
exit;
|
||||
}
|
||||
echo '<!DOCTYPE html><html><head>';
|
||||
echo '<title>Daniel\'s Hosting - Register</title>';
|
||||
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
|
||||
echo '<meta name=viewport content="width=device-width, initial-scale=1">';
|
||||
echo '</head><body>';
|
||||
echo '<p><a href="index.php">Info</a> | Register | <a href="login.php">Login</a> | <a href="list.php">List of hosted sites</a></p>';
|
||||
if($_SERVER['REQUEST_METHOD']==='POST'){
|
||||
$ok=true;
|
||||
$onion='';
|
||||
$public=0;
|
||||
$php=0;
|
||||
$autoindex=0;
|
||||
$hash='';
|
||||
$priv_key='';
|
||||
if(empty($_POST['pass'])){
|
||||
echo '<p style="color:red;">Error, password empty.</p>';
|
||||
$ok=false;
|
||||
}elseif(empty($_POST['passconfirm']) || $_POST['pass']!==$_POST['passconfirm']){
|
||||
echo '<p style="color:red;">Error, password confirmation does not match.</p>';
|
||||
$ok=false;
|
||||
}
|
||||
if(empty($_POST['username'])){
|
||||
echo '<p style="color:red;">Error, username empty.</p>';
|
||||
$ok=false;
|
||||
}elseif(preg_match('/[^a-z0-9\-_\.]/', $_POST['username'])){
|
||||
echo '<p style="color:red;">Error, username may only contain characters that are in the rage of a-z (lower case) - . _ and 0-9.</p>';
|
||||
$ok=false;
|
||||
}elseif(strlen($_POST['username'])>50){
|
||||
echo '<p style="color:red;">Error, username may not be longer than 50 characters.</p>';
|
||||
$ok=false;
|
||||
}else{
|
||||
$stmt=$db->prepare('SELECT null FROM users WHERE username=?;');
|
||||
$stmt->execute([$_POST['username']]);
|
||||
if($stmt->fetch(PDO::FETCH_NUM)){
|
||||
echo '<p style="color:red;">Error, this username is already registered.</p>';
|
||||
$ok=false;
|
||||
}
|
||||
}
|
||||
if(CAPTCHA){
|
||||
if(!isset($_REQUEST['challenge'])){
|
||||
echo '<p style="color:red;">Error: Wrong Captcha</p>';
|
||||
$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 '<p style="color:red;">Error: Captcha expired</p>';
|
||||
$ok=false;
|
||||
}else{
|
||||
$time=time();
|
||||
$stmt=$db->prepare('DELETE FROM captcha WHERE id=? OR time<?;');
|
||||
$stmt->execute([$_REQUEST['challenge'], $time-3600]);
|
||||
if($_REQUEST['captcha']!==$code){
|
||||
if(strrev($_REQUEST['captcha'])!==$code){
|
||||
echo '<p style="color:red;">Error: Wrong captcha</p>';
|
||||
$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 '<p style="color:red;">Error, private key not of bitsize 1024.</p>';
|
||||
$ok=false;
|
||||
}else{
|
||||
$onion=get_onion($pkey);
|
||||
$check->execute([$onion]);
|
||||
if($check->fetch(PDO::FETCH_NUM)){
|
||||
echo '<p style="color:red;">Error onion already exists.</p>';
|
||||
$ok=false;
|
||||
}
|
||||
}
|
||||
openssl_pkey_free($pkey);
|
||||
}else{
|
||||
echo '<p style="color:red;">Error, private key invalid.</p>';
|
||||
$ok=false;
|
||||
}
|
||||
}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;
|
||||
}
|
||||
if(isset($_POST['php']) && in_array($_POST['php'], [1, 2])){
|
||||
$php=$_POST['php'];
|
||||
}
|
||||
if(isset($_POST['autoindex']) && $_POST['autoindex']==1){
|
||||
$autoindex=1;
|
||||
}
|
||||
$priv_key=trim(str_replace("\r", '', $priv_key));
|
||||
$hash=password_hash($_POST['pass'], PASSWORD_DEFAULT);
|
||||
}
|
||||
$check=$db->prepare('SELECT null FROM users WHERE dateadded>?;');
|
||||
$check->execute([time()-60]);
|
||||
if($check->fetch(PDO::FETCH_NUM)){
|
||||
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;
|
||||
}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]);
|
||||
$create_user=$db->prepare("CREATE USER '$onion.onion'@'localhost' 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'@'localhost';");
|
||||
$db->exec('FLUSH PRIVILEGES;');
|
||||
$stmt=$db->prepare('INSERT INTO new_account (onion, password) VALUES (?, ?);');
|
||||
$stmt->execute([$onion, get_system_hash($_POST['pass'])]);
|
||||
$title="A new hidden service $onion has been created";
|
||||
$msg="A new hidden service http://$onion.onion has been created";
|
||||
$headers="From: www-data <www-data>\r\nContent-Type: text/plain; charset=UTF-8\r\n";
|
||||
mail('daniel@tt3j2x4k5ycaa5zt.onion', $title, $msg, $headers);
|
||||
echo "<p style=\"color:green;\">Your onion domain <a href=\"http://$onion.onion\" target=\"_blank\">$onion.onion</a> has successfully been created. Please wait up to one minute until the changes have been processed. You can then login <a href=\"login.php\">here</a>.</p>";
|
||||
}
|
||||
}
|
||||
echo '<form method="POST" action="register.php"><table>';
|
||||
echo '<tr><td>Username</td><td><input type="text" name="username" value="';
|
||||
if(isset($_POST['username'])){
|
||||
echo htmlspecialchars($_POST['username']);
|
||||
}
|
||||
echo '" required autofocus></td></tr>';
|
||||
echo '<tr><td>Password</td><td><input type="password" name="pass" required></td></tr>';
|
||||
echo '<tr><td>Confirm password</td><td><input type="password" name="passconfirm" required></td></tr>';
|
||||
if(CAPTCHA){
|
||||
send_captcha();
|
||||
}
|
||||
if($_SERVER['REQUEST_METHOD']!=='POST' || (isset($_POST['public']) && $_POST['public']==1)){
|
||||
$public=' checked';
|
||||
}else{
|
||||
$public='';
|
||||
}
|
||||
if(isset($_POST['autoindex']) && $_POST['public']==1){
|
||||
$autoindex=' checked';
|
||||
}else{
|
||||
$autoindex='';
|
||||
}
|
||||
$nophp='';
|
||||
$php70='';
|
||||
$php71='';
|
||||
if(isset($_POST['php']) && $_POST['php']==0){
|
||||
$nophp=' selected';
|
||||
}elseif(isset($_POST['php']) && $_POST['php']==2){
|
||||
$php71=' selected';
|
||||
}else{
|
||||
$php70=' selected';
|
||||
}
|
||||
echo '<tr><td>PHP version</td><td><select name="php"><option value="0"'.$nophp.'>None</option><option value="1" '.$php70.'>PHP 7.0</option><option value="2"'.$php71.'>PHP 7.1</option></select></td></tr>';
|
||||
echo '<tr><td colspan=2><label><input type="checkbox" name="public" value="1"'.$public.'>Publish site on list of hosted sites</label></td></tr>';
|
||||
echo '<tr><td colspan=2><label><input type="checkbox" name="autoindex" value="1"'.$autoindex.'>Enable autoindex (listing of files)</label></td></tr>';
|
||||
echo '<tr><td>Custom private key<br>(optional)</td><td><textarea name="private_key" rows="5" cols="28">';
|
||||
if(isset($_REQUEST['private_key'])){
|
||||
echo htmlspecialchars($_REQUEST['private_key']);
|
||||
}
|
||||
echo '</textarea></td></tr>';
|
||||
echo '<tr><td colspan="2"><input type="submit" value="Register"></td></tr>';
|
||||
echo '</table></form>';
|
||||
echo '</body></html>';
|
12
var/www/sendmail_wrapper.php
Normal file
12
var/www/sendmail_wrapper.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
$head=true;
|
||||
while($line=fgets(STDIN)){
|
||||
if($head && stripos(ltrim($line), 'FROM:')===0){
|
||||
continue;
|
||||
}
|
||||
if($head && ($line==="\r\n" || $line==="\n")){
|
||||
$head=false;
|
||||
echo "From: $argv[1]\r\n";
|
||||
}
|
||||
echo $line;
|
||||
}
|
33
var/www/setup.php
Normal file
33
var/www/setup.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
include('common.php');
|
||||
if(!extension_loaded('pdo_mysql')){
|
||||
die("Error: You need to install and enable the PDO php module\n");
|
||||
}
|
||||
try{
|
||||
$db=new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME . ';charset=utf8mb4', DBUSER, DBPASS, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>PERSISTENT]);
|
||||
}catch(PDOException $e){
|
||||
try{
|
||||
//Attempt to create database
|
||||
$db=new PDO('mysql:host=' . DBHOST . ';charset=utf8mb4', DBUSER, DBPASS, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>PERSISTENT]);
|
||||
if(false!==$db->exec('CREATE DATABASE ' . DBNAME)){
|
||||
$db=new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME . ';charset=utf8mb4', DBUSER, DBPASS, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>PERSISTENT]);
|
||||
}else{
|
||||
die("Error: No database connection!\n");
|
||||
}
|
||||
}catch(PDOException $e){
|
||||
die("Error: No database connection!\n");
|
||||
}
|
||||
}
|
||||
if(!@$db->query('SELECT null FROM settings LIMIT 1;')){
|
||||
//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 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 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;');
|
||||
$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;');
|
||||
$stmt=$db->prepare("INSERT INTO settings (setting, value) VALUES ('version', ?);");
|
||||
$stmt->execute([DBVERSION]);
|
||||
echo "Database has successfully been set up\n";
|
||||
}
|
||||
?>
|
10
var/www/skel/www/index.hosting.html
Normal file
10
var/www/skel/www/index.hosting.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Site hosted by Daniel's hosting service</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>This site is hosted by <a href="http://dhosting4okcs22v.onion" target="_blank">Daniel's hosting service</a>.</p>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user