Fix bug 1091.
[gnupg.git] / g10 / import.c
index fbfb18d..88eb24e 100644 (file)
@@ -28,7 +28,7 @@
 #include "gpg.h"
 #include "options.h"
 #include "packet.h"
-#include "errors.h"
+#include "status.h"
 #include "keydb.h"
 #include "util.h"
 #include "trustdb.h"
@@ -602,9 +602,9 @@ check_prefs(KBNODE keyblock)
                  if (openpgp_cipher_test_algo (prefs->value))
                    {
                      const char *algo = 
-                        (gcry_cipher_test_algo (prefs->value)
+                        (openpgp_cipher_test_algo (prefs->value)
                          ? num 
-                         : gcry_cipher_algo_name (prefs->value));
+                         : openpgp_cipher_algo_name (prefs->value));
                      if(!problem)
                        check_prefs_warning(pk);
                      log_info(_("         \"%s\": preference for cipher"
@@ -682,7 +682,7 @@ check_prefs(KBNODE keyblock)
  * Try to import one keyblock. Return an error only in serious cases, but
  * never for an invalid keyblock.  It uses log_error to increase the
  * internal errorcount, so that invalid input can be detected by programs
- * which called g10.
+ * which called gpg.
  */
 static int
 import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
@@ -697,6 +697,7 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
     int rc = 0;
     int new_key = 0;
     int mod_key = 0;
+    int same_key = 0;
     int non_self = 0;
 
     /* get the key and print some info about it */
@@ -715,12 +716,14 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
                  nbits_from_pk( pk ),
                  pubkey_letter( pk->pubkey_algo ),
                  keystr_from_pk(pk), datestr_from_pk(pk) );
-       if( uidnode )
-         print_utf8_string( stderr, uidnode->pkt->pkt.user_id->name,
+       if (uidnode)
+         print_utf8_string (log_get_stream (),
+                             uidnode->pkt->pkt.user_id->name,
                             uidnode->pkt->pkt.user_id->len );
        log_printf ("\n");
       }
 
+
     if( !uidnode )
       {
        log_error( _("key %s: no user ID\n"), keystr_from_pk(pk));
@@ -958,7 +961,8 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
        }
        else
          {
-           if (is_status_enabled ()) 
+            same_key = 1;
+            if (is_status_enabled ()) 
              print_import_ok (pk, NULL, 0);
 
            if( !opt.quiet )
@@ -975,6 +979,33 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
     }
 
   leave:
+    if (mod_key || new_key || same_key)
+      {
+       /* A little explanation for this: we fill in the fingerprint
+          when importing keys as it can be useful to know the
+          fingerprint in certain keyserver-related cases (a keyserver
+          asked for a particular name, but the key doesn't have that
+          name).  However, in cases where we're importing more than
+          one key at a time, we cannot know which key to fingerprint.
+          In these cases, rather than guessing, we do not
+          fingerprinting at all, and we must hope the user ID on the
+          keys are useful.  Note that we need to do this for new
+          keys, merged keys and even for unchanged keys.  This is
+          required because for example the --auto-key-locate feature
+          may import an already imported key and needs to know the
+          fingerprint of the key in all cases.  */
+       if (fpr)
+         {
+           xfree (*fpr);
+            /* Note that we need to compare against 0 here because
+               COUNT gets only incremented after returning form this
+               function.  */
+           if (stats->count == 0)
+             *fpr = fingerprint_from_pk (pk, NULL, fpr_len);
+           else
+             *fpr = NULL;
+         }
+      }
 
     /* Now that the key is definitely incorporated into the keydb, we
        need to check if a designated revocation is present or if the
@@ -988,24 +1019,6 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
       }
     else if(new_key)
       {
-       /* A little explanation for this: we fill in the fingerprint
-          when importing keys as it can be useful to know the
-          fingerprint in certain keyserver-related cases (a keyserver
-          asked for a particular name, but the key doesn't have that
-          name).  However, in cases where we're importing more than
-          one key at a time, we cannot know which key to fingerprint.
-          In these cases, rather than guessing, we do not fingerpring
-          at all, and we must hope the user ID on the keys are
-          useful. */
-       if(fpr)
-         {
-           xfree(*fpr);
-           if(stats->imported==1)
-             *fpr=fingerprint_from_pk(pk,NULL,fpr_len);
-           else
-             *fpr=NULL;
-         }
-
        revocation_present(keyblock);
        if(!from_sk && seckey_available(keyid)==0)
          check_prefs(keyblock);
@@ -1225,6 +1238,8 @@ import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats )
     u32 keyid[2];
     int rc = 0;
 
+    (void)fname;
+
     assert( !node->next );
     assert( node->pkt->pkttype == PKT_SIGNATURE );
     assert( node->pkt->pkt.signature->sig_class == 0x20 );
@@ -1352,6 +1367,9 @@ chk_self_sigs( const char *fname, KBNODE keyblock,
     u32 bsdate=0,rsdate=0;
     KBNODE bsnode=NULL,rsnode=NULL;
 
+    (void)fname;
+    (void)pk;
+
     for( n=keyblock; (n = find_next_kbnode(n, 0)); ) {
       if(n->pkt->pkttype==PKT_PUBLIC_SUBKEY)
        {
@@ -1524,6 +1542,8 @@ delete_inv_parts( const char *fname, KBNODE keyblock,
     KBNODE node;
     int nvalid=0, uid_seen=0, subkey_seen=0;
 
+    (void)fname;
+
     for(node=keyblock->next; node; node = node->next ) {
        if( node->pkt->pkttype == PKT_USER_ID ) {
            uid_seen = 1;
@@ -1661,11 +1681,17 @@ collapse_uids( KBNODE *keyblock )
     {
       KBNODE uid2;
 
+      if(is_deleted_kbnode(uid1))
+       continue;
+
       if(uid1->pkt->pkttype!=PKT_USER_ID)
        continue;
 
       for(uid2=uid1->next;uid2;uid2=uid2->next)
        {
+         if(is_deleted_kbnode(uid2))
+           continue;
+
          if(uid2->pkt->pkttype!=PKT_USER_ID)
            continue;
 
@@ -1681,6 +1707,9 @@ collapse_uids( KBNODE *keyblock )
                 uid1 */
              for(last=uid2;last->next;last=last->next)
                {
+                 if(is_deleted_kbnode(last))
+                   continue;
+
                  if(last->next->pkt->pkttype==PKT_USER_ID
                     || last->next->pkt->pkttype==PKT_PUBLIC_SUBKEY
                     || last->next->pkt->pkttype==PKT_SECRET_SUBKEY)
@@ -1693,13 +1722,16 @@ collapse_uids( KBNODE *keyblock )
              /* Now put uid2 in place as part of uid1 */
              last->next=uid1->next;
              uid1->next=uid2;
-             remove_kbnode(keyblock,uid2);
+             delete_kbnode(uid2);
 
              /* Now dedupe uid1 */
              for(sig1=uid1->next;sig1;sig1=sig1->next)
                {
                  KBNODE sig2;
 
+                 if(is_deleted_kbnode(sig1))
+                   continue;
+
                  if(sig1->pkt->pkttype==PKT_USER_ID
                     || sig1->pkt->pkttype==PKT_PUBLIC_SUBKEY
                     || sig1->pkt->pkttype==PKT_SECRET_SUBKEY)
@@ -1710,6 +1742,9 @@ collapse_uids( KBNODE *keyblock )
 
                  for(sig2=sig1->next,last=sig1;sig2;last=sig2,sig2=sig2->next)
                    {
+                     if(is_deleted_kbnode(sig2))
+                       continue;
+
                      if(sig2->pkt->pkttype==PKT_USER_ID
                         || sig2->pkt->pkttype==PKT_PUBLIC_SUBKEY
                         || sig2->pkt->pkttype==PKT_SECRET_SUBKEY)
@@ -1723,7 +1758,7 @@ collapse_uids( KBNODE *keyblock )
                        {
                          /* We have a match, so delete the second
                             signature */
-                         remove_kbnode(&uid1,sig2);
+                         delete_kbnode(sig2);
                          sig2=last;
                        }
                    }
@@ -1732,6 +1767,8 @@ collapse_uids( KBNODE *keyblock )
        }
     }
 
+  commit_kbnode(keyblock);
+
   if(any && !opt.quiet)
     {
       const char *key="???";
@@ -2017,11 +2054,14 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
  * append the userid starting with NODE and all signatures to KEYBLOCK.
  */
 static int
-append_uidKBNODE keyblock, KBNODE node, int *n_sigs,
-                                         const char *fname, u32 *keyid )
+append_uid (KBNODE keyblock, KBNODE node, int *n_sigs,
+            const char *fname, u32 *keyid )
 {
     KBNODE n, n_where=NULL;
 
+    (void)fname;
+    (void)keyid;
+
     assert(node->pkt->pkttype == PKT_USER_ID );
 
     /* find the position */
@@ -2069,6 +2109,9 @@ merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
     KBNODE n, n2;
     int found=0;
 
+    (void)fname;
+    (void)keyid;
+
     assert(dst->pkt->pkttype == PKT_USER_ID );
     assert(src->pkt->pkttype == PKT_USER_ID );
 
@@ -2104,12 +2147,15 @@ merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
  * Merge the sigs from SRC onto DST. SRC and DST are both a PKT_xxx_SUBKEY.
  */
 static int
-merge_keysigsKBNODE dst, KBNODE src, int *n_sigs,
-                                   const char *fname, u32 *keyid )
+merge_keysigs (KBNODE dst, KBNODE src, int *n_sigs,
+               const char *fname, u32 *keyid)
 {
     KBNODE n, n2;
     int found=0;
 
+    (void)fname;
+    (void)keyid;
+
     assert(   dst->pkt->pkttype == PKT_PUBLIC_SUBKEY
           || dst->pkt->pkttype == PKT_SECRET_SUBKEY );
 
@@ -2157,11 +2203,14 @@ merge_keysigs( KBNODE dst, KBNODE src, int *n_sigs,
  * Mark all new and copied packets by setting flag bit 0.
  */
 static int
-append_keyKBNODE keyblock, KBNODE node, int *n_sigs,
-                                         const char *fname, u32 *keyid )
+append_key (KBNODE keyblock, KBNODE node, int *n_sigs,
+            const char *fname, u32 *keyid)
 {
     KBNODE n;
 
+    (void)fname;
+    (void)keyid;
+
     assert( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
           || node->pkt->pkttype == PKT_SECRET_SUBKEY );
 
@@ -2355,7 +2404,8 @@ auto_create_card_key_stub ( const char *serialnostr,
     size_t an;
 
     fingerprint_from_pk (pk, afp, &an);
-    memset (afp, 0, MAX_FINGERPRINT_LEN);
+    if (an < MAX_FINGERPRINT_LEN)
+      memset (afp+an, 0, MAX_FINGERPRINT_LEN-an);
     rc = keydb_search_fpr (hd, afp);
   }
 
@@ -2410,4 +2460,3 @@ auto_create_card_key_stub ( const char *serialnostr,
   keydb_release (hd);
   return rc;
 }
-