diff --git a/README.md b/README.md index 9d0d5eb..75804c7 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,17 @@ -# registrar-whmcs-epp-verisign -VeriSign EPP Module for Namingo Registrar +# VeriSign EPP Module for Namingo Registrar Platform + +This is an **EPP Registrar Module** specifically designed for the Namingo Registrar platform’s WHMCS edition. + +> ⚠️ **Note**: This module is exclusive to the Namingo Registrar platform’s WHMCS edition and is not compatible with standard WHMCS installations. + +## Compatibility + +This module supports **all gTLDs** that use the VeriSign platform. + +> **Note**: For Generic EPP support, please use our standard [Registrar-WHMCS-EPP-RFC module](https://github.com/getnamingo/registrar-whmcs-epp-rfc) for full compatibility. + +> **Note**: For ccTLD support, please use our standard [WHMCS-EPP-RFC module](https://github.com/getpinga/whmcs-epp-rfc) for full compatibility. + +## Installation instructions + +This module is exclusively for use as part of the **Namingo Registrar Platform (WHMCS Edition)**. For complete installation instructions, please visit the [Installation Guide](https://namingo.org/registrar). \ No newline at end of file diff --git a/logo.gif b/logo.gif new file mode 100644 index 0000000..1392b75 Binary files /dev/null and b/logo.gif differ diff --git a/manageDNSSECDSRecords.tpl b/manageDNSSECDSRecords.tpl new file mode 100644 index 0000000..95f66f4 --- /dev/null +++ b/manageDNSSECDSRecords.tpl @@ -0,0 +1,124 @@ +
+
+

Manage DNSSEC DS Records

+ +{if $error} +
+ {$error} +
+{else} + {if $DSRecords eq 'YES'} + {foreach $DSRecordslist as $item} +
+ + + + + + +

DS records:

+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+ +
+ +
+ {/foreach} + {else} +
+ {$DSRecords} +
+ {/if} +{/if} +
+
+ +
+
+
+ + + + + + +

Create a DS Record

+ +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+ +
+ +
+
+
\ No newline at end of file diff --git a/verisign.php b/verisign.php new file mode 100644 index 0000000..da67c1d --- /dev/null +++ b/verisign.php @@ -0,0 +1,2509 @@ + 'EPP Registry', + 'APIVersion' => '1.1', + ); +} + +function _verisign_error_handler($errno, $errstr, $errfile, $errline) +{ + if (!preg_match("/epp/i", $errfile)) { + return true; + } + + _verisign_log("Error $errno:", "$errstr on line $errline in file $errfile"); +} + +set_error_handler('_verisign_error_handler'); +_verisign_log('================= ' . date("Y-m-d H:i:s") . ' ================='); + +function verisign_getConfigArray($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + + $configarray = array( + 'FriendlyName' => array( + 'Type' => 'System', + 'Value' => 'VeriSign EPP', + ), + 'Description' => array( + 'Type' => 'System', + 'Value' => 'This module supports all gTLDs that use the VeriSign platform.', + ), + 'host' => array( + 'FriendlyName' => 'EPP Server', + 'Type' => 'text', + 'Size' => '32', + 'Description' => 'EPP Server Host.' + ), + 'port' => array( + 'FriendlyName' => 'Server Port', + 'Type' => 'text', + 'Size' => '4', + 'Default' => '700', + 'Description' => 'System port number 700 has been assigned by the IANA for mapping EPP onto TCP.' + ), + 'tls_version' => array( + 'FriendlyName' => 'Use TLS v1.3', + 'Type' => 'yesno', + 'Description' => 'Use more secure TLS v1.3 if the registry supports it.' + ), + 'verify_peer' => array( + 'FriendlyName' => 'Verify Peer', + 'Type' => 'yesno', + 'Description' => 'Require verification of SSL certificate used.' + ), + 'cafile' => array( + 'FriendlyName' => 'CA File', + 'Type' => 'text', + 'Default' => '', + 'Description' => 'Certificate Authority file which should be used with the verify_peer context option
to authenticate the identity of the remote peer.' + ), + 'local_cert' => array( + 'FriendlyName' => 'Certificate', + 'Type' => 'text', + 'Default' => 'cert.pem', + 'Description' => 'Local certificate file. It must be a PEM encoded file.' + ), + 'local_pk' => array( + 'FriendlyName' => 'Private Key', + 'Type' => 'text', + 'Default' => 'key.pem', + 'Description' => 'Private Key.' + ), + 'passphrase' => array( + 'FriendlyName' => 'Pass Phrase', + 'Type' => 'password', + 'Size' => '32', + 'Description' => 'Enter pass phrase with which your certificate file was encoded.' + ), + 'clid' => array( + 'FriendlyName' => 'Client ID', + 'Type' => 'text', + 'Size' => '20', + 'Description' => 'Client identifier.' + ), + 'pw' => array( + 'FriendlyName' => 'Password', + 'Type' => 'password', + 'Size' => '20', + 'Description' => "Client's plain text password." + ), + 'registrarprefix' => array( + 'FriendlyName' => 'Registrar Prefix', + 'Type' => 'text', + 'Size' => '4', + 'Description' => 'Registry assigns each registrar a unique prefix with which that registrar must create contact IDs.' + ) + ); + return $configarray; +} + +function _verisign_startEppClient($params = array()) +{ + $s = new verisign_epp_client($params); + $s->login($params['clid'], $params['pw'], $params['registrarprefix']); + return $s; +} + +function verisign_RegisterDomain($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-check-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->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); + } + + $contacts = array(); + foreach(array( + 'registrant', + 'admin', + 'tech', + 'billing' + ) as $i => $contactType) { + // contact:create + $from = $to = array(); + $from[] = '/{{ id }}/'; + $to[] = strtoupper($s->generateRandomString()); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['firstname'] . ' ' . $params['lastname']); + $from[] = '/{{ org }}/'; + $to[] = htmlspecialchars($params['companyname']); + $from[] = '/{{ street1 }}/'; + $to[] = htmlspecialchars($params['address1']); + $from[] = '/{{ street2 }}/'; + $to[] = htmlspecialchars($params['address2']); + $from[] = '/{{ street3 }}/'; + $street3 = (isset($params['address3']) ? $params['address3'] : ''); + $to[] = htmlspecialchars($street3); + $from[] = '/{{ city }}/'; + $to[] = htmlspecialchars($params['city']); + $from[] = '/{{ state }}/'; + $to[] = htmlspecialchars($params['state']); + $from[] = '/{{ postcode }}/'; + $to[] = htmlspecialchars($params['postcode']); + $from[] = '/{{ country }}/'; + $to[] = htmlspecialchars($params['country']); + $from[] = '/{{ phonenumber }}/'; + $to[] = htmlspecialchars($params['fullphonenumber']); + $from[] = '/{{ email }}/'; + $to[] = htmlspecialchars($params['email']); + $from[] = '/{{ authInfo }}/'; + $to[] = htmlspecialchars($s->generateObjectPW()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-contact-create-' . $clTRID); + $from[] = "/<\w+:\w+>\s*<\/\w+:\w+>\s+/ims"; + $to[] = ''; + $xml = preg_replace($from, $to, ' + + + + + {{ id }} + + {{ name }} + {{ org }} + + {{ street1 }} + {{ street2 }} + {{ street3 }} + {{ city }} + {{ state }} + {{ postcode }} + {{ country }} + + + {{ phonenumber }} + + {{ email }} + + {{ authInfo }} + + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:contact-1.0')->creData; + $contacts[$i + 1] = $r->id; + } + + foreach(array( + 'ns1', + 'ns2', + 'ns3', + 'ns4', + 'ns5' + ) as $ns) { + if (empty($params["{$ns}"])) { + continue; + } + + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params["{$ns}"]); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-host-check-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->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[] = htmlspecialchars($params["{$ns}"]); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-host-create-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); +} + + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ period }}/'; + $to[] = htmlspecialchars($params['regperiod']); + $from[] = '/{{ ns1 }}/'; + $to[] = htmlspecialchars($params['ns1']); + $from[] = '/{{ ns2 }}/'; + $to[] = htmlspecialchars($params['ns2']); + $from[] = '/{{ ns3 }}/'; + $to[] = htmlspecialchars($params['ns3']); + $from[] = '/{{ ns4 }}/'; + $to[] = htmlspecialchars($params['ns4']); + $from[] = '/{{ ns5 }}/'; + $to[] = htmlspecialchars($params['ns5']); + $from[] = '/{{ cID_1 }}/'; + $to[] = htmlspecialchars($contacts[1]); + $from[] = '/{{ cID_2 }}/'; + $to[] = htmlspecialchars($contacts[2]); + $from[] = '/{{ cID_3 }}/'; + $to[] = htmlspecialchars($contacts[3]); + $from[] = '/{{ cID_4 }}/'; + $to[] = htmlspecialchars($contacts[4]); + $from[] = '/{{ authInfo }}/'; + $to[] = htmlspecialchars($s->generateObjectPW()); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-create-' . $clTRID); + $from[] = "/<\w+:\w+>\s*<\/\w+:\w+>\s+/ims"; + $to[] = ''; + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + {{ period }} + + {{ ns1 }} + {{ ns2 }} + {{ ns3 }} + {{ ns4 }} + {{ ns5 }} + + {{ cID_1 }} + {{ cID_2 }} + {{ cID_3 }} + {{ cID_4 }} + + {{ authInfo }} + + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + + // Check if the required module 'whmcs_registrar' is active + if (!Capsule::table('tbladdonmodules')->where('module', 'whmcs_registrar')->exists()) { + // Log an error if the module is not active + _verisign_log('Error: Required module is not active.'); + } + + // Insert contacts and get their IDs + $contactIds = insertContacts($params, $contacts); + + // Insert domain + insertDomain($params, $contactIds); + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_RenewDomain($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->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($params['domainname']); + $from[] = '/{{ regperiod }}/'; + $to[] = htmlspecialchars($params['regperiod']); + $from[] = '/{{ expDate }}/'; + $to[] = htmlspecialchars($expDate); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-renew-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + {{ expDate }} + {{ regperiod }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_TransferDomain($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ years }}/'; + $to[] = htmlspecialchars($params['regperiod']); + $from[] = '/{{ authInfo_pw }}/'; + $to[] = htmlspecialchars($params['transfersecret']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-transfer-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + {{ years }} + + {{ authInfo_pw }} + + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->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)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_GetNameservers($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData; + $i = 0; + foreach($r->ns->hostObj as $ns) { + $i++; + $return["ns{$i}"] = (string)$ns; + } + + $namingoDomainId = getNamingoDomainId($params['domainid']); + + $status = array(); + Capsule::table('namingo_domain_status')->where('domain_id', '=', $namingoDomainId)->delete(); + foreach($r->status as $e) { + $st = (string)$e->attributes()->s; + if ($st == 'pendingDelete') { + $updatedDomainStatus = Capsule::table('tbldomains')->where('id', $params['domainid'])->update(['status' => 'Cancelled']); + } + + Capsule::table('namingo_domain_status')->insert(['domain_id' => $namingoDomainId, 'status' => $st]); + } + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_SaveNameservers($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->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($params as $k => $v) { + if (!$v) { + continue; + } + + if (!preg_match("/^ns\d$/i", $k)) { + continue; + } + + if ($k0 = array_search($v, $rem)) { + unset($rem[$k0]); + } + else { + $add[$k] = $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($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-update-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + {{ add }} + {{ rem }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + } + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_GetRegistrarLock($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = 'unlocked'; + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData; + foreach($r->status as $e) { + $attr = $e->attributes(); + if (preg_match("/clientTransferProhibited/i", $attr['s'])) { + $return = 'locked'; + } + } + } + + catch(exception $e) { + $return = 'locked'; + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_SaveRegistrarLock($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->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 = $add = array(); + foreach(array( + 'clientDeleteProhibited', + 'clientTransferProhibited' + ) as $st) { + if ($params["lockenabled"] == 'locked') { + if (!isset($status[$st])) { + $add[] = $st; + } + } + else { + if (isset($status[$st])) { + $rem[] = $st; + } + } + } + + if (!empty($add) || !empty($rem)) { + $text = ''; + foreach($add as $st) { + $text.= '' . "\n"; + } + + $from[] = '/{{ add }}/'; + $to[] = (empty($text) ? '' : "\n{$text}\n"); + $text = ''; + foreach($rem as $st) { + $text.= '' . "\n"; + } + + $from[] = '/{{ rem }}/'; + $to[] = (empty($text) ? '' : "\n{$text}\n"); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-update-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + {{ rem }} + {{ add }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + } + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_GetContactDetails($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->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[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-contact-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ id }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:contact-1.0')->infData[0]; + $contact[$id] = array(); + $c = & $contact[$id]; + foreach($r->postalInfo as $e) { + $c["Name"] = (string)$e->name; + $c["Organization"] = (string)$e->org; + for ($i = 0; $i <= 2; $i++) { + $c["Street " . ($i + 1) ] = (string)$e->addr->street[$i]; + } + + if (empty($c["Street 3"])) { + unset($c["street3"]); + } + + $c["City"] = (string)$e->addr->city; + $c["State or Province"] = (string)$e->addr->sp; + $c["Postal Code"] = (string)$e->addr->pc; + $c["Country Code"] = (string)$e->addr->cc; + break; + } + + $c["Phone"] = (string)$r->voice; + $c["Fax"] = (string)$r->fax; + $c["Email"] = (string)$r->email; + } + + foreach($dcontact as $type => $id) { + if ($type == 'registrant') { + $type = 'Registrant'; + } + elseif ($type == 'admin') { + $type = 'Administrator'; + } + elseif ($type == 'tech') { + $type = 'Technical'; + } + elseif ($type == 'billing') { + $type = 'Billing'; + } + else { + continue; + } + + $return[$type] = $contact[$id]; + } + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_SaveContactDetails($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->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; + } + + foreach($dcontact as $type => $id) { + $a = array(); + if ($type == 'registrant') { + $a = $params['contactdetails']['Registrant']; + } + elseif ($type == 'admin') { + $a = $params['contactdetails']['Administrator']; + } + elseif ($type == 'tech') { + $a = $params['contactdetails']['Technical']; + } + elseif ($type == 'billing') { + $a = $params['contactdetails']['Billing']; + } + + if (empty($a)) { + continue; + } + + $from = $to = array(); + + $from[] = '/{{ id }}/'; + $to[] = htmlspecialchars($id); + + $from[] = '/{{ name }}/'; + $name = ($a['Name'] ? $a['Name'] : $a['Full Name']); + $to[] = htmlspecialchars($name); + + $from[] = '/{{ org }}/'; + $org = ($a['Organization'] ? $a['Organization'] : $a['Organisation Name']); + $to[] = htmlspecialchars($org); + + $from[] = '/{{ street1 }}/'; + $street1 = ($a['Street 1'] ? $a['Street 1'] : $a['Address 1']); + $to[] = htmlspecialchars($street1); + + $from[] = '/{{ street2 }}/'; + $street2 = ($a['Street 2'] ? $a['Street 2'] : $a['Address 2']); + $to[] = htmlspecialchars($street2); + + $from[] = '/{{ street3 }}/'; + $street3 = ($a['Street 3'] ? $a['Street 3'] : $a['Address 3']); + $to[] = htmlspecialchars($street3); + + $from[] = '/{{ city }}/'; + $to[] = htmlspecialchars($a['City']); + + $from[] = '/{{ sp }}/'; + $sp = ($a['State or Province'] ? $a['State or Province'] : $a['State']); + $to[] = htmlspecialchars($sp); + + $from[] = '/{{ pc }}/'; + $pc = ($a['Postal Code'] ? $a['Postal Code'] : $a['Postcode']); + $to[] = htmlspecialchars($pc); + + $from[] = '/{{ cc }}/'; + $cc = ($a['Country Code'] ? $a['Country Code'] : $a['Country']); + $to[] = htmlspecialchars($cc); + + $from[] = '/{{ voice }}/'; + $to[] = htmlspecialchars($a['Phone']); + + $from[] = '/{{ fax }}/'; + $to[] = htmlspecialchars($a['Fax']); + + $from[] = '/{{ email }}/'; + $to[] = htmlspecialchars($a['Email']); + + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-contact-chg-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ id }} + + + {{ name }} + {{ org }} + + {{ street1 }} + {{ street2 }} + {{ street3 }} + {{ city }} + {{ sp }} + {{ pc }} + {{ cc }} + + + {{ voice }} + {{ fax }} + {{ email }} + + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + } + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_IDProtectToggle($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->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[] = ($params['protectenable'] ? 1 : 0); + + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1) , 3)); + $to[] = htmlspecialchars($params['RegistrarPrefix'] . '-contact-update-' . $clTRID); + + $xml = preg_replace($from, $to, ' + + + + + {{ id }} + + + + + + + + + + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + } + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['RegistrarPrefix']); + } + + return $return; +} + +function verisign_GetEPPCode($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData; + $eppcode = (string)$r->authInfo->pw; + + // If EPP Code is returned, return it for display to the end user + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + return array('eppcode' => $eppcode); + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_RegisterNameserver($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['nameserver']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-host-check-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->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) { + throw new exception($r->cd[0]->name . " " . $r->cd[0]->reason); + } + + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['nameserver']); + $from[] = '/{{ ip }}/'; + $to[] = htmlspecialchars($params['ipaddress']); + $from[] = '/{{ v }}/'; + $to[] = (preg_match('/:/', $params['ipaddress']) ? 'v6' : 'v4'); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-host-create-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + {{ ip }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_ModifyNameserver($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['nameserver']); + $from[] = '/{{ ip1 }}/'; + $to[] = htmlspecialchars($params['currentipaddress']); + $from[] = '/{{ v1 }}/'; + $to[] = (preg_match('/:/', $params['currentipaddress']) ? 'v6' : 'v4'); + $from[] = '/{{ ip2 }}/'; + $to[] = htmlspecialchars($params['newipaddress']); + $from[] = '/{{ v2 }}/'; + $to[] = (preg_match('/:/', $params['newipaddress']) ? 'v6' : 'v4'); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-host-update-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + {{ ip2 }} + + + {{ ip1 }} + + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_DeleteNameserver($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['nameserver']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-host-delete-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_RequestDelete($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-delete-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_manageDNSSECDSRecords($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + + if (isset($_POST['command']) && ($_POST['command'] === 'secDNSadd')) { + $keyTag = $_POST['keyTag']; + $alg = $_POST['alg']; + $digestType = $_POST['digestType']; + $digest = $_POST['digest']; + + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + + $from[] = '/{{ keyTag }}/'; + $to[] = htmlspecialchars($keyTag); + + $from[] = '/{{ alg }}/'; + $to[] = htmlspecialchars($alg); + + $from[] = '/{{ digestType }}/'; + $to[] = htmlspecialchars($digestType); + + $from[] = '/{{ digest }}/'; + $to[] = htmlspecialchars($digest); + + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-update-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + + + {{ keyTag }} + {{ alg }} + {{ digestType }} + {{ digest }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + } + + if (isset($_POST['command']) && ($_POST['command'] === 'secDNSrem')) { + $keyTag = $_POST['keyTag']; + $alg = $_POST['alg']; + $digestType = $_POST['digestType']; + $digest = $_POST['digest']; + + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + + $from[] = '/{{ keyTag }}/'; + $to[] = htmlspecialchars($keyTag); + + $from[] = '/{{ alg }}/'; + $to[] = htmlspecialchars($alg); + + $from[] = '/{{ digestType }}/'; + $to[] = htmlspecialchars($digestType); + + $from[] = '/{{ digest }}/'; + $to[] = htmlspecialchars($digest); + + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-update-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + + + {{ keyTag }} + {{ alg }} + {{ digestType }} + {{ digest }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + } + + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + + $secDNSdsData = array(); + if ($r->response->extension && $r->response->extension->children('urn:ietf:params:xml:ns:secDNS-1.1')->infData) { + $DSRecords = 'YES'; + $i = 0; + $r = $r->response->extension->children('urn:ietf:params:xml:ns:secDNS-1.1')->infData; + foreach($r->dsData as $dsData) { + $i++; + $secDNSdsData[$i]["domainid"] = (int)$params['domainid']; + $secDNSdsData[$i]["keyTag"] = (string)$dsData->keyTag; + $secDNSdsData[$i]["alg"] = (int)$dsData->alg; + $secDNSdsData[$i]["digestType"] = (int)$dsData->digestType; + $secDNSdsData[$i]["digest"] = (string)$dsData->digest; + } + } + else { + $DSRecords = "You don't have any DS records"; + } + + $return = array( + 'templatefile' => 'manageDNSSECDSRecords', + 'requirelogin' => true, + 'vars' => array( + 'DSRecords' => $DSRecords, + 'DSRecordslist' => $secDNSdsData + ) + ); + } + + catch(exception $e) { + $return = array( + 'templatefile' => 'manageDNSSECDSRecords', + 'requirelogin' => true, + 'vars' => array( + 'error' => $e->getMessage() + ) + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_ClientAreaCustomButtonArray() +{ + $buttonarray = array( + Lang::Trans('Manage DNSSEC DS Records') => 'manageDNSSECDSRecords' + ); + + return $buttonarray; +} + +function verisign_AdminCustomButtonArray($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $domainid = getNamingoDomainId($params['domainid']); + + // $domain = Capsule::table('tbldomains')->where('id', $domainid)->first(); + + $domain = Capsule::table('namingo_domain_status')->where('domain_id', '=', $domainid)->where('status', '=', 'clientHold')->first(); + + if (isset($domain->status)) { + return array( + 'Unhold Domain' => 'UnHoldDomain' + ); + } + else { + return array( + 'Put Domain On Hold' => 'OnHoldDomain' + ); + } +} + +function verisign_OnHoldDomain($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData; + $status = array(); + $existing_status = 'ok'; + foreach($r->status as $e) { + $st = (string)$e->attributes()->s; + if ($st == 'clientHold') { + $existing_status = 'clientHold'; + break; + } + + if ($st == 'serverHold') { + $existing_status = 'serverHold'; + break; + } + } + + if ($existing_status == 'ok') { + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-update-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + clientHold + + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + } + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_UnHoldDomain($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData; + $status = array(); + $existing_status = 'ok'; + foreach($r->status as $e) { + $st = (string)$e->attributes()->s; + if ($st == 'clientHold') { + $existing_status = 'clientHold'; + break; + } + } + + if ($existing_status == 'clientHold') { + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['domainname']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-update-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + clientHold + + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + } + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_TransferSync($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['sld'] . '.' . $params['tld']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-transfer-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->trnData; + $trStatus = (string)$r->trStatus; + $expDate = (string)$r->exDate; + + Capsule::table('namingo_domain') + ->where('name', $params['domain']) + ->update(['trstatus' => $trStatus]); + + switch ($trStatus) { + case 'pending': + $return['completed'] = false; + break; + case 'clientApproved': + case 'serverApproved': + $return['completed'] = true; + $return['expirydate'] = date('Y-m-d', is_numeric($expDate) ? $expDate : strtotime($expDate)); + break; + case 'clientRejected': + case 'clientCancelled': + case 'serverCancelled': + $return['failed'] = true; + $return['reason'] = $trStatus; + break; + default: + $return = array( + 'error' => sprintf('invalid transfer status: %s', $trStatus) + ); + break; + } + + return $return; + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +function verisign_Sync($params = array()) +{ + _verisign_log(__FUNCTION__, $params); + $return = array(); + try { + $s = _verisign_startEppClient($params); + $from = $to = array(); + $from[] = '/{{ name }}/'; + $to[] = htmlspecialchars($params['sld'] . '.' . $params['tld']); + $from[] = '/{{ clTRID }}/'; + $clTRID = str_replace('.', '', round(microtime(1), 3)); + $to[] = htmlspecialchars($params['registrarprefix'] . '-domain-info-' . $clTRID); + $xml = preg_replace($from, $to, ' + + + + + {{ name }} + + + + + dotCOM + + + {{ clTRID }} + +'); + $r = $s->write($xml, __FUNCTION__); + $r = $r->response->resData->children('urn:ietf:params:xml:ns:domain-1.0')->infData; + $expDate = (string)$r->exDate; + $roid = (string)$r->roid; + $timestamp = strtotime($expDate); + + if ($timestamp === false) { + return array( + 'error' => 'Empty expDate date for domain: ' . $params['domain'] + ); + } + + $expDate = preg_replace("/^(\d+\-\d+\-\d+)\D.*$/", "$1", $expDate); + + // Format `exDate` to `YYYY-MM-DD HH:MM:SS.000` + $formattedExpDate = date('Y-m-d H:i:s.000', $timestamp); + + Capsule::table('namingo_domain') + ->where('name', $params['domain']) + ->update([ + 'exdate' => $formattedExpDate, + 'registry_domain_id' => $roid + ]); + + if ($timestamp < time()) { + return array( + 'expirydate' => $expDate, + 'expired' => true + ); + } + else { + return array( + 'expirydate' => $expDate, + 'active' => true + ); + } + } + + catch(exception $e) { + $return = array( + 'error' => $e->getMessage() + ); + } + + if (!empty($s)) { + $s->logout($params['registrarprefix']); + } + + return $return; +} + +class verisign_epp_client + +{ + var $socket; + var $isLogined = false; + var $params; + function __construct($params) + { + $this->params = $params; + $verify_peer = false; + if ($params['verify_peer'] == 'on') { + $verify_peer = true; + } + $ssl = array( + 'verify_peer' => $verify_peer, + 'cafile' => $params['cafile'], + 'local_cert' => $params['local_cert'], + 'local_pk' => $params['local_pk'], + 'passphrase' => $params['passphrase'] + ); + $host = $params['host']; + $port = $params['port']; + + if ($host) { + $this->connect($host, $port, $ssl); + } + } + + function connect($host, $port = 700, $ssl, $timeout = 30) + { + ini_set('display_errors', true); + error_reporting(E_ALL); + + // echo '
';print_r($host);
+        // print_r($this->params);
+        // exit;
+
+        if ($host != $this->params['host']) {
+            throw new exception("Unknown EPP server '$host'");
+        }
+        
+        $tls_version = '1.2';
+        if ($this->params['tls_version'] == 'on') {
+            $tls_version = '1.3';
+        }
+        
+        $opts = array(
+            'ssl' => array(
+                'verify_peer' => $ssl['verify_peer'],
+                'verify_peer_name' => false,
+                'verify_host' => false,
+                //'cafile' => __DIR__ . '/' . $ssl['cafile'],
+                'local_cert' => __DIR__ . '/' . $ssl['local_cert'],
+                'local_pk' => __DIR__ . '/' . $ssl['local_pk'],
+                //'passphrase' => $ssl['passphrase'],
+                'allow_self_signed' => true
+            )
+        );
+        $context = stream_context_create($opts);
+        $this->socket = stream_socket_client("tlsv{$tls_version}://{$host}:{$port}", $errno, $errmsg, $timeout, STREAM_CLIENT_CONNECT, $context);
+
+
+        if (!$this->socket) {
+            throw new exception("Cannot connect to server '{$host}': {$errmsg}");
+        }
+
+        return $this->read();
+    }
+
+    function login($login, $pwd, $prefix)
+    {
+        $from = $to = array();
+        $from[] = '/{{ clID }}/';
+        $to[] = htmlspecialchars($login);
+        $from[] = '/{{ pw }}/';
+        $to[] = $pwd;
+        $from[] = '/{{ clTRID }}/';
+        $clTRID = str_replace('.', '', round(microtime(1), 3));
+        $to[] = htmlspecialchars($prefix . '-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
+        http://www.verisign.com/epp/registry-1.0
+        http://www.verisign.com/epp/lowbalance-poll-1.0
+        http://www.verisign.com/epp/rgp-poll-1.0
+        
+          urn:ietf:params:xml:ns:secDNS-1.1
+          urn:ietf:params:xml:ns:epp:loginSec-1.0
+          http://www.verisign.com/epp/whoisInf-1.0
+          http://www.verisign.com/epp/idnLang-1.0
+          urn:ietf:params:xml:ns:coa-1.0
+          http://www.verisign-grs.com/epp/namestoreExt-1.1
+          http://www.verisign.com/epp/sync-1.0
+          http://www.verisign.com/epp/relatedDomain-1.0
+          urn:ietf:params:xml:ns:verificationCode-1.0
+          urn:ietf:params:xml:ns:rgp-1.0
+          urn:ietf:params:xml:ns:changePoll-1.0
+        
+      
+    
+    {{ clTRID }}
+  
+');
+        $r = $this->write($xml, __FUNCTION__);
+        $this->isLogined = true;
+        return true;
+    }
+
+    function logout($prefix)
+    {
+        if (!$this->isLogined) {
+            return true;
+        }
+
+        $from = $to = array();
+        $from[] = '/{{ clTRID }}/';
+        $clTRID = str_replace('.', '', round(microtime(1), 3));
+        $to[] = htmlspecialchars($prefix . '-logout-' . $clTRID);
+        $xml = preg_replace($from, $to, '
+
+  
+    
+    {{ clTRID }}
+  
+');
+        $r = $this->write($xml, __FUNCTION__);
+        $this->isLogined = false;
+        return true;
+    }
+
+    function read()
+    {
+        _verisign_log('================= read-this =================', $this);
+        $hdr = stream_get_contents($this->socket, 4);
+        if ($hdr === false) {
+        throw new exception('Connection appears to have closed.');
+        }
+        if (strlen($hdr) < 4) {
+        throw new exception('Failed to read header from the connection.');
+        }
+        $unpacked = unpack('N', $hdr);
+        $xml = fread($this->socket, ($unpacked[1] - 4));
+        $xml = preg_replace('/>\n<", $xml); 
+        _verisign_log('================= read =================', $xml);
+        return $xml;
+    }
+
+    function write($xml, $action = 'Unknown')
+    {
+        _verisign_log('================= send-this =================', $this);
+        _verisign_log('================= send =================', $xml);
+        if (fwrite($this->socket, pack('N', (strlen($xml) + 4)) . $xml) === false) {
+        throw new exception('Error writing to the connection.');
+        }
+        $r = simplexml_load_string($this->read());
+        _verisign_modulelog($xml, $r, $action);
+            if (isset($r->response) && $r->response->result->attributes()->code >= 2000) {
+                throw new exception($r->response->result->msg);
+            }
+        return $r;
+    }
+
+    function disconnect()
+    {
+        $result = fclose($this->socket);
+        if (!$result) {
+             throw new exception('Error closing the connection.');
+        }
+        $this->socket = null;
+        return $result;
+    }
+
+    function generateObjectPW($objType = 'none')
+    {
+        $result = '';
+        $uppercaseChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+        $lowercaseChars = "abcdefghijklmnopqrstuvwxyz";
+        $numbers = "1234567890";
+        $specialSymbols = "!=+-";
+        $minLength = 16;
+        $maxLength = 16;
+        $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 $result;
+    }
+    
+    function generateRandomString() 
+    {
+        $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+        $randomString = '';
+        for ($i = 0; $i < 16; $i++) {
+            $randomString .= $characters[rand(0, strlen($characters) - 1)];
+        }
+        return $randomString;
+    }
+
+}
+
+function _verisign_modulelog($send, $responsedata, $action)
+{
+    $from = $to = array();
+    $from[] = "/[^<]*<\/clID>/i";
+    $to[] = 'Not disclosed clID';
+    $from[] = "/[^<]*<\/pw>/i";
+    $to[] = 'Not disclosed pw';
+    $sendforlog = preg_replace($from, $to, $send);
+    logModuleCall('epp',$action,$sendforlog,$responsedata);
+}
+
+function _verisign_log($func, $params = false)
+{
+
+    // comment line below to see logs
+    //return true;
+
+    $handle = fopen(dirname(__FILE__) . '/verisign.log', 'a');
+    ob_start();
+    echo "\n================= $func =================\n";
+    print_r($params);
+    $text = ob_get_contents();
+    ob_end_clean();
+    fwrite($handle, $text);
+    fclose($handle);
+}
+
+function insertContacts($params, $contacts) {
+    $contactIds = [];
+
+    for ($i = 1; $i <= 4; $i++) {
+        // Insert into namingo_contact table
+        $contactId = Capsule::table('namingo_contact')->insertGetId([
+            'identifier' => $contacts[$i],
+            'voice' => $params['fullphonenumber'],
+            'email' => $params['email'],
+            'name' => $params['firstname'] . ' ' . $params['lastname'],
+            'org' => $params['companyname'],
+            'street1' => $params['address1'],
+            'street2' => $params['address2'],
+            'street3' => $params['address3'],
+            'city' => $params['city'],
+            'sp' => $params['state'],
+            'pc' => $params['postcode'],
+            'cc' => $params['country'],        
+            'clid' => 1,
+            'crdate' => date('Y-m-d H:i:s.u')
+        ]);
+
+        // Save the last insert ID
+        $contactIds[] = $contactId;
+    }
+
+    return $contactIds;
+}
+
+function insertDomain($params, $contactIds) {
+    // Calculate expiry date
+    $crdate = date('Y-m-d H:i:s.u');
+    $exdate = date('Y-m-d H:i:s.u', strtotime("+{$params['regperiod']} years"));
+
+    // Insert into namingo_domain table
+    $domainId = Capsule::table('namingo_domain')->insertGetId([
+        'name' => $params['domainname'],
+        'registry_domain_id' => '',
+        'clid' => 1,
+        'crid' => 1,
+        'crdate' => $crdate,
+        'exdate' => $exdate,
+        'registrant' => $contactIds[0] ?? null,     // Registrant contact ID
+        'admin' => $contactIds[1] ?? null,          // Admin contact ID
+        'tech' => $contactIds[2] ?? null,           // Tech contact ID
+        'billing' => $contactIds[3] ?? null,        // Billing contact ID
+        'ns1' => $params['ns1'] ?? null,    // Name servers
+        'ns2' => $params['ns2'] ?? null,
+        'ns3' => $params['ns3'] ?? null,
+        'ns4' => $params['ns4'] ?? null,
+        'ns5' => $params['ns5'] ?? null
+    ]);
+
+    return $domainId;
+}
+
+function getNamingoDomainId($whmcsDomainId) {
+    // Retrieve the `namingo_domain` ID in a single query using a join
+    $namingoDomain = Capsule::table('namingo_domain')
+        ->join('tbldomains', 'namingo_domain.name', '=', 'tbldomains.domain')
+        ->where('tbldomains.id', $whmcsDomainId)
+        ->select('namingo_domain.id')
+        ->first();
+
+    // Return the `id` from `namingo_domain` if found, otherwise null
+    return $namingoDomain ? $namingoDomain->id : null;
+}
+
+?>
\ No newline at end of file
diff --git a/whmcs.json b/whmcs.json
new file mode 100644
index 0000000..386a052
--- /dev/null
+++ b/whmcs.json
@@ -0,0 +1,23 @@
+{
+  "schema": "1.0",
+  "type": "whmcs-registrars",
+  "name": "verisign",
+  "license": "MIT",
+  "category": "domains",
+  "description": {
+    "name": "Namingo EPP (VeriSign)",
+    "tagline": "This module supports all gTLDs that use the VeriSign platform"
+  },
+  "logo": {
+    "filename": "logo.gif"
+  },
+  "support": {
+    "homepage": "https:\/\/namingo.org\/"
+  },
+  "authors": [
+    {
+      "name": "Namingo",
+      "homepage": "https:\/\/namingo.org\/"
+    }
+  ]
+}