knotc error handling using knotcExec()

This commit is contained in:
Miraty 2022-05-25 01:16:41 +02:00
parent 8dc4169a57
commit cd082e8719
20 changed files with 148 additions and 165 deletions

View file

@ -101,7 +101,7 @@ if (isset($page['title']))
// Protect against cross-site request forgery if a POST request is received // Protect against cross-site request forgery if a POST request is received
if (empty($_POST) === false AND (isset($_SERVER['HTTP_SEC_FETCH_SITE']) !== true OR $_SERVER['HTTP_SEC_FETCH_SITE'] !== "same-origin")) if (empty($_POST) === false AND (isset($_SERVER['HTTP_SEC_FETCH_SITE']) !== true OR $_SERVER['HTTP_SEC_FETCH_SITE'] !== "same-origin"))
userError("Anti-CSRF verification failed ! (Wrong or unset <code>Sec-Fetch-Site</code> HTTP header)"); userError("Anti-<abbr title='Cross-Site Request Forgery'>CSRF</abbr> verification failed ! (Wrong or unset <code>Sec-Fetch-Site</code> HTTP header)");
function closeHTML() { function closeHTML() {
?> ?>
@ -118,5 +118,9 @@ function closeHTML() {
</footer> </footer>
</body> </body>
</html> </html>
<?php
<?php } ?> exit();
}
?>

View file

@ -19,12 +19,11 @@ function userError($msg) {
http_response_code(403); http_response_code(403);
echo "<p><strong>Erreur utilisataire</strong> : <em>" . $msg . "</em></p>"; echo "<p><strong>Erreur utilisataire</strong> : <em>" . $msg . "</em></p>";
closeHTML(); closeHTML();
exit();
} }
function serverError($msg) { function serverError($msg) {
http_response_code(500); http_response_code(500);
error_log("Niver internal error: " . strip_tags($msg));
echo "<p><strong>Server error</strong>: The server encountered an error: <em>" . $msg . "</em></p>"; echo "<p><strong>Server error</strong>: The server encountered an error: <em>" . $msg . "</em></p>";
closeHTML(); closeHTML();
exit();
} }

View file

@ -9,13 +9,15 @@ ipv6_example = "2001:db8::3"
; From RFC5737: IPv4 Address Blocks Reserved for Documentation ; From RFC5737: IPv4 Address Blocks Reserved for Documentation
ipv4_example = "203.0.113.42" ipv4_example = "203.0.113.42"
[reg] [dns]
knotc_path = "/usr/sbin/knotc" knotc_path = "/usr/sbin/knotc"
[reg]
registry = niver.test. registry = niver.test.
ttl = 86400
subdomain_regex = "^[a-z0-9]{4,63}$" subdomain_regex = "^[a-z0-9]{4,63}$"
[ns] [ns]
knotc_path = "/usr/sbin/knotc"
knot_zones_path = "/srv/ns" knot_zones_path = "/srv/ns"
[ht] [ht]

16
dns.php
View file

@ -1,5 +1,21 @@
<?php <?php
function knotcExec($suffix, $cmd) {
$action = checkAction($_POST['action']);
exec(CONF['dns']['knotc_path'] . " zone-begin " . $suffix, $output['begin'], $code['begin']);
if ($code['begin'] !== 0)
serverError("<code>knotc</code> failed with exit code <samp>" . $code['begin'] . "</samp>: <samp>" . $output['begin'][0] . "</samp>.");
exec(CONF['dns']['knotc_path'] . " zone-" . $action . "set " . $suffix . " " . implode(" ", $cmd), $output['op'], $code['op']);
if ($code['op'] !== 0)
serverError("<code>knotc</code> failed with exit code <samp>" . $code['op'] . "</samp>: <samp>" . $output['op'][0] . "</samp>.");
exec(CONF['dns']['knotc_path'] . " zone-commit " . $suffix, $output['commit'], $code['commit']);
if ($code['commit'] !== 0)
serverError("<code>knotc</code> failed with exit code <samp>" . $code['commit'] . "</samp>: <samp>" . $output['commit'][0] . "</samp>.");
}
function checkIpFormat($ip) { function checkIpFormat($ip) {
if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE))
userError("IP address is on the private range."); userError("IP address is on the private range.");

23
ns.php
View file

@ -10,8 +10,6 @@ function nsCommonRequirements() {
} }
function nsParseCommonRequirements() { function nsParseCommonRequirements() {
$values['action'] = checkAction($_POST['action']);
nsCheckZonePossession($_POST['zone']); nsCheckZonePossession($_POST['zone']);
if (($_POST['subdomain'] === "") OR ($_POST['subdomain'] === "@")) if (($_POST['subdomain'] === "") OR ($_POST['subdomain'] === "@"))
@ -35,24 +33,9 @@ function nsListUserZones($username) {
$op = $db->prepare('SELECT zone FROM zones WHERE username = ?'); $op = $db->prepare('SELECT zone FROM zones WHERE username = ?');
$op->execute($usernameArray); $op->execute($usernameArray);
$data = $op->fetch(); $zones = array();
if (isset($data['zone'])) foreach ($op->fetchAll() as $zone)
$zone = $data['zone']; array_push($zones, $zone['zone']);
else
$zone = NULL;
$i = 0;
$zones = NULL;
while ($zone != NULL) {
$zones[$i] = $zone;
$i++;
$data = $op->fetch();
if (isset($data['zone']))
$zone = $data['zone'];
else
$zone = NULL;
}
return $zones; return $zones;
} }

View file

@ -39,9 +39,15 @@ if (nsCommonRequirements()
if (!(preg_match("/^[a-z0-9.-]{1,255}$/", $_POST['value']))) if (!(preg_match("/^[a-z0-9.-]{1,255}$/", $_POST['value'])))
userError("Wrong value for <code>value</code>."); userError("Wrong value for <code>value</code>.");
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']); knotcExec($_POST['zone'], array(
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN CAA " . $_POST['flag'] . " " . $_POST['tag'] . " " . $_POST['value']); $values['domain'],
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']); $values['ttl'],
"CAA",
$_POST['flag'],
$_POST['tag'],
$_POST['value']
));
echo "Enregistrement ajouté"; echo "Enregistrement ajouté";
} }

View file

@ -5,19 +5,11 @@ Afin d'activer DNSSEC, vous devez indiquer un enregistrement DS à la zone paren
<form method="post"> <form method="post">
<select required="" name="zone" id="zone"> <select required="" name="zone" id="zone">
<option value="" disabled="" selected="">---</option> <option value="" disabled="" selected="">---</option>
<?php
<?php if (isset($_SESSION['username']))
if (isset($_SESSION['username'])) { foreach(nsListUserZones($_SESSION['username']) as $zone)
$zones = nsListUserZones($_SESSION['username']); echo " <option value='" . $zone . "'>" . $zone . "</option>\n";
?>
if ($zones) {
foreach($zones as $zone) {
echo "<option value='" . $zone . "'>" . $zone . "</option>";
}
}
}
?>
</select> </select>
<br> <br>
<input value="Valider" type="submit"> <input value="Valider" type="submit">

View file

@ -42,12 +42,12 @@
<dd> <dd>
Indiquer les empreintes de clés <abbr title="Secure SHell">SSH</abbr> d'un domaine Indiquer les empreintes de clés <abbr title="Secure SHell">SSH</abbr> d'un domaine
</dd> </dd>
<dt><a class="nsButton" href="loc">NOT DONE : Enregistrement LOC</a></dt>
<!--
<dt><a class="nsButton" href="loc">Enregistrement LOC</a></dt>
<dd> <dd>
Indiquer des coordonnées géographiques Indiquer des coordonnées géographiques
</dd> </dd>
<!--
<dt><a class="nsButton" href="cname">Enregistrement <abbr title="Canonical NAME">CNAME</abbr></a></dt> <dt><a class="nsButton" href="cname">Enregistrement <abbr title="Canonical NAME">CNAME</abbr></a></dt>
<dd> <dd>
Définir un domaine comme étant l'alias d'un autre Définir un domaine comme étant l'alias d'un autre

View file

@ -21,9 +21,12 @@ if (nsCommonRequirements()
$record = checkIpFormat($_POST['ip']); $record = checkIpFormat($_POST['ip']);
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']); knotcExec($_POST['zone'], array(
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN " . $record . " " . $_POST['ip']); $values['domain'],
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']); $values['ttl'],
$record,
$_POST['ip']
));
echo "Enregistrement ajouté"; echo "Enregistrement ajouté";
} }

View file

@ -1,52 +0,0 @@
<?php require "../../common/html.php"; ?>
<form method="post">
<?php require "../../form.ns.php"; ?>
<br>
<label for="flag">Flag</label>
<br>
<input id="flag" min="0" max="127" placeholder="0" name="flag" type="number">
<br>
<label for="tag">Tag</label>
<br>
<input id="tag" minlenght="1" maxlength="128" pattern="^[a-z]{1,128}$" placeholder="issue" name="tag" type="text">
<br>
<label for="value">Valeur</label>
<br>
<input id="value" minlenght="3" maxlength="1024" pattern="^[a-z0-9.-]{3,1024}$" placeholder="letsencrypt.org" name="value" type="text">
<br>
<input value="Valider" type="submit">
</form>
<?php
if (nsCommonRequirements()
AND isset($_POST['flag'])
AND isset($_POST['tag'])
AND isset($_POST['value'])
) {
$values = nsParseCommonRequirements();
if (!($_POST['flag'] >= 0 AND $_POST['flag'] <= 255))
userError("Wrong value for <code>flag</code>.");
if (!(preg_match("/^[a-z]{1,127}$/", $_POST['tag'])))
userError("Wrong value for <code>tag</code>.");
if (!(preg_match("/^[a-z0-9.-]{1,255}$/", $_POST['value'])))
userError("Wrong value for <code>value</code>.");
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']);
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN CAA " . $_POST['flag'] . " " . $_POST['tag'] . " " . $_POST['value']);
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']);
echo "Enregistrement ajouté";
}
?>
<?php closeHTML(); ?>

View file

@ -34,9 +34,14 @@ if (nsCommonRequirements()
checkAbsoluteDomainFormat($_POST['host']); checkAbsoluteDomainFormat($_POST['host']);
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']); knotcExec($_POST['zone'], array(
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN MX " . $_POST['priority'] . " " . $_POST['host']); $values['domain'],
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']); $values['ttl'],
"MX",
$_POST['priority'],
$_POST['host']
));
echo "Enregistrement ajouté"; echo "Enregistrement ajouté";
} }

View file

@ -19,9 +19,13 @@ if (nsCommonRequirements()
checkAbsoluteDomainFormat($_POST['ns']); checkAbsoluteDomainFormat($_POST['ns']);
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']); knotcExec($_POST['zone'], array(
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN NS " . $_POST['ns']); $values['domain'],
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']); $values['ttl'],
"NS",
$_POST['ns']
));
echo "Enregistrement ajouté"; echo "Enregistrement ajouté";
} }

View file

@ -54,9 +54,16 @@ if (nsCommonRequirements()
checkAbsoluteDomainFormat($_POST['target']); checkAbsoluteDomainFormat($_POST['target']);
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']); knotcExec($_POST['zone'], array(
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN SRV " . $_POST['priority'] . " " . $_POST['weight'] . " " . $_POST['port'] . " " . $_POST['target']); $values['domain'],
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']); $values['ttl'],
"SRV",
$_POST['priority'],
$_POST['weight'],
$_POST['port'],
$_POST['target']
));
echo "Enregistrement ajouté"; echo "Enregistrement ajouté";
} }

View file

@ -51,9 +51,15 @@ if (nsCommonRequirements()
if (!(preg_match("/^[a-z0-9]{64}$/", $_POST['fp']))) if (!(preg_match("/^[a-z0-9]{64}$/", $_POST['fp'])))
userError("Wrong value for <code>fp</code>."); userError("Wrong value for <code>fp</code>.");
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']); knotcExec($_POST['zone'], array(
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN SSHFP " . $_POST['algo'] . " " . $_POST['type'] . " " . $_POST['fp']); $values['domain'],
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']); $values['ttl'],
"SSHFP",
$_POST['algo'],
$_POST['type'],
$_POST['fp']
));
echo "Enregistrement ajouté"; echo "Enregistrement ajouté";
} }

View file

@ -59,15 +59,22 @@ if (nsCommonRequirements()
if (!($_POST['selector'] === "0" OR $_POST['selector'] === "1")) if (!($_POST['selector'] === "0" OR $_POST['selector'] === "1"))
userError("Wrong value for <code>selector</code>."); userError("Wrong value for <code>selector</code>.");
if (!($_POST['type'] >= 0 OR $_POST['type'] <= 2)) if (!($_POST['type'] >= 0 AND $_POST['type'] <= 2))
userError("Wrong value for <code>type</code>."); userError("Wrong value for <code>type</code>.");
if (!(preg_match("/^[a-zA-Z0-9.-]{1,1024}$/", $_POST['content']))) if (!(preg_match("/^[a-zA-Z0-9.-]{1,1024}$/", $_POST['content'])))
userError("Wrong value for <code>content</code>."); userError("Wrong value for <code>content</code>.");
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']); knotcExec($_POST['zone'], array(
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . " IN TLSA " . $_POST['use'] . " " . $_POST['selector'] . " " . $_POST['type'] . " " . $_POST['content']); $values['domain'],
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']); $values['ttl'],
"TLSA",
$_POST['use'],
$_POST['selector'],
$_POST['type'],
$_POST['content']
));
echo "Enregistrement ajouté"; echo "Enregistrement ajouté";
} }

View file

@ -20,9 +20,13 @@ if (nsCommonRequirements()
if (!(preg_match("/^[a-zA-Z0-9 =:!%$+\/\()[\]_-]{5,8192}$/", $_POST['txt']))) if (!(preg_match("/^[a-zA-Z0-9 =:!%$+\/\()[\]_-]{5,8192}$/", $_POST['txt'])))
userError("Wrong value for <code>txt</code>."); userError("Wrong value for <code>txt</code>.");
exec(CONF['ns']['knotc_path'] . " zone-begin " . $_POST['zone']); knotcExec($_POST['zone'], array(
exec(CONF['ns']['knotc_path'] . " zone-" . $values['action'] . "set " . $_POST['zone'] . " " . $values['domain'] . " " . $values['ttl'] . ' IN TXT \"' . $_POST['txt'] . '\"'); $values['domain'],
exec(CONF['ns']['knotc_path'] . " zone-commit " . $_POST['zone']); $values['ttl'],
"TXT",
"\"" . $_POST['txt'] . "\""
));
echo "Enregistrement ajouté"; echo "Enregistrement ajouté";
} }

View file

@ -28,10 +28,10 @@ if (isset($_POST['domain']) AND isset($_SESSION['username'])) {
file_put_contents($knotZonePath, $knotZone); file_put_contents($knotZonePath, $knotZone);
chmod($knotZonePath, 0660); chmod($knotZonePath, 0660);
exec(CONF['ns']['knotc_path'] . " conf-begin"); exec(CONF['dns']['knotc_path'] . " conf-begin");
exec(CONF['ns']['knotc_path'] . " conf-set 'zone[" . $_POST['domain'] . "]'"); exec(CONF['dns']['knotc_path'] . " conf-set 'zone[" . $_POST['domain'] . "]'");
exec(CONF['ns']['knotc_path'] . " conf-set 'zone[" . $_POST['domain'] . "].template' 'niver'"); exec(CONF['dns']['knotc_path'] . " conf-set 'zone[" . $_POST['domain'] . "].template' 'niver'");
exec(CONF['ns']['knotc_path'] . " conf-commit"); exec(CONF['dns']['knotc_path'] . " conf-commit");
echo "La requête a été traitée."; echo "La requête a été traitée.";
@ -65,15 +65,15 @@ if (isset($_POST['zone']) AND isset($_SESSION['username'])) {
nsCheckZonePossession($_POST['zone']); nsCheckZonePossession($_POST['zone']);
// Remove from Knot configuration // Remove from Knot configuration
exec(CONF['ns']['knotc_path'] . " conf-begin"); exec(CONF['dns']['knotc_path'] . " conf-begin");
exec(CONF['ns']['knotc_path'] . " conf-unset 'zone[" . $_POST['zone'] . "]'"); exec(CONF['dns']['knotc_path'] . " conf-unset 'zone[" . $_POST['zone'] . "]'");
exec(CONF['ns']['knotc_path'] . " conf-commit"); exec(CONF['dns']['knotc_path'] . " conf-commit");
// Remove Knot zone file // Remove Knot zone file
unlink(CONF['ns']['knot_zones_path'] . "/" . $_POST['zone'] . "zone"); unlink(CONF['ns']['knot_zones_path'] . "/" . $_POST['zone'] . "zone");
// Remove Knot related data // Remove Knot related data
exec(CONF['ns']['knotc_path'] . " zone-purge " . $_POST['zone']); exec(CONF['dns']['knotc_path'] . " zone-purge " . $_POST['zone']);
// Remove from Niver's database // Remove from Niver's database
$db = new PDO('sqlite:' . DB_PATH); $db = new PDO('sqlite:' . DB_PATH);

View file

@ -11,17 +11,13 @@
<br> <br>
<select required="" name="zone" id="zone"> <select required="" name="zone" id="zone">
<option value="" disabled="" selected="">---</option> <option value="" disabled="" selected="">---</option>
<?php
<?php $domains = regListUserDomains($_SESSION['username']);
$domains = regListUserDomains($_SESSION['username']);
if ($domains) { foreach($domains as $domain)
foreach($domains as $domain) { echo " <option value='" . $domain . "'>" . $domain . "</option>";
echo "<option value='" . $domain . "'>" . $domain . "</option>"; ?>
}
}
?>
</select> </select>
<br> <br>
@ -91,9 +87,16 @@ if (isset($_POST['zone']) AND isset($_POST['keytag']) AND isset($_POST['algo'])
$suffix = regGetUpperDomain($_POST['zone']); $suffix = regGetUpperDomain($_POST['zone']);
exec(CONF['reg']['knotc_path'] . " zone-begin " . $suffix); knotcExec($suffix, array(
exec(CONF['reg']['knotc_path'] . " zone-" . $action . "set " . $suffix . " " . $_POST['zone'] . " 86400 IN DS " . $_POST['keytag'] . " " . $_POST['algo'] . " " . $_POST['dt'] . " " . $_POST['key']); $_POST['zone'],
exec(CONF['reg']['knotc_path'] . " zone-commit " . $suffix); CONF['reg']['ttl'],
"DS",
$_POST['keytag'],
$_POST['algo'],
$_POST['dt'],
$_POST['key']
));
echo "La requête a été envoyée à Knot"; echo "La requête a été envoyée à Knot";
} }

View file

@ -19,12 +19,13 @@
<select required="" name="suffix" id="suffix"> <select required="" name="suffix" id="suffix">
<option value="" disabled="" selected="">---</option> <option value="" disabled="" selected="">---</option>
<?php <?php
foreach(regListUserDomains($_SESSION['username']) as $suffix) if (isset($_SESSION['username']))
echo " <option value='" . $suffix . "'>." . $suffix . "</option>"; foreach(regListUserDomains($_SESSION['username']) as $suffix)
echo " <option value='" . $suffix . "'>." . $suffix . "</option>";
?> ?>
</select> </select>
</div> </div>
</fieldset> </fieldset>
@ -46,13 +47,15 @@ if (isset($_POST['action']) AND isset($_POST['subdomain']) AND isset($_POST['suf
$record = checkIpFormat($_POST['ip']); $record = checkIpFormat($_POST['ip']);
$action = checkAction($_POST['action']);
$publicSuffix = regGetUpperDomain($_POST['suffix']); $publicSuffix = regGetUpperDomain($_POST['suffix']);
exec(CONF['reg']['knotc_path'] . " zone-begin " . $publicSuffix); knotcExec($publicSuffix, array(
exec(CONF['reg']['knotc_path'] . " zone-" . $action . "set " . $publicSuffix . " " . $domain . " 86400 IN " . $record . " " . $_POST['ip']); $domain
exec(CONF['reg']['knotc_path'] . " zone-commit " . $publicSuffix); CONF['reg']['ttl'],
$record,
$_POST['ip']
));
echo "Glue record ajouté"; echo "Glue record ajouté";
} }

View file

@ -34,25 +34,16 @@ if (isset($_POST['domain']) AND isset($_POST['action']) AND isset($_POST['ns'])
regCheckDomainPossession($_POST['domain']); regCheckDomainPossession($_POST['domain']);
checkAbsoluteDomainFormat($_POST['ns']); checkAbsoluteDomainFormat($_POST['ns']);
$action = checkAction($_POST['action']);
$suffix = regGetUpperDomain($_POST['domain']); $suffix = regGetUpperDomain($_POST['domain']);
exec(CONF['reg']['knotc_path'] . " zone-begin " . $suffix, $output); knotcExec($suffix, array(
exec(CONF['reg']['knotc_path'] . " zone-" . $action . "set " . $suffix . " " . $_POST['domain'] . " 86400 IN NS " . $_POST['ns'], $output); $_POST['domain'],
exec(CONF['reg']['knotc_path'] . " zone-commit " . $suffix, $output); CONF['reg']['ttl'],
$error = false; "NS",
var_dump($output); $_POST['ns']
foreach ($output as $line) { ));
if ($line !== "OK") {
$error = true; echo "Modification effectuée avec succès";
}
}
if ($error) {
echo "An ERROR occured!";
} else {
echo "Modification effectuée avec succès";
}
} }
?> ?>