[ 'friendlyName' => 'Username', 'validators' => [ 'required' => 'required', ] ], 'password' => [ 'friendlyName' => 'Password', 'type' => 'password', 'validators' => [ 'required' => 'required', ] ], 'hostname' => [ 'friendlyName' => 'Hostname', 'validators' => [ 'required' => 'required', ] ], 'ssl' => [ 'friendlyName' => 'SSL', 'type' => 'yesno', 'validators' => [ 'required' => 'required', ] ], 'port' => [ 'friendlyName' => 'Port', 'type' => 'number', 'value' => '8053', 'validators' => [ 'required' => 'required', ] ], 'httpauth' => array( 'friendlyName' => 'HTTP Auth Type', 'type' => 'select', 'options' => array(CURLAUTH_BASIC => 'BASIC', CURLAUTH_DIGEST => 'DIGEST'), ), 'ttl' => [ 'friendlyName' => 'TTL', 'type' => 'number', 'value' => '360', 'validators' => [ 'min' => 1, 'required' => 'required', ] ], ]; private $primaryDNS = ''; private $defaultTTL = ''; public $availableTypes = [ 'A', 'AAAA', 'NS', 'MX', 'CNAME', 'TXT', 'SRV', 'PTR', 'DNSKEY' ]; /** * @var \MGModule\DNSManager2\mgLibs\custom\dns\submodules\SimpleDNSV8\Api */ private $api; public function loadApiInstance() { if (!$this->api) { $params = [ 'login' => $this->config['username'], 'password' => $this->config['password'], 'hostname' => $this->config['hostname'], 'port' => $this->config['port'], 'ssl' => $this->config['ssl'], 'httpauth' => $this->config['httpauth'] ]; $curl = new SimpleDNSV8\Curl($params); $this->api = new SimpleDNSV8\Api($curl); return $this->api; } return $this->api; } public function testConnection() { try { $this->loadApiInstance(); $this->api->getZone('mgdomain.com'); } catch (\Exception $ex) { if (strpos(strtolower($ex->getMessage()), 'not found') !== false || strpos(strtoupper($ex->getMessage()), 'IN SOA') !== false) { return true; } if (strlen($ex->getMessage()) === 0) { throw new exceptions\DNSSubmoduleException('Error: Invalid login details', dns\SubmoduleExceptionCodes::INVALID_PARAMETERS); } throw new exceptions\DNSSubmoduleException('Error: ' . $ex->getMessage(), dns\SubmoduleExceptionCodes::CONNECTION_PROBLEM); } return true; } public function getZones() { $this->loadApiInstance(); $zones = $this->api->getZones(); $out = []; foreach ($zones as $zone) { $out[trim($zone->Name)] = ''; } return $out; } public function zoneExists() { try { $this->loadApiInstance(); $zones = $this->api->getZones(); foreach ($zones as $zone) { if (trim(strtolower($zone->Name)) == strtolower($this->domain)) { return true; } } return false; } catch (\Exception $e) { if ($e->getCode() == dns\SubmoduleExceptionCodes::COMMAND_ERROR) { return false; } throw new exceptions\DNSSubmoduleException($e->getMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR); } } public function getRecords($recordType = false) { $availableRecords = $recordType !== false ? array(strtoupper($recordType)) : $this->getAvailableRecordTypes(); try { $this->loadApiInstance(); $response = $this->api->getZoneRecords($this->domain); $records = []; foreach ($response as $line => $each) { if(!in_array(strtoupper($each->Type), $availableRecords)) { continue; } $record = new dns\record\Record(); $record->name = $each->Name; $record->ttl = empty($each->TTL) ? $this->defaultTTL : $each->TTL; $record->type = $each->Type; $record->line = $line; $record->createRDATAObject(); $record->rdata->fromString(trim($each->Data)); $record->customData = $each->Comment; $this->deleteDot($record); $records[] = $record; } return $records; } catch (\Exception $ex) { throw new exceptions\DNSSubmoduleException($ex->getMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR); } } public function addRecord(dns\record\Record $record) { try { $this->loadApiInstance(); $this->api->addRecord($this->domain, $this->recordToParamsArray($record)); } catch (\Exception $ex) { throw new exceptions\DNSSubmoduleException($ex->getMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR); } } public function editRecord(dns\record\Record $record) { try { $recordsList = $this->getRecords(); foreach ($recordsList as $rec) { if ($record->line == $rec->line) { $this->deleteRecord($rec); $this->addRecord($record); break; } } } catch (\Exception $ex) { throw new exceptions\DNSSubmoduleException($ex->getMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR); } } public function deleteRecord(dns\record\Record $record) { try { $this->loadApiInstance(); if (substr($record->name, -1) == '.') { $record->name = substr($record->name, 0, -1); } $this->addDot($record); $data = [ 'Name' => $record->name, 'Type' => $record->type, 'Data' => $record->rdata->toString() ]; $this->api->removeRecord($this->domain, $data); } catch (\Exception $ex) { throw new exceptions\DNSSubmoduleException($ex->getMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR); } } public function activateZone() { $this->loadApiInstance(); $data = [ 'Type' => "Primary", 'DefaultTTL' => (int)$this->config['ttl'], ]; $this->api->createZone($this->domain, $data); if (!$this->zoneExists()) { throw new exceptions\DNSSubmoduleException('Cannot create zone', dns\SubmoduleExceptionCodes::COMMAND_ERROR); } } public function terminateZone() { $this->loadApiInstance(); $this->api->deleteZone($this->domain); if ($this->zoneExists()) { throw new exceptions\DNSSubmoduleException('Cannot terminate zone', dns\SubmoduleExceptionCodes::COMMAND_ERROR); } } private function addDot(dns\record\Record &$record) { if ($record->type == 'CNAME' && $record->rdata->toString() == '@') { return; } if ($record->type == 'SRV' || $record->type == 'MX' || $record->type == 'NS' || $record->type == 'CNAME' || $record->type == 'PTR') { $str = $record->rdata->toString(); $str = rtrim($str, '.') . '.'; $record->rdata->fromString($str); } } private function deleteDot(dns\record\Record &$record) { if ($record->type == 'SRV' || $record->type == 'MX' || $record->type == 'NS' || $record->type == 'CNAME' || $record->type == 'PTR') { $string = rtrim($record->rdata->toString(), '.'); $record->rdata->fromString($string); } } private function recordToParamsArray(dns\record\Record $record) { $relativeName = $record->nameToRelative($this->domain); $this->addDot($record); if (!$relativeName || $relativeName == '@') { $relativeName = $this->domain; } else if (strpos($relativeName, $this->domain) === false) { if (substr($relativeName, -1) !== '.') { $relativeName .= '.' . $this->domain; } else { $relativeName .= $this->domain; } } return [ 'Name' => $relativeName, 'Type' => $record->type, 'TTL' => (int)$record->ttl, 'Data' => $record->rdata->toString(), ]; } public function getSignKeys() { $this->loadApiInstance(); $result = $this->api->getDNSSecKeys($this->domain); $dnssec = new \MGModule\DNSManager2\mgLibs\custom\dns\dnssec\DnsSec(); $dnsKeys = $this->getRecords('DNSKEY'); $dnsKeys = $this->convertToIdAsKey($dnsKeys); foreach ($result as $DNSSECkey) { $class = SELF::KEY_NAMESPACE . $DNSSECkey->Type; if (!class_exists($class)) { continue; } $key = new $class(); $key->setId($DNSSECkey->ID); $key->setStarted($DNSSECkey->Created); $key->setBits($DNSSECkey->KeySize); $key->setDnsKey($dnsKeys[$DNSSECkey->ID]); $dnssec->addKey($key); } return $dnssec; } public function convertToIdAsKey($dnsKeys) { $out = []; foreach ($dnsKeys as $dnsKey) { $id = $this->findKeyId($dnsKey->customData); if(!$id) { continue; } $out[$id] = $dnsKey->rdata; } return $out; } public function findKeyId($string) { $result = explode('/', $string); foreach ($result as $piece) { if(stripos('Key:', $piece)) { continue; } return preg_replace('/[^0-9]/', '', $piece); } return false; } public function sign() { $this->loadApiInstance(); $data = [ 'Type' => (new dns\dnssec\ZSK())->getType(), 'Algorithm' => dns\dnssec\Algorithms::getAlgorithm(15), 'KeySize' => 2048, ]; $this->api->createOrUpdateDNSSECkey($this->domain, SELF::ZSKID, $data); $data['Type'] = (new dns\dnssec\KSK())->getType(); $this->api->createOrUpdateDNSSECkey($this->domain, SELF::KSKID, $data); $this->api->dnsSecSign($this->domain, 365); } public function unsign() { $this->loadApiInstance(); $this->api->deleteDNSSECkey($this->domain, SELF::ZSKID); $this->api->deleteDNSSECkey($this->domain, SELF::KSKID); } public function rectify() { $this->loadApiInstance(); $this->unsign(); $this->sign(); } public function isSigned() { $this->loadApiInstance(); $result = $this->api->getDNSSecKeys($this->domain); if (empty($result)) { return false; } return true; } }