add outstanding changes

This commit is contained in:
Steffen Vogel 2017-08-05 17:29:32 +02:00
parent c226443d02
commit 20926bb9fb
38 changed files with 664 additions and 803 deletions

View File

@ -1,18 +1,37 @@
RewriteEngine on
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} (/(?:add|delete|update|ip))\.(xml|html|gif|txt|csv|json) [OR]
RewriteCond %{REQUEST_FILENAME} (/admin/(?:cleanup|sync|parse))\.(xml|html|gif|txt|csv|json) [OR]
RewriteCond %{REQUEST_FILENAME} (/admin/get)\.(xml|html|gif|txt|csv|png|json) [OR]
RewriteCond %{REQUEST_FILENAME} (/admin/stats/types)\.(xml|html|gif|txt|csv|png|json)
RewriteRule .* %1.php?format=%2 [QSA]
# Frontend
RewriteCond %{REQUEST_URI} ^/simple$ [OR]
RewriteCond %{REQUEST_URI} ^/expert$
RewriteRule (.*) $1.php [QSA]
# Actions
RewriteCond %{REQUEST_URI} ^/ip [OR]
RewriteCond %{REQUEST_URI} ^/add [OR]
RewriteCond %{REQUEST_URI} ^/delete [OR]
RewriteCond %{REQUEST_URI} ^/update [OR]
RewriteCond %{REQUEST_URI} ^/admin/cleanup [OR]
RewriteCond %{REQUEST_URI} ^/admin/sync [OR]
RewriteCond %{REQUEST_URI} ^/admin/parse [OR]
RewriteCond %{REQUEST_URI} ^/admin/get [OR]
RewriteCond %{REQUEST_URI} ^/admin/stats/types [OR]
RewriteCond %{REQUEST_URI} ^/admin/stats/hosts
RewriteRule (.*)\.(xml|html|gif|png|txt|csv|json|) $1.php?format=$2 [QSA,S=1]
# Tiny URL
RewriteCond %{HTTP_HOST} ^(s|t).(0l.de)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} /(.+)
RewriteRule .* index.php?host=%1
# Querystring
RewriteCond %{QUERY_STRING} !zone=(0l.de)
RewriteCond %{HTTP_HOST} (0l.de)$ [NC]
RewriteRule (.*)(\?)? $1?zone=%1 [QSA]
RewriteCond %{HTTP_HOST} (0l.de)$
RewriteRule (.*)(\?)? $1?zone=%1 [QSA]
RewriteCond %{QUERY_STRING} !host=[a-z0-9.-]+
RewriteCond %{HTTP_HOST} !^(d|dns|sddns|u|url)\.(0l.de)$ [NC]
RewriteCond %{HTTP_HOST} ([a-z0-9.-]+)\.(0l.de)$ [NC]
RewriteRule (.*) $1?host=%1 [QSA]
RewriteCond %{QUERY_STRING} !host=[a-z0-9.-]+
RewriteCond %{HTTP_HOST} !^(d|s|t|ip4|ip6)\.(0l.de)$
RewriteCond %{HTTP_HOST} ([a-z0-9.-]+)\.(0l.de)$
RewriteRule (.*)(\?)? $1?host=%1 [QSA]
ExpiresActive Off

157
add.php
View File

@ -28,87 +28,92 @@ require_once 'include/init.php';
$output = Output::start();
if (array_key_exists($_REQUEST['zone'], $config['sddns']['zones'])) {
$zone = $config['sddns']['zones'][$_REQUEST['zone']];
$type = (empty($_REQUEST['type'])) ? $config['sddns']['std']['type'] : $_REQUEST['type'];
$rdata = (empty($_REQUEST['rdata']) && $type = 'A') ? $_SERVER['REMOTE_ADDR'] : $_REQUEST['rdata'];
$host = (empty($_REQUEST['host'])) ? Host::unique($zone, $db) : new Host($_REQUEST['host'], $zone);
$pw = (empty($_REQUEST['pw'])) ? randomString(8) : $_REQUEST['pw'];
if (isset($_REQUEST['lifetime']) && is_numeric($_REQUEST['lifetime'])) {
$lifetime = (int) $_REQUEST['lifetime'];
// zone
if (!empty($_REQUEST['zone'])) {
if (array_key_exists($_REQUEST['zone'], $config['sddns']['zones'])) {
$zone = $config['sddns']['zones'][$_REQUEST['zone']];
}
else {
$lifetime = $config['sddns']['std']['lifetime'];
}
if ($lifetime < 0) {
$output->add('invalid lifetime', 'error', $lifetime);
$output->send();
die();
}
if (($lifetime > $config['sddns']['max_lifetime'] || $lifetime == 0) && !isAuthentificated()) {
$output->add('lifetime exceeds limit', 'error');
$output->send();
die();
}
if ($host->isRegistred($db)) {
if ($type == 'URL') {
$output->add('host is already registred', 'error', $host);
$output->send();
die();
}
$host = new DBHost($host->isRegistred($db), $db);
$output->add('found existing host' ,'notice', $host);
if (!$host->checkPassword($pw) && !isAuthentificated()) {
$output->add('not authentificated for host', 'error', $host);
$output->send();
die();
}
}
else {
$host = $host->add($pw, $db); // returns new DBHost
$output->add('host added to db' ,'notice', $host);
if (empty($_REQUEST['pw'])) {
$output->add('generated password' ,'notice', $pw);
}
}
if ($type != 'URL') { // pseudo type to create url redirection
$ttl = (empty($_REQUEST['ttl'])) ? $config['sddns']['std']['ttl'] : (int) $_REQUEST['ttl'];
$class = (empty($_REQUEST['class'])) ? $config['sddns']['std']['class'] : $_REQUEST['class'];
$record = new Record($host, $ttl, $class, $type, $rdata);
if (!$record->isRegistred($db)) {
$record = $record->add($db, $lifetime);
$output->add('record added to db', 'success', $record);
$zone->cleanup($db);
$zone->sync($db);
}
else {
$output->add('record already exists in db', 'error', $record);
$output->send();
die();
}
}
else {
$uri = new Uri($rdata, $host);
$uri->frame = (isset($_REQUEST['frame']) && $_REQUEST['frame']) ? 1 : 0;
$uri = $uri->add($db, $lifetime);
$output->add('uri redirection added to db', 'success', $uri);
throw new UserException('invalid zone');
}
}
else {
$output->add('zone not found', 'error', $_REQUEST['zone']);
throw new UserException('missing zone');
}
$output->send();
$host = (!empty($_REQUEST['host'])) ? new Host($_REQUEST['host'], $zone) : Host::unique($zone, $db);
$pw = (!empty($_REQUEST['pw'])) ? $_REQUEST['pw'] : randomString(8);
$ttl = (!empty($_REQUEST['ttl'])) ? (int) $_REQUEST['ttl'] : $config['sddns']['std']['ttl'];
$class = (!empty($_REQUEST['class'])) ? $_REQUEST['class'] : $config['sddns']['std']['class'];
$rdata = (!empty($_REQUEST['rdata'])) ? $_REQUEST['rdata'] : $_SERVER['REMOTE_ADDR'];
?>
// type
if (isset($_REQUEST['type'])) {
if (in_array($_REQUEST['type'], $config['sddns']['types'])) {
$type = $_REQUEST['type'];
}
else {
throw new UserException('invalid type');
}
}
else if (IpV4::isValid($rdata)) {
$type = 'A';
}
else if (IpV6::isValid($rdata)) {
$type = 'AAAA';
}
else {
throw new UserException('missing type');
}
// lifetime
$lifetime = (isset($_REQUEST['lifetime']) && is_numeric($_REQUEST['lifetime'])) ? (int) $_REQUEST['lifetime'] : $config['sddns']['std']['lifetime'];
if ($lifetime < 0) {
throw new UserException('invalid lifetime', $lifetime);
}
else if (($lifetime > $config['sddns']['max_lifetime'] || $lifetime == 0) && !isAuthentificated()) {
throw new UserException('lifetime exceeds limit');
}
// host
if ($host->isRegistred($db)) {
if ($type == 'URL') {
throw new UserException('hosts is already registred', $host);
}
$host = new DBHost($host->isRegistred($db), $db);
$output->add('found existing host' ,'notice', $host);
if (!$host->checkPassword($pw) && !isAuthentificated()) {
throw new AuthentificationException('not authentificated for host', $host);
}
}
else {
$host = $host->add($pw, $db); // returns new DBHost
$output->add('host added to db' ,'notice', $host);
if (empty($_REQUEST['pw'])) {
$output->add('generated password' ,'notice', $pw);
}
}
if ($type == 'URL') { // pseudo type to create url redirection
$uri = new Uri($rdata, $host);
$uri->frame = (isset($_REQUEST['frame']) && $_REQUEST['frame']) ? 1 : 0;
$uri = $uri->add($db, $lifetime);
$output->add('uri redirection added to db', 'success', $uri);
}
else {
$record = new Record($host, $ttl, $class, $type, $rdata);
if ($record->isRegistred($db)) {
throw new UserException('record already exists in db', $record);
}
$record = $record->add($db, $lifetime);
$output->add('record added to db', 'success', $record);
$zone->cleanup($db);
$zone->sync($db);
}

View File

@ -42,7 +42,3 @@ foreach ($zones as $name => $zone) {
$output->add('cleaning zone', 'notice', $zone);
$zone->cleanup($db);
}
$output->send();
?>

View File

@ -255,7 +255,3 @@ else {
}
}
}
$output->send();
?>

View File

@ -59,7 +59,3 @@ if (isAuthentificated()) {
<a href="javascript:installSearchEngine('<?php echo $site['url']; ?>/opensearch.xml');">search plugin</a>
<address><?php echo $_SERVER['SERVER_SIGNATURE']; ?></address>
</div>
<?php
$output->send();
?>

View File

@ -36,7 +36,7 @@ $sql = 'SELECT *
$result = $db->query($sql);
$pattern = '/^queries: info: client ([:.0-9a-f]+)#(\d+): query: ([+.-\w]+) ([A-Z]+) ([0-9A-Z]+) ([-+A-Z]+) \(([:.0-9a-f]+)\)$/';
$pattern = '/^queries: info: client ([:.0-9a-f]+)#(\d+):(?: view \w+:)? query: ([^ ]+) (IN|CH|HS) ([A-Z]+) ([-+A-Z]+) \(([:.0-9a-f]+)\)$/';
$queries = array();
$update = array();
$delete = array();
@ -58,7 +58,7 @@ foreach ($result as $log) {
'options' => $matches[6],
'queried' => strtotime($log['logged']));
$db->execute('INSERT IGNORE INTO queries (ip, port, hostname, class, type, options, queried) VALUES (\'' . $query['ip'] . '\', ' . $query['port'] . ', \'' . $query['hostname'] . '\', \'' . $query['class'] . '\', \'' . $query['type'] . '\', \'' . $query['options'] . '\', \'' . date('Y-m-d H:i:s', $query['queried']) . ')');
$db->execute('INSERT IGNORE INTO queries (ip, port, hostname, class, type, options, queried) VALUES (\'' . $query['ip'] . '\', ' . $query['port'] . ', \'' . $query['hostname'] . '\', \'' . $query['class'] . '\', \'' . $query['type'] . '\', \'' . $query['options'] . '\', \'' . date('Y-m-d H:i:s', $query['queried']) . '\')');
$output->add('query parsed', 'debug', 3, $log['logged'], $log['message']);
array_push($delete, $log['id']);
@ -113,7 +113,3 @@ if ($updated > 0) {
else {
$output->add('no records updated', 'warning');
}
$output->send();
?>

View File

@ -43,7 +43,3 @@ $results = $zone->getRecordsFromNS();
foreach ($results as $result) {
$output->add('', 'data', $result);
}
$output->send();
?>

View File

@ -32,7 +32,3 @@ $result = $db->query('SELECT DISTINCT hostname, COUNT(hostname) AS sum FROM quer
foreach ($result as $row) {
$output->add($row['hostname'], 'data', $row['sum']);
}
$output->send();
?>

View File

@ -67,7 +67,3 @@ else {
$output->add($row['type'], 'data', round(($row['sum'] / $count) * 100, 5) . ' %', $row['sum']);
}
}
$output->send();
?>

View File

@ -38,7 +38,3 @@ foreach ($zones as $zone) {
$output->add('syncing zone', 'notice', $zone);
$zone->sync($db);
}
$output->send();
?>

View File

@ -27,59 +27,96 @@
require_once 'include/init.php';
$output = Output::start();
$pw = @$_REQUEST['pw'];
if (array_key_exists($_REQUEST['zone'], $config['sddns']['zones'])) {
$zone = $config['sddns']['zones'][$_REQUEST['zone']];
// default arguments
$rdata = @$_REQUEST['rdata'];
$class = @$_REQUEST['class'];
$type = @$_REQUEST['type'];
$ttl = @$_REQUEST['ttl'];
if (!empty($_REQUEST['host'])) {
if (list($host) = DBHost::get($db, array('host' => $_REQUEST['host'], 'zone' => $zone))) {
if ($host->checkPassword($pw) || isAuthentificated()) {
if (isset($_REQUEST['class']) && in_array($_REQUEST['class'], $config['sddns']['classes']))
$class = $_REQUEST['class'];
if (isset($_REQUEST['type']) && in_array($_REQUEST['type'], $config['sddns']['types'])) {
$type = $_REQUEST['type'];
if (isset($_REQUEST['rdata']) && Record::isRData($_REQUEST['rdata'], $type))
$rdata = $_REQUEST['rdata'];
}
if (@$type == 'URL' || empty($type)) {
$uris = DBUri::get($db, array('zone' => $zone, 'host' => $host));
foreach ($uris as $uri) {
$uri->delete();
$output->add('uri deleted from db', 'success', $uri);
}
}
if (@$type != 'URL' || empty($type)) {
$records = DBRecord::get($db, array('zone' => $zone, 'host' => $host, 'type' => @$type, 'class' => @$class, 'rdata' => @$rdata));
foreach ($records as $record) {
$record->delete();
$output->add('record deleted from db', 'success', $record);
}
}
$zone->cleanup($db);
$zone->sync($db);
}
else {
$output->add('not authentificated for host', 'error', $host);
}
}
else {
$output->add('host not found', 'error', $_REQUEST['host']);
}
// zone
if (!empty($_REQUEST['zone'])) {
if (array_key_exists($_REQUEST['zone'], $config['sddns']['zones'])) {
$zone = $config['sddns']['zones'][$_REQUEST['zone']];
}
else {
$output->add('no host specified', 'error');
throw new UserException('invalid zone', $_REQUEST['zone']);
}
}
else {
$output->add('zone not found', 'error', $_REQUEST['zone']);
throw new UserException('missing zone');
}
$output->send();
// password
if (!empty($_REQUEST['pw'])) {
$pw = $_REQUEST['pw'];
}
else if (!empty($_SERVER['PHP_AUTH_PW'])) {
$pw = $_SERVER['PHP_AUTH_PW'];
}
else {
throw new AuthentificationException('missing password');
}
?>
// type
if (!empty($type) && !in_array($type, $config['sddns']['types'])) {
throw new UserException('invalid type');
}
else if (IpV4::isValid($rdata)) {
$type = 'A';
}
else if (IpV6::isValid($rdata)) {
$type = 'AAAA';
}
if (!empty($rdata) && !Record::isRdata($rdata, $type)) {
throw new UserException('invalid rdata', $rdata);
}
// search host
if (!empty($_REQUEST['host'])) {
$host = new Host($_REQUEST['host'], $zone);
if ($host->isRegistred($db)) {
$host = new DBHost($host->isRegistred($db), $db);
$output->add('found existing host', 'success', $host);
}
else {
throw new UserException('host not found', $_REQUEST['host']);
}
}
else {
throw new UserException('missing host');
}
if ($host->checkPassword($pw) || isAuthentificated()) {
// search
$uris = DBUri::get($db, array('zone' => $zone, 'host' => $host));
$records = DBRecord::get($db, array('zone' => $zone, 'host' => $host, 'type' => $type, 'class' => $class, 'rdata' => $rdata, 'ttl' => $ttl));
if (empty($type)) {
$entries = array_merge($uris, $records);
}
else if ($type == 'URL') {
$entries = $uris;
}
else {
$entries = $records;
}
if (empty($entries)) {
$output->add('no records found to delete', 'warning');
}
else {
foreach ($entries as $entry) {
$entry->delete();
$output->add('entry deleted from db', 'success', $entry);
}
$zone->cleanup($db);
$zone->sync($db);
}
}
else {
throw new AuthentificationException('not authentificated for host', $host);
}

View File

@ -31,86 +31,109 @@ $output = Output::start('html');
$output->add('hits since launch', 'notice', $site['hits']);
if (isAuthentificated()) {
$output->add('authetificated as', 'notice', $_SERVER['PHP_AUTH_USER']);
$output->add('authentificated as', 'notice', $_SERVER['PHP_AUTH_USER']);
}
$ttl = (isset($_REQUEST['ttl'])) ? $_REQUEST['ttl'] : $config['sddns']['std']['ttl'];
$lifetime = (isset($_REQUEST['lifetime'])) ? $_REQUEST['lifetime'] : (isAuthentificated()) ? 0 : $config['sddns']['std']['lifetime'];
$checkedClass = (isset($_REQUEST['class'])) ? $_REQUEST['class'] : $config['sddns']['std']['class'];
$checkedType = (isset($_REQUEST['type'])) ? $_REQUEST['type'] : $config['sddns']['std']['type'];
$ttl = (!empty($_REQUEST['ttl'])) ? $_REQUEST['ttl'] : $config['sddns']['std']['ttl'];
$lifetime = (!empty($_REQUEST['lifetime'])) ? $_REQUEST['lifetime'] : (isAuthentificated()) ? 0 : $config['sddns']['std']['lifetime'];
$class = (!empty($_REQUEST['class'])) ? $_REQUEST['class'] : $config['sddns']['std']['class'];
$rdata = (!empty($_REQUEST['rdata'])) ? $_REQUEST['rdata'] : $_SERVER['REMOTE_ADDR'];
// type
if (!empty($_REQUEST['type'])) {
if (in_array($_REQUEST['type'], $config['sddns']['types'])) {
$type = $_REQUEST['type'];
}
else {
throw new UserException('invalid type');
}
}
else if (IpV4::isValid($rdata)) {
$type = 'A';
}
else if (IpV6::isValid($rdata)) {
$type = 'AAAA';
}
else {
$type = $config['sddns']['std']['type'];
}
?>
<div id="expert">
<div style="float: right;"><a href="http://dev.0l.de"><img src="images/nulll_small.png" alt="/dev/nulll" /></a></div>
<h1>Tiny DNS & URL</h1>
<h3>Expert interface</h3>
<p>by <a href="http://www.steffenvogel.de">Steffen Vogel</a></p>
<hr style="clear: both;" />
<form onsubmit="submit_expert(this);" method="post">
<div style="float: right;">
<a href="http://dev.0l.de">
<img src="images/nulll_small.png" alt="/dev/nulll" />
</a>
</div>
<h1>Tiny DNS & URL</h1>
<h3>Expert interface</h3>
<p>by <a href="http://www.steffenvogel.de">Steffen Vogel</a></p>
<hr style="clear: both;" />
<form onsubmit="submit_expert(this);" method="post" autocomplete="off" >
<table>
<tr>
<td><label for="command">operation</label></td>
<td><select name="command" size="1">
<?php
foreach ($config['sddns']['cmds'] as $cmd) {
<?php foreach ($config['sddns']['cmds'] as $cmd) {
echo '<option' . ((@$_REQUEST['command'] == $cmd) ? ' selected="selected"' : '') . ' value="' . $cmd . '">' . $cmd . '</option>';
}
?>
} ?>
</select></td>
</tr>
<tr>
<td><label for="format">format</label></td>
<td><select name="format" size="1">
<?php
foreach ($config['sddns']['formats'] as $format) {
<?php foreach ($config['sddns']['formats'] as $format) {
echo '<option value="' . $format . '">' . $format . '</option>';
}
?>
<option><i>none</i></option></select></td>
} ?>
<option><i>none</i></option>
</select></td>
<td><input type="checkbox" name="debug" value="1" /> include debugging information</td>
</tr>
<tr><td><label for="host">hostname</label></td><td><input type="text" name="host" value="<?php echo @$_REQUEST['host']; ?>" />.<select name="zone" size="1">';
<?php
foreach ($config['sddns']['zones'] as $zone) {
echo '<option' . (($_REQUEST['zone'] == $zone->name) ? ' selected="selected"' : '') . ' value="' . $zone->name . '">' . $zone->name . '</option>';
}
?>
</select></td><td>optional; random or servername</td></tr>
<tr><td><label for="ttl">ttl</label></td><td><input type="text" name="ttl" value="<?php echo $ttl; ?>" /> seconds</td><td>time to live in cache; max <?php echo $config['sddns']['max_ttl']; ?> seconds</td></tr>
<tr><td><label for="lifetime">lifetime</label></td><td><input type="text" name="lifetime" value="<?php echo $lifetime; ?>" /> seconds</td><td>lifetime of a record/url without being updated/touched; max <?php echo (isAuthentificated()) ? '0 (unlimited)' : $config['sddns']['max_lifetime']; ?></td></tr>
<tr>
<td><label for="host">hostname</label></td>
<td><input type="text" name="host" value="<?php echo @$_REQUEST['host']; ?>" size="40" />.<select name="zone" size="1">';
<?php foreach ($config['sddns']['zones'] as $zone) {
echo '<option' . (($_REQUEST['zone'] == $zone->name) ? ' selected="selected"' : '') . ' value="' . $zone->name . '">' . $zone->name . '</option>';
} ?>
</select></td>
<td>optional; random or servername</td>
</tr>
<tr>
<td><label for="ttl">ttl</label></td>
<td><input type="text" name="ttl" value="<?php echo $ttl; ?>" size="10"/> seconds</td>
<td>time to live in cache; max <?php echo $config['sddns']['max_ttl']; ?> seconds</td>
</tr>
<tr>
<td><label for="lifetime">lifetime</label></td>
<td><input type="text" name="lifetime" value="<?php echo $lifetime; ?>" size="10" /> seconds</td>
<td>lifetime of a record/url without being updated/touched; max <?php echo (isAuthentificated()) ? '0 (unlimited)' : $config['sddns']['max_lifetime']; ?></td>
</tr>
<tr>
<td><label for="class">class</label></td>
<td><select name="class" size="1">
<?php
foreach ($config['sddns']['classes'] as $class) {
echo '<option' . (($class == $checkedClass) ? ' selected="selected"' : '') . ' value="' . $class . '">' . $class . '</option>';
}
?>
<option><i>all</i></option></select></td>
<?php foreach ($config['sddns']['classes'] as $c) {
echo '<option' . (($c == $class) ? ' selected="selected"' : '') . ' value="' . $c . '">' . $c . '</option>';
} ?>
<option><i>all</i></option></select></td>
</tr>
<tr>
<td><label for="type">type</label></td>
<td><select name="type" size="1">
<?php
foreach ($config['sddns']['types'] as $type) {
echo '<option' . (($type == $checkedType) ? ' selected="selected"' : '') . ' value="' . $type . '">' . $type . '</option>';
}
?>
<option><i>all</i></option></select></td>
<?php foreach ($config['sddns']['types'] as $t) {
echo '<option' . (($t == $type) ? ' selected="selected"' : '') . ' value="' . $t . '">' . $t . '</option>';
} ?>
<option value=""><i>all</i></option></select></td>
</tr>
<tr>
<td><label for="rdata">rdata</label></td>
<td><input value="<?php echo $rdata; ?>" type="text" size="50" name="rdata" /></td>
<td><input type="checkbox" value="1" name="frame" /> hide uri in a frameset</td>
</tr>
<tr>
<td><label for="pw">password</label></td>
<td><input type="password" name="pw" size="50" /></td>
<td>optional; random generated</td>
</tr>
<tr><td><label for="rdata">rdata</label></td><td><input value="<?php echo (empty($_REQUEST['rdata']) && $checkedType == 'A') ? $_SERVER['REMOTE_ADDR'] : @$_REQUEST['rdata']; ?>" type="text" name="rdata" /></td><td><input type="checkbox" value="1" name="frame" /> hide uri in a frameset</td></tr>
<tr><td><label for="pw">password</label></td><td><input type="password" name="pw" /></td><td>optional; random generated</td></tr>
</table>
<input type="submit" />
</form>
@ -126,7 +149,3 @@ $checkedType = (isset($_REQUEST['type'])) ? $_REQUEST['type'] : $config['sddns']
<address><?php echo $_SERVER['SERVER_SIGNATURE']; ?></address>
</div>
<?php
$output->send();
?>

View File

@ -30,7 +30,7 @@ $config['path']['web'] = '';
$config['db']['host'] = 'localhost';
$config['db']['user'] = 'sddns';
$config['db']['pw'] = 'RjRXDa68hnS5A8mX';
$config['db']['db'] = 'st_sddns';
$config['db']['db'] = 'sddns';
$config['db']['tbl']['prefix'] = '';
$config['db']['tbl']['records'] = $config['db']['tbl']['prefix'] . 'records';
$config['db']['tbl']['hosts'] = $config['db']['tbl']['prefix'] . 'hosts';
@ -40,6 +40,7 @@ $config['sddns']['htpasswd'] = $site['path']['server'] . '/../.htpasswd';
$key = array('hmac' => 'gDlXSZtESw78I47O68UEigpPofn0XbpSpo5Vba+9IY38EYagPO/2C2Ch lZL+AvtN/ozRdra+p3+wLOKvVvqdrA==', 'name' => 'info.steffenvogel.de.');
$zones = array('0l.de');
$config['sddns']['ns']['hostname'] = 'localhost';
$config['sddns']['ns']['port'] = 53;
@ -50,7 +51,7 @@ foreach ($zones as $zone) {
$config['sddns']['max_lifetime'] = 6 * 30 * 24 * 60 * 60; // in seconds; 6 months
$config['sddns']['max_ttl'] = 60 * 60; // in seconds; 1 hour
$config['sddns']['classes'] = array('IN', 'CH', 'HS');
$config['sddns']['types'] = array('A', 'AAAA', 'NS', 'TXT', 'MX', 'SRV', 'CNAME', 'LOC', 'HINFO', 'URL' /* pseudo type for url redirection */);
$config['sddns']['types'] = array('A', 'AAAA', 'NS', 'TXT', 'MX', 'SRV', 'CNAME', 'LOC', 'HINFO', 'URL' /* pseudo type for url redirection */);
$config['sddns']['std']['class'] = 'IN';
$config['sddns']['std']['type'] = 'A';
@ -58,6 +59,6 @@ $config['sddns']['std']['ttl'] = 2 * 60; // in seconds; 2 minutes; < max_ttl!
$config['sddns']['std']['lifetime'] = 1 * 30 * 24 * 60 * 60; // in seconds; 1 month; < max_lifetime!
$config['sddns']['cmds'] = array('add', 'delete', 'update'); // available cmds
$config['sddns']['formats'] = array('html', 'xml', 'gif', 'txt', 'csv'); // available formats (keep in sync with .htaccess!)
$config['sddns']['formats'] = array('html', 'xml', 'gif', 'txt', 'csv', 'png', 'json'); // available formats (keep in sync with .htaccess!)
$config['sddns']['blacklist'] = array_merge($zones, array('steffenvogel.de', 'griesm.de', 'vogel.cc', 'icann.org', 'isc.org'));
?>

View File

@ -165,5 +165,3 @@ abstract class Database implements IDatabase {
*/
protected $statements = array();
}
?>

View File

@ -32,7 +32,7 @@ class DBHost extends Host implements DBObject {
private $db;
public function __construct($id, Database $db) {
$config = Registry::get('config');
global $config;
$this->db = $db;
@ -45,16 +45,12 @@ class DBHost extends Host implements DBObject {
parent::__construct($host['hostname'], $config['sddns']['zones'][$host['zone']], $host['generated']);
}
else {
throw new CustomException('Host with id ' . $id . ' not found!');
throw new CustomException('host not found by id', $id);
}
}
public function __destruct() {
//$this->update();
}
public function update() {
$config = Registry::get('config');
global $config;
$sql = 'UPDATE ' . $config['db']['tbl']['hosts'] . '
SET
@ -68,13 +64,13 @@ class DBHost extends Host implements DBObject {
}
public function delete() {
$config = Registry::get('config');
global $config;
if ($this->getRecordsFromDB() > 0) {
throw new UserException('Host has records!');
throw new UserException('host has records');
}
elseif ($this->getUrisFromDB() > 0) {
throw new UserException('Host has uris!');
throw new UserException('host has uris');
}
else {
$sql = 'DELETE FROM ' . $config['db']['tbl']['hosts'] . '
@ -84,7 +80,7 @@ class DBHost extends Host implements DBObject {
}
public function checkPassword($pw) {
$config = Registry::get('config');
global $config;
$sql = 'SELECT password
FROM ' . $config['db']['tbl']['hosts'] . '
@ -105,7 +101,7 @@ class DBHost extends Host implements DBObject {
}
public static function get(Database $db, $filter = false, $order = array()) {
$config = Registry::get('config');
global $config;
$sql = 'SELECT id
FROM ' . $config['db']['tbl']['hosts'] . '
@ -149,5 +145,3 @@ class DBHost extends Host implements DBObject {
return $xmlRecord;
}
}
?>

View File

@ -28,7 +28,6 @@ interface DBObject extends Object {
public static function get(Database $db, $filter);
public function delete();
public function __destruct();
public function update();
}
?>

View File

@ -25,6 +25,7 @@
*/
class DBRecord extends Record implements DBObject {
public $id;
public $lifetime;
public $lastAccessed;
@ -32,13 +33,11 @@ class DBRecord extends Record implements DBObject {
private $db;
public function __construct($id, Database $db) {
$config = Registry::get('config');
global $config;
$this->db = $db;
$sql = 'SELECT *
FROM ' . $config['db']['tbl']['records'] . '
WHERE id = ' . (int) $id;
$sql = 'SELECT * FROM ' . $config['db']['tbl']['records'] . ' WHERE id = ' . (int) $id;
$result = $this->db->query($sql, 1);
$record = $result->first();
@ -51,12 +50,8 @@ class DBRecord extends Record implements DBObject {
parent::__construct($this->host, (int) $record['ttl'], $record['class'], $record['type'], $record['rdata']);
}
public function __destruct() {
//$this->update();
}
public function update() {
$config = Registry::get('config');
global $config;
$sql = 'UPDATE ' . $config['db']['tbl']['records'] . '
SET
@ -70,6 +65,8 @@ class DBRecord extends Record implements DBObject {
WHERE id = ' . (int) $this->id;
$this->db->execute($sql);
return $this->db->affectedRows();
}
public function toXml(DOMDocument $doc) {
@ -84,16 +81,14 @@ class DBRecord extends Record implements DBObject {
}
public function delete() {
$config = Registry::get('config');
$sql = 'DELETE FROM ' . $config['db']['tbl']['records'] . '
WHERE id = ' . (int) $this->id;
global $config;
$sql = 'DELETE FROM ' . $config['db']['tbl']['records'] . ' WHERE id = ' . (int) $this->id;
$this->db->execute($sql);
}
public static function get(Database $db, $filter = false, $order = array()) {
$config = Registry::get('config');
global $config;
$sql = 'SELECT r.id
FROM ' . $config['db']['tbl']['records'] . ' AS r
@ -137,5 +132,3 @@ class DBRecord extends Record implements DBObject {
return $records;
}
}
?>

View File

@ -33,7 +33,7 @@ class DBUri extends Uri implements DBObject {
private $db;
public function __construct($id, Database $db) {
$config = Registry::get('config');
global $config;
$this->db = $db;
@ -54,12 +54,8 @@ class DBUri extends Uri implements DBObject {
parent::__construct($uri['uri'], $this->host);
}
public function __destruct() {
//$this->update();
}
public function update() {
$config = Registry::get('config');
global $config;
$sql = 'UPDATE ' . $config['db']['tbl']['uris'] . '
SET
@ -86,7 +82,7 @@ class DBUri extends Uri implements DBObject {
}
public function delete() {
$config = Registry::get('config');
global $config;
$sql = 'DELETE FROM ' . $config['db']['tbl']['uris'] . '
WHERE id = ' . (int) $this->id;
@ -95,7 +91,7 @@ class DBUri extends Uri implements DBObject {
}
public static function get(Database $db, $filter = false, $order = array()) {
$config = Registry::get('config');
global $config;
$sql = 'SELECT u.id
FROM ' . $config['db']['tbl']['uris'] . ' AS u
@ -134,5 +130,3 @@ class DBUri extends Uri implements DBObject {
return $uris;
}
}
?>

View File

@ -24,11 +24,19 @@
* along with sddns. If not, see <http://www.gnu.org/licenses/>.
*/
class UserException extends CustomException {}
class ValidationException extends UserException {}
class NameServerException extends CustomException {}
class CustomException extends Exception {
protected $data;
function __construct($message = '', $data = array(), $code = 0) {
$this->data = $data;
parent::__construct($message, $code);
}
public function getData() {
return $this->data;
}
public function toXml(DOMDocument $doc) {
$xmlRecord = $doc->createElement('exception');
$xmlRecord->setAttribute('code', $this->code);
@ -37,7 +45,7 @@ class CustomException extends Exception {
$xmlRecord->appendChild($doc->createElement('line', $this->line));
$xmlRecord->appendChild($doc->createElement('file', $this->file));
$xmlRecord->appendChild(backtrace2xml($this->getTrace(), $doc));
$xmlRecord->appendChild(backtrace2xml($this->getTrace(), $doc));
return $xmlRecord;
}
@ -47,4 +55,9 @@ class CustomException extends Exception {
}
}
?>
class NameServerException extends CustomException {}
class UserException extends CustomException {
}
class AuthentificationException extends UserException {}
class ValidationException extends UserException {}
class MissingArgumentException extends UserException {}

View File

@ -30,15 +30,14 @@ function doAuthentification() {
}
function isAuthentificated() {
$config = Registry::get('config');
$htpasswd = file($config['htpasswd']);
global $config;
$htpasswd = file($config['htpasswd'], FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($htpasswd as $line) {
list($user, $crypt) = explode(':', $line);
$salt = substr($crypt, 0, 2);
list($user, $sha1) = explode(':', $line);
if ($user == @$_SERVER['PHP_AUTH_USER'] &&
trim($crypt) == crypt(@$_SERVER['PHP_AUTH_PW'], $salt)) {
$sha1 == '{SHA}' . base64_encode(sha1(@$_SERVER['PHP_AUTH_PW'], true))) {
return true;
}
}
@ -49,9 +48,11 @@ function isAuthentificated() {
function randomString($length, $characters='abcdefghijklmnopqrstuvwxyz0123456789') {
$random_string = '';
$characters_length = strlen($characters);
for($i = 0; $i<$length; $i++) {
$random_string .= $characters[mt_rand(0, $characters_length - 1)];
}
return $random_string;
}
@ -101,4 +102,3 @@ function backtrace2html($traces) {
return $trace;
}
?>

View File

@ -25,6 +25,7 @@
*/
class Host implements Object {
public $punycode;
public $zone;
public $generated;
@ -41,14 +42,14 @@ class Host implements Object {
}
else {
if (strlen($hostname) > 63)
throw new UserException('Invalid hostname: too long');
throw new UserException('invalid hostname', 'too long');
else
throw new UserException('Invalid hostname: ' . idn_to_ascii($hostname));
throw new UserException('invalid hostname', idn_to_ascii($hostname));
}
}
public static function unique(Zone $zone, Database $db) {
$config = Registry::get('config');
global $config;
$sql = 'SELECT hostname
FROM ' . $config['db']['tbl']['hosts'] . '
@ -84,7 +85,7 @@ class Host implements Object {
}
public function isRegistred(Database $db) {
$config = Registry::get('config');
global $config;
$sql = 'SELECT *
FROM ' . $config['db']['tbl']['hosts'] . '
@ -100,7 +101,7 @@ class Host implements Object {
* Database
*/
public function add($pw, Database $db) {
$config = Registry::get('config');
global $config;
$sql = 'INSERT INTO ' . $config['db']['tbl']['hosts'] . ' (hostname, zone, password, generated)
VALUES (
@ -144,4 +145,3 @@ class Host implements Object {
}
}
?>

View File

@ -30,7 +30,6 @@ $site['path']['server'] = dirname(dirname(__FILE__));
require_once $site['path']['server'] . '/include/functions.php';
require_once $site['path']['server'] . '/include/exceptions.php';
require_once $site['path']['server'] . '/include/registry.php';
require_once $site['path']['server'] . '/include/mysql.php';
require_once $site['path']['server'] . '/include/output.php';
@ -50,7 +49,6 @@ require_once $site['path']['server'] . '/include/nameserver.php';
require_once $site['path']['server'] . '/include/zone.php';
require_once $site['path']['server'] . '/include/config.php';
Registry::set('config', $config);
// get relevant runtime information
$site['hostname'] = @$_SERVER['SERVER_NAME'];
@ -58,16 +56,11 @@ $site['path']['web'] = $config['path']['web'];
$site['url'] = 'http://' . $site['hostname'] . $site['path']['web'];
// debug mode
if (@isset($_REQUEST['debug'])) {
if (isset($_REQUEST['debug'])) {
$site['debug'] = (int) $_REQUEST['debug'];
}
else {
if (isAuthentificated()) {
$site['debug'] = 3;
}
else {
$site['debug'] = 0;
}
$site['debug'] = (isAuthentificated()) ? 3 : 0;
}
// simple hit counting
@ -79,8 +72,6 @@ fseek($handle, 0);
fwrite($handle, $site['hits']) ;
fclose($handle);
Registry::set('site', $site);
// set locale
setlocale(LC_TIME, 'de_DE.UTF8');
@ -92,6 +83,3 @@ date_default_timezone_set('Europe/Berlin');
// database
$db = new MySql($config['db']['host'], $config['db']['user'], $config['db']['pw'], $config['db']['db']);
Registry::set('db', $db);
?>

View File

@ -25,6 +25,7 @@
*/
class IpV4 implements Object {
public $tuples = array();
public function __construct($ipString) {
@ -45,7 +46,7 @@ class IpV4 implements Object {
}
public function toHtml() {
return '<a href="http://www.dnsstuff.com/tools/ipall/?tool_id=67&ip=' . $this . '">' . $this . '</a>';
return '<a href="https://www.ultratools.com/tools/ipWhoisLookupResult?ipAddress=' . $this . '">' . $this . '</a>';
}
public function toXml(DOMDocument $doc) {
@ -57,14 +58,15 @@ class IpV4 implements Object {
}
class IpV6 implements Object {
private $ip;
public function __construct($ipString) {
if (self::isValid($ipString)) {
$this->ip = $ipString;
$this->ip = strtolower($ipString);
}
else {
throw new ValidationException('Invalid IP: ', $ipString);
throw new ValidationException('invalid ip', $ipString);
}
}
@ -77,7 +79,7 @@ class IpV6 implements Object {
}
public function toHtml() {
return '<a href="http://www.dnsstuff.com/tools/ipall/?tool_id=67&ip=' . $this . '">' . $this . '</a>';
return '<a href="https://www.ultratools.com/tools/ipv6InfoResult?ipAddress=' . $this . '">' . $this . '</a>';
}
public function toXml(DOMDocument $doc) {
@ -87,5 +89,3 @@ class IpV6 implements Object {
return $xmlIpV6;
}
}
?>

View File

@ -29,8 +29,7 @@ require_once dirname(__FILE__) . '/db.php';
/**
* @brief base exception for mysql queries
*/
class MySqlException extends DatabaseException
{
class MySqlException extends DatabaseException {
function __construct($message = null, $code = 0) {
$message = sprintf('%04d: %s', mysql_errno(), mysql_error());
parent::__construct($message, mysql_errno());
@ -40,8 +39,7 @@ class MySqlException extends DatabaseException
/**
* @brief resultset of a mysql query
*/
class MySqlResult extends DBResultSet
{
class MySqlResult extends DBResultSet {
/**
* @param resource $resource mysql resultset
*/
@ -81,6 +79,7 @@ class MySql extends Database {
public function connect($host, $user, $pw) {
$this->close();
$__er = error_reporting(E_ERROR);
if (!$this->resource = mysql_connect($host, $user, rawurlencode($pw))) {
error_reporting($__er);
throw new MySqlException();
@ -93,8 +92,10 @@ class MySql extends Database {
* @brief close database connection
*/
public function close() {
if (!$this->resource)
if (!$this->resource) {
return;
}
mysql_close($this->resource);
$this->resource = false;
}
@ -104,8 +105,10 @@ class MySql extends Database {
* @param string $name database name
*/
public function select($db) {
if (!mysql_select_db($db, $this->resource))
if (!mysql_select_db($db, $this->resource)) {
throw new MySqlException();
}
$this->database = $db;
}
@ -115,11 +118,13 @@ class MySql extends Database {
* @return mixed
*/
public function execute($sql) {
if ($output = Registry::get('output'))
$output->add('db query', 'debug', 8, $sql);
global $output;
if (!($result = mysql_unbuffered_query($sql, $this->resource)))
if ($output) $output->add('db query', 'debug', 8, $sql);
if (!($result = mysql_unbuffered_query($sql, $this->resource))) {
throw new MySqlException();
}
return $result;
}
@ -132,8 +137,10 @@ class MySql extends Database {
* @return TDatabaseResultSet
*/
public function query($sql, $limit = -1, $offset = 0) {
if ($limit != -1)
if ($limit != -1) {
$sql .= sprintf(' LIMIT %d, %d', $offset, $limit);
}
return new MySqlResult($this->execute($sql));
}
@ -153,5 +160,3 @@ class MySql extends Database {
return mysql_affected_rows($this->resource);
}
}
?>

View File

@ -25,6 +25,7 @@
*/
class NameServer implements Object {
protected $process;
protected $pipes;
@ -34,83 +35,103 @@ class NameServer implements Object {
public $port;
public function __construct($hostname, $port = 53) {
$config = Registry::get('config');
global $config;
$this->hostname = $hostname;
$this->port = $port;
}
protected function initialize() {
$output = Registry::get('output');
$config = Registry::get('config');
protected function open() {
global $output;
$descriptorspec = array(0 => array('pipe', 'r'), // stdin
1 => array('pipe', 'w'), // stdout
2 => array('pipe', 'w')); // stderr
$descriptorspec = array(
0 => array('pipe', 'r'), // stdin
1 => array('pipe', 'w'), // stdout
2 => array('pipe', 'w') // stderr
);
if ($this->isRunning()) {
$this->close();
throw new NameserverException('ns connection' , 'already established');
}
$this->process = proc_open('nsupdate -d -v', $descriptorspec, $this->pipes);
$output->add('ns initialized', 'debug', 1);
if ($this->isRunning()) {
$output->add('ns connection', 'debug', 3, 'established');
}
else {
throw new NameserverException('ns connection', 'failed');
}
return true;
}
protected function close() {
global $output;
if (!$this->isRunning()) {
throw new NameserverException('there is no running process to close');
}
fclose($this->pipes[0]);
$result['stdout'] = stream_get_contents($this->pipes[1]);
$result['stderr'] = stream_get_contents($this->pipes[2]);
fclose($this->pipes[1]);
fclose($this->pipes[2]);
$result['code'] = proc_close($this->process);
$output->add('ns connection', 'debug', 3, 'closed');
$this->process = null;
return $result;
}
protected function initQueue() {
global $config;
$this->queue = array();
$this->queueCommand('server ' . $this->hostname . ' ' . $this->port);
$this->queueCommand('class ' . $config['sddns']['std']['class']);
$this->queueCommand('ttl ' . $config['sddns']['std']['ttl']);
}
protected final function close() {
$output = Registry::get('output');
if ($this->isRunning()) {
fclose($this->pipes[0]);
$return['stdout'] = stream_get_contents($this->pipes[1]);
$return['stderr'] = stream_get_contents($this->pipes[2]);
fclose($this->pipes[1]);
fclose($this->pipes[2]);
$return['code'] = proc_close($this->process);
$this->process = null;
$output->add('connection to ns closed', 'debug', 1);
return $return;
}
else {
throw new CustomException('There is no running process to close.');
private function sendQueue() {
while ($command = array_shift($this->queue)) {
$this->sendCommand($command);
}
}
protected final function sendQueue() {
$output = Registry::get('output');
$site = Registry::get('site');
protected function commitQueue() {
$this->open();
if ($output->debug > 2)
$this->queueCommand('show');
$this->queueCommand('show');
$this->queueCommand('send');
$output->add('send queue to ns', 'debug', 1);
$this->queueCommand('answer');
$this->sendQueue();
return $this->close();
}
protected final function queueCommand($command) {
$output = Registry::get('output');
private function sendCommand($command) {
global $output;
if (!$this->isRunning()) {
$this->initialize();
}
fwrite($this->pipes[0], $command . "\n");
$this->queue[] = $command;
fwrite($this->pipes[0], $command . "\n");
if (substr($command, 0, 3) != 'key') {
$output->add('added command to ns queue', 'debug', 3, $command);
$output->add('ns command', 'debug', 3, $command);
}
}
protected function queueCommand($command) {
$this->queue[] = $command;
}
protected function add(Record $record) {
$this->queueCommand('update add ' . $record);
}
@ -124,15 +145,16 @@ class NameServer implements Object {
}
public function query($host, $type = 'A', $class = 'IN') {
$output = Registry::get('output');
$config = Registry::get('config');
global $output;
global $config;
$cli = 'dig -c ' . $class . ' -t ' . $type . ' ' . $host . ' @' . $this->hostname . ' +noall +answer';
$output->add('execute dig', 'debug', 2, $cli);
exec(escapeshellcmd($cli), $return, $returnCode);
if ($returnCode != 0)
throw new NameServerException('dig query failed with code: ' . $returnCode);
if ($returnCode != 0) {
throw new NameServerException('dig query', 'failed', $returnCode);
}
$results = array();
@ -170,4 +192,3 @@ class NameServer implements Object {
}
}
?>

View File

@ -32,4 +32,3 @@ interface Object {
}
?>

View File

@ -25,6 +25,7 @@
*/
class JsonOutput extends Output {
public function __construct($debug) {
parent::__construct('application/json', 'UTF-8', $debug);
}
@ -48,6 +49,7 @@ class JsonOutput extends Output {
}
class XmlOutput extends Output {
public function __construct($debug) {
parent::__construct('text/xml', 'UTF-8', $debug);
}
@ -86,11 +88,12 @@ class XmlOutput extends Output {
// needs JPGraph >= 3.0.7!
class GraphOutput extends Output {
private $graph;
public function __construct($debug) {
parent::__construct('text/html', 'UTF-8', $debug);
$site = Registry::get('site');
global $site;
require_once 'jpgraph/jpgraph.php';
}
@ -110,20 +113,21 @@ class GraphOutput extends Output {
public function showGraph() {
if (@isset($this->graph))
if (isset($this->graph))
$this->graph->Stroke();
}
protected function getOutput() { // TODO beautify
if (count($this->getMessages()) > 0) {
echo '<pre>';
print_r($this->getMessages());
echo '</pre>';
}
protected function getOutput() { // TODO
if (count($this->getMessages()) > 0) {
echo '<pre>';
print_r($this->getMessages());
echo '</pre>';
}
}
}
class GifOutput extends Output {
public function __construct() {
parent::__construct('image/gif');
}
@ -140,6 +144,7 @@ class GifOutput extends Output {
}
class PlainLineOutput extends Output {
public function __construct($debug, $fields = array('index', 'time', 'type', 'description', 'data'), $delimiter = "\t", $lineDelimiter = "\n", $escape = true) {
parent::__construct('text/plain', 'UTF-8', $debug);
$this->fields = $fields;
@ -159,7 +164,7 @@ class PlainLineOutput extends Output {
foreach ($this->fields as $fieldIndex => $field) {
switch ($field) {
case 'type':
fwrite($fd, $message['type']);
fwrite($fd, '[' . $message['type'] . ']');
break;
case 'index':
@ -175,9 +180,7 @@ class PlainLineOutput extends Output {
break;
case 'data':
foreach ($message['data'] as $object) {
fwrite($fd, $this->delimiter . $object);
}
fwrite($fd, implode(', ', $message['data']));
break;
default:
fwrite($fd, $message[$field]);
@ -199,6 +202,7 @@ class PlainLineOutput extends Output {
}
class HtmlOutput extends Output {
public function __construct($debug) {
parent::__construct('text/html', 'UTF-8', $debug);
@ -206,7 +210,8 @@ class HtmlOutput extends Output {
}
protected function getOutput() {
$site = Registry::get('site');
global $site;
$columnCount = 0;
$messages = $this->getMessages();
$html = ob_get_clean();
@ -271,6 +276,7 @@ class HtmlOutput extends Output {
}
abstract class Output {
protected $messages = array();
public $debug = 0;
public $format;
@ -282,7 +288,6 @@ abstract class Output {
$this->encoding = $encoding;
$this->debug = $debug;
if ($this->contentType != null)
header('Content-type: ' . $this->contentType . (($this->encoding != null) ? '; charset=' . $this->encoding : ''));
}
@ -300,8 +305,7 @@ abstract class Output {
}
for ($i = ($type == 'debug') ? 3 : 2; $i < $argc; $i++) {
if (empty($argv[$i]))
continue;
if (empty($argv[$i])) continue;
if (!is_array($argv[$i])) {
$message['data'][] = $argv[$i];
@ -315,19 +319,16 @@ abstract class Output {
}
protected function getMessages($exclude = true, $args = null) {
$types = array('notice', 'success', 'error', 'exception', 'warning', 'data'); // 'debug');
$types = array('notice', 'success', 'error', 'exception', 'warning', 'data', 'debug');
if ($args == null)
$args = array();
$args = array();
if ($exclude)
$types = array_diff($types, $args);
else
$types = $args;
$types = ($exclude) ? array_diff($types, $args) : $args;
$messages = array();
foreach ($this->messages as $message) {
if (in_array($message['type'], $types) || ($message['type'] == 'debug' && $message['level'] <= $this->debug)) {
if (in_array($message['type'], $types) && ($message['type'] != 'debug' || $message['level'] <= $this->debug)) {
$messages[] = $message;
}
}
@ -342,17 +343,13 @@ abstract class Output {
break;
case 'txt':
return new PlainLineOutput($debug, array('index', 'time', 'type', 'description', 'data'), "\t", "\n");
return new PlainLineOutput($debug, array('type', 'description', 'data'), "\t", "\n");
break;
case 'csv':
return new PlainLineOutput($debug, array('time', 'type', 'description', 'data'), ";", "\n");
break;
case 'dyndns':
return new DynDnsOutput();
break;
case 'png':
return new GraphOutput($debug);
break;
@ -374,27 +371,26 @@ abstract class Output {
static function start($forced = null) {
global $argc;
$site = Registry::get('site');
global $site;
if (isset($forced))
$format = $forced;
elseif (isset($argc))
$format = 'txt';
elseif ($_SERVER['SERVER_NAME'] === 'members.dyndns.org')
$format = 'dyndns';
elseif (empty($_REQUEST['format']) || @$_REQUEST['format'] == 'php')
$format = 'html';
else
$format = $_REQUEST['format'];
$output = self::getInstance($format, $site['debug']);
Registry::set('output', $output);
// errorhandling
set_exception_handler(array($output, 'exception_handler'));
set_error_handler(array($output, 'error_handler'), E_ALL);
// shutdown
register_shutdown_function(array($output, 'send'));
// debugging
$parameters = array();
foreach ($_REQUEST as $parName => $parValue) {
@ -408,16 +404,27 @@ abstract class Output {
}
function exception_handler($exception) {
$this->add('unhandled ' . get_class($exception), 'exception', (array) $exception);
$this->debug = 7; // increase verbosity in case of an exception
$this->send();
if (is_subclass_of($exception, 'CustomException')) {
$this->add($exception->getMessage(), 'error', $exception->getData());
}
else {
$this->debug = 7; // increase verbosity in case of an exception
$this->add(get_class($exception), 'exception', (array) $exception);
}
switch (get_class($exception)) {
case 'CustomException': http_response_code(500); break;
case 'UserException': http_response_code(400); break;
case 'ValidationException': http_response_code(400); break;
case 'AuthentificationException': http_response_code(403); break;
default: $code = 500; break;
}
exit(1);
}
function error_handler($errno, $errstr, $errfile, $errline) {
if (($errno & error_reporting()) == 0) {
return;
}
else {
if (($errno & error_reporting()) != 0) {
switch ($errno) {
case E_USER_WARNING:
case E_WARNING:
@ -438,7 +445,7 @@ abstract class Output {
$str = $type;
break;
}
$this->add($str . ' in script', $type, $errstr . ' in ' . $errfile . ':' . $errline);
$this->add($str, $type, $errstr . ' in ' . $errfile . ':' . $errline);
}
}
@ -448,5 +455,3 @@ abstract class Output {
echo $this->getOutput();
}
}
?>

View File

@ -25,32 +25,33 @@
*/
class Record implements Object {
public $host, $ttl, $class, $type, $rdata;
/*
* Constructors
*/
public function __construct(Host $host, $ttl, $class, $type, $rdata) {
$config = Registry::get('config');
global $config;
$this->host = $host;
if (is_int($ttl) && $ttl > 0 && $ttl <= $config['sddns']['max_ttl']) {
$this->ttl = $ttl;
} else {
throw new UserException('Invalid ttl: ' . $ttl);
throw new UserException('Invalid ttl', $ttl);
}
if (in_array($class, $config['sddns']['classes'])) {
$this->class = $class;
} else {
throw new UserException('Invalid class: ' . $class);
throw new UserException('invalid class', $class);
}
if (in_array($type, $config['sddns']['types'])) {
$this->type = $type;
} else {
throw new UserException('Invalid type: ' . $type);
throw new UserException('invalid type', $type);
}
$this->setRData($rdata);
@ -72,22 +73,31 @@ class Record implements Object {
$this->rdata = $rdata;
}
} else {
throw new ValidationException('Invalid rdata: ' . $rdata);
throw new ValidationException('invalid rdata', $rdata);
}
}
public function setTtl($ttl) {
if (is_numeric($ttl)) {
$this->ttl = $ttl;
}
else {
throw new ValidationException('invalid ttl', $ttl);
}
}
/*
* Database
*/
public function add(Database $db, $lifetime) {
$config = Registry::get('config');
$db = Registry::get('db');
global $config;
if ($this->host->isRegistred($db)) {
$host = new DBHost($this->host->isRegistred($db), $db);
}
else {
throw new UserException('Unable to add record: Host is not registred!');
throw new UserException('unable to add record: host is not registred!');
}
$sql = 'INSERT INTO ' . $config['db']['tbl']['records'] . ' (host_id, ttl, class, type, rdata, created, last_accessed, lifetime, ip) VALUES (
@ -144,7 +154,7 @@ class Record implements Object {
}
public function isRegistred(Database $db) {
$config = Registry::get('config');
global $config;
$sql = 'SELECT *
FROM ' . $config['db']['tbl']['records'] . ' AS r
@ -200,7 +210,7 @@ class Record implements Object {
}
public function toHtml() {
$html = '' . $this->host->toHtml() . '&nbsp;<a target="_blank" href="/?host=' . $this->host->toPunycode() . '&ttl=' . $this->ttl . '&type=' . $this->type . '&class=' . $this->class . '&rdata=' . $this->rdata . '">' . $this->ttl . '&nbsp;' . $this->class . '&nbsp;' . $this->type . '</a>';
$html = '' . $this->host->toHtml() . '&nbsp;<a target="_blank" href="/expert?host=' . $this->host->toPunycode() . '&ttl=' . $this->ttl . '&type=' . $this->type . '&class=' . $this->class . '&rdata=' . $this->rdata . '">' . $this->ttl . '&nbsp;' . $this->class . '&nbsp;' . $this->type . '</a>';
$html .= '&nbsp;';
switch ($this->type) {
@ -211,7 +221,7 @@ class Record implements Object {
case 'NS':
case 'CNAME':
$html .= '<a target="_blank" href="http://' . $this->rdata . '">' . $this->rdata . '</a>';
$html .= '<a target="_blank" href="https://www.ultratools.com/whois/whoisDashboardResult?domainName=' . $this->rdata . '">' . $this->rdata . '</a>';
break;
default:
@ -223,4 +233,3 @@ class Record implements Object {
}
}
?>

View File

@ -1,108 +0,0 @@
<?php
/**
* Registry class
*
* provides a global key value registry
*
* @copyright 2013 Steffen Vogel
* @license http://www.gnu.org/licenses/gpl.txt GNU Public License
* @author Steffen Vogel <post@steffenvogel.de>
* @link http://www.steffenvogel.de
*/
/*
* This file is part of sddns
*
* sddns is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* sddns is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sddns. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Registry class to pass global variables between classes.
*/
abstract class Registry {
/**
* Object registry provides storage for shared objects
*
* @var array
*/
private static $registry = array();
/**
* Adds a new variable to the Registry.
*
* @param string $key Name of the variable
* @param mixed $value Value of the variable
* @throws Exception
* @return bool
*/
public static function set($key, $value) {
if (!isset(self::$registry[$key])) {
self::$registry[$key] = $value;
return true;
} else {
throw new Exception('Unable to set variable `' . $key . '`. It was already set.');
}
}
/**
* Returns the value of the specified $key in the Registry.
*
* @param string $key Name of the variable
* @return mixed Value of the specified $key
*/
public static function get($key)
{
if (isset(self::$registry[$key])) {
return self::$registry[$key];
}
return null;
}
/**
* Returns the whole Registry as an array.
*
* @return array Whole Registry
*/
public static function getAll()
{
return self::$registry;
}
/**
* Removes a variable from the Registry.
*
* @param string $key Name of the variable
* @return bool
*/
public static function remove($key)
{
if (isset(self::$registry[$key])) {
unset(self::$registry[$key]);
return true;
}
return false;
}
/**
* Removes all variables from the Registry.
*
* @return void
*/
public static function removeAll()
{
self::$registry = array();
return;
}
}
?>

View File

@ -2,17 +2,6 @@ function submit_expert(form) {
form.action = form.elements['command'].value + '.' + form.format.value;
}
function submit_simple(form) {
var matches = form.elements['rdata'].value.match(/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/);
if (matches) {
form.elements['type'].value = 'A';
}
else {
form.elements['type'].value = 'URL';
}
}
function fade(elm) {
if (ie) {
elm.style.filter = 'alpha(opacity=' + op + ')';

View File

@ -40,8 +40,7 @@ class Uri implements Object {
* Database
*/
public function add(Database $db, $lifetime) {
$config = Registry::get('config');
$db = Registry::get('db');
global $config;
$sql = 'INSERT INTO ' . $config['db']['tbl']['uris'] . ' (host_id, uri, frame, lifetime, last_accessed, created, ip) VALUES(
' . $this->host->id . ',
@ -99,4 +98,3 @@ class Uri implements Object {
}
}
?>

View File

@ -25,6 +25,7 @@
*/
class Zone extends NameServer implements Object {
public $name;
private $key;
@ -35,8 +36,8 @@ class Zone extends NameServer implements Object {
$this->key = $key;
}
protected function initialize() {
parent::initialize();
protected function initQueue() {
parent::initQueue();
$this->queueCommand('zone ' . $this->name);
$this->queueCommand('key ' . $this->key['name'] . ' ' . $this->key['hmac']);
@ -46,8 +47,8 @@ class Zone extends NameServer implements Object {
* Maintenance
*/
function cleanup(Database $db) {
$config = Registry::get('config');
$output = Registry::get('output');
global $config;
global $output;
// expired records & records without host
$sql = 'DELETE r FROM ' . $config['db']['tbl']['records'] . ' AS r
@ -96,13 +97,21 @@ class Zone extends NameServer implements Object {
}
public function sync(Database $db) {
$output = Registry::get('output');
global $output;
$nsRecords = $this->getRecordsFromNS();
$dbRecords = $this->getRecordsFromDB($db);
$delete = array_diff($nsRecords, $dbRecords);
$add = array_diff($dbRecords, $nsRecords);
if (empty($delete) && empty($add)) {
$output->add('ns in sync', 'success');
return true;
}
$this->initQueue();
foreach ($add as $record) {
$this->add($record);
$output->add('record added to ns', 'success', $record);
@ -112,49 +121,47 @@ class Zone extends NameServer implements Object {
$this->delete($record);
$output->add('record deleted from ns', 'success', $record);
}
}
public function add(Record $record) {
global $output;
$config = Registry::get('config');
$result = $this->commitQueue();
if ($record->host->zone->name != $this->name) {
throw new NameServerException('zone mismatch: trying to add record "' . $record . '" to zone "' . $this . '"');
}
parent::add($record);
$nsresult = $this->sendQueue();
if ($nsresult['code'] != 0) {
throw new NameServerException('error during nameserver update: ' . $nsresult['stderr']);
if ($result['code']) {
throw new NameServerException('error during nameserver update', $result);
}
if (isAuthentificated()) {
$output->add('ns response', 'debug', 7, $result); // includes key!
}
$output->add('ns synced', 'success');
return true;
}
public function add(Record $record) {
global $config;
if ($record->host->zone->name != $this->name) {
throw new NameServerException('zone mismatch: trying to add record ' . $record . ' to zone ' . $this);
}
parent::add($record);
}
public function delete(Record $record) {
$config = Registry::get('config');
global $config;
if ($record->host->zone->name != $this->name) {
throw new NameServerException('zone mismatch: trying to delete record ' . $record . ' from zone ' . $this);
}
parent::delete($record);
$nsresult = $this->sendQueue();
if($nsresult['code'] != 0) {
throw new NameServerException('error during nameserver update: ' . $nsresult['stderr']);
}
return true;
}
/*
* Getter
*/
public function getRecordsFromNS() {
$config = Registry::get('config');
$output = Registry::get('output');
global $config;
global $output;
$records = array();

View File

@ -26,11 +26,13 @@
require_once 'include/init.php';
$filter = array('host' => @$_REQUEST['host'], 'zone' => @$_REQUEST['zone']);
$uris = DBUri::get($db, $filter);
$host = $_REQUEST['host'];
$zone = $_REQUEST['zone'];
$uris = DBUri::get($db, array('host' => $host, 'zone' => $zone));
if (count($uris) == 1) {
$uri = $uris[0];
$uri = array_pop($uris);
$uri->accessed++;
$uri->lastAccessed = time();
@ -38,7 +40,8 @@ if (count($uris) == 1) {
$fullUri = $uri->uri;
if ($_SERVER['REQUEST_URI'] != '/') {
$realHost = substr($_SERVER['HTTP_HOST'], 0 , -(strlen($zone)+1));
if (!in_array($realHost, array('s', 't')) && $_SERVER['REQUEST_URI'] != '/') {
$fullUri .= $_SERVER['REQUEST_URI'];
}
@ -62,12 +65,10 @@ else {
$qs = '?' . $_SERVER['QUERY_STRING'];
}
if (!isAuthentificated()) {
header('Location: simple' . $qs);
if (isAuthentificated()) {
header('Location: /expert' . $qs);
}
else {
header('Location: expert' . $qs);
header('Location: /simple' . $qs);
}
}
?>

3
ip.php
View File

@ -39,6 +39,3 @@ else {
$output->add('your current internet ip address', 'notice', $ip);
$output->send();
?>

View File

@ -42,13 +42,9 @@ the credentials required.</p>
<hr>
<address>' . $_SERVER['SERVER_SIGNATURE'] . '</address>';
$output->add('authentification failed', 'error', 'user', @$_SERVER['PHP_AUTH_USER']);
throw new AuthentificationException('authentification failed', @$_SERVER['PHP_AUTH_USER']);
} else {
echo '<script language="javascript">window.setTimeout(function(){ window.location="/expert"; }, 1500);</script>';
$output->add('authentificated as', 'notice', $_SERVER['PHP_AUTH_USER']);
}
$output->send();
?>

View File

@ -1,83 +0,0 @@
#!/bin/bash
##
 # SDDNS update script
 #
 # @copyright 2013 Steffen Vogel
 # @license http://www.gnu.org/licenses/gpl.txt GNU Public License
 # @author Steffen Vogel <post@steffenvogel.de>
 # @link http://www.steffenvogel.de
 ##
##
 # This file is part of sddns
 #
 # sddns is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # any later version.
 #
 # sddns is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with sddns. If not, see <http://www.gnu.org/licenses/>.
 ##
################################################################################
# Requirements
#
# This script requires bash, curl, dig
#
################################################################################
# Settings
# Password
PW=Ohsongei6
# Hostname
HOST=sea
# Zone
ZONE=0l.de
# Interface
IF=eth0
# Get ipv6 ip
#IPV6=$(ip -6 -o addr show dev eth0 dynamic scope global | sed -r 's/\s+/\t/g' | cut -f4 | cut -f1 -d/)
################################################################################
# Expert settings
# Time to live value in seconds for the record
TTL=120
# Type (A for IPv4, AAAA for IPv6)
TYPE=AAAA
################################################################################
# Do not touch anything under this!
RDATA=$(dig $TYPE $HOST.$ZONE @0l.de +short)
# 2: eth0 inet6 2a02:908:f318:7201:52e5:49ff:feeb:740c/64 scope global dynamic valid_lft 7200sec preferred_lft 3600sec
REGEX='^[0-9]+: +([^ ]+) +(inet6?) +([^/]+)/([0-9]+) +scope +global +dynamic +valid_lft +([0-9]+)sec +preferred_lft +([0-9]+)sec'
ip -o monitor address | while read ACTION; do
if [[ ${ACTION} =~ ${REGEX} ]]; then
if [ "${RDATA}" != "${BASH_REMATCH[3]}" ]; then
WAIT=1
RDATA=${BASH_REMATCH[3]}
URL="http://d.0l.de/update.txt?host=$HOST&zone=$ZONE&ttl=$TTL&class=IN&type=$TYPE&rdata=$RDATA&pw=$PW"
echo "Updating record: $URL"
while [ $WAIT -lt 60 ] && ! curl "$URL" 2>/dev/null | sed 's/^/ /'; do
sleep $WAIT; # wait until interface is ready
WAIT=$(($WAIT*2))
done
else
echo "Address hasn't changed: ${RDATA}"
fi
fi
done

View File

@ -27,49 +27,39 @@
require_once 'include/init.php';
$output = Output::start('html');
?>
<div id="simple">
<header>
<a href="http://dev.0l.de"><img src="images/nulll_small.png" alt="/dev/nulll" /></a>
<h1>Tiny DNS &amp; URL</h1>
</header>
<header>
<a href="http://dev.0l.de"><img src="images/nulll_small.png" alt="/dev/nulll" /></a>
<h1>Tiny DNS &amp; URL</h1>
</header>
<form name="formular" action="add.html" method="post" >
<dl>
<dt><label for="host"><a href="http://de.wikipedia.org/wiki/Domain">Domain</a></label></dt>
<dd>
<input type="text" name="host" value="<?php echo @$_REQUEST['host']; ?>" tabindex="1" size="19" style="width:134px" />.
<select name="zone" size="1">
<?php foreach ($config['sddns']['zones'] as $zone) {
$selected = $_REQUEST['zone'] == $zone->name ? ' selected="selected"' : ''; ?>
<option <?php echo $selected; ?> value="<?php echo $zone->name; ?>"><?php echo $zone->name; ?></option>
<?php } ?>
</select>
</dd>
<dt><label for="rdata"><a href="http://de.wikipedia.org/wiki/IP-Adresse">IP</a> / <a href="http://de.wikipedia.org/wiki/Uniform_Resource_Locator">URL</a></label></dt>
<dd><input style="width:217px" tabindex="2" value="<?php echo isset($_REQUEST['rdata']) ? $_REQUEST['rdata'] : $_SERVER['REMOTE_ADDR']; ?>" type="text" name="rdata" /></dd>
<form name="formular" action="add.html" method="post" onsubmit="submit_simple(this);">
<dl>
<dt><label for="host"><a href="http://de.wikipedia.org/wiki/Domain">Domain</a></label></dt>
<dd>
<input type="text" name="host" value="<?php echo @$_REQUEST['host']; ?>" tabindex="1" size="19" style="width:134px" />.
<select name="zone" size="1">
<?php foreach ($config['sddns']['zones'] as $zone) {
$selected = $_REQUEST['zone'] == $zone->name ? ' selected="selected"' : ''; ?>
<option <?php echo $selected; ?> value="<?php echo $zone->name; ?>"><?php echo $zone->name; ?></option>
<?php } ?>
</select>
</dd>
<?php if (!isAuthentificated()) { ?>
<dt><label for="pw">Password</label></dt>
<dd><input style="width:217px" tabindex="3" type="password" name="pw" /></dd>
<?php } ?>
</dl>
<dt><label for="rdata"><a href="http://de.wikipedia.org/wiki/IP-Adresse">IP</a> / <a href="http://de.wikipedia.org/wiki/Uniform_Resource_Locator">URL</a></label></dt>
<dd><input style="width:217px" tabindex="2" value="<?php echo isset($_REQUEST['rdata']) ? $_REQUEST['rdata'] : $_SERVER['REMOTE_ADDR']; ?>" type="text" name="rdata" /></dd>
<?php
if (!isAuthentificated()) {
echo '<dt><label for="pw">Password</label></dt>
<dd><input style="width:217px" tabindex="3" type="password" name="pw" /></dd>';
}
?>
</dl>
<input type="submit" tabindex="4" value="register" />
<input type="hidden" name="type" value="A" />
</form>
<footer>
<p>by <a href="http://www.steffenvogel.de">Steffen Vogel</a> - <a href="expert">expert mode</a> - <a href="http://dev.0l.de/projects/sddns/usage">usage help</a> - <a href="javascript:installSearchEngine('<?php echo $site['url']; ?>/opensearch.xml');">searchplugin</a></p>
<a href="javascript:u='http://d.0l.de/add.html?type=URL&rdata='+encodeURIComponent(location.href);h=encodeURIComponent(window.getSelection().toString().replace(/[\s\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2E\x2F\x3A\x3B\x3C\x3D\x3F\x40\x5B\x5C\x5D\x5E\x5F\x60\x7B\x7C\x7C\x7D\x7E]+/gi,'-').replace(/^\-+/,'').replace(/\-+$/,''));if(!h){h=prompt('Subdomain','');}if(h){u+='&host='+h;}location.href=u"><img style="margin-bottom: -6px;" src="images/bookmarklet.gif" alt="/dev/nulll/url bookmarklet" /></a> drag this button into your bookmarks for creating tiny urls easily!<p>
</footer>
<input type="submit" tabindex="4" value="register" />
</form>
<footer>
<p>by <a href="http://www.steffenvogel.de">Steffen Vogel</a> - <a href="expert">expert mode</a> - <a href="http://dev.0l.de/projects/sddns/usage">usage help</a> - <a href="javascript:installSearchEngine('<?php echo $site['url']; ?>/opensearch.xml');">searchplugin</a></p>
<a href="javascript:u='http://d.0l.de/add.html?type=URL&rdata='+encodeURIComponent(location.href);h=encodeURIComponent(window.getSelection().toString().replace(/[\s\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2E\x2F\x3A\x3B\x3C\x3D\x3F\x40\x5B\x5C\x5D\x5E\x5F\x60\x7B\x7C\x7C\x7D\x7E]+/gi,'-').replace(/^\-+/,'').replace(/\-+$/,''));if(!h){h=prompt('Subdomain','');}if(h){u+='&host='+h;}location.href=u"><img style="margin-bottom: -6px;" src="images/bookmarklet.gif" alt="/dev/nulll/url" /></a> drag this button into your bookmarks for creating tiny urls easily!<p>
</footer>
</div>
<?php
$output->send();
?>

View File

@ -25,104 +25,111 @@
*/
require_once 'include/init.php';
$output = Output::start();
// default arguments
$ttl = (!empty($_REQUEST['ttl'])) ? $_REQUEST['ttl'] : $config['sddns']['std']['ttl'];
$class = (!empty($_REQUEST['class'])) ? $_REQUEST['class'] : $config['sddns']['std']['class'];
$rdata = (!empty($_REQUEST['rdata'])) ? $_REQUEST['rdata'] : $_SERVER['REMOTE_ADDR'];
// zone
if (!empty($_REQUEST['zone'])) {
if (array_key_exists($_REQUEST['zone'], $config['sddns']['zones'])) {
$zone = $config['sddns']['zones'][$_REQUEST['zone']];
}
else {
throw new UserException('invalid zone', $_REQUEST['zone']);
}
}
else {
throw new UserException('missing zone');
}
// password
if (!empty($_REQUEST['pw'])) {
$pw = $_REQUEST['pw'];
}
else {
$pw = false;
}
// host & zone
if (!empty($_REQUEST['hostname'])) {
foreach ($config['sddns']['zones'] as $z) {
if (substr($_REQUEST['hostname'], -strlen($z->name)) === $z->name) {
$zone = $z;
list($host) = DBHost::get($db, array('host' => substr($_REQUEST['hostname'], 0, -(strlen($zone->name)+1)), 'zone' => $zone));
}
}
}
elseif (!empty($_REQUEST['host'])) {
if (array_key_exists($_REQUEST['zone'], $config['sddns']['zones'])) {
$zone = $config['sddns']['zones'][$_REQUEST['zone']];
list($host) = DBHost::get($db, array('host' => $_REQUEST['host'], 'zone' => $zone));
}
}
// class
if (!empty($_REQUEST['class']) && in_array($_REQUEST['class'], $config['sddns']['classes']))
$class = $_REQUEST['class'];
// type, rdata and ip
if (!empty($_REQUEST['type']) && in_array($_REQUEST['type'], $config['sddns']['types'])) {
$type = $_REQUEST['type'];
}
// ip
if (!empty($_REQUEST['myip'])) {
$rdata = $_REQUEST['myip'];
}
elseif (!empty($_REQUEST['ip'])) {
$rdata = $_REQUEST['ip'];
}
elseif (!empty($_REQUEST['rdata'])) {
$rdata = $_REQUEST['rdata'];
else if (!empty($_SERVER['PHP_AUTH_PW'])) {
$pw = $_SERVER['PHP_AUTH_PW'];
}
else {
$rdata = $_SERVER['REMOTE_ADDR'];
throw new AuthentificationException('missing password');
}
if (!empty($zone)) {
if (!empty($host)) {
if ($type == 'URL') {
$entries = DBUri::get($db, array('host' => $host, 'zone' => $zone));
}
else {
$entries = DBRecord::get($db, array('host' => $host, 'zone' => $zone, 'class' => @$class, 'type' => @$type));
}
// type
if (!empty($_REQUEST['type'])) {
if (in_array($_REQUEST['type'], $config['sddns']['types'])) {
$type = $_REQUEST['type'];
}
else {
throw new UserException('invalid type');
}
}
else if (IpV4::isValid($rdata)) {
$type = 'A';
}
else if (IpV6::isValid($rdata)) {
$type = 'AAAA';
}
else {
throw new UserException('missing type');
}
if (count($entries) > 0) {
$output->add('found host', 'success', $host);
// search host
if (!empty($_REQUEST['host'])) {
$host = new Host($_REQUEST['host'], $zone);
if (isAuthentificated() || $host->checkPassword($pw)) {
if ($type == 'URL') {
if (isset($_REQUEST['frame'])) $entries[0]->frame = $_REQUEST['frame'];
$entries[0]->setUri($rdata);
}
else {
$entries[0]->setRData($rdata);
}
$entries[0]->lastAccessed = time();
$entries[0]->update();
$output->add('entry updated in db', 'success', $entries[0]);
for ($i = 1; $i < count($entries); $i++) {
$records[$i]->delete();
$output->add('record deleted from db', 'warning', $entries[$i]);
}
$zone->cleanup($db);
$zone->sync($db);
}
else {
$output->add('not authentificated for host', 'error', $host);
}
}
else {
$output->add('nothing found to update', 'warning');
}
if ($host->isRegistred($db)) {
$host = new DBHost($host->isRegistred($db), $db);
$output->add('found existing host', 'success', $host);
}
else {
$output->add('host not found', 'error', @$_REQUEST['host'], @$_REQUEST['hostname']);
throw new UserException('host not found', $_REQUEST['host']);
}
}
else {
$output->add('zone not found', 'error', $_REQUEST['host'], $_REQUEST['zone']);
throw new UserException('missing host');
}
$output->send();
?>
if ($host->checkPassword($pw) || isAuthentificated()) {
// search entries
if ($type == 'URL') {
$entries = DBUri::get($db, array('host' => $host, 'zone' => $zone));
}
else {
$entries = DBRecord::get($db, array('host' => $host, 'zone' => $zone, 'class' => $class, 'type' => $type));
}
if (empty($entries)) {
throw new UserException('no records found to update');
}
$entry = array_shift($entries);
if ($type == 'URL') {
$entry->frame = (isset($_REQUEST['frame']) && $_REQUEST['frame']) ? 1 : 0;
$entry->setUri($rdata);
}
else {
$entry->setTtl($ttl);
$entry->setRData($rdata);
}
$entry->lastAccessed = time();
$entry->update();
$output->add('entry updated in db', 'success', $entry);
// delete other entries
foreach ($entries as $entry) {
$entry->delete();
$output->add('record deleted from db', 'warning', $entry);
}
$zone->cleanup($db);
$zone->sync($db);
}
else {
throw new AuthentificationException('not authentificated for host', $host);
}