NobuNobu
nobun****@users*****
2006年 4月 11日 (火) 22:00:16 JST
Index: xoops2jp/html/class/snoopy.php diff -u xoops2jp/html/class/snoopy.php:1.1 xoops2jp/html/class/snoopy.php:1.1.16.1 --- xoops2jp/html/class/snoopy.php:1.1 Thu Sep 9 14:14:50 2004 +++ xoops2jp/html/class/snoopy.php Tue Apr 11 22:00:16 2006 @@ -31,7 +31,7 @@ Lincoln, NE 68510 The latest version of Snoopy can be obtained from: -http://snoopy.sourceforge.com +http://snoopy.sourceforge.net/ *************************************************/ @@ -45,7 +45,10 @@ var $port = 80; // port we are connecting to var $proxy_host = ""; // proxy host to use var $proxy_port = ""; // proxy port to use - var $agent = "Snoopy v1.01"; // agent we masquerade as + var $proxy_user = ""; // proxy user to use + var $proxy_pass = ""; // proxy password to use + + var $agent = "Snoopy v1.2.3"; // agent we masquerade as var $referer = ""; // referer info to pass var $cookies = array(); // array of cookies to pass // $cookies["username"]="joe"; @@ -58,7 +61,7 @@ var $maxframes = 0; // frame content depth maximum. 0 = disallow var $expandlinks = true; // expand links to fully qualified URLs. // this only applies to fetchlinks() - // or submitlinks() + // submitlinks(), and submittext() var $passcookies = true; // pass set cookies back through redirects // NOTE: this currently does not respect // dates, domains or paths. @@ -80,7 +83,11 @@ // set to 0 to disallow timeouts var $timed_out = false; // if a read operation timed out var $status = 0; // http request status - + + var $temp_dir = "/tmp"; // temporary directory that the webserver + // has permission to write to. + // under Windows, this should be C:\temp + var $curl_path = "/usr/local/bin/curl"; // Snoopy will use cURL for fetching // SSL content if a full system path to @@ -128,8 +135,12 @@ $this->user = $URI_PARTS["user"]; if (!empty($URI_PARTS["pass"])) $this->pass = $URI_PARTS["pass"]; + if (empty($URI_PARTS["query"])) + $URI_PARTS["query"] = ''; + if (empty($URI_PARTS["path"])) + $URI_PARTS["path"] = ''; - switch($URI_PARTS["scheme"]) + switch(strtolower($URI_PARTS["scheme"])) { case "http": $this->host = $URI_PARTS["host"]; @@ -191,8 +202,11 @@ return true; break; case "https": - if(!$this->curl_path || (!is_executable($this->curl_path))) + if(!$this->curl_path) return false; + if(function_exists("is_executable")) + if (!is_executable($this->curl_path)) + return false; $this->host = $URI_PARTS["host"]; if(!empty($URI_PARTS["port"])) $this->port = $URI_PARTS["port"]; @@ -257,6 +271,8 @@ Input: $URI the location to post the data $formvars the formvars to use. format: $formvars["var"] = "val"; + $formfiles an array of files to submit + format: $formfiles["var"] = "/dir/filename.ext"; Output: $this->results the text output from the post \*======================================================================*/ @@ -271,8 +287,12 @@ $this->user = $URI_PARTS["user"]; if (!empty($URI_PARTS["pass"])) $this->pass = $URI_PARTS["pass"]; - - switch($URI_PARTS["scheme"]) + if (empty($URI_PARTS["query"])) + $URI_PARTS["query"] = ''; + if (empty($URI_PARTS["path"])) + $URI_PARTS["path"] = ''; + + switch(strtolower($URI_PARTS["scheme"])) { case "http": $this->host = $URI_PARTS["host"]; @@ -308,7 +328,10 @@ /* follow the redirect */ $this->_redirectdepth++; $this->lastredirectaddr=$this->_redirectaddr; - $this->submit($this->_redirectaddr,$formvars, $formfiles); + if( strpos( $this->_redirectaddr, "?" ) > 0 ) + $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get + else + $this->submit($this->_redirectaddr,$formvars, $formfiles); } } } @@ -338,8 +361,11 @@ return true; break; case "https": - if(!$this->curl_path || (!is_executable($this->curl_path))) + if(!$this->curl_path) return false; + if(function_exists("is_executable")) + if (!is_executable($this->curl_path)) + return false; $this->host = $URI_PARTS["host"]; if(!empty($URI_PARTS["port"])) $this->port = $URI_PARTS["port"]; @@ -369,7 +395,10 @@ /* follow the redirect */ $this->_redirectdepth++; $this->lastredirectaddr=$this->_redirectaddr; - $this->submit($this->_redirectaddr,$formvars, $formfiles); + if( strpos( $this->_redirectaddr, "?" ) > 0 ) + $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get + else + $this->submit($this->_redirectaddr,$formvars, $formfiles); } } } @@ -413,7 +442,8 @@ { if ($this->fetch($URI)) { - + if($this->lastredirectaddr) + $URI = $this->lastredirectaddr; if(is_array($this->results)) { for($x=0;$x<count($this->results);$x++) @@ -493,6 +523,8 @@ { if($this->submit($URI,$formvars, $formfiles)) { + if($this->lastredirectaddr) + $URI = $this->lastredirectaddr; if(is_array($this->results)) { for($x=0;$x<count($this->results);$x++) @@ -525,6 +557,8 @@ { if($this->submit($URI,$formvars, $formfiles)) { + if($this->lastredirectaddr) + $URI = $this->lastredirectaddr; if(is_array($this->results)) { for($x=0;$x<count($this->results);$x++) @@ -569,7 +603,7 @@ $this->_submit_type = "application/x-www-form-urlencoded"; } - + // XOOPS2 Hack begin // Added on March 4, 2003 by onoka****@xoops***** /*======================================================================*\ @@ -582,7 +616,7 @@ $this->_submit_type = "text/xml"; } // XOOPS2 Hack end - + /*======================================================================*\ Private functions @@ -725,14 +759,20 @@ preg_match("/^[^\?]+/",$URI,$match); $match = preg_replace("|/[^\/\.]+\.[^\/\.]+$|","",$match[0]); + $match = preg_replace("|/$|","",$match); + $match_part = parse_url($match); + $match_root = + $match_part["scheme"]."://".$match_part["host"]; $search = array( "|^http://".preg_quote($this->host)."|i", - "|^(?!http://)(\/)?(?!mailto:)|i", + "|^(\/)|i", + "|^(?!http://)(?!mailto:)|i", "|/\./|", "|/[^\/]+/\.\./|" ); $replace = array( "", + $match_root."/", $match."/", "/", "/" @@ -765,8 +805,12 @@ $headers = $http_method." ".$url." ".$this->_httpversion."\r\n"; if(!empty($this->agent)) $headers .= "User-Agent: ".$this->agent."\r\n"; - if(!empty($this->host) && !isset($this->rawheaders['Host'])) - $headers .= "Host: ".$this->host."\r\n"; + if(!empty($this->host) && !isset($this->rawheaders['Host'])) { + $headers .= "Host: ".$this->host; + if(!empty($this->port)) + $headers .= ":".$this->port; + $headers .= "\r\n"; + } if(!empty($this->accept)) $headers .= "Accept: ".$this->accept."\r\n"; if(!empty($this->referer)) @@ -802,6 +846,11 @@ $headers .= "Content-length: ".strlen($body)."\r\n"; if(!empty($this->user) || !empty($this->pass)) $headers .= "Authorization: Basic ".base64_encode($this->user.":".$this->pass)."\r\n"; + + //add proxy auth headers + if(!empty($this->proxy_user)) + $headers .= 'Proxy-Authorization: ' . 'Basic ' . base64_encode($this->proxy_user . ':' . $this->proxy_pass)."\r\n"; + $headers .= "\r\n"; @@ -830,7 +879,7 @@ if(preg_match("/^(Location:|URI:)/i",$currentHeader)) { // get URL portion of the redirect - preg_match("/^(Location:|URI:)[ ]+(.*)/",chop($currentHeader),$matches); + preg_match("/^(Location:|URI:)[ ]+(.*)/i",chop($currentHeader),$matches); // look for :// in the Location header to see if hostname is included if(!preg_match("|\:\/\/|",$matches[2])) { @@ -875,7 +924,8 @@ // check if there is a a redirect meta tag - if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]+URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match)) + if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match)) + { $this->_redirectaddr = $this->_expandlinks($match[1],$URI); } @@ -921,7 +971,10 @@ if(!empty($this->agent)) $headers[] = "User-Agent: ".$this->agent; if(!empty($this->host)) - $headers[] = "Host: ".$this->host; + if(!empty($this->port)) + $headers[] = "Host: ".$this->host.":".$this->port; + else + $headers[] = "Host: ".$this->host; if(!empty($this->accept)) $headers[] = "Accept: ".$this->accept; if(!empty($this->referer)) @@ -958,8 +1011,10 @@ if(!empty($this->user) || !empty($this->pass)) $headers[] = "Authorization: BASIC ".base64_encode($this->user.":".$this->pass); - for($curr_header = 0; $curr_header < count($headers); $curr_header++) - $cmdline_params .= " -H \"".$headers[$curr_header]."\""; + for($curr_header = 0; $curr_header < count($headers); $curr_header++) { + $safer_header = strtr( $headers[$curr_header], "\"", " " ); + $cmdline_params .= " -H \"".$safer_header."\""; + } if(!empty($body)) $cmdline_params .= " -d \"$body\""; @@ -967,9 +1022,10 @@ if($this->read_timeout > 0) $cmdline_params .= " -m ".$this->read_timeout; - $headerfile = uniqid(time()); + $headerfile = tempnam($temp_dir, "sno"); - exec($this->curl_path." -D \"/tmp/$headerfile\"".$cmdline_params." ".$URI,$results,$return); + $safer_URI = strtr( $URI, "\"", " " ); // strip quotes from the URI to avoid shell access + exec($this->curl_path." -D \"$headerfile\"".$cmdline_params." \"".$safer_URI."\"",$results,$return); if($return) { @@ -980,7 +1036,7 @@ $results = implode("\r\n",$results); - $result_headers = file("/tmp/$headerfile"); + $result_headers = file("$headerfile"); $this->_redirectaddr = false; unset($this->headers); @@ -1016,7 +1072,7 @@ // check if there is a a redirect meta tag - if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]+URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match)) + if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match)) { $this->_redirectaddr = $this->_expandlinks($match[1],$URI); } @@ -1035,7 +1091,7 @@ else $this->results = $results; - unlink("/tmp/$headerfile"); + unlink("$headerfile"); return true; } @@ -1050,7 +1106,7 @@ for($x=0; $x<count($this->headers); $x++) { if(preg_match('/^set-cookie:[\s]+([^=]+)=([^;]+)/i', $this->headers[$x],$match)) - $this->cookies[$match[1]] = $match[2]; + $this->cookies[$match[1]] = urldecode($match[2]); } } @@ -1084,6 +1140,7 @@ if(!empty($this->proxy_host) && !empty($this->proxy_port)) { $this->_isproxy = true; + $host = $this->proxy_host; $port = $this->proxy_port; } @@ -1149,6 +1206,7 @@ { settype($formvars, "array"); settype($formfiles, "array"); + $postdata = ''; if (count($formvars) == 0 && count($formfiles) == 0) return;