diff --git a/e107_plugins/download/includes/admin.php b/e107_plugins/download/includes/admin.php index e992375aa..8cf6abd51 100644 --- a/e107_plugins/download/includes/admin.php +++ b/e107_plugins/download/includes/admin.php @@ -286,7 +286,11 @@ class download_main_admin_ui extends e_admin_ui //required - default column user prefs protected $fieldpref = array('checkboxes', 'download_image', 'download_id', 'download_datestamp', 'download_category', 'download_name', 'download_active', 'download_class', 'fb_order', 'options'); - // + // Security modes + protected $security_options = array( + 'none' => LAN_DL_SECURITY_MODE_NONE, + 'nginx-secure_link_md5' => LAN_DL_SECURITY_MODE_NGINX_SECURELINKMD5 + ); // optional - required only in case of e.g. tables JOIN. This also could be done with custom model (set it in init()) //protected $editQry = "SELECT * FROM #release WHERE release_id = {ID}"; @@ -1149,6 +1153,19 @@ $columnInfo = array( if ($_POST['download_subsub']) $temp['download_subsub'] = '1'; else $temp['download_subsub'] = '0'; if ($_POST['download_incinfo']) $temp['download_incinfo'] = '1'; else $temp['download_incinfo'] = '0'; + + if ($_POST['download_security_mode'] === 'nginx-secure_link_md5') + { + $temp['download_security_mode'] = $_POST['download_security_mode']; + $temp['download_security_expression'] = $_POST['download_security_expression']; + $temp['download_security_link_expiry'] = $_POST['download_security_link_expiry']; + } + else + { + e107::getConfig('core')->removePref('download_security_mode'); + e107::getConfig('core')->removePref('download_security_expression'); + e107::getConfig('core')->removePref('download_security_link_expiry'); + } e107::getConfig('core')->setPref($temp)->save(false); @@ -2115,14 +2132,15 @@ $columnInfo = array( "ASC" => DOWLAN_62, "DESC" => DOWLAN_63 ); - + $text = "
\n @@ -2226,6 +2244,39 @@ $columnInfo = array(
+
+

+ ".LAN_DL_SECURITY_DESCRIPTION." +

+ + + + + + + + + + + + + + + + + + + +
".LAN_DL_SECURITY_MODE."".$frm->select('download_security_mode', $this->security_options, $pref['download_security_mode'])."
".LAN_DL_SECURITY_NGINX_SECURELINKMD5_EXPRESSION." + ".$frm->text('download_security_expression', $pref['download_security_expression'], 1024)." +
".LAN_DL_SECURITY_NGINX_SECURELINKMD5_EXPRESSION_HELP."
+
".LAN_DL_SECURITY_LINK_EXPIRY." + ".$frm->text('download_security_link_expiry', $pref['download_security_link_expiry'], 16, array('pattern' => '\d+'))." +
".LAN_DL_SECURITY_LINK_EXPIRY_HELP."
+
+
+
+
@@ -2246,7 +2297,20 @@ $columnInfo = array( "; - // $ns->tablerender(LAN_DL_OPTIONS, $text); + + e107::js('footer-inline', " + $('#download-security-mode').on('change', function() { + var mode = $(this).val(); + + if (mode == 'nginx-secure_link_md5') { + $('#nginx-secure_link_md5').show('slow'); + return; + } + + $('#nginx-secure_link_md5').hide('slow'); + }); + "); + echo $text; } diff --git a/e107_plugins/download/includes/shim_http_build_url.php b/e107_plugins/download/includes/shim_http_build_url.php new file mode 100644 index 000000000..99b3337a3 --- /dev/null +++ b/e107_plugins/download/includes/shim_http_build_url.php @@ -0,0 +1,104 @@ + + +define("LAN_DL_SECURITY_DESCRIPTION", "Downloads can make use of server-side URL protection features to prevent hotlinking and/or enforce link expiry. " . + "The download server needs to be configured first before setting the options below."); +define("LAN_DL_SECURITY_MODE", "URL protection mode"); +define("LAN_DL_SECURITY_MODE_NONE", "None (Default)"); +define("LAN_DL_SECURITY_MODE_NGINX_SECURELINKMD5", "NGINX secure_link_md5"); +define("LAN_DL_SECURITY_NGINX_SECURELINKMD5_EXPRESSION", + "NGINX secure_link_md5 expression"); +define("LAN_DL_SECURITY_NGINX_SECURELINKMD5_EXPRESSION_HELP", "Same expression as configured on the server"); +define("LAN_DL_SECURITY_LINK_EXPIRY", "Duration of validity in seconds"); +define("LAN_DL_SECURITY_LINK_EXPIRY_HELP", "Number of seconds the download link should last after being generated. " . + "Only effective if the expression supports expiry time. " . + "Defaults to a very long time if this field is left blank."); \ No newline at end of file diff --git a/e107_plugins/download/plugin.xml b/e107_plugins/download/plugin.xml index 08dcdcb01..ece353f73 100755 --- a/e107_plugins/download/plugin.xml +++ b/e107_plugins/download/plugin.xml @@ -1,7 +1,7 @@ - + - This plugin is a fully featured File-download system + This plugin is a fully featured file download system content DOWLAN_CAPTION diff --git a/e107_plugins/download/request.php b/e107_plugins/download/request.php index fecf3c75c..346eae424 100644 --- a/e107_plugins/download/request.php +++ b/e107_plugins/download/request.php @@ -72,7 +72,7 @@ if(strstr(e_QUERY, "mirror")) } $sql->update("download", "download_requested = download_requested + 1, download_mirror = '{$mstr}' WHERE download_id = '".intval($download_id)."'"); $sql->update("download_mirror", "mirror_count = mirror_count + 1 WHERE mirror_id = '".intval($mirror_id)."'"); - header("Location: {$gaddress}"); + header("Location: ".decorate_download_location($gaddress)); exit(); } @@ -189,7 +189,7 @@ if ($type == "file") $sql->update("download", "download_requested = download_requested + 1, download_mirror = '{$mstr}' WHERE download_id = '".intval($download_id)."'"); $sql->update("download_mirror", "mirror_count = mirror_count + 1 WHERE mirror_id = '".intval($mirror_id)."'"); - header("Location: ".$gaddress); + header("Location: ".decorate_download_location($gaddress)); exit(); } @@ -217,7 +217,7 @@ if ($type == "file") if (strstr($download_url, "http://") || strstr($download_url, "ftp://") || strstr($download_url, "https://")) { $download_url = e107::getParser()->parseTemplate($download_url,true); // support for shortcode-driven dynamic URLS. - e107::redirect($download_url); + e107::redirect(decorate_download_location($download_url)); // header("Location: {$download_url}"); exit(); } @@ -435,4 +435,35 @@ function check_download_limits() } } -?> +function decorate_download_location($url) +{ + $pref = e107::getPref(); + if ($pref['download_security_mode'] !== 'nginx-secure_link_md5') + return $url; + $expiry = intval($pref['download_security_link_expiry']); + if ($expiry <= 0) + $expiry = PHP_INT_MAX; + else + $expiry = time() + $expiry; + $url_parts = parse_url($url); + $evaluation = str_replace( + array( + '$secure_link_expires', + '$uri', + '$remote_addr' + ), + array( + $expiry, + $url_parts['path'], + $_SERVER['REMOTE_ADDR'] + ), + $pref['download_security_expression'] + ); + $query_string = $url_parts['query']; + parse_str($query_string, $query_args); + $query_args['md5'] = md5($evaluation); + if (strpos($pref['download_security_expression'], '$secure_link_expires') !== false) + $query_args['expires'] = $expiry; + require_once(__DIR__.'/includes/shim_http_build_url.php'); + return http_build_url($url_parts, array('query' => http_build_query($query_args))); +} \ No newline at end of file