Added PGP Two Factor Authentication (2FA)
This commit is contained in:
@ -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,64 +8,117 @@ 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'){
|
||||
$db = get_db_instance();
|
||||
$ok=true;
|
||||
if($error=check_captcha_error()){
|
||||
$msg.="<p style=\"color:red;\">$error</p>";
|
||||
$ok=false;
|
||||
}elseif(!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, id 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=?;');
|
||||
$stmt->execute([$match[1]]);
|
||||
$tmp=$stmt->fetch(PDO::FETCH_NUM);
|
||||
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>';
|
||||
}
|
||||
if($tmp){
|
||||
$username=$tmp[0];
|
||||
$password=$tmp[1];
|
||||
$stmt=$db->prepare('SELECT new_account.approved FROM new_account INNER JOIN users ON (users.id=new_account.user_id) WHERE users.id=?;');
|
||||
$stmt->execute([$tmp[2]]);
|
||||
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>';
|
||||
}else{
|
||||
$msg.='<p style="color:red;">Error: Your account is pending creation. Please try again in a minute.</p>';
|
||||
} else {
|
||||
$db = get_db_instance();
|
||||
$ok=true;
|
||||
if($error=check_captcha_error()){
|
||||
$msg.="<p style=\"color:red;\">$error</p>";
|
||||
$ok=false;
|
||||
}elseif(!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, id, tfa, pgp_key FROM users WHERE username=?;');
|
||||
$stmt->execute([$_POST['username']]);
|
||||
$tmp=[];
|
||||
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_ASSOC);
|
||||
}
|
||||
if($tmp){
|
||||
$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['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>';
|
||||
}else{
|
||||
$msg.='<p style="color:red;">Error: Your account is pending creation. Please try again in a minute.</p>';
|
||||
}
|
||||
$ok=false;
|
||||
}elseif(!isset($_POST['pass']) || !password_verify($_POST['pass'], $password)){
|
||||
$msg.='<p style="color:red;">Error: wrong password.</p>';
|
||||
$ok=false;
|
||||
}
|
||||
$ok=false;
|
||||
}elseif(!isset($_POST['pass']) || !password_verify($_POST['pass'], $password)){
|
||||
$msg.='<p style="color:red;">Error: wrong password.</p>';
|
||||
}else{
|
||||
$msg.='<p style="color:red;">Error: username was not found. If you forgot it, you can enter youraccount.onion instead.</p>';
|
||||
$ok=false;
|
||||
}
|
||||
}else{
|
||||
$msg.='<p style="color:red;">Error: username was not found. If you forgot it, you can enter youraccount.onion instead.</p>';
|
||||
$ok=false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if($ok){
|
||||
$_SESSION['hosting_username']=$username;
|
||||
$_SESSION['csrf_token']=sha1(uniqid());
|
||||
session_write_close();
|
||||
header('Location: home.php');
|
||||
}
|
||||
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();
|
||||
|
Reference in New Issue
Block a user