Added PGP Two Factor Authentication (2FA)

This commit is contained in:
Daniel Winzen
2020-02-17 07:07:02 +01:00
parent e949e4ea48
commit c2b010e8e6
14 changed files with 287 additions and 187 deletions

View File

@ -5,7 +5,7 @@ const DBUSER='hosting'; // Database user
const DBPASS='MY_PASSWORD'; // Database password const DBPASS='MY_PASSWORD'; // Database password
const DBNAME='hosting'; // Database const DBNAME='hosting'; // Database
const PERSISTENT=true; // Use persistent database conection true/false const PERSISTENT=true; // Use persistent database conection true/false
const DBVERSION=17; //database layout version const DBVERSION=18; //database layout version
const CAPTCHA=1; // Captcha difficulty (0=off, 1=simple, 2=moderate, 3=extreme) const CAPTCHA=1; // Captcha difficulty (0=off, 1=simple, 2=moderate, 3=extreme)
const ADDRESS='dhosting4xxoydyaivckq7tsmtgi4wfs3flpeyitekkmqwu4v4r46syd.onion'; // our own address const ADDRESS='dhosting4xxoydyaivckq7tsmtgi4wfs3flpeyitekkmqwu4v4r46syd.onion'; // our own address
const CANONICAL_URL='https://hosting.danwin1210.me'; // our preferred domain for search engines 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; 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
}

View File

@ -6,16 +6,8 @@ session_start(['name'=>'hosting_admin']);
if($_SERVER['REQUEST_METHOD']==='HEAD'){ if($_SERVER['REQUEST_METHOD']==='HEAD'){
exit; // headers sent, no further processing needed 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> <h1>Hosting - Admin panel</h1>
<?php <?php
$error=false; $error=false;

View File

@ -17,14 +17,8 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
} }
} }
header('Content-Type: text/html; charset=UTF-8'); 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> <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; ?> <?php echo $msg; ?>
<form method="POST" action="delete.php"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"><table> <form method="POST" action="delete.php"><input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"><table>

View File

@ -2,16 +2,10 @@
require('../common.php'); require('../common.php');
header('Content-Type: text/html; charset=UTF-8'); header('Content-Type: text/html; charset=UTF-8');
header('X-Accel-Expires: 60'); header('X-Accel-Expires: 60');
print_header('FAQ');
?> ?>
<!DOCTYPE html><html><head> <h1>Hosting - FAQ</h1>
<title><?php echo htmlspecialchars(SITE_NAME); ?> - FAQ</title> <?php main_menu('faq.php'); ?>
<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>
<table border="1"> <table border="1">
<tr><th>Question</th><th>Answer</th></tr> <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> <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>

View File

@ -274,17 +274,7 @@ if($sort==='M'){
if($order==='D'){ if($order==='D'){
$list=array_reverse($list); $list=array_reverse($list);
} }
$style = '.list td:nth-child(3){word-break:break-all;} .list td:nth-child(5){text-align:right;} .list tr{height:28px;}
$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;}
.back{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPH/AAAAADMzM2ZmZpmZmSH5BAUAAAQALAAAAAAUABYAAANLSLrc/oKE8CoZM1O7os7c9WmcN04WdoKQdBIANypAHG5YbS/7kus1RlDxA+p4xqSRpmwCKE7nINqMwKi6wEAY1VaS3tBV/OiRz4sEADs=);} .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=);} .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=);} .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=);} .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=);} .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);} .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=);} .sh{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPH/AAAAADMzM5mZmf///yH5BAUAAAQALAAAAAAUABYAAANgGLq89JCEQaudIb5pO88R11UiuFXAkJIXxAEwjAYATZ9UuuZxjPc7imAoAOBUyBHRKBk5hUzR01L8AXuVanPa0b6usWyU2x2rwDLokTzw8tDiNdnNVksCxLx+eIOg0Q8JADs=);}';
</style> print_header('FileManager - Index of '.$dir, $style);
</head><body> $dir=htmlspecialchars($dir);
?>
<h1>Index of <?php echo $dir; ?></h1> <h1>Index of <?php echo $dir; ?></h1>
<?php if($dir!=='/'){ ?> <?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> <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(){ function send_not_found(){
header("HTTP/1.1 404 Not Found"); header("HTTP/1.1 404 Not Found");
echo '<!DOCTYPE html><html><head>'; print_header('FileManager - 404 Not Found');
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>';
echo '<p>The requested file '.htmlspecialchars($_REQUEST['path']).' was not found on your account.</p>'; 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 '<p><a href="files.php">Go back to home directory</a>.</p>';
echo '</body></html>'; echo '</body></html>';
} }
function send_login(){ 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>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> <p><a href="home.php">Go back to dashboard</a>.</p>
</body></html> </body></html>
@ -437,11 +419,7 @@ function ftp_recursive_delete($ftp, $file){
} }
function send_rename($dir){ function send_rename($dir){
echo '<!DOCTYPE html><html><head>'; print_header('FileManager - Rename file');
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>';
echo '<form action="files.php" method="post">'; echo '<form action="files.php" method="post">';
echo '<input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'">'; echo '<input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'">';
echo '<input type="hidden" name="path" value="'.htmlspecialchars($dir).'">'; echo '<input type="hidden" name="path" value="'.htmlspecialchars($dir).'">';
@ -456,11 +434,7 @@ function send_rename($dir){
} }
function send_edit($ftp, $dir){ function send_edit($ftp, $dir){
echo '<!DOCTYPE html><html><head>'; print_header('FileManager - Edit file');
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>';
echo '<form action="files.php" method="post">'; echo '<form action="files.php" method="post">';
echo '<input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'">'; echo '<input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'">';
echo '<input type="hidden" name="path" value="'.htmlspecialchars($dir).'">'; echo '<input type="hidden" name="path" value="'.htmlspecialchars($dir).'">';

View File

@ -12,14 +12,9 @@ if(isset($_POST['action']) && $_POST['action']==='add_db'){
if(isset($_POST['action']) && $_POST['action']==='del_db' && !empty($_POST['db'])){ if(isset($_POST['action']) && $_POST['action']==='del_db' && !empty($_POST['db'])){
if($error=check_csrf_error()){ if($error=check_csrf_error()){
die($error); die($error);
} ?> }
<!DOCTYPE html><html><head> print_header('Delete database');
<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>
<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> <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']; ?>"> <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']); ?>"> <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(isset($_POST['action']) && $_POST['action']==='del_onion' && !empty($_POST['onion'])){
if($error=check_csrf_error()){ if($error=check_csrf_error()){
die($error); die($error);
} ?> }
<!DOCTYPE html><html><head> print_header('Delete onion domain');
<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>
<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> <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']; ?>"> <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']); ?>"> <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(isset($_POST['action']) && $_POST['action']==='del_domain' && !empty($_POST['domain'])){
if($error=check_csrf_error()){ if($error=check_csrf_error()){
die($error); die($error);
} ?> }
<!DOCTYPE html><html><head> print_header('Delete domain');
<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>
<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> <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']; ?>"> <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']); ?>"> <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(); enqueue_instance_reload();
} }
} }
?> print_header('Dashboard', '#custom_onion:not(checked)+#private_key{display:none;}#custom_onion:checked+#private_key{display:block;}td{padding:5px}meter{width:200px}');
<!DOCTYPE html><html><head> dashboard_menu($user, 'home.php');
<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
if(!empty($msg)){ if(!empty($msg)){
echo $msg; echo $msg;
} }

View File

@ -2,16 +2,10 @@
require('../common.php'); require('../common.php');
header('Content-Type: text/html; charset=UTF-8'); header('Content-Type: text/html; charset=UTF-8');
header('X-Accel-Expires: 60'); 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> <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> <p>Here you can get yourself a free web hosting account on my server.</p>
<h2>What you get:</h2> <h2>What you get:</h2>
<ul> <ul>
@ -29,8 +23,9 @@ header('X-Accel-Expires: 60');
<li>Webmail and IMAP, POP3 and SMTP access to your mail account</li> <li>Webmail and IMAP, POP3 and SMTP access to your mail account</li>
<li>Your own .onion domains</li> <li>Your own .onion domains</li>
<li>Clearnet domains or a free subdomain of danwin1210.me</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>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> <li>More to come…</li>
</ul> </ul>
<h2>Rules</h2> <h2>Rules</h2>

View File

@ -3,19 +3,11 @@ require_once('../common.php');
header('Content-Type: text/html; charset=UTF-8'); header('Content-Type: text/html; charset=UTF-8');
header('X-Accel-Expires: 60'); header('X-Accel-Expires: 60');
$db = get_db_instance(); $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> <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 <?php
main_menu('list.php');
$stmt=$db->query('SELECT COUNT(*) FROM users WHERE public=1;'); $stmt=$db->query('SELECT COUNT(*) FROM users WHERE public=1;');
$count=$stmt->fetch(PDO::FETCH_NUM); $count=$stmt->fetch(PDO::FETCH_NUM);
$stmt=$db->query('SELECT COUNT(*) FROM users WHERE public=0;'); $stmt=$db->query('SELECT COUNT(*) FROM users WHERE public=0;');

View File

@ -8,7 +8,25 @@ if(!empty($_SESSION['hosting_username']) && empty($_SESSION['2fa_code'])){
} }
$msg=''; $msg='';
$username=''; $username='';
$pgp_key='';
$tfa=0;
if(!empty($_SESSION['hosting_username'])){
$tfa = $_SESSION['tfa'];
$pgp_key = $_SESSION['pgp_key'];
}
if($_SERVER['REQUEST_METHOD']==='POST'){ 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(); $db = get_db_instance();
$ok=true; $ok=true;
if($error=check_captcha_error()){ 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>'; $msg.='<p style="color:red;">Error: username may not be empty.</p>';
$ok=false; $ok=false;
}else{ }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']]); $stmt->execute([$_POST['username']]);
$tmp=[]; $tmp=[];
if(($tmp=$stmt->fetch(PDO::FETCH_NUM))===false && preg_match('/^([2-7a-z]{16}).onion$/', $_POST['username'], $match)){ if(($tmp=$stmt->fetch(PDO::FETCH_ASSOC))===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=?;'); $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]]); $stmt->execute([$match[1]]);
$tmp=$stmt->fetch(PDO::FETCH_NUM); $tmp=$stmt->fetch(PDO::FETCH_ASSOC);
} }
if($tmp){ if($tmp){
$username=$tmp[0]; $username=$tmp['username'];
$password=$tmp[1]; $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=$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($tmp=$stmt->fetch(PDO::FETCH_NUM)){
if(REQUIRE_APPROVAL && !$tmp[0]){ if(REQUIRE_APPROVAL && !$tmp[0]){
$msg.='<p style="color:red;">Error: Your account is pending admin approval. Please try again later.</p>'; $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){ if($ok){
$_SESSION['hosting_username']=$username; $_SESSION['hosting_username']=$username;
$_SESSION['csrf_token']=sha1(uniqid()); $_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(); session_write_close();
header('Location: home.php'); header('Location: home.php');
exit; 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> <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
<?php echo $msg; ?> main_menu('login.php');
echo $msg;
?>
<form method="POST" action="login.php"><table> <form method="POST" action="login.php"><table>
<tr><td>Username</td><td><input type="text" name="username" value="<?php <tr><td>Username</td><td><input type="text" name="username" value="<?php
if(isset($_POST['username'])){ if(isset($_POST['username'])){

View File

@ -36,13 +36,7 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
} }
} }
header('Content-Type: text/html; charset=UTF-8'); header('Content-Type: text/html; charset=UTF-8');
echo '<!DOCTYPE html><html><head>'; print_header('Change password');
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>';
echo $msg; echo $msg;
echo '<form method="POST" action="password.php"><input type="hidden" name="csrf_token" value="'.$_SESSION['csrf_token'].'"><table>'; 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">'; echo '<tr><td>Reset type:</td><td><select name="type">';

80
var/www/html/pgp.php Normal file
View 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>

View File

@ -6,18 +6,11 @@ if(!empty($_SESSION['hosting_username'])){
header('Location: home.php'); header('Location: home.php');
exit; 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> <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 <?php
main_menu('register.php');
if($_SERVER['REQUEST_METHOD']==='POST'){ if($_SERVER['REQUEST_METHOD']==='POST'){
$db = get_db_instance(); $db = get_db_instance();
$ok=true; $ok=true;

View File

@ -8,15 +8,8 @@ $user=check_login();
use chillerlan\QRCode\QRCode; use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions; use chillerlan\QRCode\QROptions;
header('Content-Type: text/html; charset=UTF-8'); 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> <h1>Hosting - Upgrade account</h1>
<?php <?php
$rates = coinpayments_get_rates(); $rates = coinpayments_get_rates();

View File

@ -23,7 +23,7 @@ if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';"))
//create tables //create tables
$db->exec('CREATE TABLE captcha (id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, time int(11) NOT NULL, code char(5) COLLATE latin1_bin NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;'); $db->exec('CREATE TABLE captcha (id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, time int(11) NOT NULL, code char(5) COLLATE latin1_bin NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;');
$db->exec("CREATE TABLE 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 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 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 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;'); $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("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;'); $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=$db->prepare("UPDATE settings SET value=? WHERE setting='version';");
$stmt->execute([DBVERSION]); $stmt->execute([DBVERSION]);
} }