ubuntiano
ubuntiano

Reputation: 89

Help with gpgme_passphrase_cb_t

I'm working with GPGME...I need an example on use of gpgme_passphrase_cb_t and gpgme_set_passphrase_cb function because I don't understand how to create a gpgme_passphrase_cb_t.

Upvotes: 0

Views: 852

Answers (1)

Marc Mutz - mmutz
Marc Mutz - mmutz

Reputation: 25313

This is the code from gpgme++ that wraps the callback-based interface into a C++ interface:

The interface:

class PassphraseProvider {
public:
  virtual ~PassphraseProvider() {}

  virtual char * getPassphrase( const char * useridHint,
                                const char * description,
                                bool previousWasBad,
                                bool & canceled ) = 0;
};

The function is supposed to display description as a prompt, and return the passphrase entered (the buffer must be malloc()ed). It may also set canceled to true to indicate that the user aborted. The parameters useridHint and previousWasBad are just additional information.

And this this the generic callback:

// Code taken from gpgme++, license: LGPLv2+
static
gpgme_error_t passphrase_callback( void * opaque, const char * uid_hint, const char * desc,
                                   int prev_was_bad, int fd ) {
  PassphraseProvider * provider = static_cast<PassphraseProvider*>( opaque );
  bool canceled = false;
  gpgme_error_t err = GPG_ERR_NO_ERROR;
  char * passphrase = provider ? provider->getPassphrase( uid_hint, desc, prev_was_bad, canceled ) : 0 ;
  if ( canceled )
    err = make_error( GPG_ERR_CANCELED );
  else
    if ( passphrase && *passphrase ) {
      size_t passphrase_length = std::strlen( passphrase );
      size_t written = 0;
      do {
#ifdef HAVE_GPGME_IO_READWRITE
        ssize_t now_written = gpgme_io_write( fd, passphrase + written, passphrase_length - written );
#else
        ssize_t now_written = write( fd, passphrase + written, passphrase_length - written );
#endif
        if ( now_written < 0 ) {
          err = make_err_from_syserror();
          break;
        }
        written += now_written;
      } while ( written < passphrase_length );
    }

  free( passphrase );
#ifdef HAVE_GPGME_IO_READWRITE
  gpgme_io_write( fd, "\n", 1 );
#else
  write( fd, "\n", 1 );
#endif
  return err;
}

Given an implementation pp of the PassphraseProvider interface, you'd tie everything together like this:

gpgme_set_passphrase_cb( ctx, &passphrase_callback, pp );

Upvotes: 2

Related Questions