reg.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <?php declare(strict_types=1);
  2. const SUBDOMAIN_REGEX = '^(?!\-)(?!..\-\-)[a-z0-9-]{4,63}(?<!\-)$';
  3. const REG_TEXTAREA_MAX_CHARACTERS = 5000;
  4. const REG_ALLOWED_TYPES = ['NS', 'DS', 'AAAA', 'A'];
  5. function regListUserDomains(): array {
  6. if (isset($_SESSION['id']))
  7. return query('select', 'registry', ['username' => $_SESSION['id']], ['domain']);
  8. return [];
  9. }
  10. function regCheckDomainPossession(string $domain): void {
  11. if (in_array($domain, regListUserDomains(), true) !== true)
  12. output(403, 'You don\'t own this domain on the registry.');
  13. }
  14. function regStripDomain(string $domain, string $content): string {
  15. return preg_replace('/^(?:[a-z0-9._-]+\.)?' . preg_quote($domain, '/') . '[\t ]+.+$/Dm', '', $content);
  16. }
  17. function regDeleteDomain(string $domain, string $user_id): void {
  18. // Delete domain from registry file
  19. $path = CONF['reg']['suffixes_path'] . '/' . regParseDomain($domain)['suffix'] . 'zone';
  20. if (($content = file_get_contents($path)) === false)
  21. output(500, 'Failed to read current registry file.');
  22. if (file_put_contents($path, regStripDomain($domain, $content)) === false)
  23. output(500, 'Failed to write new registry file.');
  24. try {
  25. DB->beginTransaction();
  26. $conditions = [
  27. 'domain' => $domain,
  28. 'username' => $user_id,
  29. ];
  30. insert('registry-history', [
  31. 'domain' => $domain,
  32. 'creation' => query('select', 'registry', $conditions, ['creation'])[0],
  33. 'expiration' => date('Y-m'),
  34. ]);
  35. query('delete', 'registry', $conditions);
  36. DB->commit();
  37. } catch (Exception $e) {
  38. DB->rollback();
  39. output(500, 'Database error.', [$e->getMessage()]);
  40. }
  41. }
  42. function regParseDomain(string $domain): array {
  43. $parts = explode('.', $domain, 2);
  44. $subdomain = $parts[0];
  45. $suffix = $parts[1];
  46. if (array_key_exists($suffix, CONF['reg']['suffixes']) !== true)
  47. output(403, 'This suffix doesn\'t exist.');
  48. return [
  49. 'subdomain' => $subdomain,
  50. 'suffix' => $suffix,
  51. ];
  52. }
  53. function regParseRecord(string $domain, array $record): array {
  54. checkAbsoluteDomainFormat($record['domain']);
  55. if ($record['domain'] !== $_POST['domain']) {
  56. if ($record['type'] !== 'ip')
  57. output(403, _('You can only set a NS/DS record for an apex domain.'));
  58. else if (!str_ends_with($record['domain'], '.' . $domain))
  59. output(403, _('You can\'t set a record for another domain.'));
  60. }
  61. $new_rec = [
  62. $record['domain'],
  63. CONF['reg']['ttl'],
  64. $record['type'],
  65. ];
  66. if ($record['type'] === 'DS') {
  67. if (!in_array($record['algo'], ['8', '13', '14', '15', '16'], true))
  68. output(403, 'Wrong value for <code>algo</code>.');
  69. if ((preg_match('/^[0-9]{1,6}$/D', $record['keytag'])) !== 1 OR !($record['keytag'] >= 1) OR !($record['keytag'] <= 65535))
  70. output(403, 'Wrong value for <code>keytag</code>.');
  71. if ($record['dt'] !== '2' AND $record['dt'] !== '4')
  72. output(403, 'Wrong value for <code>dt</code>.');
  73. if (preg_match('/^(?:[0-9a-fA-F]{64}|[0-9a-fA-F]{96})$/D', $record['key']) !== 1)
  74. output(403, 'Wrong value for <code>key</code>.');
  75. return [
  76. ...$new_rec,
  77. $record['keytag'],
  78. $record['algo'],
  79. $record['dt'],
  80. $record['key'],
  81. ];
  82. }
  83. if ($record['type'] === 'NS')
  84. return [
  85. ...$new_rec,
  86. formatAbsoluteDomain($record['ns']),
  87. ];
  88. if ($record['type'] === 'ip')
  89. return [
  90. $record['domain'],
  91. CONF['reg']['ttl'],
  92. checkIpFormat($record['ip']),
  93. $record['ip'],
  94. ];
  95. }