/* Operations may take a long time.
* Be sure PHP's safe mode is off.
*/
- set_time_limit(0);
+set_time_limit(0);
$link_name = $_GET['h'];
if (isset ($_GET['d']) && !empty ($_GET['d']))
$delete_code = $_GET['d'];
+$crypt_key = '';
+if (isset ($_GET['k']) && !empty ($_GET['k']))
+ $crypt_key = $_GET['k'];
+
$button_download = false;
if (isset ($_GET['bd']) && !empty ($_GET['bd']))
$button_download = true;
exit;
}
+if (empty ($crypt_key) && $link['crypted'])
+{
+ require (JIRAFEAU_ROOT.'lib/template/header.php');
+ echo '<div class="error"><p>' . t('Sorry, the requested file is not found') .
+ '</p></div>';
+ require (JIRAFEAU_ROOT.'lib/template/footer.php');
+ exit;
+}
+
$password_challenged = false;
if (!empty ($link['key']))
{
{
require (JIRAFEAU_ROOT.'lib/template/header.php');
echo '<div>' .
- '<form action = "' . $_SERVER['REQUEST_URI'] . '" ' .
- 'method = "post" id = "submit">'; ?>
+ '<form action = "';
+ echo $cfg['web_root'] . '/file.php';
+ echo '" ' .
+ 'method = "post" id = "submit">'; ?>
<input type = "hidden" name = "jirafeau" value = "<?php echo JIRAFEAU_VERSION ?>"/><?php
echo '<fieldset>' .
'<legend>' . t('Password protection') .
'</td></tr>' .
'<tr><td>';
?><input type="submit" id = "submit_download" value="<?php echo t('Download'); ?>"
- onclick="document.getElementById('submit').action='<?php echo $_SERVER['REQUEST_URI'] ?>&bd=1';
- document.getElementById('submit_download').submit ();"/><?php
-
+ onclick="document.getElementById('submit').action='
+<?php
+ echo $cfg['web_root'] . '/file.php?h=' . $link_name . '&bd=1';
+ if (!empty($crypt_key))
+ echo '&k=' . urlencode($crypt_key);
+?>';
+ document.getElementById('submit_download').submit ();"/><?php
if ($cfg['download_page'] && $cfg['preview'])
{
?><input type="submit" id = "submit_preview" value="<?php echo t('Preview'); ?>"
- onclick="document.getElementById('submit').action='<?php echo $_SERVER['REQUEST_URI'] ?>&bp=1';
- document.getElementById('submit_preview').submit ();"/><?php
+ onclick="document.getElementById('submit').action='
+<?php
+ echo $cfg['web_root'] . '/file.php?h=' . $link_name . '&bp=1';
+ if (!empty($crypt_key))
+ echo '&k=' . urlencode($crypt_key);
+?>';
+ document.getElementById('submit_preview').submit ();"/><?php
}
echo '</td></tr></table></fieldset></form></div>';
require (JIRAFEAU_ROOT.'lib/template/footer.php');
}
else
{
- if ($link['key'] != md5 ($_POST['key']))
+ if ($link['key'] == md5 ($_POST['key']))
+ $password_challenged = true;
+ else
{
header ("Access denied");
require (JIRAFEAU_ROOT.'lib/template/header.php');
require (JIRAFEAU_ROOT.'lib/template/footer.php');
exit;
}
- else
- $password_challenged = true;
}
}
{
require (JIRAFEAU_ROOT.'lib/template/header.php');
echo '<div>' .
- '<form action = "' . $_SERVER['REQUEST_URI'] . '" ' .
- 'method = "post" id = "submit">'; ?>
+ '<form action = "';
+ echo $cfg['web_root'] . '/file.php';
+ echo '" ' .
+ 'method = "post" id = "submit">'; ?>
<input type = "hidden" name = "jirafeau" value = "<?php echo JIRAFEAU_VERSION ?>"/><?php
echo '<fieldset><legend>' . $link['file_name'] . '</legend><table>' .
'<tr><td>' .
'<tr><td>' .
t('By using our services, you accept of our'). ' <a href="' . $cfg['web_root'] . '/tos.php' . '">' . t('Term Of Service') . '</a>';
?><input type="submit" id = "submit_download" value="<?php echo t('Download'); ?>"
- onclick="document.getElementById('submit').action='<?php echo $_SERVER['REQUEST_URI'] ?>&bd=1';
- document.getElementById('submit_download').submit ();"/><?php
+ onclick="document.getElementById('submit').action='
+<?php
+ echo $cfg['web_root'] . '/file.php?h=' . $link_name . '&bd=1';
+ if (!empty($crypt_key))
+ echo '&k=' . urlencode($crypt_key);
+?>';
+ document.getElementById('submit_download').submit ();"/><?php
if ($cfg['download_page'] && $cfg['preview'])
{
?><input type="submit" id = "submit_preview" value="<?php echo t('Preview'); ?>"
- onclick="document.getElementById('submit').action='<?php echo $_SERVER['REQUEST_URI'] ?>&bp=1';
- document.getElementById('submit_preview').submit ();"/><?php
+ onclick="document.getElementById('submit').action='
+<?php
+ echo $cfg['web_root'] . '/file.php?h=' . $link_name . '&bp=1';
+ if (!empty($crypt_key))
+ echo '&k=' . urlencode($crypt_key);
+?>';
+ document.getElementById('submit_preview').submit ();"/><?php
}
echo '</td></tr>';
echo '</table></fieldset></form></div>';
else
header ('Content-Type: ' . $link['mime_type']);
-/* Read file */
-$r = fopen (VAR_FILES . $p . $link['md5'], 'r');
-while (!feof ($r))
+/* Read encrypted file. */
+if ($link['crypted'])
+{
+ /* Extract key and iv. */
+ $ex = explode (".", $crypt_key);
+ $key = $ex[0];
+ $iv = base64_decode($ex[1]);
+ error_log ("crypt_key: " . $crypt_key . " iv: " . $v . " key: ". $key . "\n", 3, "debug.log");
+ /* Init module */
+ $m = mcrypt_module_open('rijndael-256', '', 'ofb', '');
+ mcrypt_generic_init($m, $key, $iv);
+ /* Decrypt file. */
+ $r = fopen (VAR_FILES . $p . $link['md5'], 'r');
+ while (!feof ($r))
+ {
+ $dec = mdecrypt_generic($m, fread ($r, 1024));
+ print $dec;
+ ob_flush();
+ }
+ fclose ($r);
+ /* Cleanup. */
+ mcrypt_generic_deinit($m);
+ mcrypt_module_close($m);
+}
+/* Read file. */
+else
{
- print fread ($r, 1024);
- ob_flush();
+ $r = fopen (VAR_FILES . $p . $link['md5'], 'r');
+ while (!feof ($r))
+ {
+ print fread ($r, 1024);
+ ob_flush();
+ }
+ fclose ($r);
}
-fclose ($r);
-
-//readfile (VAR_FILES . $p . $link['md5']);
if ($link['onetime'] == 'O')
jirafeau_delete_link ($link_name);
The scripting interface can propose to create, read, write, delete blocks
of data. */
$cfg['enable_blocks'] = false;
+/* Encryption feature. disabled by default.
+ * This feature needs to have mcrypt php module installed.
+ * Note: activating encryption will make file-deduplication to fail.
+ */
+$cfg['enable_crypt'] = false;
if ((basename (__FILE__) != 'config.local.php')
&& file_exists (JIRAFEAU_ROOT.'lib/config.local.php'))
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-function show_link (url, reference, delete_code, date)
+function show_link (url, reference, delete_code, crypt_key, date)
{
var download_link = url + 'file.php?h=' + reference;
- var delete_link = download_link + '&d=' + delete_code;
- var delete_link_href = download_link + '&d=' + delete_code;
+ var download_link_href = url + 'file.php?h=' + reference;
+ if (crypt_key.length > 0)
+ {
+ download_link += '&k=' + crypt_key;
+ download_link_href += '&k=' + crypt_key;
+ }
+
+ var delete_link = url + 'file.php?h=' + reference + '&d=' + delete_code;
+ var delete_link_href = url + 'file.php?h=' + reference + '&d=' + delete_code;
+
document.getElementById('upload_link').innerHTML = download_link;
- document.getElementById('upload_link').href = download_link;
+ document.getElementById('upload_link').href = download_link_href;
document.getElementById('delete_link').innerHTML = delete_link;
document.getElementById('delete_link').href = delete_link_href;
if (date)
/* Show the user the operation do not reach 100%, the server need time
* to give a response before providing the link.
*/
- var p = Math.round (e.loaded * 99 / e.total);
- show_upload_progression (p.toString() + '%');
+ var p = Math.round (e.loaded * 100 / e.total);
+ if (p == 100)
+ show_upload_progression ('Finalizing ...');
+ else
+ show_upload_progression (p.toString() + '%');
}
function upload_failed (e)
d.setSeconds (d.getSeconds() + 2419200);
else
return;
- show_link (url, res[0], res[1], d.toString());
+ show_link (url, res[0], res[1], res[2], d.toString());
}
else
- show_link (url, res[0], res[1]);
+ show_link (url, res[0], res[1], res[2]);
}
}
req.open ("POST", url + 'script.php' , true);
{
if (!e.lengthComputable && async_global_file.size != 0)
return;
- var p = Math.round ((e.loaded + async_global_transfered) * 99 / (async_global_file.size));
- show_upload_progression (p.toString() + '%');
+ var p = Math.round ((e.loaded + async_global_transfered) * 100 / (async_global_file.size));
+ if (p == 100)
+ show_upload_progression ('Finalizing...');
+ else
+ show_upload_progression (p.toString() + '%');
}
function async_upload_push (code)
}
req.open ("POST", async_global_url + 'script.php?push_async' , true);
- var chunk_size = parseInt (async_global_max_size * 0.90);
+ var chunk_size = parseInt (async_global_max_size * 0.50);
var start = async_global_transfered;
var end = start + chunk_size;
if (end >= async_global_file.size)
d.setSeconds (d.getSeconds() + 2419200);
else
return;
- show_link (async_global_url, res[0], res[1], d.toString());
+ show_link (async_global_url, res[0], res[1], res[2], d.toString());
}
else
- show_link (async_global_url, res[0], res[1]);
+ show_link (async_global_url, res[0], res[1], res[2]);
}
}
req.open ("POST", async_global_url + 'script.php?end_async' , true);
* @param $key if not empty, protect the file with this key
* @param $time the time of validity of the file
* @param $ip uploader's ip
+ * @param $crypt boolean asking to crypt or not
* @returns an array containing some information
* 'error' => information on possible errors
* 'link' => the link name of the uploaded file
* 'delete_link' => the link code to delete file
*/
function
-jirafeau_upload ($file, $one_time_download, $key, $time, $ip)
+jirafeau_upload ($file, $one_time_download, $key, $time, $ip, $crypt)
{
if (empty ($file['tmp_name']) || !is_uploaded_file ($file['tmp_name']))
{
/* array representing no error */
$noerr = array ('has_error' => false, 'why' => '');
+ /* Crypt file if option is enabled. */
+ $crypted = false;
+ $crypt_key = '';
+ if ($crypt == true && extension_loaded('mcrypt'))
+ {
+ $crypt_key = jirafeau_encrypt_file ($file['tmp_name'], $file['tmp_name']);
+ if (strlen($crypt_key) > 0)
+ $crypted = true;
+ }
+
/* file informations */
$md5 = md5_file ($file['tmp_name']);
$name = str_replace (NL, '', trim ($file['name']));
/* Create delete code. */
$delete_link_code = jirafeau_gen_random (8);
- /* md5 password or empty */
+ /* md5 password or empty. */
$password = '';
if (!empty ($key))
$password = md5 ($key);
fwrite ($handle,
$name . NL. $mime_type . NL. $size . NL. $password . NL. $time .
NL . $md5. NL . ($one_time_download ? 'O' : 'R') . NL . date ('U') .
- NL . $ip . NL. $delete_link_code . NL);
+ NL . $ip . NL. $delete_link_code . NL . ($crypted ? 'C' : 'O'));
fclose ($handle);
$md5_link = base_16_to_64 (md5_file ($link_tmp_name));
$l = s2p ("$md5_link");
}
return (array ('error' => $noerr,
'link' => $md5_link,
- 'delete_link' => $delete_link_code));
+ 'delete_link' => $delete_link_code,
+ 'crypt_key' => $crypt_key));
}
/**
$out['upload_date'] = trim ($c[7]);
$out['ip'] = trim ($c[8]);
$out['link_code'] = trim ($c[9]);
+ if (trim ($c[10]) == 'C')
+ $out['crypted'] = true;
return $out;
}
* Finalyze an asynchronous upload.
* @param $ref asynchronous upload reference
* @param $code client code for this operation
+ * @param $crypt boolean asking to crypt or not
* @return a string containing the download reference followed by a delete code or the string "Error"
*/
function
-jirafeau_async_end ($ref, $code)
+jirafeau_async_end ($ref, $code, $crypt)
{
/* Get async infos. */
$a = jirafeau_get_async_ref ($ref);
$p = VAR_ASYNC . s2p ($ref) . $ref . "_data";
if (!file_exists($p))
return "Error";
+
+ $crypted = false;
+ $crypt_key = '';
+ if ($crypt == true && extension_loaded('mcrypt'))
+ {
+ $cypt_key = jirafeau_encrypt_file ($p, $p);
+ if (strlen($crypt_key) > 0)
+ $crypted = true;
+ }
+
$md5 = md5_file ($p);
$size = filesize($p);
$np = s2p ($md5);
fwrite ($handle,
$a['file_name'] . NL . $a['mime_type'] . NL . $size . NL .
$a['key'] . NL . $a['time'] . NL . $md5 . NL . $a['onetime'] . NL .
- date ('U') . NL . $a['ip'] . NL . $delete_link_code . NL);
+ date ('U') . NL . $a['ip'] . NL . $delete_link_code . NL . ($crypted ? 'C' : 'O'));
fclose ($handle);
$md5_link = base_16_to_64 (md5_file ($link_tmp_name));
$l = s2p ("$md5_link");
/* Clean async upload. */
jirafeau_async_delete ($ref);
- return $md5_link . NL . $delete_link_code;
+ return $md5_link . NL . $delete_link_code . NL . urlencode($crypt_key);
}
/**
return $count;
}
+/**
+ * Crypt file and returns decrypt key.
+ * @param $fp_src file path to the file to crypt.
+ * @param $fp_dst file path to the file to write crypted file (could be the same).
+ * @return decrypt key composed of the key and the iv separated by a point ('.')
+ */
+function
+jirafeau_encrypt_file ($fp_src, $fp_dst)
+{
+ $fs = filesize ($fp_src);
+ if ($fs === false || $fs == 0 || !extension_loaded('mcrypt'))
+ return '';
+
+ /* Prepare module. */
+ $m = mcrypt_module_open('rijndael-256', '', 'ofb', '');
+ $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($m), MCRYPT_DEV_URANDOM);
+ /* Generate key. */
+ $ks = mcrypt_enc_get_key_size($m);
+ $key = substr(md5(jirafeau_gen_random(12)), 0, $ks);
+ /* Init module. */
+ mcrypt_generic_init($m, $key, $iv);
+ /* Crypt file. */
+ $r = fopen ($fp_src, 'r');
+ $w = fopen ($fp_dst, 'c');
+ while (!feof ($r))
+ {
+ $enc = mcrypt_generic($m, fread ($r, 1024));
+ if (fwrite ($w, $enc) === false)
+ return '';
+ }
+ fclose ($r);
+ fclose ($w);
+ /* Cleanup. */
+ mcrypt_generic_deinit($m);
+ mcrypt_module_close($m);
+ return $key . "." . base64_encode($iv);
+}
+
+/**
+ * Decrypt file.
+ * @param $fp_src file path to the file to decrypt.
+ * @param $fp_dst file path to the file to write decrypted file (could be the same).
+ * @param $k string composed of the key and the iv separated by a point ('.')
+ * @return key used to decrypt. a string of length 0 is returned if failed.
+ */
+function
+jirafeau_decrypt_file ($fp_src, $fp_dst, $k)
+{
+ $fs = filesize ($fp_src);
+ if ($fs === false || $fs == 0 || !extension_loaded('mcrypt'))
+ return false;
+
+ /* Extract key and iv. */
+ $ex = explode (".", $k);
+ $key = $ex[0];
+ $iv = base64_decode($ex[1]);
+ /* Init module */
+ $m = mcrypt_module_open('rijndael-256', '', 'ofb', '');
+ mcrypt_generic_init($m, $key, $iv);
+ /* Decrypt file. */
+ $r = fopen ($fp_src, 'r');
+ $w = fopen ($fp_dst, 'c');
+ while (!feof ($r))
+ {
+ $dec = mdecrypt_generic($m, fread ($r, 1024));
+ if (fwrite ($w, $dec) === false)
+ return false;
+ }
+ fclose ($r);
+ fclose ($w);
+ /* Cleanup. */
+ mcrypt_generic_deinit($m);
+ mcrypt_module_close($m);
+ return true;
+}
?>
return ($text);\r
}\r
\r
-?>
\ No newline at end of file
+?>\r
}\r
$res = jirafeau_upload ($_FILES['file'],\r
isset ($_POST['one_time_download']),\r
- $key, $time, $_SERVER['REMOTE_ADDR']);\r
+ $key, $time, $_SERVER['REMOTE_ADDR'],\r
+ $cfg['enable_crypt']);\r
\r
if (empty($res) || $res['error']['has_error'])\r
{\r
}\r
/* Print direct link. */\r
echo $res['link'];\r
- echo NL;\r
/* Print delete link. */\r
+ echo NL;\r
echo $res['delete_link'];\r
+ /* Print decrypt key. */\r
+ echo NL;\r
+ echo urlencode($res['crypt_key']);\r
}\r
elseif (isset ($_GET['h']))\r
{\r
|| !isset ($_POST['code']))\r
echo "Error";\r
else\r
- echo jirafeau_async_end ($_POST['ref'], $_POST['code']);\r
+ echo jirafeau_async_end ($_POST['ref'], $_POST['code'], $cfg['enable_crypt']);\r
}\r
/* Initialize block. */\r
elseif (isset ($_GET['init_block']) && $cfg['enable_blocks'])\r