Giter VIP home page Giter VIP logo

passage's Issues

make install fails due to missing pass.fish-completion

Running make install errors with:

install: cannot stat 'src/completion/pass.fish-completion': No such file or directory

src/completion/pass.fish-completion was deleted in a previous commit. If dropping fish support was intentional, I think references to the completion need to be removed from the Makefile.

OTP support?

Is there any interest in adding OTP support in passage? I would be interested in knowing how you @FiloSottile suggest to deal with that, I used the pass-otp extension.

passage --version returns with exit 1 if identities are missing

Expected behavior:
No matter if the standard path to stores and identities as well as env vars like PASSAGE_DIR and/or PASSAGE_IDENTITIES_FILE are empty the exit status code for passage --version will be 0.

Actual behavior:
passage returns with exit status 1 if the standard identities path and PASSAGE_IDENTITIES_FILE are empty.

Because passage returns without error if standard store and PASSAGE_DIR are empty, I would think that also with missing identities passage should exit without an error.

Passage does not recognize git repository in `.passage` dir

Hello,

Many thanks for your work on age and passage. I recently switched to both from gpg and pass. Key management is much easier with age! :)

Instead of putting .passage/store/ into a git repository, I track the whole .passage dir (identities are stored on a yubikey). The git subcommand does not recognize that the passage dir is a repository.

I narrowed it down to line 33 in password-store.sh:

[[ $(git -C "$INNER_GIT_DIR" rev-parse --is-inside-work-tree 2>/dev/null) == true ]] || INNER_GIT_DIR=""

This test somehow fails (and resets the variable to "") even though executing this test manually results in the correct true result. I do not understand why this test does not detect correctly that the .passage dir is a git repository in the script but executing it manually gives the correct result.

The GIT_CEILING_DIRECTORIES seems to be correctly set to the home directory.

Can somebody help me out here?

Thanks for your help!

Submitting formula to Homebrew

Would y'all mind if I submitted a Homebrew formula for passage to homebrew/core? I've written a basic formula here:

class Passage < Formula
  desc "Fork of password-store that uses age instead of GnuPG"
  homepage "https://github.com/FiloSottile/passage"
  url "https://github.com/FiloSottile/passage/archive/1.7.4a1.tar.gz"
  version "1.7.4a1"
  sha256 "0705ff409d4a6160ade347e63be623170da023ec199116dac83b406a18f7e0d7"
  license "GPL-2.0-or-later"
  head "https://github.com/FiloSottile/passage.git", branch: "main"

  depends_on "age"
  depends_on "gnu-getopt"
  depends_on "qrencode"
  depends_on "tree"

  def install
    system "make", "PREFIX=#{prefix}", "WITH_ALLCOMP=yes", "BASHCOMPDIR=#{bash_completion}",
                   "ZSHCOMPDIR=#{zsh_completion}", "FISHCOMPDIR=#{fish_completion}", "install"
    inreplace "#{bin}/passage",
              /^SYSTEM_EXTENSION_DIR=.*$/,
              "SYSTEM_EXTENSION_DIR=\"#{HOMEBREW_PREFIX}/lib/passage/extensions\""
  end

  test do
    (testpath/".passage").mkdir
    system Formula["age"].opt_bin/"age-keygen", "-o", ".passage/identities"
    system bin/"passage", "generate", "foo.bar"
    assert_predicate testpath/".passage/store/foo.bar.age", :exist?
  end
end

There is no support for `pinentry`.

In pass, the gpg-agent manages the secret associated with the GPG key. This may be the PIN to access a YubiKey, or the passphrase to a password-protected GPG identity file.

On the other hand, passage prompts for the password to the age private key every time it is needed. This program should either hand-off the secret-gathering to another program (like an age-plugin-... or ssh-agent or something) or it should support the use of a chosen pinentry program.

Missing fish completion

The tag 1.7.4a0 tries to install fish completion but the completion file for it is not in the repo. It was added later. Could you create a new release with this fixed?

btw thx for doing this. I wanted to port pass to age myself. :D

Feature Request - ability to rekey all secrets

It would be great to have the option to easily rekey all secrets if there are changes to the recipients.

agenix which is a mechanism to deploy secrets to hosts that uses age has this option, which is very convenient.

zsh-specific code in "Migrating from pass" instructions

Sorry, but another little gotcha: the README's instructions to migrate from pass are zsh specific.

In particular, name="${${passfile#./}%.gpg}" doesn't work on bash. You need to do
that in two steps for bash.

Maybe just add that those instructions are an example for zsh users and that bash users
should edit accordingly?

For what it's worth, I used the following for bash:

set -o pipefail
cd "${PASSWORD_STORE_DIR:-$HOME/.password-store}" || exit
while read -r -d "" passfile
do
	name="${passfile#./}"
	name="${name%.gpg}"
	[[ -f "${PASSAGE_DIR:-$HOME/.passage/store}/$name.age" ]] && continue
	pass "$name" | passage insert -m "$name" || { passage rm "$name"; break; }
done < <(find . -path '*/.git' -prune -o -iname '*.gpg' -print0)

XDG Base Directory Compatibility

Would the project be amenable to being XDG compatible instead of defaulting to ~/.passage? That is, first check to see if the XDG_CONFIG_HOME environment variable is defined, and if so, put .passage/ under there. In the typical configuration, this would be ~/.config/passage.

This simplifies my backups, as I can copy ~/.config/ without having to special case dot folders under $HOME.

make install [with prefix] tries to read passage.sh that doesn't exist

Steps to reproduce:

[capitol@batia ~]$ cd /tmp/
[capitol@batia tmp]$ mkdir d
[capitol@batia tmp]$ cd d
[capitol@batia d]$ git clone [email protected]:FiloSottile/passage.git
Cloning into 'passage'...
remote: Enumerating objects: 2553, done.
remote: Counting objects: 100% (2553/2553), done.
remote: Compressing objects: 100% (1038/1038), done.
remote: Total 2553 (delta 1471), reused 2550 (delta 1468), pack-reused 0
Receiving objects: 100% (2553/2553), 395.23 KiB | 1.20 MiB/s, done.
Resolving deltas: 100% (1471/1471), done.
[capitol@batia d]$ cd passage/
[capitol@batia passage]$ mkdir /tmp/passage
[capitol@batia passage]$ LANG=C PREFIX=/tmp/passage make install
sed: can't read src/passage.sh: No such file or directory
make: *** [Makefile:52: install] Error 2

value too great for base

Before adding any passwords:

โฏ passage ls
/opt/homebrew/bin/passage: line 290: [[: 0p: value too great for base (error token is "0p")
Error: password store is empty.

After generating the first password:

โฏ passage ls
/opt/homebrew/bin/passage: line 290: [[: 0p: value too great for base (error token is "0p")
Passage

And trying to fetch it:

โฏ passage show test
/opt/homebrew/bin/passage: line 290: [[: 0p: value too great for base (error token is "0p")
/opt/homebrew/bin/passage: line 297: [[: 0p: value too great for base (error token is "0p")
Clip location '' is not a number.

Occurs in zsh and bash on macOS.

Allow multiple identities files

On one of my machines, I have 2 age keys that I use for my passwords:

  • One secure enclave key (for Touch ID), not encrypted with a passphrase
  • One standard age key, protected by a passphrase

Some folders in my store have a recipients file with both recipients in them, some only the one for the passphrase-protected age key.

I'd like to be able for passage to use the unencrypted (Touch ID) key when it can, and only prompt me for a passphrase when it needs to use the passphrase-protected key (i.e. when the password is only encrypted for the passphrase-protected key).

Passage only looks in one identities file, and as far as I know, I cannot combine passphrase-protected age keys and non-password-protected keys (such as the secure enclave one) in one identities file, so I can't make passage behave this way. It does work with age directly when I pass both identities in the correct order.

Proposed solution

One possible solution (which I implemented in my local copy): if identities is a directory, add all files in that directory in alphabetical order as identities to the age command-line (there may need to be a filter here).

One thing to bear in mind is extensions, which expect one $IDENTITIES_FILE; they could still be passed the first one through that variable for backwards compatibility, but in order to support multiple, they would have to support a new variable. I chose to pass an array $AGE_IDENTITY_ARGS, which avoids having to construct the -i command line by hand; this is also what password-store seems to do with $GPG_OPTS. (BTW, it seems there is a reference to $AGE_IDENTITY_ARGS in the code already, but Iโ€™m not sure this is intentional; I think the command where this is referenced, git init, is currently broken).

Another thing to note is that passage git init fixes the identity arguments in a config file. This means the identity files will be fixed at init time. I think the only way to make the git diff subcommand work is to not use age directly, but delay the parameter expansion (e.g. by using something like passage show that supports full paths as conversion script)

I created a PR to illustrate this solution.

Unclear how to setup new machines

I am trying to use multiple yubikeys. To set up a key on a new machine I do the following:

age-plugin-yubikey --identity > $HOME/.passage/identities
git clone password-repo ~$HOME/.passage/store/
pass Example

This obviously fails to work because I did not re-encrypt the repository, but init is not implemented. Do I just have to copy each file again so it is re-encrypted with both keys?

Using multiple identities with age-plugin-yubikey

I created a password with only one identity in my .passage/identities file. Then later I added a new identity to the same file. Both identities (and recipients in .passage/store/.age-recipients) were setup using age-plugin-yubikey.

Then I used passage cp to reencrypt the secret using the new age-recipients file. When I tried to decrypt the secret, age-plugin-yubikey prompted me for the yubikey that was first in the identifies file. I didn't see how to have it use the new yubikey who's recipient key was used to encrypt the secret.

Does passage + age-plugin-yubikey support multiple yubikeys? Apologies if this is more of a age-plugin-yubikey question.

cc: @str4d

Encrypt when yubikey isn't present

passage expects the yubikey to be inserted:

$ passage insert foo -m
Enter contents of foo and press Ctrl+D when finished:

Please insert YubiKey with serial 12345678 (press [1] for "YubiKey is plugged in" or [2] for "Skip this YubiKey")

Pressing 2:

age: error: failed to wrap key for recipient #1: yubikey plugin: Could not open YubiKey with serial 12345678
age: report unexpected or unhelpful errors at https://filippo.io/age/report
Password encryption aborted.

I was expecting to be able to encrypt to a yubikey that isn't present.

feature request: expose reencrypt as a subcommand

When copying/moving to a new path passage will reencrypt.

Would be nice to expose a reencrypt in place subcommand that could be used to rotate the keys used for encryption (eg: in the case they are leaked.

Allow multiple identities files

On one of my machines, I have 2 secret keys that I use for my passwords:

  • One secure enclave key, protected by touch ID
  • One standard age key, protected by a password

Some folders in my store have a recipients file with both identities in them, some only the password protected.

I'd like to be able for passage to use Touch ID when it can, and only prompt me for the password when it needs to use the password-protected key.

Passage only looks in one identities file, and as far as I know, I cannot combine password-protected age keys and non-password-protected keys (such as the secure enclave one) in one identities file, so I can't make passage behave this way. It does work with age directly when I pass both identities in the correct order.

Completion files are not installed to Homebrew Cellar

$ make install PREFIX="$(brew --cellar)/passage/dev"
install: mkdir /opt/homebrew/Cellar/passage
install: mkdir /opt/homebrew/Cellar/passage/dev
install: mkdir /opt/homebrew/Cellar/passage/dev/lib
install: mkdir /opt/homebrew/Cellar/passage/dev/lib/passage
install: src/platform/darwin.sh -> /opt/homebrew/Cellar/passage/dev/lib/passage/platform.sh
install: mkdir /opt/homebrew/Cellar/passage/dev/lib/passage/extensions
install: mkdir /opt/homebrew/Cellar/passage/dev/bin
install: src/.passage -> /opt/homebrew/Cellar/passage/dev/bin/passage

macOS/Homebrew installation fails

Because the repo does not yet have any tagged commits, the current instructions lead to an error though the rest of the steps continue.

fatal: No names found, cannot describe anything. # this is the error from git describe --tags
install: mkdir /usr/local/Cellar/passage
install: mkdir /usr/local/Cellar/passage//lib
install: mkdir /usr/local/Cellar/passage//lib/passage
install: src/platform/darwin.sh -> /usr/local/Cellar/passage//lib/passage/platform.sh
install: mkdir /usr/local/Cellar/passage//lib/passage/extensions
install: mkdir /usr/local/Cellar/passage//bin
install: src/.passage -> /usr/local/Cellar/passage//bin/passage

brew link passage doesn't work after that, presumably because brew expects installations to be in a tagged subfolder.

$ brew link passage
Linking /usr/local/Cellar/passage/lib... 0 symlinks created.

Running the commands with a manual tag works fine. E.g., make install PREFIX="$(brew --cellar)/passage/0.0.1"

No need to do anything since I'm assuming that this is still relatively alpha and you're not ready to tag anything yet. But I figured I would put this here for anyone else who has this problem.

Checking parent directories for .age-recipients file stops at $PREFIX

It seems that only the $PASSAGE_DIR folder is checked for the .age-recipients file. That, or I am misunderstanding the documentation:

For encryption, the nearest .age-recipients file (that is, the one in the same
directory as the secret, or in the closest parent) is used with the -R age CLI
option.

For the current version (set_age_recipients()):

local current="$PREFIX/$1"
#        should prevent traversal above $PREFIX
#        vvvvvvvvvvvvvvvvvvvvv
while [[ $current != "$PREFIX" && ! -f $current/.age-recipients ]]; do
        current="${current%/*}"
done
current="$current/.age-recipients"

Where PREFIX="${PASSAGE_DIR:-$HOME/.passage/store}", seems to prevent passage from traversing upwards. Removing the first condition leads the program to act as I would expect. There may be security implications to allowing an infinite upwards traversal in search for recipients, so the fix may be a documentation edit.

Additionally, there is no warning when the identity key fallback is used; this may lead to an unfortunate UX where additional recipients are not used to encrypt, and a "recovery" key would fail to recover the data.

Thank you for your work.

Storing the .age-recipient file

An attacker should not be able to edit the .age-recipient file unnoticed (e.g. add a new recipient unnoticed). Where and how should the .age-recipient file be stored most securely? Should it be signed (e.g. with minisign) if you store it at a location less trusted than the local disk?

Feature Request/Question - encrypt recipient file

To share passwords with others, it makes sense to store the data on a shared storage. The shared storage might not be very trusted (e.g. Google Drive).
One problem is to share the recipient file securely with others.
Would it make sense to encrypt the recipient file also for all recipients with the recipient keys of the recipient file and put it on the shared storage? If so, would it make sense to add in passage a command e.g. "encrypt_recipient_file" or an env variable e.g. "ENCRYPT_RECIPIENT_FILE=true"?

Best way to add a new yubikey to the store?

Now that age-plugin-yubikey supports multiple keys, what's the best way to add a new yubikey (for example, a backup) to the passage store? I added my new key to the existing identities and .age-recipients and then copied:

passage cp path/to/secret  new/path/to/secret

It's a bit cumbersome and sort of messes up the paths in the store. Is this the only option, or is there a better one I haven't considered?

@str4d

Might be vulnerable to file rename attacks

This is very hypothetical, and only based on me reading the source code since I had a bit of trouble installing it.

But pass is vulnerable to file rename attacks, if an attacker have control over the encrypted files then he can copy one file into another, and cause the teams password for service A to be leaked to service B.

See CVE-2020-28086 ( https://blog.hackeriet.no/filename-rename-in-pass/ ) for my writeup on the issue.

It looks like there isn't any protection in passage for this type of attack either.

Sorry if I was wrong about this, just close this issue then :)

And this isn't really responsible disclosure, but i reckon that since this is so new there isn't any user impact to take into account.

Feature Request/Question - encrypt recipient file (part 2)

In the feature request #25 I suggested that it might be useful to store the recipient file encrypted on a shared storage as well, if you want to share the passwords with others and the shared storage is not trusted.

But every write operation would require decryption.

To avoid this the following idea might be useful:
A copy of the plaintext recipient file is stored locally (trusted storage) and the hash value of the encrypted recipient file. For each write operation the locally stored hash value is compared with the hash value of the encrypted recipient file stored on the shared storage. If they match, the locally stored plaintext recipient file can be used (this results in less costs than a decryption). If not, decryption must be performed.

Unecessary prompt for password

When editing a password, passage prompts for the password once to decrypt the file. But then it asks again when saving the file. It should not need to prompt the second time.

$ passage edit tmp
Enter passphrase for identity file "/home/username/.passage/identities":
Enter passphrase for identity file "/home/username/.passage/identities":
Password unchanged.

Caching passphrase for the identity file like pass

The pass utility caches the password to the gpg key for a while just like sudo which allows for quick subsequent decryptions without entering the password. Is there something similar which can be implemented with passage?

Passage requiring first entry of .age-recipients for decryption

I've setup three Yubikeys with Age and configured passage to use them by running once for each yubikey:

โžœ age-plugin-yubikey --identity >> $HOME/.passage/identities
โžœ age-plugin-yubikey --list >> $HOME/.passage/store/.age-recipients

I then generated a test password and am only able to decrypt it with the first yubikey I added to the .age-recipients file:

โžœ passage test/pass               
Please insert YubiKey with serial 19234119: (y/n) 

Confusing UI when reencrypting with identities file referencing multiple Yubikeys

To reproduce:

  • create .passage/identities and .passage/store/.age-recipients with identities found on two different Yubikeys
$ passage generate test

Unplug one of the two YubiKeys, then

$ rm .passage/store/.age-recipients
$ passage mv test test_new

What happens now is that for some reason, passage is asking for the PIN for the Yubikey present and for the second Yubikey to be inserted at the same time, so it's very unclear what to enter. I've tried 2 to skip and typing in the PIN, but neither worked for me ...

This might lead to users inadvertently exhausting their PIN entry attempts ...

EDIT: Probably that is due to the PIN being needed for the decryption, and the missing YubiKey to get the public key?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.