MediaWiki  REL1_22
img_auth.php
Go to the documentation of this file.
00001 <?php
00042 define( 'MW_NO_OUTPUT_COMPRESSION', 1 );
00043 require __DIR__ . '/includes/WebStart.php';
00044 wfProfileIn( 'img_auth.php' );
00045 
00046 # Set action base paths so that WebRequest::getPathInfo()
00047 # recognizes the "X" as the 'title' in ../img_auth.php/X urls.
00048 $wgArticlePath = false; # Don't let a "/*" article path clober our action path
00049 $wgActionPaths = array( "$wgUploadPath/" );
00050 
00051 wfImageAuthMain();
00052 wfLogProfilingData();
00053 
00054 function wfImageAuthMain() {
00055     global $wgImgAuthPublicTest, $wgRequest;
00056 
00057     // See if this is a public Wiki (no protections).
00058     if ( $wgImgAuthPublicTest
00059         && in_array( 'read', User::getGroupPermissions( array( '*' ) ), true )
00060     ) {
00061         // This is a public wiki, so disable this script (for private wikis only)
00062         wfForbidden( 'img-auth-accessdenied', 'img-auth-public' );
00063         return;
00064     }
00065 
00066     // Get the requested file path (source file or thumbnail)
00067     $matches = WebRequest::getPathInfo();
00068     if ( !isset( $matches['title'] ) ) {
00069         wfForbidden( 'img-auth-accessdenied', 'img-auth-nopathinfo' );
00070         return;
00071     }
00072     $path = $matches['title'];
00073     if ( $path && $path[0] !== '/' ) {
00074         // Make sure $path has a leading /
00075         $path = "/" . $path;
00076     }
00077 
00078     // Check for bug 28235: QUERY_STRING overriding the correct extension
00079     $whitelist = array();
00080     $dotPos = strrpos( $path, '.' );
00081     if ( $dotPos !== false ) {
00082         $whitelist[] = substr( $path, $dotPos + 1 );
00083     }
00084     if ( !$wgRequest->checkUrlExtension( $whitelist ) ) {
00085         return;
00086     }
00087 
00088     // Get the local file repository
00089     $repo = RepoGroup::singleton()->getRepo( 'local' );
00090 
00091     // Get the full file storage path and extract the source file name.
00092     // (e.g. 120px-Foo.png => Foo.png or page2-120px-Foo.png => Foo.png).
00093     // This only applies to thumbnails, and all thumbnails should
00094     // be under a folder that has the source file name.
00095     if ( strpos( $path, '/thumb/' ) === 0 ) {
00096         $name = wfBaseName( dirname( $path ) ); // file is a thumbnail
00097         $filename = $repo->getZonePath( 'thumb' ) . substr( $path, 6 ); // strip "/thumb"
00098     } else {
00099         $name = wfBaseName( $path ); // file is a source file
00100         $filename = $repo->getZonePath( 'public' ) . $path;
00101     }
00102 
00103     // Check to see if the file exists
00104     if ( !$repo->fileExists( $filename ) ) {
00105         wfForbidden( 'img-auth-accessdenied', 'img-auth-nofile', $filename );
00106         return;
00107     }
00108 
00109     $title = Title::makeTitleSafe( NS_FILE, $name );
00110     if ( !$title instanceof Title ) { // files have valid titles
00111         wfForbidden( 'img-auth-accessdenied', 'img-auth-badtitle', $name );
00112         return;
00113     }
00114 
00115     // Run hook for extension authorization plugins
00117     $result = null;
00118     if ( !wfRunHooks( 'ImgAuthBeforeStream', array( &$title, &$path, &$name, &$result ) ) ) {
00119         wfForbidden( $result[0], $result[1], array_slice( $result, 2 ) );
00120         return;
00121     }
00122 
00123     // Check user authorization for this title
00124     // Checks Whitelist too
00125     if ( !$title->userCan( 'read' ) ) {
00126         wfForbidden( 'img-auth-accessdenied', 'img-auth-noread', $name );
00127         return;
00128     }
00129 
00130     // Stream the requested file
00131     wfDebugLog( 'img_auth', "Streaming `" . $filename . "`." );
00132     $repo->streamFile( $filename, array( 'Cache-Control: private', 'Vary: Cookie' ) );
00133 }
00134 
00142 function wfForbidden( $msg1, $msg2 ) {
00143     global $wgImgAuthDetails;
00144 
00145     $args = func_get_args();
00146     array_shift( $args );
00147     array_shift( $args );
00148 
00149     $msgHdr = wfMessage( $msg1 )->escaped();
00150     $detailMsgKey = $wgImgAuthDetails ? $msg2 : 'badaccess-group0';
00151     $detailMsg = wfMessage( $detailMsgKey, $args )->escaped();
00152 
00153     wfDebugLog( 'img_auth',
00154         "wfForbidden Hdr: " . wfMessage( $msg1 )->inLanguage( 'en' )->text() . " Msg: " .
00155             wfMessage( $msg2, $args )->inLanguage( 'en' )->text()
00156     );
00157 
00158     header( 'HTTP/1.0 403 Forbidden' );
00159     header( 'Cache-Control: no-cache' );
00160     header( 'Content-Type: text/html; charset=utf-8' );
00161     echo <<<ENDS
00162 <html>
00163 <body>
00164 <h1>$msgHdr</h1>
00165 <p>$detailMsg</p>
00166 </body>
00167 </html>
00168 ENDS;
00169 }