initial move to git (subversion history dropped intentionally)
This commit is contained in:
54
lib/whois.php
Normal file
54
lib/whois.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<html>
|
||||
<body>
|
||||
<form target="<? echo $PHP_SELF; ?>" method="POST">
|
||||
Domain: <input type="text" name="domain" value="<? echo $_POST["domain"] ?>">
|
||||
<input type="submit" value="Lookup">
|
||||
</form>
|
||||
<?
|
||||
if(isset($_POST["domain"]) && !empty($_POST["domain"])) {
|
||||
$neutralnameserver = "toffee.snt.utwente.nl";
|
||||
require_once("zonecheck.class.php");
|
||||
|
||||
$domainname = $_POST["domain"];
|
||||
echo "<h1>Whois records for $domainname</h1>";
|
||||
$zonecheck = checkzone($domainname, true, false);
|
||||
|
||||
?>
|
||||
<table border=1 cellspacing=0 cellpadding=4>
|
||||
<tr><td valign=top><h2>Raw output</h2><pre>
|
||||
<?
|
||||
for($i=0; $i<count($zonecheck->info); $i++) {
|
||||
echo $zonecheck->info[$i]."\n";
|
||||
}
|
||||
?>
|
||||
</pre></td><td valign=top><h2>Parsed output</h2>
|
||||
<?
|
||||
echo "<h3>Domain name</h3>";
|
||||
echo "<pre>".$zonecheck->parseddomain."</pre>";
|
||||
echo "<h3>Domain holder</h3>";
|
||||
echo "<pre>".$zonecheck->registrant."</pre>";
|
||||
echo "<h3>Admin contact</h3>";
|
||||
echo "<pre>".$zonecheck->admincontact."</pre>";
|
||||
echo "<h3>Tech contact</h3>";
|
||||
echo "<pre>".$zonecheck->techcontact."</pre>";
|
||||
echo "<h3>Nameservers</h3>";
|
||||
echo "<pre>";
|
||||
for($i=0; $i<count($zonecheck->ns); $i++) {
|
||||
echo $zonecheck->ns[$i]."\n";
|
||||
}
|
||||
echo "</pre>";
|
||||
echo "<h3>Registrar</h3>";
|
||||
echo "<pre>".$zonecheck->registrar."</pre>";
|
||||
echo "<h3>Service provider</h3>";
|
||||
echo "<pre>".$zonecheck->rsp."</pre>";
|
||||
?>
|
||||
<hr><h3>Unparsed data</h3>
|
||||
<pre>
|
||||
<?
|
||||
var_dump($zonecheck->meta);
|
||||
?>
|
||||
</pre></td></tr>
|
||||
</table>
|
||||
<?
|
||||
} // if domain was posted
|
||||
?>
|
||||
327
lib/zonecheck.class.php
Normal file
327
lib/zonecheck.class.php
Normal file
@@ -0,0 +1,327 @@
|
||||
<?
|
||||
/* Okay so all those whois scripts don't really do much usefull */
|
||||
/* Let's do it ourselves once more *sigh* */
|
||||
|
||||
define(CACHEDIR,"/home/florian/apps/safe/cache"); /* Must be writeable for webserver */
|
||||
define(CACHEEXPIRE,86400); /* 24 hours cache time */
|
||||
define(NSSERVER,"ns1.snt.utwente.nl"); /* Must allow queries from here */
|
||||
|
||||
/* Simple wrapper function that creates or reuses a zonecheck object */
|
||||
function checkzone($domain, $usecache=true) {
|
||||
global $checkzone_obj;
|
||||
if(empty($checkzone_obj)) {
|
||||
$checkzone_obj = new zonecheck($domain, $usecache, $debug);
|
||||
} else {
|
||||
$checkzone_obj->lookup($domain, $usecache);
|
||||
}
|
||||
return $checkzone_obj;
|
||||
} // End of function checkzone
|
||||
|
||||
// This works similar to array_intersect_key, but uses regexps in the second array
|
||||
// I initially used array_intersect_ukey with a callback function, but
|
||||
// for some reason that was behaving erroneously
|
||||
function array_intersect_ekey($haystack, $needles) {
|
||||
foreach($haystack as $payload => $value) {
|
||||
// Test this twig against the regexps in $needles
|
||||
foreach($needles as $pattern => $noop) {
|
||||
$matches = preg_match($pattern, $payload);
|
||||
if($matches == 1) {
|
||||
$intersect[$payload] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(empty($intersect)) $intersect = array();
|
||||
return $intersect;
|
||||
} // End of function array_intersect_ekey
|
||||
|
||||
function get_array_intersect_entry($haystack, $needles) {
|
||||
$intersect = array_intersect_ekey($haystack, $needles);
|
||||
//$entry = current(array_values($intersect));
|
||||
foreach($intersect as $member) {
|
||||
foreach($member as $particle) {
|
||||
$entry[] = $particle;
|
||||
}
|
||||
}
|
||||
if(empty($entry)) {
|
||||
$entry = array();
|
||||
}
|
||||
return $entry;
|
||||
}
|
||||
|
||||
// Test purposes only
|
||||
if(false) {
|
||||
$pattern = "/^Technical Contact (?!ID).+$/";
|
||||
$payload = "Technical Contact Pass ID";
|
||||
echo "$pattern <-> $payload == ";
|
||||
echo preg_match($pattern, $payload);
|
||||
die;
|
||||
}
|
||||
|
||||
/* Class zonecheck */
|
||||
class zonecheck {
|
||||
var $domain;
|
||||
var $debug;
|
||||
var $tld;
|
||||
var $info = array();
|
||||
var $meta = array();
|
||||
var $ns = array();
|
||||
var $parseddomain;
|
||||
var $registrar;
|
||||
var $rsp;
|
||||
var $registrant;
|
||||
var $admincontact;
|
||||
var $techcontact;
|
||||
var $ns_ns = array();
|
||||
var $ns_mx = array();
|
||||
|
||||
// Definition of array matrices to intercept keys
|
||||
// This array has all tokens that we have seen to contain domain name data
|
||||
var $tokens_domain = array(
|
||||
"/^Domain$/" => 0,
|
||||
"/^Domain name$/i" => 0,
|
||||
"/^Domain Name \(ASCII\)$/i" => 0);
|
||||
// This array has all tokens that we have seen to contain nameserver data
|
||||
var $tokens_ns = array(
|
||||
"/^Domain nameservers$/" => 0,
|
||||
"/^Domain servers in listed order$/" => 0,
|
||||
"/^Nserver$/" => 0,
|
||||
"/^Nameserver(s)?$/" => 0,
|
||||
"/^Name Server$/" => 0);
|
||||
// This array has all tokens that we have seen to contain registrant data
|
||||
var $tokens_registrant = array(
|
||||
"/^Registrars\.Registrant$/" => 0,
|
||||
"/^Registrant (?!ID).+$/" => 0,
|
||||
"/^Holder (?!ID).+$/" => 0,
|
||||
"/^Registrant$/" => 0);
|
||||
// This array has all tokens that we have seen to contain registrar data
|
||||
var $tokens_registrar = array(
|
||||
"/^Sponsoring Registrar$/" => 0,
|
||||
"/^Zone-C (?!ID).+$/" => 0,
|
||||
"/^Registrar$/" => 0);
|
||||
// This array has all tokens that we have seen to contain admin contact data
|
||||
var $tokens_admincontact = array(
|
||||
"/^Administrative Contact (?!ID).+$/" => 0,
|
||||
"/^Administrative Contact,/" => 0,
|
||||
"/^Admin(-C)? (?!ID).+$/" => 0,
|
||||
"/^Administrative Contact$/i" => 0);
|
||||
// This array has all tokens that we have seen to contain tech contact data
|
||||
var $tokens_techcontact = array(
|
||||
"/^Technical Contact,/" => 0,
|
||||
"/^.+Technical Contact$/" => 0,
|
||||
"/^Technical Contact (?!ID).+$/" => 0,
|
||||
"/^Tech(-C)? (?!ID).+$/" => 0,
|
||||
"/^Technical contact(?:\(s\))?$/i" => 0);
|
||||
// This array has all tokens that we have seen to contain rsp data
|
||||
var $tokens_rsp = array(
|
||||
"/^Registration Service Provider$/" => 0);
|
||||
|
||||
// Constructor
|
||||
function zonecheck($domainname, $usecache=true, $debug=false) {
|
||||
$this->debug = $debug;
|
||||
return $this->lookup($domainname, $usecache, $debug);
|
||||
} // End function zonecheck (Constructor)
|
||||
|
||||
function debug($debugtext) {
|
||||
if($this->debug) echo $this->domain.": ".$debugtext."\n";
|
||||
} // End of function debug
|
||||
|
||||
function lookup($domainname, $usecache=true, $debug=false) {
|
||||
$this->debug = $debug;
|
||||
$this->domain = $domainname;
|
||||
$this->tld = substr($this->domain, strrpos($this->domain, "."));
|
||||
$this->info = array();
|
||||
$this->meta = array();
|
||||
$this->ns = array();
|
||||
$this->parseddomain = "";
|
||||
$this->registrar = "";
|
||||
$this->rsp = "";
|
||||
$this->registrant = "";
|
||||
$this->admincontact = "";
|
||||
$this->techcontact = "";
|
||||
$this->ns_ns = array();
|
||||
$this->ns_mx = array();
|
||||
|
||||
// Check cache
|
||||
$cached = false;
|
||||
$cachefilename = CACHEDIR."/".$domainname.".txt";
|
||||
if($usecache) {
|
||||
if(file_exists($cachefilename)) {
|
||||
$this->debug("found cached in file $cachefilename");
|
||||
if((time()-filemtime($cachefilename)) < CACHEEXPIRE) {
|
||||
$this->debug("accepted cached file $cachefilename");
|
||||
$this->info = file($cachefilename);
|
||||
$cached = true;
|
||||
} else {
|
||||
$this->debug("expired cached file $cachefilename");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->debug("cache not used by request");
|
||||
}
|
||||
|
||||
if(!$cached) {
|
||||
$this->debug("performing whois query");
|
||||
// Get the raw data
|
||||
$args = "";
|
||||
switch($this->tld) {
|
||||
case ".me": $args = "-h whois.nic.me"; break;
|
||||
}
|
||||
$cmd = "whois $args $domainname";
|
||||
$retcode = exec($cmd, $this->info);
|
||||
}
|
||||
|
||||
// Normalize the array and save to cache if needed
|
||||
for($line=0; $line<count($this->info); $line++) {
|
||||
$this->info[$line] = trim($this->info[$line]);
|
||||
}
|
||||
if(!$cached && is_writable(CACHEDIR)) {
|
||||
$cachefp = fopen($cachefilename, 'w');
|
||||
if($cachefp !== false) {
|
||||
for($line=0; $line<count($this->info); $line++) {
|
||||
fwrite($cachefp, $this->info[$line]."\r\n");
|
||||
}
|
||||
fclose($cachefp);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse more intelligent stuff
|
||||
$this->enkey_data();
|
||||
$this->compose_members();
|
||||
$this->extract_registrar();
|
||||
$this->extract_domainname();
|
||||
$this->extract_nameservers();
|
||||
$this->extract_registrant();
|
||||
$this->extract_admincontact();
|
||||
$this->extract_techcontact();
|
||||
$this->extract_rsp();
|
||||
$this->nslookup();
|
||||
} // End function lookup
|
||||
|
||||
function enkey_data() {
|
||||
$key = "general";
|
||||
$initoken = "";
|
||||
$this->debug("building key/value array");
|
||||
// Basically a simple state machine that parses the whois output
|
||||
for($line=0; $line<count($this->info); $line++) {
|
||||
// Check if this is an INI-style whois line
|
||||
if((substr($this->info[$line],0,1) == "[") && (substr($this->info[$line],-1,1) == "]")) {
|
||||
// INI-style formatting found (like .de domain)
|
||||
$initoken = substr($this->info[$line],1,strlen($this->info[$line])-2);
|
||||
}
|
||||
|
||||
// Locate the first : in line
|
||||
$tokenpos = strpos($this->info[$line], ":");
|
||||
|
||||
if($tokenpos !== false) {
|
||||
// Don't count it if it is part of something generic
|
||||
$contextpos = strpos($this->info[$line], "http://");
|
||||
if($contextpos !== false && $contextpos == $tokenpos-4) $tokenpos = false;
|
||||
$contextpos = strpos($this->info[$line], "Last update of whois database:");
|
||||
if($contextpos !== false && $contextpos == $tokenpos-29) $tokenpos = false;
|
||||
$contextpos = strpos($this->info[$line], "to: (1) allow");
|
||||
if($contextpos !== false && $contextpos == $tokenpos-2) $tokenpos = false;
|
||||
$contextpos = strpos($this->info[$line], "terms of use: You agree");
|
||||
if($contextpos !== false && $contextpos == $tokenpos-12) $tokenpos = false;
|
||||
$contextpos = strpos($this->info[$line], "NOTICE: The expiration");
|
||||
if($contextpos !== false && $contextpos == $tokenpos-6) $tokenpos = false;
|
||||
$contextpos = strpos($this->info[$line], "TERMS OF USE: You are not");
|
||||
if($contextpos !== false && $contextpos == $tokenpos-12) $tokenpos = false;
|
||||
$contextpos = strpos($this->info[$line], "NOTE: THE WHOIS DATABASE");
|
||||
if($contextpos !== false && $contextpos == $tokenpos-4) $tokenpos = false;
|
||||
$contextpos = strpos($this->info[$line], "under no circumstances will you use this data to:");
|
||||
if($contextpos !== false && $contextpos == $tokenpos-48) $tokenpos = false;
|
||||
$contextpos = strpos($this->info[$line], "% Version: ");
|
||||
if($contextpos !== false && $contextpos == $tokenpos-9) $tokenpos = false;
|
||||
}
|
||||
|
||||
// Split key/value pairs
|
||||
if($tokenpos === false) {
|
||||
// No key in this line, so use the previous key
|
||||
$value = trim($this->info[$line]);
|
||||
if($value == "") {
|
||||
// Empty lines reset the key and inittoken
|
||||
$key = "general";
|
||||
$initoken = "";
|
||||
} else {
|
||||
$this->meta[$key][] = $value;
|
||||
}
|
||||
} else {
|
||||
// Key in line, so split the parts
|
||||
$key = trim(substr($this->info[$line], 0, strpos($this->info[$line], ":")));
|
||||
if($initoken != "") $key = "$initoken $key";
|
||||
$value = trim(substr($this->info[$line], strpos($this->info[$line], ":")+1));
|
||||
if($value != "") {
|
||||
// Don't care about superfluous empty lines
|
||||
$this->meta[$key][] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Clean up metadata we really don't need again
|
||||
unset($this->meta["general"]);
|
||||
} // End function build_array
|
||||
|
||||
function compose_members() {
|
||||
// For .info:
|
||||
switch($this->tld) {
|
||||
case ".info":
|
||||
$this->meta["Registrant"][] = $this->meta["Registrant ID"];
|
||||
$this->meta["Registrant"][] = $this->meta["Registrant Name"];
|
||||
$this->meta["Registrant"][] = $this->meta["Registrant Organisation"];
|
||||
$this->meta["Registrant"][] = $this->meta["Registrant Address1"];
|
||||
$this->meta["Administrative Contact"][] = $this->meta["Administrative Contact ID"];
|
||||
$this->meta["Administrative Contact"][] = $this->meta["Administrative Contact Name"];
|
||||
}
|
||||
}
|
||||
|
||||
function extract_nameservers() {
|
||||
$this->debug("locating nameserver info");
|
||||
$this->ns=get_array_intersect_entry($this->meta, $this->tokens_ns);
|
||||
for($i=0; $i<count($this->ns); $i++) {
|
||||
if(strpos($this->ns[$i], " ") !== false) {
|
||||
$this->ns[$i] = substr($this->ns[$i], 0, strpos($this->ns[$i], " "));
|
||||
}
|
||||
}
|
||||
sort($this->ns);
|
||||
} // End function extract_nameservers
|
||||
|
||||
function extract_registrant() {
|
||||
$this->debug("locating registrant info");
|
||||
$this->registrant=implode("\n", get_array_intersect_entry($this->meta, $this->tokens_registrant));
|
||||
} // End function extract_registrant
|
||||
|
||||
function extract_admincontact() {
|
||||
$this->debug("locating admin contact info");
|
||||
$this->admincontact=implode("\n", get_array_intersect_entry($this->meta, $this->tokens_admincontact));
|
||||
} // End function extract_admincontact
|
||||
|
||||
function extract_techcontact() {
|
||||
$this->debug("locating tech contact info");
|
||||
$this->techcontact=implode("\n", get_array_intersect_entry($this->meta, $this->tokens_techcontact));
|
||||
} // End function extract_techcontact
|
||||
|
||||
function extract_domainname() {
|
||||
$this->debug("locating domainname info");
|
||||
$this->parseddomain=implode("\n", array_unique(get_array_intersect_entry($this->meta, $this->tokens_domain)));
|
||||
} // End function extract_domainname
|
||||
|
||||
function extract_registrar() {
|
||||
$this->debug("locating registrar info");
|
||||
$this->registrar=implode("\n", get_array_intersect_entry($this->meta, $this->tokens_registrar));
|
||||
} // End function extract_registrar
|
||||
|
||||
function extract_rsp() {
|
||||
$this->debug("locating registration service provider info");
|
||||
$this->rsp=implode("\n", get_array_intersect_entry($this->meta, $this->tokens_rsp));
|
||||
} // End function extract_rsp
|
||||
|
||||
function nslookup() {
|
||||
// $ttl = array();
|
||||
// $ns = array();
|
||||
$this->ns_mx = dns_get_record($this->domain, DNS_MX, $ns, $ttl);
|
||||
echo "<pre>";
|
||||
var_dump($ns);
|
||||
var_dump($this->ns_mx);
|
||||
echo "</pre>";
|
||||
} // End function nslookup_ns
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user