Помогите с gpgme_passphrase_cb_t - PullRequest
       37

Помогите с gpgme_passphrase_cb_t

0 голосов
/ 04 января 2011

Я работаю с GPGME ... Мне нужен пример использования функций gpgme_passphrase_cb_t и gpgme_set_passphrase_cb, потому что я не понимаю, как создать gpgme_passphrase_cb_t.

1 Ответ

2 голосов
/ 26 апреля 2011

Это код из gpgme ++, который оборачивает основанный на обратном вызове интерфейс в интерфейс C ++:

Интерфейс:

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

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

Предполагается, что функция отображает description в качестве приглашения и возвращает введенную фразу-пароль (буфер должен быть malloc() ed). Он также может установить canceled на true, чтобы указать, что пользователь прервал. Параметры useridHint и previousWasBad являются просто дополнительной информацией.

А это этот универсальный обратный вызов:

// 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;
}

Учитывая реализацию pp интерфейса PassphraseProvider, вы бы связали все вместе так:

gpgme_set_passphrase_cb( ctx, &passphrase_callback, pp );
...