Usando o retorno de chamada da senha no Ruby GPGME
Pergunta
Estou usando o Ruby GPGME Gem (1.0.8). Meu retorno de chamada da minha senha não é chamado:
def passfunc(*args)
fd = args.last
io = IO.for_fd(fd, 'w')
io.puts "mypassphrase"
io.flush
end
opts = {
:passphrase_callback => method(:passfunc)
}
GPGME.decrypt(input,output, opts)
Alguém tem um exemplo funcional de retorno de chamada da senha?
Solução
Amostra de retorno de chamada que você pode encontrar no seguinte exemplo de funcionamento. Ele assina um arquivo no modo destacado, ou seja, o arquivo de assinatura é separado do arquivo original. Ele usa o chaveiro padrão em ~/.gnupg ou algo assim. Para usar um diretório diferente para o seu chaveiro, defina a variável de ambiente Env ["GNUPGHOME"] = "" Antes de ligar para GPGME :: SIGN ().
#!/usr/bin/ruby
require 'rubygems'
require 'gpgme'
puts "Signing #{ARGV[0]}"
input = File.open(ARGV[0],'r')
PASSWD = "abc"
def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
puts("Passphrase for #{uid_hint}: ")
io = IO.for_fd(fd, 'w')
io.write(PASSWD+"\n")
io.flush
end
output = File.open(ARGV[0]+'.asc','w')
sign = GPGME::sign(input, {
:passphrase_callback => method(:passfunc),
:mode => GPGME::SIG_MODE_DETACH
})
output.write(sign)
output.close
input.close
Outras dicas
Aqui está outro exemplo de funcionamento para você que não usa uma assinatura isolada. Para testar isso, basta alterar 'user@host.name' para o identificador da sua chave e fazer isso: gpg.decrypt (gpg.encrypt ('algum texto',: armadura => true))
require 'gpgme'
require 'highline/import'
module GPG
ENCRYPT_KEY = 'user@host.com'
@gpg = GPGME::Crypto.new
class << self
def decrypt(encrypted_data, options = {})
options = { :passphrase_callback => self.method(:passfunc) }.merge(options)
@gpg.decrypt(encrypted_data, options).read
end
def encrypt(data_to_encrypt, options = {})
options = { :passphrase_callback => self.method(:passfunc), :armor => true }.merge(options)
@gpg.encrypt(data_to_encrypt, options).read
end
private
def get_passphrase
ask("Enter passphrase for #{ENCRYPT_KEY}: ") { |q| q.echo = '*' }
end
def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
begin
system('stty -echo')
io = IO.for_fd(fd, 'w')
io.puts(get_passphrase)
io.flush
ensure
(0 ... $_.length).each do |i| $_[i] = ?0 end if $_
system('stty echo')
end
$stderr.puts
end
end
end
Felicidades!,
- Carl
É importante observar que a partir do GNUPG 2.0 (e em 1.4 quando o use-agent
a opção é usada) pinentry
é usado para coleta de senha. Isso significa que o retorno de chamada da shrase GPGME não ser invocado. Isso é descrito aqui e um exemplo de uso pode ser encontrado no gpgme-tool
exemplo.