Add reg/transfer.php

This commit is contained in:
Miraty 2022-12-13 16:52:10 +01:00
parent 7a018e5a88
commit 1c193cd59d
7 changed files with 64 additions and 13 deletions

View File

@ -7,19 +7,21 @@ public_domains[] = "niver.test"
[dns]
knotc_path = "/usr/sbin/knotc"
kdig_path = "/usr/bin/kdig"
[reg]
enabled = true
registry = "niver.test."
registry_file = "/srv/niver/reg/niver.test.zone"
ttl = 86400
; A local address to query the registry nameserver
address = "[::1]:42053"
[ns]
enabled = true
knot_zones_path = "/srv/niver/ns"
servers[] = "ns1.niver.test."
servers[] = "ns2.niver.test."
kdig_path = "/usr/bin/kdig"
kzonecheck_path = "/usr/bin/kzonecheck"
; @ must be replaced by a dot
public_soa_email = "hostmaster.niver.invalid."

View File

@ -20,8 +20,8 @@ function knotcConfExec($cmds) {
}
}
function knotcZoneExec($zone, $cmd) {
$action = checkAction($_POST['action']);
function knotcZoneExec($zone, $cmd, $action = NULL) {
$action = checkAction($action ?? $_POST['action']);
exec(CONF['dns']['knotc_path'] . ' zone-begin ' . $zone, $output['begin'], $code['begin']);
if ($code['begin'] !== 0)
@ -48,9 +48,8 @@ function checkIpFormat($ip) {
output(403, 'IP address malformed.');
}
function checkAbsoluteDomainFormat($domain) {
// If the domain must end with a dot
if (!filter_var($domain, FILTER_VALIDATE_DOMAIN) OR !preg_match('/^([a-z0-9_-]{1,63}\.){2,127}$/D', $domain))
function checkAbsoluteDomainFormat($domain) { // If the domain must end with a dot
if (!filter_var($domain, FILTER_VALIDATE_DOMAIN) OR preg_match('/^([a-z0-9_-]{1,63}\.){2,127}$/D', $domain) !== 1)
output(403, 'Domain malformed.');
}

View File

@ -65,6 +65,10 @@ define('PAGES', [
'title' => 'Enregistrements <abbr title="Delegation Signer">DS</abbr>',
'description' => 'Déléguer la confiance <abbr title="Domain Name System Security Extensions">DNSSEC</abbr>',
],
'transfer' => [
'title' => 'Recevoir un transfert de domaine',
'description' => 'Transférer un domaine vers ce compte',
],
'glue' => [
'title' => 'Glue Records',
'description' => 'Avancé : Indiquer l\'IP d\'un serveur de noms dont l\'adresse dépend de la zone qu\'il sert',

View File

@ -63,7 +63,7 @@ if (processForm(false)) {
<p>Une clé de passe sécurisée est trop compliquée à deviner pour une attaque qui testerait automatiquement plein de clés de passe tout en connaissant d'autres informations et secrets sur vous.</p>
<p>Minimum 8 caractères si elle contient minuscule, majuscule et chiffre, ou minimum 10 caractères sinon.</p>
</details>
<input autocomplete="new-password" id="password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" required="" name="password" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>"><br>
<input autocomplete="new-password" id="password" minlength="8" maxlength="1024" pattern="<?= PASSWORD_REGEX ?>" required="" name="password" type="password" placeholder="<?= PLACEHOLDER_PASSWORD ?>">
<br>
<input type="submit">
</form>

View File

@ -6,14 +6,14 @@ if (processForm()) {
if (query('select', 'zones', ['zone' => $_POST['domain']], 'zone') !== [])
output(403, 'Cette zone existe déjà sur ce service.');
exec(CONF['ns']['kdig_path'] . ' ' . ltrim(strstr($_POST['domain'], '.'), '.') . ' NS +short', $parentAuthoritatives);
exec(CONF['dns']['kdig_path'] . ' ' . ltrim(strstr($_POST['domain'], '.'), '.') . ' NS +short', $parentAuthoritatives);
if ($parentAuthoritatives === [])
output(403, 'Serveurs de noms de la zone parente introuvables');
foreach ($parentAuthoritatives as $parentAuthoritative)
checkAbsoluteDomainFormat($parentAuthoritative);
exec(CONF['ns']['kdig_path'] . ' ' . $_POST['domain'] . ' NS @' . $parentAuthoritatives[0] . ' +noidn', $results);
if (preg_match('/^' . preg_quote($_POST['domain'], '/') . '[\t ]+[0-9]{1,8}[\t ]+IN[\t ]+NS[\t ]+(?<salt>[0-9a-f]{8})-(?<hash>[0-9a-f]{32})\._domain-verification\.' . preg_quote(SERVER_NAME, '/') . '$/Dm', implode(LF, $results), $matches) !== 1)
exec(CONF['dns']['kdig_path'] . ' ' . $_POST['domain'] . ' NS @' . $parentAuthoritatives[0] . ' +noidn', $results);
if (preg_match('/^' . preg_quote($_POST['domain'], '/') . '[\t ]+[0-9]{1,8}[\t ]+IN[\t ]+NS[\t ]+(?<salt>[0-9a-f]{8})-(?<hash>[0-9a-f]{32})\._domain-verification\.' . preg_quote(SERVER_NAME, '/') . '\.$/Dm', implode(LF, $results), $matches) !== 1)
output(403, 'Enregistrement d\'authentification introuvable');
checkAuthToken($matches['salt'], $matches['hash']);

View File

@ -32,7 +32,7 @@ if (processForm()) {
<form method="post">
<label for="subdomain">Sous-domaine</label>
<br>
<input id="subdomain" pattern="<?= SUBDOMAIN_REGEX ?>" required="" placeholder="niver" name="subdomain" type="text">.<?= CONF['reg']['registry'] ?>
<code><input id="subdomain" pattern="<?= SUBDOMAIN_REGEX ?>" required="" placeholder="niver" name="subdomain" type="text">.<?= CONF['reg']['registry'] ?></code>
<br>
<input value="Valider" type="submit">
<input value="Enregistrer" type="submit">
</form>

46
pages/reg/transfer.php Normal file
View File

@ -0,0 +1,46 @@
<?php
if (processForm()) {
if (preg_match('/' . SUBDOMAIN_REGEX . '/D', $_POST['domain']) !== 1)
output(403, 'Le nom de domaine semble incorrect');
$domain = $_POST['domain'] . '.' . CONF['reg']['registry'];
if (query('select', 'registry', ['username' => $_SESSION['id'], 'domain' => $domain], 'domain') !== [])
output(403, 'Le compte présent possède déjà ce domaine.');
exec(CONF['dns']['kdig_path'] . ' ' . $domain . ' NS @' . CONF['reg']['address'] . ' +noidn', $results);
if (preg_match('/^' . preg_quote($domain, '/') . '[\t ]+[0-9]{1,8}[\t ]+IN[\t ]+NS[\t ]+(?<salt>[0-9a-f]{8})-(?<hash>[0-9a-f]{32})\._transfer-verification\.' . preg_quote(SERVER_NAME, '/') . '\.$/Dm', implode(LF, $results), $matches) !== 1)
output(403, 'Enregistrement d\'authentification introuvable');
checkAuthToken($matches['salt'], $matches['hash']);
$stmt = DB->prepare('UPDATE registry SET username = :username WHERE domain = :domain');
$stmt->bindValue(':username', $_SESSION['id']);
$stmt->bindValue(':domain', $domain);
$stmt->execute();
knotcZoneExec(CONF['reg']['registry'], [
$domain,
'NS',
$matches['salt'] . '-' . $matches['hash'] . '._transfer-verification.' . SERVER_NAME . '.'
], 'delete');
output(200, 'Le domaine a été transféré vers le compte présent, l\'enregistrement d\'authentification a été automatiquement retiré.');
}
$proof = getAuthToken();
?>
<p>
Pour prouver que vous êtes autorisé à recevoir le domaine par san possessaire actuele, ledit domaine doit posséder un <?= linkToDocs('ns-record', 'enregistrement NS') ?> égal à <code><?= $proof ?>._transfer-verification.<?= SERVER_NAME ?>.</code> lors du traitement de ce formulaire. Cet enregistrement sera automatiquement retiré une fois validé.
</p>
<form method="post">
<label for="subdomain">Sous-domaine à recevoir</label>
<br>
<code><input required="" placeholder="subdomain" id="subdomain" name="subdomain" type="text">.<?= CONF['reg']['registry'] ?></code>
<br>
<input value="Recevoir ce domaine" type="submit">
</form>