Change capitalization of TOR to Tor.
[gnupg.git] / g10 / photoid.c
index 138ecd6..f6e625a 100644 (file)
@@ -1,11 +1,11 @@
 /* photoid.c - photo ID handling code
- * Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2005, 2006, 2008, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
  * GnuPG is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * GnuPG is distributed in the hope that it will be useful,
  * 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
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
-#ifdef __MINGW32__ 
+#ifdef _WIN32
+# ifdef HAVE_WINSOCK2_H
+#  include <winsock2.h>
+# endif
 # include <windows.h>
 # ifndef VER_PLATFORM_WIN32_WINDOWS
 #  define VER_PLATFORM_WIN32_WINDOWS 1
 # endif
 #endif
+
+#include "gpg.h"
+#include "util.h"
 #include "packet.h"
 #include "status.h"
 #include "exec.h"
 #include "keydb.h"
-#include "util.h"
 #include "i18n.h"
 #include "iobuf.h"
-#include "memory.h"
 #include "options.h"
 #include "main.h"
 #include "photoid.h"
+#include "ttyio.h"
+#include "trustdb.h"
 
-/* Generate a new photo id packet, or return NULL if canceled */
-PKT_user_id *generate_photo_id(PKT_public_key *pk)
+/* Generate a new photo id packet, or return NULL if canceled.
+   FIXME:  Should we add a duplicates check similar to generate_user_id? */
+PKT_user_id *
+generate_photo_id(PKT_public_key *pk,const char *photo_name)
 {
   PKT_user_id *uid;
   int error=1,i;
   unsigned int len;
-  char *filename=NULL;
+  char *filename;
   byte *photo=NULL;
   byte header[16];
   IOBUF file;
+  int overflow;
 
   header[0]=0x10; /* little side of photo header length */
   header[1]=0;    /* big side of photo header length */
@@ -59,71 +67,103 @@ PKT_user_id *generate_photo_id(PKT_public_key *pk)
   for(i=4;i<16;i++) /* The reserved bytes */
     header[i]=0;
 
-  uid=m_alloc_clear(sizeof(*uid)+50);
+#define EXTRA_UID_NAME_SPACE 71
+  uid=xmalloc_clear(sizeof(*uid)+71);
 
-  printf(_("\nPick an image to use for your photo ID.  "
-          "The image must be a JPEG file.\n"
-          "Remember that the image is stored within your public key.  "
-          "If you use a\n"
-          "very large picture, your key will become very large as well!\n"
-          "Keeping the image close to 240x288 is a good size to use.\n"));
+  if(photo_name && *photo_name)
+    filename=make_filename(photo_name,(void *)NULL);
+  else
+    {
+      tty_printf(_("\nPick an image to use for your photo ID."
+                  "  The image must be a JPEG file.\n"
+                  "Remember that the image is stored within your public key."
+                  "  If you use a\n"
+                  "very large picture, your key will become very large"
+                  " as well!\n"
+                  "Keeping the image close to 240x288 is a good size"
+                  " to use.\n"));
+      filename=NULL;
+    }
 
   while(photo==NULL)
     {
-      printf("\n");
+      if(filename==NULL)
+       {
+         char *tempname;
 
-      m_free(filename);
+         tty_printf("\n");
 
-      filename=cpr_get("photoid.jpeg.add",
-                      _("Enter JPEG filename for photo ID: "));
+         tty_enable_completion(NULL);
 
-      if(strlen(filename)==0)
-       goto scram;
+         tempname=cpr_get("photoid.jpeg.add",
+                          _("Enter JPEG filename for photo ID: "));
+
+         tty_disable_completion();
+
+         filename=make_filename(tempname,(void *)NULL);
+
+         xfree(tempname);
+
+         if(strlen(filename)==0)
+           goto scram;
+       }
 
       file=iobuf_open(filename);
+      if (file && is_secured_file (iobuf_get_fd (file)))
+        {
+          iobuf_close (file);
+          file = NULL;
+          gpg_err_set_errno (EPERM);
+        }
       if(!file)
        {
-         log_error(_("Unable to open photo \"%s\": %s\n"),
+         log_error(_("unable to open JPEG file '%s': %s\n"),
                    filename,strerror(errno));
+         xfree(filename);
+         filename=NULL;
          continue;
        }
 
-      len=iobuf_get_filelength(file);
-      if(len>6144)
+
+      len=iobuf_get_filelength(file, &overflow);
+      if(len>6144 || overflow)
        {
-         printf("This JPEG is really large (%d bytes) !\n",len);
+         tty_printf( _("This JPEG is really large (%d bytes) !\n"),len);
          if(!cpr_get_answer_is_yes("photoid.jpeg.size",
-                           _("Are you sure you want to use it (y/N)? ")))
+                           _("Are you sure you want to use it? (y/N) ")))
          {
            iobuf_close(file);
+           xfree(filename);
+           filename=NULL;
            continue;
          }
        }
 
-      photo=m_alloc(len);
+      photo=xmalloc(len);
       iobuf_read(file,photo,len);
       iobuf_close(file);
 
       /* Is it a JPEG? */
-      if(photo[0]!=0xFF || photo[1]!=0xD8 ||
-        photo[6]!='J' || photo[7]!='F' || photo[8]!='I' || photo[9]!='F')
+      if(photo[0]!=0xFF || photo[1]!=0xD8)
        {
-         log_error(_("\"%s\" is not a JPEG file\n"),filename);
-         m_free(photo);
+         log_error(_("'%s' is not a JPEG file\n"),filename);
+         xfree(photo);
          photo=NULL;
+         xfree(filename);
+         filename=NULL;
          continue;
        }
 
       /* Build the packet */
       build_attribute_subpkt(uid,1,photo,len,header,16);
       parse_attribute_subpkts(uid);
-      make_attribute_uidname(uid);
+      make_attribute_uidname(uid, EXTRA_UID_NAME_SPACE);
 
       /* Showing the photo is not safe when noninteractive since the
          "user" may not be able to dismiss a viewer window! */
       if(opt.command_fd==-1)
        {
-         show_photos(uid->attribs,uid->numattribs,pk,NULL);
+         show_photos (uid->attribs, uid->numattribs, pk, uid);
          switch(cpr_get_answer_yes_no_quit("photoid.jpeg.okay",
                                         _("Is this photo correct (y/N/q)? ")))
            {
@@ -131,8 +171,10 @@ PKT_user_id *generate_photo_id(PKT_public_key *pk)
              goto scram;
            case 0:
              free_attributes(uid);
-             m_free(photo);
+             xfree(photo);
              photo=NULL;
+             xfree(filename);
+             filename=NULL;
              continue;
            }
        }
@@ -142,13 +184,13 @@ PKT_user_id *generate_photo_id(PKT_public_key *pk)
   uid->ref=1;
 
  scram:
-  m_free(filename);
-  m_free(photo);
+  xfree(filename);
+  xfree(photo);
 
   if(error)
     {
       free_attributes(uid);
-      m_free(uid);
+      xfree(uid);
       return NULL;
     }
 
@@ -188,8 +230,9 @@ int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len)
 
 /* style==0 for extension, 1 for name, 2 for MIME type.  Remember that
    the "name" style string could be used in a user ID name field, so
-   make sure it is not too big (see
-   parse-packet.c:parse_attribute). */
+   make sure it is not too big (see parse-packet.c:parse_attribute).
+   Extensions should be 3 characters long for the best cross-platform
+   compatibility. */
 char *image_type_to_string(byte type,int style)
 {
   char *string;
@@ -221,7 +264,7 @@ char *image_type_to_string(byte type,int style)
 #if !defined(FIXED_PHOTO_VIEWER) && !defined(DISABLE_PHOTO_VIEWER)
 static const char *get_default_photo_command(void)
 {
-#if defined(__MINGW32__)
+#if defined(_WIN32)
   OSVERSIONINFO osvi;
 
   memset(&osvi,0,sizeof(osvi));
@@ -243,23 +286,30 @@ static const char *get_default_photo_command(void)
 }
 #endif
 
-void show_photos(const struct user_attribute *attrs,
-                int count,PKT_public_key *pk,PKT_secret_key *sk)
+void
+show_photos(const struct user_attribute *attrs, int count,
+            PKT_public_key *pk, PKT_user_id *uid)
 {
-#ifndef DISABLE_PHOTO_VIEWER
+#ifdef DISABLE_PHOTO_VIEWER
+  (void)attrs;
+  (void)count;
+  (void)pk;
+  (void)uid;
+#else /*!DISABLE_PHOTO_VIEWER*/
   int i;
   struct expando_args args;
   u32 len;
   u32 kid[2]={0,0};
 
-  memset(&args,0,sizeof(args));
-  args.pk=pk;
-  args.sk=sk;
+  memset (&args, 0, sizeof(args));
+  args.pk = pk;
+  args.validity_info = get_validity_info (pk, uid);
+  args.validity_string = get_validity_string (pk, uid);
+  namehash_from_uid (uid);
+  args.namehash = uid->namehash;
 
-  if(pk)
-    keyid_from_pk(pk,kid);
-  else if(sk)
-    keyid_from_sk(sk,kid);
+  if (pk)
+    keyid_from_pk (pk, kid);
 
   for(i=0;i<count;i++)
     if(attrs[i].type==ATTRIB_IMAGE &&
@@ -281,13 +331,13 @@ void show_photos(const struct user_attribute *attrs,
        if(!command)
          goto fail;
 
-       name=m_alloc(16+strlen(EXTSEP_S)+
+       name=xmalloc(16+strlen(EXTSEP_S)+
                     strlen(image_type_to_string(args.imagetype,0))+1);
 
        /* Make the filename.  Notice we are not using the image
            encoding type for more than cosmetics.  Most external image
            viewers can handle a multitude of types, and even if one
-           cannot understand a partcular type, we have no way to know
+           cannot understand a particular type, we have no way to know
            which.  The spec permits this, by the way. -dms */
 
 #ifdef USE_ONLY_8DOT3
@@ -300,16 +350,16 @@ void show_photos(const struct user_attribute *attrs,
 
        if(exec_write(&spawn,NULL,command,name,1,1)!=0)
          {
-           m_free(name);
+           xfree(name);
            goto fail;
          }
 
 #ifdef __riscos__
-        riscos_set_filetype(spawn->tempfile_in,
-                            image_type_to_string(args.imagetype,2));
+        riscos_set_filetype_by_mimetype(spawn->tempfile_in,
+                                        image_type_to_string(args.imagetype,2));
 #endif
 
-       m_free(name);
+       xfree(name);
 
        fwrite(&attrs[i].data[offset],attrs[i].len-offset,1,spawn->tochild);
 
@@ -326,6 +376,6 @@ void show_photos(const struct user_attribute *attrs,
   return;
 
  fail:
-  log_error("unable to display photo ID!\n");
-#endif
+  log_error(_("unable to display photo ID!\n"));
+#endif /*!DISABLE_PHOTO_VIEWER*/
 }