Index: trunk/phase3/img_auth.php |
— | — | @@ -1,63 +1,89 @@ |
2 | 2 | <?php |
| 3 | + |
3 | 4 | /** |
4 | | - * Image download authorisation script |
| 5 | + * Image authorisation script |
5 | 6 | * |
6 | | - * To use, in LocalSettings.php set $wgUploadDirectory to point to a non-public |
7 | | - * directory, and $wgUploadPath to point to this file. Also set $wgWhitelistRead |
8 | | - * to an array of pages you want everyone to be able to access. Your server must |
9 | | - * support PATH_INFO, CGI-based configurations generally don't. |
| 7 | + * To use this: |
| 8 | + * |
| 9 | + * Set $wgUploadDirectory to a non-public directory (not web accessible) |
| 10 | + * Set $wgUploadPath to point to this file |
| 11 | + * |
| 12 | + * Your server needs to support PATH_INFO; CGI-based configurations |
| 13 | + * usually don't. |
10 | 14 | */ |
| 15 | + |
11 | 16 | define( 'MW_NO_OUTPUT_COMPRESSION', 1 ); |
12 | | -require_once( './includes/WebStart.php' ); |
| 17 | +require_once( dirname( __FILE__ ) . '/includes/WebStart.php' ); |
13 | 18 | wfProfileIn( 'img_auth.php' ); |
14 | | -require_once( './includes/StreamFile.php' ); |
| 19 | +require_once( dirname( __FILE__ ) . '/includes/StreamFile.php' ); |
15 | 20 | |
| 21 | +// Extract path and image information |
16 | 22 | if( !isset( $_SERVER['PATH_INFO'] ) ) { |
17 | | - wfDebugLog( 'img_auth', "missing PATH_INFO" ); |
| 23 | + wfDebugLog( 'img_auth', 'Missing PATH_INFO' ); |
18 | 24 | wfForbidden(); |
19 | 25 | } |
20 | 26 | |
21 | | -# Get filenames/directories |
22 | | -wfDebugLog( 'img_auth', "PATH_INFO is: " . $_SERVER['PATH_INFO'] ); |
| 27 | +$path = $_SERVER['PATH_INFO']; |
23 | 28 | $filename = realpath( $wgUploadDirectory . $_SERVER['PATH_INFO'] ); |
24 | | -$realUploadDirectory = realpath( $wgUploadDirectory ); |
25 | | -$imageName = $wgContLang->getNsText( NS_IMAGE ) . ":" . wfBaseName( $_SERVER['PATH_INFO'] ); |
| 29 | +$realUpload = realpath( $wgUploadDirectory ); |
| 30 | +wfDebugLog( 'img_auth', "\$path is {$path}" ); |
| 31 | +wfDebugLog( 'img_auth', "\$filename is {$filename}" ); |
26 | 32 | |
27 | | -# Check if the filename is in the correct directory |
28 | | -if ( substr( $filename, 0, strlen( $realUploadDirectory ) ) != $realUploadDirectory ) { |
29 | | - wfDebugLog( 'img_auth', "requested path not in upload dir: $filename" ); |
| 33 | +// Basic directory traversal check |
| 34 | +if( substr( $filename, 0, strlen( $realUpload ) ) != $realUpload ) { |
| 35 | + wfDebugLog( 'img_auth', 'Requested path not in upload directory' ); |
30 | 36 | wfForbidden(); |
31 | 37 | } |
32 | 38 | |
33 | | -if ( is_array( $wgWhitelistRead ) && !in_array( $imageName, $wgWhitelistRead ) && !$wgUser->getID() ) { |
34 | | - wfDebugLog( 'img_auth', "not logged in and requested file not in whitelist: $imageName" ); |
| 39 | +// Extract the file name and chop off the size specifier |
| 40 | +// (e.g. 120px-Foo.png => Foo.png) |
| 41 | +$name = wfBaseName( $path ); |
| 42 | +if( preg_match( '!\d+px-(.*)!i', $name, $m ) ) |
| 43 | + $name = $m[1]; |
| 44 | +wfDebugLog( 'img_auth', "\$name is {$name}" ); |
| 45 | + |
| 46 | +$title = Title::makeTitleSafe( NS_IMAGE, $name ); |
| 47 | +if( !$title instanceof Title ) { |
| 48 | + wfDebugLog( 'img_auth', "Unable to construct a valid Title from `{$name}`" ); |
35 | 49 | wfForbidden(); |
36 | 50 | } |
| 51 | +$title = $title->getPrefixedText(); |
37 | 52 | |
| 53 | +// Check the whitelist if needed |
| 54 | +if( !$wgUser->getId() && ( !is_array( $wgWhitelistRead ) || !in_array( $title, $wgWhitelistRead ) ) ) { |
| 55 | + wfDebugLog( 'img_auth', "Not logged in and `{$title}` not in whitelist." ); |
| 56 | + wfForbidden(); |
| 57 | +} |
| 58 | + |
38 | 59 | if( !file_exists( $filename ) ) { |
39 | | - wfDebugLog( 'img_auth', "requested file does not exist: $filename" ); |
| 60 | + wfDebugLog( 'img_auth', "`{$filename}` does not exist" ); |
40 | 61 | wfForbidden(); |
41 | 62 | } |
42 | 63 | if( is_dir( $filename ) ) { |
43 | | - wfDebugLog( 'img_auth', "requested file is a directory: $filename" ); |
| 64 | + wfDebugLog( 'img_auth', "`{$filename}` is a directory" ); |
44 | 65 | wfForbidden(); |
45 | 66 | } |
46 | 67 | |
47 | | -# Write file |
48 | | -wfDebugLog( 'img_auth', "streaming file: $filename" ); |
| 68 | +// Stream the requested file |
| 69 | +wfDebugLog( 'img_auth', "Streaming `{$filename}`" ); |
49 | 70 | wfStreamFile( $filename ); |
50 | 71 | wfLogProfilingData(); |
51 | 72 | |
| 73 | +/** |
| 74 | + * Issue a standard HTTP 403 Forbidden header and a basic |
| 75 | + * error message, then end the script |
| 76 | + */ |
52 | 77 | function wfForbidden() { |
53 | 78 | header( 'HTTP/1.0 403 Forbidden' ); |
54 | 79 | header( 'Content-Type: text/html; charset=utf-8' ); |
55 | | - print |
56 | | -"<html><body> |
57 | | -<h1>Access denied</h1> |
58 | | -<p>You need to log in to access files on this server</p> |
59 | | -</body></html>"; |
| 80 | + echo <<<END |
| 81 | +<html> |
| 82 | +<body> |
| 83 | +<h1>Access Denied</h1> |
| 84 | +<p>You need to log in to access files on this server.</p> |
| 85 | +</body> |
| 86 | +</html> |
| 87 | +END; |
60 | 88 | wfLogProfilingData(); |
61 | | - exit; |
62 | | -} |
63 | | - |
64 | | - |
| 89 | + exit(); |
| 90 | +} |
\ No newline at end of file |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -356,6 +356,9 @@ |
357 | 357 | edit box scroll position preserve/restore behaviour |
358 | 358 | * (bug 10805) Fix "undo" link when viewing the diff of the most recent |
359 | 359 | change to a page using "diff=0" |
| 360 | +* img_auth.php now interacts properly with $wgWhitelistRead |
| 361 | +* (bug 10765) img_auth.php will now forbid access to images if $wgWhitelistRead |
| 362 | + is not set to an array |
360 | 363 | |
361 | 364 | == API changes since 1.10 == |
362 | 365 | |