You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

355 lines
9.4 KiB

<?php
/**
* Plugin Univers SPIP
* (c) 2010 Cedric
* Distribue sous licence GPL
*/
// User agent used to load the page
@define(
'_INC_DISTANT_USER_AGENT',
'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; fr; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9'
);
@define('_INC_DISTANT_VERSION_HTTP', 'HTTP/1.0');
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
include_spip('inc/filtres');
include_spip('inc/distant');
include_spip('inc/meta');
/**
* Get the complete page.
* Should be sub.something.tld/spip.php
*
* Some site set a cookie then redirect before everything else
* so we have to accept it
*
* @param string $url
* @param string $cookie
*
*/
function univers_recuperer_lapage($url, $cookie = '') {
$ref = $GLOBALS['meta']['adresse_site'];
// let's say we're coming from google, after all...
$GLOBALS['meta']['adresse_site'] = 'http://www.google.fr';
$datas = ''
."Cookie: $cookie\r\n"
."\r\n"
;
$site = $url;
$max_redir = 10;
while ($site and is_string($site) and $max_redir--) {
$url = $site;
$site = recuperer_lapage($url, false, 'GET', 1048576, $datas);
}
$GLOBALS['meta']['adresse_site'] = $ref;
if (!$site) {
return $site;
}
if (is_string($site) and !$max_redir) {
return false;
}
list($header, $page) = $site;
// if a cookie set, accept it an retry with it
if (preg_match(',Set-Cookie: (.*)(;.*)?$,Uims', $header, $r)) {
//ne pas relancer si le cookie est déjà présent
if (strpos($cookie, $r[1])===false) {
$cookie .= $r[1] . ';';
spip_log("Cookie : $cookie on repart pour un tour ", 'univers_check');
return univers_recuperer_lapage($url, $cookie);
}
}
return $site;
}
/**
* Get address by host.
* Use nslookup instead of php function
*
* @param string $host
* @param int $timeout
* @return string
*/
function univers_getaddrbyhost($host, $timeout = 3) {
$ip = gethostbyname($host);
if ($ip and $ip !== $host) {
return $ip;
}
if (is_callable('shell_exec') && false === stripos(ini_get('disable_functions'), 'shell_exec')) {
$query = `nslookup -timeout=$timeout -retry=1 $host`;
if (preg_match('/\nAddress: (.*)\n/', $query, $matches)) {
return trim($matches[1]);
}
}
return $host;
}
/**
* Analyse a site to check it's made with SPIP and find versions and plugins
*
* @param string $url
* @param bool $debug
* @return boolean|array false ou un tableau de donnees
*/
function univers_analyser($url, $debug = false) {
$res = array();
spip_log("analyse version : $url ", 'univers_check');
$path = parse_url($url);
$ip = univers_getaddrbyhost($path['host']);
if (!$ip or $ip == $path['host']) {
return false; // pas d'ip, pas de site, rien a faire
}
$res['ip'] = $ip;
// get the complete page
$site = univers_recuperer_lapage($url);
if (!$site) {
$res['response'] = false;
return $res;
}
list($header, $page) = $site;
if ($debug) {
var_dump($header);
}
// get some generic informations (server, php, gzip, length)
if (preg_match(',Server: (.*)$,m', $header, $r)) {
$res['server'] = $r[1];
}
if (preg_match(',X-Powered-By: PHP/(.+)$,m', $header, $r)) {
$res['php'] = $r[1];
}
if (preg_match(',Content-Encoding: gzip$,m', $header)) {
$res['gzip'] = true;
}
if (preg_match(',Content-Length: ([0-9]+)$,m', $header, $r)) {
$res['length'] = $r[1];
}
// check if the header says "Hey, i'm made with SPIP"
$regexp_plugin_spip = ',Composed-By: (?:.*)\+ (?<plugins>spip\((?<spip>[^)]+)\)(.*)?)$,m';
$regexp_generique = ',Composed-By: (?<spip>.*)( @ www.spip.net)( ?\+ ?(?<plugins>.*))?$,m';
if (
preg_match($regexp_plugin_spip, $header, $r)
or preg_match($regexp_generique, $header, $r)
) {
// essayer de choper local/config.txt si il est la car plus complet si le header semble coupe
if (substr($header, -1)!==')') {
$url_config = suivre_lien($url, 'local/config.txt');
$config = univers_recuperer_lapage($url_config);
if (!$config) {
$url_mutu = str_replace('ww2.', '', str_replace('www.', '', $path['host']));
$url_config = suivre_lien($url, "sites/$url_mutu/local/config.txt");
$config = univers_recuperer_lapage($url_config);
}
if ($config) {
if (
preg_match($regexp_plugin_spip, $config[1], $rc)
or preg_match($regexp_generique, $config[1], $rc)
) {
$r = $rc;
}
}
}
$res['spip'] = trim(preg_replace(',^[^0-9]*,', '', $r['spip']));
if (!$res['spip']) {
$res['spip'] = '?';
}
$res['plugins'] = array();
if ($p = array_filter(explode(',', $r['plugins']))) {
foreach ($p as $plugin) {
$plugin = trim($plugin);
$res['plugins'][preg_replace(',[(].*,', '', $plugin)] = $plugin;
}
}
}
// else, find another clue
// if 'spip_' is in the html, there are some chance that it is a SPIP site
if (!isset($res['spip'])) {
if (preg_match(',spip_(in|out|logo),i', $page)) {
$res['spip'] = '?';
}
}
// if maybe but not sure, try to get the login page
// it should have some information that says "SPIP"
if (isset($res['spip']) and $res['spip'] === '?') {
// recuperer la page de login
$login = preg_replace(',spip[.]php.*$,', '', $url).'ecrire/';
if ($login = univers_recuperer_lapage($login)) {
list(, $login) = $login;
if (preg_match(',<meta name=[\'"]generator["\'][^>]*>,Uims', $login, $r)
and $v = extraire_attribut($r[0], 'content')
and preg_match(',SPIP ([^\[]+),', $v, $r)) {
$res['spip'] = trim($r[1]);
}
}
}
// if we did'nt found login page, or there whas no information
// try to get the htaccess.txt delivered with SPIP,
// it has some extra informations
if (isset($res['spip']) and $res['spip'] === '?') {
// tenter de recup le htaccess.txt qui contient un numero de version
$ht = preg_replace(',spip[.]php.*$,', '', $url).'htaccess.txt';
if ($ht = univers_recuperer_lapage($ht)) {
list(, $htpage) = $ht;
if (preg_match(',SPIP v\s*([0-9.]+),', $htpage, $r)) {
$res['spip'] = $r[1];
}
}
// if we didn't found a confirmation and there was only 'spip' in the html
// maybe it's an old spip site, but it’s no more a SPIP now.
if ($res['spip'] === '?') {
unset($res['spip']);
}
}
// if it is a 404, that was a bad adress
if (count($res)==1 and preg_match(',404 ,', $header)) {
$res['response'] = '404';
} else {
// else record the page size and so on
$res['size'] = strlen($page);
$res['response'] = true;
if (
false !== stripos($page, 'Fatal error')
and false !== stripos($page, 'Call to undefined function')
) {
$res['response'] = 'fatal';
}
if (preg_match(',<title>(.*)</title>,Uims', $page, $r)) {
$res['title'] = $r[1];
}
if (preg_match(',<meta name=[\'"]description["\'][^>]*>,Uims', $page, $r)) {
$res['description'] = extraire_attribut($r[0], 'content');
}
}
return $res;
}
/**
* Take one record to check in database, and process it.
*
* @param array $row The row
* @param boolean $debug The debug mode for the exec web page
*/
function univers_analyser_un($row, $debug = false) {
if ($debug) {
var_dump($row);
}
$id = $row['id_website'];
$url = $row['url'];
// incrementer le retry et la date avant tout pour ne pas tourner en rond
// sur ce site si il timeout
sql_updateq(
'spip_websites',
array('retry' => $row['retry']+1, 'date' => date('Y-m-d H:i:s'), 'status' => 'timeout?'),
'id_website='.intval($id)
);
$res = univers_analyser($url, $debug);
if ($debug) {
var_dump($res);
}
$set = array();
if ($res===false) {
$set['retry'] = ++$row['retry'];
$set['status'] = 'no-dns';
} elseif (
$res['response']===false
or $res['response']==='404'
or $res['response']==='fatal'
) {
$set['ip'] = $res['ip'];
$set['retry'] = ++$row['retry'];
$set['status'] = ($res['response']?$res['response']:'dead');
} elseif ($res['response']===true) {
$set['ip'] = $res['ip'];
$set['server'] = !empty($res['server'])?$res['server']:'';
$set['php'] = !empty($res['php'])?$res['php']:'';
$set['gzip'] = !empty($res['gzip'])?'oui':'';
$set['length'] = !empty($res['length'])?$res['length']:0;
$set['size'] = !empty($res['size'])?$res['size']:0;
if (isset($res['spip'])) {
$set['pays'] = univers_geoip($set['ip']);
// c'estun SPIP !
$set['spip'] = $res['spip'];
$set['statut'] = 'publie';
if ($res['title']) {
$set['titre'] = $res['title'];
}
if ($res['description']) {
$set['descriptif'] = $res['description'];
}
$set['plugins'] = count($res['plugins']);
// mettre a jour les plugins
sql_delete('spip_websites_plugins', 'id_website='.intval($id));
if (is_array($res['plugins'])) {
foreach ($res['plugins'] as $p => $v) {
sql_insertq('spip_websites_plugins', array('id_website'=>$id,'plugin'=>$p,'version'=>$v));
}
}
if ($debug) {
var_dump(univers_geoip($set['ip']));
}
} else {
// c'en est pas un !
$set['statut'] = 'refuse';
}
$set['status'] = '';
$set['retry'] = 0;
} else {
// ???
$set['retry'] = ++$row['retry'];
$set['status'] = $res['response'];
}
$set['date'] = date('Y-m-d H:i:s');
if ($debug) {
var_dump($set);
}
sql_updateq('spip_websites', $set, 'id_website='.intval($id));
}
/**
* Find state information from IP adress with GeoIP tool
*
* @staticvar string $gi
* @param string $ip
* @return string
*/
function univers_geoip($ip = null) {
static $gi = null;
if (is_null($ip)) {
include_spip('geoip/geoip');
geoip_close($gi);
return;
}
if (is_null($gi)) {
include_spip('geoip/geoip');
$gi = geoip_open(find_in_path('geoip/GeoIP.dat'), GEOIP_STANDARD);
}
return geoip_country_code_by_addr($gi, $ip);
}