diff --git a/security/acme-client/pkg-descr b/security/acme-client/pkg-descr index d9d83c57b..8f7f21ace 100644 --- a/security/acme-client/pkg-descr +++ b/security/acme-client/pkg-descr @@ -13,10 +13,12 @@ Plugin Changelog Added: * new automation to reload www/caddy (#4692) * add support for Websupport.sk DNS API (#4540) +* add SFTP option: Preserve Modification Time (#3862) Changed: * automatically fix account config if CERT_HOME is set (#4622) * automatically resolve cron job mismatch (#4627) +* change default SFTP options to NOT preserve modification time (#3862) Fixed: * deploy hooks may use the old CERT_HOME (#4622) diff --git a/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/forms/dialogAction.xml b/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/forms/dialogAction.xml index a2fb434eb..292fd9c23 100644 --- a/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/forms/dialogAction.xml +++ b/security/acme-client/src/opnsense/mvc/app/controllers/OPNsense/AcmeClient/forms/dialogAction.xml @@ -68,6 +68,12 @@ The path can be absolute or relative to home and must exist. Leave blank to not change path after login. + + action.sftp_modtime + + checkbox + Preserves modification times from the source file. Note that this is not supported by all SFTP servers and may cause the upload to fail, e.g. on VMware + action.sftp_chmod diff --git a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/SftpUploader.php b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/SftpUploader.php index 353495880..d7b5df79a 100644 --- a/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/SftpUploader.php +++ b/security/acme-client/src/opnsense/mvc/app/library/OPNsense/AcmeClient/SftpUploader.php @@ -1,6 +1,7 @@ $local_file, "target" => $remote_file, "mode" => $chmod, - "group" => $chgrp + "group" => $chgrp, + "modtime" => $modtime ]; return $local_file; @@ -94,9 +99,10 @@ class SftpUploader * @param int $content_last_modified the unix timestamp when the content was last modified (is preserved when chmod is also specified). * @param bool $chmod the 4 digit unix permission to apply or false to leave it unchanged. * @param bool $chgrp the numeric group on the remote server to apply or false to leave it unchanged. + * @param bool $modtime a boolean to indicate that the modification times should be preserved. * @return string the name of the remote file. */ - public function addContent(string $content, string $remote_file = "", $content_last_modified = 0, $chmod = false, $chgrp = false): string + public function addContent(string $content, string $remote_file = "", $content_last_modified = 0, $chmod = false, $chgrp = false, $modtime = false): string { $local_file = $this->temporaryFile(); Utils::requireThat($local_file, "Failed creating temporary file for '$remote_file'"); @@ -113,7 +119,7 @@ class SftpUploader $remote_file = basename($local_file); } - $local_file = $this->addFile($local_file, $remote_file, $chmod, $chgrp); + $local_file = $this->addFile($local_file, $remote_file, $chmod, $chgrp, $modtime); $this->pending_files[$local_file]["delete_source"] = true; return $remote_file; @@ -252,16 +258,24 @@ class SftpUploader $chmod = $file["mode"] ?? ""; $chmod = preg_match('/^0\d{3}$/', $chmod) ? (string)$chmod : false; + // Preserving the modification time is not supported by all SFTP servers. + $preserve = $file["modtime"]; + if ($preserve !== false) { + LeUtils::log("Sftp upload will try to preserve file modification time"); + } else { + LeUtils::log("Sftp upload will not preserve file modification time"); + } // Initial upload when permissions are properly set. $should_upload_with_permission_change = $chmod !== false && isset($remote_files[$remote_filename]); + // Upload file. if (!$remote_is_readonly) { $preserve_times_and_mod = $chmod !== false; - if ($error = $this->sftp->put($local_file, $remote_filename, $preserve_times_and_mod)->lastError()) { + if ($error = $this->sftp->put($local_file, $remote_filename, $preserve)->lastError()) { if ($error["permission_denied"] !== true) { $should_upload_with_permission_change = false; } @@ -281,11 +295,13 @@ class SftpUploader if ($should_upload_with_permission_change && $this->isFileOwnedByConnection($remote_file, $connection)) { Utils::log()->info("Trying to upload file '{$local_file}' to '{$file["target"]}' with adjusted permissions"); + // Change file permission to make it writable. if ($error = $this->sftp->chmod($remote_filename, '0600')->lastError()) { Utils::log()->error("Failed changing permission to '0600' for '{$file["target"]}'. ", $error); $this->sftp->clearError(); } + // Try again to upload file. if ($error = $this->sftp->put($local_file, $remote_filename)->lastError()) { Utils::log()->error("Failed uploading file (with adjusted permissions) '{$local_file}' to '{$file["target"]}'", $error); return self::UPLOAD_ERROR_NO_PERMISSION; diff --git a/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/AcmeClient.xml b/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/AcmeClient.xml index 4a3a31dcf..8d4b88475 100644 --- a/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/AcmeClient.xml +++ b/security/acme-client/src/opnsense/mvc/app/models/OPNsense/AcmeClient/AcmeClient.xml @@ -1,6 +1,6 @@ //OPNsense/AcmeClient - 4.2.0 + 4.3.0 A secure ACME Client plugin @@ -1410,6 +1410,10 @@ /^0[0-9]{3}$/u A unix permission, 4 digits (e.g. 0400). + + N + 0 + N /^(?![\/\\])[\w\d_\-@.\/{}%]{1,255}(?<![\/\\])$/ui