Line data Source code
1 : /* delete.c - Delete certificates from the keybox.
2 : * Copyright (C) 2002, 2009 Free Software Foundation, Inc.
3 : *
4 : * This file is part of GnuPG.
5 : *
6 : * GnuPG is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU General Public License as published by
8 : * the Free Software Foundation; either version 3 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * GnuPG is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License
17 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include <config.h>
21 : #include <stdio.h>
22 : #include <stdlib.h>
23 : #include <string.h>
24 : #include <errno.h>
25 : #include <unistd.h>
26 : #include <time.h>
27 : #include <assert.h>
28 :
29 : #include "gpgsm.h"
30 : #include <gcrypt.h>
31 : #include <ksba.h>
32 :
33 : #include "keydb.h"
34 : #include "i18n.h"
35 :
36 :
37 : /* Delete a certificate or an secret key from a key database. */
38 : static int
39 0 : delete_one (ctrl_t ctrl, const char *username)
40 : {
41 0 : int rc = 0;
42 : KEYDB_SEARCH_DESC desc;
43 0 : KEYDB_HANDLE kh = NULL;
44 0 : ksba_cert_t cert = NULL;
45 0 : int duplicates = 0;
46 0 : int is_ephem = 0;
47 :
48 0 : rc = classify_user_id (username, &desc, 0);
49 0 : if (rc)
50 : {
51 0 : log_error (_("certificate '%s' not found: %s\n"),
52 : username, gpg_strerror (rc));
53 0 : gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "1", NULL);
54 0 : goto leave;
55 : }
56 :
57 0 : kh = keydb_new (0);
58 0 : if (!kh)
59 : {
60 0 : log_error ("keydb_new failed\n");
61 0 : goto leave;
62 : }
63 :
64 : /* If the key is specified in a unique way, include ephemeral keys
65 : in the search. */
66 0 : if ( desc.mode == KEYDB_SEARCH_MODE_FPR
67 0 : || desc.mode == KEYDB_SEARCH_MODE_FPR20
68 0 : || desc.mode == KEYDB_SEARCH_MODE_FPR16
69 0 : || desc.mode == KEYDB_SEARCH_MODE_KEYGRIP )
70 : {
71 0 : is_ephem = 1;
72 0 : keydb_set_ephemeral (kh, 1);
73 : }
74 :
75 0 : rc = keydb_search (kh, &desc, 1);
76 0 : if (!rc)
77 0 : rc = keydb_get_cert (kh, &cert);
78 0 : if (!rc && !is_ephem)
79 : {
80 : unsigned char fpr[20];
81 :
82 0 : gpgsm_get_fingerprint (cert, 0, fpr, NULL);
83 :
84 : next_ambigious:
85 0 : rc = keydb_search (kh, &desc, 1);
86 0 : if (rc == -1)
87 0 : rc = 0;
88 0 : else if (!rc)
89 : {
90 0 : ksba_cert_t cert2 = NULL;
91 : unsigned char fpr2[20];
92 :
93 : /* We ignore all duplicated certificates which might have
94 : been inserted due to program bugs. */
95 0 : if (!keydb_get_cert (kh, &cert2))
96 : {
97 0 : gpgsm_get_fingerprint (cert2, 0, fpr2, NULL);
98 0 : ksba_cert_release (cert2);
99 0 : if (!memcmp (fpr, fpr2, 20))
100 : {
101 0 : duplicates++;
102 0 : goto next_ambigious;
103 : }
104 : }
105 0 : rc = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
106 : }
107 : }
108 0 : if (rc)
109 : {
110 0 : if (rc == -1)
111 0 : rc = gpg_error (GPG_ERR_NO_PUBKEY);
112 0 : log_error (_("certificate '%s' not found: %s\n"),
113 : username, gpg_strerror (rc));
114 0 : gpgsm_status2 (ctrl, STATUS_DELETE_PROBLEM, "3", NULL);
115 0 : goto leave;
116 : }
117 :
118 : /* We need to search again to get back to the right position. */
119 0 : rc = keydb_lock (kh);
120 0 : if (rc)
121 : {
122 0 : log_error (_("error locking keybox: %s\n"), gpg_strerror (rc));
123 0 : goto leave;
124 : }
125 :
126 : do
127 : {
128 0 : keydb_search_reset (kh);
129 0 : rc = keydb_search (kh, &desc, 1);
130 0 : if (rc)
131 : {
132 0 : log_error ("problem re-searching certificate: %s\n",
133 : gpg_strerror (rc));
134 0 : goto leave;
135 : }
136 :
137 0 : rc = keydb_delete (kh, duplicates ? 0 : 1);
138 0 : if (rc)
139 0 : goto leave;
140 0 : if (opt.verbose)
141 : {
142 0 : if (duplicates)
143 0 : log_info (_("duplicated certificate '%s' deleted\n"), username);
144 : else
145 0 : log_info (_("certificate '%s' deleted\n"), username);
146 : }
147 : }
148 0 : while (duplicates--);
149 :
150 : leave:
151 0 : keydb_release (kh);
152 0 : ksba_cert_release (cert);
153 0 : return rc;
154 : }
155 :
156 :
157 :
158 : /* Delete the certificates specified by NAMES. */
159 : int
160 0 : gpgsm_delete (ctrl_t ctrl, strlist_t names)
161 : {
162 : int rc;
163 :
164 0 : if (!names)
165 : {
166 0 : log_error ("nothing to delete\n");
167 0 : return gpg_error (GPG_ERR_NO_DATA);
168 : }
169 :
170 0 : for (; names; names=names->next )
171 : {
172 0 : rc = delete_one (ctrl, names->d);
173 0 : if (rc)
174 : {
175 0 : log_error (_("deleting certificate \"%s\" failed: %s\n"),
176 0 : names->d, gpg_strerror (rc) );
177 0 : return rc;
178 : }
179 : }
180 :
181 0 : return 0;
182 : }
|