Add public function gpgme_set_pinentry_mode.

* src/gpgme.c (gpgme_set_pinentry_mode): New.
* src/gpgme.h.in (gpgme_pinentry_t): New.
(gpgme_set_pinentry_mode): New.
* src/context.h (struct gpgme_context): Add field pinentry_mode.
* src/engine-backend.h (struct engine_ops): Add field
set_pinentry_mode.
* src/engine-gpg.c (struct engine_gpg): Add field pinentry_mode.
(build_argv): Implement pinentry_mode.
(gpg_set_pinentry_mode): New.
(_gpgme_engine_ops_gpg): Register gpg_set_pinentry_mode.

--

Note that this new fucntion may only be used with gpg 2.1.
This commit is contained in:
Werner Koch 2013-02-07 20:59:16 +01:00
parent 29eced5068
commit 61a0d92b67
14 changed files with 140 additions and 7 deletions

8
NEWS
View File

@ -3,7 +3,15 @@ Noteworthy changes in version 1.3.3 (unreleased)
* Interface changes relative to the 1.3.1 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_io_writen NEW.
gpgme_set_global_flag NEW.
gpgme_set_pinentry_mode NEW.
gpgme_pinentry_mode_t NEW.
GPGME_PINENTRY_MODE_DEFAULT NEW.
GPGME_PINENTRY_MODE_ASK NEW.
GPGME_PINENTRY_MODE_CANCEL NEW.
GPGME_PINENTRY_MODE_ERROR NEW.
GPGME_PINENTRY_MODE_LOOPBACK NEW.
Noteworthy changes in version 1.3.2 (2012-05-02)

View File

@ -101,6 +101,9 @@ struct gpgme_context
/* Flags for keylist mode. */
gpgme_keylist_mode_t keylist_mode;
/* The current pinnetry mode. */
gpgme_pinentry_mode_t pinentry_mode;
/* Number of certs to be included. */
unsigned int include_certs;

View File

@ -781,5 +781,7 @@ struct engine_ops _gpgme_engine_ops_assuan =
llass_set_io_cbs,
llass_io_event,
llass_cancel,
llass_cancel_op
llass_cancel_op,
NULL, /* passwd */
NULL /* set_pinentry_mode */
};

View File

@ -121,6 +121,9 @@ struct engine_ops
/* Change the passphrase for KEY. */
gpgme_error_t (*passwd) (void *engine, gpgme_key_t key, unsigned int flags);
/* Set the pinentry mode. */
gpgme_error_t (*set_pinentry_mode) (void *engine, gpgme_pinentry_mode_t mode);
};

View File

@ -798,4 +798,6 @@ struct engine_ops _gpgme_engine_ops_g13 =
g13_io_event,
g13_cancel,
g13_cancel_op,
NULL, /* passwd */
NULL /* set_pinentry_mode */
};

View File

@ -134,6 +134,7 @@ struct engine_gpg
} cmd;
struct gpgme_io_cbs io_cbs;
gpgme_pinentry_mode_t pinentry_mode;
};
typedef struct engine_gpg *engine_gpg_t;
@ -769,6 +770,8 @@ build_argv (engine_gpg_t gpg)
argc++;
if (use_agent)
argc++;
if (gpg->pinentry_mode)
argc++;
if (!gpg->cmd.used)
argc++; /* --batch */
argc += 1; /* --no-sk-comment */
@ -818,6 +821,32 @@ build_argv (engine_gpg_t gpg)
}
argc++;
}
if (gpg->pinentry_mode)
{
const char *s = NULL;
switch (gpg->pinentry_mode)
{
case GPGME_PINENTRY_MODE_DEFAULT: break;
case GPGME_PINENTRY_MODE_ASK: s = "--pinentry-mode=ask"; break;
case GPGME_PINENTRY_MODE_CANCEL: s = "--pinentry-mode=cancel"; break;
case GPGME_PINENTRY_MODE_ERROR: s = "--pinentry-mode=error"; break;
case GPGME_PINENTRY_MODE_LOOPBACK:s = "--pinentry-mode=loopback"; break;
}
if (s)
{
argv[argc] = strdup (s);
if (!argv[argc])
{
int saved_err = gpg_error_from_syserror ();
free (fd_data_map);
free_argv (argv);
return saved_err;
}
argc++;
}
}
if (!gpg->cmd.used)
{
argv[argc] = strdup ("--batch");
@ -2348,6 +2377,17 @@ gpg_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs)
gpg->io_cbs = *io_cbs;
}
static gpgme_error_t
gpg_set_pinentry_mode (void *engine, gpgme_pinentry_mode_t mode)
{
engine_gpg_t gpg = engine;
gpg->pinentry_mode = mode;
return 0;
}
struct engine_ops _gpgme_engine_ops_gpg =
{
@ -2389,5 +2429,6 @@ struct engine_ops _gpgme_engine_ops_gpg =
gpg_io_event,
gpg_cancel,
NULL, /* cancel_op */
gpg_passwd
gpg_passwd,
gpg_set_pinentry_mode
};

View File

@ -925,5 +925,8 @@ struct engine_ops _gpgme_engine_ops_gpgconf =
gpgconf_conf_save,
gpgconf_set_io_cbs,
NULL, /* io_event */
NULL /* cancel */
NULL, /* cancel */
NULL, /* cancel_op */
NULL, /* passwd */
NULL /* set_pinentry_mode */
};

View File

@ -1986,5 +1986,6 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
gpgsm_io_event,
gpgsm_cancel,
NULL, /* cancel_op */
gpgsm_passwd
gpgsm_passwd,
NULL /* set_pinentry_mode */
};

View File

@ -1339,4 +1339,6 @@ struct engine_ops _gpgme_engine_ops_uiserver =
uiserver_io_event,
uiserver_cancel,
NULL /* cancel_op */
NULL, /* passwd */
NULL /* set_pinentry_mode */
};

View File

@ -923,3 +923,16 @@ _gpgme_engine_op_passwd (engine_t engine, gpgme_key_t key,
return (*engine->ops->passwd) (engine->engine, key, flags);
}
/* Set the pinentry mode for ENGINE to MODE. */
gpgme_error_t
_gpgme_engine_set_pinentry_mode (engine_t engine, gpgme_pinentry_mode_t mode)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->set_pinentry_mode)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->set_pinentry_mode) (engine->engine, mode);
}

View File

@ -160,5 +160,8 @@ gpgme_error_t _gpgme_engine_cancel_op (engine_t engine);
gpgme_error_t _gpgme_engine_op_passwd (engine_t engine, gpgme_key_t key,
unsigned int flags);
gpgme_error_t _gpgme_engine_set_pinentry_mode (engine_t engine,
gpgme_pinentry_mode_t mode);
#endif /* ENGINE_H */

View File

@ -53,8 +53,8 @@ DEFINE_STATIC_LOCK (result_ref_lock);
/* Set the global flag NAME to VALUE. Return 0 on success. Note that
this function does use gpgme_error and thus a non-zero return value
merely means "error". Certain flags may be set before
this function does not use gpgme_error and thus a non-zero return
value merely means "error". Certain flags may be set before
gpgme_check_version is called. See the manual for a description of
supported flags. The caller must assure that this function is
called only by one thread at a time. */
@ -512,6 +512,33 @@ gpgme_get_keylist_mode (gpgme_ctx_t ctx)
}
/* Set the pinentry mode for CTX to MODE. */
gpgme_error_t
gpgme_set_pinentry_mode (gpgme_ctx_t ctx, gpgme_keylist_mode_t mode)
{
TRACE1 (DEBUG_CTX, "gpgme_set_pinentry_mode", ctx, "pinentry_mode=%u",
(unsigned int)mode);
if (!ctx)
return gpg_error (GPG_ERR_INV_VALUE);
switch (mode)
{
case GPGME_PINENTRY_MODE_DEFAULT:
case GPGME_PINENTRY_MODE_ASK:
case GPGME_PINENTRY_MODE_CANCEL:
case GPGME_PINENTRY_MODE_ERROR:
case GPGME_PINENTRY_MODE_LOOPBACK:
break;
default:
return gpg_error (GPG_ERR_INV_VALUE);
}
ctx->pinentry_mode = mode;
return 0;
}
/* This function sets a callback function to be used to pass a
passphrase to gpg. */
void

View File

@ -1,7 +1,7 @@
/* gpgme.h - Public interface to GnuPG Made Easy. -*- c -*-
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009
2010, 2011, 2012 g10 Code GmbH
2010, 2011, 2012, 2013 g10 Code GmbH
This file is part of GPGME.
@ -353,6 +353,18 @@ gpgme_protocol_t;
typedef unsigned int gpgme_keylist_mode_t;
/* The pinentry modes. */
typedef enum
{
GPGME_PINENTRY_MODE_DEFAULT = 0,
GPGME_PINENTRY_MODE_ASK = 1,
GPGME_PINENTRY_MODE_CANCEL = 2,
GPGME_PINENTRY_MODE_ERROR = 3,
GPGME_PINENTRY_MODE_LOOPBACK = 4
}
gpgme_pinentry_mode_t;
/* The available export mode flags. */
#define GPGME_EXPORT_MODE_EXTERN 2
@ -859,6 +871,10 @@ gpgme_error_t gpgme_set_keylist_mode (gpgme_ctx_t ctx,
/* Get keylist mode in CTX. */
gpgme_keylist_mode_t gpgme_get_keylist_mode (gpgme_ctx_t ctx);
/* Set the pinentry mode for CTX to MODE. */
gpgme_error_t gpgme_set_pinentry_mode (gpgme_ctx_t ctx,
gpgme_pinentry_mode_t mode);
/* Set the passphrase callback function in CTX to CB. HOOK_VALUE is
passed as first argument to the passphrase callback function. */
void gpgme_set_passphrase_cb (gpgme_ctx_t ctx,

View File

@ -134,6 +134,15 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
#endif
if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
err = 0;
if (!err)
{
err = _gpgme_engine_set_pinentry_mode (ctx->engine,
ctx->pinentry_mode);
if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
err = 0;
}
if (err)
{
_gpgme_engine_release (ctx->engine);