mirror of
https://github.com/getnamingo/registry.git
synced 2025-05-09 16:28:34 +02:00
Added scripts for testing the components
- DAS server output optimization - Fixed EPP formatting error
This commit is contained in:
parent
5084e1f6ee
commit
34da89751d
6 changed files with 626 additions and 13 deletions
|
@ -60,25 +60,25 @@ $server->on('receive', function ($server, $fd, $reactorId, $data) use ($c, $pool
|
|||
try {
|
||||
// Validate and sanitize the domain name
|
||||
if (!$domain) {
|
||||
$server->send($fd, "please enter a domain name");
|
||||
$server->send($fd, "2");
|
||||
$server->close($fd);
|
||||
}
|
||||
if (strlen($domain) > 68) {
|
||||
$server->send($fd, "domain name is too long");
|
||||
$server->send($fd, "2");
|
||||
$server->close($fd);
|
||||
}
|
||||
// Convert to Punycode if the domain is not in ASCII
|
||||
if (!mb_detect_encoding($domain, 'ASCII', true)) {
|
||||
$convertedDomain = idn_to_ascii($domain, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
|
||||
if ($convertedDomain === false) {
|
||||
$server->send($fd, "Domain conversion to Punycode failed");
|
||||
$server->send($fd, "2");
|
||||
$server->close($fd);
|
||||
} else {
|
||||
$domain = $convertedDomain;
|
||||
}
|
||||
}
|
||||
if (!preg_match('/^(?:(xn--[a-zA-Z0-9-]{1,63}|[a-zA-Z0-9-]{1,63})\.){1,3}(xn--[a-zA-Z0-9-]{2,63}|[a-zA-Z]{2,63})$/', $domain)) {
|
||||
$server->send($fd, "domain name invalid format");
|
||||
$server->send($fd, "2");
|
||||
$server->close($fd);
|
||||
}
|
||||
$domain = strtoupper($domain);
|
||||
|
@ -94,7 +94,7 @@ $server->on('receive', function ($server, $fd, $reactorId, $data) use ($c, $pool
|
|||
$tldExists = $stmtTLD->fetchColumn();
|
||||
|
||||
if (!$tldExists) {
|
||||
$server->send($fd, "Invalid TLD. Please search only allowed TLDs");
|
||||
$server->send($fd, "2");
|
||||
$server->close($fd);
|
||||
return;
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ $server->on('receive', function ($server, $fd, $reactorId, $data) use ($c, $pool
|
|||
$domain_already_reserved = $stmtReserved->fetchColumn();
|
||||
|
||||
if ($domain_already_reserved) {
|
||||
$server->send($fd, "Domain name is reserved or restricted");
|
||||
$server->send($fd, "3");
|
||||
$server->close($fd);
|
||||
return;
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ $server->on('receive', function ($server, $fd, $reactorId, $data) use ($c, $pool
|
|||
$idnRegex = $stmtRegex->fetchColumn();
|
||||
|
||||
if (!$idnRegex) {
|
||||
$server->send($fd, "Failed to fetch domain IDN table");
|
||||
$server->send($fd, "2");
|
||||
$server->close($fd);
|
||||
return;
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ $server->on('receive', function ($server, $fd, $reactorId, $data) use ($c, $pool
|
|||
$label = strtolower($parts[0]);
|
||||
}
|
||||
if (!preg_match($idnRegex, $label)) {
|
||||
$server->send($fd, "Domain name invalid IDN characters");
|
||||
$server->send($fd, "2");
|
||||
$server->close($fd);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -101,6 +101,11 @@ $server->handle(function (Connection $conn) use ($table, $pool, $c, $log, $permi
|
|||
libxml_use_internal_errors(true);
|
||||
|
||||
$xml = simplexml_load_string($xmlData);
|
||||
if ($xml === false) {
|
||||
sendEppError($conn, $pdo, 2001, 'Invalid XML');
|
||||
break;
|
||||
}
|
||||
|
||||
$xml->registerXPathNamespace('e', 'urn:ietf:params:xml:ns:epp-1.0');
|
||||
$xml->registerXPathNamespace('xsi', 'http://www.w3.org/2001/XMLSchema-instance');
|
||||
$xml->registerXPathNamespace('domain', 'urn:ietf:params:xml:ns:domain-1.0');
|
||||
|
@ -113,11 +118,6 @@ $server->handle(function (Connection $conn) use ($table, $pool, $c, $log, $permi
|
|||
$xml->registerXPathNamespace('mark', 'urn:ietf:params:xml:ns:mark-1.0');
|
||||
$xml->registerXPathNamespace('allocationToken', 'urn:ietf:params:xml:ns:allocationToken-1.0');
|
||||
|
||||
if ($xml === false) {
|
||||
sendEppError($conn, $pdo, 2001, 'Invalid XML');
|
||||
break;
|
||||
}
|
||||
|
||||
if ($xml->getName() != 'epp') {
|
||||
continue; // Skip this iteration if not an EPP command
|
||||
}
|
||||
|
|
71
tests/das.php
Normal file
71
tests/das.php
Normal file
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
// Namingo DAS QA Testing Tool
|
||||
|
||||
$server = 'your_das_server_address';
|
||||
$port = 1043;
|
||||
|
||||
/**
|
||||
* Sends a domain request to the DAS server and returns the response.
|
||||
*/
|
||||
function sendRequest($server, $port, $domain) {
|
||||
$timeout = 10;
|
||||
$errorNumber = 0;
|
||||
$errorMessage = '';
|
||||
|
||||
// Open the socket
|
||||
$socket = @stream_socket_client("tcp://$server:$port", $errorNumber, $errorMessage, $timeout);
|
||||
|
||||
if (!$socket) {
|
||||
echo "Error: $errorMessage ($errorNumber)\n";
|
||||
return null;
|
||||
}
|
||||
|
||||
// Send the domain request
|
||||
fwrite($socket, $domain . "\r\n"); // Use carriage return and newline
|
||||
|
||||
// Wait for the response
|
||||
$response = '';
|
||||
while (!feof($socket)) {
|
||||
$response .= fread($socket, 8192);
|
||||
}
|
||||
|
||||
fclose($socket);
|
||||
|
||||
return trim($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a domain request against expected response.
|
||||
*/
|
||||
function testDomainRequest($domain, $expected, $message) {
|
||||
global $server, $port;
|
||||
$response = sendRequest($server, $port, $domain);
|
||||
|
||||
if ($response === $expected) {
|
||||
echo "PASS: $message\n";
|
||||
} else {
|
||||
echo "FAIL: $message (Expected: $expected, Got: $response)\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Basic Test Cases
|
||||
testDomainRequest('test.test', '1', 'Valid domain name');
|
||||
testDomainRequest('nonexistentdomain.test', '0', 'Non-existent domain');
|
||||
testDomainRequest('hyphen-domain.test', '0', 'Hyphenated domain name');
|
||||
|
||||
// Edge Cases
|
||||
testDomainRequest('', '2', 'Empty domain name');
|
||||
testDomainRequest('12345.test', '0', 'Numerical domain name');
|
||||
testDomainRequest('test', '2', 'Top-level domain only');
|
||||
testDomainRequest('!@#$%^&*', '2', 'Special characters in domain');
|
||||
testDomainRequest('a.test', '0', 'Single character domain name');
|
||||
testDomainRequest('verylongdomainnametestingxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.test', '2', 'Unusually long domain name');
|
||||
|
||||
// Security Cases
|
||||
testDomainRequest('example.test; DROP TABLE domains;', '2', 'SQL Injection attempt');
|
||||
testDomainRequest(str_repeat('A', 5000), '2', 'Buffer Overflow attempt');
|
||||
testDomainRequest('<script>alert("XSS")</script>.test', '2', 'XSS Injection attempt');
|
||||
testDomainRequest('`; ls -la`.test', '2', 'Command Injection attempt');
|
||||
testDomainRequest('测试.test', '2', 'Unicode characters in domain');
|
||||
testDomainRequest(' test .test', '2', 'Domain with leading whitespace');
|
||||
testDomainRequest('test .test', '2', 'Domain with trailing whitespace');
|
253
tests/epp.php
Normal file
253
tests/epp.php
Normal file
|
@ -0,0 +1,253 @@
|
|||
<?php
|
||||
class EppClient {
|
||||
private $connection;
|
||||
private $server;
|
||||
private $port;
|
||||
private $sslCert;
|
||||
private $sslKey;
|
||||
|
||||
public function __construct($server, $port, $sslCert = null, $sslKey = null) {
|
||||
$this->server = $server;
|
||||
$this->port = $port;
|
||||
$this->sslCert = $sslCert;
|
||||
$this->sslKey = $sslKey;
|
||||
}
|
||||
|
||||
public function connect() {
|
||||
$contextOptions = [
|
||||
'ssl' => [
|
||||
'local_cert' => $this->sslCert,
|
||||
'local_pk' => $this->sslKey,
|
||||
'allow_self_signed' => true, // Set to false in production
|
||||
'verify_peer' => false, // Set to true in production
|
||||
'verify_peer_name' => false, // Set to true in production
|
||||
],
|
||||
];
|
||||
$context = stream_context_create($contextOptions);
|
||||
$this->connection = stream_socket_client("ssl://{$this->server}:{$this->port}", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
|
||||
|
||||
if (!$this->connection) {
|
||||
throw new Exception("Could not connect to EPP Server: $errstr ($errno)");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function generateUniqueClTRID() {
|
||||
$timeComponent = microtime(true);
|
||||
$randomComponent = bin2hex(random_bytes(8));
|
||||
return "clTRID-{$timeComponent}-{$randomComponent}";
|
||||
}
|
||||
|
||||
public function sendRequest($xml) {
|
||||
$length = strlen($xml) + 4; // 4 bytes for the length field itself
|
||||
$lengthField = pack('N', $length); // 'N' for big-endian order
|
||||
fwrite($this->connection, $lengthField . $xml);
|
||||
|
||||
// Read the response
|
||||
return $this->readResponse();
|
||||
}
|
||||
|
||||
private function readResponse() {
|
||||
// Read the 4-byte length field
|
||||
$lengthField = fread($this->connection, 4);
|
||||
$unpacked = unpack('N', $lengthField);
|
||||
$length = reset($unpacked) - 4; // Subtract the 4 bytes of the length field
|
||||
|
||||
// Read the message based on the length
|
||||
$response = '';
|
||||
while ($length > 0 && !feof($this->connection)) {
|
||||
$part = fread($this->connection, $length);
|
||||
$response .= $part;
|
||||
$length -= strlen($part);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function disconnect() {
|
||||
fclose($this->connection);
|
||||
}
|
||||
|
||||
public function login($clientId, $password) {
|
||||
$xmlRequest = '<?xml version="1.0" encoding="UTF-8"?><epp xmlns="urn:ietf:params:xml:ns:epp-1.0"><command><login><clID>'.$clientId.'</clID><pw><![CDATA['.$password.']]></pw></login><clTRID>login-'.$this->generateUniqueClTRID().'</clTRID></command></epp>';
|
||||
echo $this->sendRequest($xmlRequest);
|
||||
}
|
||||
|
||||
public function logout() {
|
||||
$xmlRequest = '<?xml version="1.0" encoding="UTF-8" standalone="no"?><epp xmlns="urn:ietf:params:xml:ns:epp-1.0"><command><logout/><clTRID>logout-'.$this->generateUniqueClTRID().'</clTRID></command></epp>';
|
||||
echo $this->sendRequest($xmlRequest);
|
||||
}
|
||||
|
||||
public function testDomainCheck() {
|
||||
$xmlRequest = '<?xml version="1.0" encoding="UTF-8" standalone="no"?><epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd"><command><check><domain:check
|
||||
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd"><domain:name>example.test</domain:name><domain:name>example.net</domain:name><domain:name>verylongdomainnamethatisunlikelytobevalidandcausesprocessingdelays.test</domain:name></domain:check></check><clTRID>domaincheck-'.$this->generateUniqueClTRID().'</clTRID></command></epp>';
|
||||
echo $this->sendRequest($xmlRequest);
|
||||
}
|
||||
|
||||
public function testInvalidCommand() {
|
||||
$xmlRequest = '<?xml version="1.0" encoding="UTF-8" standalone="no"?><epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd"><command><invalidCommand/></command></epp>';
|
||||
echo $this->sendRequest($xmlRequest);
|
||||
}
|
||||
|
||||
public function testInvalidExtension() {
|
||||
$xmlRequest = '<?xml version="1.0" encoding="UTF-8" standalone="no"?><epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd"><command><check><unsupported:check xmlns:unsupported="urn:ietf:params:xml:ns:unsupported-1.0"><unsupported:name>example.com</unsupported:name></unsupported:check></check></command></epp>';
|
||||
echo $this->sendRequest($xmlRequest);
|
||||
}
|
||||
|
||||
public function testBadXml() {
|
||||
$xmlRequest = '<?xml version="1.0" encoding="UTF-8" standalone="no"?><epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd"><command><check><domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0"><domain:name>example.com</domain:name></domain:check></check</command></epp>';
|
||||
echo $this->sendRequest($xmlRequest);
|
||||
}
|
||||
|
||||
public function testSqlInj() {
|
||||
$xmlRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><epp xmlns=\"urn:ietf:params:xml:ns:epp-1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
|
||||
xsi:schemaLocation=\"urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd\"><command><check><domain:check
|
||||
xmlns:domain=\"urn:ietf:params:xml:ns:domain-1.0\" xsi:schemaLocation=\"urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd\"><domain:name>' OR '1'='1</domain:name></domain:check></check><clTRID>domaincheck-".$this->generateUniqueClTRID()."</clTRID></command></epp>";
|
||||
echo $this->sendRequest($xmlRequest);
|
||||
}
|
||||
|
||||
public function testUnusuallyFormattedCommands() {
|
||||
$xmlRequest = "<epp>\n\n <command>\n <check>\n <domain:check xmlns:domain=\"urn:ietf:params:xml:ns:domain-1.0\">\n <domain:name>example.com</domain:name>\n </domain:check>\n </check>\n </command>\n</epp>";
|
||||
echo $this->sendRequest($xmlRequest);
|
||||
}
|
||||
|
||||
public function testBoundaryValues() {
|
||||
$longDomainName = str_repeat("a", 255) . ".com"; // Adjust the length as needed
|
||||
|
||||
$xmlRequest = <<<XML
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>{$longDomainName}</domain:name>
|
||||
</domain:check>
|
||||
</check>
|
||||
</command>
|
||||
</epp>
|
||||
XML;
|
||||
echo $this->sendRequest($xmlRequest);
|
||||
}
|
||||
|
||||
public function testRepeatedLoginLogout() {
|
||||
for ($i = 0; $i < 10; $i++) { // Adjust the number of iterations as needed
|
||||
// Replace with actual login and logout XML requests
|
||||
$loginRequest = "<epp><command><login><clID>clientID</clID><pw>password</pw></login></command></epp>";
|
||||
$logoutRequest = "<epp><command><logout/></command></epp>";
|
||||
|
||||
$this->sendRequest($loginRequest);
|
||||
$this->sendRequest($logoutRequest);
|
||||
}
|
||||
|
||||
echo "Repeated Login and Logout Test Completed.\n";
|
||||
}
|
||||
|
||||
public function testMalformedUnicodeCharacters() {
|
||||
echo "Running Malformed Unicode Characters Test...\n";
|
||||
|
||||
// Example: Malformed Unicode characters in the domain name
|
||||
$malformedDomainName = "exämple.cöm"; // Contains unusual/malformed characters
|
||||
|
||||
$xmlRequest = <<<XML
|
||||
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
|
||||
<command>
|
||||
<check>
|
||||
<domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
|
||||
<domain:name>{$malformedDomainName}</domain:name>
|
||||
</domain:check>
|
||||
</check>
|
||||
</command>
|
||||
</epp>
|
||||
XML;
|
||||
|
||||
$response = $this->sendRequest($xmlRequest);
|
||||
echo "Response: " . $response . "\n";
|
||||
}
|
||||
|
||||
public function testSimulatedNetworkInstability() {
|
||||
echo "Running Simulated Network Instability Test...\n";
|
||||
|
||||
// Example: Introduce delays in sending requests
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$xmlRequest = "<epp><command><check><domain:check xmlns:domain='urn:ietf:params:xml:ns:domain-1.0'><domain:name>example.com</domain:name></domain:check></check></command></epp>";
|
||||
|
||||
// Introducing a delay
|
||||
sleep(rand(1, 5)); // Delay between 1 to 5 seconds
|
||||
|
||||
$response = $this->sendRequest($xmlRequest);
|
||||
echo "Response: " . $response . "\n";
|
||||
}
|
||||
|
||||
echo "Simulated Network Instability Test Completed.\n";
|
||||
}
|
||||
|
||||
public function testUnexpectedProtocolVersion() {
|
||||
echo "Running Unexpected Protocol Version Test...\n";
|
||||
|
||||
$xmlRequest = "<epp xmlns='urn:ietf:params:xml:ns:epp-2.0'><command><check><domain:check xmlns:domain='urn:ietf:params:xml:ns:domain-1.0'><domain:name>example.com</domain:name></domain:check></check></command></epp>";
|
||||
|
||||
$response = $this->sendRequest($xmlRequest);
|
||||
echo "Response: " . $response . "\n";
|
||||
}
|
||||
|
||||
public function testServerOverloadWithLongDuration() {
|
||||
echo "Running Server Overload with Long Duration Requests Test...\n";
|
||||
|
||||
$startTime = time();
|
||||
$duration = 60; // Run the test for 60 seconds
|
||||
|
||||
while (time() - $startTime < $duration) {
|
||||
$xmlRequest = "<epp><command><check><domain:check xmlns:domain='urn:ietf:params:xml:ns:domain-1.0'><domain:name>example.com</domain:name></domain:check></check></command></epp>";
|
||||
|
||||
$response = $this->sendRequest($xmlRequest);
|
||||
// Optionally process the response
|
||||
}
|
||||
|
||||
echo "Server Overload with Long Duration Requests Test Completed.\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class EppTest {
|
||||
private $client;
|
||||
|
||||
public function __construct() {
|
||||
// Initialize the EPP client with your server's details
|
||||
$this->client = new EppClient('epp.server.com', 700, 'cert.pem', 'key.pem');
|
||||
}
|
||||
|
||||
public function runTests() {
|
||||
echo "Starting EPP Tests...\n";
|
||||
|
||||
// Connect to the EPP server
|
||||
$this->client->connect();
|
||||
$this->client->login('clid', 'password');
|
||||
|
||||
// Run various tests
|
||||
$this->client->testDomainCheck();
|
||||
$this->client->testInvalidCommand();
|
||||
//$this->client->testUnusuallyFormattedCommands();
|
||||
//$this->client->testInvalidExtension();
|
||||
//$this->client->testBadXml();
|
||||
//$this->client->testSqlInj();
|
||||
//$this->client->testBoundaryValues();
|
||||
//$this->client->testRepeatedLoginLogout();
|
||||
//$this->client->testMalformedUnicodeCharacters();
|
||||
//$this->client->testSimulatedNetworkInstability();
|
||||
//$this->client->testUnexpectedProtocolVersion();
|
||||
//$this->client->testServerOverloadWithLongDuration();
|
||||
|
||||
// Disconnect from the server
|
||||
$this->client->logout();
|
||||
$this->client->disconnect();
|
||||
|
||||
echo "EPP Tests Completed.\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$test = new EppTest();
|
||||
$test->runTests();
|
78
tests/rdap.php
Normal file
78
tests/rdap.php
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
// Namingo RDAP QA Testing Tool
|
||||
|
||||
// Configuration
|
||||
$rdapServer = "https://example-rdap-server.com";
|
||||
|
||||
// Test Cases
|
||||
$testCases = [
|
||||
// Basic Cases
|
||||
["type" => "domain", "query" => "example.test", "expected" => "Not Found"],
|
||||
["type" => "nameserver", "query" => "ns1.example.test", "expected" => "Not Found"],
|
||||
["type" => "domain", "query" => "test.test", "expected" => "domain"],
|
||||
|
||||
// Edge Cases
|
||||
["type" => "domain", "query" => "", "expected" => "Not Found"],
|
||||
["type" => "nameserver", "query" => "ns1.exa#mple.test", "expected" => "Nameserver invalid format"],
|
||||
["type" => "domain", "query" => "verylongdomainnametestingxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.test", "expected" => "Domain name is too long"],
|
||||
["type" => "domain", "query" => "special!@#$.test", "expected" => "Domain name invalid format"],
|
||||
|
||||
// Security Cases
|
||||
["type" => "domain", "query" => "example.test; DROP TABLE users;", "expected" => "Domain name invalid format"],
|
||||
["type" => "domain", "query" => "<script>alert('XSS')</script>", "expected" => "Domain name invalid format"],
|
||||
["type" => "domain", "query" => "; ls -la", "expected" => "Domain name invalid format"],
|
||||
["type" => "domain", "query" => str_repeat("A", 10000), "expected" => "Domain name is too long"],
|
||||
|
||||
// Protocol and Compliance Cases
|
||||
["type" => "invalidpath", "query" => "example.test", "expected" => "Endpoint not found"],
|
||||
|
||||
// Response and Format Cases
|
||||
["type" => "domain", "query" => "utf8testé.test", "expected" => "Domain name invalid IDN characters"],
|
||||
];
|
||||
|
||||
// Function to send RDAP request
|
||||
function sendRdapRequest($server, $type, $query) {
|
||||
$url = $server . "/" . $type . "/" . urlencode($query);
|
||||
$ch = curl_init($url);
|
||||
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
|
||||
// Check for cURL errors
|
||||
if (curl_errno($ch)) {
|
||||
throw new Exception('cURL error: ' . curl_error($ch));
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
return $response;
|
||||
}
|
||||
|
||||
// Function to validate response
|
||||
function validateResponse($response, $expected) {
|
||||
$decodedResponse = json_decode($response, true);
|
||||
|
||||
// Basic validation
|
||||
if (isset($decodedResponse['objectClassName']) && $decodedResponse['objectClassName'] === $expected) {
|
||||
return true;
|
||||
} else if (isset($decodedResponse['title']) && $decodedResponse['title'] === $expected) {
|
||||
return true;
|
||||
} else if (isset($decodedResponse['error']) && $decodedResponse['error'] === $expected) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Main testing loop
|
||||
foreach ($testCases as $testCase) {
|
||||
$response = sendRdapRequest($rdapServer, $testCase['type'], $testCase['query']);
|
||||
$isValid = validateResponse($response, $testCase['expected']);
|
||||
// Logging and Reporting
|
||||
echo "Test: " . $testCase['query'] . " - " . ($isValid ? "PASS" : "FAIL") . "\n";
|
||||
}
|
211
tests/whois.php
Normal file
211
tests/whois.php
Normal file
|
@ -0,0 +1,211 @@
|
|||
<?php
|
||||
// Namingo WHOIS QA Testing Tool
|
||||
|
||||
class WhoisTest {
|
||||
private $whoisServer = "whois.example.com"; // Replace with actual WHOIS server
|
||||
|
||||
public function runTests() {
|
||||
$this->testBasicQueries();
|
||||
$this->testEdgeCases();
|
||||
$this->testSecurityCases();
|
||||
$this->testResponseTime();
|
||||
$this->testDataAccuracy();
|
||||
$this->testInvalidQueries();
|
||||
$this->testIDNSupport();
|
||||
$this->testRateLimiting();
|
||||
$this->testComplianceWithStandards();
|
||||
}
|
||||
|
||||
private function testBasicQueries() {
|
||||
echo "Running Basic Queries Test...\n";
|
||||
// List of domains to test
|
||||
$domains = ['test.test', 'example.test', 'example.org'];
|
||||
|
||||
foreach ($domains as $domain) {
|
||||
$result = $this->queryWhoisServer($domain);
|
||||
if ($result && (strpos($result, 'NOT FOUND') !== false || strpos($result, 'Invalid TLD') === 0 || strpos($result, 'Domain Name:') === 0)) {
|
||||
echo "Test: $domain - PASS\n";
|
||||
} else {
|
||||
echo "Test: $domain - FAIL\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function testEdgeCases() {
|
||||
echo "Running Edge Cases Test...\n";
|
||||
// Test non-existing domains, special characters, long domain names
|
||||
$edgeCaseDomains = ['thisdomaindoesnotexist123456.test', 'example-.test', str_repeat('a', 75) . '.test'];
|
||||
|
||||
foreach ($edgeCaseDomains as $domain) {
|
||||
$result = $this->queryWhoisServer($domain);
|
||||
// In edge cases, we expect failures or specific responses
|
||||
if ($result && (strpos($result, 'NOT FOUND') !== false || strpos($result, 'Domain name invalid IDN characters') === 0 || strpos($result, 'domain name is too long') === 0)) {
|
||||
echo "Test: $domain - PASS\n";
|
||||
} else {
|
||||
echo "Test: $domain - FAIL\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function testSecurityCases() {
|
||||
echo "Running Security Cases Test...\n";
|
||||
// Test with potential security risk inputs
|
||||
$securityTestDomains = [
|
||||
"; DROP TABLE domains;", // SQL Injection
|
||||
"\"><script>alert(1)</script>", // Basic XSS
|
||||
"' OR '1'='1", // SQL Injection Variant
|
||||
"| rm -rf /", // Command Injection
|
||||
str_repeat("A", 10000), // Buffer Overflow
|
||||
"<svg/onload=alert(1)>", // XSS with HTML5
|
||||
"<!--#exec cmd=\"/bin/echo 'Vulnerable'\" -->", // Server Side Includes (SSI) Injection
|
||||
"(|(uid=*)(cn=*))", // LDAP Injection
|
||||
"../etc/passwd", // Path Traversal
|
||||
"<foo><![CDATA[<]]><bar>]]>baz</bar>", // XML Injection
|
||||
];
|
||||
|
||||
foreach ($securityTestDomains as $domain) {
|
||||
$result = $this->queryWhoisServer($domain);
|
||||
if ($result && (strpos($result, 'domain name invalid format') !== false || strpos($result, 'domain name is too long') === 0)) {
|
||||
echo "Test: $domain - PASS\n";
|
||||
} else {
|
||||
echo "Test: $domain - FAIL\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function testResponseTime() {
|
||||
echo "Testing Response Time...\n";
|
||||
$domains = ['example.test', 'test.test', 'example.org']; // Multiple domains for a broader test
|
||||
$testCount = 5; // Number of tests per domain
|
||||
$totalDuration = 0;
|
||||
|
||||
foreach ($domains as $domain) {
|
||||
$domainDurations = [];
|
||||
|
||||
for ($i = 0; $i < $testCount; $i++) {
|
||||
$startTime = microtime(true);
|
||||
$this->queryWhoisServer($domain);
|
||||
$endTime = microtime(true);
|
||||
$duration = $endTime - $startTime;
|
||||
$domainDurations[] = $duration;
|
||||
$totalDuration += $duration;
|
||||
}
|
||||
|
||||
$averageDuration = array_sum($domainDurations) / count($domainDurations);
|
||||
$variance = $this->calculateVariance($domainDurations, $averageDuration);
|
||||
|
||||
echo "Average response time for $domain: " . number_format($averageDuration, 3) . " seconds\n";
|
||||
echo "Variance in response time for $domain: " . number_format($variance, 3) . "\n";
|
||||
}
|
||||
|
||||
$overallAverage = $totalDuration / ($testCount * count($domains));
|
||||
echo "Overall average response time: " . number_format($overallAverage, 3) . " seconds\n";
|
||||
}
|
||||
|
||||
private function testDataAccuracy() {
|
||||
echo "Testing Data Accuracy...\n";
|
||||
$testDomain = 'test.test'; // Use a domain whose WHOIS info you know
|
||||
$expectedRegistrar = 'LeoNet LLC'; // Replace with known data
|
||||
$result = $this->queryWhoisServer($testDomain);
|
||||
if (strpos($result, $expectedRegistrar) !== false) {
|
||||
echo "Test: $testDomain - PASS\n";
|
||||
} else {
|
||||
echo "Test: $testDomain - FAIL\n";
|
||||
}
|
||||
}
|
||||
|
||||
private function testInvalidQueries() {
|
||||
echo "Testing Handling of Invalid Queries...\n";
|
||||
$invalidDomains = ['this is not a domain', '', '1234567890', 'invalid_domain.com'];
|
||||
foreach ($invalidDomains as $domain) {
|
||||
$result = $this->queryWhoisServer($domain);
|
||||
if ($result && (strpos($result, 'domain name invalid format') !== false || strpos($result, 'please enter a domain name') === 0)) {
|
||||
echo "Test: $domain - PASS\n";
|
||||
} else {
|
||||
echo "Test: $domain - FAIL\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function testIDNSupport() {
|
||||
echo "Testing International Domain Name (IDN) Support...\n";
|
||||
$idnDomain = 'xn--exmple-cua.com'; // Punycode for an IDN domain
|
||||
$result = $this->queryWhoisServer($idnDomain);
|
||||
if ($result) {
|
||||
echo "Test: $idnDomain - PASS\n";
|
||||
} else {
|
||||
echo "Test: $idnDomain - FAIL\n";
|
||||
}
|
||||
}
|
||||
|
||||
private function testRateLimiting() {
|
||||
echo "Testing Rate Limiting...\n";
|
||||
$domain = 'example.com';
|
||||
$successCount = 0;
|
||||
$testCount = 10; // Number of requests to simulate rate limiting
|
||||
|
||||
for ($i = 0; $i < $testCount; $i++) {
|
||||
if ($this->queryWhoisServer($domain)) {
|
||||
$successCount++;
|
||||
}
|
||||
sleep(1); // Sleep to avoid hitting the server too rapidly
|
||||
}
|
||||
|
||||
if ($successCount < $testCount) {
|
||||
echo "Test: Rate limiting - PASS. Number of successful queries: $successCount\n";
|
||||
} else {
|
||||
echo "Test: Rate limiting - FAIL\n";
|
||||
}
|
||||
}
|
||||
|
||||
private function testComplianceWithStandards() {
|
||||
echo "Testing Compliance with WHOIS Protocol Standards...\n";
|
||||
$domain = 'test.test';
|
||||
$result = $this->queryWhoisServer($domain);
|
||||
|
||||
// Check for a standard response format (this will depend on the specific standard)
|
||||
if (strpos($result, 'Domain Name:') !== false && strpos($result, 'Registrar:') !== false) {
|
||||
echo "Test: $domain - PASS\n";
|
||||
} else {
|
||||
echo "Test: $fail - PASS\n";
|
||||
}
|
||||
}
|
||||
|
||||
private function queryWhoisServer($domain) {
|
||||
$server = $this->whoisServer; // WHOIS server
|
||||
$port = 43; // Standard WHOIS port
|
||||
|
||||
// Open a connection to the WHOIS server
|
||||
$connection = fsockopen($server, $port);
|
||||
if (!$connection) {
|
||||
return false; // Connection failed
|
||||
}
|
||||
|
||||
// Send the query
|
||||
fputs($connection, "$domain\r\n");
|
||||
|
||||
// Read and store the response
|
||||
$response = '';
|
||||
while (!feof($connection)) {
|
||||
$response .= fgets($connection, 128);
|
||||
}
|
||||
|
||||
// Close the connection
|
||||
fclose($connection);
|
||||
|
||||
// Return the response
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function calculateVariance($durations, $mean) {
|
||||
$sumOfSquares = 0;
|
||||
foreach ($durations as $duration) {
|
||||
$sumOfSquares += pow(($duration - $mean), 2);
|
||||
}
|
||||
return $sumOfSquares / count($durations);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$whoisTest = new WhoisTest();
|
||||
$whoisTest->runTests();
|
Loading…
Add table
Reference in a new issue