servnest/fn/ht.php

129 lines
4.0 KiB
PHP

<?php
function htSetupUserFs($id) {
// Setup SFTP directory
umask(0002);
if (mkdir(CONF['ht']['ht_path'] . '/' . $id, 0775) !== true)
output(500, 'Can\'t create user directory.');
exec(CONF['ht']['sudo_path'] . ' ' . CONF['ht']['chgrp_path'] . ' ' . CONF['ht']['sftpgo_group'] . ' ' . CONF['ht']['ht_path'] . '/' . $id . ' --no-dereference', result_code: $code);
if ($code !== 0)
output(500, 'Can\'t change user directory group.');
// Setup Tor config directory
if (mkdir(CONF['ht']['tor_config_path'] . '/' . $id, 0755) !== true)
output(500, 'Can\'t create Tor config directory.');
// Setup Tor keys directory
exec(CONF['ht']['sudo_path'] . ' -u ' . CONF['ht']['tor_user'] . ' ' . CONF['ht']['mkdir_path'] . ' --mode=0700 ' . CONF['ht']['tor_keys_path'] . '/' . $id, result_code: $code);
if ($code !== 0)
output(500, 'Can\'t create Tor keys directory.');
}
function checkDomainFormat($domain) {
// If the domain must end without a dot
if (!filter_var($domain, FILTER_VALIDATE_DOMAIN) OR !preg_match('/^([a-z0-9_-]{1,63}\.){1,126}[a-z0-9]{1,63}$/D', $domain))
output(403, _('Domain malformed.'));
}
function formatDomain($domain) {
$domain = rtrim(strtolower($domain), '.');
checkDomainFormat($domain);
return $domain;
}
function listFsDirs($username) {
$absoluteDirs = glob(CONF['ht']['ht_path'] . '/' . $username . '/*/', GLOB_ONLYDIR);
$dirs = [];
foreach ($absoluteDirs as $absoluteDir)
if (preg_match('/^[a-zA-Z0-9_-]{1,64}$/D', basename($absoluteDir)))
array_push($dirs, basename($absoluteDir));
return $dirs;
}
function addSite($username, $siteDir, $address, $type) {
insert('sites', [
'username' => $username,
'site_dir' => $siteDir,
'address' => $address,
'type' => $type,
'creation_date' => date('Y-m-d H:i:s'),
]);
}
function dirsStatuses($type) {
if (isset($_SESSION['id']) !== true)
return [];
$dbDirs = query('select', 'sites', [
'username' => $_SESSION['id'],
'type' => $type,
], 'site_dir');
$dirs = [];
foreach (listFsDirs($_SESSION['id']) as $fsDir)
$dirs[$fsDir] = in_array($fsDir, $dbDirs);
return $dirs;
}
function htDeleteSite($address, $type) {
match ($type) {
'onion', 'dns' => htDeleteDedicatedSite($address, $type),
'subpath', 'subdomain' => htDeleteSubSite($address, $type)
};
}
function htDeleteSubSite($address, $type) {
if (unlink(CONF['ht'][$type . '_path'] . '/' . $address) !== true)
output(500, 'Unable to delete symlink.');
query('delete', 'sites', [
'username' => $_SESSION['id'],
'type' => $type,
'address' => $address,
]);
}
function htDeleteDedicatedSite($address, $type) {
$dir = query('select', 'sites', [
'address' => $address,
'type' => $type,
], 'site_dir')[0];
if ($type === 'onion') {
// Delete Tor config
if (unlink(CONF['ht']['tor_config_path'] . '/' . $_SESSION['id'] . '/' . $dir) !== true)
output(500, 'Failed to delete Tor configuration.');
// Reload Tor
exec(CONF['ht']['sudo_path'] . ' ' . CONF['ht']['tor_reload_cmd'], $output, $code);
if ($code !== 0)
output(500, 'Failed to reload Tor.');
// Delete Tor keys
exec(CONF['ht']['sudo_path'] . ' -u ' . CONF['ht']['tor_user'] . ' ' . CONF['ht']['rm_path'] . ' --recursive ' . CONF['ht']['tor_keys_path'] . '/' . $_SESSION['id'] . '/' . $dir, $output, $code);
if ($code !== 0)
output(500, 'Failed to delete Tor keys.');
}
// Delete Nginx config
if (unlink(CONF['ht']['nginx_config_path'] . '/' . $address . '.conf') !== true)
output(500, 'Failed to delete Nginx configuration.');
// Reload Nginx
exec(CONF['ht']['sudo_path'] . ' ' . CONF['ht']['nginx_reload_cmd'], result_code: $code);
if ($code !== 0)
output(500, 'Failed to reload Nginx.');
if ($type === 'dns') {
// Delete Let's Encrypt certificate
exec(CONF['ht']['sudo_path'] . ' ' . CONF['ht']['certbot_path'] . ' delete --quiet --cert-name ' . $address, $output, $code);
if ($code !== 0)
output(500, 'Certbot failed to delete the Let\'s Encrypt certificate.');
}
// Delete from database
query('delete', 'sites', [
'username' => $_SESSION['id'],
'type' => $type,
'site_dir' => $dir,
]);
}