Allow adding and removing onion domains
This commit is contained in:
@ -106,6 +106,7 @@ server {
|
|||||||
}
|
}
|
||||||
';
|
';
|
||||||
const MAX_NUM_USER_DBS = 5; //maximum number of databases a user may have
|
const MAX_NUM_USER_DBS = 5; //maximum number of databases a user may have
|
||||||
|
const MAX_NUM_USER_ONIONS = 3; //maximum number of onion domains a user may have
|
||||||
|
|
||||||
function get_onion_v2($pkey) : string {
|
function get_onion_v2($pkey) : string {
|
||||||
$keyData = openssl_pkey_get_details($pkey);
|
$keyData = openssl_pkey_get_details($pkey);
|
||||||
@ -523,13 +524,23 @@ function del_user_db(PDO $db, int $user_id, string $mysql_db) {
|
|||||||
$stmt = $db->prepare('SELECT null FROM mysql_databases WHERE user_id = ? AND mysql_database = ?;');
|
$stmt = $db->prepare('SELECT null FROM mysql_databases WHERE user_id = ? AND mysql_database = ?;');
|
||||||
$stmt->execute([$user_id, $mysql_db]);
|
$stmt->execute([$user_id, $mysql_db]);
|
||||||
if($stmt->fetch()){
|
if($stmt->fetch()){
|
||||||
$db->exec('REVOKE ALL PRIVILEGES ON `'.preg_replace('/[^a-z0-9]/i', '', $mysql_db)."`.* FROM '".preg_replace('/[^a-z0-9]/i', '', $user['mysql_user'])."'@'%';");
|
$stmt = $db->prepare('REVOKE ALL PRIVILEGES ON `'.preg_replace('/[^a-z0-9]/i', '', $mysql_db)."`.* FROM ?@'%';");
|
||||||
|
$stmt->execute([$user['mysql_user']]);
|
||||||
$db->exec('DROP DATABASE IF EXISTS `'.preg_replace('/[^a-z0-9]/i', '', $mysql_db).'`;');
|
$db->exec('DROP DATABASE IF EXISTS `'.preg_replace('/[^a-z0-9]/i', '', $mysql_db).'`;');
|
||||||
$stmt = $db->prepare('DELETE FROM mysql_databases WHERE user_id = ? AND mysql_database = ?;');
|
$stmt = $db->prepare('DELETE FROM mysql_databases WHERE user_id = ? AND mysql_database = ?;');
|
||||||
$stmt->execute([$user_id, $mysql_db]);
|
$stmt->execute([$user_id, $mysql_db]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function del_user_onion(PDO $db, int $user_id, string $onion) {
|
||||||
|
$stmt = $db->prepare('SELECT null FROM onions WHERE user_id = ? AND onion = ? AND enabled IN (0, 1);');
|
||||||
|
$stmt->execute([$user_id, $onion]);
|
||||||
|
if($stmt->fetch()){
|
||||||
|
$stmt = $db->prepare("UPDATE onions SET enabled='-1' WHERE user_id = ? AND onion = ?;");
|
||||||
|
$stmt->execute([$user_id, $onion]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function check_csrf_error(){
|
function check_csrf_error(){
|
||||||
if(empty($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']){
|
if(empty($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']){
|
||||||
return 'Invalid CSRF token, please try again.';
|
return 'Invalid CSRF token, please try again.';
|
||||||
|
@ -38,6 +38,78 @@ if(isset($_POST['action']) && $_POST['action']==='del_db_2' && !empty($_POST['db
|
|||||||
}
|
}
|
||||||
del_user_db($db, $user['id'], $_POST['db']);
|
del_user_db($db, $user['id'], $_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>Daniel's Hosting - 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">
|
||||||
|
</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>
|
||||||
|
<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']); ?>">
|
||||||
|
<button type="submit" name="action" value="del_onion_2">Yes, delete</button>
|
||||||
|
</form>
|
||||||
|
<p><a href="home.php">No, don't delete.</a></p>
|
||||||
|
</body></html><?php
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
if(isset($_POST['action']) && $_POST['action']==='add_onion'){
|
||||||
|
if($error=check_csrf_error()){
|
||||||
|
die($error);
|
||||||
|
}
|
||||||
|
$ok = true;
|
||||||
|
if(isset($_REQUEST['onion_type']) && $_REQUEST['onion_type']==='custom' && isset($_REQUEST['private_key']) && !empty(trim($_REQUEST['private_key']))){
|
||||||
|
$priv_key = trim($_REQUEST['private_key']);
|
||||||
|
$data = private_key_to_onion($priv_key);
|
||||||
|
$onion = $data['onion'];
|
||||||
|
$onion_version = $data['version'];
|
||||||
|
if(!$data['ok']){
|
||||||
|
$msg = "<p style=\"color:red;\">$data[message]</p>";
|
||||||
|
$ok = false;
|
||||||
|
} else {
|
||||||
|
$check=$db->prepare('SELECT null FROM onions WHERE onion=?;');
|
||||||
|
$check->execute([$onion]);
|
||||||
|
if($check->fetch(PDO::FETCH_NUM)){
|
||||||
|
$msg = '<p style="color:red;">Error onion already exists.</p>';
|
||||||
|
$ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
$onion_version = 3;
|
||||||
|
if(isset($_REQUEST['onion_type']) && in_array($_REQUEST['onion_type'], [2, 3])){
|
||||||
|
$onion_version = $_REQUEST['onion_type'];
|
||||||
|
}
|
||||||
|
$check=$db->prepare('SELECT null FROM onions WHERE onion=?;');
|
||||||
|
do{
|
||||||
|
$data = generate_new_onion($onion_version);
|
||||||
|
$priv_key = $data['priv_key'];
|
||||||
|
$onion = $data['onion'];
|
||||||
|
$onion_version = $data['version'];
|
||||||
|
$check->execute([$onion]);
|
||||||
|
}while($check->fetch(PDO::FETCH_NUM));
|
||||||
|
}
|
||||||
|
$priv_key=trim(str_replace("\r", '', $priv_key));
|
||||||
|
$stmt = $db->prepare('SELECT COUNT(*) FROM onions WHERE user_id = ?;');
|
||||||
|
$stmt->execute([$user['id']]);
|
||||||
|
$count = $stmt->fetch(PDO::FETCH_NUM);
|
||||||
|
if($count[0]>=MAX_NUM_USER_ONIONS) {
|
||||||
|
$ok = false;
|
||||||
|
}
|
||||||
|
if($ok){
|
||||||
|
$stmt=$db->prepare('INSERT INTO onions (user_id, onion, private_key, version, enabled) VALUES (?, ?, ?, ?, 2);');
|
||||||
|
$stmt->execute([$user['id'], $onion, $priv_key, $onion_version]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isset($_POST['action']) && $_POST['action']==='del_onion_2' && !empty($_POST['onion'])){
|
||||||
|
if($error=check_csrf_error()){
|
||||||
|
die($error);
|
||||||
|
}
|
||||||
|
del_user_onion($db, $user['id'], $_POST['onion']);
|
||||||
|
}
|
||||||
if(isset($_REQUEST['action']) && isset($_REQUEST['onion']) && $_REQUEST['action']==='edit'){
|
if(isset($_REQUEST['action']) && isset($_REQUEST['onion']) && $_REQUEST['action']==='edit'){
|
||||||
if($error=check_csrf_error()){
|
if($error=check_csrf_error()){
|
||||||
die($error);
|
die($error);
|
||||||
@ -74,15 +146,21 @@ echo '<title>Daniel\'s Hosting - Dashboard</title>';
|
|||||||
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
|
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
|
||||||
echo '<meta name="author" content="Daniel Winzen">';
|
echo '<meta name="author" content="Daniel Winzen">';
|
||||||
echo '<meta name="viewport" content="width=device-width, initial-scale=1">';
|
echo '<meta name="viewport" content="width=device-width, initial-scale=1">';
|
||||||
|
echo '<style type="text/css">#custom_onion:not(checked)+#private_key{display:none;}#custom_onion:checked+#private_key{display:block;}</style>';
|
||||||
echo '</head><body>';
|
echo '</head><body>';
|
||||||
echo "<p>Logged in as $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>";
|
echo "<p>Logged in as $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>";
|
||||||
|
if(!empty($msg)){
|
||||||
|
echo $msg;
|
||||||
|
}
|
||||||
echo "<p>Enter system account password to check your $user[system_account]@" . ADDRESS . " mail:</td><td><form action=\"squirrelmail/src/redirect.php\" method=\"post\" target=\"_blank\"><input type=\"hidden\" name=\"login_username\" value=\"$user[system_account]\"><input type=\"password\" name=\"secretkey\"><input type=\"submit\" value=\"Login to webmail\"></form></p>";
|
echo "<p>Enter system account password to check your $user[system_account]@" . ADDRESS . " mail:</td><td><form action=\"squirrelmail/src/redirect.php\" method=\"post\" target=\"_blank\"><input type=\"hidden\" name=\"login_username\" value=\"$user[system_account]\"><input type=\"password\" name=\"secretkey\"><input type=\"submit\" value=\"Login to webmail\"></form></p>";
|
||||||
echo '<h3>Domains</h3>';
|
echo '<h3>Domains</h3>';
|
||||||
echo '<table border="1">';
|
echo '<table border="1">';
|
||||||
echo '<tr><th>Onion</th><th>Private key</th><th>Enabled</th><th>SMTP enabled</th><th>Nr. of intros</th><th>Max streams per rend circuit</th><th>Save</th></tr>';
|
echo '<tr><th>Onion</th><th>Private key</th><th>Enabled</th><th>SMTP enabled</th><th>Nr. of intros</th><th>Max streams per rend circuit</th><th>Action</th></tr>';
|
||||||
$stmt=$db->prepare('SELECT onion, private_key, enabled, enable_smtp, num_intros, max_streams FROM onions WHERE user_id = ?;');
|
$stmt=$db->prepare('SELECT onion, private_key, enabled, enable_smtp, num_intros, max_streams FROM onions WHERE user_id = ?;');
|
||||||
$stmt->execute([$user['id']]);
|
$stmt->execute([$user['id']]);
|
||||||
|
$count_onions = 0;
|
||||||
while($onion=$stmt->fetch(PDO::FETCH_ASSOC)){
|
while($onion=$stmt->fetch(PDO::FETCH_ASSOC)){
|
||||||
|
++$count_onions;
|
||||||
echo "<form action=\"home.php\" method=\"post\"><input type=\"hidden\" name=\"csrf_token\" value=\"$_SESSION[csrf_token]\"><input type=\"hidden\" name=\"onion\" value=\"$onion[onion]\"><tr><td><a href=\"http://$onion[onion].onion\" target=\"_blank\">$onion[onion].onion</a></td><td>";
|
echo "<form action=\"home.php\" method=\"post\"><input type=\"hidden\" name=\"csrf_token\" value=\"$_SESSION[csrf_token]\"><input type=\"hidden\" name=\"onion\" value=\"$onion[onion]\"><tr><td><a href=\"http://$onion[onion].onion\" target=\"_blank\">$onion[onion].onion</a></td><td>";
|
||||||
if(isset($_REQUEST['show_priv'])){
|
if(isset($_REQUEST['show_priv'])){
|
||||||
echo "<pre>$onion[private_key]</pre>";
|
echo "<pre>$onion[private_key]</pre>";
|
||||||
@ -98,12 +176,30 @@ while($onion=$stmt->fetch(PDO::FETCH_ASSOC)){
|
|||||||
echo '<td><input type="number" name="num_intros" min="3" max="20" value="'.$onion['num_intros'].'"></td>';
|
echo '<td><input type="number" name="num_intros" min="3" max="20" value="'.$onion['num_intros'].'"></td>';
|
||||||
echo '<td><input type="number" name="max_streams" min="0" max="65535" value="'.$onion['max_streams'].'"></td>';
|
echo '<td><input type="number" name="max_streams" min="0" max="65535" value="'.$onion['max_streams'].'"></td>';
|
||||||
if(in_array($onion['enabled'], [0, 1])){
|
if(in_array($onion['enabled'], [0, 1])){
|
||||||
echo '<td><button type="submit" name="action" value="edit">Save</button></td>';
|
echo '<td><button type="submit" name="action" value="edit">Save</button>';
|
||||||
|
echo '<button type="submit" name="action" value="del_onion">Delete</button></td>';
|
||||||
}else{
|
}else{
|
||||||
echo '<td>Unavailable</td>';
|
echo '<td>Unavailable</td>';
|
||||||
}
|
}
|
||||||
echo '</tr></form>';
|
echo '</tr></form>';
|
||||||
}
|
}
|
||||||
|
if($count_onions<MAX_NUM_USER_ONIONS){
|
||||||
|
echo "<form action=\"home.php\" method=\"post\"><input type=\"hidden\" name=\"csrf_token\" value=\"$_SESSION[csrf_token]\">";
|
||||||
|
echo '<tr><td colspan="6">Add additional hidden service:<br>';
|
||||||
|
echo '<label><input type="radio" name="onion_type" value="3"';
|
||||||
|
echo (!isset($_POST['onion_type']) || isset($_POST['onion_type']) && $_POST['onion_type']==3) ? ' checked' : '';
|
||||||
|
echo '>Random v3 Address</label>';
|
||||||
|
echo '<label><input type="radio" name="onion_type" value="2"';
|
||||||
|
echo isset($_POST['onion_type']) && $_POST['onion_type']==2 ? ' checked' : '';
|
||||||
|
echo '>Random v2 Address</label>';
|
||||||
|
echo '<label><input id="custom_onion" type="radio" name="onion_type" value="custom"';
|
||||||
|
echo isset($_POST['onion_type']) && $_POST['onion_type']==='custom' ? ' checked' : '';
|
||||||
|
echo '>Custom private key';
|
||||||
|
echo '<textarea id="private_key" name="private_key" rows="5" cols="28">';
|
||||||
|
echo isset($_REQUEST['private_key']) ? htmlspecialchars($_REQUEST['private_key']) : '';
|
||||||
|
echo '</textarea>';
|
||||||
|
echo '</label></td><td><button type="submit" name="action" value="add_onion">Add onion</button></td></tr></form>';
|
||||||
|
}
|
||||||
echo '</table>';
|
echo '</table>';
|
||||||
echo '<h3>MySQL Database</h3>';
|
echo '<h3>MySQL Database</h3>';
|
||||||
echo '<table border="1">';
|
echo '<table border="1">';
|
||||||
|
Reference in New Issue
Block a user