1 /* photoid.c - photo ID handling code
2 * Copyright (C) 2001, 2002, 2005, 2006, 2008 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
26 # ifndef VER_PLATFORM_WIN32_WINDOWS
27 # define VER_PLATFORM_WIN32_WINDOWS 1
45 /* Generate a new photo id packet, or return NULL if canceled */
47 generate_photo_id(PKT_public_key
*pk
,const char *photo_name
)
58 header
[0]=0x10; /* little side of photo header length */
59 header
[1]=0; /* big side of photo header length */
60 header
[2]=1; /* 1 == version of photo header */
61 header
[3]=1; /* 1 == JPEG */
63 for(i
=4;i
<16;i
++) /* The reserved bytes */
66 #define EXTRA_UID_NAME_SPACE 71
67 uid
=xmalloc_clear(sizeof(*uid
)+71);
69 if(photo_name
&& *photo_name
)
70 filename
=make_filename(photo_name
,(void *)NULL
);
73 tty_printf(_("\nPick an image to use for your photo ID."
74 " The image must be a JPEG file.\n"
75 "Remember that the image is stored within your public key."
77 "very large picture, your key will become very large"
79 "Keeping the image close to 240x288 is a good size"
92 tty_enable_completion(NULL
);
94 tempname
=cpr_get("photoid.jpeg.add",
95 _("Enter JPEG filename for photo ID: "));
97 tty_disable_completion();
99 filename
=make_filename(tempname
,(void *)NULL
);
103 if(strlen(filename
)==0)
107 file
=iobuf_open(filename
);
108 if (file
&& is_secured_file (iobuf_get_fd (file
)))
116 log_error(_("unable to open JPEG file `%s': %s\n"),
117 filename
,strerror(errno
));
124 len
=iobuf_get_filelength(file
, &overflow
);
125 if(len
>6144 || overflow
)
127 tty_printf( _("This JPEG is really large (%d bytes) !\n"),len
);
128 if(!cpr_get_answer_is_yes("photoid.jpeg.size",
129 _("Are you sure you want to use it? (y/N) ")))
139 iobuf_read(file
,photo
,len
);
143 if(photo
[0]!=0xFF || photo
[1]!=0xD8 ||
144 photo
[6]!='J' || photo
[7]!='F' || photo
[8]!='I' || photo
[9]!='F')
146 log_error(_("`%s' is not a JPEG file\n"),filename
);
154 /* Build the packet */
155 build_attribute_subpkt(uid
,1,photo
,len
,header
,16);
156 parse_attribute_subpkts(uid
);
157 make_attribute_uidname(uid
, EXTRA_UID_NAME_SPACE
);
159 /* Showing the photo is not safe when noninteractive since the
160 "user" may not be able to dismiss a viewer window! */
161 if(opt
.command_fd
==-1)
163 show_photos(uid
->attribs
,uid
->numattribs
,pk
,NULL
,uid
);
164 switch(cpr_get_answer_yes_no_quit("photoid.jpeg.okay",
165 _("Is this photo correct (y/N/q)? ")))
170 free_attributes(uid
);
189 free_attributes(uid
);
197 /* Returns 0 for error, 1 for valid */
198 int parse_image_header(const struct user_attribute
*attr
,byte
*type
,u32
*len
)
205 /* For historical reasons (i.e. "oops!"), the header length is
207 headerlen
=(attr
->data
[1]<<8) | attr
->data
[0];
209 if(headerlen
>attr
->len
)
212 if(type
&& attr
->len
>=4)
214 if(attr
->data
[2]==1) /* header version 1 */
220 *len
=attr
->len
-headerlen
;
228 /* style==0 for extension, 1 for name, 2 for MIME type. Remember that
229 the "name" style string could be used in a user ID name field, so
230 make sure it is not too big (see parse-packet.c:parse_attribute).
231 Extensions should be 3 characters long for the best cross-platform
233 char *image_type_to_string(byte type
,int style
)
254 string
="image/x-unknown";
261 #if !defined(FIXED_PHOTO_VIEWER) && !defined(DISABLE_PHOTO_VIEWER)
262 static const char *get_default_photo_command(void)
267 memset(&osvi
,0,sizeof(osvi
));
268 osvi
.dwOSVersionInfoSize
=sizeof(osvi
);
271 if(osvi
.dwPlatformId
==VER_PLATFORM_WIN32_WINDOWS
)
272 return "start /w %i";
274 return "cmd /c start /w %i";
275 #elif defined(__APPLE__)
276 /* OS X. This really needs more than just __APPLE__. */
278 #elif defined(__riscos__)
279 return "Filer_Run %I";
281 return "xloadimage -fork -quiet -title 'KeyID 0x%k' stdin";
287 show_photos(const struct user_attribute
*attrs
,
288 int count
,PKT_public_key
*pk
,PKT_secret_key
*sk
,
291 #ifndef DISABLE_PHOTO_VIEWER
293 struct expando_args args
;
297 memset(&args
,0,sizeof(args
));
300 args
.validity_info
=get_validity_info(pk
,uid
);
301 args
.validity_string
=get_validity_string(pk
,uid
);
304 keyid_from_pk(pk
,kid
);
306 keyid_from_sk(sk
,kid
);
309 if(attrs
[i
].type
==ATTRIB_IMAGE
&&
310 parse_image_header(&attrs
[i
],&args
.imagetype
,&len
))
313 struct exec_info
*spawn
;
314 int offset
=attrs
[i
].len
-len
;
316 #ifdef FIXED_PHOTO_VIEWER
317 opt
.photo_viewer
=FIXED_PHOTO_VIEWER
;
319 if(!opt
.photo_viewer
)
320 opt
.photo_viewer
=get_default_photo_command();
323 /* make command grow */
324 command
=pct_expando(opt
.photo_viewer
,&args
);
328 name
=xmalloc(16+strlen(EXTSEP_S
)+
329 strlen(image_type_to_string(args
.imagetype
,0))+1);
331 /* Make the filename. Notice we are not using the image
332 encoding type for more than cosmetics. Most external image
333 viewers can handle a multitude of types, and even if one
334 cannot understand a particular type, we have no way to know
335 which. The spec permits this, by the way. -dms */
337 #ifdef USE_ONLY_8DOT3
338 sprintf(name
,"%08lX" EXTSEP_S
"%s",(ulong
)kid
[1],
339 image_type_to_string(args
.imagetype
,0));
341 sprintf(name
,"%08lX%08lX" EXTSEP_S
"%s",(ulong
)kid
[0],(ulong
)kid
[1],
342 image_type_to_string(args
.imagetype
,0));
345 if(exec_write(&spawn
,NULL
,command
,name
,1,1)!=0)
352 riscos_set_filetype_by_mimetype(spawn
->tempfile_in
,
353 image_type_to_string(args
.imagetype
,2));
358 fwrite(&attrs
[i
].data
[offset
],attrs
[i
].len
-offset
,1,spawn
->tochild
);
360 if(exec_read(spawn
)!=0)
366 if(exec_finish(spawn
)!=0)
373 log_error(_("unable to display photo ID!\n"));