<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
 * MD5 hash lookup script that returns XML
 *
 * written by Ben Ramsey (ben at benramsey dot com)
 * with code by Ilia Alshanetsky (ilia at ilia dot ws)
 *
 * Copyright (c) 2005, Ilia Alshanetsky
 * Copyright (c) 2005, Ben Ramsey
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *    * Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the name of the XSSOOPS nor the names of its
 *      contributors may be used to endorse or promote products derived from
 *      this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

ini_set('include_path''.:/home/bramsey/local/pear/php:/usr/local/php5/lib/php:/usr/local/lib/php');

require_once 
'HTTP/Request.php';

/* MD5 databases we're using; corresponds to a function name */
$md5_stores = array(
    
'rednoize',   // md5.rednoize.com
    
'schwett',    // www.schwett.com
    
'crysm_us',   // us.md5.crysm.net
    
'crysm_nz',   // nz.md5.crysm.net
    
'gdata'       // gdataonline.com
);

/* Provides escaping for output to XML */
function escape_xml($input)
{
    
$output  '<![CDATA[';
    
$output .= $input;
    
$output .= ']]>';

    return 
$output;
}

/* md5.rednoize.com */
function md5_rednoize($str)
{
    
$xml simplexml_load_file("http://md5.rednoize.com/?q={$str}&xml");

    
$string = (string) $xml->ResultString;

    if (
strlen($string) > 0)
    {
        return 
$string;
    }
}

/* www.schwett.com */
function md5_schwett($str)
{
    
$xml simplexml_load_file("http://www.schwett.com/md5/xml.php?hash={$str}");

    
$string = (string) $xml->password->cleantext;

    if (
strlen($string) > 0)
    {
        return 
$string;
    }
}

/* us.md5.crysm.net */
function md5_crysm_us($str)
{
    
$data '';
    
$req =& new HTTP_Request("http://us.md5.crysm.net/find?md5={$str}");

    if (!
PEAR::isError($req->sendRequest()))
    {
        
$data $req->getResponseBody();
    }

    if (
preg_match('!<li>(.*?)</li>!'$data$m))
    {
        return 
$m[1];
    }
}

/* nz.md5.crysm.net */
function md5_crysm_nz($str)
{
    
$data '';
    
$req =& new HTTP_Request("http://nz.md5.crysm.net/find?md5={$str}");

    if (!
PEAR::isError($req->sendRequest()))
    {
        
$data $req->getResponseBody();
    }

    if (
preg_match('!<li>(.*?)</li>!'$data$m))
    {
        return 
$m[1];
    }
}

/* gdataonline.com */
function md5_gdata($str)
{
    
$data '';

    if (!empty(
$_SERVER['HTTP_USER_AGENT']))
    {
        
$ua strtr($_SERVER['HTTP_USER_AGENT'], "\r\n"'  '); /* CRLF protection */
    
}
    else
    {
        
$ua 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.8) Gecko/20050511 Firefox/1.0.4';
    }

    
$req =& new HTTP_Request('http://gdataonline.com/seekhash.php');
    
$req->setMethod(HTTP_REQUEST_METHOD_POST);
    
$req->addHeader('User-Agent'$ua);
    
$req->addHeader('Referer''http://gdataonline.com/seekhash.php');
    
$req->addPostData('hash'$str);

    if (!
PEAR::isError($req->sendRequest()))
    {
        
$data $req->getResponseBody();
    }

    if (
preg_match('!<td width="35%"><b>(.*?)</b></td>!'$data$m))
    {
        return 
trim($m[1], '?');
    }
}


/* Start processing the request */
$clean = array();
$url   = array();
$xml   = array();

/* Ensure the hash is exactly 32 alpha-numeric characters */
if (strlen($_GET['hash']) == 32 && ctype_alnum($_GET['hash']))
{
    
$clean['hash'] = $_GET['hash'];
}
else
{
    
$xml['error'] = escape_xml('The string provided is not a true MD5 hash. Please try again.');
}

/* Perform the MD5 hash lookup */
if (isset($clean['hash']))
{
    
$url['hash'] = urlencode($clean['hash']);

    
$string NULL;

    
/* Iterate through the MD5 stores to find a value for the hash */
    
foreach ($md5_stores as $store)
    {
        
$f "md5_{$store}";
        if ((
$string $f($url['hash'])))
        {
            break;
        }
    }

    if (
strlen($string) > && ctype_print($string))
    {
        
$clean['string'] = $string;
    }
    else
    {
        
$xml['error'] = escape_xml('No value in MD5 database for this hash.');
    }
}

/* Prepare data for output */
if (isset($clean['hash']))
{
    
$xml['hash'] = escape_xml($clean['hash']);
}

if (isset(
$clean['string']))
{
    
$xml['string'] = escape_xml($clean['string']);
}

/* Set content type to text/xml for output */
header('Content-type: text/xml');
echo 
'<?xml version="1.0" encoding="UTF-8"?>' "\n";
?>
<md5lookup>
<?php if (isset($xml['error'])): ?>
    <error><?php echo $xml['error']; ?></error>
<?php else: ?>
    <hash><?php echo $xml['hash']; ?></hash>
    <string><?php echo $xml['string']; ?></string>
<?php endif; ?>
</md5lookup>