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);
+}