Added PGP Two Factor Authentication (2FA)
This commit is contained in:
@ -5,7 +5,7 @@ const DBUSER='hosting'; // Database user
|
||||
const DBPASS='MY_PASSWORD'; // Database password
|
||||
const DBNAME='hosting'; // Database
|
||||
const PERSISTENT=true; // Use persistent database conection true/false
|
||||
const DBVERSION=17; //database layout version
|
||||
const DBVERSION=18; //database layout version
|
||||
const CAPTCHA=1; // Captcha difficulty (0=off, 1=simple, 2=moderate, 3=extreme)
|
||||
const ADDRESS='dhosting4xxoydyaivckq7tsmtgi4wfs3flpeyitekkmqwu4v4r46syd.onion'; // our own address
|
||||
const CANONICAL_URL='https://hosting.danwin1210.me'; // our preferred domain for search engines
|
||||
@ -1034,3 +1034,70 @@ function sanitize_system_account(string $system_account){
|
||||
}
|
||||
return $account;
|
||||
}
|
||||
|
||||
function main_menu(string $current_site){
|
||||
echo '<p>';
|
||||
$sites = [
|
||||
'index.php' => 'Info',
|
||||
'register.php' => 'Register',
|
||||
'login.php' => 'Login',
|
||||
'list.php' => 'List of hosted sites',
|
||||
'faq.php' => 'FAQ',
|
||||
];
|
||||
$first = true;
|
||||
foreach($sites as $link => $name){
|
||||
if($first){
|
||||
$first = false;
|
||||
if($link===$current_site){
|
||||
echo $name;
|
||||
} else {
|
||||
echo "<a href=\"$link\" target=\"_self\">$name</a>";
|
||||
}
|
||||
} else {
|
||||
if($link===$current_site){
|
||||
echo " | $name";
|
||||
} else {
|
||||
echo " | <a href=\"$link\" target=\"_self\">$name</a>";
|
||||
}
|
||||
}
|
||||
}
|
||||
echo '</p>';
|
||||
}
|
||||
|
||||
function dashboard_menu(array $user, string $current_site){
|
||||
echo '<p>Logged in as ' . htmlspecialchars($user['username']);
|
||||
$sites = [
|
||||
'logout.php' => 'Logout',
|
||||
'home.php' => 'Dashboard',
|
||||
'pgp.php' => 'PGP 2FA',
|
||||
'password.php' => 'Change password',
|
||||
'files.php' => 'FileManager',
|
||||
'delete.php' => 'Delete account',
|
||||
];
|
||||
foreach($sites as $link => $name){
|
||||
if($link===$current_site){
|
||||
echo " | $name";
|
||||
} else {
|
||||
echo " | <a href=\"$link\" target=\"_self\">$name</a>";
|
||||
}
|
||||
}
|
||||
echo '</p>';
|
||||
}
|
||||
|
||||
function print_header(string $sub_title, string $style = '', string $base_target = '_self'){
|
||||
?>
|
||||
<!DOCTYPE html><html><head>
|
||||
<title><?php echo htmlspecialchars(SITE_NAME) . ' - ' . htmlspecialchars($sub_title); ?></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL . $_SERVER['SCRIPT_NAME']; ?>">
|
||||
<?php
|
||||
if(!empty($style)){
|
||||
echo "<style type=\"text/css\">$style</style>";
|
||||
}
|
||||
echo "<base rel=\"noopener\" target=\"$base_target\">";
|
||||
?>
|
||||
</head><body>
|
||||
<?php
|
||||
}
|
||||
|
@ -6,16 +6,8 @@ session_start(['name'=>'hosting_admin']);
|
||||
if($_SERVER['REQUEST_METHOD']==='HEAD'){
|
||||
exit; // headers sent, no further processing needed
|
||||
}
|
||||
print_header('Admin panel', 'td{padding:5px;}', '_blank');
|
||||
?>
|
||||
<!DOCTYPE html><html><head>
|
||||
<title><?php echo htmlspecialchars(SITE_NAME); ?> - Admin panel</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="canonical" href="'.CANONICAL_URL. $_SERVER['SCRIPT_NAME'] .'">
|
||||
<style>td{padding:5px;}</style>
|
||||
<base target="_blank">
|
||||
</head><body>
|
||||
<h1>Hosting - Admin panel</h1>
|
||||
<?php
|
||||
$error=false;
|
||||
|
@ -17,14 +17,8 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
|
||||
}
|
||||
}
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
print_header('Delete account');
|
||||
?>
|
||||
<!DOCTYPE html><html><head>
|
||||
<title><?php echo htmlspecialchars(SITE_NAME); ?> - Delete account</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL . $_SERVER['SCRIPT_NAME']; ?>">
|
||||
</head><body>
|
||||
<p>This will delete your account and all data asociated with it. It can't be un-done. Are you sure?</p>
|
||||
<?php echo $msg; ?>
|
||||
<form method="POST" action="delete.php"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"><table>
|
||||
|
@ -2,16 +2,10 @@
|
||||
require('../common.php');
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
header('X-Accel-Expires: 60');
|
||||
print_header('FAQ');
|
||||
?>
|
||||
<!DOCTYPE html><html><head>
|
||||
<title><?php echo htmlspecialchars(SITE_NAME); ?> - FAQ</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL . $_SERVER['SCRIPT_NAME']; ?>">
|
||||
</head><body>
|
||||
<h1>Hosting - Info</h1>
|
||||
<p><a href="index.php">Info</a> | <a href="register.php">Register</a> | <a href="login.php">Login</a> | <a href="list.php">List of hosted sites</a> | FAQ</p>
|
||||
<h1>Hosting - FAQ</h1>
|
||||
<?php main_menu('faq.php'); ?>
|
||||
<table border="1">
|
||||
<tr><th>Question</th><th>Answer</th></tr>
|
||||
<tr><td>Your rules are so strict. Can't you make an exception for my site?</td><td>No, I will not make exceptions for any site and neither am I corruptible 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.</td></tr>
|
||||
|
@ -274,17 +274,7 @@ if($sort==='M'){
|
||||
if($order==='D'){
|
||||
$list=array_reverse($list);
|
||||
}
|
||||
|
||||
$dir=htmlspecialchars($dir);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL . $_SERVER['SCRIPT_NAME']; ?>">
|
||||
<title><?php echo htmlspecialchars(SITE_NAME); ?> - FileManager - Index of <?php echo $dir; ?></title>
|
||||
<style type="text/css">.list td:nth-child(3){word-break:break-all;} .list td:nth-child(5){text-align:right;} .list tr{height:28px;}
|
||||
$style = '.list td:nth-child(3){word-break:break-all;} .list td:nth-child(5){text-align:right;} .list tr{height:28px;}
|
||||
.back{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPH/AAAAADMzM2ZmZpmZmSH5BAUAAAQALAAAAAAUABYAAANLSLrc/oKE8CoZM1O7os7c9WmcN04WdoKQdBIANypAHG5YbS/7kus1RlDxA+p4xqSRpmwCKE7nINqMwKi6wEAY1VaS3tBV/OiRz4sEADs=);}
|
||||
.dir{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPH/AAAAADMzM5lmM//MmSH5BAUAAAQALAAAAAAUABYAAANUSLrc/jDKSRm4+E4wuu9AxH1kpimAQHpqiQ5CLMcrHI71GgdXngs8nI8F7A1JReFxZzyygk4iNNpJUmFWmFbF3cJ4hNRsPA6Aw+a0es0LLEzwjDsBADs=);}
|
||||
.img{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPMLAAAAADMzM2YAAAAzZmZmZv8zMwCZMwCZzJmZmczMzP///wAAAAAAAAAAAAAAAAAAACH5BAUAAAsALAAAAAAUABYAAASQMMhJ57p4BcW730F2bV5JhhlZdio6KkUsF4mi2tg2y4ICBL/gaxfrAY5IwJDY4yCeCKUGNjNYDTUFVKqTGTgJa1bLVSRi3/CVlIi+EgIB9mrdJAbuaYe+ThzwZSx8BAEHf3k3CQFXhIaHgR2KE46PLytmlJV6JX6ZgJYedwOjpJ+blyWIAVCsrU9AGUmys1IRADs=);}
|
||||
@ -295,9 +285,10 @@ $dir=htmlspecialchars($dir);
|
||||
.bin{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPIFAAAAADMzM5mZmczMzP///wAAAAAAAAAAACH5BAUAAAUALAAAAAAUABYAAANpGLq89bAEQqudIb4JABkdMBATqXFeR6ilCaFr6rWuFN8qEOj8doOdUWjosxgpgqQA4AOKbhUl05aTHZe+KtSCpVpVxu7EKfSEp7TjOeshX9E469obf7Prc5g7r+6LA0qBgkk7EUOHiFMJADs=);}
|
||||
.doc{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPL/AAAAADMzM/8zM5lmM//MM2bM/5mZmf///yH5BAUAAAgALAAAAAAUABYAAARvMMhJJ7oYhcO730F2bV5JhtlZceSBjixBFDT7YedMFxwQ+ECYa1c7AI5IgDAwaDY9hqhBqWE5n9AotVXqHqZCbxdcNSbPHTJXnN72zsl2mC0vcwTmOEdNL/E7eHB1a3R/fXtbAVKLjFE/GXCRSBcRADs=);}
|
||||
.txt{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPH/AAAAADMzM5mZmf///yH5BAUAAAQALAAAAAAUABYAAANYGLq89JCEQaudIb5pO88R11UiuI3XBXFA61JAEM8nCrtujbeW4AuAmq3yC0puuxcFKBwSjaykcsA8OntQpPTZvFZF2un3iu1ul1kyuuv8Bn7wuE8WkdqNCQA7);}
|
||||
.sh{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPH/AAAAADMzM5mZmf///yH5BAUAAAQALAAAAAAUABYAAANgGLq89JCEQaudIb5pO88R11UiuFXAkJIXxAEwjAYATZ9UuuZxjPc7imAoAOBUyBHRKBk5hUzR01L8AXuVanPa0b6usWyU2x2rwDLokTzw8tDiNdnNVksCxLx+eIOg0Q8JADs=);}
|
||||
</style>
|
||||
</head><body>
|
||||
.sh{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPH/AAAAADMzM5mZmf///yH5BAUAAAQALAAAAAAUABYAAANgGLq89JCEQaudIb5pO88R11UiuFXAkJIXxAEwjAYATZ9UuuZxjPc7imAoAOBUyBHRKBk5hUzR01L8AXuVanPa0b6usWyU2x2rwDLokTzw8tDiNdnNVksCxLx+eIOg0Q8JADs=);}';
|
||||
print_header('FileManager - Index of '.$dir, $style);
|
||||
$dir=htmlspecialchars($dir);
|
||||
?>
|
||||
<h1>Index of <?php echo $dir; ?></h1>
|
||||
<?php if($dir!=='/'){ ?>
|
||||
<p>Upload up to 1GB and up to 100 files at once <form action="files.php" enctype="multipart/form-data" method="post"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"><input name="files[]" type="file" multiple><input type="hidden" name="path" value="<?php echo $dir; ?>"><input type="submit" value="Upload"></form></p><br>
|
||||
@ -376,24 +367,15 @@ function get_properties($name, &$icon, &$size){
|
||||
|
||||
function send_not_found(){
|
||||
header("HTTP/1.1 404 Not Found");
|
||||
echo '<!DOCTYPE html><html><head>';
|
||||
echo '<title>404 Not Found</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 '<link rel="canonical" href="'.CANONICAL_URL . $_SERVER['SCRIPT_NAME'].'">';
|
||||
echo '</head><body>';
|
||||
print_header('FileManager - 404 Not Found');
|
||||
echo '<p>The requested file '.htmlspecialchars($_REQUEST['path']).' was not found on your account.</p>';
|
||||
echo '<p><a href="files.php">Go back to home directory</a>.</p>';
|
||||
echo '</body></html>';
|
||||
}
|
||||
|
||||
function send_login(){
|
||||
print_header('FileManager - Login');
|
||||
?>
|
||||
<!DOCTYPE html><html><head>
|
||||
<title><?php echo htmlspecialchars(SITE_NAME); ?> - FileManager - Login</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name=viewport content="width=device-width, initial-scale=1">
|
||||
</head><body>
|
||||
<p>Please type in your system account password: <form action="files.php" method="post"><input name="ftp_pass" type="password" autofocus><input type="submit" value="Login"></form></p>
|
||||
<p><a href="home.php">Go back to dashboard</a>.</p>
|
||||
</body></html>
|
||||
@ -437,11 +419,7 @@ function ftp_recursive_delete($ftp, $file){
|
||||
}
|
||||
|
||||
function send_rename($dir){
|
||||
echo '<!DOCTYPE html><html><head>';
|
||||
echo '<title>' . htmlspecialchars(SITE_NAME) . ' - FileManager - Rename file</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>';
|
||||
print_header('FileManager - Rename file');
|
||||
echo '<form action="files.php" method="post">';
|
||||
echo '<input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'">';
|
||||
echo '<input type="hidden" name="path" value="'.htmlspecialchars($dir).'">';
|
||||
@ -456,11 +434,7 @@ function send_rename($dir){
|
||||
}
|
||||
|
||||
function send_edit($ftp, $dir){
|
||||
echo '<!DOCTYPE html><html><head>';
|
||||
echo '<title>' . htmlspecialchars(SITE_NAME) . ' - FileManager - Edit file</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>';
|
||||
print_header('FileManager - Edit file');
|
||||
echo '<form action="files.php" method="post">';
|
||||
echo '<input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'">';
|
||||
echo '<input type="hidden" name="path" value="'.htmlspecialchars($dir).'">';
|
||||
|
@ -12,14 +12,9 @@ if(isset($_POST['action']) && $_POST['action']==='add_db'){
|
||||
if(isset($_POST['action']) && $_POST['action']==='del_db' && !empty($_POST['db'])){
|
||||
if($error=check_csrf_error()){
|
||||
die($error);
|
||||
} ?>
|
||||
<!DOCTYPE html><html><head>
|
||||
<title><?php echo htmlspecialchars(SITE_NAME); ?> - Delete database</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL . $_SERVER['SCRIPT_NAME']; ?>">
|
||||
</head><body>
|
||||
}
|
||||
print_header('Delete database');
|
||||
?>
|
||||
<p>This will delete your database <?php echo htmlspecialchars($_POST['db']); ?> and all data asociated with it. It can't be un-done. Are you sure?</p>
|
||||
<form method="post" action="home.php"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
|
||||
<input type="hidden" name="db" value="<?php echo htmlspecialchars($_POST['db']); ?>">
|
||||
@ -38,14 +33,9 @@ if(isset($_POST['action']) && $_POST['action']==='del_db_2' && !empty($_POST['db
|
||||
if(isset($_POST['action']) && $_POST['action']==='del_onion' && !empty($_POST['onion'])){
|
||||
if($error=check_csrf_error()){
|
||||
die($error);
|
||||
} ?>
|
||||
<!DOCTYPE html><html><head>
|
||||
<title><?php echo htmlspecialchars(SITE_NAME); ?> - Delete onion domain</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL . $_SERVER['SCRIPT_NAME']; ?>">
|
||||
</head><body>
|
||||
}
|
||||
print_header('Delete onion domain');
|
||||
?>
|
||||
<p>This will delete your onion domain <?php echo htmlspecialchars($_POST['onion']); ?>.onion and all data asociated with it. It can't be un-done. Are you sure?</p>
|
||||
<form method="post" action="home.php"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
|
||||
<input type="hidden" name="onion" value="<?php echo htmlspecialchars($_POST['onion']); ?>">
|
||||
@ -119,14 +109,9 @@ if(isset($_POST['action']) && $_POST['action']==='add_domain' && !empty($_POST['
|
||||
if(isset($_POST['action']) && $_POST['action']==='del_domain' && !empty($_POST['domain'])){
|
||||
if($error=check_csrf_error()){
|
||||
die($error);
|
||||
} ?>
|
||||
<!DOCTYPE html><html><head>
|
||||
<title><?php echo htmlspecialchars(SITE_NAME); ?> - Delete domain</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL . $_SERVER['SCRIPT_NAME']; ?>">
|
||||
</head><body>
|
||||
}
|
||||
print_header('Delete domain');
|
||||
?>
|
||||
<p>This will delete your domain <?php echo htmlspecialchars($_POST['domain']); ?> and all data asociated with it. It can't be un-done. Are you sure?</p>
|
||||
<form method="post" action="home.php"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
|
||||
<input type="hidden" name="domain" value="<?php echo htmlspecialchars($_POST['domain']); ?>">
|
||||
@ -183,18 +168,8 @@ if(isset($_REQUEST['action']) && isset($_POST['domain']) && $_POST['action']==='
|
||||
enqueue_instance_reload();
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html><html><head>
|
||||
<title><?php echo htmlspecialchars(SITE_NAME); ?> - Dashboard</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL . $_SERVER['SCRIPT_NAME']; ?>">
|
||||
<style type="text/css">#custom_onion:not(checked)+#private_key{display:none;}#custom_onion:checked+#private_key{display:block;}</style>
|
||||
<style>td{padding:5px}meter{width:200px}</style>
|
||||
</head><body>
|
||||
<p>Logged in as <?php echo htmlspecialchars($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>
|
||||
<?php
|
||||
print_header('Dashboard', '#custom_onion:not(checked)+#private_key{display:none;}#custom_onion:checked+#private_key{display:block;}td{padding:5px}meter{width:200px}');
|
||||
dashboard_menu($user, 'home.php');
|
||||
if(!empty($msg)){
|
||||
echo $msg;
|
||||
}
|
||||
|
@ -2,16 +2,10 @@
|
||||
require('../common.php');
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
header('X-Accel-Expires: 60');
|
||||
print_header('Info');
|
||||
?>
|
||||
<!DOCTYPE html><html><head>
|
||||
<title><?php echo htmlspecialchars(SITE_NAME); ?></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL . $_SERVER['SCRIPT_NAME']; ?>">
|
||||
</head><body>
|
||||
<h1>Hosting - Info</h1>
|
||||
<p>Info | <a href="register.php">Register</a> | <a href="login.php">Login</a> | <a href="list.php">List of hosted sites</a> | <a href="faq.php">FAQ</a></p>
|
||||
<?php main_menu('index.php'); ?>
|
||||
<p>Here you can get yourself a free web hosting account on my server.</p>
|
||||
<h2>What you get:</h2>
|
||||
<ul>
|
||||
@ -29,8 +23,9 @@ header('X-Accel-Expires: 60');
|
||||
<li>Webmail and IMAP, POP3 and SMTP access to your mail account</li>
|
||||
<li>Your own .onion domains</li>
|
||||
<li>Clearnet domains or a free subdomain of danwin1210.me</li>
|
||||
<li>There is a missing feature or you need a special configuration? Just <a href="https://danwin1210.me/contact.php">contact me</a> and I'll see what I can do.</li>
|
||||
<li>Empty/Unused accounts will be automatically deleted after a month of inactivity</li>
|
||||
<li>PGP based Two Factor Authentication (2FA)</li>
|
||||
<li>There is a missing feature or you need a special configuration? Just <a href="https://danwin1210.me/contact.php">contact me</a> and I'll see what I can do.</li>
|
||||
<li>More to come…</li>
|
||||
</ul>
|
||||
<h2>Rules</h2>
|
||||
|
@ -3,19 +3,11 @@ require_once('../common.php');
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
header('X-Accel-Expires: 60');
|
||||
$db = get_db_instance();
|
||||
print_header('List of hosted sites', 'td{padding:5px;}', '_blank');
|
||||
?>
|
||||
<!DOCTYPE html><html><head>
|
||||
<title><?php echo htmlspecialchars(SITE_NAME); ?> - List of hosted sites</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL . $_SERVER['SCRIPT_NAME']; ?>">
|
||||
<style>td{padding:5px;}</style>
|
||||
<base rel="noopener" target="_blank">
|
||||
</head><body>
|
||||
<h1>Hosting - List of hosted sites</h1>
|
||||
<p><a href="index.php" target="_self">Info</a> | <a href="register.php" target="_self">Register</a> | <a href="login.php" target="_self">Login</a> | List of hosted sites | <a href="faq.php" target="_self">FAQ</a></p>
|
||||
<?php
|
||||
main_menu('list.php');
|
||||
$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;');
|
||||
|
@ -8,7 +8,25 @@ if(!empty($_SESSION['hosting_username']) && empty($_SESSION['2fa_code'])){
|
||||
}
|
||||
$msg='';
|
||||
$username='';
|
||||
$pgp_key='';
|
||||
$tfa=0;
|
||||
if(!empty($_SESSION['hosting_username'])){
|
||||
$tfa = $_SESSION['tfa'];
|
||||
$pgp_key = $_SESSION['pgp_key'];
|
||||
}
|
||||
if($_SERVER['REQUEST_METHOD']==='POST'){
|
||||
if(!empty($_SESSION['hosting_username'])){
|
||||
if(!empty($_POST['2fa_code']) && $_POST['2fa_code'] === $_SESSION['2fa_code']){
|
||||
unset($_SESSION['2fa_code']);
|
||||
unset($_SESSION['pgp_key']);
|
||||
unset($_SESSION['tfa']);
|
||||
session_write_close();
|
||||
header('Location: home.php');
|
||||
exit;
|
||||
}else{
|
||||
$msg.='<p style="color:red">Wrong 2FA code</p>';
|
||||
}
|
||||
} else {
|
||||
$db = get_db_instance();
|
||||
$ok=true;
|
||||
if($error=check_captcha_error()){
|
||||
@ -18,19 +36,21 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
|
||||
$msg.='<p style="color:red;">Error: username may not be empty.</p>';
|
||||
$ok=false;
|
||||
}else{
|
||||
$stmt=$db->prepare('SELECT username, password, id FROM users WHERE username=?;');
|
||||
$stmt=$db->prepare('SELECT username, password, id, tfa, pgp_key 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 users.username, users.password, users.id FROM users INNER JOIN onions ON (onions.user_id=users.id) WHERE onions.onion=?;');
|
||||
if(($tmp=$stmt->fetch(PDO::FETCH_ASSOC))===false && preg_match('/^([2-7a-z]{16}).onion$/', $_POST['username'], $match)){
|
||||
$stmt=$db->prepare('SELECT users.username, users.password, users.id, users.tfa, users.pgp_key FROM users INNER JOIN onions ON (onions.user_id=users.id) WHERE onions.onion=?;');
|
||||
$stmt->execute([$match[1]]);
|
||||
$tmp=$stmt->fetch(PDO::FETCH_NUM);
|
||||
$tmp=$stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
if($tmp){
|
||||
$username=$tmp[0];
|
||||
$password=$tmp[1];
|
||||
$username=$tmp['username'];
|
||||
$password=$tmp['password'];
|
||||
$tfa=$tmp['tfa'];
|
||||
$pgp_key=$tmp['pgp_key'];
|
||||
$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['id']]);
|
||||
if($tmp=$stmt->fetch(PDO::FETCH_NUM)){
|
||||
if(REQUIRE_APPROVAL && !$tmp[0]){
|
||||
$msg.='<p style="color:red;">Error: Your account is pending admin approval. Please try again later.</p>';
|
||||
@ -50,22 +70,55 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
|
||||
if($ok){
|
||||
$_SESSION['hosting_username']=$username;
|
||||
$_SESSION['csrf_token']=sha1(uniqid());
|
||||
if($tfa){
|
||||
$code = bin2hex(random_bytes(3));
|
||||
$_SESSION['2fa_code'] = $code;
|
||||
$_SESSION['pgp_key'] = $pgp_key;
|
||||
$_SESSION['tfa'] = $tfa;
|
||||
} else {
|
||||
session_write_close();
|
||||
header('Location: home.php');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print_header('Login');
|
||||
if($tfa){
|
||||
$gpg = gnupg_init();
|
||||
gnupg_seterrormode($gpg, GNUPG_ERROR_WARNING);
|
||||
gnupg_setarmor($gpg, 1);
|
||||
$imported_key = gnupg_import($gpg, $pgp_key);
|
||||
if($imported_key){
|
||||
$key_info = gnupg_keyinfo($gpg, $imported_key['fingerprint']);
|
||||
foreach($key_info as $key){
|
||||
if($key['can_encrypt']){
|
||||
foreach($key['subkeys'] as $subkey){
|
||||
gnupg_addencryptkey($gpg, $subkey['fingerprint']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$encrypted = gnupg_encrypt($gpg, "To login, please enter the following code to confirm ownership of your key:\n\n".$_SESSION['2fa_code']."\n");
|
||||
echo $msg;
|
||||
echo "<p>To login, please decrypt the following PGP encrypted message and confirm the code:</p>";
|
||||
echo "<pre>$encrypted</pre>";
|
||||
?>
|
||||
<form action="login.php" method="post"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
|
||||
<table border="1">
|
||||
<tr><td><input type="text" name="2fa_code"></td><td><button type="submit">Confirm</button></td></tr>
|
||||
</table></form>
|
||||
<p>Don't have the private key at hand? <a href="logout.php">Logout</a></p>
|
||||
</body></html>
|
||||
<?php
|
||||
exit;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html><html><head>
|
||||
<title><?php echo htmlspecialchars(SITE_NAME); ?> - Login</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL . $_SERVER['SCRIPT_NAME']; ?>">
|
||||
</head><body>
|
||||
<h1>Hosting - Login</h1>
|
||||
<p><a href="index.php">Info</a> | <a href="register.php">Register</a> | Login | <a href="list.php">List of hosted sites</a> | <a href="faq.php">FAQ</a></p>
|
||||
<?php echo $msg; ?>
|
||||
<?php
|
||||
main_menu('login.php');
|
||||
echo $msg;
|
||||
?>
|
||||
<form method="POST" action="login.php"><table>
|
||||
<tr><td>Username</td><td><input type="text" name="username" value="<?php
|
||||
if(isset($_POST['username'])){
|
||||
|
@ -36,13 +36,7 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
|
||||
}
|
||||
}
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
echo '<!DOCTYPE html><html><head>';
|
||||
echo '<title>' . htmlspecialchars(SITE_NAME) . ' - Change password</title>';
|
||||
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
|
||||
echo '<meta name="author" content="Daniel Winzen">';
|
||||
echo '<meta name="viewport" content="width=device-width, initial-scale=1">';
|
||||
echo '<link rel="canonical" href="' . CANONICAL_URL . $_SERVER['SCRIPT_NAME'] . '">';
|
||||
echo '</head><body>';
|
||||
print_header('Change password');
|
||||
echo $msg;
|
||||
echo '<form method="POST" action="password.php"><input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'"><table>';
|
||||
echo '<tr><td>Reset type:</td><td><select name="type">';
|
||||
|
80
var/www/html/pgp.php
Normal file
80
var/www/html/pgp.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
require('../common.php');
|
||||
$user=check_login();
|
||||
print_header('PGP 2FA');
|
||||
dashboard_menu($user, 'pgp.php');
|
||||
if($_SERVER['REQUEST_METHOD']==='POST'){
|
||||
if($error=check_csrf_error()){
|
||||
die($error);
|
||||
}
|
||||
if(isset($_POST['pgp_key'])){
|
||||
$pgp_key = trim($_POST['pgp_key']);
|
||||
$gpg = gnupg_init();
|
||||
gnupg_seterrormode($gpg, GNUPG_ERROR_WARNING);
|
||||
gnupg_setarmor($gpg, 1);
|
||||
$imported_key = gnupg_import($gpg, $pgp_key);
|
||||
if(!$imported_key){
|
||||
echo "<p style=\"color:red\">There was an error importing the key</p>";
|
||||
}else{
|
||||
$db = get_db_instance();
|
||||
$stmt = $db->prepare('UPDATE users SET pgp_key = ?, tfa = 0, pgp_verified = 0 WHERE id = ?;');
|
||||
$stmt->execute([$pgp_key, $user['id']]);
|
||||
$user['pgp_key'] = $pgp_key;
|
||||
}
|
||||
}
|
||||
if(isset($_POST['enable_2fa_code'])){
|
||||
if($_POST['enable_2fa_code'] !== $_SESSION['enable_2fa_code']){
|
||||
echo "<p style=\"color:red\">Sorry, the code was incorrect</p>";
|
||||
} else {
|
||||
$db = get_db_instance();
|
||||
$stmt = $db->prepare('UPDATE users SET tfa = 1, pgp_verified = 1 WHERE id = ?;');
|
||||
$stmt->execute([$user['id']]);
|
||||
$user['tfa'] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!empty($user['pgp_key'])){
|
||||
if($user['tfa'] == '1'){
|
||||
echo "<p style=\"color:green\">Yay, PGP based 2FA is enabled!</p>";
|
||||
} else {
|
||||
$gpg = gnupg_init();
|
||||
gnupg_seterrormode($gpg, GNUPG_ERROR_WARNING);
|
||||
gnupg_setarmor($gpg, 1);
|
||||
$imported_key = gnupg_import($gpg, $user['pgp_key']);
|
||||
if($imported_key){
|
||||
$key_info = gnupg_keyinfo($gpg, $imported_key['fingerprint']);
|
||||
foreach($key_info as $key){
|
||||
if(!$key['can_encrypt']){
|
||||
echo "<p>Sorry, this key can't be used to encrypt a message to you. Your key may have expired or has been revoked.</p>";
|
||||
}else{
|
||||
foreach($key['subkeys'] as $subkey){
|
||||
gnupg_addencryptkey($gpg, $subkey['fingerprint']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$_SESSION['enable_2fa_code'] = bin2hex(random_bytes(3));
|
||||
if($encrypted = gnupg_encrypt($gpg, "To enable 2FA, please enter the following code to confirm ownership of your key:\n\n$_SESSION[enable_2fa_code]\n")){
|
||||
echo "<p>To enable 2FA using your PGP key, please decrypt the following PGP encrypted message and confirm the code:</p>";
|
||||
echo "<pre>$encrypted</pre>";
|
||||
?>
|
||||
<form action="pgp.php" method="post"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
|
||||
<table border="1">
|
||||
<tr><td><input type="text" name="enable_2fa_code"></td><td><button type="submit">Confirm</button></td></tr>
|
||||
</table></form>
|
||||
<hr>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
<p>Add your PGP key for more security features like 2FA:</p>
|
||||
<form action="pgp.php" method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
|
||||
<table border="1">
|
||||
<tr><td><textarea name="pgp_key" rows="10" cols="50"><?php echo $user['pgp_key']; ?></textarea></td></tr>
|
||||
<tr><td><button type="submit">Update PGP key</button></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
<p><a href="home.php">Go back to dashboard.</a></p>
|
||||
</body></html>
|
@ -6,18 +6,11 @@ if(!empty($_SESSION['hosting_username'])){
|
||||
header('Location: home.php');
|
||||
exit;
|
||||
}
|
||||
print_header('Register', '#custom_onion:not(checked)+#private_key{display:none;}#custom_onion:checked+#private_key{display:block;}');
|
||||
?>
|
||||
<!DOCTYPE html><html><head>
|
||||
<title><?php echo htmlspecialchars(SITE_NAME); ?> - Register</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL . $_SERVER['SCRIPT_NAME']; ?>">
|
||||
<style type="text/css">#custom_onion:not(checked)+#private_key{display:none;}#custom_onion:checked+#private_key{display:block;}</style>
|
||||
</head><body>
|
||||
<h1>Hosting - Register</h1>
|
||||
<p><a href="index.php">Info</a> | Register | <a href="login.php">Login</a> | <a href="list.php">List of hosted sites</a> | <a href="faq.php">FAQ</a></p>
|
||||
<?php
|
||||
main_menu('register.php');
|
||||
if($_SERVER['REQUEST_METHOD']==='POST'){
|
||||
$db = get_db_instance();
|
||||
$ok=true;
|
||||
|
@ -8,15 +8,8 @@ $user=check_login();
|
||||
use chillerlan\QRCode\QRCode;
|
||||
use chillerlan\QRCode\QROptions;
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
print_header('Upgrade account', 'td{padding:5px;}');
|
||||
?>
|
||||
<!DOCTYPE html><html><head>
|
||||
<title><?php echo htmlspecialchars(SITE_NAME); ?> - Upgrade account</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="author" content="Daniel Winzen">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="canonical" href="<?php echo CANONICAL_URL . $_SERVER['SCRIPT_NAME']; ?>">
|
||||
<style>td{padding:5px;}</style>
|
||||
</head><body>
|
||||
<h1>Hosting - Upgrade account</h1>
|
||||
<?php
|
||||
$rates = coinpayments_get_rates();
|
||||
|
@ -23,7 +23,7 @@ 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 service_instances (id char(1) NOT NULL PRIMARY KEY, reload tinyint(1) UNSIGNED NOT NULL DEFAULT '0', KEY reload (reload)) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;");
|
||||
$db->exec("CREATE TABLE users (id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, system_account varchar(32) COLLATE latin1_bin NOT NULL UNIQUE, username varchar(50) COLLATE latin1_bin NOT NULL UNIQUE, password varchar(255) COLLATE latin1_bin NOT NULL, dateadded int(10) unsigned NOT NULL, public tinyint(1) unsigned NOT NULL, php tinyint(1) unsigned NOT NULL, autoindex tinyint(1) unsigned NOT NULL, todelete tinyint(1) UNSIGNED NOT NULL DEFAULT '0', mysql_user varchar(32) NOT NULL, instance char(1) NOT NULL DEFAULT '2', KEY dateadded (dateadded), KEY public (public), KEY todelete (todelete), KEY instance (instance), CONSTRAINT instance_ibfk_2 FOREIGN KEY (instance) REFERENCES service_instances (id) ON DELETE RESTRICT ON UPDATE RESTRICT) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;");
|
||||
$db->exec("CREATE TABLE users (id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, system_account varchar(32) COLLATE latin1_bin NOT NULL UNIQUE, username varchar(50) COLLATE latin1_bin NOT NULL UNIQUE, password varchar(255) COLLATE latin1_bin NOT NULL, dateadded int(10) unsigned NOT NULL, public tinyint(1) unsigned NOT NULL, php tinyint(1) unsigned NOT NULL, autoindex tinyint(1) unsigned NOT NULL, todelete tinyint(1) UNSIGNED NOT NULL DEFAULT '0', mysql_user varchar(32) NOT NULL, instance char(1) NOT NULL DEFAULT '2', pgp_key text COLLATE 'latin1_bin' NULL, pgp_verified tinyint(1) NOT NULL DEFAULT '0', tfa tinyint(1) NOT NULL DEFAULT '0', KEY dateadded (dateadded), KEY public (public), KEY todelete (todelete), KEY instance (instance), CONSTRAINT instance_ibfk_2 FOREIGN KEY (instance) REFERENCES service_instances (id) ON DELETE RESTRICT ON UPDATE RESTRICT) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;");
|
||||
$db->exec("CREATE TABLE new_account (user_id int(11) NOT NULL PRIMARY KEY, password varchar(255) COLLATE latin1_bin NOT NULL, approved tinyint(1) UNSIGNED NOT NULL DEFAULT '0', CONSTRAINT new_account_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;");
|
||||
$db->exec('CREATE TABLE pass_change (user_id int(11) NOT NULL PRIMARY KEY, password varchar(255) COLLATE latin1_bin NOT NULL, CONSTRAINT pass_change_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;');
|
||||
$db->exec('CREATE TABLE mysql_databases (user_id int(11) NOT NULL, mysql_database varchar(64) COLLATE latin1_bin NOT NULL, KEY user_id (user_id), CONSTRAINT mysql_database_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;');
|
||||
@ -160,6 +160,10 @@ if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';"))
|
||||
$db->exec("ALTER TABLE disk_quota ADD quota_size_used int(10) unsigned NOT NULL DEFAULT '0', ADD quota_files_used int(10) unsigned NOT NULL DEFAULT '0';");
|
||||
$db->exec('CREATE TABLE payments (id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, user_id int(11) NULL, payment_for varchar(255) COLLATE latin1_bin NOT NULL, txn_id varchar(255) COLLATE utf8mb4_bin NOT NULL, status tinyint NOT NULL, CONSTRAINT payments_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE SET NULL ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;');
|
||||
}
|
||||
if($version<18){
|
||||
$db->exec('UPDATE disk_quota set updated=1;');
|
||||
$db->exec("ALTER TABLE users ADD pgp_key text COLLATE 'latin1_bin' NULL, ADD pgp_verified tinyint(1) NOT NULL DEFAULT '0', ADD tfa tinyint(1) NOT NULL DEFAULT '0';");
|
||||
}
|
||||
$stmt=$db->prepare("UPDATE settings SET value=? WHERE setting='version';");
|
||||
$stmt->execute([DBVERSION]);
|
||||
}
|
||||
|
Reference in New Issue
Block a user