v0.2.11
[gnupg.git] / g10 / pkclist.c
1 /* pkclist.c
2  *      Copyright (C) 1998 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 2 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, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27
28 #include "options.h"
29 #include "packet.h"
30 #include "errors.h"
31 #include "keydb.h"
32 #include "memory.h"
33 #include "util.h"
34 #include "trustdb.h"
35 #include "ttyio.h"
36 #include "i18n.h"
37
38 /****************
39  * Returns true if a ownertrust has changed.
40  */
41 static int
42 query_ownertrust( ulong lid )
43 {
44     char *p;
45     int rc;
46     size_t n;
47     u32 keyid[2];
48     PKT_public_cert *pkc ;
49     int changed=0;
50
51     rc = keyid_from_trustdb( lid, keyid );
52     if( rc ) {
53         log_error("ooops: can't get keyid for lid %lu\n", lid);
54         return 0;
55     }
56
57     pkc = m_alloc_clear( sizeof *pkc );
58     rc = get_pubkey( pkc, keyid );
59     if( rc ) {
60         log_error("keyid %08lX: pubkey not found: %s\n",
61                                 (ulong)keyid[1], g10_errstr(rc) );
62         return 0;
63     }
64
65     tty_printf(_("No ownertrust defined for %lu:\n"
66                "%4u%c/%08lX %s \""), lid,
67               nbits_from_pkc( pkc ), pubkey_letter( pkc->pubkey_algo ),
68               (ulong)keyid[1], datestr_from_pkc( pkc ) );
69     p = get_user_id( keyid, &n );
70     tty_print_string( p, n ),
71     m_free(p);
72     tty_printf(_("\"\n\n"
73 "Please decide in how far do you trust this user to\n"
74 "correctly sign other users keys (looking at his passport,\n"
75 "checking the fingerprints from different sources ...)?\n\n"
76 " 1 = Don't know\n"
77 " 2 = I do NOT trust\n"
78 " 3 = I trust marginally\n"
79 " 4 = I trust fully\n"
80 " s = please show me more informations\n\n") );
81
82     for(;;) {
83         p = tty_get(_("Your decision? "));
84         trim_spaces(p);
85         tty_kill_prompt();
86         if( *p && p[1] )
87             ;
88         else if( *p == '?' ) {
89             tty_printf(_(
90 "It's up to you to assign a value here; this value will never be exported\n"
91 "to any 3rd party.  We need it to implement the web-of-trust; it has nothing\n"
92 "to do with the (implicitly created) web-of-certificates.\n"));
93         }
94         else if( !p[1] && (*p >= '1' && *p <= '4') ) {
95             unsigned trust;
96             switch( *p ) {
97               case '1': trust = TRUST_UNDEFINED; break;
98               case '2': trust = TRUST_NEVER    ; break;
99               case '3': trust = TRUST_MARGINAL ; break;
100               case '4': trust = TRUST_FULLY    ; break;
101               default: BUG();
102             }
103             if( !update_ownertrust( lid, trust ) )
104                 changed++;
105             break;
106         }
107         else if( *p == 's' || *p == 'S' ) {
108             tty_printf(_("You will see a list of signators etc. here\n"));
109         }
110         m_free(p); p = NULL;
111     }
112     m_free(p);
113     m_free(pkc);
114     return changed;
115 }
116
117
118 /****************
119  * Try to add some more owner trusts (interactive)
120  * Returns: -1 if no ownertrust were added.
121  */
122 static int
123 add_ownertrust( PKT_public_cert *pkc )
124 {
125     int rc;
126     void *context = NULL;
127     ulong lid;
128     unsigned trust;
129     int any=0;
130
131     tty_printf(
132 _("Could not find a valid trust path to the key.  Lets see, wether we\n"
133   "can assign some missing owner trust values.\n\n"));
134
135     rc = query_trust_record( pkc );
136     if( rc ) {
137         log_error("Ooops: not in trustdb\n");
138         return -1;
139     }
140
141     lid = pkc->local_id;
142     while( !(rc=enum_trust_web( &context, &lid )) ) {
143         rc = get_ownertrust( lid, &trust );
144         if( rc )
145             log_fatal("Ooops: couldn't get ownertrust for %lu\n", lid);
146         if( trust == TRUST_UNDEFINED || trust == TRUST_EXPIRED ||
147             trust == TRUST_UNKNOWN ) {
148             if( query_ownertrust( lid ) )
149                 any=1;
150         }
151     }
152     if( rc == -1 )
153         rc = 0;
154     enum_trust_web( &context, NULL ); /* close */
155
156     if( !any )
157         tty_printf(_("No ownertrust values changed.\n\n") );
158
159     return rc? rc : any? 0:-1;
160 }
161
162 /****************
163  * Check wether we can trust this pkc which has a trustlevel of TRUSTLEVEL
164  * Returns: true if we trust.
165  */
166 static int
167 do_we_trust( PKT_public_cert *pkc, int trustlevel )
168 {
169     int rc;
170
171     if( (trustlevel & TRUST_FLAG_REVOKED) ) {
172         char *answer;
173         int yes;
174
175         log_info("key has beed revoked!\n");
176         if( opt.batch )
177             return 0;
178
179         answer = tty_get("Use this key anyway? ");
180         tty_kill_prompt();
181         yes = answer_is_yes(answer);
182         m_free(answer);
183         if( !yes )
184             return 0;
185     }
186
187
188     switch( (trustlevel & TRUST_MASK) ) {
189       case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
190         rc = insert_trust_record( pkc );
191         if( rc ) {
192             log_error("failed to insert it into the trustdb: %s\n",
193                                                       g10_errstr(rc) );
194             return 0; /* no */
195         }
196         rc = check_trust( pkc, &trustlevel );
197         if( rc )
198             log_fatal("trust check after insert failed: %s\n",
199                                                       g10_errstr(rc) );
200         if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED )
201             BUG();
202         return do_we_trust( pkc, trustlevel );
203
204       case TRUST_EXPIRED:
205         log_info("trust has expired: NOT yet implemented\n");
206         return 0; /* no */
207
208       case TRUST_UNDEFINED:
209         if( opt.batch || opt.answer_no )
210             log_info("no info to calculate a trust probability\n");
211         else {
212             rc = add_ownertrust( pkc );
213             if( !rc ) {
214                 rc = check_trust( pkc, &trustlevel );
215                 if( rc )
216                     log_fatal("trust check after add_ownertrust failed: %s\n",
217                                                               g10_errstr(rc) );
218                 /* FIXME: this is recursive; we better should unroll it */
219                 return do_we_trust( pkc, trustlevel );
220             }
221         }
222         return 0; /* no FIXME: add "Proceed anyway?" */
223
224       case TRUST_NEVER:
225         log_info("We do NOT trust this key\n");
226         return 0; /* no */
227
228       case TRUST_MARGINAL:
229         log_info("I'm not sure wether this keys really belongs to the owner\n"
230                  "but I proceed anyway\n");
231         return 1; /* yes */
232
233       case TRUST_FULLY:
234         if( opt.verbose )
235             log_info("This key probably belongs to the owner\n");
236         return 1; /* yes */
237
238       case TRUST_ULTIMATE:
239         if( opt.verbose )
240             log_info("This key belongs to us (we have the secret key)\n");
241         return 1; /* yes */
242
243       default: BUG();
244     }
245
246
247     /* Eventuell fragen falls der trustlevel nicht ausreichend ist */
248
249
250     return 1; /* yes */
251 }
252
253
254 /****************
255  * wrapper arounf do_we_trust, so we can ask wether to use the
256  * key anyway.
257  */
258 static int
259 do_we_trust_pre( PKT_public_cert *pkc, int trustlevel )
260 {
261     int rc = do_we_trust( pkc, trustlevel );
262
263     if( !opt.batch && !rc ) {
264         char *answer;
265
266         tty_printf(_(
267 "It is NOT certain, that the key belongs to his owner.\n"
268 "If you *really* know what you are doing, you may answer\n"
269 "the next question with yes\n\n") );
270
271         answer = tty_get("Use this key anyway? ");
272         tty_kill_prompt();
273         if( answer_is_yes(answer) )
274             rc = 1;
275         m_free(answer);
276     }
277     return rc;
278 }
279
280
281 void
282 release_pkc_list( PKC_LIST pkc_list )
283 {
284     PKC_LIST pkc_rover;
285
286     for( ; pkc_list; pkc_list = pkc_rover ) {
287         pkc_rover = pkc_list->next;
288         free_public_cert( pkc_list->pkc );
289         m_free( pkc_list );
290     }
291 }
292
293 int
294 build_pkc_list( STRLIST remusr, PKC_LIST *ret_pkc_list )
295 {
296     PKC_LIST pkc_list = NULL;
297     PKT_public_cert *pkc=NULL;
298     int rc=0;
299
300     if( !remusr && !opt.batch ) { /* ask */
301         char *answer=NULL;
302
303         tty_printf(_(
304                 "You did not specify a user ID. (you may use \"-r\")\n\n"));
305         for(;;) {
306             rc = 0;
307             m_free(answer);
308             answer = tty_get(_("Enter the user ID: "));
309             trim_spaces(answer);
310             tty_kill_prompt();
311             if( !*answer )
312                 break;
313             if( pkc )
314                 free_public_cert( pkc );
315             pkc = m_alloc_clear( sizeof *pkc );
316             rc = get_pubkey_byname( pkc, answer );
317             if( rc )
318                 tty_printf("No such user ID.\n");
319             else if( !(rc=check_pubkey_algo(pkc->pubkey_algo)) ) {
320                 int trustlevel;
321
322                 rc = check_trust( pkc, &trustlevel );
323                 if( rc ) {
324                     log_error("error checking pkc of '%s': %s\n",
325                                                       answer, g10_errstr(rc) );
326                 }
327                 else if( do_we_trust_pre( pkc, trustlevel ) ) {
328                     PKC_LIST r;
329
330                     r = m_alloc( sizeof *r );
331                     r->pkc = pkc; pkc = NULL;
332                     r->next = pkc_list;
333                     r->mark = 0;
334                     pkc_list = r;
335                     break;
336                 }
337             }
338         }
339         m_free(answer);
340         if( pkc ) {
341             free_public_cert( pkc );
342             pkc = NULL;
343         }
344     }
345     else {
346         for(; remusr; remusr = remusr->next ) {
347
348             pkc = m_alloc_clear( sizeof *pkc );
349             if( (rc = get_pubkey_byname( pkc, remusr->d )) ) {
350                 free_public_cert( pkc ); pkc = NULL;
351                 log_error("skipped '%s': %s\n", remusr->d, g10_errstr(rc) );
352             }
353             else if( !(rc=check_pubkey_algo(pkc->pubkey_algo)) ) {
354                 int trustlevel;
355
356                 rc = check_trust( pkc, &trustlevel );
357                 if( rc ) {
358                     free_public_cert( pkc ); pkc = NULL;
359                     log_error("error checking pkc of '%s': %s\n",
360                                                       remusr->d, g10_errstr(rc) );
361                 }
362                 else if( do_we_trust_pre( pkc, trustlevel ) ) {
363                     /* note: do_we_trust may have changed the trustlevel */
364                     PKC_LIST r;
365
366                     r = m_alloc( sizeof *r );
367                     r->pkc = pkc; pkc = NULL;
368                     r->next = pkc_list;
369                     r->mark = 0;
370                     pkc_list = r;
371                 }
372                 else { /* we don't trust this pkc */
373                     free_public_cert( pkc ); pkc = NULL;
374                 }
375             }
376             else {
377                 free_public_cert( pkc ); pkc = NULL;
378                 log_error("skipped '%s': %s\n", remusr->d, g10_errstr(rc) );
379             }
380         }
381     }
382
383
384     if( !rc && !pkc_list ) {
385         log_error("no valid addressees\n");
386         rc = G10ERR_NO_USER_ID;
387     }
388
389     if( rc )
390         release_pkc_list( pkc_list );
391     else
392         *ret_pkc_list = pkc_list;
393     return rc;
394 }
395
396