del-http-onion.php + query()

This commit is contained in:
Miraty 2022-06-11 23:42:48 +02:00
parent 6b602eb43f
commit d9440231ac
16 changed files with 164 additions and 114 deletions

View file

@ -6,6 +6,10 @@ define("SERVICE", substr(dirname($_SERVER['PHP_SELF']), strlen(CONF['common']['p
define("PAGE", basename($_SERVER['PHP_SELF'], '.php')); define("PAGE", basename($_SERVER['PHP_SELF'], '.php'));
define("DB_PATH", CONF['common']['root_path'] . "/db/niver.db"); // Niver's SQLite database define("DB_PATH", CONF['common']['root_path'] . "/db/niver.db"); // Niver's SQLite database
define("PLACEHOLDER_DOMAIN", "example"); // From RFC2606: Reserved Top Level DNS Names > 2. TLDs for Testing, & Documentation Examples
define("PLACEHOLDER_IPV6", "2001:db8::3"); // From RFC3849: IPv6 Address Prefix Reserved for Documentation
define("PLACEHOLDER_IPV4", "203.0.113.42"); // From RFC5737: IPv4 Address Blocks Reserved for Documentation
// Page titles definition // Page titles definition
require "pages.php"; require "pages.php";

View file

@ -92,12 +92,18 @@ switch (SERVICE) {
case "mkdir": case "mkdir":
$page['title'] = "Créer un dossier de site"; $page['title'] = "Créer un dossier de site";
break; break;
case "http-onion": case "add-http-onion":
$page['title'] = "Accès HTTP par service Onion"; $page['title'] = "Ajouter un accès HTTP par Onion";
break; break;
case "https-domain": case "add-http-dns":
$page['title'] = "Accès HTTP par DNS et TLS"; $page['title'] = "Ajouter un accès HTTP par DNS+TLS";
break; break;
case "del-http-onion":
$page['title'] = "Retirer un accès HTTP par Onion";
break;
case "del-http-dns":
$page['title'] = "Retirer un accès HTTP par DNS+TLS";
break;
case "le": case "le":
$page['title'] = "Installer un certificat Let's Encrypt"; $page['title'] = "Installer un certificat Let's Encrypt";
break; break;

View file

@ -76,8 +76,8 @@ function changePassword($username, $password) {
$stmt = $db->prepare("UPDATE users SET password = :password WHERE username = :username"); $stmt = $db->prepare("UPDATE users SET password = :password WHERE username = :username");
$stmt->bindParam(':username', $username); $stmt->bindValue(':username', $username);
$stmt->bindParam(':password', $password); $stmt->bindValue(':password', $password);
$stmt->execute(); $stmt->execute();
} }

View file

@ -22,3 +22,33 @@ function switchToFormProcess($requireLogin = true) {
if ($requireLogin AND !isset($_SESSION['username'])) if ($requireLogin AND !isset($_SESSION['username']))
userError("Vous devez être connecté·e pour effectuer cette action."); userError("Vous devez être connecté·e pour effectuer cette action.");
} }
function query($action, $table, $conditions = [], $column = NULL) {
$query = match ($action) {
'select' => 'SELECT *',
'delete' => 'DELETE',
};
$query .= " FROM $table";
foreach ($conditions as $key => $val) {
if ($key === array_key_first($conditions))
$query .= " WHERE $key = :$key";
else
$query .= " AND $key = :$key";
}
$db = new PDO('sqlite:' . DB_PATH);
$op = $db->prepare($query);
foreach ($conditions as $key => $val)
$op->bindValue(":$key", $val);
$op->execute();
if (isset($column))
return array_column($op->fetchAll(PDO::FETCH_ASSOC), $column);
return $op->fetchAll(PDO::FETCH_ASSOC);
}

View file

@ -1,9 +1,5 @@
<?php <?php
define("PLACEHOLDER_DOMAIN", "example"); // From RFC2606: Reserved Top Level DNS Names > 2. TLDs for Testing, & Documentation Examples
define("PLACEHOLDER_IPV6", "2001:db8::3"); // From RFC3849: IPv6 Address Prefix Reserved for Documentation
define("PLACEHOLDER_IPV4", "203.0.113.42"); // From RFC5737: IPv4 Address Blocks Reserved for Documentation
function knotcExec($suffix, $cmd) { function knotcExec($suffix, $cmd) {
$action = checkAction($_POST['action']); $action = checkAction($_POST['action']);

View file

@ -8,7 +8,7 @@ function checkDomainFormat($domain) {
function listFsDirs($username) { function listFsDirs($username) {
$absoluteDirs = glob(CONF['ht']['ht_path'] . "/" . $username . "/*/", GLOB_ONLYDIR); $absoluteDirs = glob(CONF['ht']['ht_path'] . "/" . $username . "/*/", GLOB_ONLYDIR);
$dirs = array(); $dirs = [];
foreach ($absoluteDirs as $absoluteDir) foreach ($absoluteDirs as $absoluteDir)
if (preg_match("/^[a-z0-9-]{1,32}$/", basename($absoluteDir))) if (preg_match("/^[a-z0-9-]{1,32}$/", basename($absoluteDir)))
array_push($dirs, basename($absoluteDir)); array_push($dirs, basename($absoluteDir));
@ -20,69 +20,30 @@ function addSite($username, $siteDir, $domain, $domainType, $protocol) {
$op = $db->prepare("INSERT INTO sites(username, site_dir, domain, domain_type, protocol, creation_date, le_enabled) VALUES(:username, :site_dir, :domain, :domain_type, :protocol, :creation_date, :le_enabled)"); $op = $db->prepare("INSERT INTO sites(username, site_dir, domain, domain_type, protocol, creation_date, le_enabled) VALUES(:username, :site_dir, :domain, :domain_type, :protocol, :creation_date, :le_enabled)");
$time = date("Y-m-d H:i:s");
if ($domainType === "dns" AND $protocol === "http") if ($domainType === "dns" AND $protocol === "http")
$le_enabled = 0; $le_enabled = 0;
else else
$le_enabled = NULL; $le_enabled = NULL;
$op->bindParam(':username', $username); $op->bindValue(':username', $username);
$op->bindParam(':site_dir', $siteDir); $op->bindValue(':site_dir', $siteDir);
$op->bindParam(':domain', $domain); $op->bindValue(':domain', $domain);
$op->bindParam(':domain_type', $domainType); $op->bindValue(':domain_type', $domainType);
$op->bindParam(':protocol', $protocol); $op->bindValue(':protocol', $protocol);
$op->bindParam(':creation_date', $time); $op->bindValue(':creation_date', date("Y-m-d H:i:s"));
$op->bindParam(':le_enabled', $le_enabled); $op->bindValue(':le_enabled', $le_enabled);
$op->execute(); $op->execute();
} }
function listDbDirs($username, $domainType, $protocol) {
$db = new PDO('sqlite:' . DB_PATH);
$op = $db->prepare('SELECT site_dir FROM sites WHERE username = :username AND domain_type = :domain_type AND protocol = :protocol');
$op->bindParam(':username', $username);
$op->bindParam(':domain_type', $domainType);
$op->bindParam(':protocol', $protocol);
$op->execute();
return array_column($op->fetchAll(PDO::FETCH_ASSOC), 'site_dir');
}
function dirsStatuses($username, $domainType, $protocol) { function dirsStatuses($username, $domainType, $protocol) {
$dirs = array(); $dbDirs = query('select', 'sites', [
$fsDirs = listFsDirs($username); 'username' => $username,
$dbUsedDirs = listDbDirs($username, $domainType, $protocol); 'domain_type' => $domainType,
foreach ($fsDirs as $fsDir) 'protocol' => $protocol,
$dirs[$fsDir] = ($dbUsedDirs AND in_array($fsDir, $dbUsedDirs)); ], 'site_dir');
$dirs = [];
foreach (listFsDirs($username) as $fsDir)
$dirs[$fsDir] = in_array($fsDir, $dbDirs);
return $dirs; return $dirs;
} }
function selectSites($username, $domainType, $protocol, $onlyLeAvailable) {
$db = new PDO('sqlite:' . DB_PATH);
$query = "SELECT site_dir,domain FROM sites WHERE username = :username AND domain_type = :domain_type AND protocol = :protocol";
if ($onlyLeAvailable === true)
$query = $query . " AND le_enabled = 0";
$op = $db->prepare($query);
$op->bindParam(':username', $username);
$op->bindParam(':domain_type', $domainType);
$op->bindParam(':protocol', $protocol);
$op->execute();
$i = 0;
$entry = $op->fetch();
while (isset($entry['site_dir'])) {
$result[$i]["siteDir"] = $entry['site_dir'];
$result[$i]["domain"] = $entry['domain'];
$i++;
$entry = $op->fetch();
}
if (isset($result))
return $result;
else
return false;
}

View file

@ -27,35 +27,12 @@ function nsParseCommonRequirements() {
} }
function nsListUserZones($username) { function nsListUserZones($username) {
$db = new PDO('sqlite:' . DB_PATH); return query('select', 'zones', ['username' => $username], 'zone');
$usernameArray[0] = $username;
$op = $db->prepare('SELECT zone FROM zones WHERE username = ?');
$op->execute($usernameArray);
$zones = array();
foreach ($op->fetchAll() as $zone)
array_push($zones, $zone['zone']);
return $zones;
} }
function nsCheckZonePossession($submittedZone) { function nsCheckZonePossession($submittedZone) {
checkAbsoluteDomainFormat($submittedZone); checkAbsoluteDomainFormat($submittedZone);
$db = new PDO('sqlite:' . DB_PATH); if (!in_array($submittedZone, query('select', 'zones', ['username' => $_SESSION['username']], 'zone'), true))
$username[0] = $_SESSION['username']; userError("You don't own this zone on the nameserver.");
$op = $db->prepare('SELECT zone FROM zones WHERE username = ?');
$op->execute($username);
$dbZone = $op->fetch()['zone'];
while ($dbZone != NULL) {
if ($dbZone === $submittedZone) return;
$dbZone = $op->fetch()['zone'];
}
// If there is no entry in the database for the user matching the submitted zone
userError("You don't own this zone on the nameserver.");
} }

View file

@ -12,7 +12,7 @@ function regListUserDomains($username) {
$op = $db->prepare('SELECT domain FROM registry WHERE username = ?'); $op = $db->prepare('SELECT domain FROM registry WHERE username = ?');
$op->execute($usernameArray); $op->execute($usernameArray);
$domains = array(); $domains = [];
foreach ($op->fetchAll() as $domain) foreach ($op->fetchAll() as $domain)
array_push($domains, $domain['domain']); array_push($domains, $domain['domain']);

View file

@ -40,17 +40,13 @@ exec(CONF['ht']['sudo_path'] . " " . CONF['ht']['chgrp_path'] . " " . CONF['ht']
if ($code !== 0) if ($code !== 0)
serverError("Can't change user directory group."); serverError("Can't change user directory group.");
$password = hashPassword($_POST['password']);
$db = new PDO('sqlite:' . DB_PATH); $db = new PDO('sqlite:' . DB_PATH);
$stmt = $db->prepare("INSERT INTO users(username, password, registration_date) VALUES(:username, :password, :registration_date)"); $stmt = $db->prepare("INSERT INTO users(username, password, registration_date) VALUES(:username, :password, :registration_date)");
$time = date("Y-m-d H:i:s"); $stmt->bindValue(':username', $_POST['username']);
$stmt->bindValue(':password', hashPassword($_POST['password']));
$stmt->bindParam(':username', $_POST['username']); $stmt->bindValue(':registration_date', date("Y-m-d H:i:s"));
$stmt->bindParam(':password', $password);
$stmt->bindParam(':registration_date', $time);
$stmt->execute(); $stmt->execute();

View file

@ -0,0 +1,74 @@
<?php require "../../common/html.php"; ?>
<p>
Ajouter un accès en .onion sur un dossier
</p>
<form method="post">
<label for="dir">Dossier ciblé</label><br>
<select required="" name="dir" id="dir">
<option value="" disabled="" selected="">---</option>
<?php
if (isset($_SESSION['username'])) {
$dirsStatuses = dirsStatuses($_SESSION['username'], "onion", "http");
foreach ($dirsStatuses as $dir => $alreadyEnabled) {
$disabled = $alreadyEnabled ? "" : "disabled='' ";
echo " <option " . $disabled . "value='" . $dir . "'>" . $dir . "</option>\n";
}
}
?>
</select>
<br>
<input value="Valider" type="submit">
</form>
<?php
switchToFormProcess();
if ($dirsStatuses[$_POST['dir']] !== true)
userError("Wrong value for <code>dir</code>.");
// Delete Tor config
$torConf = file_get_contents(CONF['ht']['tor_config_path']);
if ($torConf === false)
serverError("Failed to read current Tor configuration.");
$torConf = str_replace("HiddenServiceDir " . CONF['ht']['tor_keys_path'] . "/" . $_POST['dir'] . "/
HiddenServicePort 80 [::1]:" . CONF['ht']['internal_onion_http_port'] . "
", "", $torConf);
if (file_put_contents(CONF['ht']['tor_config_path'], $torConf) === false)
serverError("Failed to write new Tor configuration.");
// Reload Tor
exec(CONF['ht']['sudo_path'] . " " . CONF['ht']['systemctl_path'] . " reload " . CONF['ht']['tor_service'], $output, $code);
if ($code !== 0)
serverError("Failed to reload Tor.");
// Delete Nginx config
$onion = query('select', 'sites', [
'username' => $_SESSION['username'],
'domain_type' => 'onion',
'protocol' => 'http',
'site_dir' => $_POST['dir'],
], 'domain')[0];
if (unlink(CONF['ht']['nginx_config_path'] . "/" . $onion . ".conf") !== true)
serverError("Failed to delete Nginx configuration.");
// Reload Nginx
exec(CONF['ht']['sudo_path'] . " " . CONF['ht']['systemctl_path'] . " reload nginx", result_code: $code);
if ($code !== 0)
serverError("Failed to reload Nginx.");
// Delete from database
query('delete', 'sites', [
'username' => $_SESSION['username'],
'domain_type' => 'onion',
'protocol' => 'http',
'site_dir' => $_POST['dir'],
]);
success("Accès retiré avec succès.");

View file

@ -53,13 +53,21 @@
</dl> </dl>
<dl> <dl>
<dt><a href="http-onion">Accès HTTP par service Onion</a></dt> <dt><a href="add-http-onion">Ajouter un accès HTTP par Onion</a></dt>
<dd> <dd>
Un site HTML, accessible par Tor, avec une adresse en .onion Ajouter un accès HTTP par service Onion sur un sous-dossier de l'espace SFTP
</dd> </dd>
<dt><a href="https-domain">Accès HTTP par DNS et TLS</a></dt> <dt><a href="add-http-dns">Ajouter un accès HTTP par DNS+TLS</a></dt>
<dd> <dd>
Un site HTML, accessible directement, par un nom de domaine Ajouter un accès HTTP par DNS et TLS sur un sous-dossier de l'espace SFTP
</dd>
<dt><a href="del-http-onion">Retirer un accès HTTP par Onion</a></dt>
<dd>
Retirer un accès HTTP par service Onion d'un sous-dossier de l'espace SFTP
</dd>
<dt><a href="del-http-dns">Retirer un accès HTTP par DNS+TLS</a></dt>
<dd>
Retirer un accès HTTP par DNS et TLS d'un sous-dossier de l'espace SFTP
</dd> </dd>
<dt><a href="le">Let's Encrypt</a></dt> <dt><a href="le">Let's Encrypt</a></dt>
<dd> <dd>

View file

@ -16,8 +16,8 @@ if (isset($_POST['domain']) AND isset($_SESSION['username'])) {
$db = new PDO('sqlite:' . DB_PATH); $db = new PDO('sqlite:' . DB_PATH);
$stmt = $db->prepare("INSERT INTO zones(zone, username) VALUES(:zone, :username)"); $stmt = $db->prepare("INSERT INTO zones(zone, username) VALUES(:zone, :username)");
$stmt->bindParam(':zone', $_POST['domain']); $stmt->bindValue(':zone', $_POST['domain']);
$stmt->bindParam(':username', $_SESSION['username']); $stmt->bindValue(':username', $_SESSION['username']);
$stmt->execute(); $stmt->execute();
@ -79,8 +79,8 @@ if (isset($_POST['zone']) AND isset($_SESSION['username'])) {
$db = new PDO('sqlite:' . DB_PATH); $db = new PDO('sqlite:' . DB_PATH);
$stmt = $db->prepare("DELETE FROM zones WHERE zone = :zone AND username = :username"); $stmt = $db->prepare("DELETE FROM zones WHERE zone = :zone AND username = :username");
$stmt->bindParam(':zone', $_POST['zone']); $stmt->bindValue(':zone', $_POST['zone']);
$stmt->bindParam(':username', $_SESSION['username']); $stmt->bindValue(':username', $_SESSION['username']);
$stmt->execute(); $stmt->execute();

View file

@ -30,11 +30,9 @@ if (regIsFree($domain) !== true)
$db = new PDO('sqlite:' . DB_PATH); $db = new PDO('sqlite:' . DB_PATH);
$stmt = $db->prepare("INSERT INTO registry(domain, username, last_renewal) VALUES(:domain, :username, :last_renewal)"); $stmt = $db->prepare("INSERT INTO registry(domain, username, last_renewal) VALUES(:domain, :username, :last_renewal)");
$time = date("Y-m-d H:i:s"); $stmt->bindValue(':domain', $domain);
$stmt->bindValue(':username', $_SESSION['username']);
$stmt->bindParam(':domain', $domain); $stmt->bindValue(':last_renewal', date("Y-m-d H:i:s"));
$stmt->bindParam(':username', $_SESSION['username']);
$stmt->bindParam(':last_renewal', $time);
$stmt->execute(); $stmt->execute();

View file

@ -34,8 +34,8 @@ if (file_put_contents(CONF['reg']['registry_file'], $regFile) === false)
$db = new PDO('sqlite:' . DB_PATH); $db = new PDO('sqlite:' . DB_PATH);
$stmt = $db->prepare("DELETE FROM registry WHERE domain = :domain AND username = :username"); $stmt = $db->prepare("DELETE FROM registry WHERE domain = :domain AND username = :username");
$stmt->bindParam(':domain', $_POST['domain']); $stmt->bindValue(':domain', $_POST['domain']);
$stmt->bindParam(':username', $_SESSION['username']); $stmt->bindValue(':username', $_SESSION['username']);
$stmt->execute(); $stmt->execute();