/* Data used to associate an Assuan context with local server data. */
-struct server_local_s
+struct server_local_s
{
/* Our current Assuan context. */
- assuan_context_t assuan_ctx;
+ assuan_context_t assuan_ctx;
/* File descriptor as set by the MESSAGE command. */
- gnupg_fd_t message_fd;
+ gnupg_fd_t message_fd;
/* List of prepared recipients. */
pk_list_t recplist;
+ /* Set if pinentry notifications should be passed back to the
+ client. */
+ int allow_pinentry_notify;
};
\f
/* Helper to close the message fd if it is open. */
-static void
+static void
close_message_fd (ctrl_t ctrl)
{
if (ctrl->server_local->message_fd != GNUPG_INVALID_FD)
{
assuan_sock_close (ctrl->server_local->message_fd);
ctrl->server_local->message_fd = GNUPG_INVALID_FD;
- }
+ }
}
{
const char *s;
int n = strlen (name);
-
+
s = strstr (line, name);
if (s && s >= skip_options (line))
return 0;
static gpg_error_t
option_handler (assuan_context_t ctx, const char *key, const char *value)
{
-/* ctrl_t ctrl = assuan_get_pointer (ctx); */
+ ctrl_t ctrl = assuan_get_pointer (ctx);
- (void)ctx;
(void)value;
/* Fixme: Implement the tty and locale args. */
{
/* This is for now a dummy option. */
}
+ else if (!strcmp (key, "allow-pinentry-notify"))
+ {
+ ctrl->server_local->allow_pinentry_notify = 1;
+ }
else
return gpg_error (GPG_ERR_UNKNOWN_OPTION);
output_notify (assuan_context_t ctx, char *line)
{
/* ctrl_t ctrl = assuan_get_pointer (ctx); */
-
+
(void)ctx;
if (strstr (line, "--armor"))
remusr = rcpts;
*/
- err = find_and_check_key (ctrl, line, PUBKEY_USAGE_ENC, hidden,
+ err = find_and_check_key (ctrl, line, PUBKEY_USAGE_ENC, hidden,
&ctrl->server_local->recplist);
-
+
if (err)
log_error ("command '%s' failed: %s\n", "RECIPIENT", gpg_strerror (err));
return err;
then not be done for this key. If the policy is not to sign at all
if not all signer keys are valid, the client has to take care of
this. All SIGNER commands are cumulative until a RESET but they
- are *not* reset by an SIGN command becuase it can be expected that
+ are *not* reset by an SIGN command because it can be expected that
set of signers are used for more than one sign operation.
Note that this command returns an INV_RECP status which is a bit
\f
-/* ENCRYPT
+/* ENCRYPT
Do the actual encryption process. Takes the plaintext from the
INPUT command, writes the ciphertext to the file descriptor set
(void)line; /* LINE is not used. */
- if ( !ctrl->server_local->recplist )
+ if ( !ctrl->server_local->recplist )
{
write_status_text (STATUS_NO_RECP, "0");
err = gpg_error (GPG_ERR_NO_USER_ID);
goto leave;
}
- /* Fixme: Check that we are using real files and not pipes if in
- PGP-2 mode. Do all the other checks we do in gpg.c for aEncr.
- Maybe we should drop the PGP2 compatibility. */
-
/* FIXME: GPGSM does this here: Add all encrypt-to marked recipients
from the default list. */
/* fixme: err = ctrl->audit? 0 : start_audit_session (ctrl);*/
-
+
err = encrypt_crypt (ctrl, inp_fd, NULL, NULL, 0,
ctrl->server_local->recplist,
out_fd);
This does a verify operation on the message send to the input-FD.
The result is written out using status lines. If an output FD was
given, the signed text will be written to that.
-
+
If the signature is a detached one, the server will inquire about
the signed material and the client must provide it.
*/
cmd_verify (assuan_context_t ctx, char *line)
{
int rc;
+#ifdef HAVE_W32_SYSTEM
+ (void)ctx;
+ (void)line;
+ rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+#else
ctrl_t ctrl = assuan_get_pointer (ctx);
gnupg_fd_t fd = assuan_get_input_fd (ctx);
gnupg_fd_t out_fd = assuan_get_output_fd (ctx);
/* FIXME: Revamp this code it is nearly to 3 years old and was only
intended as a quick test. */
-
+
(void)line;
if (fd == GNUPG_INVALID_FD)
if (out_fd != GNUPG_INVALID_FD)
{
- out_fp = es_fdopen_nc (out_fd, "w");
+ es_syshd_t syshd;
+
+#ifdef HAVE_W32_SYSTEM
+ syshd.type = ES_SYSHD_HANDLE;
+ syshd.u.handle = out_fd;
+#else
+ syshd.type = ES_SYSHD_FD;
+ syshd.u.fd = out_fd;
+#endif
+ out_fp = es_sysopen_nc (&syshd, "w");
if (!out_fp)
return set_error (gpg_err_code_from_syserror (), "fdopen() failed");
}
log_debug ("WARNING: The server mode is WORK "
- "iN PROGRESS and not ready for use\n");
+ "IN PROGRESS and not ready for use\n");
rc = gpg_verify (ctrl, fd, ctrl->server_local->message_fd, out_fp);
close_message_fd (ctrl);
assuan_close_input_fd (ctx);
assuan_close_output_fd (ctx);
+#endif
if (rc)
log_error ("command '%s' failed: %s\n", "VERIFY", gpg_strerror (rc));
static int
register_commands (assuan_context_t ctx)
{
- static struct
+ static struct
{
const char *name;
assuan_handler_t handler;
{ "SIGN", cmd_sign },
{ "IMPORT", cmd_import },
{ "EXPORT", cmd_export },
- { "INPUT", NULL },
- { "OUTPUT", NULL },
+ { "INPUT", NULL },
+ { "OUTPUT", NULL },
{ "MESSAGE", cmd_message },
{ "LISTKEYS", cmd_listkeys },
{ "LISTSECRETKEYS",cmd_listsecretkeys },
table[i].handler, table[i].help);
if (rc)
return rc;
- }
+ }
return 0;
}
gpg_server (ctrl_t ctrl)
{
int rc;
+#ifndef HAVE_W32_SYSTEM
int filedes[2];
+#endif
assuan_context_t ctx = NULL;
static const char hello[] = ("GNU Privacy Guard's OpenPGP server "
VERSION " ready");
/* We use a pipe based server so that we can work from scripts.
assuan_init_pipe_server will automagically detect when we are
called with a socketpair and ignore FILEDES in this case. */
+#ifndef HAVE_W32_SYSTEM
filedes[0] = assuan_fdopen (0);
filedes[1] = assuan_fdopen (1);
+#endif
rc = assuan_new (&ctx);
if (rc)
{
gpg_strerror (rc));
goto leave;
}
-
+
+#ifdef HAVE_W32_SYSTEM
+ rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+#else
rc = assuan_init_pipe_server (ctx, filedes);
+#endif
if (rc)
{
log_error ("failed to initialize the server: %s\n", gpg_strerror (rc));
if (opt.verbose || opt.debug)
{
char *tmp = NULL;
- const char *s1 = getenv ("GPG_AGENT_INFO");
tmp = xtryasprintf ("Home: %s\n"
"Config: %s\n"
- "AgentInfo: %s\n"
"%s",
opt.homedir,
"fixme: need config filename",
- s1?s1:"[not set]",
hello);
if (tmp)
{
log_info ("Assuan accept problem: %s\n", gpg_strerror (rc));
break;
}
-
+
rc = assuan_process (ctx);
if (rc)
{
return rc;
}
+
+/* Helper to notify the client about Pinentry events. Because that
+ might disturb some older clients, this is only done when enabled
+ via an option. If it is not enabled we tell Windows to allow
+ setting the foreground window right here. Returns an gpg error
+ code. */
+gpg_error_t
+gpg_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line)
+{
+ if (!ctrl || !ctrl->server_local
+ || !ctrl->server_local->allow_pinentry_notify)
+ {
+ gnupg_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10));
+ /* Client might be interested in that event - send as status line. */
+ if (!strncmp (line, "PINENTRY_LAUNCHED", 17)
+ && (line[17]==' '||!line[17]))
+ {
+ for (line += 17; *line && spacep (line); line++)
+ ;
+ write_status_text (STATUS_PINENTRY_LAUNCHED, line);
+ }
+ return 0;
+ }
+ return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
+}