Photo ID patch

David Shaw dshaw at jabberwocky.com
Sat Jul 28 00:32:01 CEST 2001


Here is a patch to allow displaying the photo user IDs.

This adds two new options:

--show-photos: Turn on displaying photos.  When show-photos is on,
	       photos will be displayed in a --list-keys or
	       --list-sigs listing.

--photo-viewer: Set the command line to use to display photos.  There
		are a few %-expandos that can be used:

    %n is expanded to a temporary file that contains the photo.
    %N is the same as %n, but the file isn't deleted afterwards.
    %k is expanded to the key ID of the key.
    %K is expanded to the long OpenPGP key ID of the key.
    %f is expanded to the fingerprint of the key.
    %% is %, of course.

    If %n or %N is not present, then the photo is supplied to the
    viewer on stdin.

    The default viewer is "xv -name \"KeyID 0x%k\" -"

In the --edit-key menu, there is also a new "photo" command, which
will display any selected photo ID.

This patch is against 1.0.6, with a few lines from CVS included so
that photo IDs aren't all listed as revoked. ;)

If I need to do something to assign the FSF the copyright for this,
let me know.

David

-- 
David Shaw          |  Senior Software Engineer
<dshaw at akamai.com>  |  Live Streaming Guy
617-250-3028        |  Akamai Technologies
-------------- next part --------------
diff -Nur gnupg-1.0.6/g10/Makefile.am gnupg-1.0.6-photoid/g10/Makefile.am
--- gnupg-1.0.6/g10/Makefile.am	Fri Jul 27 17:11:20 2001
+++ gnupg-1.0.6-photoid/g10/Makefile.am	Fri Jul 27 15:28:03 2001
@@ -60,6 +60,7 @@
 	      pkclist.c 	\
 	      skclist.c 	\
 	      pubkey-enc.c	\
+	      photoid.c         \
 	      passphrase.c	\
 	      seckey-cert.c	\
 	      encr-data.c	\
diff -Nur gnupg-1.0.6/g10/g10.c gnupg-1.0.6-photoid/g10/g10.c
--- gnupg-1.0.6/g10/g10.c	Fri Jul 27 17:11:20 2001
+++ gnupg-1.0.6-photoid/g10/g10.c	Fri Jul 27 15:29:51 2001
@@ -164,6 +164,8 @@
     oComment,
     oDefaultComment,
     oThrowKeyid,
+    oShowPhotos,
+    oPhotoViewer,
     oForceV3Sigs,
     oForceMDC,
     oS2KMode,
@@ -320,8 +322,9 @@
     { oDigestAlgo, "digest-algo", 2 , N_("|NAME|use message digest algorithm NAME")},
     { oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")},
     { oThrowKeyid, "throw-keyid", 0, N_("throw keyid field of encrypted packets")},
+    { oShowPhotos,   "show-photos", 0, N_("Show Photo IDs")},
+    { oPhotoViewer,  "photo-viewer", 2, N_("Set command line to view Photo IDs")},
     { oNotation,   "notation-data", 2, N_("|NAME=VALUE|use this notation data")},
-
     { 302, NULL, 0, N_(
   "@\n(See the man page for a complete listing of all commands and options)\n"
 		      )},
@@ -916,6 +919,8 @@
 	  case oComment: opt.comment_string = pargs.r.ret_str; break;
 	  case oDefaultComment: opt.comment_string = NULL; break;
 	  case oThrowKeyid: opt.throw_keyid = 1; break;
+	  case oShowPhotos: opt.show_photos = 1; break;
+ 	  case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break;
 	  case oForceV3Sigs: opt.force_v3_sigs = 1; break;
 	  case oForceMDC: opt.force_mdc = 1; break;
 	  case oS2KMode:   opt.s2k_mode = pargs.r.ret_int; break;
diff -Nur gnupg-1.0.6/g10/keyedit.c gnupg-1.0.6-photoid/g10/keyedit.c
--- gnupg-1.0.6/g10/keyedit.c	Fri Jul 27 17:11:20 2001
+++ gnupg-1.0.6-photoid/g10/keyedit.c	Fri Jul 27 15:50:47 2001
@@ -32,6 +32,7 @@
 #include "iobuf.h"
 #include "keydb.h"
 #include "memory.h"
+#include "photoid.h"
 #include "util.h"
 #include "main.h"
 #include "trustdb.h"
@@ -60,6 +61,7 @@
 static int menu_revsig( KBNODE keyblock );
 static int menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
 static int enable_disable_key( KBNODE keyblock, int disable );
+static void menu_photo( KBNODE keyblock );
 
 #define CONTROL_D ('D' - 'A' + 1)
 
@@ -570,7 +572,7 @@
 	   cmdDEBUG, cmdSAVE, cmdADDUID, cmdDELUID, cmdADDKEY, cmdDELKEY,
 	   cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, cmdEXPIRE,
            cmdENABLEKEY, cmdDISABLEKEY,  cmdSHOWPREF,
-	   cmdINVCMD, cmdNOP };
+	   cmdINVCMD, cmdPHOTO, cmdNOP };
     static struct { const char *name;
 		    enum cmdids id;
 		    int need_sk;
@@ -611,6 +613,7 @@
 	{ N_("revkey")  , cmdREVKEY    , 1,1,0, N_("revoke a secondary key") },
 	{ N_("disable") , cmdDISABLEKEY, 0,1,0, N_("disable a key") },
 	{ N_("enable")  , cmdENABLEKEY , 0,1,0, N_("enable a key") },
+	{ N_("photo")   , cmdPHOTO     , 0,0,0, N_("show photo ID") },
 
     { NULL, cmdNONE } };
     enum cmdids cmd = 0;
@@ -955,6 +958,10 @@
 	    }
 	    break;
 
+	  case cmdPHOTO:
+	    menu_photo(keyblock);
+	    break;
+
 	  case cmdQUIT:
 	    if( have_commands )
 		goto leave;
@@ -2029,3 +2036,45 @@
     return 0;
 }
 
+static void
+menu_photo( KBNODE keyblock )
+{
+  KBNODE node;
+  int select_all = !count_selected_uids(keyblock);
+  int count=0;
+  PKT_public_key *pk=NULL;
+  u32 keyid[2];
+
+  /* Look for the public key first.  We have to be really, really,
+     explicit as to which photo this is, and what key it is a UID on
+     since people may want to sign it. */
+
+  for( node = keyblock; node; node = node->next )
+    {
+      if( node->pkt->pkttype == PKT_PUBLIC_KEY )
+	pk = node->pkt->pkt.public_key;
+    }
+
+  for( node = keyblock; node; node = node->next )
+    {
+      if( node->pkt->pkttype == PKT_USER_ID )
+	{
+	  PKT_user_id *uid = node->pkt->pkt.user_id;
+	  count++;
+
+	  if((select_all || (node->flag & NODFLG_SELUID)) &&
+	     uid->photo!=NULL)
+	    {
+	      /* Can this really ever happen? */
+	      if(pk==NULL)
+		keyid[1]=0;
+	      else
+		keyid_from_pk(pk, keyid);
+
+	      tty_printf("Displaying photo ID of size %d for key 0x%08lX "
+			 "(uid %d)\n",uid->photolen,(ulong)keyid[1],count);
+	      show_photo(uid->photo,uid->photolen,pk);
+	    }
+	}
+    }
+}
diff -Nur gnupg-1.0.6/g10/keylist.c gnupg-1.0.6-photoid/g10/keylist.c
--- gnupg-1.0.6/g10/keylist.c	Fri Jul 27 17:11:20 2001
+++ gnupg-1.0.6-photoid/g10/keylist.c	Fri Jul 27 15:29:02 2001
@@ -30,6 +30,7 @@
 #include "errors.h"
 #include "keydb.h"
 #include "memory.h"
+#include "photoid.h"
 #include "util.h"
 #include "trustdb.h"
 #include "main.h"
@@ -258,6 +259,10 @@
 		    print_key_data( pk, keyid );
 		any = 1;
 	    }
+
+	    if(opt.show_photos && node->pkt->pkt.user_id->photo!=NULL)
+	      show_photo(node->pkt->pkt.user_id->photo,
+			 node->pkt->pkt.user_id->photolen,pk);
 	}
 	else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
 	    u32 keyid2[2];
@@ -667,7 +672,6 @@
             primary = primary2 = node;
             for (node=node->next; node; primary2=node, node = node->next ) {
                 if( node->pkt->pkttype == PKT_USER_ID 
-                    || node->pkt->pkttype == PKT_PHOTO_ID 
                     || node->pkt->pkttype == PKT_PUBLIC_SUBKEY 
                     || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
                     break;
diff -Nur gnupg-1.0.6/g10/options.h gnupg-1.0.6-photoid/g10/options.h
--- gnupg-1.0.6/g10/options.h	Fri Jul 27 17:11:20 2001
+++ gnupg-1.0.6-photoid/g10/options.h	Fri Jul 27 15:23:28 2001
@@ -71,6 +71,8 @@
     const char *set_filename;
     const char *comment_string;
     int throw_keyid;
+    int show_photos;
+    const char *photo_viewer;
     int s2k_mode;
     int s2k_digest_algo;
     int s2k_cipher_algo;
diff -Nur gnupg-1.0.6/g10/options.skel gnupg-1.0.6-photoid/g10/options.skel
--- gnupg-1.0.6/g10/options.skel	Fri Jul 27 17:11:20 2001
+++ gnupg-1.0.6-photoid/g10/options.skel	Fri Jul 27 16:50:42 2001
@@ -114,6 +114,20 @@
 
 honor-http-proxy
 
+# Uncomment this line to display photo user IDs
+# show-photos
 
-
-
+# Use this program to display photo user IDs
+#
+# %n is expanded to a temporary file that contains the photo.
+# %N is the same as %n, but the file isn't deleted afterwards by GnuPG.
+# %k is expanded to the key ID of the key.
+# %K is expanded to the long OpenPGP key ID of the key.
+# %f is expanded to the fingerprint of the key.
+# %% is %, of course.
+#
+# If %n or %N is not present, then the photo is supplied to the viewer
+# on standard input.
+#
+# The default program is "xv -name \"KeyID 0x%k\" -"
+# photo-viewer "xv -name \"KeyID 0x%k\" -"
diff -Nur gnupg-1.0.6/g10/parse-packet.c gnupg-1.0.6-photoid/g10/parse-packet.c
--- gnupg-1.0.6/g10/parse-packet.c	Fri Jul 27 17:11:20 2001
+++ gnupg-1.0.6-photoid/g10/parse-packet.c	Fri Jul 27 15:10:43 2001
@@ -423,7 +423,7 @@
 	rc = parse_user_id(inp, pkttype, pktlen, pkt );
 	break;
       case PKT_PHOTO_ID:
-	pkt->pkttype = pkttype = PKT_USER_ID;  /* must fix it */
+	pkt->pkttype = pkttype = PKT_USER_ID;  /* we store it in the userID */
 	rc = parse_photo_id(inp, pkttype, pktlen, pkt);
 	break;
       case PKT_OLD_COMMENT:
@@ -1625,6 +1625,11 @@
     packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id  + 30);
     sprintf( packet->pkt.user_id->name, "[image of size %lu]", pktlen );
     packet->pkt.user_id->len = strlen(packet->pkt.user_id->name);
+    packet->pkt.user_id->is_primary = 0;
+    packet->pkt.user_id->is_revoked = 0;
+    packet->pkt.user_id->created = 0;
+    packet->pkt.user_id->help_key_usage = 0;
+    packet->pkt.user_id->help_key_expire = 0;
 
     packet->pkt.user_id->photo = m_alloc(sizeof *packet->pkt.user_id + pktlen);
     packet->pkt.user_id->photolen = pktlen;
diff -Nur gnupg-1.0.6/g10/photoid.c gnupg-1.0.6-photoid/g10/photoid.c
--- gnupg-1.0.6/g10/photoid.c	Wed Dec 31 19:00:00 1969
+++ gnupg-1.0.6-photoid/g10/photoid.c	Fri Jul 27 17:13:36 2001
@@ -0,0 +1,179 @@
+#include <config.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include "options.h"
+#include "keydb.h"
+#include "photoid.h"
+
+#define PHOTO_COMMAND_MAXLEN 1024
+
+void show_photo(char *buf,int buflen,PKT_public_key *pk)
+{
+  const char *ch,*shell;
+  char command[PHOTO_COMMAND_MAXLEN]={'\0'};
+  int size=0,tempfile=-1,pair[2]={-1},deletefile=0;
+  char filename[]="gnupg-photo-id-XXXXXX";
+  pid_t child;
+  u32 keyid[2]={0,0};
+
+  keyid_from_pk(pk,keyid);
+
+  shell=getenv("SHELL");
+  if(shell==NULL)
+    shell="/bin/sh";
+
+  ch=opt.photo_viewer?opt.photo_viewer:"xv -name \"KeyID 0x%k\" -";
+
+  /* %-expandos */
+
+  while(*ch!='\0')
+    {
+      if(*ch=='%')
+	{
+	  ch++;
+
+	  switch(*ch)
+	    {
+	    case 'n': /* filename */
+	      deletefile=1;	      
+
+	    case 'N': /* filename without file deletion */
+	      tempfile=mkstemp(filename);
+	      if(tempfile==-1)
+		goto fail;
+
+	      write(tempfile,&buf[22],buflen-22);
+	      close(tempfile);
+
+	      size+=strlen(filename);
+	      if(size>PHOTO_COMMAND_MAXLEN-1)
+		goto fail;
+
+	      strcat(command,filename);
+	      break;
+
+	    case 'k': /* short key id */
+	      if(size+8>PHOTO_COMMAND_MAXLEN-1)
+		goto fail;
+
+	      sprintf(&command[size],"%08lX",(ulong)keyid[1]);
+	      size+=8;
+	      break;
+
+	    case 'K': /* long key id */
+	      if(size+16>PHOTO_COMMAND_MAXLEN-1)
+		goto fail;
+
+	      sprintf(&command[size],"%08lX%08lX",
+		      (ulong)keyid[0],(ulong)keyid[1]);
+	      size+=16;
+	      break;
+
+	    case 'f': /* fingerprint */
+	      {
+		byte array[MAX_FINGERPRINT_LEN];
+		int len,i;
+
+		fingerprint_from_pk(pk,array,&len);
+
+		if(size+(len*2)>PHOTO_COMMAND_MAXLEN-1)
+		  goto fail;
+
+		for(i=0;i<len;i++)
+		  {
+		    sprintf(&command[size],"%02X",array[i]);
+		    size+=2;
+		  }
+	      }
+	      break;
+		
+	      case '%':
+		size++;
+		if(size>PHOTO_COMMAND_MAXLEN-1)
+		  goto fail;
+
+		strcat(command,"%");
+		break;
+
+	      default:
+		ch--;
+		break;
+	      }
+	}
+      else
+	{
+	  command[size++]=*ch;
+	  if(size>PHOTO_COMMAND_MAXLEN-1)
+	    goto fail;
+	}
+
+      ch++;
+    }
+
+  command[PHOTO_COMMAND_MAXLEN-1]='\0';
+
+  if(tempfile==-1 && pipe(pair)==-1)
+      goto fail;
+
+  child=fork();
+  if(child==-1)
+    {
+      if(tempfile==-1)
+	{
+	  close(pair[0]);
+	  close(pair[1]);
+	}
+
+      goto fail;
+    }
+
+  if(child==0)
+    {
+      /* I'm the child */
+
+      if(tempfile==-1)
+	{
+	  close(pair[1]);
+	  if(dup2(pair[0],0)==-1) /* implied close of 0 */
+	    goto fail;
+	}
+
+      execlp(shell,shell,"-c",command,NULL);
+
+      /* If we get this far the exec failed.  Clean up and return. */
+
+      close(pair[0]);
+      goto fail;
+    }
+  else
+    {
+      /* I'm the parent */
+
+      if(tempfile==-1)
+	{
+	  close(pair[0]);
+
+	  /* I'm not quite sure what the first 22 bytes are, but the rest
+	     is straightforward JPEG... */
+
+	  write(pair[1],&buf[22],buflen-22);
+
+	  close(pair[1]);
+	}
+      else
+	waitpid(child,NULL,0); /* Must wait for the child to exit so
+                                  we can unlink the temp file. */
+    }
+
+  if(tempfile>-1 && deletefile)
+    unlink(filename);
+
+  return;
+
+ fail:
+  printf("Unable to display Photo ID!\n");
+}
diff -Nur gnupg-1.0.6/g10/photoid.h gnupg-1.0.6-photoid/g10/photoid.h
--- gnupg-1.0.6/g10/photoid.h	Wed Dec 31 19:00:00 1969
+++ gnupg-1.0.6-photoid/g10/photoid.h	Fri Jul 27 15:25:41 2001
@@ -0,0 +1,6 @@
+#ifndef PHOTOID_H
+#define PHOTOID_H
+
+void show_photo(char *buf,int buflen,PKT_public_key *pk);
+
+#endif /* !PHOTOID_H */


More information about the Gnupg-devel mailing list