Advertisement
Guest User

img_auth.php

a guest
Jan 14th, 2014
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 5.26 KB | None | 0 0
  1. <?php
  2.  
  3. /**
  4.  * Image authorisation script
  5.  *
  6.  * To use this, see http://www.mediawiki.org/wiki/Manual:Image_Authorization
  7.  *
  8.  * - Set $wgUploadDirectory to a non-public directory (not web accessible)
  9.  * - Set $wgUploadPath to point to this file
  10.  *
  11.  * Optional Parameters
  12.  *
  13.  * - Set $wgImgAuthDetails = true if you want the reason the access was denied messages to
  14.  *       be displayed instead of just the 403 error (doesn't work on IE anyway),
  15.  *       otherwise it will only appear in error logs
  16.  * - Set $wgImgAuthPublicTest false if you don't want to just check and see if all are public
  17.  *       must be set to false if using specific restrictions such as LockDown or NSFileRepo
  18.  *
  19.  *  For security reasons, you usually don't want your user to know *why* access was denied,
  20.  *  just that it was. If you want to change this, you can set $wgImgAuthDetails to 'true'
  21.  *  in localsettings.php and it will give the user the reason why access was denied.
  22.  *
  23.  * Your server needs to support PATH_INFO; CGI-based configurations usually don't.
  24.  *
  25.  * @file
  26.  *
  27.  **/
  28.  
  29. define( 'MW_NO_OUTPUT_COMPRESSION', 1 );
  30. if ( isset( $_SERVER['MW_COMPILED'] ) ) {
  31.     require ( 'phase3/includes/WebStart.php' );
  32. } else {
  33.     require ( dirname( __FILE__ ) . '/includes/WebStart.php' );
  34. }
  35. wfProfileIn( 'img_auth.php' );
  36.  
  37. # Set action base paths so that WebRequest::getPathInfo()
  38. # recognizes the "X" as the 'title' in ../image_auth/X urls.
  39. $wgArticlePath = false; # Don't let a "/*" article path clober our action path
  40. $wgActionPaths = array( "$wgUploadPath/" );
  41.  
  42. wfImageAuthMain();
  43. wfLogProfilingData();
  44.  
  45. function wfImageAuthMain() {
  46.     global $wgImgAuthPublicTest, $wgRequest, $wgUploadDirectory;
  47.  
  48.     // See if this is a public Wiki (no protections).
  49.     if ( $wgImgAuthPublicTest
  50.         && in_array( 'read', User::getGroupPermissions( array( '*' ) ), true ) )
  51.     {
  52.         // This is a public wiki, so disable this script (for private wikis only)
  53.         wfForbidden( 'img-auth-accessdenied', 'img-auth-public' );
  54.         return;
  55.     }
  56.  
  57.     // Get the requested file path (source file or thumbnail)
  58.     $matches = WebRequest::getPathInfo();
  59.     if ( !isset( $matches['title'] ) ) {
  60.         wfForbidden( 'img-auth-accessdenied', 'img-auth-nopathinfo' );
  61.         return;
  62.     }
  63.     $path = $matches['title'];
  64.     if ( $path && $path[0] !== '/' ) {
  65.         // Make sure $path has a leading /
  66.         $path = "/" . $path;
  67.     }
  68.  
  69.     // Check for bug 28235: QUERY_STRING overriding the correct extension
  70.     $whitelist = array();
  71.     $dotPos = strrpos( $path, '.' );
  72.     if ( $dotPos !== false ) {
  73.         $whitelist[] = substr( $path, $dotPos + 1 );
  74.     }
  75.     if ( !$wgRequest->checkUrlExtension( $whitelist ) ) {
  76.         return;
  77.     }
  78.  
  79.     // Get the local file repository
  80.     $repo = RepoGroup::singleton()->getRepo( 'local' );
  81.  
  82.     // Get the full file storage path and extract the source file name.
  83.     // (e.g. 120px-Foo.png => Foo.png or page2-120px-Foo.png => Foo.png).
  84.     // This only applies to thumbnails, and all thumbnails should
  85.     // be under a folder that has the source file name.
  86.     if ( strpos( $path, '/thumb/' ) === 0 ) {
  87.         $name = wfBaseName( dirname( $path ) ); // file is a thumbnail
  88.         $filename = $repo->getZonePath( 'thumb' ) . substr( $path, 6 ); // strip "/thumb"
  89.     } else {
  90.         $name = wfBaseName( $path ); // file is a source file
  91.         $filename = $repo->getZonePath( 'public' ) . $path;
  92.     }
  93.  
  94.     // Check to see if the file exists
  95.     if ( !$repo->fileExists( $filename, FileRepo::FILES_ONLY ) ) {
  96.         wfForbidden( 'img-auth-accessdenied','img-auth-nofile', $filename );
  97.         return;
  98.     }
  99.  
  100.     $title = Title::makeTitleSafe( NS_FILE, $name );
  101.     if ( !$title instanceof Title ) { // files have valid titles
  102.         wfForbidden( 'img-auth-accessdenied', 'img-auth-badtitle', $name );
  103.         return;
  104.     }
  105.  
  106.     // Run hook for extension authorization plugins
  107.     if ( !wfRunHooks( 'ImgAuthBeforeStream', array( &$title, &$path, &$name, &$result ) ) ) {
  108.         wfForbidden( $result[0], $result[1], array_slice( $result, 2 ) );
  109.         return;
  110.     }
  111.  
  112.     // Check user authorization for this title
  113.     // Checks Whitelist too
  114.     if ( !$title->userCan( 'read' ) ) {
  115.         wfForbidden( 'img-auth-accessdenied', 'img-auth-noread', $name );
  116.         return;
  117.     }
  118.  
  119.     // Stream the requested file
  120.     wfDebugLog( 'img_auth', "Streaming `".$filename."`." );
  121.     $repo->streamFile( $filename, array( 'Cache-Control: private', 'Vary: Cookie' ) );
  122. }
  123.  
  124. /**
  125.  * Issue a standard HTTP 403 Forbidden header ($msg1-a message index, not a message) and an
  126.  * error message ($msg2, also a message index), (both required) then end the script
  127.  * subsequent arguments to $msg2 will be passed as parameters only for replacing in $msg2
  128.  * @param $msg1
  129.  * @param $msg2
  130.  */
  131. function wfForbidden( $msg1, $msg2 ) {
  132.     global $wgImgAuthDetails;
  133.  
  134.     $args = func_get_args();
  135.     array_shift( $args );
  136.     array_shift( $args );
  137.  
  138.     $msgHdr = htmlspecialchars( wfMsg( $msg1 ) );
  139.     $detailMsgKey = $wgImgAuthDetails ? $msg2 : 'badaccess-group0';
  140.     $detailMsg = htmlspecialchars( wfMsg( $detailMsgKey, $args ) );
  141.  
  142.     wfDebugLog( 'img_auth',
  143.         "wfForbidden Hdr:" . wfMsgExt( $msg1, array( 'language' => 'en' ) ). " Msg: ".
  144.         wfMsgExt( $msg2, array( 'language' => 'en' ), $args )
  145.     );
  146.  
  147.     header( 'HTTP/1.0 403 Forbidden' );
  148.     header( 'Cache-Control: no-cache' );
  149.     header( 'Content-Type: text/html; charset=utf-8' );
  150.     echo <<<ENDS
  151. <html>
  152. <body>
  153. <h1>$msgHdr</h1>
  154. <p>$detailMsg</p>
  155. </body>
  156. </html>
  157. ENDS;
  158. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement