Mercurial > hg > marc_php
diff marns_import.php @ 1:caa68b502313 draft
Added the MARC DNS server (and small fixes in marcus and anoclaims)
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Thu, 13 Nov 2014 17:22:12 +0100 |
parents | |
children | 5c8c4fa95803 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/marns_import.php Thu Nov 13 17:22:12 2014 +0100 @@ -0,0 +1,128 @@ +<?php +require_once './marccore.php'; + +if (!isset($argv)) $argv = $_SERVER['argv']; +if (count($argv) < 4) { + echo "Usage: ".$argv[0]." [marc-flatfile-database-filename] [domain-name-or-IP-network] [secret-key-or-file] < [zone-file]\n"; + die(); +} + +$marclabel = argtolabel($argv[2]); +switch (ord($marclabel[0])) { + case 1: + $bits = ord($marclabel[5]); + $orgzonename = 'in-addr.arpa'; + if (($bits % 8) != 0) throw new Exception('Invalid prefix length for IPv4 network'); + for ($i = 0; $i < $bits / 8; $i++) $orgzonename = ord($marclabel[$i + 1]).'.'.$orgzonename; + break; + case 2: + $bits = ord($marclabel[17]); + $hex = bin2hex(substr($marclabel, 1, 16)); + $orgzonename = 'ip6.arpa'; + if (($bits % 4) != 0) throw new Exception('Invalid prefix length for IPv6 network'); + for ($i = 0; $i < $bits / 4; $i++) $orgzonename = $hex[$i].'.'.$orgzonename; + break; + case 4: + $orgzonename = substr($marclabel, 1); + break; + default: + throw new Exception('Unsupported zone type'); +} +$orgzonename .= '.'; + +$stdin = fopen('php://stdin', 'r'); +$dnsrecords = array(); +while (($line = fgets($stdin)) !== FALSE) { + $line = rtrim($line, "\r\n"); + if (!strlen($line) || $line[0] == ';') continue; + $token = strtok($line, " \t"); + if ($line[0] != ' ' && $line[0] != "\t") { + if (!strlen($token) || $token[0] == ';') continue; + if ($token == '@' || strcasecmp($token, $orgzonename) == 0) $name = ''; + elseif (strlen($token) > strlen($orgzonename) && strcasecmp(substr($token, -strlen($orgzonename)-1), '.'.$orgzonename) == 0) $name = substr($token, 0, -strlen($orgzonename)-1); + elseif (strlen($token) && $token[strlen($token) - 1] == '.') continue; + else $name = $token; + $name = strtolower($name); + $token = strtok(" \t"); + } + $rr = array(); + if (is_numeric($token)) { + $rr['ttl'] = intval($token); + $token = strtok(" \t"); + if ($token == 'IN') { + $rr['class'] = $token; + $token = strtok(" \t"); + } + } else if ($token == 'IN') { + $rr['class'] = $token; + $token = strtok(" \t"); + if (is_numeric($token)) { + $rr['ttl'] = intval($token); + $token = strtok(" \t"); + } + } + $rr['type'] = strtoupper($token); + switch ($rr['type']) { + case 'A': + case 'AAAA': + $rr['target'] = strtok(" \t"); + break; + case 'CNAME': + case 'NS': + case 'PTR': + $rr['target'] = strtok(" \t"); + break; + case 'MX': + $rr['priority'] = strtok(" \t"); + $rr['target'] = strtok(" \t"); + break; + default: + $rr = NULL; + } + if ($rr === NULL) continue; + if (!isset($dnsrecords[$name])) $dnsrecords[$name] = array(); + $dnsrecords[$name][] = $rr; +} +fclose($stdin); + +print_r($dnsrecords); + +$skey = $argv[3]; +if (file_exists($skey)) { + $skey = file_get_contents($skey); +} else if (strlen($skey) == 64) { + $skey = bin2hex($skey); +} else if ($skey == '-') { + nacl_crypto_sign_ed25519_keypair($skey); +} +if (strlen($skey) != 32 && strlen($skey) != 64) throw new Exception('Invalid signing key specified'); + +error_reporting(E_ALL); +$database = new MARCDatabaseFlatFile(); +$database->Open($argv[1]); +$label = chr(4).'ucis-test.ano'; +$resource = $database->GetResource($marclabel); +if ($resource) { + $resource = $resource->ToArray(); + unset($resource['key']); +} else { + $resource = array('label' => $marclabel, 'value' => array(), 'transfer' => '', 'expiration' => time() + 3600 * 24 * 7); +} +$resource['value']['dnsrecords'] = $dnsrecords; +if (!$database->UpdateResource($resource, $skey)) throw new Exception('Could not update resource'); +$database->Save(); +$database->Close(); + +function argtolabel($t) { + if (preg_match('_^[0-9]{1-3}\.[0-9]{1-3}\.[0-9]{1-3}\.[0-9]{1-3}/[0-9]{1-2}$_', $t)) return ipnettolabel($t); + if (preg_match('_^(((?=.*(::))(?!.*\3.+\3))\3?|([\dA-F]{1,4}(\3|:\b|$)|\2))(?4){5}((?4){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})\z/[0-9]{1-3}_i', $t)) return ipnettolabel($t); + if (preg_match('/^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6}$/i', $t)) return chr(4).strtolower(trim($t, '.')); + throw new Exception('Could not detect label type for '.$t); +} +function ipnettolabel($s) { + $ip = inet_pton(strtok($s, '/')); + $pl = intval(strtok('/')); + if ($pl == 0) throw new Exception('Invalid IP network specified'); + if (strlen($ip) == 4) return chr(1).$ip.chr($pl); + if (strlen($ip) == 16) return chr(2).$ip.chr($pl); +}