diff --git a/sm/ChangeLog b/sm/ChangeLog index 34a73a298..35839a70c 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,13 @@ +2002-07-22 Werner Koch + + * delete.c: New. + * gpgsm.c: Made --delete-key work. + * server.c (cmd_delkeys): New. + (register_commands): New command DELKEYS. + + * decrypt.c (gpgsm_decrypt): Print a convenience note when RC2 is + used and a STATUS_ERROR with the algorithm oid. + 2002-07-03 Werner Koch * server.c (gpgsm_status2): Insert a blank between all optional diff --git a/sm/Makefile.am b/sm/Makefile.am index 3061cb51b..489e59ebe 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -44,6 +44,7 @@ gpgsm_SOURCES = \ decrypt.c \ import.c \ export.c \ + delete.c \ certreqgen.c diff --git a/sm/decrypt.c b/sm/decrypt.c index ccbcae2a6..a793bbbef 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -320,6 +320,10 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp) if (!algo || !mode) { log_error ("unsupported algorithm `%s'\n", algoid? algoid:"?"); + if (algoid && !strcmp (algoid, "1.2.840.113549.3.2")) + log_info (_("(this is the RC2 algorithm)\n")); + gpgsm_status2 (ctrl, STATUS_ERROR, "decrypt.algorithm", + gnupg_error_token (rc), algoid, NULL); rc = GNUPG_Unsupported_Algorithm; goto leave; } diff --git a/sm/delete.c b/sm/delete.c new file mode 100644 index 000000000..cd1491a86 --- /dev/null +++ b/sm/delete.c @@ -0,0 +1,165 @@ +/* delete.c + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "gpgsm.h" +#include "keydb.h" +#include "i18n.h" + + +/* Delete a certificate or an secret key from a key database. */ +static int +delete_one (CTRL ctrl, const char *username) +{ + int rc = 0; + KEYDB_SEARCH_DESC desc; + KEYDB_HANDLE kh = NULL; + KsbaCert cert = NULL; + int duplicates = 0; + + rc = keydb_classify_name (username, &desc); + if (rc) + { + log_error (_("certificate `%s' not found: %s\n"), + username, gnupg_strerror (rc)); + gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "1", NULL); + goto leave; + } + + kh = keydb_new (0); + if (!kh) + { + log_error ("keydb_new failed\n"); + goto leave; + } + + + rc = keydb_search (kh, &desc, 1); + if (!rc) + rc = keydb_get_cert (kh, &cert); + if (!rc) + { + char fpr[20]; + + gpgsm_get_fingerprint (cert, 0, fpr, NULL); + + next_ambigious: + rc = keydb_search (kh, &desc, 1); + if (rc == -1) + rc = 0; + else if (!rc) + { + KsbaCert cert2 = NULL; + char fpr2[20]; + + /* We ignore all duplicated certificates which might have + been inserted due to program bugs. */ + if (!keydb_get_cert (kh, &cert2)) + { + gpgsm_get_fingerprint (cert2, 0, fpr2, NULL); + ksba_cert_release (cert2); + if (!memcmp (fpr, fpr2, 20)) + { + duplicates++; + goto next_ambigious; + } + } + rc = GNUPG_Ambiguous_Name; + } + } + if (rc) + { + if (rc == -1) + rc = GNUPG_No_Public_Key; + log_error (_("certificate `%s' not found: %s\n"), + username, gnupg_strerror (rc)); + gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "3", NULL); + goto leave; + } + + /* we need to search again to get back to the right position. */ + do + { + keydb_search_reset (kh); + rc = keydb_search (kh, &desc, 1); + if (rc) + { + log_error ("problem re-searching certificate: %s\n", + gnupg_strerror (rc)); + goto leave; + } + + rc = keydb_delete (kh); + if (rc) + goto leave; + if (opt.verbose) + { + if (duplicates) + log_info (_("duplicated certificate `%s' deleted\n"), username); + else + log_info (_("certificate `%s' deleted\n"), username); + } + } + while (duplicates--); + + leave: + keydb_release (kh); + ksba_cert_release (cert); + return rc; +} + + + +/* Delete the certificates specified by NAMES. */ +int +gpgsm_delete (CTRL ctrl, STRLIST names) +{ + int rc; + + if (!names) + { + log_error ("nothing to delete\n"); + return GNUPG_No_Data; + } + + for (; names; names=names->next ) + { + rc = delete_one (ctrl, names->d); + if (rc) + { + log_error (_("deleting certificate \"%s\" failed: %s\n"), + names->d, gnupg_strerror (rc) ); + return rc; + } + } + + return 0; +} diff --git a/sm/fingerprint.c b/sm/fingerprint.c index 88fe72b1e..d8b6ec4a3 100644 --- a/sm/fingerprint.c +++ b/sm/fingerprint.c @@ -36,7 +36,7 @@ libksba because we need libgcrypt support). The caller must provide an array of sufficient length or NULL so that the function allocates the array. If r_len is not NULL, the length of the - digest is return, well, this can also be done by using + digest is returned; well, this can also be done by using gcry_md_get_algo_dlen(). If algo is 0, a SHA-1 will be used. If there is a problem , the function does never return NULL but a diff --git a/sm/gpgsm.c b/sm/gpgsm.c index f2287ef20..9efeca79f 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -742,7 +742,7 @@ main ( int argc, char **argv) case aDeleteKey: set_cmd (&cmd, aDeleteKey); - greeting=1; + /*greeting=1;*/ break; case aDetachedSign: @@ -1213,13 +1213,10 @@ main ( int argc, char **argv) break; case aDeleteKey: - if (argc != 1) - wrong_args(_("--delete-key user-id")); - log_error ("this command has not yet been implemented\n"); -/* username = make_username (fname); */ -/* if( (rc = delete_key(username)) ) */ -/* log_error ("%s: delete key failed: %s\n", username, gpg_errstr(rc) ); */ -/* xfree(username); */ + for (sl=NULL; argc; argc--, argv++) + add_to_strlist (&sl, *argv); + gpgsm_delete (&ctrl, sl); + free_strlist(sl); break; case aListSigs: diff --git a/sm/gpgsm.h b/sm/gpgsm.h index efa98dee5..0d5294b44 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -210,6 +210,9 @@ int gpgsm_import (CTRL ctrl, int in_fd); /*-- export.c --*/ void gpgsm_export (CTRL ctrl, STRLIST names, FILE *fp); +/*-- delete.c --*/ +int gpgsm_delete (CTRL ctrl, STRLIST names); + /*-- verify.c --*/ int gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp); diff --git a/sm/server.c b/sm/server.c index 5f490b5a9..0e30ae873 100644 --- a/sm/server.c +++ b/sm/server.c @@ -499,6 +499,49 @@ cmd_export (ASSUAN_CONTEXT ctx, char *line) } +static int +cmd_delkeys (ASSUAN_CONTEXT ctx, char *line) +{ + CTRL ctrl = assuan_get_pointer (ctx); + char *p; + STRLIST list, sl; + int rc; + + /* break the line down into an STRLIST */ + list = NULL; + for (p=line; *p; line = p) + { + while (*p && *p != ' ') + p++; + if (*p) + *p++ = 0; + if (*line) + { + sl = xtrymalloc (sizeof *sl + strlen (line)); + if (!sl) + { + free_strlist (list); + return ASSUAN_Out_Of_Core; + } + sl->flags = 0; + strcpy_escaped_plus (sl->d, line); + sl->next = list; + list = sl; + } + } + + rc = gpgsm_delete (ctrl, list); + free_strlist (list); + + /* close and reset the fd */ + close_message_fd (ctrl); + assuan_close_input_fd (ctx); + assuan_close_output_fd (ctx); + + return map_to_assuan_status (rc); +} + + /* MESSAGE FD= @@ -645,6 +688,7 @@ register_commands (ASSUAN_CONTEXT ctx) { "LISTKEYS", 0, cmd_listkeys }, { "LISTSECRETKEYS", 0, cmd_listsecretkeys }, { "GENKEY", 0, cmd_genkey }, + { "DELKEYS", 0, cmd_delkeys }, { NULL } }; int i, j, rc;