1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00
gnupg/g10/pkclist.c

397 lines
9.4 KiB
C
Raw Normal View History

1997-12-31 12:32:54 +00:00
/* pkclist.c
1998-02-24 18:50:46 +00:00
* Copyright (C) 1998 Free Software Foundation, Inc.
1997-12-31 12:32:54 +00:00
*
1998-02-24 18:50:46 +00:00
* This file is part of GNUPG.
1997-12-31 12:32:54 +00:00
*
1998-02-24 18:50:46 +00:00
* GNUPG is free software; you can redistribute it and/or modify
1997-12-31 12:32:54 +00:00
* 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.
*
1998-02-24 18:50:46 +00:00
* GNUPG is distributed in the hope that it will be useful,
1997-12-31 12:32:54 +00:00
* 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 <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include "options.h"
#include "packet.h"
#include "errors.h"
#include "keydb.h"
#include "memory.h"
#include "util.h"
1998-01-12 10:18:17 +00:00
#include "trustdb.h"
1998-01-19 18:54:44 +00:00
#include "ttyio.h"
1998-01-26 22:09:01 +00:00
#include "i18n.h"
1998-01-19 18:54:44 +00:00
1998-01-24 16:32:27 +00:00
/****************
1998-04-14 17:51:16 +00:00
* Returns true if an ownertrust has changed.
1998-01-24 16:32:27 +00:00
*/
1998-01-19 18:54:44 +00:00
static int
1998-01-24 16:32:27 +00:00
query_ownertrust( ulong lid )
1998-01-19 18:54:44 +00:00
{
char *p;
1998-01-24 16:32:27 +00:00
int rc;
1998-01-19 18:54:44 +00:00
size_t n;
u32 keyid[2];
1998-01-24 16:32:27 +00:00
PKT_public_cert *pkc ;
int changed=0;
rc = keyid_from_trustdb( lid, keyid );
if( rc ) {
log_error("ooops: can't get keyid for lid %lu\n", lid);
return 0;
}
pkc = m_alloc_clear( sizeof *pkc );
rc = get_pubkey( pkc, keyid );
if( rc ) {
log_error("keyid %08lX: pubkey not found: %s\n",
(ulong)keyid[1], g10_errstr(rc) );
return 0;
}
1998-01-19 18:54:44 +00:00
1998-01-26 22:09:01 +00:00
tty_printf(_("No ownertrust defined for %lu:\n"
"%4u%c/%08lX %s \""), lid,
1998-01-19 18:54:44 +00:00
nbits_from_pkc( pkc ), pubkey_letter( pkc->pubkey_algo ),
(ulong)keyid[1], datestr_from_pkc( pkc ) );
p = get_user_id( keyid, &n );
tty_print_string( p, n ),
m_free(p);
1998-01-26 22:09:01 +00:00
tty_printf(_("\"\n\n"
1998-04-14 17:51:16 +00:00
"Please decide how far you trust this user to correctly\n"
"verify other users' keys (by looking at passports,\n"
"checking fingerprints from different sources...)?\n\n"
1998-01-19 18:54:44 +00:00
" 1 = Don't know\n"
" 2 = I do NOT trust\n"
" 3 = I trust marginally\n"
" 4 = I trust fully\n"
1998-04-14 17:51:16 +00:00
" s = please show me more information\n\n") );
1998-01-19 18:54:44 +00:00
for(;;) {
1998-01-26 22:09:01 +00:00
p = tty_get(_("Your decision? "));
1998-01-19 18:54:44 +00:00
trim_spaces(p);
tty_kill_prompt();
if( *p && p[1] )
;
else if( *p == '?' ) {
1998-01-26 22:09:01 +00:00
tty_printf(_(
1998-01-19 18:54:44 +00:00
"It's up to you to assign a value here; this value will never be exported\n"
"to any 3rd party. We need it to implement the web-of-trust; it has nothing\n"
1998-01-26 22:09:01 +00:00
"to do with the (implicitly created) web-of-certificates.\n"));
1998-01-19 18:54:44 +00:00
}
else if( !p[1] && (*p >= '1' && *p <= '4') ) {
1998-01-24 16:32:27 +00:00
unsigned trust;
switch( *p ) {
case '1': trust = TRUST_UNDEFINED; break;
case '2': trust = TRUST_NEVER ; break;
case '3': trust = TRUST_MARGINAL ; break;
case '4': trust = TRUST_FULLY ; break;
default: BUG();
}
if( !update_ownertrust( lid, trust ) )
changed++;
1998-01-19 18:54:44 +00:00
break;
}
else if( *p == 's' || *p == 'S' ) {
1998-01-26 22:09:01 +00:00
tty_printf(_("You will see a list of signators etc. here\n"));
1998-01-19 18:54:44 +00:00
}
m_free(p); p = NULL;
}
m_free(p);
1998-01-24 16:32:27 +00:00
m_free(pkc);
return changed;
1998-01-19 18:54:44 +00:00
}
1998-01-12 10:18:17 +00:00
1998-01-24 16:32:27 +00:00
/****************
* Try to add some more owner trusts (interactive)
* Returns: -1 if no ownertrust were added.
*/
static int
add_ownertrust( PKT_public_cert *pkc )
{
int rc;
void *context = NULL;
ulong lid;
unsigned trust;
int any=0;
tty_printf(
1998-04-14 17:51:16 +00:00
_("Could not find a valid trust path to the key. Let's see whether we\n"
1998-01-26 22:09:01 +00:00
"can assign some missing owner trust values.\n\n"));
1998-01-24 16:32:27 +00:00
rc = query_trust_record( pkc );
if( rc ) {
log_error("Ooops: not in trustdb\n");
return -1;
}
lid = pkc->local_id;
while( !(rc=enum_trust_web( &context, &lid )) ) {
rc = get_ownertrust( lid, &trust );
if( rc )
log_fatal("Ooops: couldn't get ownertrust for %lu\n", lid);
if( trust == TRUST_UNDEFINED || trust == TRUST_EXPIRED ||
trust == TRUST_UNKNOWN ) {
if( query_ownertrust( lid ) )
any=1;
}
}
if( rc == -1 )
rc = 0;
enum_trust_web( &context, NULL ); /* close */
1998-03-03 08:43:28 +00:00
if( !any )
tty_printf(_("No ownertrust values changed.\n\n") );
1998-01-24 16:32:27 +00:00
return rc? rc : any? 0:-1;
}
1998-01-12 10:18:17 +00:00
/****************
1998-04-14 17:51:16 +00:00
* Check whether we can trust this pkc which has a trustlevel of TRUSTLEVEL
1998-01-12 10:18:17 +00:00
* Returns: true if we trust.
*/
static int
do_we_trust( PKT_public_cert *pkc, int trustlevel )
{
1998-01-13 19:04:23 +00:00
int rc;
if( (trustlevel & TRUST_FLAG_REVOKED) ) {
char *answer;
int yes;
1998-04-30 14:06:01 +00:00
log_info("key has been revoked!\n");
if( opt.batch )
return 0;
answer = tty_get("Use this key anyway? ");
tty_kill_prompt();
yes = answer_is_yes(answer);
m_free(answer);
if( !yes )
return 0;
}
switch( (trustlevel & TRUST_MASK) ) {
1998-01-19 18:54:44 +00:00
case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
1998-01-13 19:04:23 +00:00
rc = insert_trust_record( pkc );
if( rc ) {
log_error("failed to insert it into the trustdb: %s\n",
g10_errstr(rc) );
return 0; /* no */
}
1998-01-19 18:54:44 +00:00
rc = check_trust( pkc, &trustlevel );
1998-01-13 19:04:23 +00:00
if( rc )
log_fatal("trust check after insert failed: %s\n",
g10_errstr(rc) );
1998-01-19 18:54:44 +00:00
if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED )
1998-01-16 21:15:24 +00:00
BUG();
1998-01-19 18:54:44 +00:00
return do_we_trust( pkc, trustlevel );
case TRUST_EXPIRED:
1998-04-02 10:30:03 +00:00
log_info("key has expired\n");
1998-01-19 18:54:44 +00:00
return 0; /* no */
case TRUST_UNDEFINED:
if( opt.batch || opt.answer_no )
log_info("no info to calculate a trust probability\n");
else {
1998-01-24 16:32:27 +00:00
rc = add_ownertrust( pkc );
if( !rc ) {
rc = check_trust( pkc, &trustlevel );
if( rc )
log_fatal("trust check after add_ownertrust failed: %s\n",
g10_errstr(rc) );
1998-04-14 17:51:16 +00:00
/* fixme: this is recursive; we should unroll it */
1998-01-24 16:32:27 +00:00
return do_we_trust( pkc, trustlevel );
}
1998-01-19 18:54:44 +00:00
}
1998-04-02 10:30:03 +00:00
return 0;
1998-01-19 18:54:44 +00:00
case TRUST_NEVER:
log_info("We do NOT trust this key\n");
return 0; /* no */
case TRUST_MARGINAL:
1998-04-14 17:51:16 +00:00
log_info("I'm not sure whether this key really belongs to the owner\n"
1998-01-19 18:54:44 +00:00
"but I proceed anyway\n");
return 1; /* yes */
case TRUST_FULLY:
1998-02-11 23:22:09 +00:00
if( opt.verbose )
log_info("This key probably belongs to the owner\n");
1998-01-19 18:54:44 +00:00
return 1; /* yes */
case TRUST_ULTIMATE:
1998-02-11 23:22:09 +00:00
if( opt.verbose )
log_info("This key belongs to us (we have the secret key)\n");
1998-01-19 18:54:44 +00:00
return 1; /* yes */
default: BUG();
1998-01-13 19:04:23 +00:00
}
1998-01-12 10:18:17 +00:00
/* Eventuell fragen falls der trustlevel nicht ausreichend ist */
return 1; /* yes */
}
1997-12-31 12:32:54 +00:00
1998-03-03 08:43:28 +00:00
/****************
1998-04-14 17:51:16 +00:00
* wrapper around do_we_trust, so we can ask whether to use the
1998-03-03 08:43:28 +00:00
* key anyway.
*/
static int
do_we_trust_pre( PKT_public_cert *pkc, int trustlevel )
{
int rc = do_we_trust( pkc, trustlevel );
if( !opt.batch && !rc ) {
char *answer;
tty_printf(_(
1998-04-14 17:51:16 +00:00
"It is NOT certain that the key belongs to its owner.\n"
1998-03-03 08:43:28 +00:00
"If you *really* know what you are doing, you may answer\n"
"the next question with yes\n\n") );
answer = tty_get("Use this key anyway? ");
tty_kill_prompt();
if( answer_is_yes(answer) )
rc = 1;
m_free(answer);
}
return rc;
}
1997-12-31 12:32:54 +00:00
void
release_pkc_list( PKC_LIST pkc_list )
{
PKC_LIST pkc_rover;
for( ; pkc_list; pkc_list = pkc_rover ) {
pkc_rover = pkc_list->next;
free_public_cert( pkc_list->pkc );
m_free( pkc_list );
}
}
int
1998-04-08 19:49:02 +00:00
build_pkc_list( STRLIST remusr, PKC_LIST *ret_pkc_list, unsigned usage )
1997-12-31 12:32:54 +00:00
{
PKC_LIST pkc_list = NULL;
1998-03-03 08:43:28 +00:00
PKT_public_cert *pkc=NULL;
int rc=0;
if( !remusr && !opt.batch ) { /* ask */
char *answer=NULL;
tty_printf(_(
"You did not specify a user ID. (you may use \"-r\")\n\n"));
for(;;) {
rc = 0;
m_free(answer);
answer = tty_get(_("Enter the user ID: "));
trim_spaces(answer);
tty_kill_prompt();
if( !*answer )
break;
if( pkc )
free_public_cert( pkc );
pkc = m_alloc_clear( sizeof *pkc );
rc = get_pubkey_byname( pkc, answer );
if( rc )
tty_printf("No such user ID.\n");
1998-04-08 19:49:02 +00:00
else if( !(rc=check_pubkey_algo2(pkc->pubkey_algo, usage)) ) {
1998-03-03 08:43:28 +00:00
int trustlevel;
1997-12-31 12:32:54 +00:00
1998-03-03 08:43:28 +00:00
rc = check_trust( pkc, &trustlevel );
if( rc ) {
log_error("error checking pkc of '%s': %s\n",
answer, g10_errstr(rc) );
}
else if( do_we_trust_pre( pkc, trustlevel ) ) {
PKC_LIST r;
r = m_alloc( sizeof *r );
r->pkc = pkc; pkc = NULL;
r->next = pkc_list;
r->mark = 0;
pkc_list = r;
break;
}
}
}
m_free(answer);
if( pkc ) {
free_public_cert( pkc );
pkc = NULL;
}
1997-12-31 12:32:54 +00:00
}
else {
for(; remusr; remusr = remusr->next ) {
pkc = m_alloc_clear( sizeof *pkc );
if( (rc = get_pubkey_byname( pkc, remusr->d )) ) {
free_public_cert( pkc ); pkc = NULL;
log_error("skipped '%s': %s\n", remusr->d, g10_errstr(rc) );
}
1998-04-08 19:49:02 +00:00
else if( !(rc=check_pubkey_algo2(pkc->pubkey_algo, usage )) ) {
1998-01-12 10:18:17 +00:00
int trustlevel;
1998-01-19 18:54:44 +00:00
rc = check_trust( pkc, &trustlevel );
1998-01-12 10:18:17 +00:00
if( rc ) {
free_public_cert( pkc ); pkc = NULL;
log_error("error checking pkc of '%s': %s\n",
remusr->d, g10_errstr(rc) );
}
1998-03-03 08:43:28 +00:00
else if( do_we_trust_pre( pkc, trustlevel ) ) {
1998-01-13 19:04:23 +00:00
/* note: do_we_trust may have changed the trustlevel */
1998-01-12 10:18:17 +00:00
PKC_LIST r;
r = m_alloc( sizeof *r );
r->pkc = pkc; pkc = NULL;
r->next = pkc_list;
r->mark = 0;
pkc_list = r;
}
else { /* we don't trust this pkc */
free_public_cert( pkc ); pkc = NULL;
}
1997-12-31 12:32:54 +00:00
}
else {
free_public_cert( pkc ); pkc = NULL;
log_error("skipped '%s': %s\n", remusr->d, g10_errstr(rc) );
}
}
}
if( !rc && !pkc_list ) {
log_error("no valid addressees\n");
rc = G10ERR_NO_USER_ID;
}
if( rc )
release_pkc_list( pkc_list );
else
*ret_pkc_list = pkc_list;
return rc;
}