array ( 'friendlyName' => 'Username', 'validators' => array( 'required' => 'required', ) ), 'password' =>array ( 'friendlyName' => 'User Password', 'type'=> 'password', 'validators' => array( 'required' => 'required', ) ), 'customer_name' =>array ( 'friendlyName' => 'Customer Name', ), 'hostname' =>array ( 'friendlyName' => 'Hostname/IP', 'validators' => array( 'required' => 'required', ) ), 'ssl' =>array ( 'friendlyName' => 'Enable SSL', 'type'=> 'yesno', ), 'default_ip' =>array ( 'friendlyName' => 'Default IP', 'validators' => array( 'pattern' => Patterns::IP4_OR_IP6, ) ), 'adminemail' =>array ( 'friendlyName' => 'Admin Email', 'type'=> 'email', 'validators' => array( 'required' => 'required', ) ), 'default_ttl' =>array ( //?? 'friendlyName' => 'Default TTL', 'type' => 'number', 'help' => 'Default TTL (in seconds) for records in the zone', 'validators' => array( 'required' => 'required', ), ), /*'dnssec_contact_nickname' => array( 'friendlyName' => 'DNSSEC Contact Nickname', 'type' => 'text', )*/ ); public $availableTypes = array('A', 'AAAA', 'NS', 'MX', 'CNAME', 'DNAME', 'LOC', 'TXT', 'SRV', 'PTR', 'DS'); private $token; public function getRecords($recordType = false){ $return = $this->execute('GET', 'AllRecord/'.$this->domain); $out = array(); foreach($return['data'] as $url) { $url = substr($url, 6); $type = substr($url, 0, strpos($url, 'Record')); if(!in_array(strtoupper($type), $this->getAvailableRecordTypes())) { continue; } $data = $this->execute('GET', $url); $record = new dns\record\Record(); $record->line = $data['data']['record_id']; $record->name = $data['data']['fqdn']; $record->type = $data['data']['record_type']; $record->ttl = $data['data']['ttl']; $record->createRDATAObject(); $record->rdata->setDataFromArray($data['data']['rdata']); if($type == 'DS') { $record->rdata->digesttype = $data['data']['rdata']['digtype']; } $out[] = $record; } return $out; } private function recordToParamsArray(dns\record\Record $record) { $params = array( 'rdata' => $record->rdata->toArray(false), 'ttl' => $record->ttl, ); return $params; } public function editRecord(dns\record\Record $record) { $params = $this->recordToParamsArray($record); $this->execute('PUT', $record->type.'Record/'.$this->domain.'/'.$record->nameToAbsolute($this->domain, false) . '/' . $record->line, $params); $this->publishZone(); } public function deleteRecord(dns\record\Record $record) { $ret = $this->execute('DELETE', $record->type.'Record/'.$this->domain.'/'.$record->nameToAbsolute($this->domain, false) . '/' . $record->line); $this->publishZone(); } public function addRecord(dns\record\Record $record) { $params = $this->recordToParamsArray($record); $this->execute('POST', $record->type.'Record/'.$this->domain.'/'.$record->nameToAbsolute($this->domain, false), $params); $this->publishZone(); } public function zoneExists() { try { $this->execute('GET', 'Zone/' . $this->domain); } catch (exceptions\DNSSubmoduleException $e) { if($e->getCode() == dns\SubmoduleExceptionCodes::COMMAND_ERROR) { return false; } throw $e; } return true; } public function terminateZone() { $this->execute('DELETE','Zone/'.$this->domain); } public function activateZone() { $params = array( 'ttl' => $this->config['default_ttl'], 'rname' => $this->config['adminemail'], 'serial_style' => 'epoch' ); if(!$this->zoneExists()) { $this->execute('POST','Zone/'.$this->domain, $params); } $this->execute('PUT','Zone/'.$this->domain, array('publish' => 'true')); } protected function publishZone(){ $this->execute('PUT','Zone/'.$this->domain, array( 'publish' => 1 )); } private function execute($method, $function, $params = array()){ if(empty($this->token) && $function != 'Session') { $this->login(); } $header = array(); $header[] = 'Content-Type: application/json'; if ($function != 'Session'){ $header[] = 'Auth-Token: '. $this->token; } $url = self::URL . $function . '/'; if (!empty($params) && strtoupper($method) == 'GET') { $params = $this->getParams($params); $url .= '?'.$params; } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($method)); if (!empty($params)) { curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params)); } curl_setopt($ch, CURLOPT_TIMEOUT, 20); $curl_result = curl_exec($ch); //$this->http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if (curl_errno($ch)) { throw new exceptions\DNSSubmoduleException("cURL Error: " . curl_errno($ch) . " - " . curl_error($ch), dns\SubmoduleExceptionCodes::CONNECTION_PROBLEM); } curl_close($ch); $json = json_decode($curl_result, true); if(empty($json)) { throw new exceptions\DNSSubmoduleException('Unable to parse response', dns\SubmoduleExceptionCodes::INVALID_RESPONSE); } if($json['status'] != 'success') { if(!empty($json['msgs'])) { $errors = array(); foreach($json['msgs'] as $message) { $errors[] = $message['INFO']; } throw new exceptions\DNSSubmoduleException(implode('; ', $errors), dns\SubmoduleExceptionCodes::COMMAND_ERROR); } throw new exceptions\DNSSubmoduleException('Unknown Error', dns\SubmoduleExceptionCodes::COMMAND_ERROR); } return $json; } private function getParams($params){ $string = ''; foreach ($params as $key => $value){ $string .= $key.'='.$value.'&'; } $string = substr($string, 0, -1); //erase last & return $string; } private function login(){ $result = $this->execute('POST', 'Session', array( 'customer_name' => $this->config['customer_name'], 'user_name' => $this->config['username'], 'password' => $this->config['password'] ) ); $this->token = trim($result['data']['token']); } public function testConnection() { $this->login(); } public function getZones() { $result = $this->execute('GET', 'Zone' . $this->domain); $out = array(); foreach($result as $zone) { $out[$zone->zone] = ''; } return $out; } /** * * @return boolean */ public function isSigned() { return $this->getSignKeys() ? true : false; } public function generateSignKeys() { } /** * * @return Array of \MGModule\DNSManager2\mgLibs\custom\dns\submodules\dnssec\Key */ public function getSignKeys() { try { $ret = $this->execute('GET', 'DNSSEC/'.$this->domain); $dnssec = new dns\dnssec\DnsSec(); foreach($ret['data']['keys'] as $k) { $key = null; if($k['type'] == 'ZSK') { $key = new dns\dnssec\ZSK(); } else { $key = new dns\dnssec\KSK(); } $key->setId($k['dnssec_key_id']); $key->setExpires($k['expire_ts']); $key->setLifetime($k['lifetime']); $key->setBits($k['bits']); //DNSKEY $dnskey = new dns\record\type\DNSKEY(); $dnskey->setProtocol($k['dnskey']['protocol']); $dnskey->setFlags($k['dnskey']['flags']); $dnskey->setAlgorithm($k['dnskey']['algorithm']); $dnskey->setPublicKey($k['dnskey']['public_key']); $key->setDnsKey($dnskey); //DS if($k['ds']['keytag']) { $ds = new dns\record\type\DS(); $ds->setAlgorithm($k['ds']['algorithm']); $ds->setKeytag($k['ds']['keytag']); $ds->setDigestType($k['ds']['digtype']); $ds->setDigest($k['ds']['digest']); $key->setDs($ds); } $dnssec->addKey($key); } return $dnssec; } catch(exceptions\DNSSubmoduleException $ex) { if(strpos($ex->getMessage(), 'No such service in your account')) { return null; } throw $ex; } } public function sign() { $this->execute('POST', 'DNSSEC/'.$this->domain, array( 'keys' => array ( array ( 'type' => 'KSK', 'algorithm' => 'RSA/SHA-1', 'bits' => 2048, 'start_ts' => time(), 'lifetime' => 60*60*24*356, 'overlap' => 60*60*24*7, // use default value //'expire_ts' => '' ), array ( 'type' => 'ZSK', 'algorithm' => 'RSA/SHA-1', 'bits' => 2048, 'start_ts' => time(), 'lifetime' => 60*60*24*356, 'overlap' => 60*60*24*7, // use default value //'expire_ts' => '' ) ), 'contact_nickname' => $this->config['dnssec_contact_nickname'] )); } public function unsign() { $this->execute('DELETE', 'DNSSEC/'.$this->domain); } }