diff --git a/fn/common.php b/fn/common.php index bb20853..1491679 100644 --- a/fn/common.php +++ b/fn/common.php @@ -28,6 +28,7 @@ function kdig(string $name, string $type, string $server = NULL): array { '+json', '+timeout=5', '+retry=0', + '+noidn', '-q', $name, '-t', diff --git a/init.php b/init.php index 33c1b82..ddfac3b 100644 --- a/init.php +++ b/init.php @@ -7,7 +7,7 @@ set_error_handler(function ($level, $message, $file = '', $line = 0) { set_exception_handler(function ($e) { error_log((string) $e); http_response_code(500); - echo '

Error

An error occured.

'; + echo '

Error

An error occured.

' . LF; }); register_shutdown_function(function () { // Also catch fatal errors if (($error = error_get_last()) !== NULL) diff --git a/jobs/check.php b/jobs/check.php index 3e9562d..e10c7da 100644 --- a/jobs/check.php +++ b/jobs/check.php @@ -13,9 +13,8 @@ const SUFFIX = 'test.servnest.test.'; const TOR_PROXY = 'socks5h://127.0.0.1:9050'; -exescape([CONF['dns']['kdig_path'], 'torproject.org', 'AAAA'], $output, $return_code); -if (preg_match('/^;; Flags: qr rd ra ad;/Dm', implode("\n", $output)) !== 1) - exit('Unable to do a DNSSEC-validated DNS query.' . LF); +if (kdig(name: 'nlnet.nl', type: 'AAAA')['AD'] !== 1) + exit('DNS queries don\'t seem to be DNSSEC-validated.' . LF); define('COOKIE_FILE', sys_get_temp_dir() . '/cookie-' . bin2hex(random_bytes(16)) . '.txt'); @@ -108,13 +107,8 @@ function testReg(): string { 'domain' => $domain, 'ns' => 'ns1.servnest.invalid.', ]); - exescape([ - CONF['dns']['kdig_path'], - '@' . CONF['reg']['address'], - $domain, - 'NS', - ], $output); - if (preg_match('/[ \t]+ns1\.servnest\.invalid\.$/Dm', implode(LF, $output)) !== 1) + $results = kdig(name: $domain, type: 'NS', server: CONF['reg']['address']); + if ($results['authorityRRs'][0]['rdataNS'] !== 'ns1.servnest.invalid.') exit('Error: /reg/ns: NS record not set' . LF); curlTest('/reg/ns', [ @@ -194,13 +188,10 @@ function testNs(string $domain): void { 'tag' => 'issue', 'value' => 'letsencrypt.org', ]); - exescape([ - CONF['dns']['kdig_path'], - '@' . CONF['reg']['address'], - $domain, - 'CAA', - ], $output); - if (preg_match('/^' . preg_quote($domain, '/') . '[ \t]+7200[ \t]+IN[ \t]+CAA[ \t]+0[ \t]+issue[ \t]+"letsencrypt\.org"$/Dm', implode(LF, $output)) !== 1) + $results = kdig(name: $domain, type: 'CAA', server: CONF['reg']['address']); + if ($results['answerRRs'][0]['TTL'] !== 7200) + exit('Error: /ns/caa: wrong TTL' . LF); + if ($results['answerRRs'][0]['rdataCAA'] !== '0 issue "letsencrypt.org" ') exit('Error: /ns/caa: CAA record not set' . LF); curlTest('/ns/edit', [ @@ -208,13 +199,8 @@ function testNs(string $domain): void { 'records' => 'aaaa.' . $domain . ' 3600 AAAA ' . CONF['ht']['ipv6_address'] . "\r\n" . '@ 86400 NS ' . CONF['ns']['servers'][0] . "\r\n", ]); - exescape([ - CONF['dns']['kdig_path'], - '@' . CONF['reg']['address'], - 'aaaa.' . $domain, - 'AAAA', - ], $output); - if (preg_match('/[ \t]+' . preg_quote(CONF['ht']['ipv6_address'], '/') . '$/Dm', implode(LF, $output)) !== 1) + $results = kdig(name: 'aaaa.' . $domain, type: 'AAAA', server: CONF['reg']['address']); + if ($results['answerRRs'][0]['rdataAAAA'] !== CONF['ht']['ipv6_address']) exit('Error: /ns/edit: AAAA record not set' . LF); } diff --git a/pages.php b/pages.php index 6e567a3..4712238 100644 --- a/pages.php +++ b/pages.php @@ -22,7 +22,7 @@ define('PAGES', [ 'title' => _('Create account'), 'description' => _('Create a new account, and log in with it'), 'require-login' => false, - 'tokens_instance_cost' => 7200, + 'tokens_instance_cost' => 1800, ], 'unregister' => [ 'title' => _('Delete account'), diff --git a/pg-act/ns/zone-add.php b/pg-act/ns/zone-add.php index 90fa410..51f586e 100644 --- a/pg-act/ns/zone-add.php +++ b/pg-act/ns/zone-add.php @@ -5,28 +5,14 @@ $_POST['domain'] = formatAbsoluteDomain($_POST['domain']); if (query('select', 'zones', ['zone' => $_POST['domain']], 'zone') !== []) output(403, _('This zone already exists on the service.')); -exescape([ - CONF['dns']['kdig_path'], - ltrim(strstr($_POST['domain'], '.'), '.'), - 'NS', - '+short', - ...(CONF['ns']['local_only_check'] ? ['@' . CONF['reg']['address']] : []), -], $parentAuthoritatives, $code); -if ($code !== 0) - output(500, 'Unable to query parent name servers.'); -if ($parentAuthoritatives === []) +$parent_authoritatives = array_column(kdig(name: ltrim(strstr($_POST['domain'], '.'), '.'), type: 'NS', server: (CONF['ns']['local_only_check'] ? CONF['reg']['address'] : NULL))['answerRRs'], 'rdataNS'); +if ($parent_authoritatives === []) output(403, _('Parent zone\'s name servers not found.')); -foreach ($parentAuthoritatives as $parentAuthoritative) - checkAbsoluteDomainFormat($parentAuthoritative); +foreach ($parent_authoritatives as $parent_authoritative) + checkAbsoluteDomainFormat($parent_authoritative); -exescape([ - CONF['dns']['kdig_path'], - $_POST['domain'], - 'NS', - '@' . (CONF['ns']['local_only_check'] ? CONF['reg']['address'] : $parentAuthoritatives[0]), - '+noidn' -], $results); -if (preg_match('/^' . preg_quote($_POST['domain'], '/') . '[\t ]+[0-9]{1,8}[\t ]+IN[\t ]+NS[\t ]+(?[0-9a-f]{8})-(?[0-9a-f]{32})\._domain-verification\.' . preg_quote(SERVER_NAME, '/') . '\.$/Dm', implode(LF, $results), $matches) !== 1) +$ns_records = array_column(kdig(name: $_POST['domain'], type: 'NS', server: (CONF['ns']['local_only_check'] ? CONF['reg']['address'] : $parentAuthoritatives[0]))['authorityRRs'], 'rdataNS'); +if (preg_match('/^(?[0-9a-f]{8})-(?[0-9a-f]{32})\._domain-verification\.' . preg_quote(SERVER_NAME, '/') . '\.$/Dm', implode(LF, $ns_records), $matches) !== 1) output(403, _('NS authentication record not found.')); checkAuthToken($matches['salt'], $matches['hash']); diff --git a/pg-act/reg/transfer.php b/pg-act/reg/transfer.php index 12b87e7..4d46619 100644 --- a/pg-act/reg/transfer.php +++ b/pg-act/reg/transfer.php @@ -11,16 +11,8 @@ $domain = formatAbsoluteDomain($_POST['subdomain'] . '.' . $_POST['suffix']); if (query('select', 'registry', ['username' => $_SESSION['id'], 'domain' => $domain], 'domain') !== []) output(403, _('The current account already owns this domain.')); -exescape([ - CONF['dns']['kdig_path'], - $domain, - 'NS', - '@' . CONF['reg']['address'], - '+noidn', -], $results, $code); -if ($code !== 0) - output(500, 'Unable to query registry\'s name servers.'); -if (preg_match('/^' . preg_quote($domain, '/') . '[\t ]+[0-9]{1,8}[\t ]+IN[\t ]+NS[\t ]+(?[0-9a-f]{8})-(?[0-9a-f]{32})\._transfer-verification\.' . preg_quote(SERVER_NAME, '/') . '\.$/Dm', implode(LF, $results), $matches) !== 1) +$ns_records = array_column(kdig(name: $domain, type: 'NS', server: CONF['reg']['address'])['authorityRRs'], 'rdataNS'); +if (preg_match('/^(?[0-9a-f]{8})-(?[0-9a-f]{32})\._transfer-verification\.' . preg_quote(SERVER_NAME, '/') . '\.$/Dm', implode(LF, $ns_records), $matches) !== 1) output(403, _('NS authentication record not found.')); checkAuthToken($matches['salt'], $matches['hash']);