1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-06-18 00:49:50 +02:00

* photoid.h, photoid.c (parse_image_header, image_type_to_string): Useful

functions to return data about an image.

* packet.h, parse-packet.c (make_attribute_uidname,
parse_attribute_subpkts, parse_attribute), photoid.h, photoid.c
(show_photos): Handle multiple images in a single attribute packet.

* main.h, misc.c (pct_expando), sign.c (mk_notation_and_policy), photoid.c
(show_photos): Simpler expando code that does not require using
compile-time string sizes.  Call image_type_to_string to get image strings
(i.e. "jpg", "image/jpeg").  Change all callers.

* keyedit.c (menu_showphoto), keylist.c (list_keyblock_print): Allow
viewing multiple images within a single attribute packet.

* gpgv.c: Various stubs for link happiness.
This commit is contained in:
David Shaw 2002-05-02 20:47:23 +00:00
parent 0d63a076b0
commit 6dc53d136a
11 changed files with 283 additions and 157 deletions

View File

@ -1,3 +1,24 @@
2002-05-02 David Shaw <dshaw@jabberwocky.com>
* photoid.h, photoid.c (parse_image_header, image_type_to_string):
Useful functions to return data about an image.
* packet.h, parse-packet.c (make_attribute_uidname,
parse_attribute_subpkts, parse_attribute), photoid.h, photoid.c
(show_photos): Handle multiple images in a single attribute
packet.
* main.h, misc.c (pct_expando), sign.c (mk_notation_and_policy),
photoid.c (show_photos): Simpler expando code that does not
require using compile-time string sizes. Call
image_type_to_string to get image strings (i.e. "jpg",
"image/jpeg"). Change all callers.
* keyedit.c (menu_showphoto), keylist.c (list_keyblock_print):
Allow viewing multiple images within a single attribute packet.
* gpgv.c: Various stubs for link happiness.
2002-05-02 David Shaw <dshaw@jabberwocky.com>
* build-packet.c (build_sig_subpkt), keyedit.c (sign_uids),

View File

@ -301,8 +301,10 @@ passphrase_to_dek( u32 *keyid, int pubkey_algo,
return NULL;
}
/* Stub to avoid linking to photoid.c */
void show_photo(const struct user_attribute *attr,PKT_public_key *pk) {}
/* Stubs to avoid linking to photoid.c */
void show_photos(const struct user_attribute *attrs,int count,PKT_public_key *pk) {}
int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len) {return 0;}
char *image_type_to_string(byte type,int string) {return NULL;}
/* Stubs to void linking to ../cipher/cipher.c */
int string_to_cipher_algo( const char *string ) { return 0; }

View File

@ -2131,7 +2131,7 @@ menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
action = selected? 0 : -1;
else /* no */
action = selected? 1 : 0;
if (action) {
int rc = update_keysig_packet (&newsig, sig,
main_pk, uid,
@ -2684,30 +2684,36 @@ menu_showphoto( KBNODE keyblock )
for( node = keyblock; node; node = node->next )
{
if( node->pkt->pkttype == PKT_PUBLIC_KEY )
pk = node->pkt->pkt.public_key;
}
{
pk = node->pkt->pkt.public_key;
keyid_from_pk(pk, keyid);
}
else if( node->pkt->pkttype == PKT_USER_ID )
{
PKT_user_id *uid = node->pkt->pkt.user_id;
count++;
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->attribs!=NULL)
{
int i;
if((select_all || (node->flag & NODFLG_SELUID)) &&
uid->attribs!=NULL)
{
/* Can this really ever happen? */
if(pk==NULL)
keyid[1]=0;
else
keyid_from_pk(pk, keyid);
for(i=0;i<uid->numattribs;i++)
{
byte type;
u32 size;
tty_printf(_("Displaying %s photo ID of size %ld "
"for key 0x%08lX (uid %d)\n"),
"jpeg",uid->attribs->len,(ulong)keyid[1],count);
show_photo(uid->attribs,pk);
}
}
if(uid->attribs[i].type==ATTRIB_IMAGE &&
parse_image_header(&uid->attribs[i],&type,&size))
{
tty_printf(_("Displaying %s photo ID of size %ld for "
"key 0x%08lX (uid %d)\n"),
image_type_to_string(type,1),
(ulong)size,(ulong)keyid[1],count);
show_photos(&uid->attribs[i],1,pk);
}
}
}
}
}
}

View File

@ -399,9 +399,9 @@ list_keyblock_print ( KBNODE keyblock, int secret, int fpr, void *opaque )
any = 1;
}
if(opt.show_photos && node->pkt->pkt.user_id->attribs!=NULL &&
node->pkt->pkt.user_id->attribs->type==ATTRIB_JPEG)
show_photo(node->pkt->pkt.user_id->attribs,pk);
if(opt.show_photos && node->pkt->pkt.user_id->attribs!=NULL)
show_photos(node->pkt->pkt.user_id->attribs,
node->pkt->pkt.user_id->numattribs,pk);
}
else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
u32 keyid2[2];

View File

@ -67,7 +67,14 @@ int openpgp_pk_algo_usage ( int algo );
int openpgp_md_test_algo( int algo );
int check_permissions(const char *path,int extension,int checkonly);
void idea_cipher_warn( int show );
char *pct_expando(const char *string,PKT_public_key *pk);
struct expando_args
{
PKT_public_key *pk;
byte imagetype;
};
char *pct_expando(const char *string,struct expando_args *args);
int hextobyte( const char *s );
/*-- helptext.c --*/

View File

@ -38,6 +38,7 @@
#endif
#include "util.h"
#include "main.h"
#include "photoid.h"
#include "options.h"
#include "i18n.h"
@ -439,55 +440,56 @@ idea_cipher_warn(int show)
}
}
/* The largest string we have an expando for. */
#define LARGEST_EXPANDO (MAX_FINGERPRINT_LEN*2)
/* Expand %-strings. Returns a string which must be m_freed. Returns
NULL if the string cannot be expanded (too large). */
char *
pct_expando(const char *string,PKT_public_key *pk)
pct_expando(const char *string,struct expando_args *args)
{
const char *ch=string;
int idx=0,maxlen;
int idx=0,maxlen=0,done=0;
u32 keyid[2]={0,0};
char *ret;
char *ret=NULL;
keyid_from_pk(pk,keyid);
maxlen=LARGEST_EXPANDO*2;
ret=m_alloc(maxlen+1); /* one more to leave room for the trailing \0 */
ret[0]='\0';
if(args->pk)
keyid_from_pk(args->pk,keyid);
while(*ch!='\0')
{
/* 8192 is way bigger than we'll need here */
if(maxlen-idx<LARGEST_EXPANDO && maxlen<8192)
char *str=NULL;
if(!done)
{
maxlen+=LARGEST_EXPANDO*2;
ret=m_realloc(ret,maxlen+1);
/* 8192 is way bigger than we'll need here */
if(maxlen>=8192)
goto fail;
maxlen+=1024;
ret=m_realloc(ret,maxlen);
}
done=0;
if(*ch=='%')
{
ch++;
switch(*ch)
switch(*(ch+1))
{
case 'k': /* short key id */
if(idx+8>maxlen)
goto fail;
sprintf(&ret[idx],"%08lX",(ulong)keyid[1]);
idx+=8;
if(idx+8<maxlen)
{
sprintf(&ret[idx],"%08lX",(ulong)keyid[1]);
idx+=8;
done=1;
}
break;
case 'K': /* long key id */
if(idx+16>maxlen)
goto fail;
sprintf(&ret[idx],"%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]);
idx+=16;
if(idx+16<maxlen)
{
sprintf(&ret[idx],"%08lX%08lX",
(ulong)keyid[0],(ulong)keyid[1]);
idx+=16;
done=1;
}
break;
case 'f': /* fingerprint */
@ -496,43 +498,46 @@ pct_expando(const char *string,PKT_public_key *pk)
size_t len;
int i;
fingerprint_from_pk(pk,array,&len);
if(args->pk)
fingerprint_from_pk(args->pk,array,&len);
else
memset(array,0,MAX_FINGERPRINT_LEN);
if(idx+(len*2)>maxlen)
goto fail;
for(i=0;i<len;i++)
if(idx+(len*2)<maxlen)
{
sprintf(&ret[idx],"%02X",array[i]);
idx+=2;
for(i=0;i<len;i++)
{
sprintf(&ret[idx],"%02X",array[i]);
idx+=2;
}
done=1;
}
}
break;
/* photo types. For now, it's always jpeg so this is
easy! */
case 't':
if(idx+3>maxlen)
goto fail;
case 't': /* e.g. "jpg" */
str=image_type_to_string(args->imagetype,1);
/* fall through */
strcpy(&ret[idx],"jpg");
idx+=3;
break;
case 'T': /* e.g. "image/jpeg" */
if(str==NULL)
str=image_type_to_string(args->imagetype,2);
case 'T':
if(idx+10>maxlen)
goto fail;
strcpy(&ret[idx],"image/jpeg");
idx+=10;
if(idx+strlen(str)<maxlen)
{
strcpy(&ret[idx],str);
idx+=strlen(str);
done=1;
}
break;
case '%':
if(idx+1>maxlen)
goto fail;
ret[idx++]='%';
ret[idx]='\0';
if(idx+1<maxlen)
{
ret[idx++]='%';
ret[idx]='\0';
done=1;
}
break;
/* Any unknown %-keys (like %i, %o, %I, and %O) are
@ -541,25 +546,31 @@ pct_expando(const char *string,PKT_public_key *pk)
string is a '%' - the terminating \0 will end up here
and properly terminate the string. */
default:
if(idx+2>maxlen)
goto fail;
ret[idx++]='%';
ret[idx++]=*ch;
ret[idx]='\0';
if(idx+2<maxlen)
{
ret[idx++]='%';
ret[idx++]=*(ch+1);
ret[idx]='\0';
done=1;
}
break;
}
}
if(done)
ch++;
}
else
{
if(idx+1>maxlen)
goto fail;
ret[idx++]=*ch;
ret[idx]='\0';
if(idx+1<maxlen)
{
ret[idx++]=*ch;
ret[idx]='\0';
done=1;
}
}
ch++;
if(done)
ch++;
}
return ret;

View File

@ -148,15 +148,11 @@ typedef struct {
MPI data[PUBKEY_MAX_NSIG];
} PKT_signature;
typedef enum
{
ATTRIB_UNKNOWN,
ATTRIB_JPEG
} attribtype_t;
#define ATTRIB_IMAGE 1
/* This is the cooked form of attributes */
struct user_attribute {
attribtype_t type;
byte type;
const byte *data;
unsigned long len;
};

View File

@ -31,6 +31,7 @@
#include "cipher.h"
#include "memory.h"
#include "filter.h"
#include "photoid.h"
#include "options.h"
#include "main.h"
#include "i18n.h"
@ -1739,23 +1740,7 @@ parse_attribute_subpkts(PKT_user_id *uid)
buflen--;
n--;
/* In order: is it an image, is it large enough to carry the
image header, is it version 1, and is it a JPEG? */
if(type==1 && n>=16 && buffer[2]==1 && buffer[3]==1)
{
/* For historical reasons (i.e. "oops!"), headerlen is
little endian. */
u16 headerlen=(buffer[1]<<8) | buffer[0];
attribs[count].type=ATTRIB_JPEG;
buffer+=headerlen;
buflen-=headerlen;
n-=headerlen;
}
else
attribs[count].type=ATTRIB_UNKNOWN;
attribs[count].type=type;
attribs[count].data=buffer;
attribs[count].len=n;
buffer+=n;
@ -1821,14 +1806,29 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
void
make_attribute_uidname(PKT_user_id *uid)
{
/* List the first attribute as the "user id" */
if(uid->attribs)
sprintf( uid->name, "[%s of size %lu]",
uid->attribs->type==ATTRIB_JPEG?"image":"unknown attribute",
uid->attribs->len);
if(uid->numattribs<=0)
sprintf(uid->name,"[bad attribute packet of size %lu]",uid->attrib_len);
else if(uid->numattribs>1)
sprintf(uid->name,"[%d attributes of size %lu]",
uid->numattribs,uid->attrib_len);
else
sprintf( uid->name, "[bad attribute of size %lu]",
uid->attrib_len );
{
/* Only one attribute, so list it as the "user id" */
if(uid->attribs->type==ATTRIB_IMAGE)
{
u32 len;
byte type;
if(parse_image_header(uid->attribs,&type,&len))
sprintf(uid->name,"[%s image of size %lu]",
image_type_to_string(type,1),(ulong)len);
else
sprintf(uid->name,"[invalid image]");
}
else
sprintf(uid->name,"[unknown attribute of size %lu]",uid->attribs->len);
}
uid->len = strlen(uid->name);
}
@ -1838,7 +1838,7 @@ parse_attribute( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
{
byte *p;
packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id + 50);
packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id + 70);
setup_user_id(packet);

View File

@ -116,7 +116,7 @@ PKT_user_id *generate_photo_id(PKT_public_key *pk)
parse_attribute_subpkts(uid);
make_attribute_uidname(uid);
show_photo(uid->attribs,pk);
show_photos(uid->attribs,uid->numattribs,pk);
switch(cpr_get_answer_yes_no_quit("photoid.jpeg.okay",
_("Is this photo correct (y/N/q)? ")))
{
@ -147,31 +147,113 @@ PKT_user_id *generate_photo_id(PKT_public_key *pk)
return uid;
}
void show_photo(const struct user_attribute *attr,PKT_public_key *pk)
/* Returns 0 for error, 1 for valid */
int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len)
{
char *command;
struct exec_info *spawn;
int headerlen;
/* make command grow */
command=
pct_expando(opt.photo_viewer?opt.photo_viewer:DEFAULT_PHOTO_COMMAND,pk);
if(attr->len<3)
return 0;
if(!command)
goto fail;
/* For historical reasons (i.e. "oops!"), the header length is
little endian. */
headerlen=(attr->data[1]<<8) | attr->data[0];
if(exec_write(&spawn,NULL,command,1,1)!=0)
goto fail;
if(headerlen>attr->len)
return 0;
fwrite(attr->data,attr->len,1,spawn->tochild);
if(exec_read(spawn)!=0)
if(type && attr->len>=4)
{
exec_finish(spawn);
goto fail;
if(attr->data[2]==1) /* header version 1 */
*type=attr->data[3];
else
*type=0;
}
if(exec_finish(spawn)!=0)
goto fail;
*len=attr->len-headerlen;
if(*len==0)
return 0;
return 1;
}
/* 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). */
char *image_type_to_string(byte type,int style)
{
char *string;
switch(type)
{
case 1: /* jpeg */
if(style==0)
string="jpg";
else if(style==1)
string="jpeg";
else
string="image/jpeg";
break;
default:
if(style==0)
string="bin";
else if(style==1)
string="unknown";
else
string="image/x-unknown";
break;
}
return string;
}
void show_photos(const struct user_attribute *attrs,
int count,PKT_public_key *pk)
{
int i;
struct expando_args args;
u32 len;
memset(&args,0,sizeof(args));
args.pk=pk;
for(i=0;i<count;i++)
if(attrs[i].type==ATTRIB_IMAGE &&
parse_image_header(&attrs[i],&args.imagetype,&len))
{
char *command;
struct exec_info *spawn;
int offset=attrs[i].len-len;
/* Notice we are not using the byte for 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 which.
The spec specifically permits this, by the way. -dms */
/* make command grow */
command=pct_expando(opt.photo_viewer?
opt.photo_viewer:DEFAULT_PHOTO_COMMAND,&args);
if(!command)
goto fail;
if(exec_write(&spawn,NULL,command,1,1)!=0)
goto fail;
fwrite(&attrs[i].data[offset],attrs[i].len-offset,1,spawn->tochild);
if(exec_read(spawn)!=0)
{
exec_finish(spawn);
goto fail;
}
if(exec_finish(spawn)!=0)
goto fail;
}
return;

View File

@ -6,6 +6,8 @@
#include "packet.h"
PKT_user_id *generate_photo_id(PKT_public_key *pk);
void show_photo(const struct user_attribute *attr,PKT_public_key *pk);
int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len);
char *image_type_to_string(byte type,int style);
void show_photos(const struct user_attribute *attrs,int count,PKT_public_key *pk);
#endif /* !_PHOTOID_H_ */

View File

@ -62,6 +62,10 @@ mk_notation_and_policy( PKT_signature *sig, PKT_public_key *pk )
byte *buf;
unsigned n1, n2;
STRLIST nd=NULL,pu=NULL;
struct expando_args args;
memset(&args,0,sizeof(args));
args.pk=pk;
/* notation data */
if(IS_SIG(sig) && opt.sig_notation_data)
@ -124,18 +128,13 @@ mk_notation_and_policy( PKT_signature *sig, PKT_public_key *pk )
{
string = pu->d;
if(pk)
s=pct_expando(string,&args);
if(!s)
{
s=pct_expando(string,pk);
if(!s)
{
log_error(_("WARNING: unable to %%-expand policy url "
"(too large). Using unexpanded.\n"));
s=m_strdup(string);
}
log_error(_("WARNING: unable to %%-expand policy url "
"(too large). Using unexpanded.\n"));
s=m_strdup(string);
}
else
s=m_strdup(string);
build_sig_subpkt(sig,SIGSUBPKT_POLICY|
((pu->flags & 1)?SIGSUBPKT_FLAG_CRITICAL:0),