From c8904214543405f79dd9e6855fe0239628d41176 Mon Sep 17 00:00:00 2001 From: Miraty Date: Fri, 20 May 2022 02:19:45 +0200 Subject: [PATCH] Use HTTP error codes, better error handling --- auth.php | 6 ++++-- common/init.php | 10 ++++++++++ common/top.php | 2 +- db/source.sql | 1 - dns.php | 15 +++++++++------ ht.php | 30 +----------------------------- ns.php | 4 ++-- public/auth/login.php | 9 +++------ public/auth/password.php | 5 ++--- public/auth/register.php | 15 ++++++--------- public/ht/http-onion.php | 4 ++-- public/ht/https-domain.php | 2 +- public/ht/le.php | 4 ++-- public/ns/caa.php | 6 +++--- public/ns/dnssec.php | 2 +- public/ns/ip.php | 9 +-------- public/ns/loc.php | 6 +++--- public/ns/mx.php | 2 +- public/ns/srv.php | 6 +++--- public/ns/sshfp.php | 6 +++--- public/ns/tlsa.php | 8 ++++---- public/ns/txt.php | 2 +- public/reg/ds.php | 6 +++--- public/reg/glue.php | 16 +++------------- reg.php | 2 +- 25 files changed, 70 insertions(+), 108 deletions(-) diff --git a/auth.php b/auth.php index 5628609..9ee67b2 100644 --- a/auth.php +++ b/auth.php @@ -12,11 +12,13 @@ define("OPTIONS_PASSWORD", array( )); function checkPasswordFormat($password) { - return preg_match("/" . PASSWORD_REGEX . "/", $password); + if (preg_match("/" . PASSWORD_REGEX . "/", $password) !== true) + userError("Password malformed.") } function checkUsernameFormat($username) { - return preg_match("/" . USERNAME_REGEX . "/", $username); + if (preg_match("/" . USERNAME_REGEX . "/", $username) !== true) + userError("Username malformed.") } function hashPassword($password) { diff --git a/common/init.php b/common/init.php index 359a9b5..181f716 100644 --- a/common/init.php +++ b/common/init.php @@ -14,3 +14,13 @@ if (SERVICE !== "") // Page titles definition require "pages.php"; + +function userError($msg) { + http_response_code(422); + exit("User error: The server refused to process this request: " . $msg . ""); +} + +function serverError($msg) { + http_response_code(500); + exit("Server error: The server encountered an error: " . $msg . ""); +} diff --git a/common/top.php b/common/top.php index 90115f9..d706e25 100644 --- a/common/top.php +++ b/common/top.php @@ -4,7 +4,7 @@ require "init.php"; function antiCSRF() { if (!isset($_SERVER['HTTP_SEC_FETCH_SITE']) OR $_SERVER['HTTP_SEC_FETCH_SITE'] !== "same-origin") - exit("ERROR: Anti-CSRF verification failed ! (Wrong or unset Sec-Fetch-Site HTTP header)"); + userError("Anti-CSRF verification failed ! (Wrong or unset Sec-Fetch-Site HTTP header)"); } // Session initialisation (with cookies) diff --git a/db/source.sql b/db/source.sql index 7cab512..c5f6fcd 100644 --- a/db/source.sql +++ b/db/source.sql @@ -16,7 +16,6 @@ CREATE TABLE IF NOT EXISTS "users" ( "id" INTEGER NOT NULL UNIQUE, "username" TEXT NOT NULL, "password" TEXT NOT NULL, - "sftp_enabled" INTEGER NOT NULL, "registration_date" INTEGER NOT NULL, PRIMARY KEY("id" AUTOINCREMENT) ); diff --git a/dns.php b/dns.php index 89846fb..4cfe171 100644 --- a/dns.php +++ b/dns.php @@ -1,18 +1,21 @@ prepare('SELECT sftp_enabled FROM users WHERE username = ?'); - $op->execute($usernameArr); - - $status = $op->fetch()['sftp_enabled']; - - if ($status == "0") { - return false; - } else if ($status == "1") { - return true; - } else { - exit("Wrong value for sftp_enabled"); - } -} - -function enableSftp($username) { - $db = new PDO('sqlite:' . DB_PATH); - - $op = $db->prepare("UPDATE users SET sftp_enabled = 1 WHERE username = :username"); - - $op->bindParam(':username', $username); - - $op->execute(); -} - function selectSites($username, $domainType, $protocol, $onlyLeAvailable) { $db = new PDO('sqlite:' . DB_PATH); $usernameArray[0] = $username; diff --git a/ns.php b/ns.php index 72f8e07..7409a0f 100644 --- a/ns.php +++ b/ns.php @@ -26,7 +26,7 @@ function nsParseCommonRequirements() { $values['ttl'] = $_POST['ttl-value'] * $_POST['ttl-multiplier']; if (!($values['ttl'] >= 300 AND $values['ttl'] <= 432000)) - exit("Erreur : le TTL doit être compris entre 5 minutes et 5 jours (entre 300 et 432000 secondes)"); + userError("Le TTL doit être compris entre 5 minutes et 5 jours (entre 300 et 432000 secondes)."); return $values; } @@ -77,5 +77,5 @@ function nsCheckZonePossession($submittedZone) { } // If there is no entry in the database for the user matching the submitted zone - exit("ERROR: You don't own this zone on the nameserver"); + userError("You don't own this zone on the nameserver."); } diff --git a/public/auth/login.php b/public/auth/login.php index 12d9046..2cbe066 100644 --- a/public/auth/login.php +++ b/public/auth/login.php @@ -20,11 +20,9 @@ if (isset($_POST['username']) AND isset($_POST['password'])) { antiCSRF(); - if (!checkPasswordFormat($_POST['password'])) - exit("Le format du mot de passe n'est pas valide !"); + checkPasswordFormat($_POST['password']); - if (!checkUsernameFormat($_POST['username'])) - exit("Le format du nom du compte n'est pas valide !"); + checkUsernameFormat($_POST['username']); if (checkPassword($_POST['username'], $_POST['password'])) { @@ -37,11 +35,10 @@ if (isset($_POST['username']) AND isset($_POST['password'])) { if (preg_match("/^[0-9a-z\/-]+$/", $_GET['redir'])) header("Location: " . CONF['common']['prefix'] . "/" . $_GET['redir']); else - exit("ERROR : Wrong character in redir argument"); + userError("Wrong character in redir."); } else { header("Location: " . CONF['common']['prefix'] . "/"); } - exit; } else { echo "
Connexion impossible : mot de passe invalide"; } diff --git a/public/auth/password.php b/public/auth/password.php index c2a078e..9979314 100644 --- a/public/auth/password.php +++ b/public/auth/password.php @@ -20,10 +20,9 @@ if (isset($_SESSION['username']) AND isset($_POST['newPassword']) AND isset($_PO antiCSRF(); - if (checkPassword($_SESSION['username'], $_POST['currentPassword'])) { + checkPasswordFormat($_POST['newPassword']); - if (!checkPasswordFormat($_POST['newPassword'])) - exit("Erreur : Le format du nouveau mot de passe n'est pas bon !"); + if (checkPassword($_SESSION['username'], $_POST['currentPassword'])) { $username = $_SESSION['username']; $newPassword = password_hash($_POST['newPassword'], PASSWORD_DEFAULT); diff --git a/public/auth/register.php b/public/auth/register.php index 5a6571f..8a96fc4 100644 --- a/public/auth/register.php +++ b/public/auth/register.php @@ -6,11 +6,9 @@ if (isset($_POST['username']) AND isset($_POST['password'])) { antiCSRF(); - if (!checkPasswordFormat($_POST['password'])) - exit("Le format du mot de passe n'est pas valide !"); + checkPasswordFormat($_POST['password']); - if (!checkUsernameFormat($_POST['username'])) - exit("Le format du nom du compte n'est pas valide !"); + checkUsernameFormat($_POST['username']); $username = $_POST['username']; $userExist = userExist($username); @@ -18,17 +16,17 @@ if (isset($_POST['username']) AND isset($_POST['password'])) { // Setup SFTP directory umask(0002); - if (!mkdir(CONF['ht']['ht_path'] . "/" . $username, 0775)) - exit("ERROR: Can't create directory"); + if (mkdir(CONF['ht']['ht_path'] . "/" . $username, 0775) !== true) + serverError("Can't create user directory."); exec(CONF['ht']['sudo_path'] . " " . CONF['ht']['chgrp_path'] . " " . CONF['ht']['sftpgo_group'] . " " . CONF['ht']['ht_path'] . "/" . $username, $stdout, $code); if ($code !== 0) - exit("ERROR: Can't change group"); + serverError("Can't change user directory group."); $password = hashPassword($_POST['password']); $db = new PDO('sqlite:' . DB_PATH); - $stmt = $db->prepare("INSERT INTO users(username, password, sftp_enabled, registration_date) VALUES(:username, :password, 0, :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"); @@ -39,7 +37,6 @@ if (isset($_POST['username']) AND isset($_POST['password'])) { $stmt->execute(); $_SESSION['username'] = $username; - $_SESSION['sftp_enabled'] = false; header('Location: ' . CONF['common']['prefix'] . '/'); exit; } diff --git a/public/ht/http-onion.php b/public/ht/http-onion.php index 93e042a..1fc222b 100644 --- a/public/ht/http-onion.php +++ b/public/ht/http-onion.php @@ -55,7 +55,7 @@ if (isset($_POST['dir']) AND isset($_SESSION['username'])) { antiCSRF(); if (!in_array($_POST['dir'], $notYetEnabledDirs)) - exit("ERROR : Wrong value for dir"); + userError("Wrong value for dir."); // Generate a .onion address $torConf = file_get_contents(CONF['ht']['tor_config_path']); @@ -78,7 +78,7 @@ HiddenServicePort 80 [::1]:" . CONF['ht']['internal_onion_http_port'] . " $onion = file_get_contents(CONF['ht']['ht_path'] . "/" . $_SESSION['username'] . "/" . $_POST['dir'] . "/hostname"); $onion = str_replace(array("\r", "\n"), "", $onion); if (preg_match("/[0-9a-z]{56}\.onion/", $onion) !== 1) - exit("ERROR: No onion address found"); + serverError("No onion address found."); // Store it in the database addSite($_SESSION['username'], $_POST['dir'], $onion, "onion", "http"); diff --git a/public/ht/https-domain.php b/public/ht/https-domain.php index 25027c4..0c06511 100644 --- a/public/ht/https-domain.php +++ b/public/ht/https-domain.php @@ -65,7 +65,7 @@ if (isset($_POST['domain']) AND isset($_POST['dir']) AND isset($_SESSION['userna checkDomainFormat($_POST['domain']); if (!in_array($_POST['dir'], $notYetEnabledDirs)) - exit("ERROR : Wrong value for dir"); + userError("Wrong value for dir."); addSite($_SESSION['username'], $_POST['dir'], $_POST['domain'], "dns", "http"); diff --git a/public/ht/le.php b/public/ht/le.php index b1fdeb5..9bd41d6 100644 --- a/public/ht/le.php +++ b/public/ht/le.php @@ -31,7 +31,7 @@ if (isset($_POST['domain']) AND isset($_SESSION['username'])) { // Abort if Certbot failed if ($returnCode !== 0) - exit("Let's Encrypt certificate obtention failed. Try again later, or contact an administrator."); + serverError("Certbot failed to get a Let's Encrypt certificate."); // Replace self-signed certificate by Let's Encrypt certificate in Nginx configuration $conf = file_get_contents(CONF['ht']['nginx_config_path'] . "/" . $_POST['domain'] . ".conf"); @@ -44,7 +44,7 @@ if (isset($_POST['domain']) AND isset($_SESSION['username'])) { // Abort if Nginx reload failed if ($returnCode !== 0) - exit("Nginx configuration reload failed. Try again later, or contact an administrator."); + serverError("Nginx configuration reload failed."); echo "Succès : La connexion avec votre site utilise désomais un certificat TLS émis par Let's Encrypt."; } diff --git a/public/ns/caa.php b/public/ns/caa.php index 8ba1c85..77434bc 100644 --- a/public/ns/caa.php +++ b/public/ns/caa.php @@ -31,13 +31,13 @@ if (nsCommonRequirements() $values = nsParseCommonRequirements(); if (!($_POST['flag'] >= 0 AND $_POST['flag'] <= 255)) - exit("ERROR: Wrong value for flag"); + userError("Wrong value for flag."); if (!(preg_match("/^[a-z]{1,127}$/", $_POST['tag']))) - exit("ERROR: Wrong value for tag"); + userError("Wrong value for tag."); if (!(preg_match("/^[a-z0-9.-]{1,255}$/", $_POST['value']))) - exit("ERROR: Wrong value for value"); + userError("Wrong value for value."); 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']); diff --git a/public/ns/dnssec.php b/public/ns/dnssec.php index 158e9a1..a722042 100644 --- a/public/ns/dnssec.php +++ b/public/ns/dnssec.php @@ -35,7 +35,7 @@ if (isset($_POST['zone']) AND isset($_SESSION['username'])) { $found = preg_match("#\n" . preg_quote($_POST['zone']) . "\s+0\s+CDS\s+([0-9]{1,5})\s+([0-9]{1,2})\s+([0-9])\s+([0-9A-F]{64})\n#", $zoneContent, $matches); if ($found !== 1) - exit("ERROR: Unable to get public key record from zone file"); + serverError("Unable to get public key record from zone file."); $tag = $matches[1]; $algo = $matches[2]; diff --git a/public/ns/ip.php b/public/ns/ip.php index 0e2255c..0160ab0 100644 --- a/public/ns/ip.php +++ b/public/ns/ip.php @@ -19,14 +19,7 @@ if (nsCommonRequirements() $values = nsParseCommonRequirements(); - checkIpFormat($_POST['ip']); - - if (filter_var($_POST['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) - $record = "A"; - else if (filter_var($_POST['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) - $record = "AAAA"; - else - exit("ERROR: unknown IP format"); + $record = checkIpFormat($_POST['ip']); 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 " . $record . " " . $_POST['ip']); diff --git a/public/ns/loc.php b/public/ns/loc.php index 8ba1c85..77434bc 100644 --- a/public/ns/loc.php +++ b/public/ns/loc.php @@ -31,13 +31,13 @@ if (nsCommonRequirements() $values = nsParseCommonRequirements(); if (!($_POST['flag'] >= 0 AND $_POST['flag'] <= 255)) - exit("ERROR: Wrong value for flag"); + userError("Wrong value for flag."); if (!(preg_match("/^[a-z]{1,127}$/", $_POST['tag']))) - exit("ERROR: Wrong value for tag"); + userError("Wrong value for tag."); if (!(preg_match("/^[a-z0-9.-]{1,255}$/", $_POST['value']))) - exit("ERROR: Wrong value for value"); + userError("Wrong value for value."); 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']); diff --git a/public/ns/mx.php b/public/ns/mx.php index b70d720..2b74893 100644 --- a/public/ns/mx.php +++ b/public/ns/mx.php @@ -30,7 +30,7 @@ if (nsCommonRequirements() $values = nsParseCommonRequirements(); if (!($_POST['priority'] >= 0 AND $_POST['priority'] <= 255)) - exit("ERROR: Wrong value for priority"); + userError("Wrong value for priority."); checkAbsoluteDomainFormat($_POST['host']); diff --git a/public/ns/srv.php b/public/ns/srv.php index a2b09af..a22a270 100644 --- a/public/ns/srv.php +++ b/public/ns/srv.php @@ -44,13 +44,13 @@ if (nsCommonRequirements() $values = nsParseCommonRequirements(); if (!($_POST['priority'] >= 0 AND $_POST['priority'] <= 65535)) - exit("ERROR: Wrong value for priority"); + userError("Wrong value for priority."); if (!($_POST['weight'] >= 0 AND $_POST['weight'] <= 65535)) - exit("ERROR: Wrong value for weight"); + userError("Wrong value for weight."); if (!($_POST['port'] >= 0 AND $_POST['port'] <= 65535)) - exit("ERROR: Wrong value for port"); + userError("Wrong value for port."); checkAbsoluteDomainFormat($_POST['target']); diff --git a/public/ns/sshfp.php b/public/ns/sshfp.php index 361768e..29e103b 100644 --- a/public/ns/sshfp.php +++ b/public/ns/sshfp.php @@ -43,13 +43,13 @@ if (nsCommonRequirements() $values = nsParseCommonRequirements(); if (!($_POST['algo'] === "1" OR $_POST['algo'] === "3" OR $_POST['algo'] === "4")) - exit("ERROR: Wrong value for algo"); + userError("Wrong value for algo."); if (!($_POST['type'] === "2")) - exit("ERROR: Wrong value for type"); + userError("Wrong value for type."); if (!(preg_match("/^[a-z0-9]{64}$/", $_POST['fp']))) - exit("ERROR: Wrong value for fp"); + userError("Wrong value for fp."); 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 SSHFP " . $_POST['algo'] . " " . $_POST['type'] . " " . $_POST['fp']); diff --git a/public/ns/tlsa.php b/public/ns/tlsa.php index c93f7b3..b0aaf99 100644 --- a/public/ns/tlsa.php +++ b/public/ns/tlsa.php @@ -54,16 +54,16 @@ if (nsCommonRequirements() $values = nsParseCommonRequirements(); if (!($_POST['use'] >= 0 AND $_POST['use'] <= 3)) - exit("ERROR: Wrong value for use"); + userError("Wrong value for use."); if (!($_POST['selector'] === "0" OR $_POST['selector'] === "1")) - exit("ERROR: Wrong value for selector"); + userError("Wrong value for selector."); if (!($_POST['type'] >= 0 OR $_POST['type'] <= 2)) - exit("ERROR: Wrong value for type"); + userError("Wrong value for type."); if (!(preg_match("/^[a-zA-Z0-9.-]{1,1024}$/", $_POST['content']))) - exit("ERROR: Wrong value for content"); + userError("Wrong value for content."); 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 TLSA " . $_POST['use'] . " " . $_POST['selector'] . " " . $_POST['type'] . " " . $_POST['content']); diff --git a/public/ns/txt.php b/public/ns/txt.php index 37e1f29..d13582f 100644 --- a/public/ns/txt.php +++ b/public/ns/txt.php @@ -18,7 +18,7 @@ if (nsCommonRequirements() $values = nsParseCommonRequirements(); if (!(preg_match("/^[a-zA-Z0-9 =:!%$+\/\()[\]_-]{5,8192}$/", $_POST['txt']))) - exit("ERROR : Wrong caracter or wrong caracter quantity"); + userError("Wrong value for txt."); 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 TXT \"' . $_POST['txt'] . '\"'); diff --git a/public/reg/ds.php b/public/reg/ds.php index 011e995..c3216f1 100644 --- a/public/reg/ds.php +++ b/public/reg/ds.php @@ -78,14 +78,14 @@ if (isset($_POST['zone']) AND isset($_POST['keytag']) AND isset($_POST['algo']) AND !($_POST['algo'] === "15") AND !($_POST['algo'] === "16") ) - exit("Wrong value for algo"); + userError("Wrong value for algo."); $_POST['keytag'] = intval($_POST['keytag']); if ((!preg_match("/^[0-9]{1,6}$/", $_POST['keytag'])) OR !($_POST['keytag'] >= 1) OR !($_POST['keytag'] <= 65535)) - exit("Wrong value for keytag"); + userError("Wrong value for keytag."); if (!$_POST['dt'] === "2" AND !$_POST['dt'] === "4") - exit("Wrong value for dt"); + userError("Wrong value for dt."); checkAbsoluteDomainFormat($_POST['zone']); nsCheckZonePossession($_POST['zone']); diff --git a/public/reg/glue.php b/public/reg/glue.php index 33e0261..d1e3ce4 100644 --- a/public/reg/glue.php +++ b/public/reg/glue.php @@ -45,24 +45,14 @@ if (isset($_POST['action']) AND isset($_POST['subdomain']) AND isset($_POST['suf antiCSRF(); - if (!$suffixes) - exit("ERROR : You don't own any domain"); - - if (!in_array($_POST['suffix'], $suffixes)) - exit("ERROR : You don't own this suffix"); + if (in_array($_POST['suffix'], $suffixes) !== true) + userError("You don't own this domain."); $domain = $_POST['subdomain'] . "." . $_POST['suffix']; checkAbsoluteDomainFormat($domain); - checkIpFormat($_POST['ip']); - - if (filter_var($_POST['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) - $record = "A"; - else if (filter_var($_POST['ip'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) - $record = "AAAA"; - else - exit("Unknown error about IP format"); + $record = checkIpFormat($_POST['ip']); $action = checkAction($_POST['action']); diff --git a/reg.php b/reg.php index 090259b..ce0eb8f 100644 --- a/reg.php +++ b/reg.php @@ -53,7 +53,7 @@ function regCheckDomainPossession($domain) { } if (!($owned === true)) - exit("Erreur : Vous ne possédez pas ce domaine sur le registre !"); + userError("You don't own this domain."); } function regIsFree($domain) {