diff options
author | Tom Ryder <tom@sanctum.geek.nz> | 2018-06-10 00:54:44 +1200 |
---|---|---|
committer | Tom Ryder <tom@sanctum.geek.nz> | 2018-06-10 01:01:17 +1200 |
commit | 5a257fe0030cbee3bd50422d592025fbed8e4bde (patch) | |
tree | 40b463639fd3b52af774ddf49714adcfc81239a9 /contrib/vim | |
parent | dda2ecce34de808d22b4b0f388bd1cb640158a29 (diff) |
Replace noplaintext.vim as redact_pass.vim plugin
Per debugging from Enno Nagel <enno.nagel+vim@gmail.com>, it's become
apparent to me that to have any degree of confidence that none of these
options have actually got any plaintext password data in them, we need
to disable the options globally when a password file is edited.
In particular, in the case of the 'viminfo' global option, it's not
possible to disable it per path, and not terribly meaningful either;
things like the last seach pattern or the contents of registers, i.e.
global state of the editor, are recorded. There's no sensible approach I
can see except to actually switch the feature off entirely by blanking
it.
I've therefore completely rewritten this, to make as thorough a check as
possible that the Vim user is editing a pass(1) file by calling `pass
edit`, and then to disable the "leaky" options globally, with an
explicit warning so that the user can see it's been done.
This plugin is also available as Vim script #5707:
<https://www.vim.org/scripts/script.php?script_id=5707>
Its homepage is here:
<https://sanctum.geek.nz/cgit/vim-redact-pass.git/about/>
Diffstat (limited to 'contrib/vim')
-rw-r--r-- | contrib/vim/noplaintext.vim | 46 | ||||
-rw-r--r-- | contrib/vim/redact_pass.txt | 41 | ||||
-rw-r--r-- | contrib/vim/redact_pass.vim | 80 |
3 files changed, 121 insertions, 46 deletions
diff --git a/contrib/vim/noplaintext.vim b/contrib/vim/noplaintext.vim deleted file mode 100644 index 9493194..0000000 --- a/contrib/vim/noplaintext.vim +++ /dev/null @@ -1,46 +0,0 @@ -" -" Prevent various Vim features from keeping the contents of pass(1) password -" files (or any other purely temporary files) in plaintext on the system. -" -" Either append this to the end of your .vimrc, or install it as a plugin with -" a plugin manager like Tim Pope's Pathogen. -" -" Author: Tom Ryder <tom@sanctum.geek.nz> -" - -" Don't backup files in temp directories or shm -if exists('&backupskip') - set backupskip+=/tmp/*,$TMPDIR/*,$TMP/*,$TEMP/*,*/shm/* -endif - -" Don't keep swap files in temp directories or shm -if has('autocmd') - augroup swapskip - autocmd! - silent! autocmd BufNewFile,BufReadPre - \ /tmp/*,$TMPDIR/*,$TMP/*,$TEMP/*,*/shm/* - \ setlocal noswapfile - augroup END -endif - -" Don't keep undo files in temp directories or shm -if has('persistent_undo') && has('autocmd') - augroup undoskip - autocmd! - silent! autocmd BufWritePre - \ /tmp/*,$TMPDIR/*,$TMP/*,$TEMP/*,*/shm/* - \ setlocal noundofile - augroup END -endif - -" Don't keep viminfo for files in temp directories or shm -if has('viminfo') - if has('autocmd') - augroup viminfoskip - autocmd! - silent! autocmd BufNewFile,BufReadPre - \ /tmp/*,$TMPDIR/*,$TMP/*,$TEMP/*,*/shm/* - \ setlocal viminfo= - augroup END - endif -endif diff --git a/contrib/vim/redact_pass.txt b/contrib/vim/redact_pass.txt new file mode 100644 index 0000000..86d8a25 --- /dev/null +++ b/contrib/vim/redact_pass.txt @@ -0,0 +1,41 @@ +*redact_pass.txt* For Vim version 6.0 Last change: 2018 June 10 + +DESCRIPTION *redact_pass* + +This plugin switches off the 'viminfo', 'backup', 'writebackup', 'swapfile', +and 'undofile' options globally when editing a password in `pass(1)`. + +This is to prevent anyone being able to extract passwords from your Vim cache +files in the event of a compromise. + +You should test this after installed to ensure you see this message is printed +whenever you `pass edit`: + +> Editing password file--disabled leaky options! + +REQUIREMENTS *redact_pass-requirements* + +This plugin is only available if 'compatible' is not set. It also requires the +|+autocmd| feature. + +IMPLEMENTATION *redact_pass-implementation* + +The options are disabled globally rather than attempting to set them local to +the buffer only, which was the flawed approach of previous versions. This is +mostly because of the 'viminfo' option; it's global, and there's no meaningful +way to exclude information from the sensitive buffer from appearing in it. + +Because the typical use case for editing a password file in Vim is that you +load and change a single short document, and then quit, it's more sensible to +just turn the relevant options off completely, and makes what the plugin is +doing more reliable and straightforward to understand. + +AUTHOR *redact_pass-author* + +Written and maintained by Tom Ryder <tom@sanctum.geek.nz>. + +LICENSE *redact_pass-license* + +Licensed for distribution under the same terms as the pass(1) project. + + vim:tw=78:ts=8:ft=help:norl: diff --git a/contrib/vim/redact_pass.vim b/contrib/vim/redact_pass.vim new file mode 100644 index 0000000..14919bb --- /dev/null +++ b/contrib/vim/redact_pass.vim @@ -0,0 +1,80 @@ +" +" redact_pass.vim: Switch off the 'viminfo', 'backup', 'writebackup', +" 'swapfile', and 'undofile' globally when editing a password in pass(1). +" +" This is to prevent anyone being able to extract passwords from your Vim +" cache files in the event of a compromise. +" +" Author: Tom Ryder <tom@sanctum.geek.nz> +" License: Same as Vim itself +" +if exists('g:loaded_redact_pass') || &compatible + finish +endif +if !has('autocmd') + finish +endif +let g:loaded_redact_pass = 1 + +" Pattern to match for the portion of the path after the temporary dir, +" starting with the leading slash +let s:pattern = '\m\C/pass\.[^/]\+/[^/]\+\.txt$' + +" Check whether the given dir name is not an empty string, whether the first +" file in the argument list is within the named dir, and that the whole path +" matches the above pattern immediately after that dir name +function! s:PassPath(root) + + " Check we actually got a value, i.e. this wasn't an empty environment + " variable + if !strlen(a:root) + return 0 + endif + + " Full resolved path to the root dir with no trailing slashes + let l:root = fnamemodify(a:root, ':p:h') + + " Full resolved path to the first file in the arg list + let l:path = fnamemodify(argv(0), ':p') + + " Check the string all match and at the expected points + return stridx(l:path, l:root) == 0 + \ && strlen(l:root) == match(l:path, s:pattern) + +endfunction + +" Check whether we should set redacting options or not +function! s:CheckArgsRedact() + + " Short-circuit unless we're editing just one file and it looks like a path + " in one of the three expected directories; we're trying hard to make sure + " this really is a password file and we're not messing with the user's + " precious settings unnecessarily + if argc() != 1 + \ || !s:PassPath('/dev/shm') + \ && !s:PassPath($TMPDIR) + \ && !s:PassPath('/tmp') + return + endif + + " Disable all the leaky options globally + set nobackup + set nowritebackup + set noswapfile + set viminfo= + if has('persistent_undo') + set noundofile + endif + + " Tell the user what we're doing so they know this worked, via a message and + " a global variable they can check + echomsg 'Editing password file--disabled leaky options!' + let g:redact_pass_redacted = 1 + +endfunction + +" Auto function loads only when Vim starts up +augroup redact_pass + autocmd! + autocmd VimEnter * call s:CheckArgsRedact() +augroup END |