ueno / ruby-gpgme

a ruby interface to GnuPG Made Easy (GPGME).
GNU Lesser General Public License v2.1
232 stars 99 forks source link

Deleting a private key on macOS Big Sur hangs #145

Open dvkch opened 3 years ago

dvkch commented 3 years ago

I've encountered an issue where deleting a key would hang forever, using the following code:

GPGME::Key.find(:public, key_id).each { |k| k.delete!(true) }

# or
GPGME::Key.find(:private key_id).each { |k| k.delete!(true) }
(B(B(0lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk(B(B(0x(B Do you really want to permanently delete the OpenPGP secret key: (0x(B(B(0x(B "EnsoTest <test@example.com>"(0x(B(B(0x(B 2048-bit RSA key, ID 0FDD92544BA73B80,(0x(B(B(0x(B created 2020-08-25.(0x(B(B(0x(B ?(0x(B(B(0x(B(B(0x(B(B(0x(B     (B<Delete key>(B

If the key is a public key with no associated private key it works fine. If this is a public key with an associated private key, or if it is a private key itself, it will hang for around 2 minutes.

I have been able to reproduce this every time when running rspec on a Rails 6.0 project; the key was generated once and is re-added to the my test env using:

private_key = IO.read('spec/support/test_gpg')
key_id = GPGME::Key.import(private_key).imports.map(&:fpr)

Maybe there is an additional argument or configuration that is missing to prevent user confirmation via STDIN ?

errfanwadia commented 2 years ago

@dvkch were you able to find any workaround to input the user confirmation?

dvkch commented 2 years ago

@errfanwadia Unfortunately not. There might be a way in Ruby to connect to STDIN and STDOUT to know when the lib asks for confirmation and write it to STDOUT programmatically from another thread, but I haven't had the chance to test it though

evgenii commented 9 months ago

The current gem is not supporting this for now but the gpg/gpgme has an additional function gpgme_op_delete_ext where we can put the flags for the force delete:

/* Flags for the key delete functions.  */
#define GPGME_DELETE_ALLOW_SECRET (1 << 0)  /* Also delete secret key.     */
#define GPGME_DELETE_FORCE        (1 << 1)  /* Do not ask user to confirm.  */

see:

kernelsmith commented 3 months ago

@errfanwadia Unfortunately not. There might be a way in Ruby to connect to STDIN and STDOUT to know when the lib asks for confirmation and write it to STDOUT programmatically from another thread, but I haven't had the chance to test it though

you can definitely do this, but it is kind of painful obviously. All 3 are predefined as IO objects named STDOUT, STDIN, and STDERR. Instead tho, you might consider just marking the key untrusted. It will still be there, but not get used normally.