note 51592 deleted from function.fopen by googleguy

From: Date: Tue, 22 Oct 2013 10:17:46 +0000
Subject: note 51592 deleted from function.fopen by googleguy
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-196984@lists.php.net to get a copy of this message
Note Submitter: abesharp at yahoo dot co dot uk ---- This function has a basic implementation of HTTP Digest Authentication (as per RFC 2617) to get a file from a web server which requires digest authentication (as opposed to basic authentication - the difference being that, with basic, your password is sent to the server as plain text, whereas with digest, it is hashed with a server-supplied nonce to protect against sniffing and replay attacks). You just supply the host (e.g www.example.com), the name of the file you want (e.g protected_page.html), and the necessary username and password, and the function returns the contents of the protected file (or the error message that the server sends, if you supplied the wrong credentials). If the server only supports a QOP of auth-int (rather then auth) this function won't work, but can be easily modified with reference to the RFC at http://www.ietf.org/rfc/rfc2617.txt <?php function readHTTPDigestAuthenticatedFile($host,$file,$username,$password) { if (!$fp=fsockopen($host,80, $errno, $errstr, 15)) return false; //first do the non-authenticated header so that the server //sends back a 401 error containing its nonce and opaque $out = "GET /$file HTTP/1.1\r\n"; $out .= "Host: $host\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); //read the reply and look for the WWW-Authenticate element while (!feof($fp)) { $line=fgets($fp, 512); if (strpos($line,"WWW-Authenticate:")!==false) $authline=trim(substr($line,18)); } fclose($fp); //split up the WWW-Authenticate string to find digest-realm,nonce and opaque values //if qop value is presented as a comma-seperated list (e.g auth,auth-int) then it won't be retrieved correctly //but that doesn't matter because going to use 'auth' anyway $authlinearr=explode(",",$authline); $autharr=array(); foreach ($authlinearr as $el) { $elarr=explode("=",$el); //the substr here is used to remove the double quotes from the values $autharr[trim($elarr[0])]=substr($elarr[1],1,strlen($elarr[1])-2); } foreach ($autharr as $k=>$v) echo("$k ==> $v\r\n"); //these are all the vals required from the server $nonce=$autharr['nonce']; $opaque=$autharr['opaque']; $drealm=$autharr['Digest realm']; //client nonce can be anything since this authentication session is not going to be persistent //likewise for the cookie - just call it MyCookie $cnonce="sausages"; //calculate the hashes of A1 and A2 as described in RFC 2617 $a1="$username:$drealm:$password";$a2="GET:/$file"; $ha1=md5($a1);$ha2=md5($a2); //calculate the response hash as described in RFC 2617 $concat = $ha1.':'.$nonce.':00000001:'.$cnonce.':auth:'.$ha2; $response=md5($concat); //put together the Authorization Request Header $out = "GET /$file HTTP/1.1\r\n"; $out .= "Host: $host\r\n"; $out .= "Connection: Close\r\n"; $out .= "Cookie: cookie=MyCookie\r\n"; $out .= "Authorization: Digest username=\"$username\", realm=\"$drealm\", qop=\"auth\", algorithm=\"MD5\", uri=\"/$file\", nonce=\"$nonce\", nc=00000001, cnonce=\"$cnonce\", opaque=\"$opaque\", response=\"$response\"\r\n\r\n"; if (!$fp=fsockopen($host,80, $errno, $errstr, 15)) return false; fwrite($fp, $out); //read in a string which is the contents of the required file while (!feof($fp)) { $str.=fgets($fp, 512); } fclose($fp); return $str; } ?>

« previous php.notes (#196984) next »