diff --git a/epp.php b/epp.php new file mode 100644 index 0000000..505ca6d --- /dev/null +++ b/epp.php @@ -0,0 +1,1355 @@ +config['username'] = $options['username']; + } + if(isset($options['password'])) { + $this->config['password'] = $options['password']; + } + if(isset($options['host'])) { + $this->config['host'] = $options['host']; + } + if(isset($options['port'])) { + $this->config['port'] = $options['port']; + } + if(isset($options['registrarprefix'])) { + $this->config['registrarprefix'] = $options['registrarprefix']; + } + } + + public function getTlds() + { + return array(); + } + + public static function getConfig() + { + return array( + 'label' => 'An EPP registry module allows registrars to manage and register domain names using the Extensible Provisioning Protocol (EPP). All details below are typically provided by the domain registry and are used to authenticate your account when connecting to the EPP server.', + 'form' => array( + 'username' => array('text', array( + 'label' => 'EPP Server Username', + 'required' => true, + ), + ), + 'password' => array('password', array( + 'label' => 'EPP Server Password', + 'required' => true, + ), + ), + 'host' => array('text', array( + 'label' => 'EPP Server Host', + 'required' => true, + ), + ), + 'port' => array('text', array( + 'label' => 'EPP Server Port', + 'required' => true, + ), + ), + 'registrarprefix' => array('text', array( + 'label' => 'Registrar Prefix', + 'required' => true, + ), + ), + ), + ); + } + + public function isDomaincanBeTransferred(Registrar_Domain $domain) + { + $this->getLog()->debug('Checking if domain can be transferred: ' . $domain->getName()); + return true; + } + + public function isDomainAvailable(Registrar_Domain $domain) + { + $this->getLog()->debug('Checking domain availability: ' . $domain->getName()); + $s = $this->connect(); + $this->login(); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1) , 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-check-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + {{ clTRID }} + + '); + + $r = $this->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->chkData; + $reason = (string)$r->cd[0]->reason; + + if ($reason) + { + return false; + } else { + return true; + } + if (!empty($s)) + { + $this->logout(); + } + + return true; + } + + public function modifyNs(Registrar_Domain $domain) + { + $this->getLog()->debug('Modifying nameservers: ' . $domain->getName()); + $this->getLog()->debug('Ns1: ' . $domain->getNs1()); + $this->getLog()->debug('Ns2: ' . $domain->getNs2()); + $this->getLog()->debug('Ns3: ' . $domain->getNs3()); + $this->getLog()->debug('Ns4: ' . $domain->getNs4()); + $return = array(); + try { + $s = $this->connect(); + $this->login(); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData; + $add = $rem = array(); + $i = 0; + foreach($r->ns->hostObj as $ns) { + $i++; + $ns = (string)$ns; + if (!$ns) { + continue; + } + + $rem["ns{$i}"] = $ns; + } + + foreach (range(1, 4) as $i) { + $k = "getNs$i"; + $v = $domain->{$k}(); + if (!$v) { + continue; + } + + if ($k0 = array_search($v, $rem)) { + unset($rem[$k0]); + } else { + $add["ns$i"] = $v; + } + } + + if (!empty($add) || !empty($rem)) { + $from = $to = array(); + $text = ''; + foreach($add as $k => $v) { + $text.= '' . $v . '' . "\n"; + } + + $from[] = '/{{ add }}/'; + $to[] = (empty($text) ? '' : "\n{$text}\n"); + $text = ''; + foreach($rem as $k => $v) { + $text.= '' . $v . '' . "\n"; + } + + $from[] = '/{{ rem }}/'; + $to[] = (empty($text) ? '' : "\n{$text}\n"); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-update-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + {{ add }} + {{ rem }} + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + } + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $this->logout(); + } + + return $return; + } + + public function transferDomain(Registrar_Domain $domain) + { + $this->getLog()->debug('Transfering domain: ' . $domain->getName()); + $this->getLog()->debug('Epp code: ' . $domain->getEpp()); + $return = array(); + try { + $s = $this->connect(); + $this->login(); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ authInfo_pw }}/'; + $to[] = htmlspecialchars($domain->getEpp()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-transfer-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + 1 + + {{ authInfo_pw }} + + + + {{ clTRID }} + +'); + $r = $this->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->trnData; + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $this->logout(); + } + + return $return; + } + + public function getDomainDetails(Registrar_Domain $domain) + { + $this->getLog()->debug('Getting whois: ' . $domain->getName()); + + if(!$domain->getRegistrationTime()) { + $domain->setRegistrationTime(time()); + } + if(!$domain->getExpirationTime()) { + $years = $domain->getRegistrationPeriod(); + $domain->setExpirationTime(strtotime("+$years year")); + } + return $domain; + } + + public function deleteDomain(Registrar_Domain $domain) + { + $this->getLog()->debug('Removing domain: ' . $domain->getName()); + $return = array(); + try { + $s = $this->connect(); + $this->login(); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-delete-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + {{ clTRID }} + +'); + $r = $this->write($xml, __FUNCTION__); + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $this->logout(); + } + + return $return; + } + + public function registerDomain(Registrar_Domain $domain) + { + $this->getLog()->debug('Registering domain: ' . $domain->getName(). ' for '.$domain->getRegistrationPeriod(). ' years'); + $client = $domain->getContactRegistrar(); + + $return = array(); + try { + $s = $this->connect(); + $this->login(); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-check-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->chkData; + $reason = (string)$r->cd[0]->reason; + if (!$reason) { + $reason = 'Domain is not available'; + } + + if (0 == (int)$r->cd[0]->name->attributes()->avail) { + throw new exception($r->cd[0]->name . ' ' . $reason); + } + + // contact:create + $from = $to = array(); + $from[] = '/{{ id }}/'; + $c_id = strtoupper($this->generateRandomString()); + $to[] = $c_id; + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($client->getFirstName() . ' ' . $client->getLastName()); + $from[] = '/{{ org }}/'; + $to[] = htmlspecialchars($client->getCompany()); + $from[] = '/{{ street1 }}/'; + $to[] = htmlspecialchars($client->getAddress1()); + $from[] = '/{{ city }}/'; + $to[] = htmlspecialchars($client->getCity()); + $from[] = '/{{ state }}/'; + $to[] = htmlspecialchars($client->getState()); + $from[] = '/{{ postcode }}/'; + $to[] = htmlspecialchars($client->getZip()); + $from[] = '/{{ country }}/'; + $to[] = htmlspecialchars($client->getCountry()); + $from[] = '/{{ phonenumber }}/'; + $to[] = htmlspecialchars('+'.$client->getTelCc().'.'.$client->getTel()); + $from[] = '/{{ email }}/'; + $to[] = htmlspecialchars($client->getEmail()); + $from[] = '/{{ authInfo }}/'; + $to[] = htmlspecialchars($this->generateObjectPW()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-contact-create-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ id }} + + {{ name }} + {{ org }} + + {{ street1 }} + + + {{ city }} + {{ state }} + {{ postcode }} + {{ country }} + + + {{ phonenumber }} + + {{ email }} + + {{ authInfo }} + + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:contact-1.0')->creData; + $contacts = $r->id; + + //host create + foreach (['ns1', 'ns2', 'ns3', 'ns4'] as $ns) { + if ($domain->{'get' . ucfirst($ns)}()) { + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = $domain->{'get' . ucfirst($ns)}(); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-host-check-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:host-1.0')->chkData; + + if (0 == (int)$r->cd[0]->name->attributes()->avail) { + continue; + } + + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = $domain->{'get' . ucfirst($ns)}(); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-host-create-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + 5.6.7.8 + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + } + } + + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ period }}/'; + $to[] = htmlspecialchars($domain->getRegistrationPeriod()); + if($domain->getNs1()) { + $from[] = '/{{ ns1 }}/'; + $to[] = htmlspecialchars($domain->getNs1()); + } else { + $from[] = '/{{ ns1 }}/'; + $to[] = ''; + } + if($domain->getNs2()) { + $from[] = '/{{ ns2 }}/'; + $to[] = htmlspecialchars($domain->getNs2()); + } else { + $from[] = '/{{ ns2 }}/'; + $to[] = ''; + } + if($domain->getNs3()) { + $from[] = '/{{ ns3 }}/'; + $to[] = htmlspecialchars($domain->getNs3()); + } else { + $from[] = '/{{ ns3 }}/'; + $to[] = ''; + } + if($domain->getNs4()) { + $from[] = '/{{ ns4 }}/'; + $to[] = htmlspecialchars($domain->getNs4()); + } else { + $from[] = '/{{ ns4 }}/'; + $to[] = ''; + } + $from[] = '/{{ cID_1 }}/'; + $to[] = htmlspecialchars($contacts); + $from[] = '/{{ cID_2 }}/'; + $to[] = htmlspecialchars($contacts); + $from[] = '/{{ cID_3 }}/'; + $to[] = htmlspecialchars($contacts); + $from[] = '/{{ cID_4 }}/'; + $to[] = htmlspecialchars($contacts); + $from[] = '/{{ authInfo }}/'; + $to[] = htmlspecialchars($this->generateObjectPW()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-create-' . $clTRID); + $from[] = "/<\w+:\w+>\s*<\/\w+:\w+>\s+/ims"; + $to[] = ''; + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + {{ period }} + + {{ ns1 }} + {{ ns2 }} + {{ ns3 }} + {{ ns4 }} + + {{ cID_1 }} + {{ cID_2 }} + {{ cID_3 }} + {{ cID_4 }} + + {{ authInfo }} + + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $this->logout(); + } + + return $return; + } + + public function renewDomain(Registrar_Domain $domain) + { + $this->getLog()->debug('Renewing domain: ' . $domain->getName()); + $return = array(); + try { + $s = $this->connect(); + $this->login(); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData; + $expDate = (string)$r->exDate; + $expDate = preg_replace("/^(\d+\-\d+\-\d+)\D.*$/", "$1", $expDate); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ expDate }}/'; + $to[] = htmlspecialchars($expDate); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-renew-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + {{ expDate }} + 1 + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $this->logout(); + } + + return $return; + } + + public function modifyContact(Registrar_Domain $domain) + { + $this->getLog()->debug('Updating contact info: ' . $domain->getName()); + $client = $domain->getContactRegistrar(); + $return = array(); + try { + $s = $this->connect(); + $this->login(); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData; + $registrant = (string)$r->registrant; + $from = $to = array(); + $from[] = '/{{ id }}/'; + $to[] = $registrant; + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($client->getFirstName() . ' ' . $client->getLastName()); + $from[] = '/{{ org }}/'; + $to[] = htmlspecialchars($client->getCompany()); + $from[] = '/{{ street1 }}/'; + $to[] = htmlspecialchars($client->getAddress1()); + $from[] = '/{{ street2 }}/'; + $to[] = htmlspecialchars($client->getAddress2()); + $from[] = '/{{ city }}/'; + $to[] = htmlspecialchars($client->getCity()); + $from[] = '/{{ state }}/'; + $to[] = htmlspecialchars($client->getState()); + $from[] = '/{{ postcode }}/'; + $to[] = htmlspecialchars($client->getZip()); + $from[] = '/{{ country }}/'; + $to[] = htmlspecialchars($client->getCountry()); + $from[] = '/{{ phonenumber }}/'; + $to[] = htmlspecialchars('+'.$client->getTelCc().'.'.$client->getTel()); + $from[] = '/{{ email }}/'; + $to[] = htmlspecialchars($client->getEmail()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-contact-update-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ id }} + + + {{ name }} + {{ org }} + + {{ street1 }} + {{ street2 }} + + {{ city }} + {{ state }} + {{ postcode }} + {{ country }} + + + {{ phonenumber }} + + + + + {{ clTRID }} + +'); + $r = $this->write($xml, __FUNCTION__); + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $this->logout(); + } + + return $return; + } + + public function enablePrivacyProtection(Registrar_Domain $domain) + { + $this->getLog()->debug('Enabling Privacy protection: ' . $domain->getName()); + $return = array(); + try { + $s = $this->connect(); + $this->login(); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData; + $dcontact = array(); + $dcontact['registrant'] = (string)$r->registrant; + foreach($r->contact as $e) { + $type = (string)$e->attributes()->type; + $dcontact[$type] = (string)$e; + } + + $contact = array(); + foreach($dcontact as $id) { + if (isset($contact[$id])) { + continue; + } + $from = $to = array(); + $from[] = '/{{ id }}/'; + $to[] = htmlspecialchars($id); + $from[] = '/{{ flag }}/'; + $to[] = 1; + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1) , 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-contact-update-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ id }} + + + + + + + + + + + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + } + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $this->logout(); + } + + return $return; + } + + public function disablePrivacyProtection(Registrar_Domain $domain) + { + $this->getLog()->debug('Disabling Privacy protection: ' . $domain->getName()); + $return = array(); + try { + $s = $this->connect(); + $this->login(); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData; + $dcontact = array(); + $dcontact['registrant'] = (string)$r->registrant; + foreach($r->contact as $e) { + $type = (string)$e->attributes()->type; + $dcontact[$type] = (string)$e; + } + + $contact = array(); + foreach($dcontact as $id) { + if (isset($contact[$id])) { + continue; + } + $from = $to = array(); + $from[] = '/{{ id }}/'; + $to[] = htmlspecialchars($id); + $from[] = '/{{ flag }}/'; + $to[] = 0; + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1) , 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-contact-update-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ id }} + + + + + + + + + + + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + } + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $this->logout(); + } + + return $return; + } + + public function getEpp(Registrar_Domain $domain) + { + $this->getLog()->debug('Retrieving domain transfer code: ' . $domain->getName()); + $return = array(); + try { + $s = $this->connect(); + $this->login(); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData; + $eppcode = (string)$r->authInfo->pw; + + if (!empty($s)) { + $this->logout(); + } + return $eppcode; + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $this->logout(); + } + + return $return; + } + + public function lock(Registrar_Domain $domain) + { + $this->getLog()->debug('Locking domain: ' . $domain->getName()); + $return = array(); + try { + $s = $this->connect(); + $this->login(); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData; + $status = array(); + foreach($r->status as $e) { + $st = (string)$e->attributes()->s; + if (!preg_match("/^client.+Prohibited$/i", $st)) { + continue; + } + + $status[$st] = true; + } + + $add = array(); + foreach(array( + 'clientUpdateProhibited', + 'clientDeleteProhibited', + 'clientTransferProhibited' + ) as $st) { + if (!isset($status[$st])) { + $add[] = $st; + } + } + + if (!empty($add)) { + $text = ''; + foreach($add as $st) { + $text.= '' . "\n"; + } + $from[] = '/{{ add }}/'; + $to[] = (empty($text) ? '' : "\n{$text}\n"); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-update-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + {{ add }} + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + } + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $this->logout(); + } + + return $return; + } + + public function unlock(Registrar_Domain $domain) + { + $this->getLog()->debug('Unlocking: ' . $domain->getName()); + $return = array(); + try { + $s = $this->connect(); + $this->login(); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData; + $status = array(); + foreach($r->status as $e) { + $st = (string)$e->attributes()->s; + if (!preg_match("/^client.+Prohibited$/i", $st)) { + continue; + } + + $status[$st] = true; + } + + $rem = array(); + foreach(array( + 'clientUpdateProhibited', + 'clientDeleteProhibited', + 'clientTransferProhibited' + ) as $st) { + if (isset($status[$st])) { + $rem[] = $st; + } + } + + if (!empty($rem)) { + $text = ''; + foreach($rem as $st) { + $text.= '' . "\n"; + } + $from[] = '/{{ rem }}/'; + $to[] = (empty($text) ? '' : "\n{$text}\n"); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($domain->getName()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-domain-update-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + {{ rem }} + + + {{ clTRID }} + + '); + $r = $this->write($xml, __FUNCTION__); + } + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $this->logout(); + } + + return $return; + } + + public function connect() + { + $host = $this->config['host']; + $port = $this->config['port']; + + $opts = array( + 'ssl' => array( + 'verify_peer' => false, + 'verify_peer_name' => false, + 'verify_host' => false, + 'allow_self_signed' => true, + 'local_cert' => 'cert.pem', + 'local_pk' => 'key.pem' + ) + ); + $context = stream_context_create($opts); + $this->socket = stream_socket_client("tlsv1.3://{$host}:{$port}", $errno, $errmsg, $timeout, STREAM_CLIENT_CONNECT, $context); + + if (!$this->socket) { + throw new exception("Cannot connect to server '{$host}': {$errmsg}"); + } + + return $this->read(); + } + + public function login() + { + $from = $to = array(); + $from[] = '/{{ clID }}/'; + $to[] = htmlspecialchars($this->config['username']); + $from[] = '/{{ pw }}/'; + $to[] = $this->config['password']; + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-login-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + {{ clID }} + + + 1.0 + en + + + urn:ietf:params:xml:ns:domain-1.0 + urn:ietf:params:xml:ns:contact-1.0 + urn:ietf:params:xml:ns:host-1.0 + + urn:ietf:params:xml:ns:secDNS-1.1 + + + + {{ clTRID }} + +'); + $r = $this->write($xml, __FUNCTION__); + $this->isLogined = true; + return true; + } + + public function logout() + { + if (!$this->isLogined) { + return true; + } + + $from = $to = array(); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($this->config['registrarprefix'] . '-logout-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + {{ clTRID }} + +'); + $r = $this->write($xml, __FUNCTION__); + $this->isLogined = false; + return true; + } + + public function read() + { + if (feof($this->socket)) { + throw new exception('Connection appears to have closed.'); + } + + $hdr = @fread($this->socket, 4); + if (empty($hdr)) { + throw new exception('Error reading from server.'); + } + + $unpacked = unpack('N', $hdr); + $xml = fread($this->socket, ($unpacked[1] - 4)); + $xml = preg_replace('/>\n<", $xml); + return $xml; + } + + public function write($xml, $action = 'Unknown') + { + @fwrite($this->socket, pack('N', (strlen($xml) + 4)) . $xml); + $r = $this->read(); + $r = new SimpleXMLElement($r); + if ($r->response->result->attributes()->code >= 2000) { + throw new exception($r->response->result->msg); + } + return $r; + } + + public function disconnect() + { + return @fclose($this->socket); + } + + function generateObjectPW($objType = 'none') + { + $result = ''; + $uppercaseChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + $lowercaseChars = "abcdefghijklmnopqrstuvwxyz"; + $numbers = "1234567890"; + $specialSymbols = "!=+-"; + $minLength = 13; + $maxLength = 13; + $length = mt_rand($minLength, $maxLength); + + // Include at least one character from each set + $result .= $uppercaseChars[mt_rand(0, strlen($uppercaseChars) - 1)]; + $result .= $lowercaseChars[mt_rand(0, strlen($lowercaseChars) - 1)]; + $result .= $numbers[mt_rand(0, strlen($numbers) - 1)]; + $result .= $specialSymbols[mt_rand(0, strlen($specialSymbols) - 1)]; + + // Append random characters to reach the desired length + while (strlen($result) < $length) { + $chars = $uppercaseChars . $lowercaseChars . $numbers . $specialSymbols; + $result .= $chars[mt_rand(0, strlen($chars) - 1)]; + } + + return 'aA1' . $result; + } + + public function generateRandomString() + { + $characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + $randomString = ''; + for ($i = 0; $i < 12; $i++) { + $randomString .= $characters[rand(0, strlen($characters) - 1)]; + } + return $randomString; + } +}