1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-02 12:01:32 +01:00

* keydb.c (keydb_add_resource): Create keybox

* keylist.c (gpgsm_list_keys): Fixed non-server keylisting.
* server.c (rc_to_assuan_status): New.  Use it for all commands.
This commit is contained in:
Werner Koch 2001-11-26 13:08:36 +00:00
parent ce8a236195
commit 99829ef5fb
7 changed files with 251 additions and 153 deletions

View File

@ -0,0 +1,20 @@
2001-11-26 Werner Koch <wk@gnupg.org>
* keydb.c (keydb_add_resource): Create keybox
* keylist.c (gpgsm_list_keys): Fixed non-server keylisting.
* server.c (rc_to_assuan_status): New. Use it for all commands.
Copyright 2001 Free Software Foundation, Inc.
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without
modifications, as long as this notice is preserved.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

View File

@ -470,16 +470,16 @@ request_reply (const char *line, struct membuf *membuf)
for (;len && *p != '%'; len--, p++) for (;len && *p != '%'; len--, p++)
; ;
put_membuf (membuf, buf, p-buf); put_membuf (membuf, buf, p-buf);
buf = p;
if (len>2) if (len>2)
{ /* handle escaping */ { /* handle escaping */
unsigned char tmp[1]; unsigned char tmp[1];
buf++; p++;
*tmp = xtoi_2 (buf); *tmp = xtoi_2 (p);
buf += 2; p += 2;
len -= 3; len -= 3;
put_membuf (membuf, tmp, 1); put_membuf (membuf, tmp, 1);
} }
buf = p;
} }
goto again; goto again;
} }

View File

@ -78,134 +78,130 @@ static void unlock_all (KEYDB_HANDLE hd);
int int
keydb_add_resource (const char *url, int force, int secret) keydb_add_resource (const char *url, int force, int secret)
{ {
static int any_secret, any_public; static int any_secret, any_public;
const char *resname = url; const char *resname = url;
char *filename = NULL; char *filename = NULL;
int rc = 0; int rc = 0;
KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; FILE *fp;
/* const char *created_fname = NULL; */ KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
const char *created_fname = NULL;
/* Do we have an URL? /* Do we have an URL?
* gnupg-ring:filename := this is a plain keybox gnupg-kbx:filename := this is a plain keybox
* filename := See what is is, but create as plain keybox. filename := See what is is, but create as plain keybox.
*/ */
if (strlen (resname) > 11) { if (strlen (resname) > 10)
if (!strncmp( resname, "gnupg-kbx:", 10) ) { {
rt = KEYDB_RESOURCE_TYPE_KEYBOX; if (!strncmp (resname, "gnupg-kbx:", 10) )
resname += 11; {
}
#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
else if (strchr (resname, ':')) {
log_error ("invalid key resource URL `%s'\n", url );
rc = GNUPG_General_Error;
goto leave;
}
#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
}
if (*resname != DIRSEP_C ) { /* do tilde expansion etc */
if (strchr(resname, DIRSEP_C) )
filename = make_filename (resname, NULL);
else
filename = make_filename (opt.homedir, resname, NULL);
}
else
filename = xstrdup (resname);
if (!force)
force = secret? !any_secret : !any_public;
/* see whether we can determine the filetype */
if (rt == KEYDB_RESOURCE_TYPE_NONE) {
FILE *fp2 = fopen( filename, "rb" );
if (fp2) {
u32 magic;
/* FIXME: check for the keybox magic */
if (fread( &magic, 4, 1, fp2) == 1 )
{
if (magic == 0x13579ace || magic == 0xce9a5713)
; /* GDBM magic - no more support */
else
rt = KEYDB_RESOURCE_TYPE_KEYBOX;
}
else /* maybe empty: assume ring */
rt = KEYDB_RESOURCE_TYPE_KEYBOX;
fclose (fp2);
}
else /* no file yet: create ring */
rt = KEYDB_RESOURCE_TYPE_KEYBOX; rt = KEYDB_RESOURCE_TYPE_KEYBOX;
resname += 10;
}
#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
else if (strchr (resname, ':'))
{
log_error ("invalid key resource URL `%s'\n", url );
rc = GNUPG_General_Error;
goto leave;
}
#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
} }
switch (rt) { if (*resname != DIRSEP_C )
case KEYDB_RESOURCE_TYPE_NONE: { /* do tilde expansion etc */
log_error ("unknown type of key resource `%s'\n", url ); if (strchr(resname, DIRSEP_C) )
rc = GNUPG_General_Error; filename = make_filename (resname, NULL);
goto leave; else
filename = make_filename (opt.homedir, resname, NULL);
case KEYDB_RESOURCE_TYPE_KEYBOX: }
#if 0 else
fp = fopen (filename); filename = xstrdup (resname);
if (!iobuf && !force) {
rc = G10ERR_OPEN_FILE; if (!force)
goto leave; force = secret? !any_secret : !any_public;
}
/* see whether we can determine the filetype */
if (!fp) { if (rt == KEYDB_RESOURCE_TYPE_NONE)
char *last_slash_in_filename; {
FILE *fp2 = fopen( filename, "rb" );
last_slash_in_filename = strrchr (filename, DIRSEP_C);
*last_slash_in_filename = 0; if (fp2) {
u32 magic;
if (access(filename, F_OK)) {
/* on the first time we try to create the default /* FIXME: check for the keybox magic */
if (fread( &magic, 4, 1, fp2) == 1 )
{
if (magic == 0x13579ace || magic == 0xce9a5713)
; /* GDBM magic - no more support */
else
rt = KEYDB_RESOURCE_TYPE_KEYBOX;
}
else /* maybe empty: assume ring */
rt = KEYDB_RESOURCE_TYPE_KEYBOX;
fclose (fp2);
}
else /* no file yet: create ring */
rt = KEYDB_RESOURCE_TYPE_KEYBOX;
}
switch (rt)
{
case KEYDB_RESOURCE_TYPE_NONE:
log_error ("unknown type of key resource `%s'\n", url );
rc = GNUPG_General_Error;
goto leave;
case KEYDB_RESOURCE_TYPE_KEYBOX:
fp = fopen (filename, "rb");
if (!fp && !force)
{
rc = GNUPG_File_Open_Error;
goto leave;
}
if (!fp)
{ /* no file */
#if 0 /* no autocreate of the homedirectory yet */
{
char *last_slash_in_filename;
last_slash_in_filename = strrchr (filename, DIRSEP_C);
*last_slash_in_filename = 0;
if (access (filename, F_OK))
{ /* on the first time we try to create the default
homedir and in this case the process will be homedir and in this case the process will be
terminated, so that on the next invocation it can terminated, so that on the next invocation can
read the options file in on startup */ read the options file in on startup */
try_make_homedir (filename); try_make_homedir (filename);
rc = G10ERR_OPEN_FILE; rc = GNUPG_File_Open_Error;
*last_slash_in_filename = DIRSEP_C; *last_slash_in_filename = DIRSEP_C;
goto leave; goto leave;
}
*last_slash_in_filename = DIRSEP_C;
}
#endif
fp = fopen (filename, "w");
if (!fp)
{
log_error (_("error creating keybox `%s': %s\n"),
filename, strerror(errno));
rc = GNUPG_File_Create_Error;
goto leave;
} }
*last_slash_in_filename = DIRSEP_C; if (!opt.quiet)
log_info (_("keybox `%s' created\n"), filename);
iobuf = iobuf_create (filename); created_fname = filename;
if (!iobuf) {
log_error ( _("error creating keybox `%s': %s\n"),
filename, strerror(errno));
rc = G10ERR_OPEN_FILE;
goto leave;
}
else {
#ifndef HAVE_DOSISH_SYSTEM
if (secret && !opt.preserve_permissionws) {
if (chmod (filename, S_IRUSR | S_IWUSR) ) {
log_error (_("changing permission of "
" `%s' failed: %s\n"),
filename, strerror(errno) );
rc = G10ERR_WRITE_FILE;
goto leave;
}
}
#endif
if (!opt.quiet)
log_info (_("keybox `%s' created\n"), filename);
created_fname = filename;
}
} }
iobuf_close (iobuf); fclose (fp);
iobuf = NULL; fp = NULL;
if (created_fname) /* must invalidate that ugly cache */ /* now regsiter the file */
iobuf_ioctl (NULL, 2, 0, (char*)created_fname);
#endif
{ {
void *token = keybox_register_file (filename, secret); void *token = keybox_register_file (filename, secret);
if (!token) if (!token)
; /* already registered - ignore it */ ; /* already registered - ignore it */
else if (used_resources >= MAX_KEYDB_RESOURCES) else if (used_resources >= MAX_KEYDB_RESOURCES)
rc = GNUPG_Resource_Limit; rc = GNUPG_Resource_Limit;
else else
{ {
all_resources[used_resources].type = rt; all_resources[used_resources].type = rt;
@ -216,29 +212,26 @@ keydb_add_resource (const char *url, int force, int secret)
} }
} }
break; break;
default:
default: log_error ("resource type of `%s' not supported\n", url);
log_error ("resource type of `%s' not supported\n", url); rc = GNUPG_Not_Supported;
rc = GNUPG_General_Error; goto leave;
goto leave;
} }
/* fixme: check directory permissions and print a warning */ /* fixme: check directory permissions and print a warning */
leave: leave:
if (rc) if (rc)
log_error ("keyblock resource `%s': %s\n", filename, gnupg_strerror(rc)); log_error ("keyblock resource `%s': %s\n", filename, gnupg_strerror(rc));
else if (secret) else if (secret)
any_secret = 1; any_secret = 1;
else else
any_public = 1; any_public = 1;
xfree (filename); xfree (filename);
return rc; return rc;
} }
KEYDB_HANDLE KEYDB_HANDLE
keydb_new (int secret) keydb_new (int secret)
{ {

View File

@ -168,13 +168,13 @@ gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp)
putc ('\n', fp); putc ('\n', fp);
lastresname = resname; lastresname = resname;
} }
if (ctrl->with_colons) }
list_cert_colon (cert, fp); if (ctrl->with_colons)
else list_cert_colon (cert, fp);
list_cert_colon (cert, fp); else
ksba_cert_release (cert); list_cert_colon (cert, fp);
cert = NULL; ksba_cert_release (cert);
} cert = NULL;
} }
while (!(rc = keydb_search_next (hd))); while (!(rc = keydb_search_next (hd)));
if (rc && rc != -1) if (rc && rc != -1)

View File

@ -42,6 +42,45 @@ struct server_local_s {
int message_fd; int message_fd;
}; };
/* Map GNUPG_xxx error codes to Assuan status codes */
static int
rc_to_assuan_status (int rc)
{
switch (rc)
{
case 0: break;
case GNUPG_Bad_Certificate: rc = ASSUAN_Bad_Certificate; break;
case GNUPG_Bad_Certificate_Path: rc = ASSUAN_Bad_Certificate_Path; break;
case GNUPG_Missing_Certificate: rc = ASSUAN_Missing_Certificate; break;
case GNUPG_No_Data: rc = ASSUAN_No_Data_Available; break;
case GNUPG_Bad_Signature: rc = ASSUAN_Bad_Signature; break;
case GNUPG_Not_Implemented: rc = ASSUAN_Not_Implemented; break;
case GNUPG_No_Agent: rc = ASSUAN_No_Agent; break;
case GNUPG_Agent_Error: rc = ASSUAN_Agent_Error; break;
case GNUPG_No_Public_Key: rc = ASSUAN_No_Public_Key; break;
case GNUPG_No_Secret_Key: rc = ASSUAN_No_Secret_Key; break;
case GNUPG_Read_Error:
case GNUPG_Write_Error:
case GNUPG_IO_Error:
rc = ASSUAN_Server_IO_Error;
break;
case GNUPG_Out_Of_Core:
case GNUPG_Resource_Limit:
rc = ASSUAN_Server_Resource_Problem;
break;
case GNUPG_Bug:
case GNUPG_Internal_Error:
rc = ASSUAN_Server_Bug;
break;
default:
rc = ASSUAN_Server_Fault;
break;
}
return rc;
}
/* RECIPIENT <userID> /* RECIPIENT <userID>
@ -116,15 +155,17 @@ cmd_decrypt (ASSUAN_CONTEXT ctx, char *line)
static int static int
cmd_verify (ASSUAN_CONTEXT ctx, char *line) cmd_verify (ASSUAN_CONTEXT ctx, char *line)
{ {
int rc;
CTRL ctrl = assuan_get_pointer (ctx); CTRL ctrl = assuan_get_pointer (ctx);
int fd = assuan_get_input_fd (ctx); int fd = assuan_get_input_fd (ctx);
if (fd == -1) if (fd == -1)
return set_error (No_Input, NULL); return set_error (No_Input, NULL);
gpgsm_verify (assuan_get_pointer (ctx), fd, ctrl->server_local->message_fd); rc = gpgsm_verify (assuan_get_pointer (ctx), fd,
ctrl->server_local->message_fd);
return 0; return rc_to_assuan_status (rc);
} }
@ -139,6 +180,7 @@ cmd_sign (ASSUAN_CONTEXT ctx, char *line)
int inp_fd, out_fd; int inp_fd, out_fd;
FILE *out_fp; FILE *out_fp;
int detached; int detached;
int rc;
inp_fd = assuan_get_input_fd (ctx); inp_fd = assuan_get_input_fd (ctx);
if (inp_fd == -1) if (inp_fd == -1)
@ -152,10 +194,10 @@ cmd_sign (ASSUAN_CONTEXT ctx, char *line)
out_fp = fdopen ( dup(out_fd), "w"); out_fp = fdopen ( dup(out_fd), "w");
if (!out_fp) if (!out_fp)
return set_error (General_Error, "fdopen() failed"); return set_error (General_Error, "fdopen() failed");
gpgsm_sign (assuan_get_pointer (ctx), inp_fd, detached, out_fp); rc = gpgsm_sign (assuan_get_pointer (ctx), inp_fd, detached, out_fp);
fclose (out_fp); fclose (out_fp);
return 0; return rc_to_assuan_status (rc);
} }
@ -168,14 +210,15 @@ cmd_sign (ASSUAN_CONTEXT ctx, char *line)
static int static int
cmd_import (ASSUAN_CONTEXT ctx, char *line) cmd_import (ASSUAN_CONTEXT ctx, char *line)
{ {
int rc;
int fd = assuan_get_input_fd (ctx); int fd = assuan_get_input_fd (ctx);
if (fd == -1) if (fd == -1)
return set_error (No_Input, NULL); return set_error (No_Input, NULL);
gpgsm_import (assuan_get_pointer (ctx), fd); rc = gpgsm_import (assuan_get_pointer (ctx), fd);
return 0; return rc_to_assuan_status (rc);
} }
/* MESSAGE FD=<n> /* MESSAGE FD=<n>
@ -211,7 +254,8 @@ cmd_listkeys (ASSUAN_CONTEXT ctx, char *line)
ctrl->with_colons = 1; ctrl->with_colons = 1;
/* fixme: check that the returned data_fp is not NULL */ /* fixme: check that the returned data_fp is not NULL */
gpgsm_list_keys (assuan_get_pointer (ctx), NULL, assuan_get_data_fp (ctx)); gpgsm_list_keys (assuan_get_pointer (ctx), NULL,
assuan_get_data_fp (ctx));
return 0; return 0;
} }

View File

@ -244,16 +244,16 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
gcry_md_enable (data_md, algo); gcry_md_enable (data_md, algo);
} }
signer = 0;
if (detached) if (detached)
{ /* we hash the data right now so tha we can store the message { /* we hash the data right now so that we can store the message
digest. ksba_cms_build() takes this as an flag that deatched digest. ksba_cms_build() takes this as an flag that detached
data is expected. */ data is expected. */
unsigned char *digest; unsigned char *digest;
size_t digest_len; size_t digest_len;
/* Fixme do this for all signers and get the algo to use from /* Fixme do this for all signers and get the algo to use from
the signer's certificate - does not make mich sense, bu we the signer's certificate - does not make mich sense, bu we
should do this consistent as we have already done it above */ should do this consistent as we have already done it above */
signer = 0;
algo = GCRY_MD_SHA1; algo = GCRY_MD_SHA1;
hash_data (data_fd, data_md); hash_data (data_fd, data_md);
digest = gcry_md_read (data_md, algo); digest = gcry_md_read (data_md, algo);
@ -274,7 +274,14 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
} }
} }
err = ksba_cms_set_signing_time (cms, signer, 0 /*now*/);
if (err)
{
log_error ("ksba_cms_set_signing_time failed: %s\n",
ksba_strerror (err));
rc = map_ksba_err (err);
goto leave;
}
do do
{ {

View File

@ -136,6 +136,28 @@ print_integer (unsigned char *p)
} }
} }
static void
print_time (time_t t)
{
if (!t)
log_printf ("none");
else if ( t == (time_t)(-1) )
log_printf ("error");
else
{
struct tm *tp;
tp = gmtime (&t);
log_printf ("%04d-%02d-%02d %02d:%02d:%02d",
1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
tp->tm_hour, tp->tm_min, tp->tm_sec);
assert (!tp->tm_isdst);
}
}
static void static void
hash_data (int fd, GCRY_MD_HD md) hash_data (int fd, GCRY_MD_HD md)
@ -316,6 +338,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
{ {
char *issuer = NULL; char *issuer = NULL;
char *sigval = NULL; char *sigval = NULL;
time_t sigtime;
unsigned char *serial; unsigned char *serial;
char *msgdigest = NULL; char *msgdigest = NULL;
size_t msgdigestlen; size_t msgdigestlen;
@ -328,6 +351,17 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
print_integer (serial); print_integer (serial);
log_printf ("\n"); log_printf ("\n");
err = ksba_cms_get_signing_time (cms, signer, &sigtime);
if (err)
{
log_debug ("error getting signing time: %s\n", ksba_strerror (err));
sigtime = (time_t)-1;
}
log_debug ("signer %d - sigtime: ", signer);
print_time (sigtime);
log_printf ("\n");
err = ksba_cms_get_message_digest (cms, signer, err = ksba_cms_get_message_digest (cms, signer,
&msgdigest, &msgdigestlen); &msgdigest, &msgdigestlen);
if (err) if (err)