From 1135eca961b9e2b4deb1ff6a17adebaf7e8f889f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Fri, 5 Mar 2010 13:58:40 +0000 Subject: [PATCH] Network added, SVN fixed, misc: - Network AllAds4You partly added - Missing SVN properties added - Caching DNS resolver added (not yet configurable) - 2 typos fixed (thanks to R. Z.) - Misc fixes --- .gitattributes | 1 + inc/classes/resolver.class.php | 129 ++ inc/extensions/ext-network.php | 2020 +++++++++-------- inc/extensions/ext-repair.php | 2 +- inc/extensions/ext-sql_patches.php | 42 +- inc/extensions/ext-validator.php | 6 +- inc/filters.php | 17 + inc/functions.php | 93 +- inc/language/repair_de.php | 2 +- inc/language/validator_de.php | 6 +- inc/modules/admin/what-config_validator.php | 6 +- inc/modules/admin/what-repair_cats.php | 2 +- inc/wrapper-functions.php | 3 +- .../de/html/admin/admin_update_download.tpl | 2 +- 14 files changed, 1276 insertions(+), 1055 deletions(-) create mode 100644 inc/classes/resolver.class.php diff --git a/.gitattributes b/.gitattributes index 247c935f3d..0760a985ff 100644 --- a/.gitattributes +++ b/.gitattributes @@ -103,6 +103,7 @@ inc/cache/_compiled/html/.htaccess -text inc/classes/.htaccess -text inc/classes/cachesystem.class.php -text inc/classes/rdf.class.php -text +inc/classes/resolver.class.php -text inc/config-functions.php -text inc/config-global.php -text inc/config-local.php.dist -text diff --git a/inc/classes/resolver.class.php b/inc/classes/resolver.class.php new file mode 100644 index 0000000000..1010e2283c --- /dev/null +++ b/inc/classes/resolver.class.php @@ -0,0 +1,129 @@ + IP address resolving +class HostnameResolver { + // Resolve hostname -> IP address + function resolveHostname ($hostname) { + // If sql_patches is not at least 0.7.0, abort here and return the hostname (gethostbyname() may return something unwanted) + if (!isExtensionInstalledAndNewer('sql_patches', '0.7.0')) { + // Abort here + return $hostname; + } // END - if + + // Prepare hostname, look for :port + $hostArray = explode(':', strtolower($hostname), 2); + $hostname = $hostArray[0]; + + // Log entry + //* DEBUG: */ logDebugMessage(__METHOD__, __LINE__, sprintf("Begin lookup: %s", $hostname)); + $ret = '0.0.0.0'; + + // Search for hostname in cache + $result = SQL_QUERY_ESC("SELECT `ip` FROM `{?_MYSQL_PREFIX?}_dns_cache` WHERE `hostname`='%s' LIMIT 1", + array(strtolower($hostname)), __METHOD__, __LINE__); + + // Does an entry exist? + if (SQL_NUMROWS($result) == 1) { + // Then load the hostname + list($ip) = SQL_FETCHROW($result); + + // Count cache hit + incrementStatsEntry('dns_cache_hits'); + + // Set fetched IP number as return value + $ret = $ip; + //* DEBUG: */ logDebugMessage(__METHOD__, __LINE__, sprintf("Cache used: %s->%s", $hostname, $ip)); + } else { + // Get IP address + $ip = gethostbyname($hostname); + + // Count lookup hit + incrementStatsEntry('dns_lookup_hits'); + + // Is it an IP address? + if (preg_match('/(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])/', $hostname, $matches)) { + // Seems to be an IP! Now check deeper... + if (($matches[0] == $ip) && ($matches[1] >= 0) && ($matches[1] <= 255) && ($matches[2] >= 0) && ($matches[2] <= 255) && ($matches[3] >= 0) && ($matches[3] <= 255) && ($matches[4] >= 0) && ($matches[4] <= 255)) { + // We also cache IP addresses + SQL_QUERY_ESC("INSERT INTO `{?_MYSQL_PREFIX?}_dns_cache` (`ip`, `hostname`, `added`) VALUES('%s', '%s', NOW())", + array($ip, strtolower($hostname)), __METHOD__, __LINE__); + + // Set return value to $ip + //* DEBUG: */ logDebugMessage(__METHOD__, __LINE__, sprintf("IP detected, cache entry written: %s->%s", $hostname, $ip)); + } else { + // Network address or broadcast address found + //* DEBUG: */ logDebugMessage(__METHOD__, __LINE__, sprintf("IP %s is possibly a network or broadcast address.", $ip)); + } + } elseif ($ip == $hostname) { + // Nothing found, maybe invalid! + //* DEBUG: */ logDebugMessage(__METHOD__, __LINE__, sprintf("Cannot lookup: %s", $hostname)); + } else { + // Put entry in DB + SQL_QUERY_ESC("INSERT INTO `{?_MYSQL_PREFIX?}_dns_cache` (`ip`, `hostname`, `added`) VALUES('%s', '%s', NOW())", + array($ip, strtolower($hostname)), __METHOD__, __LINE__); + + // Set return value to $ip + $ret = $ip; + //* DEBUG: */ logDebugMessage(__METHOD__, __LINE__, sprintf("Lookup successfull, cache entry written: %s->%s", $hostname, $ip)); + } + } + + // Free result + SQL_FREERESULT($result); + + // Return IP number (let's hope it! + return $ret; + } + + // Purge old entries + function purgeEntries() { + // SQL for cleaning up + SQL_QUERY("DELETE LOW_PRIORITY FROM `{?_MYSQL_PREFIX?}_dns_cache` WHERE UNIX_TIMESTAMP(`added`) < (UNIX_TIMESTAMP() - {%config:dns_cache_timeout%})", + __METHOD__, __LINE__); + } +} + +// [EOF] +?> diff --git a/inc/extensions/ext-network.php b/inc/extensions/ext-network.php index 73640d37d8..a3579923d1 100644 --- a/inc/extensions/ext-network.php +++ b/inc/extensions/ext-network.php @@ -1,7 +1,7 @@ '; } +// Cleans up the DNS cache if sql_patches is at least 0.7.0 +function FILTER_CLEANUP_DNS_CACHE () { + // Is the latest version installed? + if (isExtensionInstalledAndNewer('sql_patches', '0.7.0')) { + // Load class file + loadIncludeOnce('inc/classes/resolver.class.php'); + + // Instance the resolver + $resolver = new HostnameResolver(); + + // Purge entries + $resolver->purgeEntries(); + + // Cute, isn't it? ;-) + } // END - if +} + // [EOF] ?> diff --git a/inc/functions.php b/inc/functions.php index 278c570375..9c3cc70ca6 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1837,14 +1837,26 @@ function sendRawRequest ($host, $request) { $useProxy = true; } // END - if + // Load include + loadIncludeOnce('inc/classes/resolver.class.php'); + + // Get resolver instance + $resolver = new HostnameResolver(); + // Open connection //* DEBUG: */ die("SCRIPT=" . $script.'
'); if ($useProxy === true) { + // Resolve hostname into IP address + $ip = $resolver->resolveHostname(compileRawCode(getConfig('proxy_host'))); + // Connect to host through proxy connection - $fp = fsockopen(compileRawCode(getConfig('proxy_host')), bigintval(getConfig('proxy_port')), $errno, $errdesc, 30); + $fp = fsockopen($ip, bigintval(getConfig('proxy_port')), $errno, $errdesc, 30); } else { + // Resolve hostname into IP address + $ip = $resolver->resolveHostname($host); + // Connect to host directly - $fp = fsockopen($host, 80, $errno, $errdesc, 30); + $fp = fsockopen($ip, 80, $errno, $errdesc, 30); } // Is there a link? @@ -1860,35 +1872,13 @@ function sendRawRequest ($host, $request) { // Do we use proxy? if ($useProxy === true) { - // Generate CONNECT request header - $proxyTunnel = 'CONNECT ' . $host . ':80 HTTP/1.1' . getConfig('HTTP_EOL'); - $proxyTunnel .= 'Host: ' . $host . getConfig('HTTP_EOL'); - - // Use login data to proxy? (username at least!) - if (getConfig('proxy_username') != '') { - // Add it as well - $encodedAuth = base64_encode(compileRawCode(getConfig('proxy_username')) . ':' . compileRawCode(getConfig('proxy_password'))); - $proxyTunnel .= 'Proxy-Authorization: Basic ' . $encodedAuth . getConfig('HTTP_EOL'); - } // END - if - - // Add last new-line - $proxyTunnel .= getConfig('HTTP_EOL'); - //* DEBUG: */ print('proxyTunnel=
' . $proxyTunnel.'
'); - - // Write request - fwrite($fp, $proxyTunnel); + // Setup proxy tunnel + $response = setupProxyTunnel($host, $fp); - // Got response? - if (feof($fp)) { - // No response received - return $response; - } // END - if - - // Read the first line - $resp = trim(fgets($fp, 10240)); - $respArray = explode(' ', $resp); - if ((strtolower($respArray[0]) !== 'http/1.0') || ($respArray[1] != '200')) { + // If the response is invalid, abort + if ((count($response) == 3) && (empty($response[0])) && (empty($response[1])) && (empty($response[2]))) { // Invalid response! + logDebugMessage(__FUNCTION__, __LINE__, 'Proxy tunnel not working?'); return $response; } // END - if } // END - if @@ -1935,7 +1925,7 @@ function sendRawRequest ($host, $request) { // Time request if debug-mode is enabled if (isDebugModeEnabled()) { // Add debug message... - logDebugMessage(__FUNCTION__, __LINE__, 'Request took ' . (microtime(true) - $start) . ' seconds.'); + logDebugMessage(__FUNCTION__, __LINE__, 'Request took ' . (microtime(true) - $start) . ' seconds and returned ' . count($response) . ' line(s).'); } // END - if // Skip first empty lines @@ -1961,6 +1951,7 @@ function sendRawRequest ($host, $request) { if (!isset($response[0])) { // No response, maybe timeout $response = array('', '', ''); + logDebugMessage(__FUNCTION__, __LINE__, 'Invalid empty response array, maybe timed out?'); } elseif ((substr(strtolower($response[0]), 0, 11) == 'proxy-agent') && ($useProxy === true)) { // Proxy header detected, so remove two lines array_shift($response); @@ -1970,6 +1961,7 @@ function sendRawRequest ($host, $request) { // Was the request successfull? if ((!isInStringIgnoreCase('200 OK', $response[0])) || (empty($response[0]))) { // Not found / access forbidden + logDebugMessage(__FUNCTION__, __LINE__, 'Unexpected status code ' . $response[0] . ' detected. "200 OK" was expected.'); $response = array('', '', ''); } // END - if @@ -1977,6 +1969,47 @@ function sendRawRequest ($host, $request) { return $response; } +// Sets up a proxy tunnel for given hostname and through resource +function setupProxyTunnel ($host, $resource) { + // Initialize array + $response = array('', '', ''); + + // Generate CONNECT request header + $proxyTunnel = 'CONNECT ' . $host . ':80 HTTP/1.1' . getConfig('HTTP_EOL'); + $proxyTunnel .= 'Host: ' . $host . getConfig('HTTP_EOL'); + + // Use login data to proxy? (username at least!) + if (getConfig('proxy_username') != '') { + // Add it as well + $encodedAuth = base64_encode(compileRawCode(getConfig('proxy_username')) . ':' . compileRawCode(getConfig('proxy_password'))); + $proxyTunnel .= 'Proxy-Authorization: Basic ' . $encodedAuth . getConfig('HTTP_EOL'); + } // END - if + + // Add last new-line + $proxyTunnel .= getConfig('HTTP_EOL'); + //* DEBUG: */ print('proxyTunnel=
' . $proxyTunnel.'
'); + + // Write request + fwrite($fp, $proxyTunnel); + + // Got response? + if (feof($fp)) { + // No response received + return $response; + } // END - if + + // Read the first line + $resp = trim(fgets($fp, 10240)); + $respArray = explode(' ', $resp); + if ((strtolower($respArray[0]) !== 'http/1.0') || ($respArray[1] != '200')) { + // Invalid response! + return $response; + } // END - if + + // All fine! + return $respArray; +} + // Taken from www.php.net isInStringIgnoreCase() user comments function isEmailValid ($email) { // Check first part of email address diff --git a/inc/language/repair_de.php b/inc/language/repair_de.php index 1a5452d34a..3ce8e6397c 100644 --- a/inc/language/repair_de.php +++ b/inc/language/repair_de.php @@ -44,7 +44,7 @@ if (!defined('__SECURITY')) { // Language definitions addMessages(array( - 'ADMIN_REPAIR_CATS_NOTHING' => "Keine Kategorie-Auswahlenn gefunden! Vermutlich sind keine Mitglieder registriert?", + 'ADMIN_REPAIR_CATS_NOTHING' => "Keine Kategorien gefunden! Vermutlich sind keine Mitglieder registriert?", 'ADMIN_REPAIR_ENTRIES_FIXED' => "Es wurden %s Einträge repariert.", 'ADMIN_REPAIR_NOTHING_FIXED' => "Es wurden keine Einträge repariert.", 'ADMIN_REPAIR_LANGUAGE_TO_MUCH' => "Es sind mehr als 100 nicht existierende Elemente in der Zielsprachdatei gefunden worden.", diff --git a/inc/language/validator_de.php b/inc/language/validator_de.php index 0705b4775c..322d1ebf61 100644 --- a/inc/language/validator_de.php +++ b/inc/language/validator_de.php @@ -10,10 +10,10 @@ * -------------------------------------------------------------------- * * Kurzbeschreibung : Deutsche Sprachunterstuetzung * * -------------------------------------------------------------------- * - * $Revision:: 1690 $ * - * $Date:: 2010-01-01 17:04:52 +0100 (Fri, 01 Jan 2010) $ * + * $Revision:: $ * + * $Date:: $ * * $Tag:: 0.2.1-FINAL $ * - * $Author:: quix0r $ * + * $Author:: $ * * Needs to be in all Files and every File needs "svn propset * * svn:keywords Date Revision" (autoprobset!) at least!!!!!! * * -------------------------------------------------------------------- * diff --git a/inc/modules/admin/what-config_validator.php b/inc/modules/admin/what-config_validator.php index 19c59dc909..39f7e55c38 100644 --- a/inc/modules/admin/what-config_validator.php +++ b/inc/modules/admin/what-config_validator.php @@ -10,10 +10,10 @@ * -------------------------------------------------------------------- * * Kurzbeschreibung : Konfiguration der Erweiterung ext-validator * * -------------------------------------------------------------------- * - * $Revision:: 1047 $ * - * $Date:: 2009-06-08 19:32:34 +0200 (Mon, 08 Jun 2009) $ * + * $Revision:: $ * + * $Date:: $ * * $Tag:: 0.2.1-FINAL $ * - * $Author:: quix0r $ * + * $Author:: $ * * Needs to be in all Files and every File needs "svn propset * * svn:keywords Date Revision" (autoprobset!) at least!!!!!! * * -------------------------------------------------------------------- * diff --git a/inc/modules/admin/what-repair_cats.php b/inc/modules/admin/what-repair_cats.php index 898ac79c64..51e4edd397 100644 --- a/inc/modules/admin/what-repair_cats.php +++ b/inc/modules/admin/what-repair_cats.php @@ -8,7 +8,7 @@ * -------------------------------------------------------------------- * * Short description : Repairs category selections * * -------------------------------------------------------------------- * - * Kurzbeschreibung : Repariert Kategorieauswahlen * + * Kurzbeschreibung : Repariert Kategorien * * -------------------------------------------------------------------- * * $Revision:: $ * * $Date:: $ * diff --git a/inc/wrapper-functions.php b/inc/wrapper-functions.php index 055cf55b88..bb570f585a 100644 --- a/inc/wrapper-functions.php +++ b/inc/wrapper-functions.php @@ -863,13 +863,14 @@ function getFetchedUserData ($keyColumn, $userId, $valueColumn) { // Wrapper for strpos() to ease porting from deprecated ereg() function function isInString ($needle, $haystack) { + //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'needle=' . $needle . ', haystack=' . $haystack . ', returned=' . intval(strpos($haystack, $needle) !== false)); return (strpos($haystack, $needle) !== false); } // Wrapper for strpos() to ease porting from deprecated eregi() function // This function is case-insensitive function isInStringIgnoreCase ($needle, $haystack) { - return (isInString(strtolower($haystack), strtolower($needle))); + return (isInString(strtolower($needle), strtolower($haystack))); } // [EOF] diff --git a/templates/de/html/admin/admin_update_download.tpl b/templates/de/html/admin/admin_update_download.tpl index 74ff42388a..177dfe4811 100644 --- a/templates/de/html/admin/admin_update_download.tpl +++ b/templates/de/html/admin/admin_update_download.tpl @@ -7,7 +7,7 @@
{--YOUR_VERSION_IS--}:
-
v{?FULL_VERSION?} {?CURR_SVN_REVISION?}
+
v{?FULL_VERSION?} R{?CURR_SVN_REVISION?}
-- 2.39.2