changed trustdb design
[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 "status.h"
37 #include "i18n.h"
38
39 /****************
40  * Returns true if an ownertrust has changed.
41  */
42 static int
43 query_ownertrust( ulong lid )
44 {
45     char *p;
46     int rc;
47     size_t n;
48     u32 keyid[2];
49     PKT_public_key *pk ;
50     int changed=0;
51
52     rc = keyid_from_lid( lid, keyid );
53     if( rc ) {
54         log_error("ooops: can't get keyid for lid %lu\n", lid);
55         return 0;
56     }
57
58     pk = m_alloc_clear( sizeof *pk );
59     rc = get_pubkey( pk, keyid );
60     if( rc ) {
61         log_error("key %08lX: public key not found: %s\n",
62                                 (ulong)keyid[1], g10_errstr(rc) );
63         return 0;
64     }
65
66     tty_printf(_("No owner trust defined for %lu:\n"
67                "%4u%c/%08lX %s \""), lid,
68               nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
69               (ulong)keyid[1], datestr_from_pk( pk ) );
70     p = get_user_id( keyid, &n );
71     tty_print_string( p, n ),
72     m_free(p);
73     tty_printf(_("\"\n\n"
74 "Please decide how far you trust this user to correctly\n"
75 "verify other users' keys (by looking at passports,\n"
76 "checking fingerprints from different sources...)?\n\n"
77 " 1 = Don't know\n"
78 " 2 = I do NOT trust\n"
79 " 3 = I trust marginally\n"
80 " 4 = I trust fully\n"
81 " s = please show me more information\n\n") );
82
83     for(;;) {
84         p = tty_get(_("Your decision? "));
85         trim_spaces(p);
86         tty_kill_prompt();
87         if( *p && p[1] )
88             ;
89         else if( *p == '?' ) {
90             tty_printf(_(
91 "It's up to you to assign a value here; this value will never be exported\n"
92 "to any 3rd party.  We need it to implement the web-of-trust; it has nothing\n"
93 "to do with the (implicitly created) web-of-certificates.\n"));
94         }
95         else if( !p[1] && (*p >= '1' && *p <= '4') ) {
96             unsigned trust;
97             switch( *p ) {
98               case '1': trust = TRUST_UNDEFINED; break;
99               case '2': trust = TRUST_NEVER    ; break;
100               case '3': trust = TRUST_MARGINAL ; break;
101               case '4': trust = TRUST_FULLY    ; break;
102               default: BUG();
103             }
104             if( !update_ownertrust( lid, trust ) )
105                 changed++;
106             break;
107         }
108         else if( *p == 's' || *p == 'S' ) {
109             tty_printf(_("You will see a list of signators etc. here\n"));
110         }
111         m_free(p); p = NULL;
112     }
113     m_free(p);
114     m_free(pk);
115     return changed;
116 }
117
118
119 /****************
120  * Try to add some more owner trusts (interactive)
121  * Returns: -1 if no ownertrust were added.
122  */
123 static int
124 add_ownertrust( PKT_public_key *pk )
125 {
126     int rc;
127     void *context = NULL;
128     ulong lid;
129     unsigned trust;
130     int any=0;
131
132     tty_printf(
133 _("Could not find a valid trust path to the key.  Let's see whether we\n"
134   "can assign some missing owner trust values.\n\n"));
135
136     rc = query_trust_record( pk );
137     if( rc ) {
138         log_error("Ooops: not in trustdb\n");
139         return -1;
140     }
141
142     lid = pk->local_id;
143     while( !(rc=enum_trust_web( &context, &lid )) ) {
144         rc = get_ownertrust( lid, &trust );
145         if( rc )
146             log_fatal("Ooops: couldn't get owner trust for %lu\n", lid);
147         if( trust == TRUST_UNDEFINED || trust == TRUST_EXPIRED ||
148             trust == TRUST_UNKNOWN ) {
149             if( query_ownertrust( lid ) )
150                 any=1;
151         }
152     }
153     if( rc == -1 )
154         rc = 0;
155     enum_trust_web( &context, NULL ); /* close */
156
157     if( !any )
158         tty_printf(_("No owner trust values changed.\n\n") );
159
160     return rc? rc : any? 0:-1;
161 }
162
163 /****************
164  * Check whether we can trust this pk which has a trustlevel of TRUSTLEVEL
165  * Returns: true if we trust.
166  */
167 static int
168 do_we_trust( PKT_public_key *pk, int trustlevel )
169 {
170     int rc;
171
172     if( (trustlevel & TRUST_FLAG_REVOKED) ) {
173         char *answer;
174         int yes;
175
176         log_info("key has been revoked!\n");
177         if( opt.batch )
178             return 0;
179
180         answer = tty_get("Use this key anyway? ");
181         tty_kill_prompt();
182         yes = answer_is_yes(answer);
183         m_free(answer);
184         if( !yes )
185             return 0;
186     }
187
188
189     switch( (trustlevel & TRUST_MASK) ) {
190       case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
191         rc = insert_trust_record( pk );
192         if( rc ) {
193             log_error("failed to insert it into the trustdb: %s\n",
194                                                       g10_errstr(rc) );
195             return 0; /* no */
196         }
197         rc = check_trust( pk, &trustlevel );
198         if( rc )
199             log_fatal("trust check after insert failed: %s\n",
200                                                       g10_errstr(rc) );
201         if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED )
202             BUG();
203         return do_we_trust( pk, trustlevel );
204
205       case TRUST_EXPIRED:
206         log_info("key has expired\n");
207         return 0; /* no */
208
209       case TRUST_UNDEFINED:
210         if( opt.batch || opt.answer_no )
211             log_info("no info to calculate a trust probability\n");
212         else {
213             rc = add_ownertrust( pk );
214             if( !rc ) {
215                 rc = check_trust( pk, &trustlevel );
216                 if( rc )
217                     log_fatal("trust check after add_ownertrust failed: %s\n",
218                                                               g10_errstr(rc) );
219                 /* fixme: this is recursive; we should unroll it */
220                 return do_we_trust( pk, trustlevel );
221             }
222         }
223         return 0;
224
225       case TRUST_NEVER:
226         log_info("We do NOT trust this key\n");
227         return 0; /* no */
228
229       case TRUST_MARGINAL:
230         log_info("I'm not sure whether this key really belongs to the owner\n"
231                  "but I proceed anyway\n");
232         return 1; /* yes */
233
234       case TRUST_FULLY:
235         if( opt.verbose )
236             log_info("This key probably belongs to the owner\n");
237         return 1; /* yes */
238
239       case TRUST_ULTIMATE:
240         if( opt.verbose )
241             log_info("This key belongs to us (we have the secret key)\n");
242         return 1; /* yes */
243
244       default: BUG();
245     }
246
247
248     /* Eventuell fragen falls der trustlevel nicht ausreichend ist */
249
250
251     return 1; /* yes */
252 }
253
254
255 /****************
256  * wrapper around do_we_trust, so we can ask whether to use the
257  * key anyway.
258  */
259 static int
260 do_we_trust_pre( PKT_public_key *pk, int trustlevel )
261 {
262     int rc = do_we_trust( pk, trustlevel );
263
264     if( !opt.batch && !rc ) {
265         char *answer;
266
267         tty_printf(_(
268 "It is NOT certain that the key belongs to its owner.\n"
269 "If you *really* know what you are doing, you may answer\n"
270 "the next question with yes\n\n") );
271
272         answer = tty_get("Use this key anyway? ");
273         tty_kill_prompt();
274         if( answer_is_yes(answer) )
275             rc = 1;
276         m_free(answer);
277     }
278     else if( opt.always_trust && !rc ) {
279         log_info(_("WARNING: Using untrusted key!\n"));
280         rc = 1;
281     }
282     return rc;
283 }
284
285
286
287 /****************
288  * Check whether we can trust this signature.
289  * Returns: Error if we shall not trust this signatures.
290  */
291 int
292 check_signatures_trust( PKT_signature *sig )
293 {
294     PKT_public_key *pk = m_alloc_clear( sizeof *pk );
295     int trustlevel;
296     int dont_try = 0;
297     int rc=0;
298
299     rc = get_pubkey( pk, sig->keyid );
300     if( rc ) { /* this should not happen */
301         log_error("Ooops; the key vanished  - can't check the trust\n");
302         rc = G10ERR_NO_PUBKEY;
303         goto leave;
304     }
305
306   retry:
307     rc = check_trust( pk, &trustlevel );
308     if( rc ) {
309         log_error("check trust failed: %s\n", g10_errstr(rc));
310         goto leave;
311     }
312
313     if( (trustlevel & TRUST_FLAG_REVOKED) ) {
314         write_status( STATUS_KEYREVOKED );
315         log_info(_("WARNING: This key has been revoked by its owner!\n"));
316         log_info(_("         This could mean that the signature is forgery.\n"));
317     }
318
319
320     switch( (trustlevel & TRUST_MASK) ) {
321       case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
322         rc = insert_trust_record( pk );
323         if( rc ) {
324             log_error("failed to insert it into the trustdb: %s\n",
325                                                       g10_errstr(rc) );
326             goto leave;
327         }
328         rc = check_trust( pk, &trustlevel );
329         if( rc )
330             log_fatal("trust check after insert failed: %s\n",
331                                                       g10_errstr(rc) );
332         if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED )
333             BUG();
334         goto retry;
335
336       case TRUST_EXPIRED:
337         log_info(_("Note: This key has expired!\n"));
338         break;
339
340       case TRUST_UNDEFINED:
341         if( dont_try || opt.batch || opt.answer_no ) {
342             write_status( STATUS_TRUST_UNDEFINED );
343             log_info(_(
344             "WARNING: This key is not certified with a trusted signature!\n"));
345             log_info(_(
346             "         There is no indication that the "
347                                     "signature belongs to the owner.\n" ));
348         }
349         else {
350             rc = add_ownertrust( pk );
351             if( rc ) {
352                 dont_try = 1;
353                 rc = 0;
354             }
355             goto retry;
356         }
357         break;
358
359       case TRUST_NEVER:
360         write_status( STATUS_TRUST_NEVER );
361         log_info(_("WARNING: We do NOT trust this key!\n"));
362         log_info(_("         The signature is probably a FORGERY.\n"));
363         rc = G10ERR_BAD_SIGN;
364         break;
365
366       case TRUST_MARGINAL:
367         write_status( STATUS_TRUST_MARGINAL );
368         log_info(_(
369          "WARNING: This key is not certified with sufficiently trusted signatures!\n"
370                 ));
371         log_info(_(
372          "         It is not certain that the signature belongs to the owner.\n"
373                  ));
374         break;
375
376       case TRUST_FULLY:
377         write_status( STATUS_TRUST_FULLY );
378         break;
379
380       case TRUST_ULTIMATE:
381         write_status( STATUS_TRUST_ULTIMATE );
382         break;
383
384       default: BUG();
385     }
386
387
388   leave:
389     free_public_key( pk );
390     return rc;
391 }
392
393
394 void
395 release_pk_list( PK_LIST pk_list )
396 {
397     PK_LIST pk_rover;
398
399     for( ; pk_list; pk_list = pk_rover ) {
400         pk_rover = pk_list->next;
401         free_public_key( pk_list->pk );
402         m_free( pk_list );
403     }
404 }
405
406 int
407 build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned usage )
408 {
409     PK_LIST pk_list = NULL;
410     PKT_public_key *pk=NULL;
411     int rc=0;
412
413     if( !remusr && !opt.batch ) { /* ask */
414         char *answer=NULL;
415
416         tty_printf(_(
417                 "You did not specify a user ID. (you may use \"-r\")\n\n"));
418         for(;;) {
419             rc = 0;
420             m_free(answer);
421             answer = tty_get(_("Enter the user ID: "));
422             trim_spaces(answer);
423             tty_kill_prompt();
424             if( !*answer )
425                 break;
426             if( pk )
427                 free_public_key( pk );
428             pk = m_alloc_clear( sizeof *pk );
429             pk->pubkey_usage = usage;
430             rc = get_pubkey_byname( pk, answer );
431             if( rc )
432                 tty_printf(_("No such user ID.\n"));
433             else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, usage)) ) {
434                 int trustlevel;
435
436                 rc = check_trust( pk, &trustlevel );
437                 if( rc ) {
438                     log_error("error checking pk of '%s': %s\n",
439                                                       answer, g10_errstr(rc) );
440                 }
441                 else if( do_we_trust_pre( pk, trustlevel ) ) {
442                     PK_LIST r;
443
444                     r = m_alloc( sizeof *r );
445                     r->pk = pk; pk = NULL;
446                     r->next = pk_list;
447                     r->mark = 0;
448                     pk_list = r;
449                     break;
450                 }
451             }
452         }
453         m_free(answer);
454         if( pk ) {
455             free_public_key( pk );
456             pk = NULL;
457         }
458     }
459     else {
460         for(; remusr; remusr = remusr->next ) {
461
462             pk = m_alloc_clear( sizeof *pk );
463             pk->pubkey_usage = usage;
464             if( (rc = get_pubkey_byname( pk, remusr->d )) ) {
465                 free_public_key( pk ); pk = NULL;
466                 log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
467             }
468             else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, usage )) ) {
469                 int trustlevel;
470
471                 rc = check_trust( pk, &trustlevel );
472                 if( rc ) {
473                     free_public_key( pk ); pk = NULL;
474                     log_error(_("%s: error checking key: %s\n"),
475                                                       remusr->d, g10_errstr(rc) );
476                 }
477                 else if( do_we_trust_pre( pk, trustlevel ) ) {
478                     /* note: do_we_trust may have changed the trustlevel */
479                     PK_LIST r;
480
481                     r = m_alloc( sizeof *r );
482                     r->pk = pk; pk = NULL;
483                     r->next = pk_list;
484                     r->mark = 0;
485                     pk_list = r;
486                 }
487                 else { /* we don't trust this pk */
488                     free_public_key( pk ); pk = NULL;
489                 }
490             }
491             else {
492                 free_public_key( pk ); pk = NULL;
493                 log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
494             }
495         }
496     }
497
498
499     if( !rc && !pk_list ) {
500         log_error(_("no valid addressees\n"));
501         rc = G10ERR_NO_USER_ID;
502     }
503
504     if( rc )
505         release_pk_list( pk_list );
506     else
507         *ret_pk_list = pk_list;
508     return rc;
509 }
510
511