aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2020-06-10 19:36:53 +0200
committerMichael Albinus2020-06-10 19:36:53 +0200
commitb19259c8412ee2e715c4bd145711e23729411fd0 (patch)
tree6e79f2d9bc1dd3ab3533380faa441e5564eb7149
parentee8b2742d7f6d03daea37f1bac48c2746f7ca789 (diff)
downloademacs-b19259c8412ee2e715c4bd145711e23729411fd0.tar.gz
emacs-b19259c8412ee2e715c4bd145711e23729411fd0.zip
Futher tramp-crypt implementation and documentation
* doc/misc/tramp.texi (Top, Configuration): Insert section `Keeping files encrypted' in menu. (Keeping files encrypted): New node. * lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist): Add `tramp-set-file-uid-gid'. (tramp-crypt-maybe-open-connection): Simplify. (tramp-crypt-do-encrypt-or-decrypt-file): Use `binary' coding system. (tramp-crypt-handle-set-file-uid-gid): New defun. * test/lisp/net/tramp-tests.el (tramp-test09-insert-file-contents): Adapt test.
-rw-r--r--doc/misc/tramp.texi118
-rw-r--r--lisp/net/tramp-crypt.el19
-rw-r--r--test/lisp/net/tramp-tests.el25
3 files changed, 144 insertions, 18 deletions
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index d1688deb1b7..176d3a5b1e0 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -141,6 +141,7 @@ Configuring @value{tramp} for use
141* Remote shell setup:: Remote shell setup hints. 141* Remote shell setup:: Remote shell setup hints.
142* Android shell setup:: Android shell setup hints. 142* Android shell setup:: Android shell setup hints.
143* Auto-save and Backup:: Auto-save and Backup. 143* Auto-save and Backup:: Auto-save and Backup.
144* Keeping files encrypted:: Protect remote files by encryption.
144* Windows setup hints:: Issues with Cygwin ssh. 145* Windows setup hints:: Issues with Cygwin ssh.
145 146
146Using @value{tramp} 147Using @value{tramp}
@@ -667,6 +668,7 @@ might be used in your init file:
667* Remote shell setup:: Remote shell setup hints. 668* Remote shell setup:: Remote shell setup hints.
668* Android shell setup:: Android shell setup hints. 669* Android shell setup:: Android shell setup hints.
669* Auto-save and Backup:: Auto-save and Backup. 670* Auto-save and Backup:: Auto-save and Backup.
671* Keeping files encrypted:: Protect remote files by encryption.
670* Windows setup hints:: Issues with Cygwin ssh. 672* Windows setup hints:: Issues with Cygwin ssh.
671@end menu 673@end menu
672 674
@@ -2648,6 +2650,114 @@ auto-saved files to the same directory as the original file.
2648Alternatively, set the user option @code{tramp-auto-save-directory} 2650Alternatively, set the user option @code{tramp-auto-save-directory}
2649to direct all auto saves to that location. 2651to direct all auto saves to that location.
2650 2652
2653
2654@node Keeping files encrypted
2655@section Protect remote files by encryption
2656@cindex Encrypt remote directories
2657
2658Sometimes, it is desirable to protect files located on remote
2659directories, like cloud storages. In order to do this, you might
2660instruct @value{tramp} to encrypt all files copied to a given remote
2661directory, and to decrypt such files when accessing. This includes
2662both file contents and file names.
2663
2664@value{tramp} does this transparently. Although both files and file
2665names are encrypted on the remote side, they are accessible inside
2666Emacs as they wouldn't be transformed as such.
2667
2668@cindex @command{encfs}
2669@cindex @command{encfsctl}
2670Internally, @value{tramp} uses the @command{encfs} package.
2671Therefore, this feature is available only if this package is installed
2672on the local host. @value{tramp} does not keep and @samp{encfs
2673mountpoint} permanently. Instead, it encrypts / decrypts files and
2674file names on the fly, using @command{encfsctl}.
2675
2676@deffn Command tramp-crypt-add-directory name
2677This command marks the existing remote directory @var{name} for
2678encryption. Files in that directory and all subdirectories will be
2679encrypted before copying to, and decrypted after copying from that
2680directory. File and directory names will be also encrypted.
2681@end deffn
2682
2683@defopt tramp-crypt-encfs-option
2684If a remote directory is marked for encryption, it is initialized via
2685@command{encfs} the very first time a file in this directory is
2686accessed. This user option controls, which default @command{encfs}
2687configuration option will be selected, it can be @t{"--standard"}
2688or @t{"--paranoia"}. See the @samp{encfs(1)} man page for details.
2689
2690However, @value{tramp} must adapt these configuration sets. The
2691@code{chainedNameIV} configuration option must be disabled; otherwise
2692@value{tramp} couldn't handle file name encryption transparently.
2693@end defopt
2694
2695A password protected @option{encfs} configuration file is created the
2696very first time you access an encrypted remote directory. It is kept
2697in your @code{user-emacs-directory} with the url-encoded directory
2698name as part of the basename, and @file{encfs6.xml} as suffix. If
2699you, for example, mark the remote directory
2700@file{@trampfn{nextcloud,user@@host,/path/to/dir}} for encryption, the
2701configuration file is saved as
2702@file{tramp-%2Fnextcloud%3Auser%40host%3A%2Fpath%2Fto%2Fdir%2F.encfs6.xml}
2703in @code{user-emacs-directory}. Do not loose this file and the
2704corresponding password; otherwise there is no way to decrypt your
2705encrypted files.
2706
2707@defopt tramp-crypt-save-encfs-config-remote
2708If this user option is non-nil (the default), the @option{encfs}
2709configuration file @file{.encfs6.xml} is also kept in the encrypted
2710remote directory. It depends on you, whether you regard the password
2711protection of this file as sufficient. The advantage would be, that
2712such a remote directory could be accessed by different Emacs sessions,
2713different users, without presharing the configuration file between the
2714users.
2715@end defopt
2716
2717The command @command{encfsctl}, the workhorse for encryption /
2718decryption, needs the configuration file password every call.
2719Therefore, it is recommend to cache this password in Emacs. This can
2720be done using @code{auth-sources}, @ref{Using an authentication file}.
2721An entry needs the url-encoded directory name as machine, your local
2722user name as user, and the password. The port is optional, if given
2723it must be the string @t{"crypt"}. The example above would require
2724the following entry in the authentication file (@t{"yourname"} is the
2725result of @code{(user-login-name)}):
2726
2727@example
2728machine %2Fnextcloud%3Auser%40host%3A%2Fpath%2Fto%2Fdir%2F \
2729 login yourname port crypt password geheim
2730@end example
2731
2732If you use a remote file name with a quoted localname part, this
2733localname and the corresponding file will not be encrypted /
2734decrypted. If you have an encrypted remote directory
2735@file{@trampfn{nextcloud,user@@host,/path/to/dir}}, the command
2736
2737@example
2738@kbd{C-x d @trampfn{nextcloud,user@@host,/path/to/dir}}
2739@end example
2740
2741@noindent
2742will show the directory listing with the plain file names, and the
2743command
2744
2745@example
2746@kbd{C-x d @trampfn{nextcloud,user@@host,/:/path/to/dir}}
2747@end example
2748
2749@noindent
2750will show the directory listing with the encrypted file names, and
2751visiting a file will show its encrypted contents. However, it is
2752highly discouraged to mix encrypted and not encrypted files in the
2753same directory.
2754
2755@deffn Command tramp-crypt-add-directory name
2756If a remote directory shall not include encrypted files anymore, it
2757must be indicated by this command.
2758@end deffn
2759
2760
2651@node Windows setup hints 2761@node Windows setup hints
2652@section Issues with Cygwin ssh 2762@section Issues with Cygwin ssh
2653@cindex cygwin, issues 2763@cindex cygwin, issues
@@ -2681,10 +2791,10 @@ Wiki} it is explained how to use the helper program
2681@cindex @option{scpx} method with cygwin 2791@cindex @option{scpx} method with cygwin
2682 2792
2683When using the @option{scpx} access method, Emacs may call 2793When using the @option{scpx} access method, Emacs may call
2684@command{scp} with MS Windows file naming, such as @code{c:/foo}. But 2794@command{scp} with MS Windows file naming, such as @file{c:/foo}. But
2685the version of @command{scp} that is installed with Cygwin does not 2795the version of @command{scp} that is installed with Cygwin does not
2686know about MS Windows file naming, which causes it to incorrectly look 2796know about MS Windows file naming, which causes it to incorrectly look
2687for a host named @code{c}. 2797for a host named @samp{c}.
2688 2798
2689A workaround: write a wrapper script for @option{scp} to convert 2799A workaround: write a wrapper script for @option{scp} to convert
2690Windows file names to Cygwin file names. 2800Windows file names to Cygwin file names.
@@ -4158,8 +4268,8 @@ Host *
4158@end group 4268@end group
4159@end example 4269@end example
4160 4270
4161Check @command{man ssh_config} whether these options are supported on 4271Check the @samp{ssh_config(5)} man page whether these options are
4162your proxy host. 4272supported on your proxy host.
4163 4273
4164 4274
4165@item 4275@item
diff --git a/lisp/net/tramp-crypt.el b/lisp/net/tramp-crypt.el
index d9ba2e49f76..664f4413473 100644
--- a/lisp/net/tramp-crypt.el
+++ b/lisp/net/tramp-crypt.el
@@ -44,11 +44,11 @@
44 44
45;; If the user option `tramp-crypt-save-encfs-config-remote' is 45;; If the user option `tramp-crypt-save-encfs-config-remote' is
46;; non-nil (the default), the encfs configuration file ".encfs6.xml" 46;; non-nil (the default), the encfs configuration file ".encfs6.xml"
47;; is also be kept in the crypted remote directory. It depends, 47;; is also kept in the crypted remote directory. It depends on you,
48;; whether you regard the password protection of this file as 48;; whether you regard the password protection of this file as
49;; sufficient. 49;; sufficient.
50 50
51;; If you apply an operation with a quoted localname part, this 51;; If you use a remote file name with a quoted localname part, this
52;; localname and the corresponding file will not be encrypted/ 52;; localname and the corresponding file will not be encrypted/
53;; decrypted. For example, if you have a crypted remote directory 53;; decrypted. For example, if you have a crypted remote directory
54;; "/nextcloud:user@host:/crypted_dir", the command 54;; "/nextcloud:user@host:/crypted_dir", the command
@@ -213,7 +213,7 @@ If NAME doesn't belong to a crypted remote directory, retun nil."
213 (start-file-process . ignore) 213 (start-file-process . ignore)
214 ;; `substitute-in-file-name' performed by default handler. 214 ;; `substitute-in-file-name' performed by default handler.
215 ;; (temporary-file-directory . tramp-crypt-handle-temporary-file-directory) 215 ;; (temporary-file-directory . tramp-crypt-handle-temporary-file-directory)
216 ;; `tramp-set-file-uid-gid' performed by default handler. 216 (tramp-set-file-uid-gid . tramp-crypt-handle-set-file-uid-gid)
217 ;; (unhandled-file-name-directory . ignore) 217 ;; (unhandled-file-name-directory . ignore)
218 (vc-registered . ignore) 218 (vc-registered . ignore)
219 (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime) 219 (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
@@ -334,7 +334,6 @@ connection if a previous connection has died for some reason."
334 (with-temp-file local-config 334 (with-temp-file local-config
335 (insert-file-contents 335 (insert-file-contents
336 (expand-file-name tramp-crypt-encfs-config tmpdir1)) 336 (expand-file-name tramp-crypt-encfs-config tmpdir1))
337 (goto-char (point-min))
338 (when (search-forward 337 (when (search-forward
339 "<chainedNameIV>1</chainedNameIV>" nil 'noerror) 338 "<chainedNameIV>1</chainedNameIV>" nil 'noerror)
340 (replace-match "<chainedNameIV>0</chainedNameIV>"))) 339 (replace-match "<chainedNameIV>0</chainedNameIV>")))
@@ -427,9 +426,9 @@ If OP ist `decrypt', the basename of INFILE must be an encrypted file name."
427 (dir (tramp-crypt-file-name-p root)) 426 (dir (tramp-crypt-file-name-p root))
428 (crypt-vec (tramp-crypt-dissect-file-name dir))) 427 (crypt-vec (tramp-crypt-dissect-file-name dir)))
429 (let ((coding-system-for-read 428 (let ((coding-system-for-read
430 (if (eq op 'decrypt) 'raw-text coding-system-for-read)) 429 (if (eq op 'decrypt) 'binary coding-system-for-read))
431 (coding-system-for-write 430 (coding-system-for-write
432 (if (eq op 'encrypt) 'raw-text coding-system-for-write))) 431 (if (eq op 'encrypt) 'binary coding-system-for-write)))
433 (tramp-crypt-send-command 432 (tramp-crypt-send-command
434 crypt-vec "cat" (and (eq op 'encrypt) "--reverse") 433 crypt-vec "cat" (and (eq op 'encrypt) "--reverse")
435 (file-name-directory infile) 434 (file-name-directory infile)
@@ -759,6 +758,14 @@ absolute file names."
759 (tramp-compat-set-file-times 758 (tramp-compat-set-file-times
760 (tramp-crypt-encrypt-file-name filename) time flag)))) 759 (tramp-crypt-encrypt-file-name filename) time flag))))
761 760
761(defun tramp-crypt-handle-set-file-uid-gid (filename &optional uid gid)
762 "Like `tramp-set-file-uid-gid' for Tramp files."
763 (with-parsed-tramp-file-name filename nil
764 (tramp-flush-file-properties v localname)
765 (let (tramp-crypt-enabled)
766 (tramp-set-file-uid-gid
767 (tramp-crypt-encrypt-file-name filename) uid gid))))
768
762(add-hook 'tramp-unload-hook 769(add-hook 'tramp-unload-hook
763 (lambda () 770 (lambda ()
764 (unload-feature 'tramp-crypt 'force))) 771 (unload-feature 'tramp-crypt 'force)))
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index d578c359d79..578da4171c7 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -2294,16 +2294,25 @@ This checks also `file-name-as-directory', `file-name-directory',
2294 (unwind-protect 2294 (unwind-protect
2295 (with-temp-buffer 2295 (with-temp-buffer
2296 (write-region "foo" nil tmp-name) 2296 (write-region "foo" nil tmp-name)
2297 (insert-file-contents tmp-name) 2297 (let ((point (point)))
2298 (should (string-equal (buffer-string) "foo")) 2298 (insert-file-contents tmp-name)
2299 (insert-file-contents tmp-name) 2299 (should (string-equal (buffer-string) "foo"))
2300 (should (string-equal (buffer-string) "foofoo")) 2300 (should (= point (point))))
2301 (goto-char (1+ (point)))
2302 (let ((point (point)))
2303 (insert-file-contents tmp-name)
2304 (should (string-equal (buffer-string) "ffoooo"))
2305 (should (= point (point))))
2301 ;; Insert partly. 2306 ;; Insert partly.
2302 (insert-file-contents tmp-name nil 1 3) 2307 (let ((point (point)))
2303 (should (string-equal (buffer-string) "oofoofoo")) 2308 (insert-file-contents tmp-name nil 1 3)
2309 (should (string-equal (buffer-string) "foofoooo"))
2310 (should (= point (point))))
2304 ;; Replace. 2311 ;; Replace.
2305 (insert-file-contents tmp-name nil nil nil 'replace) 2312 (let ((point (point)))
2306 (should (string-equal (buffer-string) "foo")) 2313 (insert-file-contents tmp-name nil nil nil 'replace)
2314 (should (string-equal (buffer-string) "foo"))
2315 (should (= point (point))))
2307 ;; Error case. 2316 ;; Error case.
2308 (delete-file tmp-name) 2317 (delete-file tmp-name)
2309 (should-error 2318 (should-error