Bläddra i källkod

Add reg/transfer.php

Miraty 2 år sedan
förälder
incheckning
1c193cd59d
7 ändrade filer med 64 tillägg och 13 borttagningar
  1. 3 1
      config.ini
  2. 4 5
      fn/dns.php
  3. 4 0
      pages.php
  4. 2 2
      pages/auth/register.php
  5. 3 3
      pages/ns/zone-add.php
  6. 2 2
      pages/reg/register.php
  7. 46 0
      pages/reg/transfer.php

+ 3 - 1
config.ini

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

+ 4 - 5
fn/dns.php

@@ -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']);
 	exec(CONF['dns']['knotc_path'] . ' zone-begin ' . $zone, $output['begin'], $code['begin']);
 	if ($code['begin'] !== 0)
 	if ($code['begin'] !== 0)
@@ -48,9 +48,8 @@ function checkIpFormat($ip) {
 	output(403, 'IP address malformed.');
 	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.');
 		output(403, 'Domain malformed.');
 }
 }
 
 

+ 4 - 0
pages.php

@@ -65,6 +65,10 @@ define('PAGES', [
 			'title' => 'Enregistrements <abbr title="Delegation Signer">DS</abbr>',
 			'title' => 'Enregistrements <abbr title="Delegation Signer">DS</abbr>',
 			'description' => 'Déléguer la confiance <abbr title="Domain Name System Security Extensions">DNSSEC</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' => [
 		'glue' => [
 			'title' => 'Glue Records',
 			'title' => 'Glue Records',
 			'description' => 'Avancé : Indiquer l\'IP d\'un serveur de noms dont l\'adresse dépend de la zone qu\'il sert',
 			'description' => 'Avancé : Indiquer l\'IP d\'un serveur de noms dont l\'adresse dépend de la zone qu\'il sert',

+ 2 - 2
pages/auth/register.php

@@ -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>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>
 		<p>Minimum 8 caractères si elle contient minuscule, majuscule et chiffre, ou minimum 10 caractères sinon.</p>
 	</details>
 	</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">
 	<input type="submit">
 </form>
 </form>

+ 3 - 3
pages/ns/zone-add.php

@@ -6,14 +6,14 @@ if (processForm()) {
 	if (query('select', 'zones', ['zone' => $_POST['domain']], 'zone') !== [])
 	if (query('select', 'zones', ['zone' => $_POST['domain']], 'zone') !== [])
 		output(403, 'Cette zone existe déjà sur ce service.');
 		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 === [])
 	if ($parentAuthoritatives === [])
 		output(403, 'Serveurs de noms de la zone parente introuvables');
 		output(403, 'Serveurs de noms de la zone parente introuvables');
 	foreach ($parentAuthoritatives as $parentAuthoritative)
 	foreach ($parentAuthoritatives as $parentAuthoritative)
 		checkAbsoluteDomainFormat($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');
 		output(403, 'Enregistrement d\'authentification introuvable');
 
 
 	checkAuthToken($matches['salt'], $matches['hash']);
 	checkAuthToken($matches['salt'], $matches['hash']);

+ 2 - 2
pages/reg/register.php

@@ -32,7 +32,7 @@ if (processForm()) {
 <form method="post">
 <form method="post">
 	<label for="subdomain">Sous-domaine</label>
 	<label for="subdomain">Sous-domaine</label>
 	<br>
 	<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>
 	<br>
-	<input value="Valider" type="submit">
+	<input value="Enregistrer" type="submit">
 </form>
 </form>

+ 46 - 0
pages/reg/transfer.php

@@ -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>