mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
Implemented the --gen-key command as we can't use the gpgsm-gencert.sh under Windows.
This commit is contained in:
parent
09cc0ee7be
commit
0b66f30d66
33 changed files with 714 additions and 317 deletions
|
@ -1,3 +1,17 @@
|
|||
2007-06-21 Werner Koch <wk@g10code.com>
|
||||
|
||||
* membuf.h (get_membuf_len): New.
|
||||
|
||||
* membuf.c (init_membuf_secure): Really allocate in secure memory.
|
||||
(put_membuf_str): New.
|
||||
|
||||
* ttyio.c (tty_getf): New.
|
||||
|
||||
* util.h (ctrl_t): Declare it here.
|
||||
|
||||
* asshelp.c (start_new_gpg_agent): New. Based on code from
|
||||
../sm/call-agent.c
|
||||
|
||||
2007-06-20 Werner Koch <wk@g10code.com>
|
||||
|
||||
* sysutils.c (gnupg_sleep): New.
|
||||
|
|
184
common/asshelp.c
184
common/asshelp.c
|
@ -29,8 +29,11 @@
|
|||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
#include "i18n.h"
|
||||
#include "util.h"
|
||||
|
||||
#include "exechelp.h"
|
||||
#include "sysutils.h"
|
||||
#include "errors.h" /* FIXME: This one conatisn only status code - rename it*/
|
||||
#include "asshelp.h"
|
||||
|
||||
|
||||
|
@ -164,3 +167,182 @@ send_pinentry_environment (assuan_context_t ctx,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Try to connect to the agent via socket or fork it off and work by
|
||||
pipes. Handle the server's initial greeting. Returns a new assuan
|
||||
context at R_CTX or an error code. */
|
||||
gpg_error_t
|
||||
start_new_gpg_agent (assuan_context_t *r_ctx,
|
||||
gpg_err_source_t errsource,
|
||||
const char *homedir,
|
||||
const char *agent_program,
|
||||
const char *opt_display,
|
||||
const char *opt_ttyname,
|
||||
const char *opt_ttytype,
|
||||
const char *opt_lc_ctype,
|
||||
const char *opt_lc_messages,
|
||||
int verbose, int debug,
|
||||
gpg_error_t (*status_cb)(ctrl_t, int, ...),
|
||||
ctrl_t status_cb_arg)
|
||||
{
|
||||
/* If we ever failed to connect via a socket we will force the use
|
||||
of the pipe based server for the lifetime of the process. */
|
||||
static int force_pipe_server = 0;
|
||||
|
||||
gpg_error_t rc = 0;
|
||||
char *infostr, *p;
|
||||
assuan_context_t ctx;
|
||||
|
||||
*r_ctx = NULL;
|
||||
|
||||
restart:
|
||||
infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO");
|
||||
if (!infostr || !*infostr)
|
||||
{
|
||||
char *sockname;
|
||||
|
||||
/* First check whether we can connect at the standard
|
||||
socket. */
|
||||
sockname = make_filename (homedir, "S.gpg-agent", NULL);
|
||||
rc = assuan_socket_connect (&ctx, sockname, 0);
|
||||
|
||||
if (rc)
|
||||
{
|
||||
/* With no success start a new server. */
|
||||
if (verbose)
|
||||
log_info (_("no running gpg-agent - starting one\n"));
|
||||
|
||||
if (status_cb)
|
||||
status_cb (status_cb_arg, STATUS_PROGRESS,
|
||||
"starting_agent ? 0 0", NULL);
|
||||
|
||||
if (fflush (NULL))
|
||||
{
|
||||
gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
|
||||
log_error ("error flushing pending output: %s\n",
|
||||
strerror (errno));
|
||||
xfree (sockname);
|
||||
return tmperr;
|
||||
}
|
||||
|
||||
if (!agent_program || !*agent_program)
|
||||
agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT);
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
{
|
||||
/* Under Windows we start the server in daemon mode. This
|
||||
is because the default is to use the standard socket
|
||||
and thus there is no need for the GPG_AGENT_INFO
|
||||
envvar. This is possible as we don't have a real unix
|
||||
domain socket but use a plain file and thus there is no
|
||||
need to care about non-local file systems. */
|
||||
const char *argv[3];
|
||||
|
||||
argv[0] = "--daemon";
|
||||
argv[1] = "--use-standard-socket";
|
||||
argv[2] = NULL;
|
||||
|
||||
rc = gnupg_spawn_process_detached (agent_program, argv, NULL);
|
||||
if (rc)
|
||||
log_debug ("failed to start agent `%s': %s\n",
|
||||
agent_program, gpg_strerror (rc));
|
||||
else
|
||||
{
|
||||
/* Give the agent some time to prepare itself. */
|
||||
gnupg_sleep (3);
|
||||
/* Now try again to connect the agent. */
|
||||
rc = assuan_socket_connect (&ctx, sockname, 0);
|
||||
}
|
||||
}
|
||||
#else /*!HAVE_W32_SYSTEM*/
|
||||
{
|
||||
const char *pgmname;
|
||||
const char *argv[3];
|
||||
int no_close_list[3];
|
||||
int i;
|
||||
|
||||
if ( !(pgmname = strrchr (agent_program, '/')))
|
||||
pgmname = agent_program;
|
||||
else
|
||||
pgmname++;
|
||||
|
||||
argv[0] = pgmname;
|
||||
argv[1] = "--server";
|
||||
argv[2] = NULL;
|
||||
|
||||
i=0;
|
||||
if (log_get_fd () != -1)
|
||||
no_close_list[i++] = log_get_fd ();
|
||||
no_close_list[i++] = fileno (stderr);
|
||||
no_close_list[i] = -1;
|
||||
|
||||
/* Connect to the agent and perform initial handshaking. */
|
||||
rc = assuan_pipe_connect (&ctx, agent_program, argv,
|
||||
no_close_list);
|
||||
}
|
||||
#endif /*!HAVE_W32_SYSTEM*/
|
||||
}
|
||||
xfree (sockname);
|
||||
}
|
||||
else
|
||||
{
|
||||
int prot;
|
||||
int pid;
|
||||
|
||||
infostr = xstrdup (infostr);
|
||||
if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
|
||||
{
|
||||
log_error (_("malformed GPG_AGENT_INFO environment variable\n"));
|
||||
xfree (infostr);
|
||||
force_pipe_server = 1;
|
||||
goto restart;
|
||||
}
|
||||
*p++ = 0;
|
||||
pid = atoi (p);
|
||||
while (*p && *p != PATHSEP_C)
|
||||
p++;
|
||||
prot = *p? atoi (p+1) : 0;
|
||||
if (prot != 1)
|
||||
{
|
||||
log_error (_("gpg-agent protocol version %d is not supported\n"),
|
||||
prot);
|
||||
xfree (infostr);
|
||||
force_pipe_server = 1;
|
||||
goto restart;
|
||||
}
|
||||
|
||||
rc = assuan_socket_connect (&ctx, infostr, pid);
|
||||
xfree (infostr);
|
||||
if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED)
|
||||
{
|
||||
log_info (_("can't connect to the agent - trying fall back\n"));
|
||||
force_pipe_server = 1;
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc)
|
||||
{
|
||||
log_error ("can't connect to the agent: %s\n", gpg_strerror (rc));
|
||||
return gpg_error (GPG_ERR_NO_AGENT);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
log_debug ("connection to agent established\n");
|
||||
|
||||
rc = assuan_transact (ctx, "RESET",
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
if (!rc)
|
||||
rc = send_pinentry_environment (ctx, errsource,
|
||||
opt_display, opt_ttyname, opt_ttytype,
|
||||
opt_lc_ctype, opt_lc_messages);
|
||||
if (rc)
|
||||
{
|
||||
assuan_disconnect (ctx);
|
||||
return rc;
|
||||
}
|
||||
|
||||
*r_ctx = ctx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,5 +34,21 @@ send_pinentry_environment (assuan_context_t ctx,
|
|||
const char *opt_lc_ctype,
|
||||
const char *opt_lc_messages);
|
||||
|
||||
/* This fucntion is used by the call-agent.c modules to fire up a new
|
||||
agent. What a parameter list ;-). */
|
||||
gpg_error_t
|
||||
start_new_gpg_agent (assuan_context_t *r_ctx,
|
||||
gpg_err_source_t errsource,
|
||||
const char *homedir,
|
||||
const char *agent_program,
|
||||
const char *opt_display,
|
||||
const char *opt_ttyname,
|
||||
const char *opt_ttytype,
|
||||
const char *opt_lc_ctype,
|
||||
const char *opt_lc_messages,
|
||||
int verbose, int debug,
|
||||
gpg_error_t (*status_cb)(ctrl_t, int, ...),
|
||||
ctrl_t status_cb_arg);
|
||||
|
||||
|
||||
#endif /*GNUPG_COMMON_ASSHELP_H*/
|
||||
|
|
|
@ -593,7 +593,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
|
|||
cmdline, /* Command line arguments. */
|
||||
&sec_attr, /* Process security attributes. */
|
||||
&sec_attr, /* Thread security attributes. */
|
||||
FALSE, /* Inherit handles. */
|
||||
FALSE, /* Inherit handles. */
|
||||
cr_flags, /* Creation flags. */
|
||||
NULL, /* Environment. */
|
||||
NULL, /* Use current drive/directory. */
|
||||
|
|
|
@ -52,7 +52,7 @@ init_membuf_secure (membuf_t *mb, int initiallen)
|
|||
mb->len = 0;
|
||||
mb->size = initiallen;
|
||||
mb->out_of_core = 0;
|
||||
mb->buf = xtrymalloc (initiallen);
|
||||
mb->buf = xtrymalloc_secure (initiallen);
|
||||
if (!mb->buf)
|
||||
mb->out_of_core = errno;
|
||||
}
|
||||
|
@ -87,6 +87,13 @@ put_membuf (membuf_t *mb, const void *buf, size_t len)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
put_membuf_str (membuf_t *mb, const char *string)
|
||||
{
|
||||
put_membuf (mb, string, strlen (string));
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
get_membuf (membuf_t *mb, size_t *len)
|
||||
{
|
||||
|
|
|
@ -34,10 +34,13 @@ struct private_membuf_s
|
|||
|
||||
typedef struct private_membuf_s membuf_t;
|
||||
|
||||
/* Return the current length of the membuf. */
|
||||
#define get_membuf_len(a) ((a)->len)
|
||||
|
||||
void init_membuf (membuf_t *mb, int initiallen);
|
||||
void init_membuf_secure (membuf_t *mb, int initiallen);
|
||||
void put_membuf (membuf_t *mb, const void *buf, size_t len);
|
||||
void put_membuf_str (membuf_t *mb, const char *string);
|
||||
void *get_membuf (membuf_t *mb, size_t *len);
|
||||
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
|
||||
#include "util.h"
|
||||
#include "ttyio.h"
|
||||
#include "estream-printf.h"
|
||||
#include "common-defs.h"
|
||||
|
||||
#define CONTROL_D ('D' - 'A' + 1)
|
||||
|
@ -243,7 +244,7 @@ tty_printf( const char *fmt, ... )
|
|||
}
|
||||
|
||||
|
||||
/* Same as tty_printf but if FP is not NULL, behave like a regualr
|
||||
/* Same as tty_printf but if FP is not NULL, behave like a regular
|
||||
fprintf. */
|
||||
void
|
||||
tty_fprintf (FILE *fp, const char *fmt, ... )
|
||||
|
@ -563,6 +564,26 @@ tty_get( const char *prompt )
|
|||
return do_get ( prompt, 0 );
|
||||
}
|
||||
|
||||
/* Variable argument version of tty_get. The prompt is is actually a
|
||||
format string with arguments. */
|
||||
char *
|
||||
tty_getf (const char *promptfmt, ... )
|
||||
{
|
||||
va_list arg_ptr;
|
||||
char *prompt;
|
||||
char *answer;
|
||||
|
||||
va_start (arg_ptr, promptfmt);
|
||||
if (estream_vasprintf (&prompt, promptfmt, arg_ptr) < 0)
|
||||
log_fatal ("estream_vasprintf failed: %s\n", strerror (errno));
|
||||
va_end (arg_ptr);
|
||||
answer = tty_get (prompt);
|
||||
xfree (prompt);
|
||||
return answer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *
|
||||
tty_get_hidden( const char *prompt )
|
||||
{
|
||||
|
|
|
@ -31,9 +31,12 @@ void tty_printf (const char *fmt, ... )
|
|||
__attribute__ ((format (printf,1,2)));
|
||||
void tty_fprintf (FILE *fp, const char *fmt, ... )
|
||||
__attribute__ ((format (printf,2,3)));
|
||||
char *tty_getf (const char *promptfmt, ... )
|
||||
__attribute__ ((format (printf,1,2)));
|
||||
#else
|
||||
void tty_printf (const char *fmt, ... );
|
||||
void tty_fprintf (FILE *fp, const char *fmt, ... );
|
||||
char *tty_getf (const char *promptfmt, ... );
|
||||
#endif
|
||||
void tty_print_string (const unsigned char *p, size_t n);
|
||||
void tty_print_utf8_string (const unsigned char *p, size_t n);
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#define asprintf estream_asprintf
|
||||
#define vasprintf estream_vasprintf
|
||||
|
||||
|
||||
/* GCC attributes. */
|
||||
#if __GNUC__ >= 4
|
||||
# define GNUPG_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a)))
|
||||
|
@ -246,5 +245,10 @@ ttyname (int fd)
|
|||
#define xtoi_4(p) ((xtoi_2(p) * 256) + xtoi_2((p)+2))
|
||||
|
||||
|
||||
/*-- Forward declaration of the commonly used server control structure. */
|
||||
/* (We need it here as it is used by some callback prototypes.) */
|
||||
struct server_control_s;
|
||||
typedef struct server_control_s *ctrl_t;
|
||||
|
||||
|
||||
#endif /*GNUPG_COMMON_UTIL_H*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue