2005-07-04 Marcus Brinkmann <marcus@g10code.de>

* symcryptrun.c (SYMC_BAD_PASSPHRASE, SYMC_CANCELED): New symbols,
	use instead constants.
	(hash_string): New function copied from simple-gettext.c.
	(confucius_get_pass): Take new argument CACHEID.
	(confucius_process): Calculate cacheid and pass it to
	confucius_get_pass.  Clear passphrase from cache if necessary.
This commit is contained in:
Marcus Brinkmann 2005-07-04 04:58:04 +00:00
parent 51a164e752
commit 53a1347fbe
2 changed files with 71 additions and 6 deletions

View File

@ -1,3 +1,12 @@
2005-07-04 Marcus Brinkmann <marcus@g10code.de>
* symcryptrun.c (SYMC_BAD_PASSPHRASE, SYMC_CANCELED): New symbols,
use instead constants.
(hash_string): New function copied from simple-gettext.c.
(confucius_get_pass): Take new argument CACHEID.
(confucius_process): Calculate cacheid and pass it to
confucius_get_pass. Clear passphrase from cache if necessary.
2005-06-16 Werner Koch <wk@g10code.com>
* gpg-connect-agent.c (read_and_print_response): Made LINELEN a

View File

@ -56,6 +56,9 @@
Other classes may be added in the future. */
#define SYMC_BAD_PASSPHRASE 2
#define SYMC_CANCELED 3
#include <config.h>
@ -107,6 +110,37 @@ my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
log_logv (level, fmt, arg_ptr);
}
/* From simple-gettext.c. */
/* We assume to have `unsigned long int' value with at least 32 bits. */
#define HASHWORDBITS 32
/* The so called `hashpjw' function by P.J. Weinberger
[see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
1986, 1987 Bell Telephone Laboratories, Inc.] */
static __inline__ ulong
hash_string( const char *str_param )
{
unsigned long int hval, g;
const char *str = str_param;
hval = 0;
while (*str != '\0')
{
hval <<= 4;
hval += (unsigned long int) *str++;
g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4));
if (g != 0)
{
hval ^= g >> (HASHWORDBITS - 8);
hval ^= g;
}
}
return hval;
}
/* Constants to identify the commands and options. */
enum cmd_and_opt_values
@ -413,9 +447,10 @@ confucius_copy_file (char *infile, char *outfile, int plain)
pointer, it will be set to true or false, depending on if the user
canceled the operation or not. On error (including cancelation), a
null pointer is returned. The passphrase must be deallocated with
confucius_drop_pass. */
confucius_drop_pass. CACHEID is the ID to be used for passphrase
caching and can be NULL to disable caching. */
char *
confucius_get_pass (int again, int *canceled)
confucius_get_pass (const char *cacheid, int again, int *canceled)
{
int err;
char *pw;
@ -444,7 +479,7 @@ confucius_get_pass (int again, int *canceled)
}
#endif
pw = simple_pwquery (NULL,
pw = simple_pwquery (cacheid,
again ? _("does not match - try again"):NULL,
_("Passphrase:"), NULL, &err);
@ -497,6 +532,7 @@ confucius_process (int mode, char *infile, char *outfile,
pid_t pid;
pid_t wpid;
int tries = 0;
char cacheid[40];
signal (SIGPIPE, SIG_IGN);
@ -518,6 +554,10 @@ confucius_process (int mode, char *infile, char *outfile,
return 1;
}
/* Generate a hash from the keyfile name for caching. */
snprintf (cacheid, sizeof (cacheid), "confucius:%lu",
hash_string (opt.keyfile));
cacheid[sizeof (cacheid) - 1] = '\0';
args = malloc (sizeof (char *) * (10 + argc));
if (!args)
{
@ -708,13 +748,20 @@ confucius_process (int mode, char *infile, char *outfile,
char *pass;
int canceled;
pass = confucius_get_pass (tries ? 1 : 0, &canceled);
/* If this is not the first attempt, the
passphrase seems to be wrong, so clear the
cache. */
if (tries)
simple_pwclear (cacheid);
pass = confucius_get_pass (cacheid,
tries ? 1 : 0, &canceled);
if (!pass)
{
kill (pid, SIGTERM);
close (master);
close (cstderr[0]);
return canceled ? 3 : 1;
return canceled ? SYMC_CANCELED : 1;
}
write (master, pass, strlen (pass));
write (master, "\n", 1);
@ -736,6 +783,8 @@ confucius_process (int mode, char *infile, char *outfile,
log_error (_("waitpid failed: %s\n"), strerror (errno));
kill (pid, SIGTERM);
/* State of cached password is unclear. Just remove it. */
simple_pwclear (cacheid);
return 1;
}
else
@ -746,15 +795,22 @@ confucius_process (int mode, char *infile, char *outfile,
if (!WIFEXITED (res))
{
log_error (_("child aborted with status %i\n"), res);
/* State of cached password is unclear. Just remove it. */
simple_pwclear (cacheid);
return 1;
}
if (WEXITSTATUS (res))
{
/* The passphrase was wrong. Remove it from the cache. */
simple_pwclear (cacheid);
/* We probably exceeded our number of attempts at guessing
the password. */
if (tries >= 3)
return 2;
return SYMC_BAD_PASSPHRASE;
else
return 1;
}