X-Git-Url: https://git.p6c8.net/jirafeau.git/blobdiff_plain/e4f9c92ff84f6146aaf1244147082efd57e289f6..0d67e0ca4e449915d0548819f1f09a29dae52c9a:/lib/functions.php diff --git a/lib/functions.php b/lib/functions.php index b26d7b4..2c799f2 100644 --- a/lib/functions.php +++ b/lib/functions.php @@ -2,7 +2,7 @@ /* * Jirafeau, your web file repository * Copyright (C) 2008 Julien "axolotl" BERNARD - * Copyright (C) 2012 Jerome Jutteau + * Copyright (C) 2015 Jerome Jutteau * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -98,6 +98,9 @@ function is_ssl() { return true; } elseif ( isset($_SERVER['SERVER_PORT']) && ( '443' == $_SERVER['SERVER_PORT'] ) ) { return true; + } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) { + if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') + return true; } return false; } @@ -443,7 +446,7 @@ jirafeau_upload ($file, $one_time_download, $key, $time, $ip, $crypt, $link_name } /** - * tells if a mime-type is viewable in a browser + * Tells if a mime-type is viewable in a browser * @param $mime the mime type * @returns a boolean telling if a mime type is viewable */ @@ -453,7 +456,7 @@ jirafeau_is_viewable ($mime) if (!empty ($mime)) { /* Actually, verify if mime-type is an image or a text. */ - $viewable = array ('image', 'text'); + $viewable = array ('image', 'text', 'video', 'audio'); $decomposed = explode ('/', $mime); return in_array ($decomposed[0], $viewable); } @@ -611,7 +614,7 @@ jirafeau_admin_list ($name, $file_hash, $link_hash) continue; /* Filter. */ - if (!empty ($name) && !preg_match ("/$name/i", $l['file_name'])) + if (!empty ($name) && !preg_match ("/$name/i", htmlspecialchars($l['file_name']))) continue; if (!empty ($file_hash) && $file_hash != $l['md5']) continue; @@ -623,7 +626,7 @@ jirafeau_admin_list ($name, $file_hash, $link_hash) '
' . '' . '' . - '' . + '' . '
'; echo ''; echo '' . $l['mime_type'] . ''; @@ -841,10 +844,11 @@ jirafeau_async_init ($filename, $type, $one_time, $key, $time, $ip) * @param $ref asynchronous upload reference * @param $file piece of data * @param $code client code for this operation + * @param $max_file_size maximum allowed file size * @return a string containing a next code to use or the string "Error" */ function -jirafeau_async_push ($ref, $data, $code) +jirafeau_async_push ($ref, $data, $code, $max_file_size) { /* Get async infos. */ $a = jirafeau_get_async_ref ($ref); @@ -858,9 +862,21 @@ jirafeau_async_push ($ref, $data, $code) $p = s2p ($ref); + /* File path. */ + $r_path = $data['tmp_name']; + $w_path = VAR_ASYNC . $p . $ref . '_data'; + + /* Check that file size is not above upload limit. */ + if ($max_file_size > 0 && + filesize ($r_path) + filesize ($w_path) > $max_file_size * 1024 * 1024) + { + jirafeau_async_delete ($ref); + return "Error"; + } + /* Concatenate data. */ - $r = fopen ($data['tmp_name'], 'r'); - $w = fopen (VAR_ASYNC . $p . $ref . '_data', 'a'); + $r = fopen ($r_path, 'r'); + $w = fopen ($w_path, 'a'); while (!feof ($r)) { if (fwrite ($w, fread ($r, 1024)) === false) @@ -873,7 +889,7 @@ jirafeau_async_push ($ref, $data, $code) } fclose ($r); fclose ($w); - unlink ($data['tmp_name']); + unlink ($r_path); /* Update async file. */ $code = jirafeau_gen_random (4); @@ -891,7 +907,7 @@ jirafeau_async_push ($ref, $data, $code) * @param $ref asynchronous upload reference * @param $code client code for this operation * @param $crypt boolean asking to crypt or not - * @param $link_name_length link name lenght + * @param $link_name_length link name length * @return a string containing the download reference followed by a delete code or the string "Error" */ function @@ -1068,3 +1084,97 @@ function jirafeau_challenge_upload_password ($cfg, $password) return false; } +/** + * Test if visitor's IP is authorized to upload. + * @param $ip IP to be challenged + * @return true if IP is authorized, false otherwise. + */ +function jirafeau_challenge_upload_ip ($cfg, $ip) +{ + if (count ($cfg['upload_ip']) == 0) + return true; + forEach ($cfg['upload_ip'] as $i) + { + if ($i == $ip) + return true; + // CIDR test for IPv4 only. + if (strpos ($i, '/') !== false) + { + list ($subnet, $mask) = explode('/', $i); + if ((ip2long ($ip) & ~((1 << (32 - $mask)) - 1) ) == ip2long ($subnet)) + return true; + } + } + return false; +} + +/** Tell if we have some HTTP headers generated by a proxy */ +function has_http_forwarded() +{ + if (!empty ($_SERVER['HTTP_X_FORWARDED_FOR'])) + return true; + if (!empty ($_SERVER['http_X_forwarded_for'])) + return true; + return false; +} + +/** + * Generate IP list from HTTP headers generated by a proxy + * return array of IP strings + */ +function get_ip_list_http_forwarded() +{ + $ip_list = array(); + if (!empty ($_SERVER['HTTP_X_FORWARDED_FOR'])) + { + $l = explode (',', $_SERVER['HTTP_X_FORWARDED_FOR']); + foreach ($l as $ip) + array_push ($ip_list, preg_replace ('/\s+/', '', $ip)); + } + if (!empty ($_SERVER['http_X_forwarded_for'])) + { + $l = explode (',', $_SERVER['http_X_forwarded_for']); + foreach ($l as $ip) + { + // Separate IP from port + $ip = explode (':', $ip)[0]; + array_push ($ip_list, preg_replace ('/\s+/', '', $ip)); + } + } + return $ip_list; +} + +/** + * Get the ip address of the client from REMOTE_ADDR + * or from HTTP_X_FORWARDED_FOR if behind a proxy + * @returns an the client ip address + */ +function get_ip_address($cfg) { + $remote = $_SERVER['REMOTE_ADDR']; + if (count ($cfg['proxy_ip']) == 0 || !has_http_forwarded ()) + return $remote; + + $ip_list = get_ip_list_http_forwarded (); + if (count ($ip_list) == 0) + return $remote; + + foreach ($cfg['proxy_ip'] as $proxy_ip) + { + if ($remote != $proxy_ip) + continue; + // Take the last IP (the one which has been set by the defined proxy). + return end ($ip_list); + } + return $remote; +} + +/** + * Convert hexadecimal string to base64 + */ +function hex_to_base64($hex) +{ + $b = ''; + foreach (str_split ($hex, 2) as $pair) + $b .= chr (hexdec ($pair)); + return base64_encode ($b); +}