]> git.p6c8.net - jirafeau.git/commitdiff
add function to check or generate file download passwords
authorgwunderlich <gwunderlich@cocus.com>
Fri, 2 Sep 2022 12:57:39 +0000 (14:57 +0200)
committerJérôme Jutteau <jerome@jutteau.fr>
Wed, 14 Dec 2022 09:06:46 +0000 (09:06 +0000)
README.md
docker/README.md
docker/docker_config.php
index.php
lib/config.original.php
lib/functions.js.php
lib/functions.php
script.php

index 9105c7ff044ee2c9ed4b9b4337b3ab85358149bc..f48f4cc3a193d6f69fa58244bc9650b4b651c0a3 100644 (file)
--- a/README.md
+++ b/README.md
@@ -20,6 +20,7 @@ See [jirafeau.net](https://jirafeau.net/) for a demo.
 - Shows progression: speed, percentage and remaining upload time
 - Preview content in browser (if possible)
 - Optional password protection (for uploading or downloading)
+- option to require, check or generate file download passwords
 - Set expiration time for downloads
 - Option to self-destruct after first download
 - Shortened URLs using base 64 encoding
index daf5302bb4f202722b5d290194406adf6c03c841..8d367ea48dffb456855f48a17f084516dbeb66e4 100644 (file)
@@ -52,6 +52,11 @@ Available options:
 - `UPLOAD_IP_NO_PASSWORD`: set one or more ip allowed to upload files without password (separated by comma).
 - `PROXY_IP`: set one or more proxy ip (separated by comma).
 - `STORE_UPLOADER_IP`: set to 1 or 0 to enable or disable keeping sender's IP with the _link_ file.
+- `DOWNLOAD_PASSWORD_REQUIREMENT`: set to 'optional' (default), 'required' or 'generated' to make a password for downloading optional, required or generated
+- `DOWNLOAD_PASSWORD_GEN_LEN`: set length of generated download passwords
+- `DOWNLOAD_PASSWORD_GEN_CHARS`: set characters used for generated download passwords
+- `DOWNLOAD_PASSWORD_POLICY`: set to 'regex' to use a regular expression to check user provided download passwords for complexity constraints
+- `DOWNLOAD_PASSWORD_POLICY_REGEX`: regex to check against if password policy is set to regex
 
 Example:
 ```
index 6a03b7360aebd63308c0ac8ea49cde3f85e612f1..8c63134df26862039eb32f1c39d65a1024dd8f89 100644 (file)
@@ -175,6 +175,11 @@ function run_setup(&$cfg)
     env_2_cfg_string_array($cfg, 'upload_ip_nopassword');
     env_2_cfg_string_array($cfg, 'proxy_ip');
     env_2_cfg_bool($cfg, 'store_uploader_ip');
+    env_2_cfg_string($cfg, 'download_password_requirement');
+    env_2_cfg_int($cfg, 'download_password_gen_len');
+    env_2_cfg_string($cfg, 'download_password_gen_chars');
+    env_2_cfg_string($cfg, 'download_password_policy');
+    env_2_cfg_string($cfg, 'download_password_policy_regex');
 
     if ($setup_ok) {
         $cfg['installation_done'] = true;
index b6dac09040a714ee8fb8aff50cc590d6e01cb7c8..24ce25c48237af1baed5e5a5c5fee38b8b5a97bc 100644 (file)
--- a/index.php
+++ b/index.php
@@ -25,6 +25,10 @@ require(JIRAFEAU_ROOT . 'lib/settings.php');
 require(JIRAFEAU_ROOT . 'lib/functions.php');
 require(JIRAFEAU_ROOT . 'lib/lang.php');
 
+if ($cfg['download_password_requirement'] === "generated"){
+    $download_pass = jirafeau_gen_download_pass();
+}
+
 check_errors($cfg);
 if (has_error()) {
     require(JIRAFEAU_ROOT . 'lib/template/header.php');
@@ -108,6 +112,21 @@ elseif (true === jirafeau_challenge_upload_ip($cfg, get_ip_address($cfg))) {
     </p>
     </div>
 
+    <?php if ($cfg['download_password_requirement'] === "generated"){
+    ?>
+    <div id="show_password">
+    <p><?php echo t('PSW') ?></p>
+
+    <div id="download_password">
+    <p>
+        <?php echo '<input id="output_key" value="' . $download_pass . '"/>'?>
+        <button id="password_copy_button">&#128203;</button>
+    </p>
+    </div>
+    </div>
+    <?php
+    }?>
+
     <?php if ($cfg['preview'] == true) {
         ?>
     <div id="upload_finished_preview">
@@ -176,15 +195,23 @@ elseif (true === jirafeau_challenge_upload_ip($cfg, get_ip_address($cfg))) {
     <div id="options">
         <table id="option_table">
         <?php
-    if ($cfg['one_time_download']) {
-        echo '<tr><td>' . t('ONE_TIME_DL') . ':</td>';
-        echo '<td><input type="checkbox" id="one_time_download" /></td></tr>';
-    }
-?>
-        <tr>
-        <td><label for="input_key"><?php echo t('PSW') . ':'; ?></label></td>
-        <td><input type="password" name="key" id="input_key" autocomplete = "new-password"/></td>
-        </tr>
+        if ($cfg['one_time_download']) {
+            echo '<tr><td>' . t('ONE_TIME_DL') . ':</td>';
+            echo '<td><input type="checkbox" id="one_time_download" /></td></tr>';
+        }
+        if ($cfg['download_password_requirement'] === 'generated'){
+            echo '<input type="hidden" name="key" id="input_key" value="' . $download_pass .'"/>';
+        }else{
+            echo '<tr><td><label for="input_key">' . t('PSW') . ':' . '</label></td>';
+            echo '<td><input type="password" name="key" id="input_key" autocomplete = "new-password"';
+            if ($cfg['download_password_policy'] === 'regex'){
+                echo ' pattern="' . substr($cfg['download_password_policy_regex'], 1, strlen($cfg['download_password_policy_regex']) - 2) . '"'; //remove php delimiters
+            }
+            if ($cfg['download_password_requirement'] === 'required'){
+                echo ' required';
+            }
+            echo '/></td></tr>';
+        }?>
         <tr>
         <td><label for="select_time"><?php echo t('TIME_LIM') . ':'; ?></label></td>
         <td><select name="time" id="select_time">
@@ -294,6 +321,7 @@ if ($max_size > 0) {
     addCopyListener('preview_link_button', 'preview_link');
     addCopyListener('direct_link_button', 'direct_link');
     addCopyListener('delete_link_button', 'delete_link');
+    addTextCopyListener('password_copy_button', 'output_key');
 // @license-end
 </script>
 <?php require(JIRAFEAU_ROOT . 'lib/template/footer.php'); ?>
index 1f2e8b7073b441454bea055c5843c876371085c5..c666d03fa169c9e675f0f4e96f4f4f04c26b076c 100644 (file)
@@ -222,3 +222,29 @@ $cfg['debug'] = false;
  * Set to 0 to remove limitation.
  */
 $cfg['max_upload_chunk_size_bytes'] = 100000000; // 100MB
+
+/* Set password requirement policy for downloading files
+ * Possible values:
+ * optional (default): Password may be set by the uploader, but is not mandatory
+ * required: Setting a password is mandatory to upload a file.
+ * generated: Passwords are automatically generated and shown to the uploader, when uploading a file
+ */
+$cfg['download_password_requirement'] = 'optional';
+
+/* Set length of generated passwords
+ */
+$cfg['download_password_gen_len'] = 10;
+
+/* Set allowed chars for password generation
+ */
+$cfg['download_password_gen_chars'] = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*()_-=+;:,.?';
+/* Set password complexity policy for downloading files
+ * possible values:
+ * none (default): Passwords for downloading files can be of arbitrary complexity
+ * regex: Passwords are checked with a regex for complexity constraints
+ */
+$cfg['download_password_policy'] = 'none';
+/* Set the regex for regex download password policy
+ * Delimiters are need, but modifiers should not be used
+ */
+$cfg['download_password_policy_regex'] = '/.*/';
index 50aa2f07be3d9d76a358eb40a6df3ef396f5abb9..58623e6b2c053d91c41bc028269632a87331601e 100644 (file)
@@ -786,6 +786,21 @@ function addCopyListener(button_id, link_id) {
     }
 }
 
+function copyTextToClipboard(text_id){
+    var copyText = document.getElementById(text_id);
+    copyText.select();
+    copyText.setSelectionRange(0, 99999); 
+    navigator.clipboard.writeText(copyText.value);
+}
+
+function addTextCopyListener(button_id, text_id) {
+    if(document.getElementById(button_id)){
+        document.getElementById(button_id)
+            .addEventListener("click", function() {
+                copyTextToClipboard(text_id);});
+    }
+}
+
 function set_dark_mode() {
     let steel_sheet = "<?php echo 'media/' . $cfg['dark_style'] . '/style.css.php'; ?>";
     let shortcut_icon = "<?php echo 'media/' . $cfg['dark_style'] . '/favicon.ico'; ?>";
index cfb27033d84dc8cda4a26b11a34f472937d7c35b..ebfffd41f7040f2be8beda0a0901259523d88026 100644 (file)
@@ -101,6 +101,21 @@ function jirafeau_gen_random($l)
     return $code;
 }
 
+function jirafeau_gen_download_pass()
+{
+    $length = $cfg['download_password_gen_len'];
+    $allowed_chars = $cfg['download_password_gen_chars'];
+    if ($length <= 0) {
+        return false;
+    }
+    $pass="";
+    for ($i = 0; $i < $length; $i++) {
+        $pass .= $allowed_chars[rand(0, strlen($allowed_chars) - 1)];
+    }
+
+    return $pass;
+}
+
 function is_ssl()
 {
     if (isset($_SERVER['HTTPS'])) {
index b861a47db7d8a9a8c4d8cd50470dd6aa19bcbc1e..40d26eaf5148aa186052e2b0f9bd6b04974d76b5 100644 (file)
@@ -81,6 +81,15 @@ if (isset($_FILES['file']) && is_writable(VAR_FILES)
     $key = '';
     if (isset($_POST['key'])) {
         $key = $_POST['key'];
+        if ($cfg['download_password_requirement'] !== 'generated' && $cfg['download_password_policy'] === 'regex'){
+            if (!preg_match($cfg['download_password_policy_regex'], $key)){
+                echo 'Error 14: The download password is not complying to the security standards.';
+                exit;
+            }
+        }
+    }elseif ($cfg['download_password_requirement'] !== 'optional'){
+        echo 'Error 13: The parameter password is required.';
+        exit;
     }
 
     $time = time();

patrick-canterino.de