Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set vim options instead of sniffing the config #2343

Merged
merged 2 commits into from
Sep 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions docs/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Alternatively, it can be installed via [chocolatey](https://chocolatey.org/packa
#### OpenBSD

For OpenBSD -current:

```
pkg_add gopass
```
Expand Down Expand Up @@ -117,6 +118,7 @@ touch foo
git add foo
git commit -S -m "test"
```

Here the `-S` flag will sign your commit using GPG, allowing you to test your GPG setup with git.
If you get an error like: "gpg failed to sign the data" try to see if creating a clear text signature works:

Expand All @@ -131,6 +133,7 @@ If this fails with an error: "Inappropriate ioctl for device" run the following
```

If you are using CSH or TCSH:

```
setenv GPG_TTY `tty`
```
Expand All @@ -141,6 +144,7 @@ If you are presented with a different error please investigate this before conti
set it in your `.zprofile`, `.bashrc` or simliar.

Also if you have both `gnupg` and `gnupg2` installed, make sure to use the latter in git:

```bash
git config --global gpg.program gpg2
```
Expand Down Expand Up @@ -287,6 +291,9 @@ autocmd BufNewFile,BufRead /dev/shm/gopass* setlocal noswapfile nobackup noundof
autocmd BufNewFile,BufRead /private/**/gopass** setlocal noswapfile nobackup noundofile viminfo=""
```

Note: gopass will attempt to detect the correct hardning flags to be used for the editor. It will pass them on
invocation.

### Migrating from pass to gopass

If you are migrating from pass to gopass, you can simply use your existing password store and everything should just work. Furthermore, it may be helpful to link the gopass binary so that you can use it as a drop-in replacement. For example, assuming `$HOME/bin/` exists and is present in your `$PATH`:
Expand Down Expand Up @@ -320,11 +327,12 @@ If you use zsh, `make install` or `make install-completion` should install the c
If zsh autocompletion is still not functional, or if you want to install it manually, you can run the following commands:

```bash
$ gopass completion zsh > ~/_gopass
$ sudo mv ~/_gopass /usr/share/zsh/site-functions/_gopass
$ rm -i ${ZDOTDIR:-${HOME:?No ZDOTDIR or HOME}}/.zcompdump && compinit
gopass completion zsh > ~/_gopass
sudo mv ~/_gopass /usr/share/zsh/site-functions/_gopass
rm -i ${ZDOTDIR:-${HOME:?No ZDOTDIR or HOME}}/.zcompdump && compinit

```

Then exit and re-run zsh if the last command failed.

Notice that it is important to directly redirect Gopass' output to a file,
Expand All @@ -334,17 +342,21 @@ completions directory, as defined by either the standard `/usr/share/zsh/site-fu
or by a user-specified `fpath` folder. It is not meant to used with `source`.

If zsh completion is still not working, you might want to add the following to your `.zshrc` file:

```bash
autoload -U compinit && compinit
```

if you don't have it already.

### Enable fish completion

If you use the [fish](https://fishshell.com/) shell, you can enable experimental shell completion by the following command:

```fish
$ mkdir -p ~/.config/fish/completions and; gopass completion fish > ~/.config/fish/completions/gopass.fish
mkdir -p ~/.config/fish/completions and; gopass completion fish > ~/.config/fish/completions/gopass.fish
```

and start a new shell afterwards.

Since writing fish completion scripts is not yet supported by the CLI library we use, this completion script is missing a few features. Feel free to contribute if you want to improve it.
Expand Down Expand Up @@ -415,10 +427,10 @@ $ gopass setup --crypto gpg --storage gitfs # used by default
If you have created a password store with `git`, `gopass` can easily clone it.

```bash
$ gopass clone git@gitlab.example.org:john/passwords.git
gopass clone git@gitlab.example.org:john/passwords.git
```

### Storing and Syncing your Password Store with Google Drive / Dropbox / Syncthing / etc.
### Storing and Syncing your Password Store with Google Drive / Dropbox / Syncthing / etc

The recommended way to use Gopass is to sync your store with a git repository, preferably a private one, since the name and path of your secrets might reveal information that you'd prefer to keep private.
However, shall you prefer to, you might also use the `noop` storage backend that is meant to store data on a cloud provider instead of a git server.
Expand Down Expand Up @@ -471,4 +483,3 @@ It will fail if the remote at `github.com/example/pass.git` is not empty.

The second command will clone the existing (no `--create` flag) remote `github.com/example/pass.git`
and mount it as the mount point `example`.

3 changes: 0 additions & 3 deletions internal/action/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ func (s *Action) Edit(c *cli.Context) error {

func (s *Action) edit(ctx context.Context, c *cli.Context, name string) error {
ed := editor.Path(c)
if err := editor.Check(ctx, ed); err != nil {
out.Warningf(ctx, "Failed to check editor config: %s", err)
}

// get existing content or generate new one from a template.
name, content, changed, err := s.editGetContent(ctx, name, c.Bool("create"))
Expand Down
4 changes: 0 additions & 4 deletions internal/action/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"github.com/gopasspw/gopass/internal/action/exit"
"github.com/gopasspw/gopass/internal/audit"
"github.com/gopasspw/gopass/internal/editor"
"github.com/gopasspw/gopass/internal/out"
"github.com/gopasspw/gopass/internal/queue"
"github.com/gopasspw/gopass/pkg/ctxutil"
"github.com/gopasspw/gopass/pkg/debug"
Expand All @@ -31,9 +30,6 @@ func (s *Action) Merge(c *cli.Context) error {
}

ed := editor.Path(c)
if err := editor.Check(ctx, ed); err != nil {
out.Warningf(ctx, "Failed to check editor config: %s", err)
}

content := &bytes.Buffer{}
for _, k := range c.Args().Slice() {
Expand Down
76 changes: 28 additions & 48 deletions internal/editor/editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,11 @@ import (
"io"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strings"

"github.com/fatih/color"
"github.com/gopasspw/gopass/internal/out"
"github.com/gopasspw/gopass/pkg/ctxutil"
"github.com/gopasspw/gopass/pkg/debug"
"github.com/gopasspw/gopass/pkg/fsutil"
"github.com/gopasspw/gopass/pkg/tempfile"
shellquote "github.com/kballard/go-shellquote"
)
Expand All @@ -27,47 +22,9 @@ var (
// Stdout is exported for tests.
Stdout io.Writer = os.Stdout
// Stderr is exported for tests.
Stderr io.Writer = os.Stderr
vimOptsRe = regexp.MustCompile(`au(tocmd)?\s+BufNewFile,BufRead\s+.*gopass.*setlocal\s+noswapfile\s+nobackup\s+noundofile\s+viminfo=`)
Stderr io.Writer = os.Stderr
)

// Check will validate the editor config.
func Check(ctx context.Context, editor string) error {
if !strings.Contains(editor, "vi") {
return nil
}

uhd, err := os.UserHomeDir()
if err != nil {
return err
}

vrc := filepath.Join(uhd, ".vimrc")
if runtime.GOOS == "windows" {
vrc = filepath.Join(uhd, "_vimrc")
}

if !fsutil.IsFile(vrc) {
return nil
}

buf, err := os.ReadFile(vrc)
if err != nil {
return err
}

if vimOptsRe.Match(buf) {
debug.Log("Recommended settings found in %s", vrc)

return nil
}

debug.Log("%s did not match %s", string(buf), vimOptsRe)
out.Warningf(ctx, "Vim might leak credentials. Check your setup.\nhttps://go.gopass.pw/setup#securing-your-editor")

dominikschulz marked this conversation as resolved.
Show resolved Hide resolved
return nil
}

// Invoke will start the given editor and return the content.
func Invoke(ctx context.Context, editor string, content []byte) ([]byte, error) {
if !ctxutil.IsTerminal(ctx) {
Expand All @@ -93,19 +50,20 @@ func Invoke(ctx context.Context, editor string, content []byte) ([]byte, error)
return []byte{}, fmt.Errorf("failed to close tmpfile to start with %s %v: %w", editor, tmpfile.Name(), err)
}

var args []string
args := make([]string, 0, 4)
if runtime.GOOS != "windows" {
cmdArgs, err := shellquote.Split(editor)
if err != nil {
return []byte{}, fmt.Errorf("failed to parse EDITOR command `%s`", editor)
}

editor = cmdArgs[0]
args = append(cmdArgs[1:], tmpfile.Name())
} else {
args = []string{tmpfile.Name()}
args = append(args, cmdArgs[1:]...)
args = append(args, vimOptions(editor)...)
}

args = append(args, tmpfile.Name())

cmd := exec.Command(editor, args...)
cmd.Stdin = Stdin
cmd.Stdout = Stdout
Expand All @@ -128,3 +86,25 @@ func Invoke(ctx context.Context, editor string, content []byte) ([]byte, error)

return nContent, nil
}

func vimOptions(editor string) []string {
if editor != "vi" && editor != "vim" && editor != "neovim" {
return []string{}
}

path := "/dev/shm/gopass*"
if runtime.GOOS == "darwin" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does that work on Windows? (Are we even using vim on windows?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea. Someone else would need to test that.

path = "/private/**/gopass**"
}
viminfo := `viminfo=""`
if editor == "neovim" {
viminfo = `shada=""`
}

return []string{
"-i", "NONE", // disable viminfo
"-n", // disable swap
"-c",
fmt.Sprintf("autocmd BufNewFile,BufRead %s setlocal noswapfile nobackup noundofile %s", path, viminfo),
dominikschulz marked this conversation as resolved.
Show resolved Hide resolved
}
}