mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
* protect-tool.c (main): Setup the used character set.
* gpg-agent.c (main): Ditto. * gpg-agent.c (set_debug): New. New option --debug-level. (main): New option --gpgconf-list.
This commit is contained in:
parent
81edc1e40e
commit
bda3467067
8
NEWS
8
NEWS
@ -8,9 +8,15 @@ Noteworthy changes in version 1.9.5
|
|||||||
* [gpgsm] The --import command is now able to autodetect pkcs#12
|
* [gpgsm] The --import command is now able to autodetect pkcs#12
|
||||||
files and import secret and private keys from this file format.
|
files and import secret and private keys from this file format.
|
||||||
|
|
||||||
* [gpgsm] The pinentry will no present a description of the key for
|
* [gpgsm] The pinentry will now present a description of the key for
|
||||||
whom the passphrase is requests.
|
whom the passphrase is requests.
|
||||||
|
|
||||||
|
* [gpgsm] New option --with-validation to check the validity of key
|
||||||
|
while listing it.
|
||||||
|
|
||||||
|
* New option --debug-level={none,basic,advanced,expert,guru} to map
|
||||||
|
the debug flags to sensitive levels on a per program base.
|
||||||
|
|
||||||
|
|
||||||
Noteworthy changes in version 1.9.4 (2004-01-30)
|
Noteworthy changes in version 1.9.4 (2004-01-30)
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
@ -1,3 +1,18 @@
|
|||||||
|
2004-02-18 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* protect-tool.c (main): Setup the used character set.
|
||||||
|
* gpg-agent.c (main): Ditto.
|
||||||
|
|
||||||
|
* gpg-agent.c (set_debug): New. New option --debug-level.
|
||||||
|
(main): New option --gpgconf-list.
|
||||||
|
|
||||||
|
2004-02-17 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* pksign.c (do_encode_md): Cleaned up by using gcry_sexp_build.
|
||||||
|
|
||||||
|
* Makefile.am (gpg_protect_tool_SOURCES): Removed
|
||||||
|
simple-pwquery.[ch], as we once moved it to ../common.
|
||||||
|
|
||||||
2004-02-13 Werner Koch <wk@gnupg.org>
|
2004-02-13 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* command.c (cmd_setkeydesc): New.
|
* command.c (cmd_setkeydesc): New.
|
||||||
|
@ -51,7 +51,6 @@ gpg_agent_LDADD = ../jnlib/libjnlib.a ../common/libcommon.a \
|
|||||||
gpg_protect_tool_SOURCES = \
|
gpg_protect_tool_SOURCES = \
|
||||||
protect-tool.c \
|
protect-tool.c \
|
||||||
protect.c \
|
protect.c \
|
||||||
simple-pwquery.c simple-pwquery.h \
|
|
||||||
minip12.c minip12.h
|
minip12.c minip12.h
|
||||||
|
|
||||||
gpg_protect_tool_LDADD = ../jnlib/libjnlib.a \
|
gpg_protect_tool_LDADD = ../jnlib/libjnlib.a \
|
||||||
|
@ -51,11 +51,13 @@ enum cmd_and_opt_values
|
|||||||
oQuiet = 'q',
|
oQuiet = 'q',
|
||||||
oSh = 's',
|
oSh = 's',
|
||||||
oVerbose = 'v',
|
oVerbose = 'v',
|
||||||
|
|
||||||
oNoVerbose = 500,
|
oNoVerbose = 500,
|
||||||
|
aGPGConfList,
|
||||||
oOptions,
|
oOptions,
|
||||||
oDebug,
|
oDebug,
|
||||||
oDebugAll,
|
oDebugAll,
|
||||||
|
oDebugLevel,
|
||||||
oDebugWait,
|
oDebugWait,
|
||||||
oNoGreeting,
|
oNoGreeting,
|
||||||
oNoOptions,
|
oNoOptions,
|
||||||
@ -86,6 +88,8 @@ aTest };
|
|||||||
|
|
||||||
|
|
||||||
static ARGPARSE_OPTS opts[] = {
|
static ARGPARSE_OPTS opts[] = {
|
||||||
|
|
||||||
|
{ aGPGConfList, "gpgconf-list", 256, "@" },
|
||||||
|
|
||||||
{ 301, NULL, 0, N_("@Options:\n ") },
|
{ 301, NULL, 0, N_("@Options:\n ") },
|
||||||
|
|
||||||
@ -96,8 +100,9 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
{ oSh, "sh", 0, N_("sh-style command output") },
|
{ oSh, "sh", 0, N_("sh-style command output") },
|
||||||
{ oCsh, "csh", 0, N_("csh-style command output") },
|
{ oCsh, "csh", 0, N_("csh-style command output") },
|
||||||
{ oOptions, "options" , 2, N_("read options from file")},
|
{ oOptions, "options" , 2, N_("read options from file")},
|
||||||
{ oDebug, "debug" ,4|16, N_("set debugging flags")},
|
{ oDebug, "debug" ,4|16, "@"},
|
||||||
{ oDebugAll, "debug-all" ,0, N_("enable full debugging")},
|
{ oDebugAll, "debug-all" ,0, "@"},
|
||||||
|
{ oDebugLevel, "debug-level" ,2, "@"},
|
||||||
{ oDebugWait,"debug-wait",1, "@"},
|
{ oDebugWait,"debug-wait",1, "@"},
|
||||||
{ oNoDetach, "no-detach" ,0, N_("do not detach from the console")},
|
{ oNoDetach, "no-detach" ,0, N_("do not detach from the console")},
|
||||||
{ oNoGrab, "no-grab" ,0, N_("do not grab keyboard and mouse")},
|
{ oNoGrab, "no-grab" ,0, N_("do not grab keyboard and mouse")},
|
||||||
@ -145,6 +150,8 @@ static char *default_lc_messages;
|
|||||||
/* Name of a config file, which will be reread on a HUP if it is not NULL. */
|
/* Name of a config file, which will be reread on a HUP if it is not NULL. */
|
||||||
static char *config_filename;
|
static char *config_filename;
|
||||||
|
|
||||||
|
/* Helper to implement --debug-level */
|
||||||
|
static const char *debug_level;
|
||||||
|
|
||||||
/* Local prototypes. */
|
/* Local prototypes. */
|
||||||
static void create_directories (void);
|
static void create_directories (void);
|
||||||
@ -216,6 +223,48 @@ my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Setup the debugging. With a LEVEL of NULL only the active debug
|
||||||
|
flags are propagated to the subsystems. With LEVEL set, a specific
|
||||||
|
set of debug flags is set; thus overriding all flags already
|
||||||
|
set. Note that we don't fail here, because it is important to keep
|
||||||
|
gpg-agent running even after re-reading the options due to a
|
||||||
|
SIGHUP. */
|
||||||
|
static void
|
||||||
|
set_debug (void)
|
||||||
|
{
|
||||||
|
if (!debug_level)
|
||||||
|
;
|
||||||
|
else if (!strcmp (debug_level, "none"))
|
||||||
|
opt.debug = 0;
|
||||||
|
else if (!strcmp (debug_level, "basic"))
|
||||||
|
opt.debug = DBG_ASSUAN_VALUE;
|
||||||
|
else if (!strcmp (debug_level, "advanced"))
|
||||||
|
opt.debug = DBG_ASSUAN_VALUE|DBG_COMMAND_VALUE;
|
||||||
|
else if (!strcmp (debug_level, "expert"))
|
||||||
|
opt.debug = (DBG_ASSUAN_VALUE|DBG_COMMAND_VALUE
|
||||||
|
|DBG_CACHE_VALUE);
|
||||||
|
else if (!strcmp (debug_level, "guru"))
|
||||||
|
opt.debug = ~0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_error (_("invalid debug-level `%s' given\n"), debug_level);
|
||||||
|
opt.debug = 0; /* Reset debugging, so that prior debug
|
||||||
|
statements won't have an undesired effect. */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt.debug && !opt.verbose)
|
||||||
|
opt.verbose = 1;
|
||||||
|
if (opt.debug && opt.quiet)
|
||||||
|
opt.quiet = 0;
|
||||||
|
|
||||||
|
if (opt.debug & DBG_MPI_VALUE)
|
||||||
|
gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
|
||||||
|
if (opt.debug & DBG_CRYPTO_VALUE )
|
||||||
|
gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
|
||||||
|
gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cleanup (void)
|
cleanup (void)
|
||||||
{
|
{
|
||||||
@ -286,6 +335,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs)
|
|||||||
|
|
||||||
case oDebug: opt.debug |= pargs->r.ret_ulong; break;
|
case oDebug: opt.debug |= pargs->r.ret_ulong; break;
|
||||||
case oDebugAll: opt.debug = ~0; break;
|
case oDebugAll: opt.debug = ~0; break;
|
||||||
|
case oDebugLevel: debug_level = pargs->r.ret_str; break;
|
||||||
|
|
||||||
case oNoGrab: opt.no_grab = 1; break;
|
case oNoGrab: opt.no_grab = 1; break;
|
||||||
|
|
||||||
@ -325,6 +375,7 @@ main (int argc, char **argv )
|
|||||||
char *logfile = NULL;
|
char *logfile = NULL;
|
||||||
int debug_wait = 0;
|
int debug_wait = 0;
|
||||||
int disable_pth = 0;
|
int disable_pth = 0;
|
||||||
|
int gpgconf_list = 0;
|
||||||
|
|
||||||
set_strusage (my_strusage);
|
set_strusage (my_strusage);
|
||||||
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
|
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
|
||||||
@ -332,6 +383,10 @@ main (int argc, char **argv )
|
|||||||
when adding any stuff between here and the call to INIT_SECMEM()
|
when adding any stuff between here and the call to INIT_SECMEM()
|
||||||
somewhere after the option parsing */
|
somewhere after the option parsing */
|
||||||
log_set_prefix ("gpg-agent", 1|4);
|
log_set_prefix ("gpg-agent", 1|4);
|
||||||
|
|
||||||
|
/* Try to auto set the character set. */
|
||||||
|
set_native_charset (NULL);
|
||||||
|
|
||||||
i18n_init ();
|
i18n_init ();
|
||||||
|
|
||||||
/* We need to initialize Pth before libgcrypt, because the libgcrypt
|
/* We need to initialize Pth before libgcrypt, because the libgcrypt
|
||||||
@ -446,6 +501,7 @@ main (int argc, char **argv )
|
|||||||
continue; /* Already handled */
|
continue; /* Already handled */
|
||||||
switch (pargs.r_opt)
|
switch (pargs.r_opt)
|
||||||
{
|
{
|
||||||
|
case aGPGConfList: gpgconf_list = 1; break;
|
||||||
case oBatch: opt.batch=1; break;
|
case oBatch: opt.batch=1; break;
|
||||||
|
|
||||||
case oDebugWait: debug_wait = pargs.r.ret_int; break;
|
case oDebugWait: debug_wait = pargs.r.ret_int; break;
|
||||||
@ -509,6 +565,7 @@ main (int argc, char **argv )
|
|||||||
log_info ("NOTE: this is a development version!\n");
|
log_info ("NOTE: this is a development version!\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
set_debug ();
|
||||||
|
|
||||||
if (atexit (cleanup))
|
if (atexit (cleanup))
|
||||||
{
|
{
|
||||||
@ -526,6 +583,22 @@ main (int argc, char **argv )
|
|||||||
sleep (debug_wait);
|
sleep (debug_wait);
|
||||||
log_debug ("... okay\n");
|
log_debug ("... okay\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gpgconf_list)
|
||||||
|
{ /* List options and default values in the GPG Conf format. */
|
||||||
|
|
||||||
|
printf ("gpgconf-gpg-agent.conf:\"%s\n", config_filename);
|
||||||
|
|
||||||
|
printf ("verbose:\n"
|
||||||
|
"quiet:\n"
|
||||||
|
"debug-level:none\n"
|
||||||
|
"log-file:\n"
|
||||||
|
"force:\n"
|
||||||
|
"faked-system-time:\n"
|
||||||
|
"no-greeting:\n");
|
||||||
|
|
||||||
|
agent_exit (0);
|
||||||
|
}
|
||||||
|
|
||||||
if (!pipe_server && !is_daemon)
|
if (!pipe_server && !is_daemon)
|
||||||
log_info (_("please use the option `--daemon'"
|
log_info (_("please use the option `--daemon'"
|
||||||
@ -853,6 +926,7 @@ reread_configuration (void)
|
|||||||
parse_rereadable_options (&pargs);
|
parse_rereadable_options (&pargs);
|
||||||
}
|
}
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
|
set_debug ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* pksign.c - public key signing (well, acually using a secret key)
|
/* pksign.c - public key signing (well, actually using a secret key)
|
||||||
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -35,17 +35,10 @@ static int
|
|||||||
do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash)
|
do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash)
|
||||||
{
|
{
|
||||||
gcry_sexp_t hash;
|
gcry_sexp_t hash;
|
||||||
const char * s;
|
const char *s;
|
||||||
char * p, tmp[16];
|
char tmp[16+1];
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#warning I do not like that stuff - libgcrypt provides easier interfaces. -wk
|
|
||||||
#endif
|
|
||||||
/* FIXME: Either use the build function or create canonical encoded
|
|
||||||
S-expressions. */
|
|
||||||
|
|
||||||
p = xmalloc (64 + 2 * mdlen);
|
|
||||||
s = gcry_md_algo_name (algo);
|
s = gcry_md_algo_name (algo);
|
||||||
if (s && strlen (s) < 16)
|
if (s && strlen (s) < 16)
|
||||||
{
|
{
|
||||||
@ -53,15 +46,10 @@ do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash)
|
|||||||
tmp[i] = tolower (s[i]);
|
tmp[i] = tolower (s[i]);
|
||||||
tmp[i] = '\0';
|
tmp[i] = '\0';
|
||||||
}
|
}
|
||||||
sprintf (p, "(data\n (flags pkcs1)\n (hash %s #", tmp);
|
rc = gcry_sexp_build (&hash, NULL,
|
||||||
for (i=0; i < mdlen; i++)
|
"(data (flags pkcs1) (hash %s %b))",
|
||||||
{
|
tmp,
|
||||||
sprintf (tmp, "%02x", (byte)md[i]);
|
mdlen, md);
|
||||||
strcat (p, tmp);
|
|
||||||
}
|
|
||||||
strcat (p, "#))\n");
|
|
||||||
rc = gcry_sexp_sscan (&hash, NULL, p, strlen (p));
|
|
||||||
xfree (p);
|
|
||||||
*r_hash = hash;
|
*r_hash = hash;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -872,6 +872,10 @@ main (int argc, char **argv )
|
|||||||
set_strusage (my_strusage);
|
set_strusage (my_strusage);
|
||||||
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
|
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
|
||||||
log_set_prefix ("gpg-protect-tool", 1);
|
log_set_prefix ("gpg-protect-tool", 1);
|
||||||
|
|
||||||
|
/* Try to auto set the character set. */
|
||||||
|
set_native_charset (NULL);
|
||||||
|
|
||||||
i18n_init ();
|
i18n_init ();
|
||||||
|
|
||||||
if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
|
if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
|
||||||
@ -884,6 +888,7 @@ main (int argc, char **argv )
|
|||||||
|
|
||||||
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
|
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
opt_homedir = read_w32_registry_string ( NULL,
|
opt_homedir = read_w32_registry_string ( NULL,
|
||||||
"Software\\GNU\\GnuPG", "HomeDir" );
|
"Software\\GNU\\GnuPG", "HomeDir" );
|
||||||
|
@ -1,486 +0,0 @@
|
|||||||
/* simple-pwquery.c - A simple password query client for gpg-agent
|
|
||||||
* Copyright (C) 2002 Free Software Foundation, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of GnuPG.
|
|
||||||
*
|
|
||||||
* GnuPG is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* GnuPG is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* This module is intended as a standalone client implementation to
|
|
||||||
gpg-agent's GET_PASSPHRASE command. In particular it does not use
|
|
||||||
the Assuan library and can only cope with an already running
|
|
||||||
gpg-agent. Some stuff is configurable in the header file. */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
#ifdef HAVE_LOCALE_H
|
|
||||||
#include <locale.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SIMPLE_PWQUERY_IMPLEMENTATION 1
|
|
||||||
#include "simple-pwquery.h"
|
|
||||||
|
|
||||||
#if defined(SPWQ_USE_LOGGING) && !defined(HAVE_JNLIB_LOGGING)
|
|
||||||
# undef SPWQ_USE_LOGGING
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _
|
|
||||||
#define _(a) (a)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined (hexdigitp) && !defined (xtoi_2)
|
|
||||||
#define digitp(p) (*(p) >= '0' && *(p) <= '9')
|
|
||||||
#define hexdigitp(a) (digitp (a) \
|
|
||||||
|| (*(a) >= 'A' && *(a) <= 'F') \
|
|
||||||
|| (*(a) >= 'a' && *(a) <= 'f'))
|
|
||||||
#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
|
|
||||||
*(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
|
|
||||||
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Write NBYTES of BUF to file descriptor FD. */
|
|
||||||
static int
|
|
||||||
writen (int fd, const void *buf, size_t nbytes)
|
|
||||||
{
|
|
||||||
size_t nleft = nbytes;
|
|
||||||
int nwritten;
|
|
||||||
|
|
||||||
while (nleft > 0)
|
|
||||||
{
|
|
||||||
nwritten = write( fd, buf, nleft );
|
|
||||||
if (nwritten < 0)
|
|
||||||
{
|
|
||||||
if (errno == EINTR)
|
|
||||||
nwritten = 0;
|
|
||||||
else {
|
|
||||||
#ifdef SPWQ_USE_LOGGING
|
|
||||||
log_error ("write failed: %s\n", strerror (errno));
|
|
||||||
#endif
|
|
||||||
return SPWQ_IO_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nleft -= nwritten;
|
|
||||||
buf = (const char*)buf + nwritten;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Read an entire line and return number of bytes read. */
|
|
||||||
static int
|
|
||||||
readline (int fd, char *buf, size_t buflen)
|
|
||||||
{
|
|
||||||
size_t nleft = buflen;
|
|
||||||
char *p;
|
|
||||||
int nread = 0;
|
|
||||||
|
|
||||||
while (nleft > 0)
|
|
||||||
{
|
|
||||||
int n = read (fd, buf, nleft);
|
|
||||||
if (n < 0)
|
|
||||||
{
|
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
return -(SPWQ_IO_ERROR);
|
|
||||||
}
|
|
||||||
else if (!n)
|
|
||||||
{
|
|
||||||
return -(SPWQ_PROTOCOL_ERROR); /* incomplete line */
|
|
||||||
}
|
|
||||||
p = buf;
|
|
||||||
nleft -= n;
|
|
||||||
buf += n;
|
|
||||||
nread += n;
|
|
||||||
|
|
||||||
for (; n && *p != '\n'; n--, p++)
|
|
||||||
;
|
|
||||||
if (n)
|
|
||||||
{
|
|
||||||
break; /* at least one full line available - that's enough.
|
|
||||||
This function is just a simple implementation, so
|
|
||||||
it is okay to forget about pending bytes */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nread;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Send an option to the agent */
|
|
||||||
static int
|
|
||||||
agent_send_option (int fd, const char *name, const char *value)
|
|
||||||
{
|
|
||||||
char buf[200];
|
|
||||||
int nread;
|
|
||||||
char *line;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
line = spwq_malloc (7 + strlen (name) + 1 + strlen (value) + 2);
|
|
||||||
if (!line)
|
|
||||||
return SPWQ_OUT_OF_CORE;
|
|
||||||
strcpy (stpcpy (stpcpy (stpcpy (
|
|
||||||
stpcpy (line, "OPTION "), name), "="), value), "\n");
|
|
||||||
i = writen (fd, line, strlen (line));
|
|
||||||
spwq_free (line);
|
|
||||||
if (i)
|
|
||||||
return i;
|
|
||||||
|
|
||||||
/* get response */
|
|
||||||
nread = readline (fd, buf, DIM(buf)-1);
|
|
||||||
if (nread < 0)
|
|
||||||
return -nread;
|
|
||||||
if (nread < 3)
|
|
||||||
return SPWQ_PROTOCOL_ERROR;
|
|
||||||
|
|
||||||
if (buf[0] == 'O' && buf[1] == 'K' && (buf[2] == ' ' || buf[2] == '\n'))
|
|
||||||
return 0; /* okay */
|
|
||||||
|
|
||||||
return SPWQ_ERR_RESPONSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Send all available options to the agent. */
|
|
||||||
static int
|
|
||||||
agent_send_all_options (int fd)
|
|
||||||
{
|
|
||||||
char *dft_display = NULL;
|
|
||||||
char *dft_ttyname = NULL;
|
|
||||||
char *dft_ttytype = NULL;
|
|
||||||
int rc = 0;
|
|
||||||
|
|
||||||
dft_display = getenv ("DISPLAY");
|
|
||||||
if (dft_display)
|
|
||||||
{
|
|
||||||
if ((rc = agent_send_option (fd, "display", dft_display)))
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
dft_ttyname = getenv ("GPG_TTY");
|
|
||||||
if ((!dft_ttyname || !*dft_ttyname) && ttyname (0))
|
|
||||||
dft_ttyname = ttyname (0);
|
|
||||||
if (dft_ttyname && *dft_ttyname)
|
|
||||||
{
|
|
||||||
if ((rc=agent_send_option (fd, "ttyname", dft_ttyname)))
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
dft_ttytype = getenv ("TERM");
|
|
||||||
if (dft_ttyname && dft_ttytype)
|
|
||||||
{
|
|
||||||
if ((rc = agent_send_option (fd, "ttytype", dft_ttytype)))
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(HAVE_SETLOCALE)
|
|
||||||
{
|
|
||||||
char *old_lc = NULL;
|
|
||||||
char *dft_lc = NULL;
|
|
||||||
|
|
||||||
#if defined(LC_CTYPE)
|
|
||||||
old_lc = setlocale (LC_CTYPE, NULL);
|
|
||||||
if (old_lc)
|
|
||||||
{
|
|
||||||
char *p = spwq_malloc (strlen (old_lc)+1);
|
|
||||||
if (!p)
|
|
||||||
return SPWQ_OUT_OF_CORE;
|
|
||||||
strcpy (p, old_lc);
|
|
||||||
old_lc = p;
|
|
||||||
}
|
|
||||||
dft_lc = setlocale (LC_CTYPE, "");
|
|
||||||
if (dft_ttyname && dft_lc)
|
|
||||||
rc = agent_send_option (fd, "lc-ctype", dft_lc);
|
|
||||||
if (old_lc)
|
|
||||||
{
|
|
||||||
setlocale (LC_CTYPE, old_lc);
|
|
||||||
spwq_free (old_lc);
|
|
||||||
}
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(LC_MESSAGES)
|
|
||||||
old_lc = setlocale (LC_MESSAGES, NULL);
|
|
||||||
if (old_lc)
|
|
||||||
{
|
|
||||||
char *p = spwq_malloc (strlen (old_lc)+1);
|
|
||||||
if (!p)
|
|
||||||
return SPWQ_OUT_OF_CORE;
|
|
||||||
strcpy (p, old_lc);
|
|
||||||
old_lc = p;
|
|
||||||
}
|
|
||||||
dft_lc = setlocale (LC_MESSAGES, "");
|
|
||||||
if (dft_ttyname && dft_lc)
|
|
||||||
rc = agent_send_option (fd, "lc-messages", dft_lc);
|
|
||||||
if (old_lc)
|
|
||||||
{
|
|
||||||
setlocale (LC_MESSAGES, old_lc);
|
|
||||||
spwq_free (old_lc);
|
|
||||||
}
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif /*HAVE_SETLOCALE*/
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Try to open a connection to the agent, send all options and return
|
|
||||||
the file descriptor for the connection. Return -1 in case of
|
|
||||||
error. */
|
|
||||||
static int
|
|
||||||
agent_open (int *rfd)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
int fd;
|
|
||||||
char *infostr, *p;
|
|
||||||
struct sockaddr_un client_addr;
|
|
||||||
size_t len;
|
|
||||||
int prot;
|
|
||||||
char line[200];
|
|
||||||
int nread;
|
|
||||||
|
|
||||||
*rfd = -1;
|
|
||||||
infostr = getenv ( "GPG_AGENT_INFO" );
|
|
||||||
if ( !infostr )
|
|
||||||
{
|
|
||||||
#ifdef SPWQ_USE_LOGGING
|
|
||||||
log_error (_("gpg-agent is not available in this session\n"));
|
|
||||||
#endif
|
|
||||||
return SPWQ_NO_AGENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !(p = strchr ( infostr, ':')) || p == infostr
|
|
||||||
|| (p-infostr)+1 >= sizeof client_addr.sun_path )
|
|
||||||
{
|
|
||||||
#ifdef SPWQ_USE_LOGGING
|
|
||||||
log_error ( _("malformed GPG_AGENT_INFO environment variable\n"));
|
|
||||||
#endif
|
|
||||||
return SPWQ_NO_AGENT;
|
|
||||||
}
|
|
||||||
*p++ = 0;
|
|
||||||
|
|
||||||
while (*p && *p != ':')
|
|
||||||
p++;
|
|
||||||
prot = *p? atoi (p+1) : 0;
|
|
||||||
if ( prot != 1)
|
|
||||||
{
|
|
||||||
#ifdef SPWQ_USE_LOGGING
|
|
||||||
log_error (_("gpg-agent protocol version %d is not supported\n"),prot);
|
|
||||||
#endif
|
|
||||||
return SPWQ_PROTOCOL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 )
|
|
||||||
{
|
|
||||||
#ifdef SPWQ_USE_LOGGING
|
|
||||||
log_error ("can't create socket: %s\n", strerror(errno) );
|
|
||||||
#endif
|
|
||||||
return SPWQ_SYS_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset (&client_addr, 0, sizeof client_addr);
|
|
||||||
client_addr.sun_family = AF_UNIX;
|
|
||||||
strcpy (client_addr.sun_path, infostr);
|
|
||||||
len = (offsetof (struct sockaddr_un, sun_path)
|
|
||||||
+ strlen(client_addr.sun_path) + 1);
|
|
||||||
|
|
||||||
if (connect (fd, (struct sockaddr*)&client_addr, len ) == -1)
|
|
||||||
{
|
|
||||||
#ifdef SPWQ_USE_LOGGING
|
|
||||||
log_error ( _("can't connect to `%s': %s\n"), infostr, strerror (errno));
|
|
||||||
#endif
|
|
||||||
close (fd );
|
|
||||||
return SPWQ_IO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
nread = readline (fd, line, DIM(line));
|
|
||||||
if (nread < 3 || !(line[0] == 'O' && line[1] == 'K'
|
|
||||||
&& (line[2] == '\n' || line[2] == ' ')) )
|
|
||||||
{
|
|
||||||
#ifdef SPWQ_USE_LOGGING
|
|
||||||
log_error ( _("communication problem with gpg-agent\n"));
|
|
||||||
#endif
|
|
||||||
close (fd );
|
|
||||||
return SPWQ_PROTOCOL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = agent_send_all_options (fd);
|
|
||||||
if (rc)
|
|
||||||
{
|
|
||||||
#ifdef SPWQ_USE_LOGGING
|
|
||||||
log_error (_("problem setting the gpg-agent options\n"));
|
|
||||||
#endif
|
|
||||||
close (fd);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
*rfd = fd;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Copy text to BUFFER and escape as required. Return a poiinter to
|
|
||||||
the end of the new buffer. NOte that BUFFER must be large enough
|
|
||||||
to keep the entire text; allocataing it 3 times the size of TEXT
|
|
||||||
is sufficient. */
|
|
||||||
static char *
|
|
||||||
copy_and_escape (char *buffer, const char *text)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char *p = buffer;
|
|
||||||
|
|
||||||
for (i=0; text[i]; i++)
|
|
||||||
{
|
|
||||||
if (text[i] < ' ' || text[i] == '+')
|
|
||||||
{
|
|
||||||
sprintf (p, "%%%02X", text[i]);
|
|
||||||
p += 3;
|
|
||||||
}
|
|
||||||
else if (text[i] == ' ')
|
|
||||||
*p++ = '+';
|
|
||||||
else
|
|
||||||
*p++ = text[i];
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Ask the gpg-agent for a passphrase and present the user with a
|
|
||||||
DESCRIPTION, a PROMPT and optiaonlly with a TRYAGAIN extra text.
|
|
||||||
If a CACHEID is not NULL it is used to locate the passphrase in in
|
|
||||||
the cache and store it under this ID. If ERRORCODE is not NULL it
|
|
||||||
should point a variable receiving an errorcode; thsi errocode might
|
|
||||||
be 0 if the user canceled the operation. The function returns NULL
|
|
||||||
to indicate an error. */
|
|
||||||
char *
|
|
||||||
simple_pwquery (const char *cacheid,
|
|
||||||
const char *tryagain,
|
|
||||||
const char *prompt,
|
|
||||||
const char *description,
|
|
||||||
int *errorcode)
|
|
||||||
{
|
|
||||||
int fd = -1;
|
|
||||||
int nread;
|
|
||||||
char *result = NULL;
|
|
||||||
char *pw = NULL;
|
|
||||||
char *p;
|
|
||||||
int rc, i;
|
|
||||||
|
|
||||||
rc = agent_open (&fd);
|
|
||||||
if (rc)
|
|
||||||
goto leave;
|
|
||||||
|
|
||||||
if (!cacheid)
|
|
||||||
cacheid = "X";
|
|
||||||
if (!tryagain)
|
|
||||||
tryagain = "X";
|
|
||||||
if (!prompt)
|
|
||||||
prompt = "X";
|
|
||||||
if (!description)
|
|
||||||
description = "X";
|
|
||||||
|
|
||||||
{
|
|
||||||
char *line;
|
|
||||||
/* We allocate 3 times the needed space so that there is enough
|
|
||||||
space for escaping. */
|
|
||||||
line = spwq_malloc (15
|
|
||||||
+ 3*strlen (cacheid) + 1
|
|
||||||
+ 3*strlen (tryagain) + 1
|
|
||||||
+ 3*strlen (prompt) + 1
|
|
||||||
+ 3*strlen (description) + 1
|
|
||||||
+ 2);
|
|
||||||
if (!line)
|
|
||||||
{
|
|
||||||
rc = SPWQ_OUT_OF_CORE;
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
strcpy (line, "GET_PASSPHRASE ");
|
|
||||||
p = line+15;
|
|
||||||
p = copy_and_escape (p, cacheid);
|
|
||||||
*p++ = ' ';
|
|
||||||
p = copy_and_escape (p, tryagain);
|
|
||||||
*p++ = ' ';
|
|
||||||
p = copy_and_escape (p, prompt);
|
|
||||||
*p++ = ' ';
|
|
||||||
p = copy_and_escape (p, description);
|
|
||||||
*p++ = '\n';
|
|
||||||
rc = writen (fd, line, p - line);
|
|
||||||
spwq_free (line);
|
|
||||||
if (rc)
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get response */
|
|
||||||
pw = spwq_secure_malloc (500);
|
|
||||||
nread = readline (fd, pw, 499);
|
|
||||||
if (nread < 0)
|
|
||||||
{
|
|
||||||
rc = -nread;
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
if (nread < 3)
|
|
||||||
{
|
|
||||||
rc = SPWQ_PROTOCOL_ERROR;
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pw[0] == 'O' && pw[1] == 'K' && pw[2] == ' ')
|
|
||||||
{ /* we got a passphrase - convert it back from hex */
|
|
||||||
size_t pwlen = 0;
|
|
||||||
|
|
||||||
for (i=3; i < nread && hexdigitp (pw+i); i+=2)
|
|
||||||
pw[pwlen++] = xtoi_2 (pw+i);
|
|
||||||
pw[pwlen] = 0; /* make a C String */
|
|
||||||
result = pw;
|
|
||||||
pw = NULL;
|
|
||||||
}
|
|
||||||
else if (nread > 7 && !memcmp (pw, "ERR 111", 7)
|
|
||||||
&& (pw[7] == ' ' || pw[7] == '\n') )
|
|
||||||
{
|
|
||||||
#ifdef SPWQ_USE_LOGGING
|
|
||||||
log_info (_("canceled by user\n") );
|
|
||||||
#endif
|
|
||||||
*errorcode = 0; /* canceled */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef SPWQ_USE_LOGGING
|
|
||||||
log_error (_("problem with the agent\n"));
|
|
||||||
#endif
|
|
||||||
rc = SPWQ_ERR_RESPONSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
leave:
|
|
||||||
if (errorcode)
|
|
||||||
*errorcode = rc;
|
|
||||||
if (fd != -1)
|
|
||||||
close (fd);
|
|
||||||
if (pw)
|
|
||||||
spwq_free (pw);
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
/* simple-pwquery.c - A simple password query cleint for gpg-agent
|
|
||||||
* Copyright (C) 2002 Free Software Foundation, Inc.
|
|
||||||
*
|
|
||||||
* This file is part of GnuPG.
|
|
||||||
*
|
|
||||||
* GnuPG is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* GnuPG is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SIMPLE_PWQUERY_H
|
|
||||||
#define SIMPLE_PWQUERY_H
|
|
||||||
|
|
||||||
#ifdef SIMPLE_PWQUERY_IMPLEMENTATION /* Begin configuration stuff. */
|
|
||||||
|
|
||||||
/* Include whatever files you need. */
|
|
||||||
#include <gcrypt.h>
|
|
||||||
#include "../jnlib/logging.h"
|
|
||||||
|
|
||||||
/* Try to write error message using the standard log mechanism. The
|
|
||||||
current implementation requires that the HAVE_JNLIB_LOGGING is also
|
|
||||||
defined. */
|
|
||||||
#define SPWQ_USE_LOGGING 1
|
|
||||||
|
|
||||||
/* Memory allocation functions used by the implementation. Note, that
|
|
||||||
the returned value is expected to be freed with
|
|
||||||
spwq_secure_free. */
|
|
||||||
#define spwq_malloc(a) gcry_malloc (a)
|
|
||||||
#define spwq_free(a) gcry_free (a)
|
|
||||||
#define spwq_secure_malloc(a) gcry_malloc_secure (a)
|
|
||||||
#define spwq_secure_free(a) gcry_free (a)
|
|
||||||
|
|
||||||
|
|
||||||
#endif /*SIMPLE_PWQUERY_IMPLEMENTATION*/ /* End configuration stuff. */
|
|
||||||
|
|
||||||
|
|
||||||
/* Ask the gpg-agent for a passphrase and present the user with a
|
|
||||||
DESCRIPTION, a PROMPT and optiaonlly with a TRYAGAIN extra text.
|
|
||||||
If a CACHEID is not NULL it is used to locate the passphrase in in
|
|
||||||
the cache and store it under this ID. If ERRORCODE is not NULL it
|
|
||||||
should point a variable receiving an errorcode; thsi errocode might
|
|
||||||
be 0 if the user canceled the operation. The function returns NULL
|
|
||||||
to indicate an error. */
|
|
||||||
char *simple_pwquery (const char *cacheid,
|
|
||||||
const char *tryagain,
|
|
||||||
const char *prompt,
|
|
||||||
const char *description,
|
|
||||||
int *errorcode);
|
|
||||||
|
|
||||||
|
|
||||||
#define SPWQ_OUT_OF_CORE 1
|
|
||||||
#define SPWQ_IO_ERROR 2
|
|
||||||
#define SPWQ_PROTOCOL_ERROR 3
|
|
||||||
#define SPWQ_ERR_RESPONSE 4
|
|
||||||
#define SPWQ_NO_AGENT 5
|
|
||||||
#define SPWQ_SYS_ERROR 6
|
|
||||||
#define SPWQ_GENERAL_ERROR 7
|
|
||||||
|
|
||||||
#endif /*SIMPLE_PWQUERY_H*/
|
|
Loading…
x
Reference in New Issue
Block a user