1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
<?php
/**
* @version $Header$
*
* Copyright (c) 2008 bitweaver.org
* All Rights Reserved. See below for details and a complete list of authors.
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See http://www.gnu.org/copyleft/lesser.html for details
*
* @package kernel
* @subpackage functions
*/
/**
* Quick guide to this file:
* $_REQUEST['ajax_path_conf'] is the kernel configuration name that contains the absolute path to the directory where the files are.
*
* Safety first:
* This method was chosen to provide a measure of security since we never pass in an absolute path via the URL this way.
* Another safety measure is provided that the configuration value set in $gBitSystem->mConfig['$_REQUEST['ajax_path_conf']] is used as 'jail'.
* Paths outside this 'jail' will be ignored including ../../ or symbolic links.
* Evil extensions as defined in EVIL_EXTENSION_PATTERN will be ignored as are [dot] files e.g.: .private.txt
*
* e.g.:
* /home/ftp/public/ is the 'jail'
* /home/ftp/public/ftp -> /home/ftp/ is a symbolic link that points outside the 'jail' and will therefore be ignored completely.
* Also makes it impossible to import stuff like /home/ftp/public/../../../../../etc/passwd
*
* You can define ajax_path_conf in two places with different effects:
* 1. define the ajax_path_conf when you include the template:
* {include file="bitpackage:kernel/ajax_file_browser.tpl" ajax_path_conf=treasury_file_import_path}
* This will show a link to "Load Files" which will then load the file list when you click on the link.
* 2. If you provide $_REQUEST['ajax_path_conf'] when you include it from your php file, all files in the root directory will already be loaded.
* $_REQUEST['ajax_path_conf'] = 'treasury_file_import_path';
* require_once( KERNEL_PKG_PATH.'ajax_file_browser.php' );
*
* NOTE: when you process the imported files, make sure you use realpath() to check of files are really in your 'jail'.
*/
require_once 'setup_inc.php';
// we need to set these global that we can include this file from functions
global $gBitThemes, $gBitSystem, $gBitSmarty;
if( !empty( $_REQUEST['ajax_path_conf'] ) && $gBitSystem->isFeatureActive( $_REQUEST['ajax_path_conf'] ) ) {
$fileList = ajax_dir_list( $gBitSystem->getConfig( $_REQUEST['ajax_path_conf'] ), !empty( $_REQUEST['relpath'] ) ? $_REQUEST['relpath'] . "/" : null);
$gBitSmarty->assign( 'fileList', $fileList );
}
$gBitThemes->loadAjax( 'mochikit', [ 'Iter.js', 'DOM.js', 'Async.js' ]);
$gBitThemes->loadJavascript( KERNEL_PKG_PATH."scripts/BitFileBrowser.js", true );
if( $gBitThemes->isAjaxRequest() ) {
$gBitSmarty->display( 'bitpackage:kernel/ajax_file_browser_inc.tpl' );
}
/**
* ajax_dir_list
*
* @param string $pDir Base directory
* @param string $pRelPath relative path on top of base directory
* @access public
* @return array
*/
function ajax_dir_list( $pDir, $pRelPath = null ) {
global $gBitSystem;
$ret = $files = [];
if( !empty( $pDir ) && is_dir( $pDir.$pRelPath )) {
if( $handle = opendir( $pDir.$pRelPath )) {
while( false !== ( $file = readdir( $handle ))) {
if( !preg_match( "#^\.#",$file ) && is_readable( $pDir.$pRelPath.$file )) {
array_push( $files, $file );
}
}
sort( $files );
foreach( $files as $i ) {
$relFile = $pRelPath.$i;
$file = realpath( $pDir.$relFile );
if( strpos( $file, $pDir ) === 0 ) {
$info = [
'name' => $i,
'relpath' => $relFile,
'indent' => ( count( explode( '/', $relFile )) * 10 ),
'size' => filesize( $file ),
'mtime' => filemtime( $file ),
];
if( is_dir( $file )) {
$ret['dir'][$i] = $info;
} elseif( !preg_match( EVIL_EXTENSION_PATTERN, $file )) {
$ret['file'][$i] = $info;
}
}
}
closedir( $handle );
}
}
if( empty( $ret )) {
$ret['file'][] = [
'indent' => ( count( explode( '/', $pRelPath )) * 10 ),
];
}
return $ret;
}
|