This commit is contained in:
Nikita 2018-05-20 19:23:06 +00:00 committed by GitHub
commit 86bf539d37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 796 additions and 531 deletions

3
.gitignore vendored
View file

@ -1,3 +1,6 @@
includes/config.inc.php includes/config.inc.php
nsedit.sublime* nsedit.sublime*
etc etc
composer.lock
vendor
.php_cs.cache

37
.php_cs Normal file
View file

@ -0,0 +1,37 @@
<?php
$finder = PhpCsFixer\Finder::create()
->in('.')
->exclude('jquery-ui');
return PhpCsFixer\Config::create()
->setFinder($finder)
->setRules([
'@PSR2' => true,
'array_syntax' => ['syntax' => 'short'],
'concat_space' => ['spacing' => 'one'],
'include' => true,
'new_with_braces' => true,
'no_empty_statement' => true,
'no_extra_consecutive_blank_lines' => true,
'no_leading_import_slash' => true,
'no_leading_namespace_whitespace' => true,
'no_multiline_whitespace_around_double_arrow' => true,
'no_multiline_whitespace_before_semicolons' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_trailing_comma_in_singleline_array' => true,
'no_unused_imports' => true,
'no_whitespace_in_blank_line' => true,
'object_operator_without_whitespace' => true,
'ordered_imports' => true,
'standardize_not_equals' => true,
'ternary_operator_spaces' => true,
'phpdoc_order' => true,
'phpdoc_types' => true,
'phpdoc_add_missing_param_annotation' => true,
'single_quote' => true,
'standardize_not_equals' => true,
'ternary_operator_spaces' => true,
'lowercase_cast' => true,
'no_empty_comment' => true,
'no_empty_phpdoc' => true,
]);

13
.travis.yml Normal file
View file

@ -0,0 +1,13 @@
language: php
php:
- 5.6
- 7.0
- 7.1
- 7.2
before_script:
- composer self-update
- phpenv config-rm xdebug.ini
- composer install --no-interaction --prefer-dist
script:
- php vendor/bin/grumphp run

10
composer.json Normal file
View file

@ -0,0 +1,10 @@
{
"name":"tuxis-ie/nsedit",
"license": "GPL-2.0-only",
"description": "DNS Editor working with PowerDNS's new API",
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.11",
"phpro/grumphp": "^0.14.0",
"jakub-onderka/php-parallel-lint": "^1.0"
}
}

9
grumphp.yml Normal file
View file

@ -0,0 +1,9 @@
parameters:
git_dir: .
bin_dir: vendor/bin
tasks:
composer:
no_check_lock: true
phplint:
phpcsfixer2:
config: '.php_cs'

View file

@ -1,12 +1,14 @@
<?php <?php
include_once('includes/config.inc.php'); include_once 'includes/config.inc.php';
class ApiHandler { class ApiHandler
public function __construct() { {
public function __construct()
{
global $apiip, $apiport, $apipass, $apiproto, $apisslverify; global $apiip, $apiport, $apipass, $apiproto, $apisslverify;
$this->headers = Array(); $this->headers = [];
$this->hostname = $apiip; $this->hostname = $apiip;
$this->port = $apiport; $this->port = $apiport;
$this->auth = $apipass; $this->auth = $apipass;
@ -14,19 +16,22 @@ class ApiHandler {
$this->sslverify = $apisslverify; $this->sslverify = $apisslverify;
$this->curlh = curl_init(); $this->curlh = curl_init();
$this->method = 'GET'; $this->method = 'GET';
$this->content = FALSE; $this->content = false;
$this->apiurl = ''; $this->apiurl = '';
} }
public function addheader($field, $content) { public function addheader($field, $content)
{
$this->headers[$field] = $content; $this->headers[$field] = $content;
} }
private function authheaders() { private function authheaders()
{
$this->addheader('X-API-Key', $this->auth); $this->addheader('X-API-Key', $this->auth);
} }
private function apiurl() { private function apiurl()
{
$tmp = new ApiHandler(); $tmp = new ApiHandler();
$tmp->url = '/api'; $tmp->url = '/api';
@ -35,40 +40,42 @@ class ApiHandler {
if ($tmp->json[0]['version'] <= 1) { if ($tmp->json[0]['version'] <= 1) {
$this->apiurl = $tmp->json[0]['url']; $this->apiurl = $tmp->json[0]['url'];
} else { } else {
throw new Exception("Unsupported API version"); throw new Exception('Unsupported API version');
} }
} }
private function curlopts() { private function curlopts()
{
$this->authheaders(); $this->authheaders();
$this->addheader('Accept', 'application/json'); $this->addheader('Accept', 'application/json');
if(defined('curl_reset')) { if (defined('curl_reset')) {
curl_reset($this->curlh); curl_reset($this->curlh);
} else { } else {
$this->curlh = curl_init(); $this->curlh = curl_init();
} }
curl_setopt($this->curlh, CURLOPT_HTTPHEADER, Array()); curl_setopt($this->curlh, CURLOPT_HTTPHEADER, []);
curl_setopt($this->curlh, CURLOPT_RETURNTRANSFER, 1); curl_setopt($this->curlh, CURLOPT_RETURNTRANSFER, 1);
if (strcasecmp($this->proto, 'https')) { if (strcasecmp($this->proto, 'https')) {
curl_setopt($this->curlh, CURLOPT_SSL_VERIFYPEER, $this->sslverify); curl_setopt($this->curlh, CURLOPT_SSL_VERIFYPEER, $this->sslverify);
} }
$setheaders = Array(); $setheaders = [];
foreach ($this->headers as $k => $v) { foreach ($this->headers as $k => $v) {
array_push($setheaders, join(": ", Array($k, $v))); array_push($setheaders, join(': ', [$k, $v]));
} }
curl_setopt($this->curlh, CURLOPT_HTTPHEADER, $setheaders); curl_setopt($this->curlh, CURLOPT_HTTPHEADER, $setheaders);
} }
private function baseurl() { private function baseurl()
return $this->proto.'://'.$this->hostname.':'.$this->port.$this->apiurl; {
return $this->proto . '://' . $this->hostname . ':' . $this->port . $this->apiurl;
} }
private function go() { private function go()
{
$this->curlopts(); $this->curlopts();
if ($this->content) { if ($this->content) {
@ -91,31 +98,31 @@ class ApiHandler {
break; break;
} }
curl_setopt($this->curlh, CURLOPT_URL, $this->baseurl().$this->url); curl_setopt($this->curlh, CURLOPT_URL, $this->baseurl() . $this->url);
$return = curl_exec($this->curlh); $return = curl_exec($this->curlh);
$code = curl_getinfo($this->curlh, CURLINFO_HTTP_CODE); $code = curl_getinfo($this->curlh, CURLINFO_HTTP_CODE);
$json = json_decode($return, 1); $json = json_decode($return, 1);
if (isset($json['error'])) { if (isset($json['error'])) {
throw new Exception("API Error $code: ".$json['error']); throw new Exception("API Error $code: " . $json['error']);
} elseif ($code < 200 || $code >= 300) { } elseif ($code < 200 || $code >= 300) {
if ($code == 401) { if ($code == 401) {
throw new Exception("Authentication failed. Have you configured your authmethod correct?"); throw new Exception('Authentication failed. Have you configured your authmethod correct?');
} }
throw new Exception("Curl Error: $code ".curl_error($this->curlh)); throw new Exception("Curl Error: $code " . curl_error($this->curlh));
} }
$this->json = $json; $this->json = $json;
} }
public function call() { public function call()
{
if (substr($this->url, 0, 1) != '/') { if (substr($this->url, 0, 1) != '/') {
$this->url = '/'.$this->url; $this->url = '/' . $this->url;
} }
$this->apiurl(); $this->apiurl();
$this->url = str_replace($this->apiurl, '', $this->url); $this->url = str_replace($this->apiurl, '', $this->url);
$this->go(); $this->go();
} }
} }

View file

@ -1,20 +1,23 @@
<?php <?php
include_once('ApiHandler.php'); include_once 'ApiHandler.php';
class PdnsAPI { class PdnsAPI
public function __construct() { {
public function __construct()
{
$this->http = new ApiHandler(); $this->http = new ApiHandler();
} }
public function listzones($q = FALSE) { public function listzones($q = false)
{
$api = clone $this->http; $api = clone $this->http;
$api->method = 'GET'; $api->method = 'GET';
if ($q) { if ($q) {
$api->url = "/servers/localhost/search-data?q=*".$q."*&max=25"; $api->url = '/servers/localhost/search-data?q=*' . $q . '*&max=25';
$api->call(); $api->call();
$ret = Array(); $ret = [];
$seen = Array(); $seen = [];
foreach ($api->json as $result) { foreach ($api->json as $result) {
if (isset($seen[$result['zone_id']])) { if (isset($seen[$result['zone_id']])) {
@ -28,13 +31,14 @@ class PdnsAPI {
return $ret; return $ret;
} }
$api->url = "/servers/localhost/zones"; $api->url = '/servers/localhost/zones';
$api->call(); $api->call();
return $api->json; return $api->json;
} }
public function loadzone($zoneid) { public function loadzone($zoneid)
{
$api = clone $this->http; $api = clone $this->http;
$api->method = 'GET'; $api->method = 'GET';
$api->url = "/servers/localhost/zones/$zoneid"; $api->url = "/servers/localhost/zones/$zoneid";
@ -43,7 +47,8 @@ class PdnsAPI {
return $api->json; return $api->json;
} }
public function exportzone($zoneid) { public function exportzone($zoneid)
{
$api = clone $this->http; $api = clone $this->http;
$api->method = 'GET'; $api->method = 'GET';
$api->url = "/servers/localhost/zones/$zoneid/export"; $api->url = "/servers/localhost/zones/$zoneid/export";
@ -52,7 +57,8 @@ class PdnsAPI {
return $api->json; return $api->json;
} }
public function savezone($zone) { public function savezone($zone)
{
$api = clone $this->http; $api = clone $this->http;
// We have to split up RRSets and Zoneinfo. // We have to split up RRSets and Zoneinfo.
// First, update the zone // First, update the zone
@ -78,14 +84,15 @@ class PdnsAPI {
// Then, update the rrsets // Then, update the rrsets
if (count($zone['rrsets']) > 0) { if (count($zone['rrsets']) > 0) {
$api->method = 'PATCH'; $api->method = 'PATCH';
$api->content = json_encode(Array('rrsets' => $zone['rrsets'])); $api->content = json_encode(['rrsets' => $zone['rrsets']]);
$api->call(); $api->call();
} }
return $this->loadzone($zone['id']); return $this->loadzone($zone['id']);
} }
public function deletezone($zoneid) { public function deletezone($zoneid)
{
$api = clone $this->http; $api = clone $this->http;
$api->method = 'DELETE'; $api->method = 'DELETE';
$api->url = "/servers/localhost/zones/$zoneid"; $api->url = "/servers/localhost/zones/$zoneid";
@ -94,8 +101,9 @@ class PdnsAPI {
return $api->json; return $api->json;
} }
public function getzonekeys($zoneid) { public function getzonekeys($zoneid)
$ret = array(); {
$ret = [];
$api = clone $this->http; $api = clone $this->http;
$api->method = 'GET'; $api->method = 'GET';
$api->url = "/servers/localhost/zones/$zoneid/cryptokeys"; $api->url = "/servers/localhost/zones/$zoneid/cryptokeys";
@ -103,14 +111,15 @@ class PdnsAPI {
$api->call(); $api->call();
foreach ($api->json as $key) { foreach ($api->json as $key) {
if (!isset($key['active'])) if (!isset($key['active'])) {
continue; continue;
}
$key['dstxt'] = $zoneid . ' IN DNSKEY '.$key['dnskey']."\n\n"; $key['dstxt'] = $zoneid . ' IN DNSKEY ' . $key['dnskey'] . "\n\n";
if (isset($key['ds'])) { if (isset($key['ds'])) {
foreach ($key['ds'] as $ds) { foreach ($key['ds'] as $ds) {
$key['dstxt'] .= $zoneid . ' IN DS '.$ds."\n"; $key['dstxt'] .= $zoneid . ' IN DS ' . $ds . "\n";
} }
unset($key['ds']); unset($key['ds']);
} }
@ -119,7 +128,4 @@ class PdnsAPI {
return $ret; return $ret;
} }
} }
?>

View file

@ -1,7 +1,9 @@
<?php <?php
class Zone { class Zone
public function __construct() { {
public function __construct()
{
$this->id = ''; $this->id = '';
$this->name = ''; $this->name = '';
$this->kind = ''; $this->kind = '';
@ -12,13 +14,14 @@ class Zone {
$this->soa_edit_api = ''; $this->soa_edit_api = '';
$this->keyinfo = ''; $this->keyinfo = '';
$this->account = ''; $this->account = '';
$this->zone = FALSE; $this->zone = false;
$this->nameservers = Array(); $this->nameservers = [];
$this->rrsets = Array(); $this->rrsets = [];
$this->masters = Array(); $this->masters = [];
} }
public function parse($data) { public function parse($data)
{
$this->setId($data['id']); $this->setId($data['id']);
$this->setName($data['name']); $this->setName($data['name']);
$this->setKind($data['kind']); $this->setKind($data['kind']);
@ -26,10 +29,12 @@ class Zone {
$this->setAccount($data['account']); $this->setAccount($data['account']);
$this->setSerial($data['serial']); $this->setSerial($data['serial']);
$this->url = $data['url']; $this->url = $data['url'];
if (isset($data['soa_edit']) && $data['soa_edit'] != "") if (isset($data['soa_edit']) && $data['soa_edit'] != '') {
$this->setSoaEdit($data['soa_edit']); $this->setSoaEdit($data['soa_edit']);
if (isset($data['soa_edit_api']) && $data['soa_edit_api'] != "") }
$this->setSoaEditApi($data['soa_edit_api'], True); if (isset($data['soa_edit_api']) && $data['soa_edit_api'] != '') {
$this->setSoaEditApi($data['soa_edit_api'], true);
}
foreach ($data['masters'] as $master) { foreach ($data['masters'] as $master) {
$this->addMaster($master); $this->addMaster($master);
@ -50,82 +55,96 @@ class Zone {
} }
} }
public function importData($data) { public function importData($data)
{
$this->zone = $data; $this->zone = $data;
} }
public function setKeyinfo($info) { public function setKeyinfo($info)
{
$this->keyinfo = $info; $this->keyinfo = $info;
} }
public function addNameserver($nameserver) { public function addNameserver($nameserver)
{
foreach ($this->nameservers as $ns) { foreach ($this->nameservers as $ns) {
if ($nameserver == $ns) { if ($nameserver == $ns) {
throw new Exception("We already have this as a nameserver"); throw new Exception('We already have this as a nameserver');
} }
} }
array_push($this->nameservers, $nameserver); array_push($this->nameservers, $nameserver);
} }
public function setSerial($serial) { public function setSerial($serial)
{
$this->serial = $serial; $this->serial = $serial;
} }
public function setSoaEdit($soaedit) { public function setSoaEdit($soaedit)
{
$this->soa_edit = $soaedit; $this->soa_edit = $soaedit;
} }
public function setSoaEditApi($soaeditapi, $overwrite=False) { public function setSoaEditApi($soaeditapi, $overwrite=false)
if (isset($this->soa_edit_api) and $this->soa_edit_api != "") { {
if ($overwrite === False) { if (isset($this->soa_edit_api) and $this->soa_edit_api != '') {
return False; if ($overwrite === false) {
return false;
} }
} }
$this->soa_edit_api = $soaeditapi; $this->soa_edit_api = $soaeditapi;
} }
public function setName($name) { public function setName($name)
{
$this->name = $name; $this->name = $name;
} }
public function setKind($kind) { public function setKind($kind)
{
$this->kind = $kind; $this->kind = $kind;
} }
public function setAccount($account) { public function setAccount($account)
{
$this->account = $account; $this->account = $account;
} }
public function setDnssec($dnssec) { public function setDnssec($dnssec)
{
$this->dnssec = $dnssec; $this->dnssec = $dnssec;
} }
public function setId($id) { public function setId($id)
{
$this->id = $id; $this->id = $id;
} }
public function addMaster($ip) { public function addMaster($ip)
{
foreach ($this->masters as $master) { foreach ($this->masters as $master) {
if ($ip == $master) { if ($ip == $master) {
throw new Exception("We already have this as a master"); throw new Exception('We already have this as a master');
} }
} }
array_push($this->masters, $ip); array_push($this->masters, $ip);
} }
public function eraseMasters() { public function eraseMasters()
$this->masters = Array(); {
$this->masters = [];
} }
public function addRRSet($name, $type, $content, $disabled = FALSE, $ttl = 3600, $setptr = FALSE) { public function addRRSet($name, $type, $content, $disabled = false, $ttl = 3600, $setptr = false)
if ($this->getRRSet($name, $type) !== FALSE) { {
throw new Exception("This rrset already exists."); if ($this->getRRSet($name, $type) !== false) {
throw new Exception('This rrset already exists.');
} }
$rrset = new RRSet($name, $type, $content, $disabled, $ttl, $setptr); $rrset = new RRSet($name, $type, $content, $disabled, $ttl, $setptr);
array_push($this->rrsets, $rrset); array_push($this->rrsets, $rrset);
} }
public function addRecord($name, $type, $content, $disabled = FALSE, $ttl = 3600, $setptr = FALSE) { public function addRecord($name, $type, $content, $disabled = false, $ttl = 3600, $setptr = false)
{
$rrset = $this->getRRSet($name, $type); $rrset = $this->getRRSet($name, $type);
if ($rrset) { if ($rrset) {
@ -138,7 +157,8 @@ class Zone {
return $this->getRecord($name, $type, $content); return $this->getRecord($name, $type, $content);
} }
public function getRecord($name, $type, $content) { public function getRecord($name, $type, $content)
{
$rrset = $this->getRRSet($name, $type); $rrset = $this->getRRSet($name, $type);
foreach ($rrset->exportRecords() as $record) { foreach ($rrset->exportRecords() as $record) {
if ($record['content'] == $content) { if ($record['content'] == $content) {
@ -150,21 +170,22 @@ class Zone {
return $record; return $record;
} }
} }
} }
public function getRRSet($name, $type) { public function getRRSet($name, $type)
{
foreach ($this->rrsets as $rrset) { foreach ($this->rrsets as $rrset) {
if ($rrset->name == $name and $rrset->type == $type) { if ($rrset->name == $name and $rrset->type == $type) {
return $rrset; return $rrset;
} }
} }
return FALSE; return false;
} }
public function rrsets2records() { public function rrsets2records()
$ret = Array(); {
$ret = [];
foreach ($this->rrsets as $rrset) { foreach ($this->rrsets as $rrset) {
foreach ($rrset->exportRecords() as $record) { foreach ($rrset->exportRecords() as $record) {
@ -180,16 +201,17 @@ class Zone {
return $ret; return $ret;
} }
public function export() { public function export()
$ret = Array(); {
$ret = [];
$ret['account'] = $this->account; $ret['account'] = $this->account;
$ret['nameservers'] = $this->nameservers; $ret['nameservers'] = $this->nameservers;
$ret['kind'] = $this->kind; $ret['kind'] = $this->kind;
$ret['name'] = $this->name; $ret['name'] = $this->name;
if (isset($this->soa_edit) && $this->soa_edit != "") { if (isset($this->soa_edit) && $this->soa_edit != '') {
$ret['soa_edit'] = $this->soa_edit; $ret['soa_edit'] = $this->soa_edit;
} }
if (isset($this->soa_edit_api) && $this->soa_edit_api != "") { if (isset($this->soa_edit_api) && $this->soa_edit_api != '') {
$ret['soa_edit_api'] = $this->soa_edit_api; $ret['soa_edit_api'] = $this->soa_edit_api;
} }
if ($this->zone) { if ($this->zone) {
@ -210,8 +232,9 @@ class Zone {
return $ret; return $ret;
} }
private function exportRRSets() { private function exportRRSets()
$ret = Array(); {
$ret = [];
foreach ($this->rrsets as $rrset) { foreach ($this->rrsets as $rrset) {
array_push($ret, $rrset->export()); array_push($ret, $rrset->export());
} }
@ -220,36 +243,42 @@ class Zone {
} }
} }
class RRSet { class RRSet
public function __construct($name = '', $type = '', $content = '', $disabled = FALSE, $ttl = 3600, $setptr = FALSE) { {
public function __construct($name = '', $type = '', $content = '', $disabled = false, $ttl = 3600, $setptr = false)
{
$this->name = $name; $this->name = $name;
$this->type = $type; $this->type = $type;
$this->ttl = $ttl; $this->ttl = $ttl;
$this->changetype = 'REPLACE'; $this->changetype = 'REPLACE';
$this->records = Array(); $this->records = [];
$this->comments = Array(); $this->comments = [];
if (isset($content) and $content != '') { if (isset($content) and $content != '') {
$this->addRecord($content, $disabled, $setptr); $this->addRecord($content, $disabled, $setptr);
} }
} }
public function delete() { public function delete()
{
$this->changetype = 'DELETE'; $this->changetype = 'DELETE';
} }
public function setTtl($ttl) { public function setTtl($ttl)
{
$this->ttl = $ttl; $this->ttl = $ttl;
} }
public function setName($name) { public function setName($name)
{
$this->name = $name; $this->name = $name;
} }
public function addRecord($content, $disabled = FALSE, $setptr = FALSE) { public function addRecord($content, $disabled = false, $setptr = false)
{
foreach ($this->records as $record) { foreach ($this->records as $record) {
if ($record->content == $content) { if ($record->content == $content) {
throw new Exception($this->name."/".$this->type." has duplicate records."); throw new Exception($this->name . '/' . $this->type . ' has duplicate records.');
} }
} }
@ -257,20 +286,23 @@ class RRSet {
array_push($this->records, $record); array_push($this->records, $record);
} }
public function deleteRecord($content) { public function deleteRecord($content)
{
foreach ($this->records as $idx => $record) { foreach ($this->records as $idx => $record) {
if ($record->content == $content) { if ($record->content == $content) {
unset($this->records[$idx]); unset($this->records[$idx]);
} }
} }
} }
public function addComment($content, $account, $modified_at = FALSE) { public function addComment($content, $account, $modified_at = false)
{
$comment = new Comment($content, $account, $modified_at); $comment = new Comment($content, $account, $modified_at);
array_push($this->comments, $comment); array_push($this->comments, $comment);
} }
public function export() { public function export()
$ret = Array(); {
$ret = [];
$ret['comments'] = $this->exportComments(); $ret['comments'] = $this->exportComments();
$ret['name'] = $this->name; $ret['name'] = $this->name;
$ret['records'] = $this->exportRecords(); $ret['records'] = $this->exportRecords();
@ -282,11 +314,12 @@ class RRSet {
return $ret; return $ret;
} }
public function exportRecords() { public function exportRecords()
$ret = Array(); {
$ret = [];
foreach ($this->records as $record) { foreach ($this->records as $record) {
if ($this->type != "A" and $this->type != "AAAA") { if ($this->type != 'A' and $this->type != 'AAAA') {
$record->setptr = FALSE; $record->setptr = false;
} }
array_push($ret, $record->export()); array_push($ret, $record->export());
} }
@ -294,45 +327,51 @@ class RRSet {
return $ret; return $ret;
} }
public function exportComments() { public function exportComments()
$ret = Array(); {
$ret = [];
foreach ($this->comments as $comment) { foreach ($this->comments as $comment) {
array_push($ret, $comment->export()); array_push($ret, $comment->export());
} }
return $ret; return $ret;
} }
} }
class Record { class Record
public function __construct($content, $disabled = FALSE, $setptr = FALSE) { {
public function __construct($content, $disabled = false, $setptr = false)
{
$this->content = $content; $this->content = $content;
$this->disabled = $disabled; $this->disabled = $disabled;
$this->setptr = $setptr; $this->setptr = $setptr;
} }
public function export() { public function export()
{
$ret; $ret;
$ret['content'] = $this->content; $ret['content'] = $this->content;
$ret['disabled'] = ( bool ) $this->disabled; $ret['disabled'] = ( bool ) $this->disabled;
if ($this->setptr) { if ($this->setptr) {
$ret['set-ptr'] = ( bool ) TRUE; $ret['set-ptr'] = ( bool ) true;
} }
return $ret; return $ret;
} }
} }
class Comment { class Comment
public function __construct($content, $account, $modified_at) { {
public function __construct($content, $account, $modified_at)
{
$this->content = $content; $this->content = $content;
$this->account = $account; $this->account = $account;
$this->modified_at = $modified_at; $this->modified_at = $modified_at;
} }
public function export() { public function export()
{
$ret; $ret;
$ret['content'] = $this->content; $ret['content'] = $this->content;
@ -340,5 +379,3 @@ class Comment {
$ret['modified_at'] = $this->modified_at; $ret['modified_at'] = $this->modified_at;
} }
} }
?>

View file

@ -1,29 +1,29 @@
<?php <?php
include('config.inc.php'); include 'config.inc.php';
$blocklogin = FALSE; $blocklogin = false;
if ((!isset($apipass) or empty($apipass)) or (!isset($apiip) or empty($apiip)) or (!isset($apiport) or empty($apiport))) { if ((!isset($apipass) or empty($apipass)) or (!isset($apiip) or empty($apiip)) or (!isset($apiport) or empty($apiport))) {
$errormsg = 'You need to configure your settings for the PowerDNS API. See <a href="doc/apiconf.txt">doc/apiconf.txt</a>'; $errormsg = 'You need to configure your settings for the PowerDNS API. See <a href="doc/apiconf.txt">doc/apiconf.txt</a>';
$blocklogin = TRUE; $blocklogin = true;
} }
if (!isset($apiproto) or !preg_match('/^http(s)?$/', $apiproto)) { if (!isset($apiproto) or !preg_match('/^http(s)?$/', $apiproto)) {
$errormsg = "The value for \$apiproto is incorrect in your config. Did you configure it?"; $errormsg = 'The value for $apiproto is incorrect in your config. Did you configure it?';
$blocklogin = TRUE; $blocklogin = true;
} }
if (!isset($apisslverify)) { if (!isset($apisslverify)) {
$errormsg = "The value for \$apisslverify is incorrect in your config. Did you configure it?"; $errormsg = 'The value for $apisslverify is incorrect in your config. Did you configure it?';
$blocklogin = TRUE; $blocklogin = true;
} else { } else {
$apisslverify = ( bool ) $apisslverify; $apisslverify = ( bool ) $apisslverify;
} }
if (!isset($authdb)) { if (!isset($authdb)) {
$errormsg = "You did not configure a value for the setting \$authdb in your config"; $errormsg = 'You did not configure a value for the setting $authdb in your config';
$blocklogin = TRUE; $blocklogin = true;
} }
if (isset($defaults['primaryns'])) { if (isset($defaults['primaryns'])) {
@ -38,25 +38,23 @@ if (!isset($logo) or empty($logo)) {
$logo = 'https://www.tuxis.nl/uploads/images/nsedit.png'; $logo = 'https://www.tuxis.nl/uploads/images/nsedit.png';
} }
/* No need to change stuf below */ /* No need to change stuf below */
if (function_exists('curl_init') === FALSE) { if (function_exists('curl_init') === false) {
$errormsg = "You need PHP Curl to run nsedit"; $errormsg = 'You need PHP Curl to run nsedit';
$blocklogin = TRUE; $blocklogin = true;
} }
if (class_exists('SQLite3') === FALSE) { if (class_exists('SQLite3') === false) {
$errormsg = "You need PHP SQLite3 to run nsedit"; $errormsg = 'You need PHP SQLite3 to run nsedit';
$blocklogin = TRUE; $blocklogin = true;
} }
if (function_exists('openssl_random_pseudo_bytes') === FALSE) { if (function_exists('openssl_random_pseudo_bytes') === false) {
$errormsg = "You need PHP compiled with openssl to run nsedit"; $errormsg = 'You need PHP compiled with openssl to run nsedit';
$blocklogin = TRUE; $blocklogin = true;
} }
$defaults['defaulttype'] = ucfirst(strtolower($defaults['defaulttype'])); $defaults['defaulttype'] = ucfirst(strtolower($defaults['defaulttype']));
if (isset($authdb) && !file_exists($authdb) && class_exists('SQLite3')) { if (isset($authdb) && !file_exists($authdb) && class_exists('SQLite3')) {
@ -65,7 +63,7 @@ if (isset($authdb) && !file_exists($authdb) && class_exists('SQLite3')) {
$createsql = file_get_contents('includes/scheme.sql'); $createsql = file_get_contents('includes/scheme.sql');
$db->exec($createsql); $db->exec($createsql);
$salt = bin2hex(openssl_random_pseudo_bytes(16)); $salt = bin2hex(openssl_random_pseudo_bytes(16));
$db->exec("INSERT INTO users (emailaddress, password, isadmin) VALUES ('admin', '".crypt("admin", '$6$'.$salt)."', 1)"); $db->exec("INSERT INTO users (emailaddress, password, isadmin) VALUES ('admin', '" . crypt('admin', '$6$' . $salt) . "', 1)");
} }
function string_starts_with($string, $prefix) function string_starts_with($string, $prefix)
@ -84,7 +82,8 @@ function string_ends_with($string, $suffix)
return (substr($string, -$length) === $suffix); return (substr($string, -$length) === $suffix);
} }
function get_db() { function get_db()
{
global $authdb, $db; global $authdb, $db;
if (!isset($db)) { if (!isset($db)) {
@ -95,10 +94,11 @@ function get_db() {
return $db; return $db;
} }
function get_all_users() { function get_all_users()
{
$db = get_db(); $db = get_db();
$r = $db->query('SELECT id, emailaddress, isadmin FROM users ORDER BY emailaddress'); $r = $db->query('SELECT id, emailaddress, isadmin FROM users ORDER BY emailaddress');
$ret = array(); $ret = [];
while ($row = $r->fetchArray(SQLITE3_ASSOC)) { while ($row = $r->fetchArray(SQLITE3_ASSOC)) {
array_push($ret, $row); array_push($ret, $row);
} }
@ -106,7 +106,8 @@ function get_all_users() {
return $ret; return $ret;
} }
function get_user_info($u) { function get_user_info($u)
{
$db = get_db(); $db = get_db();
$q = $db->prepare('SELECT * FROM users WHERE emailaddress = ?'); $q = $db->prepare('SELECT * FROM users WHERE emailaddress = ?');
$q->bindValue(1, $u); $q->bindValue(1, $u);
@ -116,11 +117,13 @@ function get_user_info($u) {
return $userinfo; return $userinfo;
} }
function user_exists($u) { function user_exists($u)
{
return (bool) get_user_info($u); return (bool) get_user_info($u);
} }
function do_db_auth($u, $p) { function do_db_auth($u, $p)
{
$db = get_db(); $db = get_db();
$q = $db->prepare('SELECT * FROM users WHERE emailaddress = ?'); $q = $db->prepare('SELECT * FROM users WHERE emailaddress = ?');
$q->bindValue(1, $u); $q->bindValue(1, $u);
@ -128,19 +131,20 @@ function do_db_auth($u, $p) {
$userinfo = $result->fetchArray(SQLITE3_ASSOC); $userinfo = $result->fetchArray(SQLITE3_ASSOC);
if ($userinfo and $userinfo['password'] and (crypt($p, $userinfo['password']) === $userinfo['password'])) { if ($userinfo and $userinfo['password'] and (crypt($p, $userinfo['password']) === $userinfo['password'])) {
return TRUE; return true;
} }
return FALSE; return false;
} }
function add_user($username, $isadmin = FALSE, $password = '') { function add_user($username, $isadmin = false, $password = '')
{
if (!$password) { if (!$password) {
$password = bin2hex(openssl_random_pseudo_bytes(32)); $password = bin2hex(openssl_random_pseudo_bytes(32));
} }
if (!string_starts_with($password, '$6$')) { if (!string_starts_with($password, '$6$')) {
$salt = bin2hex(openssl_random_pseudo_bytes(16)); $salt = bin2hex(openssl_random_pseudo_bytes(16));
$password = crypt($password, '$6$'.$salt); $password = crypt($password, '$6$' . $salt);
} }
$db = get_db(); $db = get_db();
@ -158,10 +162,11 @@ function add_user($username, $isadmin = FALSE, $password = '') {
return $ret; return $ret;
} }
function update_user($id, $isadmin, $password) { function update_user($id, $isadmin, $password)
{
if ($password && !preg_match('/\$6\$/', $password)) { if ($password && !preg_match('/\$6\$/', $password)) {
$salt = bin2hex(openssl_random_pseudo_bytes(16)); $salt = bin2hex(openssl_random_pseudo_bytes(16));
$password = crypt($password, '$6$'.$salt); $password = crypt($password, '$6$' . $salt);
} }
$db = get_db(); $db = get_db();
@ -178,19 +183,20 @@ function update_user($id, $isadmin, $password) {
$q->bindValue(1, (int)(bool)$isadmin, SQLITE3_INTEGER); $q->bindValue(1, (int)(bool)$isadmin, SQLITE3_INTEGER);
$q->bindValue(2, $password, SQLITE3_TEXT); $q->bindValue(2, $password, SQLITE3_TEXT);
$q->bindValue(3, $id, SQLITE3_INTEGER); $q->bindValue(3, $id, SQLITE3_INTEGER);
writelog("Updating password and/or settings for $username. Admin: ".(int)(bool)$isadmin); writelog("Updating password and/or settings for $username. Admin: " . (int)(bool)$isadmin);
} else { } else {
$q = $db->prepare('UPDATE users SET isadmin = ? WHERE id = ?'); $q = $db->prepare('UPDATE users SET isadmin = ? WHERE id = ?');
$q->bindValue(1, (int)(bool)$isadmin, SQLITE3_INTEGER); $q->bindValue(1, (int)(bool)$isadmin, SQLITE3_INTEGER);
$q->bindValue(2, $id, SQLITE3_INTEGER); $q->bindValue(2, $id, SQLITE3_INTEGER);
writelog("Updating settings for $username. Admin: ".(int)(bool)$isadmin); writelog("Updating settings for $username. Admin: " . (int)(bool)$isadmin);
} }
$ret = $q->execute(); $ret = $q->execute();
return $ret; return $ret;
} }
function delete_user($id) { function delete_user($id)
{
$db = get_db(); $db = get_db();
$q = $db->prepare('SELECT * FROM users WHERE id = ?'); $q = $db->prepare('SELECT * FROM users WHERE id = ?');
@ -199,41 +205,43 @@ function delete_user($id) {
$userinfo = $result->fetchArray(SQLITE3_ASSOC); $userinfo = $result->fetchArray(SQLITE3_ASSOC);
$q->close(); $q->close();
if($userinfo) { if ($userinfo) {
$q = $db->prepare('DELETE FROM users WHERE id = ?'); $q = $db->prepare('DELETE FROM users WHERE id = ?');
$q->bindValue(1, $id, SQLITE3_INTEGER); $q->bindValue(1, $id, SQLITE3_INTEGER);
$ret = $q->execute(); $ret = $q->execute();
writelog("Deleted user " . $userinfo['emailaddress'] . "."); writelog('Deleted user ' . $userinfo['emailaddress'] . '.');
return $ret; return $ret;
} else { } else {
return false; return false;
} }
} }
function valid_user($name) { function valid_user($name)
return ( bool ) preg_match( "/^[a-z0-9@_.-]+$/i" , $name ); {
return ( bool ) preg_match('/^[a-z0-9@_.-]+$/i', $name);
} }
function jtable_respond($records, $method = 'multiple', $msg = 'Undefined errormessage') { function jtable_respond($records, $method = 'multiple', $msg = 'Undefined errormessage')
$jTableResult = array(); {
$jTableResult = [];
if ($method == 'error') { if ($method == 'error') {
$jTableResult['Result'] = "ERROR"; $jTableResult['Result'] = 'ERROR';
$jTableResult['Message'] = $msg; $jTableResult['Message'] = $msg;
} elseif ($method == 'single') { } elseif ($method == 'single') {
$jTableResult['Result'] = "OK"; $jTableResult['Result'] = 'OK';
$jTableResult['Record'] = $records; $jTableResult['Record'] = $records;
} elseif ($method == 'delete') { } elseif ($method == 'delete') {
$jTableResult['Result'] = "OK"; $jTableResult['Result'] = 'OK';
} elseif ($method == 'options') { } elseif ($method == 'options') {
$jTableResult['Result'] = "OK"; $jTableResult['Result'] = 'OK';
$jTableResult['Options'] = $records; $jTableResult['Options'] = $records;
} else { } else {
if (isset($_GET['jtPageSize'])) { if (isset($_GET['jtPageSize'])) {
$jTableResult['TotalRecordCount'] = count($records); $jTableResult['TotalRecordCount'] = count($records);
$records = array_slice($records, $_GET['jtStartIndex'], $_GET['jtPageSize']); $records = array_slice($records, $_GET['jtStartIndex'], $_GET['jtPageSize']);
} }
$jTableResult['Result'] = "OK"; $jTableResult['Result'] = 'OK';
$jTableResult['Records'] = $records; $jTableResult['Records'] = $records;
$jTableResult['RecordCount'] = count($records); $jTableResult['RecordCount'] = count($records);
} }
@ -245,10 +253,11 @@ function jtable_respond($records, $method = 'multiple', $msg = 'Undefined errorm
exit(0); exit(0);
} }
function user_template_list() { function user_template_list()
{
global $templates; global $templates;
$templatelist = array(); $templatelist = [];
foreach ($templates as $template) { foreach ($templates as $template) {
if (is_adminuser() if (is_adminuser()
or (isset($template['owner']) or (isset($template['owner'])
@ -259,22 +268,25 @@ function user_template_list() {
return $templatelist; return $templatelist;
} }
function user_template_names() { function user_template_names()
$templatenames = array('None' => 'None'); {
$templatenames = ['None' => 'None'];
foreach (user_template_list() as $template) { foreach (user_template_list() as $template) {
$templatenames[$template['name']] = $template['name']; $templatenames[$template['name']] = $template['name'];
} }
return $templatenames; return $templatenames;
} }
function getlogs() { function getlogs()
{
global $logging; global $logging;
if ($logging !== TRUE) if ($logging !== true) {
return; return;
}
$db = get_db(); $db = get_db();
$r = $db->query('SELECT * FROM logs ORDER BY timestamp DESC'); $r = $db->query('SELECT * FROM logs ORDER BY timestamp DESC');
$ret = array(); $ret = [];
while ($row = $r->fetchArray(SQLITE3_ASSOC)) { while ($row = $r->fetchArray(SQLITE3_ASSOC)) {
array_push($ret, $row); array_push($ret, $row);
} }
@ -282,74 +294,82 @@ function getlogs() {
return $ret; return $ret;
} }
function clearlogs() { function clearlogs()
{
global $logging; global $logging;
if ($logging !== TRUE) if ($logging !== true) {
return; return;
}
$db = get_db(); $db = get_db();
$q = $db->query('DELETE FROM logs;'); $q = $db->query('DELETE FROM logs;');
writelog("Logtable truncated."); writelog('Logtable truncated.');
} }
function rotatelogs() { function rotatelogs()
{
global $logging, $logsdirectory; global $logging, $logsdirectory;
if ($logging !== TRUE) if ($logging !== true) {
return FALSE; return false;
}
if(!is_dir($logsdirectory) || !is_writable($logsdirectory)) { if (!is_dir($logsdirectory) || !is_writable($logsdirectory)) {
writelog("Logs directory cannot be written to."); writelog('Logs directory cannot be written to.');
return FALSE; return false;
} }
date_default_timezone_set('UTC'); date_default_timezone_set('UTC');
$filename = date("Y-m-d-His") . ".json"; $filename = date('Y-m-d-His') . '.json';
$file = fopen($logsdirectory . "/" . $filename, "x"); $file = fopen($logsdirectory . '/' . $filename, 'x');
if($file === FALSE) { if ($file === false) {
writelog("Can't create file for log rotation."); writelog("Can't create file for log rotation.");
return FALSE; return false;
} }
if(fwrite($file,json_encode(getlogs())) === FALSE) { if (fwrite($file, json_encode(getlogs())) === false) {
writelog("Can't write to file for log rotation."); writelog("Can't write to file for log rotation.");
fclose($file); fclose($file);
return FALSE; return false;
} else { } else {
fclose($file); fclose($file);
clearlogs(); clearlogs();
return $filename; return $filename;
} }
} }
function listrotatedlogs() { function listrotatedlogs()
{
global $logging, $logsdirectory; global $logging, $logsdirectory;
if ($logging !== TRUE) if ($logging !== true) {
return FALSE; return false;
$list = scandir($logsdirectory,SCANDIR_SORT_DESCENDING);
if($list === FALSE) {
writelog("Logs directory cannot read.");
return FALSE;
} }
$list=array_filter($list, $list = scandir($logsdirectory, SCANDIR_SORT_DESCENDING);
if ($list === false) {
writelog('Logs directory cannot read.');
return false;
}
$list=array_filter(
$list,
function ($val) { function ($val) {
return(preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}\.json/',$val) == 1); return(preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}\.json/', $val) == 1);
} }
); );
return $list; return $list;
} }
function writelog($line, $user=False) { function writelog($line, $user=false)
{
global $logging; global $logging;
if ($logging !== TRUE) if ($logging !== true) {
return; return;
}
if ($user === False) { if ($user === false) {
$user = get_sess_user(); $user = get_sess_user();
} }
@ -375,22 +395,26 @@ function writelog($line, $user=False) {
it available on older php versions. Thanks! */ it available on older php versions. Thanks! */
if (!function_exists('hash_pbkdf2')) { if (!function_exists('hash_pbkdf2')) {
function hash_pbkdf2($algo, $password, $salt, $iterations, $length = 0, $rawOutput = false) { function hash_pbkdf2($algo, $password, $salt, $iterations, $length = 0, $rawOutput = false)
{
// check for hashing algorithm // check for hashing algorithm
if (!in_array(strtolower($algo), hash_algos())) { if (!in_array(strtolower($algo), hash_algos())) {
trigger_error(sprintf( trigger_error(sprintf(
'%s(): Unknown hashing algorithm: %s', '%s(): Unknown hashing algorithm: %s',
__FUNCTION__, $algo __FUNCTION__,
$algo
), E_USER_WARNING); ), E_USER_WARNING);
return false; return false;
} }
// check for type of iterations and length // check for type of iterations and length
foreach (array(4 => $iterations, 5 => $length) as $index => $value) { foreach ([4 => $iterations, 5 => $length] as $index => $value) {
if (!is_numeric($value)) { if (!is_numeric($value)) {
trigger_error(sprintf( trigger_error(sprintf(
'%s() expects parameter %d to be long, %s given', '%s() expects parameter %d to be long, %s given',
__FUNCTION__, $index, gettype($value) __FUNCTION__,
$index,
gettype($value)
), E_USER_WARNING); ), E_USER_WARNING);
return null; return null;
} }
@ -401,7 +425,8 @@ if (!function_exists('hash_pbkdf2')) {
if ($iterations <= 0) { if ($iterations <= 0) {
trigger_error(sprintf( trigger_error(sprintf(
'%s(): Iterations must be a positive integer: %d', '%s(): Iterations must be a positive integer: %d',
__FUNCTION__, $iterations __FUNCTION__,
$iterations
), E_USER_WARNING); ), E_USER_WARNING);
return false; return false;
} }
@ -411,7 +436,8 @@ if (!function_exists('hash_pbkdf2')) {
if ($length < 0) { if ($length < 0) {
trigger_error(sprintf( trigger_error(sprintf(
'%s(): Iterations must be greater than or equal to 0: %d', '%s(): Iterations must be greater than or equal to 0: %d',
__FUNCTION__, $length __FUNCTION__,
$length
), E_USER_WARNING); ), E_USER_WARNING);
return false; return false;
} }
@ -420,7 +446,8 @@ if (!function_exists('hash_pbkdf2')) {
if (strlen($salt) > PHP_INT_MAX - 4) { if (strlen($salt) > PHP_INT_MAX - 4) {
trigger_error(sprintf( trigger_error(sprintf(
'%s(): Supplied salt is too long, max of INT_MAX - 4 bytes: %d supplied', '%s(): Supplied salt is too long, max of INT_MAX - 4 bytes: %d supplied',
__FUNCTION__, strlen($salt) __FUNCTION__,
strlen($salt)
), E_USER_WARNING); ), E_USER_WARNING);
return false; return false;
} }
@ -454,5 +481,3 @@ if (!function_exists('hash_pbkdf2')) {
return $derivedKey; return $derivedKey;
} }
} }
?>

View file

@ -1,28 +1,30 @@
<?php <?php
include_once('config.inc.php'); include_once 'config.inc.php';
include_once('misc.inc.php'); include_once 'misc.inc.php';
include_once('wefactauth.inc.php'); include_once 'wefactauth.inc.php';
global $current_user; global $current_user;
$current_user = false; $current_user = false;
// session startup // session startup
function _set_current_user($username, $userid, $localauth = true, $is_admin = false, $has_csrf_token = false, $is_api = false) { function _set_current_user($username, $userid, $localauth = true, $is_admin = false, $has_csrf_token = false, $is_api = false)
{
global $current_user; global $current_user;
$current_user = array( $current_user = [
'username' => $username, 'username' => $username,
'id' => $userid, 'id' => $userid,
'localauth' => $localauth, 'localauth' => $localauth,
'is_admin' => $is_admin, 'is_admin' => $is_admin,
'has_csrf_token' => $has_csrf_token, 'has_csrf_token' => $has_csrf_token,
'is_api' => $is_api, 'is_api' => $is_api,
); ];
} }
function _check_csrf_token($user) { function _check_csrf_token($user)
{
global $secret; global $secret;
if (isset($_SERVER['HTTP_X_CSRF_TOKEN']) && $_SERVER['HTTP_X_CSRF_TOKEN']) { if (isset($_SERVER['HTTP_X_CSRF_TOKEN']) && $_SERVER['HTTP_X_CSRF_TOKEN']) {
@ -55,7 +57,8 @@ function _check_csrf_token($user) {
header("X-CSRF-Token: ${csrf_token}"); header("X-CSRF-Token: ${csrf_token}");
} }
function enc_secret($message) { function enc_secret($message)
{
global $secret; global $secret;
if (isset($secret) && $secret) { if (isset($secret) && $secret) {
@ -81,14 +84,19 @@ function enc_secret($message) {
return base64_encode($message); return base64_encode($message);
} }
function dec_secret($code) { function dec_secret($code)
{
global $secret; global $secret;
$is_encrypted = (substr($code, 0, 4) === 'enc:'); $is_encrypted = (substr($code, 0, 4) === 'enc:');
if (isset($secret) && $secret) { if (isset($secret) && $secret) {
if (!$is_encrypted) return false; if (!$is_encrypted) {
return false;
}
$msg = explode(':', $code); $msg = explode(':', $code);
if (3 != count($msg)) return false; if (3 != count($msg)) {
return false;
}
$enc_secret = hash_pbkdf2('sha256', 'encryption', $secret, 100, 0, true); $enc_secret = hash_pbkdf2('sha256', 'encryption', $secret, 100, 0, true);
$hmac_secret = hash_pbkdf2('sha256', 'encryption_hmac', $secret, 100, 0, true); $hmac_secret = hash_pbkdf2('sha256', 'encryption_hmac', $secret, 100, 0, true);
@ -98,8 +106,12 @@ function dec_secret($code) {
$mac = hash_hmac('sha256', $msg[1], $hmac_secret, true); $mac = hash_hmac('sha256', $msg[1], $hmac_secret, true);
# compare hashes first: this should prevent any timing leak # compare hashes first: this should prevent any timing leak
if (hash('sha256', $mac, true) !== hash('sha256', $msg[2], true)) return false; if (hash('sha256', $mac, true) !== hash('sha256', $msg[2], true)) {
if ($mac !== $msg[2]) return false; return false;
}
if ($mac !== $msg[2]) {
return false;
}
$mcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_CBC, '') or die('missing mcrypt'); $mcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_CBC, '') or die('missing mcrypt');
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
@ -116,31 +128,36 @@ function dec_secret($code) {
return $plaintext; return $plaintext;
} }
if ($is_encrypted) return false; if ($is_encrypted) {
return false;
}
return base64_decode($code); return base64_decode($code);
} }
function _unset_cookie($name) { function _unset_cookie($name)
{
$is_ssl = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off'; $is_ssl = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off';
setcookie($name, null, -1, null, null, $is_ssl); setcookie($name, null, -1, null, null, $is_ssl);
} }
function _store_auto_login($value) { function _store_auto_login($value)
{
$is_ssl = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off'; $is_ssl = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off';
// set for 30 days // set for 30 days
setcookie('NSEDIT_AUTOLOGIN', $value, time()+60*60*24*30, null, null, $is_ssl); setcookie('NSEDIT_AUTOLOGIN', $value, time()+60*60*24*30, null, null, $is_ssl);
} }
function try_login() { function try_login()
{
if (isset($_POST['username']) and isset($_POST['password'])) { if (isset($_POST['username']) and isset($_POST['password'])) {
if (_try_login($_POST['username'], $_POST['password'])) { if (_try_login($_POST['username'], $_POST['password'])) {
global $secret; global $secret;
# only store if we have a secret. # only store if we have a secret.
if ($secret && isset($_POST['autologin']) && $_POST['autologin']) { if ($secret && isset($_POST['autologin']) && $_POST['autologin']) {
_store_auto_login(enc_secret(json_encode(array( _store_auto_login(enc_secret(json_encode([
'username' => $_POST['username'], 'username' => $_POST['username'],
'password' => $_POST['password'])))); 'password' => $_POST['password']])));
} }
return true; return true;
} }
@ -148,11 +165,12 @@ function try_login() {
return false; return false;
} }
function _try_login($username, $password) { function _try_login($username, $password)
{
global $wefactapiurl, $wefactapikey; global $wefactapiurl, $wefactapikey;
if (!valid_user($username)) { if (!valid_user($username)) {
writelog("Illegal username at login!", $username); writelog('Illegal username at login!', $username);
return false; return false;
} }
@ -160,8 +178,8 @@ function _try_login($username, $password) {
if (isset($wefactapiurl) && isset($wefactapikey)) { if (isset($wefactapiurl) && isset($wefactapikey)) {
$wefact = do_wefact_auth($username, $password); $wefact = do_wefact_auth($username, $password);
if (false === $wefact ) { if (false === $wefact) {
writelog("Failed Wefact login!", $username); writelog('Failed Wefact login!', $username);
return false; return false;
} }
if (-1 !== $wefact) { if (-1 !== $wefact) {
@ -170,13 +188,13 @@ function _try_login($username, $password) {
} }
if ($do_local_auth && !do_db_auth($username, $password)) { if ($do_local_auth && !do_db_auth($username, $password)) {
writelog("Failed login!", $username); writelog('Failed login!', $username);
return false; return false;
} }
$user = get_user_info($username); $user = get_user_info($username);
if (!$user) { if (!$user) {
writelog("Failed to find user!", $username); writelog('Failed to find user!', $username);
return false; return false;
} else { } else {
_set_current_user($username, $user['id'], (bool) $do_local_auth, (bool) $user['isadmin']); _set_current_user($username, $user['id'], (bool) $do_local_auth, (bool) $user['isadmin']);
@ -198,7 +216,8 @@ function _try_login($username, $password) {
} }
} }
function _check_session() { function _check_session()
{
global $adminapikey, $adminapiips; global $adminapikey, $adminapiips;
$is_ssl = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off'; $is_ssl = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off';
@ -207,13 +226,10 @@ function _check_session() {
if (isset($adminapikey) && '' !== $adminapikey && isset($adminapiips) && isset($_POST['adminapikey'])) { if (isset($adminapikey) && '' !== $adminapikey && isset($adminapiips) && isset($_POST['adminapikey'])) {
if (false !== array_search($_SERVER['REMOTE_ADDR'], $adminapiips) if (false !== array_search($_SERVER['REMOTE_ADDR'], $adminapiips)
and $_POST['adminapikey'] === $adminapikey) and $_POST['adminapikey'] === $adminapikey) {
{
# Allow this request, fake that we're logged in as user. # Allow this request, fake that we're logged in as user.
return _set_current_user('admin', 1, false, true, true, true); return _set_current_user('admin', 1, false, true, true, true);
} } else {
else
{
header('Status: 403 Forbidden'); header('Status: 403 Forbidden');
exit(0); exit(0);
} }
@ -251,14 +267,16 @@ function _check_session() {
# auto load session if possible # auto load session if possible
_check_session(); _check_session();
function is_logged_in() { function is_logged_in()
{
global $current_user; global $current_user;
return (bool) $current_user; return (bool) $current_user;
} }
# GET/HEAD requests only require a logged in user (they shouldn't trigger any # GET/HEAD requests only require a logged in user (they shouldn't trigger any
# "writes"); all other requests require the X-CSRF-Token to be present. # "writes"); all other requests require the X-CSRF-Token to be present.
function is_csrf_safe() { function is_csrf_safe()
{
global $current_user; global $current_user;
switch ($_SERVER['REQUEST_METHOD']) { switch ($_SERVER['REQUEST_METHOD']) {
@ -270,32 +288,38 @@ function is_csrf_safe() {
} }
} }
function is_apiuser() { function is_apiuser()
{
global $current_user; global $current_user;
return $current_user && (bool) $current_user['is_api']; return $current_user && (bool) $current_user['is_api'];
} }
function is_adminuser() { function is_adminuser()
{
global $current_user; global $current_user;
return $current_user && (bool) $current_user['is_admin']; return $current_user && (bool) $current_user['is_admin'];
} }
function get_sess_user() { function get_sess_user()
{
global $current_user; global $current_user;
return $current_user ? $current_user['username'] : null; return $current_user ? $current_user['username'] : null;
} }
function get_sess_userid() { function get_sess_userid()
{
global $current_user; global $current_user;
return $current_user ? $current_user['id'] : null; return $current_user ? $current_user['id'] : null;
} }
function has_local_auth() { function has_local_auth()
{
global $current_user; global $current_user;
return $current_user ? $current_user['localauth'] : null; return $current_user ? $current_user['localauth'] : null;
} }
function logout() { function logout()
{
@session_destroy(); @session_destroy();
@session_unset(); @session_unset();
if (isset($_COOKIE['NSEDIT_AUTOLOGIN'])) { if (isset($_COOKIE['NSEDIT_AUTOLOGIN'])) {

View file

@ -1,52 +1,53 @@
<?php <?php
include_once('config.inc.php'); include_once 'config.inc.php';
include_once('misc.inc.php'); include_once 'misc.inc.php';
/* This class is written by Wefact. See https://www.wefact.nl/wefact-hosting/apiv2/ /* This class is written by Wefact. See https://www.wefact.nl/wefact-hosting/apiv2/
*/ */
class WeFactAPI { class WeFactAPI
{
private $url; private $url;
private $responseType; private $responseType;
private $apiKey; private $apiKey;
function __construct(){ public function __construct()
{
global $wefactapiurl; global $wefactapiurl;
global $wefactapikey; global $wefactapikey;
$this->url = $wefactapiurl; $this->url = $wefactapiurl;
$this->api_key = $wefactapikey; $this->api_key = $wefactapikey;
} }
public function sendRequest($controller, $action, $params){ public function sendRequest($controller, $action, $params)
{
if(is_array($params)){ if (is_array($params)) {
$params['api_key'] = $this->api_key; $params['api_key'] = $this->api_key;
$params['controller'] = $controller; $params['controller'] = $controller;
$params['action'] = $action; $params['action'] = $action;
} }
$ch = curl_init(); $ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $this->url); curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT,'10'); curl_setopt($ch, CURLOPT_TIMEOUT, '10');
curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params)); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
$curlResp = curl_exec($ch); $curlResp = curl_exec($ch);
$curlError = curl_error($ch); $curlError = curl_error($ch);
if ($curlError != ''){ if ($curlError != '') {
$result = array( $result = [
'controller' => 'invalid', 'controller' => 'invalid',
'action' => 'invalid', 'action' => 'invalid',
'status' => 'error', 'status' => 'error',
'date' => date('c'), 'date' => date('c'),
'errors' => array($curlError) 'errors' => [$curlError]
); ];
}else{ } else {
$result = json_decode($curlResp, true); $result = json_decode($curlResp, true);
} }
@ -54,26 +55,26 @@ class WeFactAPI {
} }
} }
function do_wefact_auth($u, $p)
function do_wefact_auth($u, $p) { {
$wefact = new WeFactApi(); $wefact = new WeFactApi();
$r = $wefact->sendRequest('debtor', 'show', array( $r = $wefact->sendRequest('debtor', 'show', [
'DebtorCode' => $u)); 'DebtorCode' => $u]);
if (isset($r['status']) && $r['status'] == 'success') { if (isset($r['status']) && $r['status'] == 'success') {
$r = $wefact->sendRequest('debtor', 'checklogin', array( $r = $wefact->sendRequest('debtor', 'checklogin', [
'Username' => $u, 'Username' => $u,
'Password' => $p 'Password' => $p
)); ]);
if (isset($r['status']) && $r['status'] == 'success') { if (isset($r['status']) && $r['status'] == 'success') {
if (get_user_info($u) == FALSE) { if (get_user_info($u) == false) {
add_user($u); add_user($u);
} }
return TRUE; return true;
} }
return FALSE; return false;
} else { } else {
return -1; return -1;
} }

168
index.php
View file

@ -1,30 +1,30 @@
<?php <?php
include_once('includes/config.inc.php'); include_once 'includes/config.inc.php';
include_once('includes/session.inc.php'); include_once 'includes/session.inc.php';
include_once('includes/misc.inc.php'); include_once 'includes/misc.inc.php';
global $errormsg, $blocklogin; global $errormsg, $blocklogin;
if (isset($_GET['logout']) or isset($_POST['logout'])) { if (isset($_GET['logout']) or isset($_POST['logout'])) {
logout(); logout();
header("Location: index.php"); header('Location: index.php');
exit(0); exit(0);
} }
if (!is_logged_in() and isset($_POST['formname']) and $_POST['formname'] === "loginform") { if (!is_logged_in() and isset($_POST['formname']) and $_POST['formname'] === 'loginform') {
if (!try_login()) { if (!try_login()) {
$errormsg = "Error while trying to authenticate you\n"; $errormsg = "Error while trying to authenticate you\n";
} }
} }
if (is_logged_in() and isset($_POST['formname']) and $_POST['formname'] === "changepwform") { if (is_logged_in() and isset($_POST['formname']) and $_POST['formname'] === 'changepwform') {
if (get_sess_user() == $_POST['username']) { if (get_sess_user() == $_POST['username']) {
if (!update_user(get_sess_userid(), is_adminuser(), $_POST['password'])) { if (!update_user(get_sess_userid(), is_adminuser(), $_POST['password'])) {
$errormsg = "Unable to update password!\n"; $errormsg = "Unable to update password!\n";
} }
} else { } else {
$errormsg = "You can only update your own password!".$_POST['username']; $errormsg = 'You can only update your own password!' . $_POST['username'];
} }
} }
@ -36,9 +36,11 @@ if (is_logged_in() and isset($_POST['formname']) and $_POST['formname'] === "cha
<link href="jquery-ui/themes/base/all.css" rel="stylesheet" type="text/css"/> <link href="jquery-ui/themes/base/all.css" rel="stylesheet" type="text/css"/>
<link href="jtable/lib/themes/metro/blue/jtable.min.css" rel="stylesheet" type="text/css"/> <link href="jtable/lib/themes/metro/blue/jtable.min.css" rel="stylesheet" type="text/css"/>
<link href="css/base.css" rel="stylesheet" type="text/css"/> <link href="css/base.css" rel="stylesheet" type="text/css"/>
<?php if ($menutype === 'horizontal') { ?> <?php if ($menutype === 'horizontal') {
?>
<link href="css/horizontal-menu.css" rel="stylesheet" type="text/css"/> <link href="css/horizontal-menu.css" rel="stylesheet" type="text/css"/>
<?php } ?> <?php
} ?>
<script src="jquery-ui/external/jquery/jquery.js" type="text/javascript"></script> <script src="jquery-ui/external/jquery/jquery.js" type="text/javascript"></script>
<script src="jquery-ui/ui/core.js" type="text/javascript"></script> <script src="jquery-ui/ui/core.js" type="text/javascript"></script>
<script src="jquery-ui/ui/widget.js" type="text/javascript"></script> <script src="jquery-ui/ui/widget.js" type="text/javascript"></script>
@ -54,7 +56,7 @@ if (is_logged_in() and isset($_POST['formname']) and $_POST['formname'] === "cha
<?php <?php
if (!is_logged_in()) { if (!is_logged_in()) {
?> ?>
<body onload="document.getElementById('username').focus()"> <body onload="document.getElementById('username').focus()">
<div class="loginblock"> <div class="loginblock">
<div class="logo"> <div class="logo">
@ -63,8 +65,7 @@ if (!is_logged_in()) {
<div class="login"> <div class="login">
<?php if (isset($errormsg)) { <?php if (isset($errormsg)) {
echo '<span style="color: red">' . $errormsg . '</span><br />'; echo '<span style="color: red">' . $errormsg . '</span><br />';
} } ?>
?>
<form action="index.php" method="post"> <form action="index.php" method="post">
<table> <table>
<tr> <tr>
@ -77,17 +78,18 @@ if (!is_logged_in()) {
</tr> </tr>
<?php <?php
if (isset($secret) && $secret) { if (isset($secret) && $secret) {
?> ?>
<tr> <tr>
<td class="label">Remember me:</td> <td class="label">Remember me:</td>
<td><input type="checkbox" name="autologin" value="1"></td> <td><input type="checkbox" name="autologin" value="1"></td>
</tr> </tr>
<?php <?php
} } ?>
?>
<tr> <tr>
<td></td> <td></td>
<td><input type="submit" name="submit" value="Log me in!" <?php if ($blocklogin === TRUE) { echo "disabled"; }; ?>></td> <td><input type="submit" name="submit" value="Log me in!" <?php if ($blocklogin === true) {
echo 'disabled';
} ?>></td>
</tr> </tr>
</table> </table>
<input type="hidden" name="formname" value="loginform"> <input type="hidden" name="formname" value="loginform">
@ -99,13 +101,12 @@ if (!is_logged_in()) {
<?php <?php
exit(0); exit(0);
} }
if ($blocklogin === TRUE) { if ($blocklogin === true) {
echo '<h2>There is an error in your config!</h2>';
echo "<h2>There is an error in your config!</h2>"; echo '<a href="index.php">Refresh</a>';
echo "<a href=\"index.php\">Refresh</a>"; exit(0);
exit(0);
} }
?> ?>
@ -115,8 +116,10 @@ if ($blocklogin === TRUE) {
</div> </div>
<div id="clearlogs" style="display: none;"> <div id="clearlogs" style="display: none;">
Are you sure you want to clear the current logs? Maybe download them Are you sure you want to clear the current logs? Maybe download them
first<?php if($allowrotatelogs) { ?>, or use "Rotate logs" to save first<?php if ($allowrotatelogs) {
them on the server<?php } ?>? ?>, or use "Rotate logs" to save
them on the server<?php
} ?>?
</div> </div>
<div id="rotatelogs" style="display: none;"> <div id="rotatelogs" style="display: none;">
Are you sure you want to rotate the current logs? Are you sure you want to rotate the current logs?
@ -153,7 +156,9 @@ if ($blocklogin === TRUE) {
<tr><td>Content:</td><td><input type="text" id ="searchzone-content"></td></tr> <tr><td>Content:</td><td><input type="text" id ="searchzone-content"></td></tr>
</table> </table>
</div> </div>
<div id="menu" class="jtable-main-container <?php if ($menutype === 'horizontal') { ?>horizontal<?php } ?>"> <div id="menu" class="jtable-main-container <?php if ($menutype === 'horizontal') {
?>horizontal<?php
} ?>">
<div class="jtable-title menu-title"> <div class="jtable-title menu-title">
<div class="jtable-title-text"> <div class="jtable-title-text">
NSEdit! NSEdit!
@ -161,10 +166,12 @@ if ($blocklogin === TRUE) {
</div> </div>
<ul> <ul>
<li><a href="#" id="zoneadmin">Zones</a></li> <li><a href="#" id="zoneadmin">Zones</a></li>
<?php if (is_adminuser()) { ?> <?php if (is_adminuser()) {
?>
<li><a href="#" id="useradmin">Users</a></li> <li><a href="#" id="useradmin">Users</a></li>
<li><a href="#" id="logadmin">Logs</a></li> <li><a href="#" id="logadmin">Logs</a></li>
<?php } ?> <?php
} ?>
<li><a href="#" id="aboutme">About me</a></li> <li><a href="#" id="aboutme">About me</a></li>
<li><a href="index.php?logout=1">Logout</a></li> <li><a href="index.php?logout=1">Logout</a></li>
</ul> </ul>
@ -174,10 +181,12 @@ if ($blocklogin === TRUE) {
} }
?> ?>
<div id="zones"> <div id="zones">
<?php if (is_adminuser() or $allowzoneadd === TRUE) { ?> <?php if (is_adminuser() or $allowzoneadd === true) {
?>
<div style="display: none;" id="ImportZone"></div> <div style="display: none;" id="ImportZone"></div>
<div style="display: none;" id="CloneZone"></div> <div style="display: none;" id="CloneZone"></div>
<?php } ?> <?php
} ?>
<div class="tables" id="MasterZones"> <div class="tables" id="MasterZones">
<div class="searchbar" id="searchbar"> <div class="searchbar" id="searchbar">
<input type="text" id="domsearch" name="domsearch" placeholder="Search...."/> <input type="text" id="domsearch" name="domsearch" placeholder="Search...."/>
@ -185,31 +194,37 @@ if ($blocklogin === TRUE) {
</div> </div>
<div class="tables" id="SlaveZones"></div> <div class="tables" id="SlaveZones"></div>
</div> </div>
<?php if (is_adminuser()) { ?> <?php if (is_adminuser()) {
?>
<div id="users"> <div id="users">
<div class="tables" id="Users"></div> <div class="tables" id="Users"></div>
</div> </div>
<div id="logs"> <div id="logs">
<div class="tables" id="Logs"></div> <div class="tables" id="Logs"></div>
<?php if($allowrotatelogs) { ?> <?php if ($allowrotatelogs) {
?>
<br>Log entries being viewed: <br>Log entries being viewed:
<select id="logfile"> <select id="logfile">
<option value="">(Current logs)</option> <option value="">(Current logs)</option>
<?php <?php
$logfiles=listrotatedlogs(); $logfiles=listrotatedlogs();
if($logfiles !== FALSE) { if ($logfiles !== false) {
foreach ($logfiles as $filename) { foreach ($logfiles as $filename) {
echo '<option value="' . $filename . '">' . str_replace(".json","",$filename) . "</option>\n"; echo '<option value="' . $filename . '">' . str_replace('.json', '', $filename) . "</option>\n";
} }
} } ?></select>
?></select> <?php
<?php } else { ?> } else {
?>
<input type="hidden" id="logfile" value=""> <input type="hidden" id="logfile" value="">
<?php } ?> <?php
} ?>
</div> </div>
<?php } ?> <?php
} ?>
<?php if (has_local_auth()) { ?> <?php if (has_local_auth()) {
?>
<div id="AboutMe"> <div id="AboutMe">
<div class="tables"> <div class="tables">
<p>Hi <?php echo get_sess_user(); ?>. You can change your password here.</p> <p>Hi <?php echo get_sess_user(); ?>. You can change your password here.</p>
@ -238,7 +253,8 @@ if ($blocklogin === TRUE) {
</form> </form>
</div> </div>
</div> </div>
<?php } ?> <?php
} ?>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
window.csrf_token = '<?php echo CSRF_TOKEN ?>'; window.csrf_token = '<?php echo CSRF_TOKEN ?>';
@ -345,10 +361,12 @@ $(document).ready(function () {
actions: { actions: {
listAction: 'zones.php?action=listslaves', listAction: 'zones.php?action=listslaves',
updateAction: 'zones.php?action=update', updateAction: 'zones.php?action=update',
<?php if (is_adminuser() or $allowzoneadd === TRUE) { ?> <?php if (is_adminuser() or $allowzoneadd === true) {
?>
createAction: 'zones.php?action=create', createAction: 'zones.php?action=create',
deleteAction: 'zones.php?action=delete', deleteAction: 'zones.php?action=delete',
<?php } ?> <?php
} ?>
}, },
fields: { fields: {
id: { id: {
@ -371,7 +389,8 @@ $(document).ready(function () {
display: displayDnssecIcon, display: displayDnssecIcon,
listClass: 'dnssec' listClass: 'dnssec'
}, },
<?php if (is_adminuser()) { ?> <?php if (is_adminuser()) {
?>
account: { account: {
title: 'Account', title: 'Account',
width: '8%', width: '8%',
@ -383,7 +402,8 @@ $(document).ready(function () {
inputClass: 'account', inputClass: 'account',
listClass: 'account' listClass: 'account'
}, },
<?php } ?> <?php
} ?>
kind: { kind: {
create: true, create: true,
type: 'hidden', type: 'hidden',
@ -496,7 +516,8 @@ $(document).ready(function () {
hoverAnimationDuration: 60, hoverAnimationDuration: 60,
hoverAnimationEasing: undefined, hoverAnimationEasing: undefined,
items: [ items: [
<?php if (is_adminuser() or $allowzoneadd === TRUE) { ?> <?php if (is_adminuser() or $allowzoneadd === true) {
?>
{ {
icon: 'jtable/lib/themes/metro/add.png', icon: 'jtable/lib/themes/metro/add.png',
text: 'Import a new zone', text: 'Import a new zone',
@ -511,7 +532,8 @@ $(document).ready(function () {
$('#CloneZone').jtable('showCreateForm'); $('#CloneZone').jtable('showCreateForm');
} }
}, },
<?php } ?> <?php
} ?>
], ],
}, },
sorting: false, sorting: false,
@ -715,13 +737,17 @@ $(document).ready(function () {
openChildAsAccordion: true, openChildAsAccordion: true,
actions: { actions: {
listAction: 'zones.php?action=list', listAction: 'zones.php?action=list',
<?php if (is_adminuser() or $allowzoneadd === TRUE) { ?> <?php if (is_adminuser() or $allowzoneadd === true) {
?>
createAction: 'zones.php?action=create', createAction: 'zones.php?action=create',
deleteAction: 'zones.php?action=delete', deleteAction: 'zones.php?action=delete',
<?php } ?> <?php
<?php if (is_adminuser()) { ?> } ?>
<?php if (is_adminuser()) {
?>
updateAction: 'zones.php?action=update' updateAction: 'zones.php?action=update'
<?php } ?> <?php
} ?>
}, },
fields: { fields: {
id: { id: {
@ -744,7 +770,8 @@ $(document).ready(function () {
display: displayDnssecIcon, display: displayDnssecIcon,
listClass: 'dnssec' listClass: 'dnssec'
}, },
<?php if (is_adminuser()) { ?> <?php if (is_adminuser()) {
?>
account: { account: {
title: 'Account', title: 'Account',
width: '8%', width: '8%',
@ -756,7 +783,8 @@ $(document).ready(function () {
inputClass: 'account', inputClass: 'account',
listClass: 'account' listClass: 'account'
}, },
<?php } ?> <?php
} ?>
kind: { kind: {
title: 'Type', title: 'Type',
width: '20%', width: '20%',
@ -782,7 +810,9 @@ $(document).ready(function () {
edit: false, edit: false,
input: function(data) { input: function(data) {
var $template = data.form.find('#Edit-template'); var $template = data.form.find('#Edit-template');
var ns_form = '<?php foreach($defaults['ns'] as $ns) echo '<input type="text" name="nameserver[]" value="'.$ns.'" /><br />'; ?>'; var ns_form = '<?php foreach ($defaults['ns'] as $ns) {
echo '<input type="text" name="nameserver[]" value="' . $ns . '" /><br />';
} ?>';
var $elem = $('<div id="nameservers">' + ns_form + '</div>'); var $elem = $('<div id="nameservers">' + ns_form + '</div>');
$template.change(function() { $template.change(function() {
$.get('zones.php?action=getformnameservers&template='+$template.val(), function(getdata) { $.get('zones.php?action=getformnameservers&template='+$template.val(), function(getdata) {
@ -830,7 +860,8 @@ $(document).ready(function () {
title: 'Domain', title: 'Domain',
inputClass: 'domain' inputClass: 'domain'
}, },
<?php if (is_adminuser()) { ?> <?php if (is_adminuser()) {
?>
account: { account: {
title: 'Account', title: 'Account',
options: function(data) { options: function(data) {
@ -839,7 +870,8 @@ $(document).ready(function () {
defaultValue: 'admin', defaultValue: 'admin',
inputClass: 'account' inputClass: 'account'
}, },
<?php } ?> <?php
} ?>
kind: { kind: {
title: 'Type', title: 'Type',
options: {'Native': 'Native', 'Master': 'Master'}, options: {'Native': 'Native', 'Master': 'Master'},
@ -865,7 +897,9 @@ $(document).ready(function () {
list: false, list: false,
edit: false, edit: false,
input: function(data) { input: function(data) {
var ns_form = '<?php foreach($defaults['ns'] as $ns) echo '<input type="text" name="nameserver[]" value="'.$ns.'" /><br />'; ?>'; var ns_form = '<?php foreach ($defaults['ns'] as $ns) {
echo '<input type="text" name="nameserver[]" value="' . $ns . '" /><br />';
} ?>';
var $elem = $('<div id="nameservers">' + ns_form + '</div>'); var $elem = $('<div id="nameservers">' + ns_form + '</div>');
return $elem; return $elem;
}, },
@ -952,7 +986,8 @@ $(document).ready(function () {
stimer = setTimeout(searchDoms, 400); stimer = setTimeout(searchDoms, 400);
}); });
<?php if (is_adminuser()) { ?> <?php if (is_adminuser()) {
?>
$('#logs').hide(); $('#logs').hide();
$('#Users').hide(); $('#Users').hide();
$('#AboutMe').hide(); $('#AboutMe').hide();
@ -1083,7 +1118,8 @@ $(document).ready(function () {
}); });
} }
}, },
<?php if($allowrotatelogs === TRUE) { ?> <?php if ($allowrotatelogs === true) {
?>
{ {
text: 'Rotate logs', text: 'Rotate logs',
click: function() { click: function() {
@ -1106,8 +1142,10 @@ $(document).ready(function () {
}); });
} }
}, },
<?php } ?> <?php
<?php if($allowclearlogs === TRUE) { ?> } ?>
<?php if ($allowclearlogs === true) {
?>
{ {
icon: 'img/delete_inverted.png', icon: 'img/delete_inverted.png',
text: 'Clear logs', text: 'Clear logs',
@ -1131,7 +1169,8 @@ $(document).ready(function () {
}); });
} }
}, },
<?php } ?> <?php
} ?>
{ {
icon: 'img/export.png', icon: 'img/export.png',
text: 'Download logs', text: 'Download logs',
@ -1186,7 +1225,9 @@ $(document).ready(function () {
entry: $('#searchlogs-entry').val() entry: $('#searchlogs-entry').val()
}); });
}); });
<?php } else { ?> <?php
} else {
?>
$('#AboutMe').hide(); $('#AboutMe').hide();
$('#aboutme').click(function () { $('#aboutme').click(function () {
$('#MasterZones').hide(); $('#MasterZones').hide();
@ -1199,7 +1240,8 @@ $(document).ready(function () {
$('#SlaveZones').show(); $('#SlaveZones').show();
}); });
<?php } ?> <?php
} ?>
$('#MasterZones').jtable('load'); $('#MasterZones').jtable('load');
$('#SlaveZones').jtable('load'); $('#SlaveZones').jtable('load');
}); });

View file

@ -1,18 +1,18 @@
<?php <?php
include_once('includes/config.inc.php'); include_once 'includes/config.inc.php';
include_once('includes/session.inc.php'); include_once 'includes/session.inc.php';
include_once('includes/misc.inc.php'); include_once 'includes/misc.inc.php';
if (!is_csrf_safe()) { if (!is_csrf_safe()) {
header('Status: 403'); header('Status: 403');
header('Location: ./index.php'); header('Location: ./index.php');
jtable_respond(null, 'error', "Authentication required"); jtable_respond(null, 'error', 'Authentication required');
} }
if (!is_adminuser()) { if (!is_adminuser()) {
header('Status: 403'); header('Status: 403');
jtable_respond(null, 'error', "You need adminprivileges to get here"); jtable_respond(null, 'error', 'You need adminprivileges to get here');
} }
if (!isset($_GET['action'])) { if (!isset($_GET['action'])) {
@ -20,15 +20,15 @@ if (!isset($_GET['action'])) {
jtable_respond(null, 'error', 'No action given'); jtable_respond(null, 'error', 'No action given');
} }
if ($logging !== TRUE) { if ($logging !== true) {
jtable_respond(null, 'error', 'Logging is disabled'); jtable_respond(null, 'error', 'Logging is disabled');
} else { } else {
switch ($_GET['action']) { switch ($_GET['action']) {
case "list": case 'list':
if(!empty($_POST['logfile'])) { if (!empty($_POST['logfile'])) {
if(preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}\.json/',$_POST['logfile']) == 1) { if (preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}\.json/', $_POST['logfile']) == 1) {
$entries=json_decode(file_get_contents($logsdirectory . "/" . $_POST['logfile']),true); $entries=json_decode(file_get_contents($logsdirectory . '/' . $_POST['logfile']), true);
} else { } else {
jtable_respond(null, 'error', "Can't find log file"); jtable_respond(null, 'error', "Can't find log file");
break; break;
@ -37,18 +37,20 @@ if ($logging !== TRUE) {
$entries=getlogs(); $entries=getlogs();
} }
if(!empty($_POST['user'])) { if (!empty($_POST['user'])) {
$entries=array_filter($entries, $entries=array_filter(
$entries,
function ($val) { function ($val) {
return(stripos($val['user'], $_POST['user']) !== FALSE); return(stripos($val['user'], $_POST['user']) !== false);
} }
); );
} }
if(!empty($_POST['entry'])) { if (!empty($_POST['entry'])) {
$entries=array_filter($entries, $entries=array_filter(
$entries,
function ($val) { function ($val) {
return(stripos($val['log'], $_POST['entry']) !== FALSE); return(stripos($val['log'], $_POST['entry']) !== false);
} }
); );
} }
@ -56,10 +58,10 @@ if ($logging !== TRUE) {
jtable_respond($entries); jtable_respond($entries);
break; break;
case "export": case 'export':
if(!empty($_GET['logfile'])) { if (!empty($_GET['logfile'])) {
if(preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}\.json/',$_GET['logfile']) == 1) { if (preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}\.json/', $_GET['logfile']) == 1) {
$entries=json_decode(file_get_contents($logsdirectory . "/" . $_GET['logfile']),true); $entries=json_decode(file_get_contents($logsdirectory . '/' . $_GET['logfile']), true);
} else { } else {
jtable_respond(null, 'error', "Can't find log file"); jtable_respond(null, 'error', "Can't find log file");
break; break;
@ -68,22 +70,22 @@ if ($logging !== TRUE) {
$entries=getlogs(); $entries=getlogs();
} }
if(defined('JSON_PRETTY_PRINT')) { if (defined('JSON_PRETTY_PRINT')) {
print json_encode($entries,JSON_PRETTY_PRINT); print json_encode($entries, JSON_PRETTY_PRINT);
} else { } else {
print json_encode($entries); print json_encode($entries);
} }
break; break;
case "clear": case 'clear':
if($allowclearlogs === TRUE) { if ($allowclearlogs === true) {
clearlogs(); clearlogs();
} else { } else {
jtable_respond(null, 'error', 'Invalid action'); jtable_respond(null, 'error', 'Invalid action');
} }
break; break;
case "rotate": case 'rotate':
if($allowrotatelogs === TRUE) { if ($allowrotatelogs === true) {
rotatelogs(); rotatelogs();
} else { } else {
jtable_respond(null, 'error', 'Invalid action'); jtable_respond(null, 'error', 'Invalid action');

View file

@ -1,18 +1,18 @@
<?php <?php
include_once('includes/config.inc.php'); include_once 'includes/config.inc.php';
include_once('includes/session.inc.php'); include_once 'includes/session.inc.php';
include_once('includes/misc.inc.php'); include_once 'includes/misc.inc.php';
if (!is_csrf_safe()) { if (!is_csrf_safe()) {
header('Status: 403'); header('Status: 403');
header('Location: ./index.php'); header('Location: ./index.php');
jtable_respond(null, 'error', "Authentication required"); jtable_respond(null, 'error', 'Authentication required');
} }
if (!is_adminuser()) { if (!is_adminuser()) {
header('Status: 403'); header('Status: 403');
jtable_respond(null, 'error', "You need adminprivileges to get here"); jtable_respond(null, 'error', 'You need adminprivileges to get here');
} }
if (!isset($_GET['action'])) { if (!isset($_GET['action'])) {
@ -22,29 +22,29 @@ if (!isset($_GET['action'])) {
switch ($_GET['action']) { switch ($_GET['action']) {
case "list": case 'list':
$users = get_all_users(); $users = get_all_users();
jtable_respond($users); jtable_respond($users);
break; break;
case "listoptions": case 'listoptions':
$users = get_all_users(); $users = get_all_users();
$retusers = array(); $retusers = [];
foreach ($users as $user) { foreach ($users as $user) {
$retusers[] = array( $retusers[] = [
'DisplayText' => $user['emailaddress'], 'DisplayText' => $user['emailaddress'],
'Value' => $user['emailaddress']); 'Value' => $user['emailaddress']];
} }
jtable_respond($retusers, 'options'); jtable_respond($retusers, 'options');
break; break;
case "create": case 'create':
$emailaddress = isset($_POST['emailaddress']) ? $_POST['emailaddress'] : ''; $emailaddress = isset($_POST['emailaddress']) ? $_POST['emailaddress'] : '';
$isadmin = isset($_POST['isadmin']) ? $_POST['isadmin'] : '0'; $isadmin = isset($_POST['isadmin']) ? $_POST['isadmin'] : '0';
$password = isset($_POST['password']) ? $_POST['password'] : ''; $password = isset($_POST['password']) ? $_POST['password'] : '';
if (!valid_user($emailaddress)) { if (!valid_user($emailaddress)) {
jtable_respond(null, 'error', "Please only use ^[a-z0-9@_.-]+$ for usernames"); jtable_respond(null, 'error', 'Please only use ^[a-z0-9@_.-]+$ for usernames');
} }
if (!$password) { if (!$password) {
@ -56,31 +56,31 @@ case "create":
} }
if (add_user($emailaddress, $isadmin, $password)) { if (add_user($emailaddress, $isadmin, $password)) {
$result = array('emailaddress' => $emailaddress, 'isadmin' => $isadmin); $result = ['emailaddress' => $emailaddress, 'isadmin' => $isadmin];
jtable_respond($result, 'single'); jtable_respond($result, 'single');
} else { } else {
jtable_respond(null, 'error', 'Could not create user'); jtable_respond(null, 'error', 'Could not create user');
} }
break; break;
case "update": case 'update':
$id = isset($_POST['id']) ? intval($_POST['id']) : ''; $id = isset($_POST['id']) ? intval($_POST['id']) : '';
$emailaddress = isset($_POST['emailaddress']) ? $_POST['emailaddress'] : ''; $emailaddress = isset($_POST['emailaddress']) ? $_POST['emailaddress'] : '';
$isadmin = isset($_POST['isadmin']) ? $_POST['isadmin'] : '0'; $isadmin = isset($_POST['isadmin']) ? $_POST['isadmin'] : '0';
$password = isset($_POST['password']) ? $_POST['password'] : ''; $password = isset($_POST['password']) ? $_POST['password'] : '';
if ($id != '' and update_user($id, $isadmin, $password)) { if ($id != '' and update_user($id, $isadmin, $password)) {
$result = array('isadmin' => $isadmin); $result = ['isadmin' => $isadmin];
jtable_respond($result, 'single'); jtable_respond($result, 'single');
} else { } else {
jtable_respond(null, 'error', 'Could not update user'); jtable_respond(null, 'error', 'Could not update user');
} }
break; break;
case "delete": case 'delete':
$id = isset($_POST['id']) ? intval($_POST['id']) : ''; $id = isset($_POST['id']) ? intval($_POST['id']) : '';
if ($id != '' and delete_user($id) !== FALSE) { if ($id != '' and delete_user($id) !== false) {
jtable_respond(null, 'delete'); jtable_respond(null, 'delete');
} else { } else {
jtable_respond(null, 'error', 'Could not delete user'); jtable_respond(null, 'error', 'Could not delete user');

315
zones.php
View file

@ -1,32 +1,34 @@
<?php <?php
include_once('includes/config.inc.php'); include_once 'includes/config.inc.php';
include_once('includes/session.inc.php'); include_once 'includes/session.inc.php';
include_once('includes/misc.inc.php'); include_once 'includes/misc.inc.php';
include_once('includes/class/PdnsApi.php'); include_once 'includes/class/PdnsApi.php';
include_once('includes/class/Zone.php'); include_once 'includes/class/Zone.php';
if (!is_csrf_safe()) { if (!is_csrf_safe()) {
header('Status: 403'); header('Status: 403');
header('Location: ./index.php'); header('Location: ./index.php');
jtable_respond(null, 'error', "Authentication required"); jtable_respond(null, 'error', 'Authentication required');
} }
$quoteus = ['TXT', 'SPF'];
$quoteus = array('TXT', 'SPF');
/* This function is taken from: /* This function is taken from:
http://pageconfig.com/post/how-to-validate-ascii-text-in-php and got fixed by http://pageconfig.com/post/how-to-validate-ascii-text-in-php and got fixed by
#powerdns */ #powerdns */
function is_ascii($string) { function is_ascii($string)
return ( bool ) ! preg_match( '/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x80-\\xff]/' , $string ); {
return ( bool ) ! preg_match('/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x80-\\xff]/', $string);
} }
function _valid_label($name) { function _valid_label($name)
return is_ascii($name) && ( bool ) preg_match("/^([-.a-z0-9_\/\*]+)?.$/i", $name ); {
return is_ascii($name) && ( bool ) preg_match("/^([-.a-z0-9_\/\*]+)?.$/i", $name);
} }
function decode_record_id($id) { function decode_record_id($id)
{
$record = json_decode($id, 1); $record = json_decode($id, 1);
if (!$record if (!$record
|| !isset($record['name']) || !isset($record['name'])
@ -34,18 +36,19 @@ function decode_record_id($id) {
|| !isset($record['ttl']) || !isset($record['ttl'])
|| !isset($record['content']) || !isset($record['content'])
|| !isset($record['disabled'])) { || !isset($record['disabled'])) {
jtable_respond(null, 'error', "Invalid record id"); jtable_respond(null, 'error', 'Invalid record id');
} }
return $record; return $record;
} }
function compareName($a, $b) { function compareName($a, $b)
{
$a = array_reverse(explode('.', $a)); $a = array_reverse(explode('.', $a));
$b = array_reverse(explode('.', $b)); $b = array_reverse(explode('.', $b));
for ($i = 0; ; ++$i) { for ($i = 0; ; ++$i) {
if (!isset($a[$i])) { if (!isset($a[$i])) {
return isset($b[$i]) ? -1 : 0; return isset($b[$i]) ? -1 : 0;
} else if (!isset($b[$i])) { } elseif (!isset($b[$i])) {
return 1; return 1;
} }
$cmp = strnatcasecmp($a[$i], $b[$i]); $cmp = strnatcasecmp($a[$i], $b[$i]);
@ -55,14 +58,18 @@ function compareName($a, $b) {
} }
} }
function zone_compare($a, $b) { function zone_compare($a, $b)
if ($cmp = strnatcasecmp($a['name'], $b['name'])) return $cmp; {
if ($cmp = strnatcasecmp($a['name'], $b['name'])) {
return $cmp;
}
return 0; return 0;
} }
function rrtype_compare($a, $b) { function rrtype_compare($a, $b)
{
# sort specials before everything else # sort specials before everything else
$specials = array('SOA', 'NS', 'MX'); $specials = ['SOA', 'NS', 'MX'];
$spa = array_search($a, $specials, true); $spa = array_search($a, $specials, true);
$spb = array_search($b, $specials, true); $spb = array_search($b, $specials, true);
if ($spa === false) { if ($spa === false) {
@ -72,32 +79,55 @@ function rrtype_compare($a, $b) {
} }
} }
function record_compare_default($a, $b) { function record_compare_default($a, $b)
if ($cmp = compareName($a['name'], $b['name'])) return $cmp; {
if ($cmp = rrtype_compare($a['type'], $b['type'])) return $cmp; if ($cmp = compareName($a['name'], $b['name'])) {
if ($cmp = strnatcasecmp($a['content'], $b['content'])) return $cmp; return $cmp;
}
if ($cmp = rrtype_compare($a['type'], $b['type'])) {
return $cmp;
}
if ($cmp = strnatcasecmp($a['content'], $b['content'])) {
return $cmp;
}
return 0; return 0;
} }
function record_compare_name($a, $b) { function record_compare_name($a, $b)
{
return record_compare_default($a, $b); return record_compare_default($a, $b);
} }
function record_compare_type($a, $b) { function record_compare_type($a, $b)
if ($cmp = rrtype_compare($a['type'], $b['type'])) return $cmp; {
if ($cmp = compareName($a['name'], $b['name'])) return $cmp; if ($cmp = rrtype_compare($a['type'], $b['type'])) {
if ($cmp = strnatcasecmp($a['content'], $b['content'])) return $cmp; return $cmp;
}
if ($cmp = compareName($a['name'], $b['name'])) {
return $cmp;
}
if ($cmp = strnatcasecmp($a['content'], $b['content'])) {
return $cmp;
}
return 0; return 0;
} }
function record_compare_content($a, $b) { function record_compare_content($a, $b)
if ($cmp = strnatcasecmp($a['content'], $b['content'])) return $cmp; {
if ($cmp = compareName($a['name'], $b['name'])) return $cmp; if ($cmp = strnatcasecmp($a['content'], $b['content'])) {
if ($cmp = rrtype_compare($a['type'], $b['type'])) return $cmp; return $cmp;
}
if ($cmp = compareName($a['name'], $b['name'])) {
return $cmp;
}
if ($cmp = rrtype_compare($a['type'], $b['type'])) {
return $cmp;
}
return 0; return 0;
} }
function add_db_zone($zonename, $accountname) { function add_db_zone($zonename, $accountname)
{
if (valid_user($accountname) === false) { if (valid_user($accountname) === false) {
jtable_respond(null, 'error', "$accountname is not a valid username"); jtable_respond(null, 'error', "$accountname is not a valid username");
} }
@ -110,49 +140,53 @@ function add_db_zone($zonename, $accountname) {
} }
$db = get_db(); $db = get_db();
$q = $db->prepare("INSERT OR REPLACE INTO zones (zone, owner) VALUES (?, (SELECT id FROM users WHERE emailaddress = ?))"); $q = $db->prepare('INSERT OR REPLACE INTO zones (zone, owner) VALUES (?, (SELECT id FROM users WHERE emailaddress = ?))');
$q->bindValue(1, $zonename, SQLITE3_TEXT); $q->bindValue(1, $zonename, SQLITE3_TEXT);
$q->bindValue(2, $accountname, SQLITE3_TEXT); $q->bindValue(2, $accountname, SQLITE3_TEXT);
$q->execute(); $q->execute();
} }
function delete_db_zone($zonename) { function delete_db_zone($zonename)
{
if (!_valid_label($zonename)) { if (!_valid_label($zonename)) {
jtable_respond(null, 'error', "$zonename is not a valid zonename"); jtable_respond(null, 'error', "$zonename is not a valid zonename");
} }
$db = get_db(); $db = get_db();
$q = $db->prepare("DELETE FROM zones WHERE zone = ?"); $q = $db->prepare('DELETE FROM zones WHERE zone = ?');
$q->bindValue(1, $zonename, SQLITE3_TEXT); $q->bindValue(1, $zonename, SQLITE3_TEXT);
$q->execute(); $q->execute();
} }
function get_zone_account($zonename, $default) { function get_zone_account($zonename, $default)
{
if (!_valid_label($zonename)) { if (!_valid_label($zonename)) {
jtable_respond(null, 'error', "$zonename is not a valid zonename"); jtable_respond(null, 'error', "$zonename is not a valid zonename");
} }
$db = get_db(); $db = get_db();
$q = $db->prepare("SELECT u.emailaddress FROM users u, zones z WHERE z.owner = u.id AND z.zone = ?"); $q = $db->prepare('SELECT u.emailaddress FROM users u, zones z WHERE z.owner = u.id AND z.zone = ?');
$q->bindValue(1, $zonename, SQLITE3_TEXT); $q->bindValue(1, $zonename, SQLITE3_TEXT);
$result = $q->execute(); $result = $q->execute();
$zoneinfo = $result->fetchArray(SQLITE3_ASSOC); $zoneinfo = $result->fetchArray(SQLITE3_ASSOC);
if (isset($zoneinfo['emailaddress']) && $zoneinfo['emailaddress'] != null ) { if (isset($zoneinfo['emailaddress']) && $zoneinfo['emailaddress'] != null) {
return $zoneinfo['emailaddress']; return $zoneinfo['emailaddress'];
} }
return $default; return $default;
} }
function quote_content($content) { function quote_content($content)
{
# empty TXT records are ok, otherwise require surrounding quotes: "..." # empty TXT records are ok, otherwise require surrounding quotes: "..."
if (strlen($content) == 1 || substr($content, 0, 1) !== '"' || substr($content, -1) !== '"') { if (strlen($content) == 1 || substr($content, 0, 1) !== '"' || substr($content, -1) !== '"') {
# fix quoting: first escape all \, then all ", then surround with quotes. # fix quoting: first escape all \, then all ", then surround with quotes.
$content = '"'.str_replace('"', '\\"', str_replace('\\', '\\\\', $content)).'"'; $content = '"' . str_replace('"', '\\"', str_replace('\\', '\\\\', $content)) . '"';
} }
return $content; return $content;
} }
function check_account($zone) { function check_account($zone)
{
return is_adminuser() or ($zone->account === get_sess_user()); return is_adminuser() or ($zone->account === get_sess_user());
} }
@ -163,13 +197,13 @@ if (isset($_GET['action'])) {
} }
try { try {
$api = new PdnsAPI; $api = new PdnsAPI();
switch ($action) { switch ($action) {
case "list": case 'list':
case "listslaves": case 'listslaves':
$return = Array(); $return = [];
$q = isset($_POST['domsearch']) ? $_POST['domsearch'] : false; $q = isset($_POST['domsearch']) ? $_POST['domsearch'] : false;
foreach ($api->listzones($q) as $sresult) { foreach ($api->listzones($q) as $sresult) {
$zone = new Zone(); $zone = new Zone();
@ -178,104 +212,107 @@ case "listslaves":
$zone->setAccount(get_zone_account($zone->name, 'admin')); $zone->setAccount(get_zone_account($zone->name, 'admin'));
} }
if (!check_account($zone)) if (!check_account($zone)) {
continue; continue;
}
if ($action == "listslaves" and $zone->kind == "Slave") { if ($action == 'listslaves' and $zone->kind == 'Slave') {
array_push($return, $zone->export()); array_push($return, $zone->export());
} elseif ($action == "list" and $zone->kind != "Slave") { } elseif ($action == 'list' and $zone->kind != 'Slave') {
if ($zone->dnssec) { if ($zone->dnssec) {
$zone->setKeyinfo($api->getzonekeys($zone->id)); $zone->setKeyinfo($api->getzonekeys($zone->id));
} }
array_push($return, $zone->export()); array_push($return, $zone->export());
} }
} }
usort($return, "zone_compare"); usort($return, 'zone_compare');
jtable_respond($return); jtable_respond($return);
break; break;
case "listrecords": case 'listrecords':
$zonedata = $api->loadzone($_GET['zoneid']); $zonedata = $api->loadzone($_GET['zoneid']);
$zone = new Zone(); $zone = new Zone();
$zone->parse($zonedata); $zone->parse($zonedata);
$records = $zone->rrsets2records(); $records = $zone->rrsets2records();
if(!empty($_POST['label'])) { if (!empty($_POST['label'])) {
$records=array_filter($records, $records=array_filter(
$records,
function ($val) { function ($val) {
return(stripos($val['name'], $_POST['label']) !== FALSE); return(stripos($val['name'], $_POST['label']) !== false);
} }
); );
} }
if(!empty($_POST['type'])) { if (!empty($_POST['type'])) {
$records=array_filter($records, $records=array_filter(
$records,
function ($val) { function ($val) {
return($val['type'] == $_POST['type']); return($val['type'] == $_POST['type']);
} }
); );
} }
if(!empty($_POST['content'])) { if (!empty($_POST['content'])) {
$records=array_filter($records, $records=array_filter(
$records,
function ($val) { function ($val) {
return(stripos($val['content'], $_POST['content']) !== FALSE); return(stripos($val['content'], $_POST['content']) !== false);
} }
); );
} }
if (isset($_GET['jtSorting'])) { if (isset($_GET['jtSorting'])) {
list($scolumn, $sorder) = preg_split("/ /", $_GET['jtSorting']); list($scolumn, $sorder) = preg_split('/ /', $_GET['jtSorting']);
switch ($scolumn) { switch ($scolumn) {
case "type": case 'type':
usort($records, "record_compare_type"); usort($records, 'record_compare_type');
break; break;
case "content": case 'content':
usort($records, "record_compare_content"); usort($records, 'record_compare_content');
break; break;
default: default:
usort($records, "record_compare_name"); usort($records, 'record_compare_name');
break; break;
} }
if ($sorder == "DESC") { if ($sorder == 'DESC') {
$records = array_reverse($records); $records = array_reverse($records);
} }
} else { } else {
usort($records, "record_compare_name"); usort($records, 'record_compare_name');
} }
jtable_respond($records); jtable_respond($records);
break; break;
case "delete": case 'delete':
$zone = $api->loadzone($_POST['id']); $zone = $api->loadzone($_POST['id']);
$api->deletezone($_POST['id']); $api->deletezone($_POST['id']);
delete_db_zone($zone['name']); delete_db_zone($zone['name']);
writelog("Deleted zone ".$zone['name']); writelog('Deleted zone ' . $zone['name']);
jtable_respond(null, 'delete'); jtable_respond(null, 'delete');
break; break;
case 'create':
case "create":
$zonename = isset($_POST['name']) ? $_POST['name'] : ''; $zonename = isset($_POST['name']) ? $_POST['name'] : '';
$zonekind = isset($_POST['kind']) ? $_POST['kind'] : ''; $zonekind = isset($_POST['kind']) ? $_POST['kind'] : '';
if (!is_adminuser() and $allowzoneadd !== true) { if (!is_adminuser() and $allowzoneadd !== true) {
jtable_respond(null, 'error', "You are not allowed to add zones"); jtable_respond(null, 'error', 'You are not allowed to add zones');
} }
if (!_valid_label($zonename)) { if (!_valid_label($zonename)) {
jtable_respond(null, 'error', "Please only use [a-z0-9_/.-]"); jtable_respond(null, 'error', 'Please only use [a-z0-9_/.-]');
} }
if (!$zonename || !$zonekind) { if (!$zonename || !$zonekind) {
jtable_respond(null, 'error', "Not enough data"); jtable_respond(null, 'error', 'Not enough data');
} }
$zone = new Zone(); $zone = new Zone();
$zone->setKind($zonekind); $zone->setKind($zonekind);
$zone->setName($zonename); $zone->setName($zonename);
if ($zonekind != "Slave") { if ($zonekind != 'Slave') {
if (!isset($_POST['zone']) or isset($_POST['owns'])) { if (!isset($_POST['zone']) or isset($_POST['owns'])) {
foreach ($_POST['nameserver'] as $ns) { foreach ($_POST['nameserver'] as $ns) {
$zone->addNameserver($ns); $zone->addNameserver($ns);
@ -284,7 +321,7 @@ case "create":
$zone->importData($_POST['zone']); $zone->importData($_POST['zone']);
} }
if (isset($defaults['soa_edit_api'])) { if (isset($defaults['soa_edit_api'])) {
$zone->setSoaEditApi($defaults['soa_edit_api'], True); $zone->setSoaEditApi($defaults['soa_edit_api'], true);
} }
if (isset($defaults['soa_edit'])) { if (isset($defaults['soa_edit'])) {
$zone->setSoaEdit($defaults['soa_edit']); $zone->setSoaEdit($defaults['soa_edit']);
@ -319,7 +356,9 @@ case "create":
if (isset($_POST['template']) && $_POST['template'] != 'None') { if (isset($_POST['template']) && $_POST['template'] != 'None') {
foreach (user_template_list() as $template) { foreach (user_template_list() as $template) {
if ($template['name'] !== $_POST['template']) continue; if ($template['name'] !== $_POST['template']) {
continue;
}
foreach ($template['records'] as $record) { foreach ($template['records'] as $record) {
$rrset = $zone->getRRSet($record['name'], $record['type']); $rrset = $zone->getRRSet($record['name'], $record['type']);
@ -330,8 +369,8 @@ case "create":
$api->savezone($zone->export()); $api->savezone($zone->export());
foreach ($template['records'] as $record) { foreach ($template['records'] as $record) {
$name = $record['name'] != '' ? join(Array($record['name'],'.',$zonename)) : $zonename; $name = $record['name'] != '' ? join([$record['name'],'.',$zonename]) : $zonename;
$record['content'] = str_replace("[zonename]", $zonename, $record['content']); $record['content'] = str_replace('[zonename]', $zonename, $record['content']);
$zone->addRecord($name, $record['type'], $record['content']); $zone->addRecord($name, $record['type'], $record['content']);
} }
@ -340,20 +379,21 @@ case "create":
} }
$zone = $api->savezone($zone->export()); $zone = $api->savezone($zone->export());
writelog("Created zone ".$zone['name']); writelog('Created zone ' . $zone['name']);
jtable_respond($zone, 'single'); jtable_respond($zone, 'single');
break; break;
case "update": case 'update':
$zone = new Zone(); $zone = new Zone();
$zone->parse($api->loadzone($_POST['id'])); $zone->parse($api->loadzone($_POST['id']));
if ($zone->setSoaEditApi($defaults['soa_edit_api']) != False) if ($zone->setSoaEditApi($defaults['soa_edit_api']) != false) {
writelog("Set SOA-EDIT-API to ".$defaults['soa_edit_api']." for ",$zone->name); writelog('Set SOA-EDIT-API to ' . $defaults['soa_edit_api'] . ' for ', $zone->name);
}
$zoneaccount = isset($_POST['account']) ? $_POST['account'] : $zone->account; $zoneaccount = isset($_POST['account']) ? $_POST['account'] : $zone->account;
if ($zone->account !== $zoneaccount) { if ($zone->account !== $zoneaccount) {
if (!is_adminuser()) { if (!is_adminuser()) {
header("Status: 403 Access denied"); header('Status: 403 Access denied');
jtable_respond(null, 'error', "Can't change account"); jtable_respond(null, 'error', "Can't change account");
} else { } else {
add_db_zone($zone->name, $zoneaccount); add_db_zone($zone->name, $zoneaccount);
@ -363,20 +403,21 @@ case "update":
if (isset($_POST['masters'])) { if (isset($_POST['masters'])) {
$zone->eraseMasters(); $zone->eraseMasters();
foreach(preg_split('/[,;\s]+/', $_POST['masters'], null, PREG_SPLIT_NO_EMPTY) as $master) { foreach (preg_split('/[,;\s]+/', $_POST['masters'], null, PREG_SPLIT_NO_EMPTY) as $master) {
$zone->addMaster($master); $zone->addMaster($master);
} }
} }
writelog("Updated zone ".$zone->name); writelog('Updated zone ' . $zone->name);
jtable_respond($api->savezone($zone->export()), 'single'); jtable_respond($api->savezone($zone->export()), 'single');
break; break;
case "createrecord": case 'createrecord':
$zone = new Zone(); $zone = new Zone();
$zone->parse($api->loadzone($_GET['zoneid'])); $zone->parse($api->loadzone($_GET['zoneid']));
if ($zone->setSoaEditApi($defaults['soa_edit_api']) != False) if ($zone->setSoaEditApi($defaults['soa_edit_api']) != false) {
writelog("Set SOA-EDIT-API to ".$defaults['soa_edit_api']." for ",$zone->name); writelog('Set SOA-EDIT-API to ' . $defaults['soa_edit_api'] . ' for ', $zone->name);
}
$name = isset($_POST['name']) ? $_POST['name'] : ''; $name = isset($_POST['name']) ? $_POST['name'] : '';
$type = $_POST['type']; $type = $_POST['type'];
@ -387,40 +428,41 @@ case "createrecord":
} elseif (string_ends_with($name, '.')) { } elseif (string_ends_with($name, '.')) {
# "absolute" name, shouldn't append zone[name] - but check. # "absolute" name, shouldn't append zone[name] - but check.
if (!string_ends_with($name, $zone->name)) { if (!string_ends_with($name, $zone->name)) {
jtable_respond(null, 'error', "Name $name not in zone ".$zone->name); jtable_respond(null, 'error', "Name $name not in zone " . $zone->name);
} }
} else if (!string_ends_with($name.'.', $zone->name)) { } elseif (!string_ends_with($name . '.', $zone->name)) {
$name = $name . '.' . $zone->name; $name = $name . '.' . $zone->name;
} else { } else {
$name = $name.'.'; $name = $name . '.';
} }
if (!_valid_label($name)) { if (!_valid_label($name)) {
jtable_respond(null, 'error', "Please only use [a-z0-9_/.-]"); jtable_respond(null, 'error', 'Please only use [a-z0-9_/.-]');
} }
if (!$type) { if (!$type) {
jtable_respond(null, 'error', "Require a type"); jtable_respond(null, 'error', 'Require a type');
} }
if (!is_ascii($content)) { if (!is_ascii($content)) {
jtable_respond(null, 'error', "Please only use ASCII-characters in your fields"); jtable_respond(null, 'error', 'Please only use ASCII-characters in your fields');
} }
if (array_search($type, $quoteus) !== FALSE) { if (array_search($type, $quoteus) !== false) {
$content = quote_content($content); $content = quote_content($content);
} }
$record = $zone->addRecord($name, $type, $content, $_POST['disabled'], $_POST['ttl'], $_POST['setptr']); $record = $zone->addRecord($name, $type, $content, $_POST['disabled'], $_POST['ttl'], $_POST['setptr']);
$api->savezone($zone->export()); $api->savezone($zone->export());
writelog("Created record: ".$record['id']); writelog('Created record: ' . $record['id']);
jtable_respond($record, 'single'); jtable_respond($record, 'single');
break; break;
case "editrecord": case 'editrecord':
$zone = new Zone(); $zone = new Zone();
$zone->parse($api->loadzone($_GET['zoneid'])); $zone->parse($api->loadzone($_GET['zoneid']));
if ($zone->setSoaEditApi($defaults['soa_edit_api']) != False) if ($zone->setSoaEditApi($defaults['soa_edit_api']) != false) {
writelog("Set SOA-EDIT-API to ".$defaults['soa_edit_api']." for ",$zone->name); writelog('Set SOA-EDIT-API to ' . $defaults['soa_edit_api'] . ' for ', $zone->name);
}
$old_record = decode_record_id(isset($_POST['id']) ? $_POST['id'] : ''); $old_record = decode_record_id(isset($_POST['id']) ? $_POST['id'] : '');
@ -429,7 +471,7 @@ case "editrecord":
$content = $_POST['content']; $content = $_POST['content'];
$type = $_POST['type']; $type = $_POST['type'];
if (array_search($type, $quoteus) !== FALSE) { if (array_search($type, $quoteus) !== false) {
$content = quote_content($content); $content = quote_content($content);
} }
@ -438,15 +480,16 @@ case "editrecord":
$api->savezone($zone->export()); $api->savezone($zone->export());
$record = $zone->getRecord($_POST['name'], $_POST['type'], $content); $record = $zone->getRecord($_POST['name'], $_POST['type'], $content);
writelog("Updated record ".$_POST['id']." to ".$record['id']); writelog('Updated record ' . $_POST['id'] . ' to ' . $record['id']);
jtable_respond($record, 'single'); jtable_respond($record, 'single');
break; break;
case "deleterecord": case 'deleterecord':
$zone = new Zone(); $zone = new Zone();
$zone->parse($api->loadzone($_GET['zoneid'])); $zone->parse($api->loadzone($_GET['zoneid']));
if ($zone->setSoaEditApi($defaults['soa_edit_api']) != False) if ($zone->setSoaEditApi($defaults['soa_edit_api']) != false) {
writelog("Set SOA-EDIT-API to ".$defaults['soa_edit_api']." for ",$zone->name); writelog('Set SOA-EDIT-API to ' . $defaults['soa_edit_api'] . ' for ', $zone->name);
}
$old_record = decode_record_id(isset($_POST['id']) ? $_POST['id'] : ''); $old_record = decode_record_id(isset($_POST['id']) ? $_POST['id'] : '');
$rrset = $zone->getRRSet($old_record['name'], $old_record['type']); $rrset = $zone->getRRSet($old_record['name'], $old_record['type']);
@ -454,31 +497,32 @@ case "deleterecord":
$api->savezone($zone->export()); $api->savezone($zone->export());
writelog("Deleted record ".$_POST['id']); writelog('Deleted record ' . $_POST['id']);
jtable_respond(null, 'delete'); jtable_respond(null, 'delete');
break; break;
case "export": case 'export':
writelog("Exported zone ".$_GET['zoneid']); writelog('Exported zone ' . $_GET['zoneid']);
jtable_respond($api->exportzone($_GET['zoneid']), 'single'); jtable_respond($api->exportzone($_GET['zoneid']), 'single');
break; break;
case "clone": case 'clone':
$name = $_POST['destname']; $name = $_POST['destname'];
$src = $_POST['sourcename']; $src = $_POST['sourcename'];
if (!string_ends_with($name, '.')) { if (!string_ends_with($name, '.')) {
$name = $name."."; $name = $name . '.';
} }
if (!_valid_label($name)) { if (!_valid_label($name)) {
jtable_respond(null, 'error', "Invalid destination zonename"); jtable_respond(null, 'error', 'Invalid destination zonename');
} }
$srczone = new Zone(); $srczone = new Zone();
$srczone->parse($api->loadzone($src)); $srczone->parse($api->loadzone($src));
if ($srczone->setSoaEditApi($defaults['soa_edit_api']) != False) if ($srczone->setSoaEditApi($defaults['soa_edit_api']) != false) {
writelog("Set SOA-EDIT-API to ".$defaults['soa_edit_api']." for ",$srczone->name); writelog('Set SOA-EDIT-API to ' . $defaults['soa_edit_api'] . ' for ', $srczone->name);
}
$srczone->setId(''); $srczone->setId('');
$srczone->setName($name); $srczone->setName($name);
@ -491,7 +535,7 @@ case "clone":
foreach ($srczone->rrsets as $rrset) { foreach ($srczone->rrsets as $rrset) {
$newname = $rrset->name; $newname = $rrset->name;
$newname = preg_replace('/'.$src.'$/', $name, $newname); $newname = preg_replace('/' . $src . '$/', $name, $newname);
$rrset->setName($newname); $rrset->setName($newname);
} }
@ -509,15 +553,17 @@ case "clone":
jtable_respond($zone, 'single'); jtable_respond($zone, 'single');
break; break;
case "gettemplatenameservers": case 'gettemplatenameservers':
$ret = array(); $ret = [];
$type = $_GET['prisec']; $type = $_GET['prisec'];
foreach (user_template_list() as $template) { foreach (user_template_list() as $template) {
if ($template['name'] !== $_GET['template']) continue; if ($template['name'] !== $_GET['template']) {
continue;
}
$rc = 0; $rc = 0;
foreach ($template['records'] as $record) { foreach ($template['records'] as $record) {
if ($record['type'] == "NS") { if ($record['type'] == 'NS') {
if (($type == 'pri' && $rc == 0) or ($type == 'sec' && $rc == 1)) { if (($type == 'pri' && $rc == 0) or ($type == 'sec' && $rc == 1)) {
echo $record['content']; echo $record['content'];
exit(0); exit(0);
@ -525,31 +571,34 @@ case "gettemplatenameservers":
$rc++; $rc++;
} }
} }
echo ""; echo '';
} }
break; break;
case "getformnameservers": case 'getformnameservers':
$inputs = array(); $inputs = [];
foreach (user_template_list() as $template) { foreach (user_template_list() as $template) {
if ($template['name'] !== $_GET['template']) continue; if ($template['name'] !== $_GET['template']) {
continue;
}
foreach ($template['records'] as $record) { foreach ($template['records'] as $record) {
if ($record['type'] == "NS" and array_search($record['content'], $inputs) === false) { if ($record['type'] == 'NS' and array_search($record['content'], $inputs) === false) {
array_push($inputs, $record['content']); array_push($inputs, $record['content']);
echo '<input type="text" name="nameserver[]" value="'.$record['content'].'" readonly /><br />'; echo '<input type="text" name="nameserver[]" value="' . $record['content'] . '" readonly /><br />';
} }
} }
} }
break; break;
case "formzonelist": case 'formzonelist':
$zones = $api->listzones(); $zones = $api->listzones();
usort($zones, "zone_compare"); usort($zones, 'zone_compare');
$ret = array(); $ret = [];
foreach ($zones as $zone) { foreach ($zones as $zone) {
if ($zone['kind'] == 'Slave') if ($zone['kind'] == 'Slave') {
continue; continue;
array_push($ret, array( }
array_push($ret, [
'DisplayText' => $zone['name'], 'DisplayText' => $zone['name'],
'Value' => $zone['id'])); 'Value' => $zone['id']]);
} }
jtable_respond($ret, 'options'); jtable_respond($ret, 'options');
break; break;