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