2015-04-18 18:26:52 +00:00
|
|
|
<?php
|
2016-02-03 22:22:56 +00:00
|
|
|
/**
|
2015-04-18 18:26:52 +00:00
|
|
|
* Whois in PHP (featuring a very original name), adjusted for Sakura
|
|
|
|
* By Flashwave <http://flash.moe>
|
|
|
|
* Released under the MIT-License
|
|
|
|
*
|
|
|
|
* The MIT License (MIT)
|
2015-09-14 20:51:23 +00:00
|
|
|
*
|
2015-04-18 18:26:52 +00:00
|
|
|
* Copyright (c) 2015 Flashwave
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
|
|
* in the Software without restriction, including without limitation the rights
|
|
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
|
|
* furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
|
|
* copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
* SOFTWARE.
|
2016-02-03 22:22:56 +00:00
|
|
|
*
|
|
|
|
* @package Sakura
|
2015-04-18 18:26:52 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
namespace Sakura;
|
|
|
|
|
2015-10-18 19:06:30 +00:00
|
|
|
/**
|
2016-02-02 21:04:15 +00:00
|
|
|
* WHOIS client.
|
|
|
|
*
|
2015-10-18 19:06:30 +00:00
|
|
|
* @package Sakura
|
2016-02-02 21:04:15 +00:00
|
|
|
* @author Julian van de Groep <me@flash.moe>
|
2015-10-18 19:06:30 +00:00
|
|
|
*/
|
2015-09-14 20:51:23 +00:00
|
|
|
class Whois
|
|
|
|
{
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* The index of WHOIS servers.
|
|
|
|
*
|
|
|
|
* @var array
|
|
|
|
*/
|
2015-04-18 18:26:52 +00:00
|
|
|
public static $servers;
|
|
|
|
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* Set the list of WHOIS servers.
|
|
|
|
*
|
|
|
|
* @param string $serversFile The file containing the servers json.
|
|
|
|
*/
|
2015-09-14 20:51:23 +00:00
|
|
|
public static function setServers($serversFile)
|
|
|
|
{
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// Check if the file exists and if it does get contents.
|
2015-09-14 20:51:23 +00:00
|
|
|
if (file_exists($serversFile)) {
|
2015-07-05 15:03:58 +00:00
|
|
|
$servers = utf8_encode(file_get_contents($serversFile));
|
2015-09-14 20:51:23 +00:00
|
|
|
} else {
|
2015-04-18 18:26:52 +00:00
|
|
|
trigger_error('Failed to load whois servers file', E_USER_ERROR);
|
2015-09-14 20:51:23 +00:00
|
|
|
}
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// Parse json
|
2015-09-14 20:51:23 +00:00
|
|
|
if (($servers = json_decode($servers, true)) != true) {
|
2015-04-18 18:26:52 +00:00
|
|
|
trigger_error('Error while parsing whois servers file JSON', E_USER_ERROR);
|
2015-09-14 20:51:23 +00:00
|
|
|
}
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// Check for neccesary keys
|
2015-09-14 20:51:23 +00:00
|
|
|
if (!array_key_exists('tld', $servers) || !array_key_exists('ip', $servers)) {
|
2015-09-14 21:41:43 +00:00
|
|
|
trigger_error(
|
|
|
|
'One or more of the required whois lists isn\'t set, please check your whois servers file',
|
|
|
|
E_USER_ERROR
|
|
|
|
);
|
2015-09-14 20:51:23 +00:00
|
|
|
}
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// If everything is gucci set self::$servers
|
|
|
|
self::$servers = $servers;
|
|
|
|
}
|
|
|
|
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* Query a whois server.
|
|
|
|
*
|
|
|
|
* @param string $address Hostname/IP address
|
|
|
|
*
|
|
|
|
* @return bool|string Whois result.
|
|
|
|
*/
|
2015-09-14 20:51:23 +00:00
|
|
|
public static function query($address)
|
|
|
|
{
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// Call validate to use the right whois type
|
2015-09-14 20:51:23 +00:00
|
|
|
switch (self::validateAddress($address)) {
|
2015-04-18 18:26:52 +00:00
|
|
|
case 1: // validateAddress returns 1 for a domain...
|
|
|
|
return self::lookupDomain($address);
|
|
|
|
|
|
|
|
case 2: // ...and 2 for both IPv4 and IPv6 (should be fine)...
|
|
|
|
return self::lookupIP($address);
|
|
|
|
|
2015-09-14 20:51:23 +00:00
|
|
|
case 0: // ...and 0 in case the type is invalid in which case...
|
2015-04-18 18:26:52 +00:00
|
|
|
default: // ...a false is returned by this function
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* Validate an address.
|
|
|
|
*
|
|
|
|
* @param string $address The address.
|
|
|
|
*
|
|
|
|
* @return int The address type.
|
|
|
|
*/
|
2015-09-14 20:51:23 +00:00
|
|
|
private static function validateAddress($address)
|
|
|
|
{
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// Check if the given address is an IP address
|
2015-09-14 20:51:23 +00:00
|
|
|
if (filter_var($address, FILTER_VALIDATE_IP)) {
|
2015-04-18 18:26:52 +00:00
|
|
|
return 2;
|
2015-09-14 20:51:23 +00:00
|
|
|
}
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// Check if given address is a domain name
|
2015-09-14 20:51:23 +00:00
|
|
|
if (preg_match("/^([-a-z0-9]{2,100})\.([a-z\.]{2,8})$/i", $address)) {
|
2015-04-18 18:26:52 +00:00
|
|
|
return 1;
|
2015-09-14 20:51:23 +00:00
|
|
|
}
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// If unsuccessful return 0
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* Look up a domain.
|
|
|
|
*
|
|
|
|
* @param string $address The address.
|
|
|
|
*
|
|
|
|
* @return string The WHOIS result.
|
|
|
|
*/
|
2015-09-14 20:51:23 +00:00
|
|
|
private static function lookupDomain($address)
|
|
|
|
{
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// Get list of servers
|
|
|
|
$servers = self::$servers['tld'];
|
|
|
|
|
|
|
|
// Break domain up in parts
|
|
|
|
$addressParts = explode(".", $address);
|
|
|
|
|
|
|
|
// Get TLD
|
|
|
|
$tld = strtolower(array_pop($addressParts));
|
|
|
|
|
|
|
|
// Get proper whois server address
|
2015-09-14 20:51:23 +00:00
|
|
|
if (!$server = $servers[$tld]) {
|
2015-09-14 21:41:43 +00:00
|
|
|
return 'Error: No appropriate whois server found for the TLD '
|
|
|
|
. $tld
|
|
|
|
. ', check if the given address is correct.';
|
2015-09-14 20:51:23 +00:00
|
|
|
}
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// Get results from whois server
|
2015-09-14 20:51:23 +00:00
|
|
|
if (!$result = self::queryWhois($server, $address)) {
|
2015-04-18 18:26:52 +00:00
|
|
|
// Return an error if there's no results were retrieved.
|
2015-09-14 20:51:23 +00:00
|
|
|
return 'Error: No results retrieved from ' . $server . ' for ' . $address . '.';
|
2015-04-18 18:26:52 +00:00
|
|
|
} else {
|
|
|
|
// Assign result with heading text to return variable
|
2015-09-14 20:51:23 +00:00
|
|
|
$return = $address . " domain lookup results from " . $server . ":\r\n\r\n" . $result;
|
2015-04-18 18:26:52 +00:00
|
|
|
|
2015-09-14 20:51:23 +00:00
|
|
|
// Check if there's a secondary whois server
|
|
|
|
while (strpos($result, "Whois Server:") !== false) {
|
2015-04-18 18:26:52 +00:00
|
|
|
preg_match("/Whois Server: (.*)/", $return, $matches);
|
|
|
|
|
2015-09-14 20:51:23 +00:00
|
|
|
// If there is call it...
|
|
|
|
if (isset($matches[1])) {
|
2015-04-18 18:26:52 +00:00
|
|
|
$result = self::queryWhois(($server = $matches[1]), $address);
|
|
|
|
|
|
|
|
// ...and append the retrieved values to the return variable
|
2015-09-14 21:41:43 +00:00
|
|
|
$return .= "\r\n-------------\r\n\r\n"
|
|
|
|
. $address
|
|
|
|
. " domain lookup results from "
|
|
|
|
. $server
|
|
|
|
. ":\r\n"
|
|
|
|
. $result;
|
2015-04-18 18:26:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If all is good return the return variable
|
|
|
|
return $return;
|
|
|
|
}
|
|
|
|
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* Look up an IP.
|
|
|
|
*
|
|
|
|
* @param string $address The IP.
|
|
|
|
*
|
|
|
|
* @return string The WHOIS result.
|
|
|
|
*/
|
2015-09-14 20:51:23 +00:00
|
|
|
private static function lookupIP($address)
|
|
|
|
{
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// Get list of servers
|
|
|
|
$servers = self::$servers['ip'];
|
|
|
|
|
|
|
|
// Set variable to keep results in
|
2015-10-18 19:06:30 +00:00
|
|
|
$results = [];
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// Query servers
|
2015-09-14 20:51:23 +00:00
|
|
|
foreach ($servers as $server) {
|
2015-04-18 18:26:52 +00:00
|
|
|
// Get results
|
|
|
|
$result = self::queryWhois($server, $address);
|
|
|
|
|
|
|
|
// Assign result to results array if not in it yet
|
2015-09-14 20:51:23 +00:00
|
|
|
if ($result && !in_array($result, $results)) {
|
2015-04-18 18:26:52 +00:00
|
|
|
$results[$server] = $result;
|
2015-09-14 20:51:23 +00:00
|
|
|
}
|
2015-04-18 18:26:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Create variable to keep return value
|
2015-09-14 20:51:23 +00:00
|
|
|
$return = "RESULTS FOUND: " . count($results);
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// Append results
|
2015-09-14 20:51:23 +00:00
|
|
|
foreach ($results as $server => $result) {
|
2015-04-18 18:26:52 +00:00
|
|
|
$return .= "\r\n\r\n-------------"
|
2015-09-14 20:51:23 +00:00
|
|
|
. "\r\nLookup results for "
|
|
|
|
. $address
|
|
|
|
. " from "
|
|
|
|
. $server
|
|
|
|
. " server:\r\n\r\n"
|
|
|
|
. $result;
|
2015-04-18 18:26:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return results
|
|
|
|
return $return;
|
|
|
|
}
|
|
|
|
|
2016-02-02 21:04:15 +00:00
|
|
|
/**
|
|
|
|
* Query a whois server.
|
|
|
|
*
|
|
|
|
* @param mixed $server The WHOIS server.
|
|
|
|
* @param mixed $address The address that should WHOIS'd.
|
|
|
|
* @param mixed $port The WHOIS server port.
|
|
|
|
* @param mixed $timeout The request timeout.
|
|
|
|
*
|
|
|
|
* @return null|string The WHOIS result.
|
|
|
|
*/
|
2015-09-14 20:51:23 +00:00
|
|
|
private static function queryWhois($server, $address, $port = 43, $timeout = 10)
|
|
|
|
{
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// Open socket
|
2015-09-14 21:41:43 +00:00
|
|
|
$query = @fsockopen(
|
|
|
|
$server,
|
|
|
|
$port,
|
|
|
|
$errno,
|
|
|
|
$errstr,
|
|
|
|
$timeout
|
|
|
|
) or trigger_error(
|
|
|
|
'Failed to open socket: '
|
|
|
|
. $errno
|
|
|
|
. ' - '
|
|
|
|
. $errstr,
|
|
|
|
E_USER_ERROR
|
|
|
|
);
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// Send address
|
2015-09-14 20:51:23 +00:00
|
|
|
fputs($query, $address . "\r\n");
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// Await output
|
|
|
|
$out = null;
|
2015-09-14 20:51:23 +00:00
|
|
|
while (!feof($query)) {
|
2015-04-18 18:26:52 +00:00
|
|
|
$out .= fgets($query);
|
2015-09-14 20:51:23 +00:00
|
|
|
}
|
2015-04-18 18:26:52 +00:00
|
|
|
|
|
|
|
// Close socket
|
|
|
|
fclose($query);
|
|
|
|
|
2015-09-14 20:51:23 +00:00
|
|
|
// Return results
|
2015-04-18 18:26:52 +00:00
|
|
|
return $out;
|
|
|
|
}
|
|
|
|
}
|