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?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top