1997-12-31 13:32:54 +01:00
|
|
|
/* pkclist.c
|
1998-02-24 19:50:46 +01:00
|
|
|
* Copyright (C) 1998 Free Software Foundation, Inc.
|
1997-12-31 13:32:54 +01:00
|
|
|
*
|
1998-12-23 13:41:40 +01:00
|
|
|
* This file is part of GnuPG.
|
1997-12-31 13:32:54 +01:00
|
|
|
*
|
1998-12-23 13:41:40 +01:00
|
|
|
* GnuPG is free software; you can redistribute it and/or modify
|
1997-12-31 13:32:54 +01: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-12-23 13:41:40 +01:00
|
|
|
* GnuPG is distributed in the hope that it will be useful,
|
1997-12-31 13:32:54 +01: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 11:18:17 +01:00
|
|
|
#include "trustdb.h"
|
1998-01-19 19:54:44 +01:00
|
|
|
#include "ttyio.h"
|
1998-07-09 15:37:17 +02:00
|
|
|
#include "status.h"
|
1998-01-26 23:09:01 +01:00
|
|
|
#include "i18n.h"
|
1998-01-19 19:54:44 +01:00
|
|
|
|
1998-09-11 07:47:32 +02:00
|
|
|
|
|
|
|
#define CONTROL_D ('D' - 'A' + 1)
|
|
|
|
|
|
|
|
|
1998-11-13 20:41:41 +01:00
|
|
|
static void
|
1998-11-18 20:59:06 +01:00
|
|
|
show_paths( ulong lid, int only_first )
|
1998-11-13 20:41:41 +01:00
|
|
|
{
|
|
|
|
void *context = NULL;
|
|
|
|
unsigned otrust, validity;
|
1998-11-18 20:59:06 +01:00
|
|
|
int last_level, level;
|
1998-11-13 20:41:41 +01:00
|
|
|
|
1998-11-18 20:59:06 +01:00
|
|
|
last_level = 0;
|
1998-11-13 20:41:41 +01:00
|
|
|
while( (level=enum_cert_paths( &context, &lid, &otrust, &validity)) != -1){
|
|
|
|
char *p;
|
1999-03-08 20:50:18 +01:00
|
|
|
int c, rc;
|
1998-11-13 20:41:41 +01:00
|
|
|
size_t n;
|
|
|
|
u32 keyid[2];
|
|
|
|
PKT_public_key *pk ;
|
|
|
|
|
1998-11-18 20:59:06 +01:00
|
|
|
if( level < last_level && only_first )
|
|
|
|
break;
|
|
|
|
last_level = level;
|
|
|
|
|
1998-11-13 20:41:41 +01:00
|
|
|
rc = keyid_from_lid( lid, keyid );
|
|
|
|
if( rc ) {
|
|
|
|
log_error("ooops: can't get keyid for lid %lu\n", lid);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pk = m_alloc_clear( sizeof *pk );
|
|
|
|
rc = get_pubkey( pk, keyid );
|
|
|
|
if( rc ) {
|
|
|
|
log_error("key %08lX: public key not found: %s\n",
|
|
|
|
(ulong)keyid[1], g10_errstr(rc) );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
tty_printf("%*s%4u%c/%08lX.%lu %s \"",
|
1998-11-18 20:59:06 +01:00
|
|
|
level*2, "",
|
1998-11-13 20:41:41 +01:00
|
|
|
nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
|
|
|
|
(ulong)keyid[1], lid, datestr_from_pk( pk ) );
|
1999-03-08 20:50:18 +01:00
|
|
|
|
1998-12-17 18:36:05 +01:00
|
|
|
c = trust_letter(otrust);
|
|
|
|
if( c )
|
|
|
|
putchar( c );
|
|
|
|
else
|
|
|
|
printf( "%02x", otrust );
|
|
|
|
putchar('/');
|
|
|
|
c = trust_letter(validity);
|
|
|
|
if( c )
|
|
|
|
putchar( c );
|
|
|
|
else
|
|
|
|
printf( "%02x", validity );
|
|
|
|
putchar(' ');
|
|
|
|
|
1998-11-13 20:41:41 +01:00
|
|
|
p = get_user_id( keyid, &n );
|
|
|
|
tty_print_string( p, n ),
|
|
|
|
m_free(p);
|
1998-11-18 20:59:06 +01:00
|
|
|
tty_printf("\"\n");
|
|
|
|
free_public_key( pk );
|
1998-11-13 20:41:41 +01:00
|
|
|
}
|
|
|
|
enum_cert_paths( &context, NULL, NULL, NULL ); /* release context */
|
1998-11-18 20:59:06 +01:00
|
|
|
tty_printf("\n");
|
1998-11-13 20:41:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1998-01-24 17:32:27 +01:00
|
|
|
/****************
|
1998-04-14 19:51:16 +02:00
|
|
|
* Returns true if an ownertrust has changed.
|
1998-01-24 17:32:27 +01:00
|
|
|
*/
|
1999-03-17 13:13:04 +01:00
|
|
|
static int
|
|
|
|
do_edit_ownertrust( ulong lid, int mode, unsigned *new_trust )
|
1998-01-19 19:54:44 +01:00
|
|
|
{
|
|
|
|
char *p;
|
1998-01-24 17:32:27 +01:00
|
|
|
int rc;
|
1998-01-19 19:54:44 +01:00
|
|
|
size_t n;
|
|
|
|
u32 keyid[2];
|
1998-06-29 14:30:57 +02:00
|
|
|
PKT_public_key *pk ;
|
1998-01-24 17:32:27 +01:00
|
|
|
int changed=0;
|
1998-12-17 18:36:05 +01:00
|
|
|
int quit=0;
|
1999-03-17 13:13:04 +01:00
|
|
|
int show=0;
|
1998-01-24 17:32:27 +01:00
|
|
|
|
1998-07-21 14:53:38 +02:00
|
|
|
rc = keyid_from_lid( lid, keyid );
|
1998-01-24 17:32:27 +01:00
|
|
|
if( rc ) {
|
|
|
|
log_error("ooops: can't get keyid for lid %lu\n", lid);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1998-06-29 14:30:57 +02:00
|
|
|
pk = m_alloc_clear( sizeof *pk );
|
|
|
|
rc = get_pubkey( pk, keyid );
|
1998-01-24 17:32:27 +01:00
|
|
|
if( rc ) {
|
1998-07-09 15:37:17 +02:00
|
|
|
log_error("key %08lX: public key not found: %s\n",
|
1998-01-24 17:32:27 +01:00
|
|
|
(ulong)keyid[1], g10_errstr(rc) );
|
|
|
|
return 0;
|
|
|
|
}
|
1998-01-19 19:54:44 +01:00
|
|
|
|
1998-07-30 19:37:03 +02:00
|
|
|
if( !mode ) {
|
1998-11-13 20:41:41 +01:00
|
|
|
tty_printf(_("No trust value assigned to %lu:\n"
|
1998-07-30 19:37:03 +02:00
|
|
|
"%4u%c/%08lX %s \""), lid,
|
|
|
|
nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
|
|
|
|
(ulong)keyid[1], datestr_from_pk( pk ) );
|
|
|
|
p = get_user_id( keyid, &n );
|
|
|
|
tty_print_string( p, n ),
|
|
|
|
m_free(p);
|
|
|
|
tty_printf("\"\n\n");
|
|
|
|
}
|
|
|
|
tty_printf(_(
|
1998-04-14 19:51:16 +02: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 19:54:44 +01:00
|
|
|
" 1 = Don't know\n"
|
|
|
|
" 2 = I do NOT trust\n"
|
|
|
|
" 3 = I trust marginally\n"
|
|
|
|
" 4 = I trust fully\n"
|
1998-08-11 19:29:34 +02:00
|
|
|
" s = please show me more information\n") );
|
|
|
|
if( mode )
|
|
|
|
tty_printf(_(" m = back to the main menu\n"));
|
1998-12-17 18:36:05 +01:00
|
|
|
else
|
|
|
|
tty_printf(_(" q = quit\n"));
|
1998-08-11 19:29:34 +02:00
|
|
|
tty_printf("\n");
|
1998-01-19 19:54:44 +01:00
|
|
|
|
|
|
|
for(;;) {
|
1998-08-11 19:29:34 +02:00
|
|
|
/* a string with valid answers */
|
1998-12-17 18:36:05 +01:00
|
|
|
char *ans = _("sSmMqQ");
|
1998-08-11 19:29:34 +02:00
|
|
|
|
1998-12-17 18:36:05 +01:00
|
|
|
if( strlen(ans) != 6 )
|
1998-08-11 19:29:34 +02:00
|
|
|
BUG();
|
1998-11-27 12:42:49 +01:00
|
|
|
p = cpr_get("edit_ownertrust.value",_("Your decision? "));
|
1998-01-19 19:54:44 +01:00
|
|
|
trim_spaces(p);
|
1998-08-08 21:27:00 +02:00
|
|
|
cpr_kill_prompt();
|
1998-01-19 19:54:44 +01:00
|
|
|
if( *p && p[1] )
|
|
|
|
;
|
|
|
|
else if( !p[1] && (*p >= '1' && *p <= '4') ) {
|
1998-01-24 17:32:27 +01: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();
|
|
|
|
}
|
1999-03-17 13:13:04 +01:00
|
|
|
*new_trust = trust;
|
|
|
|
changed = 1;
|
1998-01-19 19:54:44 +01:00
|
|
|
break;
|
|
|
|
}
|
1998-08-11 19:29:34 +02:00
|
|
|
else if( *p == ans[0] || *p == ans[1] ) {
|
1998-11-13 20:41:41 +01:00
|
|
|
tty_printf(_(
|
|
|
|
"Certificates leading to an ultimately trusted key:\n"));
|
1999-03-17 13:13:04 +01:00
|
|
|
show = 1;
|
|
|
|
break;
|
1998-01-19 19:54:44 +01:00
|
|
|
}
|
1998-09-11 07:47:32 +02:00
|
|
|
else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) ) {
|
1998-08-11 19:29:34 +02:00
|
|
|
break ; /* back to the menu */
|
|
|
|
}
|
1998-12-17 18:36:05 +01:00
|
|
|
else if( !mode && (*p == ans[4] || *p == ans[5] ) ) {
|
|
|
|
quit = 1;
|
|
|
|
break ; /* back to the menu */
|
|
|
|
}
|
1998-01-19 19:54:44 +01:00
|
|
|
m_free(p); p = NULL;
|
|
|
|
}
|
|
|
|
m_free(p);
|
1998-06-29 14:30:57 +02:00
|
|
|
m_free(pk);
|
1999-03-17 13:13:04 +01:00
|
|
|
return show? -2: quit? -1 : changed;
|
1998-01-19 19:54:44 +01:00
|
|
|
}
|
|
|
|
|
1998-01-12 11:18:17 +01:00
|
|
|
|
1999-03-17 13:13:04 +01:00
|
|
|
int
|
|
|
|
edit_ownertrust( ulong lid, int mode )
|
|
|
|
{
|
|
|
|
unsigned trust;
|
|
|
|
|
|
|
|
for(;;) {
|
|
|
|
switch( do_edit_ownertrust( lid, mode, &trust ) ) {
|
|
|
|
case -1:
|
|
|
|
return 0;
|
|
|
|
case -2:
|
|
|
|
show_paths( lid, 1 );
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if( !update_ownertrust( lid, trust ) )
|
|
|
|
return 1;
|
|
|
|
return 0;
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
add_ownertrust_cb( ulong lid )
|
|
|
|
{
|
|
|
|
unsigned trust;
|
|
|
|
int rc = do_edit_ownertrust( lid, 0, &trust );
|
|
|
|
|
|
|
|
if( rc == 1 )
|
|
|
|
return trust & TRUST_MASK;
|
|
|
|
return rc > 0? 0 : rc;
|
|
|
|
}
|
|
|
|
|
1998-01-24 17:32:27 +01:00
|
|
|
/****************
|
|
|
|
* Try to add some more owner trusts (interactive)
|
1998-12-23 13:41:40 +01:00
|
|
|
* This function presents all the signator in a certificate
|
1999-03-17 13:13:04 +01:00
|
|
|
* chain who have no ownertrust value assigned.
|
1998-01-24 17:32:27 +01:00
|
|
|
* Returns: -1 if no ownertrust were added.
|
|
|
|
*/
|
|
|
|
static int
|
1999-03-17 13:13:04 +01:00
|
|
|
add_ownertrust( PKT_public_key *pk, int *quit, unsigned *trustlevel )
|
1998-01-24 17:32:27 +01:00
|
|
|
{
|
|
|
|
int rc;
|
1999-03-17 13:13:04 +01:00
|
|
|
unsigned flags = 0;
|
1998-01-24 17:32:27 +01:00
|
|
|
|
1998-12-17 18:36:05 +01:00
|
|
|
*quit = 0;
|
1999-03-17 13:13:04 +01:00
|
|
|
*trustlevel = 0;
|
1998-01-24 17:32:27 +01:00
|
|
|
tty_printf(
|
1998-04-14 19:51:16 +02:00
|
|
|
_("Could not find a valid trust path to the key. Let's see whether we\n"
|
1998-01-26 23:09:01 +01:00
|
|
|
"can assign some missing owner trust values.\n\n"));
|
1998-01-24 17:32:27 +01:00
|
|
|
|
1999-03-17 13:13:04 +01:00
|
|
|
rc = check_trust( pk, trustlevel, NULL, add_ownertrust_cb, &flags );
|
1998-01-24 17:32:27 +01:00
|
|
|
|
1999-03-17 13:13:04 +01:00
|
|
|
if( !(flags & 1) )
|
1998-11-13 20:41:41 +01:00
|
|
|
tty_printf(_("No path leading to one of our keys found.\n\n") );
|
1999-03-17 13:13:04 +01:00
|
|
|
else if( !(flags & 2) )
|
1998-11-13 20:41:41 +01:00
|
|
|
tty_printf(_("No certificates with undefined trust found.\n\n") );
|
1999-03-17 13:13:04 +01:00
|
|
|
else if( !(flags & 4) )
|
1998-11-13 20:41:41 +01:00
|
|
|
tty_printf(_("No trust values changed.\n\n") );
|
1998-01-24 17:32:27 +01:00
|
|
|
|
1999-03-17 13:13:04 +01:00
|
|
|
return (flags & 4)? 0:-1;
|
1998-01-24 17:32:27 +01:00
|
|
|
}
|
|
|
|
|
1998-01-12 11:18:17 +01:00
|
|
|
/****************
|
1998-06-29 14:30:57 +02:00
|
|
|
* Check whether we can trust this pk which has a trustlevel of TRUSTLEVEL
|
1998-01-12 11:18:17 +01:00
|
|
|
* Returns: true if we trust.
|
|
|
|
*/
|
|
|
|
static int
|
1998-06-29 14:30:57 +02:00
|
|
|
do_we_trust( PKT_public_key *pk, int trustlevel )
|
1998-01-12 11:18:17 +01:00
|
|
|
{
|
1998-01-13 20:04:23 +01:00
|
|
|
int rc;
|
1999-03-17 13:13:04 +01:00
|
|
|
int did_add = 0;
|
1998-01-13 20:04:23 +01:00
|
|
|
|
1999-03-17 13:13:04 +01:00
|
|
|
retry:
|
1998-02-18 14:58:46 +01:00
|
|
|
if( (trustlevel & TRUST_FLAG_REVOKED) ) {
|
1998-11-10 13:59:59 +01:00
|
|
|
log_info(_("key %08lX: key has been revoked!\n"),
|
1998-09-28 21:25:31 +02:00
|
|
|
(ulong)keyid_from_pk( pk, NULL) );
|
1998-02-18 14:58:46 +01:00
|
|
|
if( opt.batch )
|
|
|
|
return 0;
|
|
|
|
|
1998-11-27 12:42:49 +01:00
|
|
|
if( !cpr_get_answer_is_yes("revoked_key.override",
|
1998-08-08 21:27:00 +02:00
|
|
|
_("Use this key anyway? ")) )
|
1998-02-18 14:58:46 +01:00
|
|
|
return 0;
|
|
|
|
}
|
1999-05-06 14:26:10 +02:00
|
|
|
else if( (trustlevel & TRUST_FLAG_SUB_REVOKED) ) {
|
|
|
|
log_info(_("key %08lX: subkey has been revoked!\n"),
|
|
|
|
(ulong)keyid_from_pk( pk, NULL) );
|
|
|
|
if( opt.batch )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if( !cpr_get_answer_is_yes("revoked_key.override",
|
|
|
|
_("Use this key anyway? ")) )
|
|
|
|
return 0;
|
|
|
|
}
|
1998-02-18 14:58:46 +01:00
|
|
|
|
|
|
|
|
|
|
|
switch( (trustlevel & TRUST_MASK) ) {
|
1998-01-19 19:54:44 +01:00
|
|
|
case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
|
1998-06-29 14:30:57 +02:00
|
|
|
rc = insert_trust_record( pk );
|
1998-01-13 20:04:23 +01:00
|
|
|
if( rc ) {
|
|
|
|
log_error("failed to insert it into the trustdb: %s\n",
|
|
|
|
g10_errstr(rc) );
|
|
|
|
return 0; /* no */
|
|
|
|
}
|
1999-03-17 13:13:04 +01:00
|
|
|
rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
|
1998-01-13 20:04:23 +01:00
|
|
|
if( rc )
|
|
|
|
log_fatal("trust check after insert failed: %s\n",
|
|
|
|
g10_errstr(rc) );
|
1999-03-08 20:50:18 +01:00
|
|
|
if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED ) {
|
|
|
|
log_debug("do_we_trust: oops at %d\n", __LINE__ );
|
|
|
|
return 0;
|
|
|
|
}
|
1998-06-29 14:30:57 +02:00
|
|
|
return do_we_trust( pk, trustlevel );
|
1998-01-19 19:54:44 +01:00
|
|
|
|
|
|
|
case TRUST_EXPIRED:
|
1998-11-10 13:59:59 +01:00
|
|
|
log_info(_("%08lX: key has expired\n"),
|
|
|
|
(ulong)keyid_from_pk( pk, NULL) );
|
1998-01-19 19:54:44 +01:00
|
|
|
return 0; /* no */
|
|
|
|
|
|
|
|
case TRUST_UNDEFINED:
|
|
|
|
if( opt.batch || opt.answer_no )
|
1998-11-10 13:59:59 +01:00
|
|
|
log_info(_("%08lX: no info to calculate a trust probability\n"),
|
1998-09-28 21:25:31 +02:00
|
|
|
(ulong)keyid_from_pk( pk, NULL) );
|
1998-01-19 19:54:44 +01:00
|
|
|
else {
|
1998-12-17 18:36:05 +01:00
|
|
|
int quit;
|
|
|
|
|
1999-03-17 13:13:04 +01:00
|
|
|
rc = add_ownertrust( pk, &quit, &trustlevel );
|
|
|
|
if( !rc && !did_add && !quit ) {
|
|
|
|
did_add = 1;
|
|
|
|
goto retry;
|
1998-01-24 17:32:27 +01:00
|
|
|
}
|
1998-01-19 19:54:44 +01:00
|
|
|
}
|
1998-04-02 12:30:03 +02:00
|
|
|
return 0;
|
1998-01-19 19:54:44 +01:00
|
|
|
|
|
|
|
case TRUST_NEVER:
|
1998-11-10 13:59:59 +01:00
|
|
|
log_info(_("%08lX: We do NOT trust this key\n"),
|
1998-09-28 21:25:31 +02:00
|
|
|
(ulong)keyid_from_pk( pk, NULL) );
|
1998-01-19 19:54:44 +01:00
|
|
|
return 0; /* no */
|
|
|
|
|
|
|
|
case TRUST_MARGINAL:
|
1998-11-10 13:59:59 +01:00
|
|
|
log_info(
|
1998-11-25 12:55:58 +01:00
|
|
|
_("%08lX: It is not sure that this key really belongs to the owner\n"
|
1998-11-10 13:59:59 +01:00
|
|
|
"but it is accepted anyway\n"), (ulong)keyid_from_pk( pk, NULL) );
|
1998-01-19 19:54:44 +01:00
|
|
|
return 1; /* yes */
|
|
|
|
|
|
|
|
case TRUST_FULLY:
|
1998-02-12 00:22:09 +01:00
|
|
|
if( opt.verbose )
|
1998-11-10 13:59:59 +01:00
|
|
|
log_info(_("This key probably belongs to the owner\n"));
|
1998-01-19 19:54:44 +01:00
|
|
|
return 1; /* yes */
|
|
|
|
|
|
|
|
case TRUST_ULTIMATE:
|
1998-02-12 00:22:09 +01:00
|
|
|
if( opt.verbose )
|
1998-12-10 20:20:47 +01:00
|
|
|
log_info(_("This key belongs to us\n"));
|
1998-01-19 19:54:44 +01:00
|
|
|
return 1; /* yes */
|
|
|
|
|
|
|
|
default: BUG();
|
1998-01-13 20:04:23 +01:00
|
|
|
}
|
|
|
|
|
1998-01-12 11:18:17 +01:00
|
|
|
return 1; /* yes */
|
|
|
|
}
|
|
|
|
|
1997-12-31 13:32:54 +01:00
|
|
|
|
1998-03-03 09:43:28 +01:00
|
|
|
/****************
|
1998-04-14 19:51:16 +02:00
|
|
|
* wrapper around do_we_trust, so we can ask whether to use the
|
1998-03-03 09:43:28 +01:00
|
|
|
* key anyway.
|
|
|
|
*/
|
|
|
|
static int
|
1998-06-29 14:30:57 +02:00
|
|
|
do_we_trust_pre( PKT_public_key *pk, int trustlevel )
|
1998-03-03 09:43:28 +01:00
|
|
|
{
|
1999-02-25 18:51:55 +01:00
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = do_we_trust( pk, trustlevel );
|
1998-03-03 09:43:28 +01:00
|
|
|
|
1998-12-29 19:58:27 +01:00
|
|
|
if( (trustlevel & TRUST_FLAG_REVOKED) && !rc )
|
|
|
|
return 0;
|
1999-05-06 14:26:10 +02:00
|
|
|
if( (trustlevel & TRUST_FLAG_SUB_REVOKED) && !rc )
|
|
|
|
return 0;
|
1998-12-29 19:58:27 +01:00
|
|
|
else if( !opt.batch && !rc ) {
|
1999-02-26 17:59:48 +01:00
|
|
|
char *p;
|
|
|
|
u32 keyid[2];
|
|
|
|
size_t n;
|
|
|
|
|
|
|
|
keyid_from_pk( pk, keyid);
|
|
|
|
tty_printf( "%4u%c/%08lX %s \"",
|
|
|
|
nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
|
|
|
|
(ulong)keyid[1], datestr_from_pk( pk ) );
|
|
|
|
p = get_user_id( keyid, &n );
|
|
|
|
tty_print_string( p, n ),
|
|
|
|
m_free(p);
|
|
|
|
tty_printf("\"\n\n");
|
|
|
|
|
1998-03-03 09:43:28 +01:00
|
|
|
tty_printf(_(
|
1998-04-14 19:51:16 +02:00
|
|
|
"It is NOT certain that the key belongs to its owner.\n"
|
1998-03-03 09:43:28 +01:00
|
|
|
"If you *really* know what you are doing, you may answer\n"
|
|
|
|
"the next question with yes\n\n") );
|
|
|
|
|
1998-11-27 12:42:49 +01:00
|
|
|
if( cpr_get_answer_is_yes("untrusted_key.override",
|
|
|
|
_("Use this key anyway? ")) )
|
1998-03-03 09:43:28 +01:00
|
|
|
rc = 1;
|
1999-02-26 17:59:48 +01:00
|
|
|
|
|
|
|
/* Hmmm: Should we set a flag to tell the user the user about
|
|
|
|
* his decision the next time he encrypts for this recipient?
|
|
|
|
*/
|
1998-03-03 09:43:28 +01:00
|
|
|
}
|
1998-05-29 13:53:54 +02:00
|
|
|
else if( opt.always_trust && !rc ) {
|
|
|
|
log_info(_("WARNING: Using untrusted key!\n"));
|
|
|
|
rc = 1;
|
|
|
|
}
|
1998-03-03 09:43:28 +01:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
1997-12-31 13:32:54 +01:00
|
|
|
|
1998-07-09 15:37:17 +02:00
|
|
|
|
|
|
|
/****************
|
|
|
|
* Check whether we can trust this signature.
|
|
|
|
* Returns: Error if we shall not trust this signatures.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
check_signatures_trust( PKT_signature *sig )
|
|
|
|
{
|
|
|
|
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
|
|
|
|
int trustlevel;
|
1999-03-17 13:13:04 +01:00
|
|
|
int did_add = 0;
|
1998-07-09 15:37:17 +02:00
|
|
|
int rc=0;
|
|
|
|
|
|
|
|
rc = get_pubkey( pk, sig->keyid );
|
|
|
|
if( rc ) { /* this should not happen */
|
|
|
|
log_error("Ooops; the key vanished - can't check the trust\n");
|
|
|
|
rc = G10ERR_NO_PUBKEY;
|
|
|
|
goto leave;
|
|
|
|
}
|
|
|
|
|
1999-03-17 13:13:04 +01:00
|
|
|
rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
|
1998-07-09 15:37:17 +02:00
|
|
|
if( rc ) {
|
|
|
|
log_error("check trust failed: %s\n", g10_errstr(rc));
|
|
|
|
goto leave;
|
|
|
|
}
|
|
|
|
|
1999-03-17 13:13:04 +01:00
|
|
|
retry:
|
1998-07-09 15:37:17 +02:00
|
|
|
if( (trustlevel & TRUST_FLAG_REVOKED) ) {
|
|
|
|
write_status( STATUS_KEYREVOKED );
|
|
|
|
log_info(_("WARNING: This key has been revoked by its owner!\n"));
|
|
|
|
log_info(_(" This could mean that the signature is forgery.\n"));
|
|
|
|
}
|
1999-05-06 14:26:10 +02:00
|
|
|
else if( (trustlevel & TRUST_FLAG_SUB_REVOKED) ) {
|
|
|
|
write_status( STATUS_KEYREVOKED );
|
|
|
|
log_info(_("WARNING: This subkey has been revoked by its owner!\n"));
|
|
|
|
}
|
1998-07-09 15:37:17 +02:00
|
|
|
|
|
|
|
|
|
|
|
switch( (trustlevel & TRUST_MASK) ) {
|
|
|
|
case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
|
|
|
|
rc = insert_trust_record( pk );
|
|
|
|
if( rc ) {
|
|
|
|
log_error("failed to insert it into the trustdb: %s\n",
|
|
|
|
g10_errstr(rc) );
|
|
|
|
goto leave;
|
|
|
|
}
|
1999-03-17 13:13:04 +01:00
|
|
|
rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
|
1998-07-09 15:37:17 +02:00
|
|
|
if( rc )
|
|
|
|
log_fatal("trust check after insert failed: %s\n",
|
|
|
|
g10_errstr(rc) );
|
|
|
|
if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED )
|
|
|
|
BUG();
|
|
|
|
goto retry;
|
|
|
|
|
|
|
|
case TRUST_EXPIRED:
|
|
|
|
log_info(_("Note: This key has expired!\n"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TRUST_UNDEFINED:
|
1999-03-17 13:13:04 +01:00
|
|
|
if( did_add || opt.batch || opt.answer_no ) {
|
1998-07-09 15:37:17 +02:00
|
|
|
write_status( STATUS_TRUST_UNDEFINED );
|
|
|
|
log_info(_(
|
|
|
|
"WARNING: This key is not certified with a trusted signature!\n"));
|
|
|
|
log_info(_(
|
|
|
|
" There is no indication that the "
|
|
|
|
"signature belongs to the owner.\n" ));
|
|
|
|
}
|
|
|
|
else {
|
1998-12-17 18:36:05 +01:00
|
|
|
int quit;
|
1999-03-17 13:13:04 +01:00
|
|
|
rc = add_ownertrust( pk, &quit, &trustlevel );
|
1998-12-17 18:36:05 +01:00
|
|
|
if( rc || quit ) {
|
1999-03-17 13:13:04 +01:00
|
|
|
did_add = 1;
|
1998-07-09 15:37:17 +02:00
|
|
|
rc = 0;
|
|
|
|
}
|
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TRUST_NEVER:
|
|
|
|
write_status( STATUS_TRUST_NEVER );
|
|
|
|
log_info(_("WARNING: We do NOT trust this key!\n"));
|
|
|
|
log_info(_(" The signature is probably a FORGERY.\n"));
|
|
|
|
rc = G10ERR_BAD_SIGN;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TRUST_MARGINAL:
|
|
|
|
write_status( STATUS_TRUST_MARGINAL );
|
|
|
|
log_info(_(
|
1998-07-14 19:10:28 +02:00
|
|
|
"WARNING: This key is not certified with sufficiently trusted signatures!\n"
|
1998-07-09 15:37:17 +02:00
|
|
|
));
|
|
|
|
log_info(_(
|
|
|
|
" It is not certain that the signature belongs to the owner.\n"
|
|
|
|
));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TRUST_FULLY:
|
|
|
|
write_status( STATUS_TRUST_FULLY );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TRUST_ULTIMATE:
|
|
|
|
write_status( STATUS_TRUST_ULTIMATE );
|
|
|
|
break;
|
|
|
|
|
|
|
|
default: BUG();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
leave:
|
|
|
|
free_public_key( pk );
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1997-12-31 13:32:54 +01:00
|
|
|
void
|
1998-06-29 14:30:57 +02:00
|
|
|
release_pk_list( PK_LIST pk_list )
|
1997-12-31 13:32:54 +01:00
|
|
|
{
|
1998-06-29 14:30:57 +02:00
|
|
|
PK_LIST pk_rover;
|
1997-12-31 13:32:54 +01:00
|
|
|
|
1998-06-29 14:30:57 +02:00
|
|
|
for( ; pk_list; pk_list = pk_rover ) {
|
|
|
|
pk_rover = pk_list->next;
|
|
|
|
free_public_key( pk_list->pk );
|
|
|
|
m_free( pk_list );
|
1997-12-31 13:32:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
1999-02-16 14:16:33 +01:00
|
|
|
build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
|
1997-12-31 13:32:54 +01:00
|
|
|
{
|
1998-06-29 14:30:57 +02:00
|
|
|
PK_LIST pk_list = NULL;
|
|
|
|
PKT_public_key *pk=NULL;
|
1998-03-03 09:43:28 +01:00
|
|
|
int rc=0;
|
1999-02-16 14:16:33 +01:00
|
|
|
int any_recipients=0;
|
|
|
|
STRLIST rov;
|
|
|
|
|
|
|
|
/* check whether there are any recipients in the list and build the
|
|
|
|
* list of the encrypt-to ones (we always trust them) */
|
|
|
|
for( rov = remusr; rov; rov = rov->next ) {
|
|
|
|
if( !(rov->flags & 1) )
|
|
|
|
any_recipients = 1;
|
1999-02-19 15:54:00 +01:00
|
|
|
else if( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) {
|
1999-02-16 14:16:33 +01:00
|
|
|
pk = m_alloc_clear( sizeof *pk );
|
|
|
|
pk->pubkey_usage = use;
|
|
|
|
if( (rc = get_pubkey_byname( NULL, pk, rov->d, NULL )) ) {
|
|
|
|
free_public_key( pk ); pk = NULL;
|
|
|
|
log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
|
|
|
|
}
|
|
|
|
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
|
|
|
|
PK_LIST r;
|
|
|
|
|
|
|
|
r = m_alloc( sizeof *r );
|
|
|
|
r->pk = pk; pk = NULL;
|
|
|
|
r->next = pk_list;
|
|
|
|
r->mark = 0;
|
|
|
|
pk_list = r;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
free_public_key( pk ); pk = NULL;
|
|
|
|
log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1998-03-03 09:43:28 +01:00
|
|
|
|
1999-02-16 14:16:33 +01:00
|
|
|
if( !any_recipients && !opt.batch ) { /* ask */
|
1998-03-03 09:43:28 +01:00
|
|
|
char *answer=NULL;
|
|
|
|
|
|
|
|
tty_printf(_(
|
|
|
|
"You did not specify a user ID. (you may use \"-r\")\n\n"));
|
|
|
|
for(;;) {
|
|
|
|
rc = 0;
|
|
|
|
m_free(answer);
|
1998-11-27 12:42:49 +01:00
|
|
|
answer = cpr_get_utf8("pklist.user_id.enter",
|
1998-11-10 13:59:59 +01:00
|
|
|
_("Enter the user ID: "));
|
1998-03-03 09:43:28 +01:00
|
|
|
trim_spaces(answer);
|
1998-08-08 21:27:00 +02:00
|
|
|
cpr_kill_prompt();
|
1998-03-03 09:43:28 +01:00
|
|
|
if( !*answer )
|
|
|
|
break;
|
1998-06-29 14:30:57 +02:00
|
|
|
if( pk )
|
|
|
|
free_public_key( pk );
|
|
|
|
pk = m_alloc_clear( sizeof *pk );
|
1999-02-16 14:16:33 +01:00
|
|
|
pk->pubkey_usage = use;
|
1998-11-08 18:23:14 +01:00
|
|
|
rc = get_pubkey_byname( NULL, pk, answer, NULL );
|
1998-03-03 09:43:28 +01:00
|
|
|
if( rc )
|
1998-07-06 12:23:57 +02:00
|
|
|
tty_printf(_("No such user ID.\n"));
|
1999-02-16 14:16:33 +01:00
|
|
|
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) {
|
1998-03-03 09:43:28 +01:00
|
|
|
int trustlevel;
|
1997-12-31 13:32:54 +01:00
|
|
|
|
1999-03-17 13:13:04 +01:00
|
|
|
rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
|
1998-03-03 09:43:28 +01:00
|
|
|
if( rc ) {
|
1998-12-29 14:47:31 +01:00
|
|
|
log_error("error checking pk of `%s': %s\n",
|
1998-03-03 09:43:28 +01:00
|
|
|
answer, g10_errstr(rc) );
|
|
|
|
}
|
1998-06-29 14:30:57 +02:00
|
|
|
else if( do_we_trust_pre( pk, trustlevel ) ) {
|
|
|
|
PK_LIST r;
|
1998-03-03 09:43:28 +01:00
|
|
|
|
|
|
|
r = m_alloc( sizeof *r );
|
1998-06-29 14:30:57 +02:00
|
|
|
r->pk = pk; pk = NULL;
|
|
|
|
r->next = pk_list;
|
1998-03-03 09:43:28 +01:00
|
|
|
r->mark = 0;
|
1998-06-29 14:30:57 +02:00
|
|
|
pk_list = r;
|
1999-02-16 14:16:33 +01:00
|
|
|
any_recipients = 1;
|
1998-03-03 09:43:28 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_free(answer);
|
1998-06-29 14:30:57 +02:00
|
|
|
if( pk ) {
|
|
|
|
free_public_key( pk );
|
|
|
|
pk = NULL;
|
1998-03-03 09:43:28 +01:00
|
|
|
}
|
1997-12-31 13:32:54 +01:00
|
|
|
}
|
|
|
|
else {
|
1999-02-26 17:59:48 +01:00
|
|
|
any_recipients = 0;
|
1997-12-31 13:32:54 +01:00
|
|
|
for(; remusr; remusr = remusr->next ) {
|
1999-02-19 15:54:00 +01:00
|
|
|
if( (remusr->flags & 1) )
|
|
|
|
continue; /* encrypt-to keys are already handled */
|
1997-12-31 13:32:54 +01:00
|
|
|
|
1998-06-29 14:30:57 +02:00
|
|
|
pk = m_alloc_clear( sizeof *pk );
|
1999-02-16 14:16:33 +01:00
|
|
|
pk->pubkey_usage = use;
|
1998-11-08 18:23:14 +01:00
|
|
|
if( (rc = get_pubkey_byname( NULL, pk, remusr->d, NULL )) ) {
|
1998-06-29 14:30:57 +02:00
|
|
|
free_public_key( pk ); pk = NULL;
|
1998-07-06 12:23:57 +02:00
|
|
|
log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
|
1997-12-31 13:32:54 +01:00
|
|
|
}
|
1999-02-16 14:16:33 +01:00
|
|
|
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
|
1998-01-12 11:18:17 +01:00
|
|
|
int trustlevel;
|
|
|
|
|
1999-03-17 13:13:04 +01:00
|
|
|
rc = check_trust( pk, &trustlevel, NULL, NULL, NULL );
|
1998-01-12 11:18:17 +01:00
|
|
|
if( rc ) {
|
1998-06-29 14:30:57 +02:00
|
|
|
free_public_key( pk ); pk = NULL;
|
1998-07-06 12:23:57 +02:00
|
|
|
log_error(_("%s: error checking key: %s\n"),
|
1998-01-12 11:18:17 +01:00
|
|
|
remusr->d, g10_errstr(rc) );
|
|
|
|
}
|
1998-06-29 14:30:57 +02:00
|
|
|
else if( do_we_trust_pre( pk, trustlevel ) ) {
|
1998-01-13 20:04:23 +01:00
|
|
|
/* note: do_we_trust may have changed the trustlevel */
|
1998-06-29 14:30:57 +02:00
|
|
|
PK_LIST r;
|
1998-01-12 11:18:17 +01:00
|
|
|
|
|
|
|
r = m_alloc( sizeof *r );
|
1998-06-29 14:30:57 +02:00
|
|
|
r->pk = pk; pk = NULL;
|
|
|
|
r->next = pk_list;
|
1998-01-12 11:18:17 +01:00
|
|
|
r->mark = 0;
|
1998-06-29 14:30:57 +02:00
|
|
|
pk_list = r;
|
1999-02-16 14:16:33 +01:00
|
|
|
any_recipients = 1;
|
1998-01-12 11:18:17 +01:00
|
|
|
}
|
1998-06-29 14:30:57 +02:00
|
|
|
else { /* we don't trust this pk */
|
|
|
|
free_public_key( pk ); pk = NULL;
|
1998-01-12 11:18:17 +01:00
|
|
|
}
|
1997-12-31 13:32:54 +01:00
|
|
|
}
|
|
|
|
else {
|
1998-06-29 14:30:57 +02:00
|
|
|
free_public_key( pk ); pk = NULL;
|
1998-07-06 12:23:57 +02:00
|
|
|
log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
|
1997-12-31 13:32:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-02-16 14:16:33 +01:00
|
|
|
if( !rc && !any_recipients ) {
|
1998-07-06 12:23:57 +02:00
|
|
|
log_error(_("no valid addressees\n"));
|
1997-12-31 13:32:54 +01:00
|
|
|
rc = G10ERR_NO_USER_ID;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( rc )
|
1998-06-29 14:30:57 +02:00
|
|
|
release_pk_list( pk_list );
|
1997-12-31 13:32:54 +01:00
|
|
|
else
|
1998-06-29 14:30:57 +02:00
|
|
|
*ret_pk_list = pk_list;
|
1997-12-31 13:32:54 +01:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-02-25 18:51:55 +01:00
|
|
|
|
|
|
|
static int
|
|
|
|
algo_available( int preftype, int algo )
|
|
|
|
{
|
|
|
|
if( preftype == PREFTYPE_SYM ) {
|
|
|
|
return algo && !check_cipher_algo( algo );
|
|
|
|
}
|
|
|
|
else if( preftype == PREFTYPE_HASH ) {
|
|
|
|
return algo && !check_digest_algo( algo );
|
|
|
|
}
|
|
|
|
else if( preftype == PREFTYPE_COMPR ) {
|
|
|
|
return !algo || algo == 1 || algo == 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1998-08-05 18:51:59 +02:00
|
|
|
/****************
|
|
|
|
* Return -1 if we could not find an algorithm.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
select_algo_from_prefs( PK_LIST pk_list, int preftype )
|
|
|
|
{
|
|
|
|
PK_LIST pkr;
|
|
|
|
u32 bits[8];
|
|
|
|
byte *pref = NULL;
|
|
|
|
size_t npref;
|
|
|
|
int i, j;
|
|
|
|
int compr_hack=0;
|
|
|
|
int any;
|
|
|
|
|
|
|
|
if( !pk_list )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
memset( bits, ~0, 8 * sizeof *bits );
|
|
|
|
for( pkr = pk_list; pkr; pkr = pkr->next ) {
|
|
|
|
u32 mask[8];
|
|
|
|
|
|
|
|
memset( mask, 0, 8 * sizeof *mask );
|
1999-02-19 15:54:00 +01:00
|
|
|
if( !pkr->pk->local_id ) { /* try to set the local id */
|
1999-03-08 20:50:18 +01:00
|
|
|
query_trust_info( pkr->pk, NULL );
|
1999-02-19 15:54:00 +01:00
|
|
|
if( !pkr->pk->local_id ) {
|
|
|
|
log_debug("select_algo_from_prefs: can't get LID\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
1998-08-05 18:51:59 +02:00
|
|
|
if( preftype == PREFTYPE_SYM )
|
1998-12-13 14:14:27 +01:00
|
|
|
mask[0] |= (1<<2); /* 3DES is implicitly there */
|
1998-08-05 18:51:59 +02:00
|
|
|
m_free(pref);
|
|
|
|
pref = get_pref_data( pkr->pk->local_id, pkr->pk->namehash, &npref);
|
|
|
|
any = 0;
|
|
|
|
if( pref ) {
|
1998-12-13 14:14:27 +01:00
|
|
|
#if 0
|
|
|
|
log_hexdump("raw: ", pref, npref );
|
|
|
|
#endif
|
1998-08-05 18:51:59 +02:00
|
|
|
for(i=0; i+1 < npref; i+=2 ) {
|
|
|
|
if( pref[i] == preftype ) {
|
|
|
|
mask[pref[i+1]/32] |= 1 << (pref[i+1]%32);
|
|
|
|
any = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( (!pref || !any) && preftype == PREFTYPE_COMPR ) {
|
|
|
|
mask[0] |= 3; /* asume no_compression and old pgp */
|
|
|
|
compr_hack = 1;
|
|
|
|
}
|
|
|
|
|
1998-12-13 14:14:27 +01:00
|
|
|
#if 0
|
|
|
|
log_debug("mask=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
|
1998-08-05 18:51:59 +02:00
|
|
|
(ulong)mask[7], (ulong)mask[6], (ulong)mask[5], (ulong)mask[4],
|
1998-12-13 14:14:27 +01:00
|
|
|
(ulong)mask[3], (ulong)mask[2], (ulong)mask[1], (ulong)mask[0]);
|
|
|
|
#endif
|
1998-08-05 18:51:59 +02:00
|
|
|
for(i=0; i < 8; i++ )
|
|
|
|
bits[i] &= mask[i];
|
1998-12-13 14:14:27 +01:00
|
|
|
#if 0
|
|
|
|
log_debug("bits=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n",
|
1998-08-05 18:51:59 +02:00
|
|
|
(ulong)bits[7], (ulong)bits[6], (ulong)bits[5], (ulong)bits[4],
|
1998-12-13 14:14:27 +01:00
|
|
|
(ulong)bits[3], (ulong)bits[2], (ulong)bits[1], (ulong)bits[0]);
|
|
|
|
#endif
|
1998-08-05 18:51:59 +02:00
|
|
|
}
|
|
|
|
/* usable algorithms are now in bits
|
|
|
|
* We now use the last key from pk_list to select
|
|
|
|
* the algorithm we want to use. there are no
|
|
|
|
* preferences for the last key, we select the one
|
|
|
|
* corresponding to first set bit.
|
|
|
|
*/
|
|
|
|
i = -1;
|
|
|
|
any = 0;
|
|
|
|
if( pref ) {
|
|
|
|
for(j=0; j+1 < npref; j+=2 ) {
|
|
|
|
if( pref[j] == preftype ) {
|
|
|
|
if( (bits[pref[j+1]/32] & (1<<(pref[j+1]%32))) ) {
|
1999-02-25 18:51:55 +01:00
|
|
|
if( algo_available( preftype, pref[j+1] ) ) {
|
1999-04-18 20:53:34 +02:00
|
|
|
any = 1;
|
1999-02-25 18:51:55 +01:00
|
|
|
i = pref[j+1];
|
|
|
|
break;
|
|
|
|
}
|
1998-08-05 18:51:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( !pref || !any ) {
|
|
|
|
for(j=0; j < 256; j++ )
|
|
|
|
if( (bits[j/32] & (1<<(j%32))) ) {
|
1999-02-25 18:51:55 +01:00
|
|
|
if( algo_available( preftype, j ) ) {
|
|
|
|
i = j;
|
|
|
|
break;
|
|
|
|
}
|
1998-08-05 18:51:59 +02:00
|
|
|
}
|
|
|
|
}
|
1998-12-13 14:14:27 +01:00
|
|
|
#if 0
|
|
|
|
log_debug("prefs of type %d: selected %d\n", preftype, i );
|
|
|
|
#endif
|
1998-08-05 18:51:59 +02:00
|
|
|
if( compr_hack && !i ) {
|
|
|
|
/* selected no compression, but we should check whether
|
|
|
|
* algorithm 1 is also available (the ordering is not relevant
|
|
|
|
* in this case). */
|
|
|
|
if( bits[0] & (1<<1) )
|
|
|
|
i = 1; /* yep; we can use compression algo 1 */
|
|
|
|
}
|
|
|
|
|
|
|
|
m_free(pref);
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
|