static int pgp_send_menu (int bits, int *redraw)
{
- char *p;
- char *micalg = NULL;
+ pgp_key_t *p;
char input_signas[SHORT_STRING];
char input_micalg[SHORT_STRING];
- KEYINFO *secring;
struct pgp_vinfo *pgp = pgp_get_vinfo(PGP_SIGN);
break;
case 3: /* sign (a)s */
+
unset_option(OPTPGPCHECKTRUST);
- if(pgp)
+ if (pgp && (p = pgp_ask_for_key (pgp, _("Sign as: "), NULL, KEYFLAG_CANSIGN, PGP_PUBRING)))
{
- if(!(secring = pgp->read_secring(pgp)))
- {
- mutt_error _("Can't open your secret key ring!");
- bits &= ~PGPSIGN;
- }
- else
- {
- if ((p = pgp_ask_for_key (pgp, secring, _("Sign as: "),
- NULL, KEYFLAG_CANSIGN, &micalg)))
- {
- snprintf (input_signas, sizeof (input_signas), "0x%s", p);
- safe_free((void **) &PgpSignAs);
- PgpSignAs = safe_strdup(input_signas);
- safe_free((void **) &PgpSignMicalg);
- PgpSignMicalg = micalg; /* micalg is malloc()ed by pgp_ask_for_key */
- pgp_void_passphrase (); /* probably need a different passphrase */
- safe_free ((void **) &p);
- bits |= PGPSIGN;
- }
-
- pgp_close_keydb(&secring);
- *redraw = REDRAW_FULL;
- }
+ snprintf (input_signas, sizeof (input_signas), "0x%s", pgp_keyid (p));
+ safe_free((void **) &PgpSignAs); PgpSignAs = safe_strdup (input_signas);
+ safe_free((void **) &PgpSignMicalg); PgpSignMicalg = safe_strdup (pgp_pkalg_to_mic (p->algorithm));
+ pgp_free_key (&p);
+
+ bits |= PGPSIGN;
+
+ pgp_void_passphrase (); /* probably need a different passphrase */
}
else
{
bits &= ~PGPSIGN;
mutt_error _("An unkown PGP version was defined for signing.");
}
+
+ *redraw = REDRAW_FULL;
break;
case 4: /* (b)oth */
break;
case 5: /* select (m)ic algorithm */
- if(!(bits & PGPSIGN))
+ if (!(bits & PGPSIGN))
mutt_error _("This doesn't make sense if you don't want to sign the message.");
else
{
/* Copy the existing MIC algorithm into place */
- strfcpy(input_micalg, NONULL(PgpSignMicalg), sizeof(input_micalg));
+ strfcpy(input_micalg, NONULL (PgpSignMicalg), sizeof (input_micalg));
- if(mutt_get_field (_("MIC algorithm: "), input_micalg, sizeof(input_micalg), 0) == 0)
+ if (mutt_get_field (_("MIC algorithm: "), input_micalg, sizeof (input_micalg), 0) == 0)
{
- if(mutt_strcasecmp(input_micalg, "pgp-md5") && mutt_strcasecmp(input_micalg, "pgp-sha1")
- && mutt_strcasecmp(input_micalg, "pgp-rmd160"))
+ if (mutt_strcasecmp (input_micalg, "pgp-md5") && mutt_strcasecmp (input_micalg, "pgp-sha1")
+ && mutt_strcasecmp (input_micalg, "pgp-rmd160"))
{
mutt_error _("Unknown MIC algorithm, valid ones are: pgp-md5, pgp-sha1, pgp-rmd160");
}
else
{
- safe_free((void **) &PgpSignMicalg);
- PgpSignMicalg = safe_strdup(input_micalg);
+ safe_free ((void **) &PgpSignMicalg);
+ PgpSignMicalg = safe_strdup (input_micalg);
}
}
}
/*
* Copyright (C) 1998 Werner Koch <werner.koch@guug.de>
+ * Copyright (C) 1999 Thomas Roessler <roessler@guug.de>
*
- * This program 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
- * (at your option) any later version.
+ * This program 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 (at your option) any later
+ * version.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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., 675 Mass Ave, Cambridge, MA
+ * 02139, USA.
*/
* - signature class
*/
-static KEYINFO *parse_pub_line( char *buf, int *is_subkey )
+static pgp_key_t *parse_pub_line (char *buf, int *is_subkey, pgp_key_t *k)
{
- KEYINFO *k=NULL;
- PGPUID *uid = NULL;
- int field = 0;
- char *pend, *p;
- int trust = 0;
-
- *is_subkey = 0;
- if( !*buf )
- return NULL;
- for( p = buf; p; p = pend ) {
- if( (pend = strchr(p, ':')) )
- *pend++ = 0;
- field++;
- if( field > 1 && !*p )
- continue;
-
- switch( field ) {
- case 1: /* record type */
- if( !mutt_strcmp(p,"pub") )
- ;
- else if( !mutt_strcmp(p,"sub") )
- *is_subkey = 1;
- else if( !mutt_strcmp(p,"sec") )
- ;
- else if( !mutt_strcmp(p,"ssb") )
- *is_subkey = 1;
- else
- return NULL;
- k = safe_malloc( sizeof(KEYINFO) );
- memset(k, 0, sizeof(KEYINFO) );
- break;
- case 2: /* trust info */
- switch( *p ) { /* look only at the first letter */
- case 'e': k->flags |= KEYFLAG_EXPIRED; break;
- case 'n': trust = 1; break;
- case 'm': trust = 2; break;
- case 'f': trust = 3; break;
- case 'u': trust = 3; break;
- case 'r': k->flags |= KEYFLAG_REVOKED; break;
- }
- break;
- case 3: /* key length */
- k->keylen = atoi(p); /* fixme: add validation checks */
- break;
- case 4: /* pubkey algo */
- k->algorithm = pgp_pkalgbytype(atoi(p));
- k->flags |= pgp_get_abilities(atoi(p));
- break;
- case 5: /* 16 hex digits with the long keyid. */
- /* We really should do a check here */
- k->keyid = safe_strdup(p);
- break;
- case 6: /* timestamp (1998-02-28) */
- break;
- case 7: /* valid for n days */
+ pgp_uid_t *uid = NULL;
+ int field = 0, is_uid = 0;
+ char *pend, *p;
+ int trust = 0;
+
+ *is_subkey = 0;
+ if (!*buf)
+ return NULL;
+ for (p = buf; p; p = pend)
+ {
+ if ((pend = strchr (p, ':')))
+ *pend++ = 0;
+ field++;
+ if (field > 1 && !*p)
+ continue;
+
+ switch (field)
+ {
+ case 1: /* record type */
+ {
+ if (!mutt_strcmp (p, "pub"))
+ ;
+ else if (!mutt_strcmp (p, "sub"))
+ *is_subkey = 1;
+ else if (!mutt_strcmp (p, "sec"))
+ ;
+ else if (!mutt_strcmp (p, "ssb"))
+ *is_subkey = 1;
+ else if (!mutt_strcmp (p, "uid"))
+ is_uid = 1;
+ else
+ return NULL;
+
+ if (!is_uid)
+ k = safe_calloc (sizeof (pgp_key_t), 1);
+
+ break;
+ }
+ case 2: /* trust info */
+ /*
+ * XXX - is this the owner-trust field?
+ *
+ * Actually, we'd need the trust gpg has into the
+ * association between a user ID and a key.
+ *
+ * - tlr
+ */
+ {
+ switch (*p)
+ { /* look only at the first letter */
+ case 'e':
+ k->flags |= KEYFLAG_EXPIRED;
break;
- case 8: /* Local id */
+ case 'n':
+ trust = 1;
break;
- case 9: /* ownertrust */
+ case 'm':
+ trust = 2;
break;
- case 10: /* name */
- if( !pend || !*p )
- break; /* empty field or no trailing colon */
- k->address = mutt_new_list();
- k->address->data = safe_malloc( sizeof(PGPUID) );
- uid = (PGPUID *)k->address->data;
- uid->addr = safe_strdup(p);
- uid->trust = trust;
+ case 'f':
+ trust = 3;
break;
- case 11: /* signature class */
+ case 'u':
+ trust = 3;
break;
- default:
+ case 'r':
+ k->flags |= KEYFLAG_REVOKED;
break;
}
+ break;
+ }
+ case 3: /* key length */
+ {
+ k->keylen = atoi (p); /* fixme: add validation checks */
+ break;
+ }
+ case 4: /* pubkey algo */
+ {
+ k->algorithm = pgp_pkalgbytype (atoi (p));
+ k->flags |= pgp_get_abilities (atoi (p));
+ break;
+ }
+ case 5: /* 16 hex digits with the long keyid. */
+ {
+ /* We really should do a check here */
+ k->keyid = safe_strdup (p);
+ break;
+
+ }
+ case 6: /* timestamp (1998-02-28) */
+ break;
+ case 7: /* valid for n days */
+ break;
+ case 8: /* Local id */
+ break;
+ case 9: /* ownertrust */
+ break;
+ case 10: /* name */
+ {
+ if (!pend || !*p)
+ break; /* empty field or no trailing colon */
+ uid = safe_calloc (sizeof (pgp_uid_t), 1);
+ uid->addr = safe_strdup (p);
+ uid->trust = trust;
+ uid->parent = k;
+ uid->next = k->address;
+ k->address = uid;
+
+ if (strstr (p, "ENCR"))
+ k->flags |= KEYFLAG_PREFER_ENCRYPTION;
+ if (strstr (p, "SIGN"))
+ k->flags |= KEYFLAG_PREFER_SIGNING;
+
+ break;
+ }
+ case 11: /* signature class */
+ break;
+ default:
+ break;
}
- return k;
+ }
+ return k;
}
-static pid_t gpg_invoke_list_keys(struct pgp_vinfo *pgp,
- FILE **pgpin, FILE **pgpout, FILE **pgperr,
- int pgpinfd, int pgpoutfd, int pgperrfd,
- const char *uids, int secret)
+static pid_t gpg_invoke_list_keys (struct pgp_vinfo *pgp,
+ FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
+ int pgpinfd, int pgpoutfd, int pgperrfd,
+ pgp_ring_t keyring,
+ LIST * hints)
{
char cmd[HUGE_STRING];
char tmpcmd[HUGE_STRING];
- char *cp;
- char *keylist;
-
+
/* we use gpgm here */
- snprintf(cmd, sizeof(cmd),
- "%sm --no-verbose --batch --with-colons --list-%skeys ",
- NONULL(*pgp->binary), secret? "secret-":"");
+ snprintf (cmd, sizeof (cmd),
+ "%sm --no-verbose --batch --with-colons --list-%skeys ",
+ NONULL (*pgp->binary), keyring == PGP_SECRING ? "secret-" : "");
- keylist = safe_strdup(uids);
- for(cp = strtok(keylist, " "); cp ; cp = strtok(NULL, " "))
+ for (; hints; hints = hints->next)
{
- snprintf(tmpcmd, sizeof(tmpcmd), "%s %s",
- cmd, cp);
- strcpy(cmd, tmpcmd);
+ snprintf (tmpcmd, sizeof (tmpcmd), "%s %s", cmd, (char *) hints->data);
+ strcpy (cmd, tmpcmd);
}
- safe_free((void **) &keylist);
- return mutt_create_filter_fd(cmd, pgpin, pgpout, pgperr,
- pgpinfd, pgpoutfd, pgperrfd);
+
+ return mutt_create_filter_fd (cmd, pgpin, pgpout, pgperr,
+ pgpinfd, pgpoutfd, pgperrfd);
}
-static KEYINFO *read_ring(struct pgp_vinfo *pgp, int secret )
+pgp_key_t *gpg_get_candidates (struct pgp_vinfo * pgp, pgp_ring_t keyring,
+ LIST * hints)
{
- FILE *fp;
- pid_t thepid;
- char buf[LONG_STRING];
- KEYINFO *db = NULL, **kend, *k = NULL, *kk, *mainkey=NULL;
- int is_sub;
- int devnull;
-
- if((devnull = open("/dev/null", O_RDWR)) == -1)
- return NULL;
-
- thepid = gpg_invoke_list_keys(pgp, NULL, &fp, NULL, -1, -1, devnull,
- NULL, secret);
- if( thepid == -1 )
- {
- close(devnull);
- return NULL;
- }
+ FILE *fp;
+ pid_t thepid;
+ char buf[LONG_STRING];
+ pgp_key_t *db = NULL, **kend, *k = NULL, *kk, *mainkey = NULL;
+ int is_sub;
+ int devnull;
- kend = &db;
- k = NULL;
- while( fgets( buf, sizeof(buf)-1, fp ) ) {
- kk = parse_pub_line(buf, &is_sub );
- if( !kk )
- continue;
- if( k )
- kend = &k->next;
- *kend = k = kk;
-
- if( is_sub ) {
- k->flags |= KEYFLAG_SUBKEY;
- k->mainkey = mainkey;
- }
- else
- mainkey = k;
- }
- if( ferror(fp) )
- mutt_perror("fgets");
+ if ((devnull = open ("/dev/null", O_RDWR)) == -1)
+ return NULL;
- fclose( fp );
- mutt_wait_filter( thepid );
+ thepid = gpg_invoke_list_keys (pgp, NULL, &fp, NULL, -1, -1, devnull,
+ keyring, hints);
+ if (thepid == -1)
+ {
+ close (devnull);
+ return NULL;
+ }
- close(devnull);
-
- return db;
-}
+ kend = &db;
+ k = NULL;
+ while (fgets (buf, sizeof (buf) - 1, fp))
+ {
+ kk = parse_pub_line (buf, &is_sub, k);
+ if (!kk)
+ continue;
+ /* Only append kk to the list if it's new. */
+ if (kk != k)
+ {
+ if (k)
+ kend = &k->next;
+ *kend = k = kk;
+
+ if (is_sub)
+ {
+ k->flags |= KEYFLAG_SUBKEY;
+ k->parent = mainkey;
+ }
+ else
+ mainkey = k;
+ }
+ }
+ if (ferror (fp))
+ mutt_perror ("fgets");
-KEYINFO *gpg_read_pubring(struct pgp_vinfo *pgp)
-{
- return read_ring( pgp, 0 );
-}
+ fclose (fp);
+ mutt_wait_filter (thepid);
+ close (devnull);
-KEYINFO *gpg_read_secring(struct pgp_vinfo *pgp)
-{
- return read_ring( pgp, 1 );
+ return db;
}
+
else if (b->type == TYPEAPPLICATION)
{
if (mutt_is_application_pgp(b))
- handler = application_pgp_handler;
+ handler = pgp_application_pgp_handler;
}
#endif /* _PGPPATH */
{
return a ? strlen (a) : 0;
}
+
+const char *mutt_stristr (const char *haystack, const char *needle)
+{
+ const char *p, *q;
+
+ if (!haystack)
+ return NULL;
+ if (!needle)
+ return (haystack);
+
+ while (*(p = haystack))
+ {
+ for (q = needle; *p && *q && tolower (*p) == tolower (*q); p++, q++)
+ ;
+ if (!*q)
+ return (haystack);
+ haystack++;
+ }
+ return NULL;
+}
{ PGP_V2,
"pgp2",
&PgpV2, &PgpV2Pubring, &PgpV2Secring, &PgpV2Language,
- pgp_read_pubring, pgp_read_secring,
+ pgp_get_candidates,
pgp_v2_invoke_decode, pgp_v2_invoke_verify, pgp_v2_invoke_decrypt,
pgp_v2_invoke_sign, pgp_v2_invoke_encrypt, pgp_v2_invoke_import,
pgp_v2_invoke_export, pgp_v2_invoke_verify_key
{ PGP_V3,
"pgp3",
&PgpV3, &PgpV3Pubring, &PgpV3Secring, &PgpV3Language,
- pgp_read_pubring, pgp_read_secring,
+ pgp_get_candidates,
pgp_v3_invoke_decode, pgp_v3_invoke_verify, pgp_v3_invoke_decrypt,
pgp_v3_invoke_sign, pgp_v3_invoke_encrypt, pgp_v3_invoke_import,
pgp_v3_invoke_export, pgp_v3_invoke_verify_key
{ PGP_V3,
"pgp5",
&PgpV3, &PgpV3Pubring, &PgpV3Secring, &PgpV3Language,
- pgp_read_pubring, pgp_read_secring,
+ pgp_get_candidates,
pgp_v3_invoke_decode, pgp_v3_invoke_verify, pgp_v3_invoke_decrypt,
pgp_v3_invoke_sign, pgp_v3_invoke_encrypt, pgp_v3_invoke_import,
pgp_v3_invoke_export, pgp_v3_invoke_verify_key
{ PGP_GPG,
"gpg",
&PgpGpg, &PgpGpgDummy, &PgpGpgDummy, &PgpGpgDummy,
- gpg_read_pubring, gpg_read_secring,
+ gpg_get_candidates,
pgp_gpg_invoke_decode, pgp_gpg_invoke_verify, pgp_gpg_invoke_decrypt,
pgp_gpg_invoke_sign, pgp_gpg_invoke_encrypt, pgp_gpg_invoke_import,
pgp_gpg_invoke_export, pgp_gpg_invoke_verify_key
return NULL;
}
-char *pgp_keyid(KEYINFO *k)
+char *pgp_keyid(pgp_key_t *k)
{
- if((k->flags & KEYFLAG_SUBKEY) && k->mainkey)
- k = k->mainkey;
+ if((k->flags & KEYFLAG_SUBKEY) && k->parent)
+ k = k->parent;
return _pgp_keyid(k);
}
-char *_pgp_keyid(KEYINFO *k)
+char *_pgp_keyid(pgp_key_t *k)
{
if(option(OPTPGPLONGIDS))
return k->keyid;
/* Support for the Application/PGP Content Type. */
-void application_pgp_handler (BODY *m, STATE *s)
+void pgp_application_pgp_handler (BODY *m, STATE *s)
{
int needpass = -1, pgp_keyblock = 0;
int clearsign = 0;
*/
char *pgp_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc)
{
- char *key, *keyID, *keylist = NULL;
+ char *keyID, *keylist = NULL;
size_t keylist_size = 0;
size_t keylist_used = 0;
ADDRESS *tmp = NULL;
ADDRESS **last = &tmp;
ADDRESS *p;
int i;
- KEYINFO *db;
- KEYINFO *k_info;
- struct pgp_vinfo *pgp = pgp_get_vinfo(PGP_ENCRYPT);
+ pgp_key_t *k_info, *key;
+ struct pgp_vinfo *pgp = pgp_get_vinfo (PGP_ENCRYPT);
- if(!pgp)
+ if (!pgp)
return NULL;
- db = pgp->read_pubring(pgp);
-
for (i = 0; i < 3; i++)
{
switch (i)
{
snprintf (buf, sizeof (buf), _("Use keyID = \"%s\" for %s?"), keyID, p->mailbox);
if (mutt_yesorno (buf, M_YES) == M_YES)
- k_info = ki_getkeybystr (pgp, keyID, db, KEYFLAG_CANENCRYPT);
+ k_info = pgp_getkeybystr (pgp, keyID, KEYFLAG_CANENCRYPT, PGP_PUBRING);
}
- if (k_info == NULL && (k_info = ki_getkeybyaddr (pgp, p, db, KEYFLAG_CANENCRYPT)) == NULL)
+
+ if (k_info == NULL && (k_info = pgp_getkeybyaddr (pgp, p, KEYFLAG_CANENCRYPT, PGP_PUBRING)) == NULL)
{
snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), p->mailbox);
- if ((key = pgp_ask_for_key (pgp, db, buf, p->mailbox,
- KEYFLAG_CANENCRYPT, NULL)) == NULL)
+ if ((key = pgp_ask_for_key (pgp, buf, p->mailbox,
+ KEYFLAG_CANENCRYPT, PGP_PUBRING)) == NULL)
{
- pgp_close_keydb (&db);
safe_free ((void **)&keylist);
rfc822_free_address (&tmp);
return NULL;
}
}
else
- key = pgp_keyid(k_info);
+ key = k_info;
- keylist_size += mutt_strlen (key) + 4;
+ keyID = pgp_keyid (key);
+ pgp_free_key (&key);
+
+ keylist_size += mutt_strlen (keyID) + 4;
safe_realloc ((void **)&keylist, keylist_size);
sprintf (keylist + keylist_used, "%s0x%s", keylist_used ? " " : "",
- key);
+ keyID);
keylist_used = mutt_strlen (keylist);
}
rfc822_free_address (&tmp);
- pgp_close_keydb (&db);
return (keylist);
}
/*
* Copyright (C) 1996,1997 Michael R. Elkins <me@cs.hmc.edu>
- *
+ * Copyright (C) 1999 Thoms Roessler <roessler@guug.de>
+ *
* This program 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
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
+ */
#ifdef _PGPPATH
#define KEYFLAG_PREFER_ENCRYPTION (1 << 13)
#define KEYFLAG_PREFER_SIGNING (1 << 14)
-typedef struct keyinfo
+#define KEYFLAG_CANTUSE (KEYFLAG_DISABLED|KEYFLAG_REVOKED|KEYFLAG_EXPIRED)
+
+typedef struct pgp_keyinfo
{
char *keyid;
- LIST *address;
+ struct pgp_uid *address;
short flags;
short keylen;
unsigned long gen_time;
const char *algorithm;
- struct keyinfo *mainkey;
- struct keyinfo *next;
-} KEYINFO;
+ struct pgp_keyinfo *parent;
+ struct pgp_keyinfo *next;
+}
+pgp_key_t;
typedef struct pgp_uid
{
char *addr;
short trust;
-} PGPUID;
+ struct pgp_keyinfo *parent;
+ struct pgp_uid *next;
+}
+pgp_uid_t;
-enum pgp_version
+enum pgp_version
{
- PGP_V2,
+ PGP_V2,
PGP_V3,
PGP_GPG,
PGP_UNKNOWN
};
+enum pgp_ring
+{
+ PGP_PUBRING,
+ PGP_SECRING
+};
+
+typedef enum pgp_ring pgp_ring_t;
+
enum pgp_ops
{
- PGP_DECODE, /* application/pgp */
- PGP_VERIFY, /* PGP/MIME, signed */
- PGP_DECRYPT, /* PGP/MIME, encrypted */
- PGP_SIGN, /* sign data */
- PGP_ENCRYPT, /* encrypt data */
- PGP_IMPORT, /* extract keys from messages */
- PGP_VERIFY_KEY, /* verify key when selecting */
- PGP_EXPORT, /* extract keys from key ring */
+ PGP_DECODE, /* application/pgp */
+ PGP_VERIFY, /* PGP/MIME, signed */
+ PGP_DECRYPT, /* PGP/MIME, encrypted */
+ PGP_SIGN, /* sign data */
+ PGP_ENCRYPT, /* encrypt data */
+ PGP_IMPORT, /* extract keys from messages */
+ PGP_VERIFY_KEY, /* verify key when selecting */
+ PGP_EXPORT, /* extract keys from key ring */
PGP_LAST_OP
};
struct pgp_vinfo
{
-
+
/* data */
-
+
enum pgp_version v;
char *name;
char **binary;
char **pubring;
char **secring;
char **language;
-
+
/* functions */
+
+ pgp_key_t *(*get_candidates) (struct pgp_vinfo *, pgp_ring_t, LIST *);
- KEYINFO * (*read_pubring)(struct pgp_vinfo *);
- KEYINFO * (*read_secring)(struct pgp_vinfo *);
-
- pid_t (*invoke_decode)(struct pgp_vinfo *, FILE **, FILE **, FILE **,
- int, int, int,
- const char *, int);
+ pid_t (*invoke_decode) (struct pgp_vinfo *, FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *, int);
- pid_t (*invoke_verify)(struct pgp_vinfo *, FILE **, FILE **, FILE **,
- int, int, int,
- const char *, const char *);
+ pid_t (*invoke_verify) (struct pgp_vinfo *, FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *, const char *);
- pid_t (*invoke_decrypt)(struct pgp_vinfo *, FILE **, FILE **, FILE **,
- int, int, int,
- const char *);
+ pid_t (*invoke_decrypt) (struct pgp_vinfo *, FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
- pid_t (*invoke_sign)(struct pgp_vinfo *, FILE **, FILE **, FILE **,
- int, int, int,
- const char *);
-
- pid_t (*invoke_encrypt)(struct pgp_vinfo *, FILE **, FILE **, FILE **,
- int, int, int,
- const char *, const char *, int);
+ pid_t (*invoke_sign) (struct pgp_vinfo *, FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
- void (*invoke_import)(struct pgp_vinfo *, const char *);
+ pid_t (*invoke_encrypt) (struct pgp_vinfo *, FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *, const char *, int);
- pid_t (*invoke_export)(struct pgp_vinfo *, FILE **, FILE **, FILE **,
- int, int, int,
- const char *);
+ void (*invoke_import) (struct pgp_vinfo *, const char *);
- pid_t (*invoke_verify_key)(struct pgp_vinfo *, FILE **, FILE **, FILE **,
+ pid_t (*invoke_export) (struct pgp_vinfo *, FILE **, FILE **, FILE **,
int, int, int,
const char *);
+ pid_t (*invoke_verify_key) (struct pgp_vinfo *, FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
+
};
WHERE short PgpTimeout;
-
-
BODY *pgp_decrypt_part (BODY *, STATE *, FILE *);
BODY *pgp_make_key_attachment (char *);
-const char *pgp_pkalg_to_mic(const char *);
-
-char *pgp_ask_for_key (struct pgp_vinfo *, KEYINFO *, char *, char *, short, char **);
-char *pgp_keyid(KEYINFO *);
-char *_pgp_keyid(KEYINFO *);
+char *_pgp_keyid (pgp_key_t *);
+char *pgp_keyid (pgp_key_t *);
-struct pgp_vinfo *pgp_get_vinfo(enum pgp_ops);
+const char *pgp_pkalg_to_mic (const char *);
+const char *pgp_pkalgbytype (unsigned char);
-int mutt_check_pgp (HEADER *h);
+int mutt_check_pgp (HEADER * h);
+int mutt_is_application_pgp (BODY *);
+int mutt_is_multipart_encrypted (BODY *);
+int mutt_is_multipart_signed (BODY *);
int mutt_parse_pgp_hdr (char *, int);
-
-int mutt_is_multipart_encrypted(BODY *);
-int mutt_is_multipart_signed(BODY *);
-int mutt_is_application_pgp(BODY *);
-
int pgp_decrypt_mime (FILE *, FILE **, BODY *, BODY **);
int pgp_get_keys (HEADER *, char **);
int pgp_protect (HEADER *, char *);
int pgp_query (BODY *);
+int pgp_string_matches_hint (const char *s, LIST * hints);
int pgp_valid_passphrase (void);
-KEYINFO *ki_getkeybyaddr (struct pgp_vinfo *pgp, ADDRESS *, KEYINFO *, short);
-KEYINFO *ki_getkeybystr (struct pgp_vinfo *pgp, char *, KEYINFO *, short);
-KEYINFO *pgp_read_pubring(struct pgp_vinfo *pgp);
-KEYINFO *pgp_read_secring(struct pgp_vinfo *pgp);
-KEYINFO *gpg_read_pubring(struct pgp_vinfo *pgp);
-KEYINFO *gpg_read_secring(struct pgp_vinfo *pgp);
+pgp_key_t *gpg_get_candidates (struct pgp_vinfo *, pgp_ring_t, LIST *);
+pgp_key_t *pgp_ask_for_key (struct pgp_vinfo *, char *, char *, short, pgp_ring_t);
+pgp_key_t *pgp_get_candidates (struct pgp_vinfo *, pgp_ring_t, LIST *);
+pgp_key_t *pgp_getkeybyaddr (struct pgp_vinfo *pgp, ADDRESS *, short, pgp_ring_t);
+pgp_key_t *pgp_getkeybystr (struct pgp_vinfo *pgp, char *, short, pgp_ring_t);
+pgp_key_t *pgp_remove_key (pgp_key_t **, pgp_key_t *);
+
+short pgp_canencrypt (unsigned char);
+short pgp_cansign (unsigned char);
+short pgp_get_abilities (unsigned char);
+
+struct pgp_vinfo *pgp_get_vinfo (enum pgp_ops);
-void application_pgp_handler (BODY *, STATE *);
void mutt_forget_passphrase (void);
-void pgp_close_keydb (KEYINFO **);
+void pgp_application_pgp_handler (BODY *, STATE *);
void pgp_encrypted_handler (BODY *, STATE *);
-void pgp_extract_keys_from_attachment_list (FILE *fp, int tag, BODY *top);
-void pgp_extract_keys_from_messages(HEADER *hdr);
+void pgp_extract_keys_from_attachment_list (FILE * fp, int tag, BODY * top);
+void pgp_extract_keys_from_messages (HEADER * hdr);
+void pgp_free_key (pgp_key_t **kpp);
void pgp_signed_handler (BODY *, STATE *);
void pgp_void_passphrase (void);
-short pgp_canencrypt(unsigned char);
-short pgp_cansign(unsigned char);
-short pgp_get_abilities(unsigned char);
-const char *pgp_pkalgbytype(unsigned char);
-
#define pgp_secring(a) pgp_getring(a, 0)
#define pgp_pubring(a) pgp_getring(a, 1)
/* PGP V2 prototypes */
-pid_t pgp_v2_invoke_decode(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *, int);
+pid_t pgp_v2_invoke_decode (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *, int);
-pid_t pgp_v2_invoke_verify(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *, const char *);
+pid_t pgp_v2_invoke_verify (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *, const char *);
-pid_t pgp_v2_invoke_decrypt(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *);
+pid_t pgp_v2_invoke_decrypt (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
-pid_t pgp_v2_invoke_sign(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *);
+pid_t pgp_v2_invoke_sign (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
-pid_t pgp_v2_invoke_encrypt(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *, const char *, int);
+pid_t pgp_v2_invoke_encrypt (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *, const char *, int);
-void pgp_v2_invoke_import(struct pgp_vinfo *, const char *);
+void pgp_v2_invoke_import (struct pgp_vinfo *, const char *);
-pid_t pgp_v2_invoke_export(struct pgp_vinfo*,
+pid_t pgp_v2_invoke_export (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
+
+pid_t pgp_v2_invoke_verify_key (struct pgp_vinfo *,
FILE **, FILE **, FILE **,
int, int, int,
const char *);
-pid_t pgp_v2_invoke_verify_key(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *);
-
/* PGP V3 prototypes */
-pid_t pgp_v3_invoke_decode(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *, int);
+pid_t pgp_v3_invoke_decode (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *, int);
-pid_t pgp_v3_invoke_verify(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *, const char *);
+pid_t pgp_v3_invoke_verify (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *, const char *);
-pid_t pgp_v3_invoke_decrypt(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *);
+pid_t pgp_v3_invoke_decrypt (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
-pid_t pgp_v3_invoke_sign(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *);
+pid_t pgp_v3_invoke_sign (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
-pid_t pgp_v3_invoke_encrypt(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *, const char *, int);
+pid_t pgp_v3_invoke_encrypt (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *, const char *, int);
-void pgp_v3_invoke_import(struct pgp_vinfo *, const char *);
+void pgp_v3_invoke_import (struct pgp_vinfo *, const char *);
-pid_t pgp_v3_invoke_export(struct pgp_vinfo*,
+pid_t pgp_v3_invoke_export (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
+
+pid_t pgp_v3_invoke_verify_key (struct pgp_vinfo *,
FILE **, FILE **, FILE **,
int, int, int,
const char *);
-pid_t pgp_v3_invoke_verify_key(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *);
-
/* GNU Privacy Guard Prototypes */
-pid_t pgp_gpg_invoke_decode(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *, int);
+pid_t pgp_gpg_invoke_decode (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *, int);
-pid_t pgp_gpg_invoke_verify(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *, const char *);
+pid_t pgp_gpg_invoke_verify (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *, const char *);
-pid_t pgp_gpg_invoke_decrypt(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *);
-
-pid_t pgp_gpg_invoke_sign(struct pgp_vinfo *,
+pid_t pgp_gpg_invoke_decrypt (struct pgp_vinfo *,
FILE **, FILE **, FILE **,
int, int, int,
const char *);
-pid_t pgp_gpg_invoke_encrypt(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *, const char *, int);
+pid_t pgp_gpg_invoke_sign (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
-void pgp_gpg_invoke_import(struct pgp_vinfo *, const char *);
+pid_t pgp_gpg_invoke_encrypt (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *, const char *, int);
-pid_t pgp_gpg_invoke_export(struct pgp_vinfo*,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *);
+void pgp_gpg_invoke_import (struct pgp_vinfo *, const char *);
+
+pid_t pgp_gpg_invoke_export (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
-pid_t pgp_gpg_invoke_verify_key(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *);
+pid_t pgp_gpg_invoke_verify_key (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
/* use these as templates for your own prototypes */
-pid_t pgp_VERSION_invoke_decode(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *, int);
-
-pid_t pgp_VERSION_invoke_verify(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *, const char *);
-
-
-pid_t pgp_VERSION_invoke_decrypt(struct pgp_vinfo *,
+pid_t pgp_VERSION_invoke_decode (struct pgp_vinfo *,
FILE **, FILE **, FILE **,
int, int, int,
- const char *);
+ const char *, int);
-pid_t pgp_VERSION_invoke_sign(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *);
-
-pid_t pgp_VERSION_invoke_encrypt(struct pgp_vinfo *,
+pid_t pgp_VERSION_invoke_verify (struct pgp_vinfo *,
FILE **, FILE **, FILE **,
int, int, int,
- const char *, const char *, int);
+ const char *, const char *);
-void pgp_VERSION_invoke_import(struct pgp_vinfo *, const char *);
-pid_t pgp_VERSION_invoke_export(struct pgp_vinfo*,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *);
+pid_t pgp_VERSION_invoke_decrypt (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
+
+pid_t pgp_VERSION_invoke_sign (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
+
+pid_t pgp_VERSION_invoke_encrypt (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *, const char *, int);
+
+void pgp_VERSION_invoke_import (struct pgp_vinfo *, const char *);
+
+pid_t pgp_VERSION_invoke_export (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
-pid_t pgp_VERSION_invoke_verify_key(struct pgp_vinfo *,
- FILE **, FILE **, FILE **,
- int, int, int,
- const char *);
+pid_t pgp_VERSION_invoke_verify_key (struct pgp_vinfo *,
+ FILE **, FILE **, FILE **,
+ int, int, int,
+ const char *);
#endif
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
+ */
#include "mutt.h"
#include "mutt_curses.h"
#ifdef _PGPPATH
-static struct pgp_cache {
+struct pgp_cache
+{
char *what;
char *dflt;
struct pgp_cache *next;
-} * id_defaults = NULL;
+};
-typedef struct
-{
- KEYINFO *k;
- PGPUID *a;
-} pgp_key_t;
+static struct pgp_cache *id_defaults = NULL;
static char trust_flags[] = "?- +";
-static char *pgp_key_abilities(int flags)
+static char *pgp_key_abilities (int flags)
{
static char buff[3];
-
- if(!(flags & KEYFLAG_CANENCRYPT))
+
+ if (!(flags & KEYFLAG_CANENCRYPT))
buff[0] = '-';
- else if(flags & KEYFLAG_PREFER_SIGNING)
+ else if (flags & KEYFLAG_PREFER_SIGNING)
buff[0] = '.';
else
buff[0] = 'e';
-
- if(!(flags & KEYFLAG_CANSIGN))
+
+ if (!(flags & KEYFLAG_CANSIGN))
buff[1] = '-';
- else if(flags & KEYFLAG_PREFER_ENCRYPTION)
+ else if (flags & KEYFLAG_PREFER_ENCRYPTION)
buff[1] = '.';
else
buff[1] = 's';
-
+
buff[2] = '\0';
-
+
return buff;
}
-static void pgp_entry (char *s, size_t l, MUTTMENU *menu, int num)
+static char pgp_flags (int flags)
+{
+ if (flags & KEYFLAG_REVOKED)
+ return 'R';
+ else if (flags & KEYFLAG_EXPIRED)
+ return 'X';
+ else if (flags & KEYFLAG_DISABLED)
+ return 'd';
+ else if (flags & KEYFLAG_CRITICAL)
+ return 'c';
+ else
+ return ' ';
+}
+
+static pgp_key_t *pgp_principal_key (pgp_key_t *key)
{
- pgp_key_t *KeyTable = (pgp_key_t *) menu->data;
+ if (key->flags & KEYFLAG_SUBKEY && key->parent)
+ return key->parent;
+ else
+ return key;
+}
+static void pgp_entry (char *s, size_t l, MUTTMENU * menu, int num)
+{
+ pgp_uid_t **KeyTable = (pgp_uid_t **) menu->data;
+ pgp_uid_t *entry;
+ pgp_key_t *key;
+
+ entry = KeyTable[num];
+ key = pgp_principal_key (entry->parent);
+
snprintf (s, l, "%4d %c%c %4d/0x%s %-4s %2s %s",
- num + 1,
- trust_flags[KeyTable[num].a->trust & 0x03],
- (KeyTable[num].k->flags & KEYFLAG_CRITICAL ?
- 'c' : ' '),
- KeyTable[num].k->keylen,
- _pgp_keyid(KeyTable[num].k),
- KeyTable[num].k->algorithm,
- pgp_key_abilities(KeyTable[num].k->flags),
- KeyTable[num].a->addr);
+ num + 1, trust_flags[entry->trust & 0x03],
+ pgp_flags (key->flags),
+ entry->parent->keylen,
+ _pgp_keyid (key),
+ key->algorithm,
+ pgp_key_abilities (key->flags),
+ entry->addr);
}
-static int pgp_search (MUTTMENU *m, regex_t *re, int n)
+static int pgp_search (MUTTMENU * m, regex_t * re, int n)
{
char buf[LONG_STRING];
-
+
pgp_entry (buf, sizeof (buf), m, n);
return (regexec (re, buf, 0, NULL, 0));
}
static int pgp_compare (const void *a, const void *b)
{
int r;
-
- pgp_key_t *s = (pgp_key_t *) a;
- pgp_key_t *t = (pgp_key_t *) b;
- if((r = mutt_strcasecmp (s->a->addr, t->a->addr)) != 0)
+ pgp_uid_t **s = (pgp_uid_t **) a;
+ pgp_uid_t **t = (pgp_uid_t **) b;
+
+ if ((r = mutt_strcasecmp ((*s)->addr, (*t)->addr)) != 0)
return r;
else
- return mutt_strcasecmp(pgp_keyid(s->k), pgp_keyid(t->k));
+ return mutt_strcasecmp (pgp_keyid ((*s)->parent), pgp_keyid ((*t)->parent));
}
-static KEYINFO *pgp_select_key (struct pgp_vinfo *pgp,
- LIST *keys,
- ADDRESS *p, const char *s)
+static pgp_key_t *pgp_select_key (struct pgp_vinfo *pgp,
+ pgp_key_t *keys,
+ ADDRESS * p, const char *s)
{
int keymax;
- pgp_key_t *KeyTable;
+ pgp_uid_t **KeyTable;
MUTTMENU *menu;
- LIST *a;
- int i;
- int done = 0;
- LIST *l;
+ int i, done = 0;
char helpstr[SHORT_STRING], buf[LONG_STRING];
char cmd[LONG_STRING], tempfile[_POSIX_PATH_MAX];
FILE *fp, *devnull;
pid_t thepid;
- KEYINFO *info;
-
-
- for (i = 0, l = keys; l; l = l->next)
+ pgp_key_t *kp;
+ pgp_uid_t *a;
+
+ for (i = 0, kp = keys; kp; kp = kp->next)
{
- int did_main_key = 0;
-
- info = (KEYINFO *) l->data;
- a = info->address;
- retry1:
- for (; a; i++, a = a->next)
+ for (a = kp->address; a; i++, a = a->next)
;
-
- if(!did_main_key && info->flags & KEYFLAG_SUBKEY && info->mainkey)
- {
- did_main_key = 1;
- a = info->mainkey->address;
- goto retry1;
- }
}
-
- if (i == 0) return NULL;
+
+ if (i == 0)
+ return NULL;
keymax = i;
- KeyTable = safe_malloc (sizeof (pgp_key_t) * i);
+ KeyTable = safe_malloc (sizeof (pgp_key_t *) * i);
- for (i = 0, l = keys; l; l = l->next)
+ for (i = 0, kp = keys; kp; kp = kp->next)
{
- int did_main_key = 0;
- info = (KEYINFO *)l->data;
- a = info->address;
- retry2:
- for (; a ; i++, a = a->next)
- {
- KeyTable[i].k = (KEYINFO *) l->data;
- KeyTable[i].a = (PGPUID *)a->data;
- }
- if(!did_main_key && info->flags & KEYFLAG_SUBKEY && info->mainkey)
- {
- did_main_key = 1;
- a = info->mainkey->address;
- goto retry2;
- }
+ for (a = kp->address; a; i++, a = a->next)
+ KeyTable[i] = a;
}
-
- qsort (KeyTable, i, sizeof (pgp_key_t), pgp_compare);
+
+ qsort (KeyTable, i, sizeof (pgp_key_t *), pgp_compare);
helpstr[0] = 0;
mutt_make_help (buf, sizeof (buf), _("Exit "), MENU_PGP, OP_EXIT);
strcat (helpstr, buf);
- mutt_make_help (buf, sizeof (buf), _("Select "), MENU_PGP,
+ mutt_make_help (buf, sizeof (buf), _("Select "), MENU_PGP,
OP_GENERIC_SELECT_ENTRY);
strcat (helpstr, buf);
mutt_make_help (buf, sizeof (buf), _("Check key "), MENU_PGP, OP_VERIFY_KEY);
strcat (buf, s);
menu->title = buf;
- info = NULL;
-
+ kp = NULL;
+
while (!done)
{
switch (mutt_menuLoop (menu))
{
- case OP_VERIFY_KEY:
+ case OP_VERIFY_KEY:
- mutt_mktemp (tempfile);
- if ((devnull = fopen ("/dev/null", "w")) == NULL)
+ mutt_mktemp (tempfile);
+ if ((devnull = fopen ("/dev/null", "w")) == NULL)
+ {
+ mutt_perror _("Can't open /dev/null");
+ break;
+ }
+ if ((fp = safe_fopen (tempfile, "w")) == NULL)
+ {
+ fclose (devnull);
+ mutt_perror _("Can't create temporary file");
+ break;
+ }
+
+ mutt_message _("Invoking PGP...");
+
+ if ((thepid = pgp->invoke_verify_key (pgp, NULL, NULL, NULL, -1,
+ fileno (fp), fileno (devnull),
+ pgp_keyid (pgp_principal_key (KeyTable[menu->current]->parent)))) == -1)
+ {
+ mutt_perror _("Can't create filter");
+ unlink (tempfile);
+ fclose (fp);
+ fclose (devnull);
+ }
+
+ mutt_wait_filter (thepid);
+ fclose (fp);
+ fclose (devnull);
+ mutt_clear_error ();
+ snprintf (cmd, sizeof (cmd), _("Key ID: 0x%s"),
+ pgp_keyid (pgp_principal_key (KeyTable[menu->current]->parent)));
+ mutt_do_pager (cmd, tempfile, 0, NULL);
+ menu->redraw = REDRAW_FULL;
+
+ break;
+
+ case OP_VIEW_ID:
+
+ mutt_message (KeyTable[menu->current]->addr);
+ break;
+
+ case OP_GENERIC_SELECT_ENTRY:
+
+
+ /* XXX make error reporting more verbose */
+
+ if (option (OPTPGPCHECKTRUST))
+ {
+ pgp_key_t *key, *principal;
+
+ key = KeyTable[menu->current]->parent;
+ principal = pgp_principal_key (key);
+
+ if ((key->flags | principal->flags) & KEYFLAG_CANTUSE)
{
- mutt_perror _("Can't open /dev/null");
+ mutt_error _("This key can't be used: expired/disabled/revoked.");
break;
}
- if ((fp = safe_fopen (tempfile, "w")) == NULL)
+ }
+
+ if (option (OPTPGPCHECKTRUST) &&
+ (KeyTable[menu->current]->trust & 0x03) < 3)
+ {
+ char *s = "";
+ char buff[LONG_STRING];
+
+ switch (KeyTable[menu->current]->trust & 0x03)
{
- fclose (devnull);
- mutt_perror _("Can't create temporary file");
+ case 0:
+ s = N_("This ID's trust level is undefined.");
+ break;
+ case 1:
+ s = N_("This ID is not trusted.");
+ break;
+ case 2:
+ s = N_("This ID is only marginally trusted.");
break;
- }
-
- mutt_message _("Invoking PGP...");
-
- if((thepid = pgp->invoke_verify_key(pgp, NULL, NULL, NULL, -1,
- fileno(fp), fileno(devnull),
- pgp_keyid(KeyTable[menu->current].k))) == -1)
- {
- mutt_perror _("Can't create filter");
- unlink (tempfile);
- fclose (fp);
- fclose (devnull);
}
- mutt_wait_filter (thepid);
- fclose (fp);
- fclose (devnull);
- mutt_clear_error ();
- snprintf(cmd, sizeof(cmd), _("Key ID: 0x%s"), pgp_keyid(KeyTable[menu->current].k));
- mutt_do_pager (cmd, tempfile, 0, NULL);
- menu->redraw = REDRAW_FULL;
-
- break;
+ snprintf (buff, sizeof (buff), _("%s Do you really want to use it?"),
+ _(s));
- case OP_VIEW_ID:
-
- mutt_message (KeyTable[menu->current].a->addr);
- break;
-
- case OP_GENERIC_SELECT_ENTRY:
-
- if (option (OPTPGPCHECKTRUST) &&
- (KeyTable[menu->current].a->trust & 0x03) < 3)
+ if (mutt_yesorno (buff, 0) != 1)
{
- char *s = "";
- char buff[LONG_STRING];
-
- switch (KeyTable[menu->current].a->trust & 0x03)
- {
- case 0: s = N_("This ID's trust level is undefined."); break;
- case 1: s = N_("This ID is not trusted."); break;
- case 2: s = N_("This ID is only marginally trusted."); break;
- }
-
- snprintf (buff, sizeof(buff), _("%s Do you really want to use it?"),
- _(s));
-
- if (mutt_yesorno (buff, 0) != 1)
- {
- mutt_clear_error ();
- break;
- }
+ mutt_clear_error ();
+ break;
}
+ }
- info = KeyTable[menu->current].k;
- done = 1;
- break;
+# if 0
+ kp = pgp_principal_key (KeyTable[menu->current]->parent);
+# else
+ kp = KeyTable[menu->current]->parent;
+# endif
+ done = 1;
+ break;
- case OP_EXIT:
+ case OP_EXIT:
- info = NULL;
- done = 1;
- break;
+ kp = NULL;
+ done = 1;
+ break;
}
}
mutt_menuDestroy (&menu);
safe_free ((void **) &KeyTable);
- return (info);
+ return (kp);
}
-char *pgp_ask_for_key (struct pgp_vinfo *pgp, KEYINFO *db, char *tag, char *whatfor,
- short abilities, char **alg)
+pgp_key_t *pgp_ask_for_key (struct pgp_vinfo *pgp, char *tag, char *whatfor,
+ short abilities, pgp_ring_t keyring)
{
- KEYINFO *key;
- char *key_id;
+ pgp_key_t *key;
char resp[SHORT_STRING];
struct pgp_cache *l = NULL;
resp[0] = 0;
- if (whatfor)
+ if (whatfor)
{
for (l = id_defaults; l; l = l->next)
if (!mutt_strcasecmp (whatfor, l->what))
{
- strcpy (resp, NONULL(l->dflt));
+ strcpy (resp, NONULL (l->dflt));
break;
}
}
resp[0] = 0;
if (mutt_get_field (tag, resp, sizeof (resp), M_CLEAR) != 0)
return NULL;
-
- if (whatfor)
+
+ if (whatfor)
{
if (l)
{
- safe_free ((void **)&l->dflt);
+ safe_free ((void **) &l->dflt);
l->dflt = safe_strdup (resp);
- }
+ }
else
{
l = safe_malloc (sizeof (struct pgp_cache));
}
}
- if ((key = ki_getkeybystr (pgp, resp, db, abilities)))
- {
- key_id = safe_strdup(pgp_keyid (key));
+ if ((key = pgp_getkeybystr (pgp, resp, abilities, keyring)))
+ return key;
- if (alg)
- *alg = safe_strdup(pgp_pkalg_to_mic(key->algorithm));
-
- return (key_id);
- }
BEEP ();
}
/* not reached */
/* generate a public key attachment */
-BODY *pgp_make_key_attachment (char * tempf)
+BODY *pgp_make_key_attachment (char *tempf)
{
BODY *att;
char buff[LONG_STRING];
FILE *devnull;
struct stat sb;
pid_t thepid;
- KEYINFO *db;
- struct pgp_vinfo *pgp = pgp_get_vinfo(PGP_EXPORT);
+ pgp_key_t *key;
+ struct pgp_vinfo *pgp = pgp_get_vinfo (PGP_EXPORT);
- if(!pgp)
+ if (!pgp)
return NULL;
-
+
unset_option (OPTPGPCHECKTRUST);
-
- db = pgp->read_pubring(pgp);
- id = pgp_ask_for_key (pgp, db, _("Please enter the key ID: "), NULL, 0, NULL);
- pgp_close_keydb(&db);
-
- if(!id)
- return NULL;
- if (!tempf) {
+ key = pgp_ask_for_key (pgp, _("Please enter the key ID: "), NULL, 0, PGP_PUBRING);
+
+ if (!key) return NULL;
+
+ id = safe_strdup (pgp_keyid (pgp_principal_key(key)));
+ pgp_free_key (&key);
+
+ if (!tempf)
+ {
mutt_mktemp (tempfb);
tempf = tempfb;
}
- if ((tempfp = safe_fopen (tempf, tempf == tempfb ? "w" : "a")) == NULL) {
+ if ((tempfp = safe_fopen (tempf, tempf == tempfb ? "w" : "a")) == NULL)
+ {
mutt_perror _("Can't create temporary file");
- safe_free ((void **)&id);
+ safe_free ((void **) &id);
return NULL;
}
- if ((devnull = fopen ("/dev/null", "w")) == NULL) {
+ if ((devnull = fopen ("/dev/null", "w")) == NULL)
+ {
mutt_perror _("Can't open /dev/null");
- safe_free ((void **)&id);
+ safe_free ((void **) &id);
fclose (tempfp);
- if (tempf == tempfb) unlink (tempf);
+ if (tempf == tempfb)
+ unlink (tempf);
return NULL;
}
- if ((thepid = pgp->invoke_export(pgp,
- NULL, NULL, NULL, -1,
- fileno(tempfp), fileno(devnull), id)) == -1)
+ mutt_message _("Invoking pgp...");
+
+ if ((thepid =
+ pgp->invoke_export (pgp, NULL, NULL, NULL, -1,
+ fileno (tempfp), fileno (devnull), id)) == -1)
{
mutt_perror _("Can't create filter");
unlink (tempf);
fclose (tempfp);
fclose (devnull);
- safe_free ((void **)&id);
+ safe_free ((void **) &id);
return NULL;
}
-
+
mutt_wait_filter (thepid);
-
+
fclose (tempfp);
fclose (devnull);
att->filename = safe_strdup (tempf);
att->unlink = 1;
att->type = TYPEAPPLICATION;
- att->subtype = safe_strdup ("pgp-keys");
+ att->subtype = safe_strdup ("pgp-keys");
snprintf (buff, sizeof (buff), _("PGP Key 0x%s."), id);
att->description = safe_strdup (buff);
mutt_update_encoding (att);
-
+
stat (tempf, &sb);
att->length = sb.st_size;
- safe_free ((void **)&id);
+ safe_free ((void **) &id);
return att;
}
-static char *mutt_stristr (char *haystack, char *needle)
+static LIST *pgp_add_string_to_hints (LIST *hints, const char *str)
{
- char *p, *q;
-
- if (!haystack)
- return NULL;
- if (!needle)
- return (haystack);
-
- while (*(p = haystack))
+ char *scratch = safe_strdup (str);
+ char *t;
+
+ t = strtok (scratch, " \n");
+ while (t)
{
- for (q = needle ; *p && *q && tolower (*p) == tolower (*q) ; p++, q++)
- ;
- if (!*q)
- return (haystack);
- haystack++;
+ hints = mutt_add_list (hints, t);
+ t = strtok (NULL, " \n");
}
- return NULL;
+
+ safe_free ((void **) &scratch);
+ return hints;
}
-KEYINFO *ki_getkeybyaddr (struct pgp_vinfo *pgp,
- ADDRESS *a, KEYINFO *k, short abilities)
+
+pgp_key_t *pgp_getkeybyaddr (struct pgp_vinfo * pgp,
+ ADDRESS * a, short abilities, pgp_ring_t keyring)
{
ADDRESS *r, *p;
- LIST *l = NULL, *t = NULL;
- LIST *q;
+ LIST *hints = NULL;
int weak = 0;
int weak_association;
int match;
- int did_main_key;
- PGPUID *u;
+ pgp_uid_t *q;
+ pgp_key_t *keys, *k, *kn;
+ pgp_key_t *matches = NULL;
+ pgp_key_t **last = &matches;
- dprint (5, (debugfile, "ki_getkeybyaddr: looking for %s <%s>.",
- a->personal, a->mailbox));
+ if (a && a->mailbox)
+ hints = pgp_add_string_to_hints (hints, a->mailbox);
+ if (a && a->personal)
+ hints = pgp_add_string_to_hints (hints, a->personal);
+
+ mutt_message _("Looking for keys...");
+ keys = pgp->get_candidates (pgp, keyring, hints);
+ mutt_free_list (&hints);
- for ( ; k ; k = k->next)
+ if (!keys)
+ return NULL;
+
+ dprint (5, (debugfile, "pgp_getkeybyaddr: looking for %s <%s>.",
+ a->personal, a->mailbox));
+
+
+ for (k = keys; k; k = kn)
{
+ kn = k->next;
+
dprint (5, (debugfile, " looking at key: %s\n",
pgp_keyid (k)));
-
- if(k->flags & (KEYFLAG_REVOKED | KEYFLAG_EXPIRED | KEYFLAG_DISABLED))
- {
- dprint (5, (debugfile, " key disabled/revoked/expired\n"));
- continue;
- }
-
- if(abilities && !(k->flags & abilities))
+
+ if (abilities && !(k->flags & abilities))
{
dprint (5, (debugfile, " insufficient abilities: Has %x, want %x\n",
k->flags, abilities));
continue;
}
-
+
q = k->address;
- did_main_key = 0;
weak_association = 1;
match = 0;
-
- retry:
-
- for (;q ; q = q->next)
+
+ for (; q; q = q->next)
{
- u = (PGPUID *) q->data;
- r = rfc822_parse_adrlist(NULL, u->addr);
+ r = rfc822_parse_adrlist (NULL, q->addr);
-
- for(p = r; p && weak_association; p = p->next)
+
+ for (p = r; p && weak_association; p = p->next)
{
if ((p->mailbox && a->mailbox &&
mutt_strcasecmp (p->mailbox, a->mailbox) == 0) ||
{
match = 1;
- if(((u->trust & 0x03) == 3) &&
- (p->mailbox && a->mailbox && !mutt_strcasecmp(p->mailbox, a->mailbox)))
+ if (((q->trust & 0x03) == 3) &&
+ (p->mailbox && a->mailbox && !mutt_strcasecmp (p->mailbox, a->mailbox)))
weak_association = 0;
}
}
- rfc822_free_address(&r);
+ rfc822_free_address (&r);
}
- if(match)
+ if (match)
{
- t = mutt_new_list ();
- t->data = (void *) k;
- t->next = l;
- l = t;
-
- if(weak_association)
- weak = 1;
+ pgp_key_t *_p, *_k;
+
+ _k = pgp_principal_key (k);
- }
+ *last = _k;
+ kn = pgp_remove_key (&keys, _k);
- if(!did_main_key && !match && k->flags & KEYFLAG_SUBKEY && k->mainkey)
- {
- did_main_key = 1;
- q = k->mainkey->address;
- goto retry;
+ /* start with k, not with _k: k is always a successor of _k. */
+
+ for (_p = k; _p; _p = _p->next)
+ {
+ if (!_p->next)
+ {
+ last = &_p->next;
+ break;
+ }
+ }
}
}
+
+ pgp_free_key (&keys);
- if (l)
+ if (matches)
{
- if (l->next || weak)
+ if (matches->next || weak)
{
/* query for which key the user wants */
- k = pgp_select_key (pgp, l, a, NULL);
+ k = pgp_select_key (pgp, matches, a, NULL);
+ if (k)
+ pgp_remove_key (&matches, k);
+
+ pgp_free_key (&matches);
}
else
- k = (KEYINFO *)l->data;
-
- /* mutt_free_list() frees the .data member, so clear the pointers */
-
- for(t = l; t; t = t->next)
- t->data = NULL;
+ k = matches;
- mutt_free_list (&l);
+ return k;
}
- return (k);
+ return NULL;
}
-KEYINFO *ki_getkeybystr (struct pgp_vinfo *pgp,
- char *p, KEYINFO *k, short abilities)
+pgp_key_t *pgp_getkeybystr (struct pgp_vinfo * pgp,
+ char *p, short abilities, pgp_ring_t keyring)
{
- LIST *t = NULL, *l = NULL;
- LIST *a;
+ LIST *hints = NULL;
+ pgp_key_t *keys;
+ pgp_key_t *matches = NULL;
+ pgp_key_t **last = &matches;
+ pgp_key_t *k, *kn;
+ pgp_uid_t *a;
+ short match;
+
+ mutt_message _("Looking for keys...");
+
+ hints = pgp_add_string_to_hints (hints, p);
+ keys = pgp->get_candidates (pgp, keyring, hints);
+ mutt_free_list (&hints);
+
+ if (!keys)
+ return NULL;
- for(; k; k = k->next)
+
+ for (k = keys; k; k = kn)
{
- int did_main_key = 0;
-
- if(k->flags & (KEYFLAG_REVOKED | KEYFLAG_EXPIRED | KEYFLAG_DISABLED))
- continue;
-
- if(abilities && !(k->flags & abilities))
+ kn = k->next;
+ if (abilities && !(k->flags & abilities))
continue;
- a = k->address;
-
- retry:
+ match = 0;
- for(; a ; a = a->next)
+ for (a = k->address; a; a = a->next)
{
- dprint (5, (debugfile, "ki_getkeybystr: matching \"%s\" against key %s, \"%s\": ",
- p, pgp_keyid (k), ((PGPUID *)a->data)->addr));
- if (!*p || mutt_strcasecmp (p, pgp_keyid(k)) == 0 ||
- (!mutt_strncasecmp(p, "0x", 2) && !mutt_strcasecmp(p+2, pgp_keyid(k))) ||
- (option(OPTPGPLONGIDS) && !mutt_strncasecmp(p, "0x", 2) &&
- !mutt_strcasecmp(p+2, k->keyid+8)) ||
- mutt_stristr(((PGPUID *)a->data)->addr,p))
+ dprint (5, (debugfile, "pgp_getkeybystr: matching \"%s\" against key %s, \"%s\": ",
+ p, pgp_keyid (k), a->addr));
+ if (!*p || mutt_strcasecmp (p, pgp_keyid (k)) == 0 ||
+ (!mutt_strncasecmp (p, "0x", 2) && !mutt_strcasecmp (p + 2, pgp_keyid (k))) ||
+ (option (OPTPGPLONGIDS) && !mutt_strncasecmp (p, "0x", 2) &&
+ !mutt_strcasecmp (p + 2, k->keyid + 8)) ||
+ mutt_stristr (a->addr, p))
{
dprint (5, (debugfile, "match.\n"));
- t = mutt_new_list ();
- t->data = (void *)k;
- t->next = l;
- l = t;
+ match = 1;
break;
}
- else
- dprint (5, (debugfile, "no match.\n"));
}
- if(!did_main_key && k->flags & KEYFLAG_SUBKEY && k->mainkey)
+ if (match)
{
- did_main_key = 1;
- a = k->mainkey->address;
- goto retry;
+ pgp_key_t *_p, *_k;
+
+ _k = pgp_principal_key (k);
+
+ *last = _k;
+ kn = pgp_remove_key (&keys, _k);
+
+ /* start with k, not with _k: k is always a successor of _k. */
+
+ for (_p = k; _p; _p = _p->next)
+ {
+ if (!_p->next)
+ {
+ last = &_p->next;
+ break;
+ }
+ }
}
}
- if (l)
- {
- k = pgp_select_key (pgp, l, NULL, p);
- set_option(OPTNEEDREDRAW);
-
- for(t = l; t; t = t->next)
- t->data = NULL;
+ pgp_free_key (&keys);
- mutt_free_list (&l);
+ if (matches)
+ {
+ k = pgp_select_key (pgp, matches, NULL, p);
+ if (k)
+ pgp_remove_key (&matches, k);
+
+ pgp_free_key (&matches);
+ return k;
}
- return (k);
+ return NULL;
}
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA
* 02139, USA.
- */
+ */
#include <stdio.h>
static unsigned char *pbuf = NULL;
static size_t plen = 0;
-enum packet_tags {
- PT_RES0 = 0, /* reserved */
- PT_ESK, /* Encrypted Session Key */
- PT_SIG, /* Signature Packet */
- PT_CESK, /* Conventionally Encrypted Session Key Packet */
- PT_OPS, /* One-Pass Signature Packet */
- PT_SECKEY, /* Secret Key Packet */
- PT_PUBKEY, /* Public Key Packet */
- PT_SUBSECKEY, /* Secret Subkey Packet */
- PT_COMPRESSED, /* Compressed Data Packet */
- PT_SKE, /* Symmetrically Encrypted Data Packet */
- PT_MARKER, /* Marker Packet */
- PT_LITERAL, /* Literal Data Packet */
- PT_TRUST, /* Trust Packet */
- PT_NAME, /* Name Packet */
- PT_SUBKEY, /* Subkey Packet */
- PT_RES15, /* Reserved */
- PT_COMMENT /* Comment Packet */
+enum packet_tags
+{
+ PT_RES0 = 0, /* reserved */
+ PT_ESK, /* Encrypted Session Key */
+ PT_SIG, /* Signature Packet */
+ PT_CESK, /* Conventionally Encrypted Session Key Packet */
+ PT_OPS, /* One-Pass Signature Packet */
+ PT_SECKEY, /* Secret Key Packet */
+ PT_PUBKEY, /* Public Key Packet */
+ PT_SUBSECKEY, /* Secret Subkey Packet */
+ PT_COMPRESSED, /* Compressed Data Packet */
+ PT_SKE, /* Symmetrically Encrypted Data Packet */
+ PT_MARKER, /* Marker Packet */
+ PT_LITERAL, /* Literal Data Packet */
+ PT_TRUST, /* Trust Packet */
+ PT_NAME, /* Name Packet */
+ PT_SUBKEY, /* Subkey Packet */
+ PT_RES15, /* Reserved */
+ PT_COMMENT /* Comment Packet */
};
/* FIXME I can't find where those strings are displayed! */
-const char *pgp_packet_name[] = {
+const char *pgp_packet_name[] =
+{
N_("reserved"),
N_("Encrypted Session Key"),
N_("Signature Packet"),
N_("Comment Packet")
};
-const char *pgp_pkalgbytype(unsigned char type)
+const char *pgp_pkalgbytype (unsigned char type)
{
- switch(type)
+ switch (type)
{
- case 1: return "RSA";
- case 2: return "RSA";
- case 3: return "RSA";
- case 16: return "ElG";
- case 17: return "DSA";
- case 20: return "ElG";
- default: return "unk";
+ case 1:
+ return "RSA";
+ case 2:
+ return "RSA";
+ case 3:
+ return "RSA";
+ case 16:
+ return "ElG";
+ case 17:
+ return "DSA";
+ case 20:
+ return "ElG";
+ default:
+ return "unk";
}
}
char *pkalg;
char *micalg;
}
-pktomic[] =
+pktomic[] =
{
- { "RSA", "pgp-md5" },
- { "ElG", "pgp-rmd160" },
- { "DSA", "pgp-sha1" },
- { NULL, "x-unknown" }
+ {
+ "RSA", "pgp-md5"
+ }
+ ,
+ {
+ "ElG", "pgp-rmd160"
+ }
+ ,
+ {
+ "DSA", "pgp-sha1"
+ }
+ ,
+ {
+ NULL, "x-unknown"
+ }
};
-const char *pgp_pkalg_to_mic(const char *alg)
+const char *pgp_pkalg_to_mic (const char *alg)
{
int i;
-
- for(i = 0; pktomic[i].pkalg; i++)
+
+ for (i = 0; pktomic[i].pkalg; i++)
{
- if(!mutt_strcasecmp(pktomic[i].pkalg, alg))
+ if (!mutt_strcasecmp (pktomic[i].pkalg, alg))
break;
}
-
+
return pktomic[i].micalg;
}
#if 0
-static const char *hashalgbytype(unsigned char type)
+static const char *hashalgbytype (unsigned char type)
{
- switch(type)
+ switch (type)
{
- case 1: return "MD5";
- case 2: return "SHA1";
- case 3: return "RIPE-MD/160";
- case 4: return "HAVAL";
- default: return "unknown";
+ case 1:
+ return "MD5";
+ case 2:
+ return "SHA1";
+ case 3:
+ return "RIPE-MD/160";
+ case 4:
+ return "HAVAL";
+ default:
+ return "unknown";
}
}
#endif
-short pgp_canencrypt(unsigned char type)
+short pgp_canencrypt (unsigned char type)
{
- switch(type)
+ switch (type)
{
- case 1:
- case 2:
- case 16:
- case 20:
- return 1;
- default:
- return 0;
+ case 1:
+ case 2:
+ case 16:
+ case 20:
+ return 1;
+ default:
+ return 0;
}
}
-short pgp_cansign(unsigned char type)
+short pgp_cansign (unsigned char type)
{
- switch(type)
+ switch (type)
{
- case 1:
- case 3:
- case 16:
- case 17:
- case 20:
- return 1;
- default:
- return 0;
+ case 1:
+ case 3:
+ case 16:
+ case 17:
+ case 20:
+ return 1;
+ default:
+ return 0;
}
}
/* return values:
- *
+
* 1 = sign only
* 2 = encrypt only
* 3 = both
*/
-short pgp_get_abilities(unsigned char type)
+short pgp_get_abilities (unsigned char type)
{
- return (pgp_canencrypt(type) << 1) | pgp_cansign(type);
+ return (pgp_canencrypt (type) << 1) | pgp_cansign (type);
}
-static int read_material(size_t material, size_t *used, FILE *fp)
+static int read_material (size_t material, size_t * used, FILE * fp)
{
- if(*used + material >= plen)
+ if (*used + material >= plen)
{
unsigned char *p;
size_t nplen;
-
+
nplen = *used + material + CHUNKSIZE;
- if(!(p = realloc(pbuf, nplen)))
+ if (!(p = realloc (pbuf, nplen)))
{
- mutt_perror("realloc");
+ mutt_perror ("realloc");
return -1;
}
plen = nplen;
pbuf = p;
}
-
- if(fread(pbuf + *used, 1, material, fp) < material)
+
+ if (fread (pbuf + *used, 1, material, fp) < material)
{
- mutt_perror("fread");
+ mutt_perror ("fread");
return -1;
}
-
+
*used += material;
return 0;
}
-static unsigned char *pgp_read_packet(FILE *fp, size_t *len)
+static unsigned char *pgp_read_packet (FILE * fp, size_t * len)
{
size_t used = 0;
long startpos;
unsigned char ctb;
unsigned char b;
size_t material;
-
- startpos = ftell(fp);
-
- if(!plen)
+
+ startpos = ftell (fp);
+
+ if (!plen)
{
plen = CHUNKSIZE;
- pbuf = safe_malloc(plen);
+ pbuf = safe_malloc (plen);
}
- if(fread(&ctb, 1, 1, fp) < 1)
+ if (fread (&ctb, 1, 1, fp) < 1)
{
- if(!feof(fp))
- mutt_perror("fread");
+ if (!feof (fp))
+ mutt_perror ("fread");
goto bail;
}
- if(!(ctb & 0x80))
+ if (!(ctb & 0x80))
{
goto bail;
}
- if(ctb & 0x40) /* handle PGP 5.0 packets. */
+ if (ctb & 0x40) /* handle PGP 5.0 packets. */
{
int partial = 0;
- pbuf[0] = ctb; used++;
-
- do {
- if(fread(&b, 1, 1, fp) < 1)
+ pbuf[0] = ctb;
+ used++;
+
+ do
+ {
+ if (fread (&b, 1, 1, fp) < 1)
{
- mutt_perror("fread");
+ mutt_perror ("fread");
goto bail;
}
-
- if(b < 192)
+
+ if (b < 192)
{
material = b;
partial = 0;
material -= 1;
- }
- else if(192 <= b && b <= 223)
+ }
+ else if (192 <= b && b <= 223)
{
material = (b - 192) * 256;
- if(fread(&b, 1, 1, fp) < 1)
+ if (fread (&b, 1, 1, fp) < 1)
{
- mutt_perror("fread");
+ mutt_perror ("fread");
goto bail;
}
material += b + 192;
partial = 0;
material -= 2;
}
- else if(b < 255)
+ else if (b < 255)
{
material = 1 << (b & 0x1f);
partial = 1;
material -= 1;
}
- else /* b == 255 */
+ else
+ /* b == 255 */
{
unsigned char buf[4];
- if( fread( buf, 4, 1, fp ) < 1)
+ if (fread (buf, 4, 1, fp) < 1)
{
- mutt_perror("fread");
- goto bail;
+ mutt_perror ("fread");
+ goto bail;
}
- /*assert( sizeof(material) >= 4 );*/
- material = buf[0] << 24;
+ /*assert( sizeof(material) >= 4 ); */
+ material = buf[0] << 24;
material |= buf[1] << 16;
material |= buf[2] << 8;
material |= buf[3];
partial = 0;
material -= 5;
}
-
- if(read_material(material, &used, fp) == -1)
+
+ if (read_material (material, &used, fp) == -1)
goto bail;
- } while (partial);
+ }
+ while (partial);
}
- else /* Old-Style PGP */
+ else
+ /* Old-Style PGP */
{
int bytes = 0;
pbuf[0] = 0x80 | ((ctb >> 2) & 0x0f);
used++;
-
- switch(ctb & 0x03)
+
+ switch (ctb & 0x03)
{
case 0:
{
- if(fread(&b, 1, 1, fp) < 1)
+ if (fread (&b, 1, 1, fp) < 1)
{
- mutt_perror("fread");
+ mutt_perror ("fread");
goto bail;
}
-
+
material = b;
break;
}
-
+
case 1:
- bytes = 2;
-
+ bytes = 2;
+
case 2:
{
int i;
- if(!bytes) bytes = 4;
-
+ if (!bytes)
+ bytes = 4;
+
material = 0;
-
- for(i = 0; i < bytes; i++)
+
+ for (i = 0; i < bytes; i++)
{
- if(fread(&b, 1, 1, fp) < 1)
+ if (fread (&b, 1, 1, fp) < 1)
{
- mutt_perror("fread");
+ mutt_perror ("fread");
goto bail;
}
-
+
material = (material << 8) + b;
}
break;
}
-
+
default:
- goto bail;
+ goto bail;
}
-
- if(read_material(material, &used, fp) == -1)
+
+ if (read_material (material, &used, fp) == -1)
goto bail;
}
-
- if(len)
+
+ if (len)
*len = used;
-
+
return pbuf;
-
- bail:
-
- fseek(fp, startpos, SEEK_SET);
+
+bail:
+
+ fseek (fp, startpos, SEEK_SET);
return NULL;
}
-static KEYINFO *pgp_new_keyinfo(void)
+static pgp_key_t *pgp_new_keyinfo (void)
{
- KEYINFO *p;
+ return safe_calloc (sizeof (pgp_key_t), 1);
+}
- p = safe_malloc(sizeof(KEYINFO));
- p->keyid = NULL;
- p->address = NULL;
- p->flags = 0;
- p->next = NULL;
- p->keylen = 0;
+void pgp_free_uid (pgp_uid_t ** upp)
+{
+ pgp_uid_t *up, *q;
- return p;
+ if (!upp || !*upp)
+ return;
+ for (up = *upp; up; up = q)
+ {
+ q = up->next;
+ safe_free ((void **) &up->addr);
+ safe_free ((void **) &up);
+ }
+
+ *upp = NULL;
+}
+
+static void _pgp_free_key (pgp_key_t ** kpp)
+{
+ pgp_key_t *kp;
+
+ if (!kpp || !*kpp)
+ return;
+
+ kp = *kpp;
+
+ pgp_free_uid (&kp->address);
+ safe_free ((void **) &kp->keyid);
+ safe_free ((void **) kpp);
}
-static KEYINFO *pgp_parse_pgp2_key(unsigned char *buff, size_t l)
+pgp_key_t *pgp_remove_key (pgp_key_t ** klist, pgp_key_t * key)
{
- KEYINFO *p;
+ pgp_key_t **last;
+ pgp_key_t *p, *q, *r;
+
+ if (!klist || !*klist || !key)
+ return NULL;
+
+ if (key->parent && key->parent != key)
+ key = key->parent;
+
+ last = klist;
+ for (p = *klist; p && p != key; p = p->next)
+ last = &p->next;
+
+ if (!p)
+ return NULL;
+
+ for (q = p->next, r = p; q && q->parent == p; q = q->next)
+ r = q;
+
+ if (r)
+ r->next = NULL;
+
+ *last = q;
+ return q;
+}
+
+void pgp_free_key (pgp_key_t ** kpp)
+{
+ pgp_key_t *p, *q, *r;
+
+ if (!kpp || !*kpp)
+ return;
+
+ if ((*kpp)->parent && (*kpp)->parent != *kpp)
+ *kpp = (*kpp)->parent;
+
+ /* Order is important here:
+ *
+ * - First free all children.
+ * - If we are an orphan (i.e., our parent was not in the key list),
+ * free our parent.
+ * - free ourselves.
+ */
+
+ for (p = *kpp; p; p = q)
+ {
+ for (q = p->next; q && q->parent == p; q = r)
+ {
+ r = q->next;
+ _pgp_free_key (&q);
+ }
+ if (p->parent)
+ _pgp_free_key (&p->parent);
+
+ _pgp_free_key (&p);
+ }
+
+ *kpp = NULL;
+}
+
+static pgp_key_t *pgp_parse_pgp2_key (unsigned char *buff, size_t l)
+{
+ pgp_key_t *p;
unsigned char alg;
size_t expl;
unsigned long id;
size_t j;
int i, k;
unsigned char scratch[LONG_STRING];
-
- if(l < 12)
+
+ if (l < 12)
return NULL;
-
- p = pgp_new_keyinfo();
-
- for(i = 0, j = 2; i < 4; i++)
+
+ p = pgp_new_keyinfo ();
+
+ for (i = 0, j = 2; i < 4; i++)
gen_time = (gen_time << 8) + buff[j++];
-
- for(i = 0; i < 2; i++)
+
+ for (i = 0; i < 2; i++)
exp_days = (exp_days << 8) + buff[j++];
-
- if(exp_days && time(NULL) > gen_time + exp_days * 24 * 3600)
+
+ if (exp_days && time (NULL) > gen_time + exp_days * 24 * 3600)
p->flags |= KEYFLAG_EXPIRED;
-
+
alg = buff[j++];
-
- p->algorithm = pgp_pkalgbytype(alg);
- p->flags |= pgp_get_abilities(alg);
-
+
+ p->algorithm = pgp_pkalgbytype (alg);
+ p->flags |= pgp_get_abilities (alg);
+
expl = 0;
- for(i = 0; i < 2; i++)
+ for (i = 0; i < 2; i++)
expl = (expl << 8) + buff[j++];
-
+
p->keylen = expl;
-
- expl = (expl + 7)/ 8;
- if(expl < 4)
+
+ expl = (expl + 7) / 8;
+ if (expl < 4)
goto bailout;
-
+
j += expl - 8;
-
- for(k = 0; k < 2; k++)
+
+ for (k = 0; k < 2; k++)
{
- for(id = 0, i = 0; i < 4; i++)
+ for (id = 0, i = 0; i < 4; i++)
id = (id << 8) + buff[j++];
-
- snprintf((char *)scratch + k * 8, sizeof(scratch) - k * 8,
- "%08lX", id);
+
+ snprintf ((char *) scratch + k * 8, sizeof (scratch) - k * 8,
+ "%08lX", id);
}
-
- p->keyid = safe_strdup((char *)scratch);
-
+
+ p->keyid = safe_strdup ((char *) scratch);
+
return p;
-
- bailout:
-
- safe_free((void **)&p);
+
+bailout:
+
+ safe_free ((void **) &p);
return NULL;
}
-static void pgp_make_pgp3_fingerprint(unsigned char *buff, size_t l,
- unsigned char *digest)
+static void pgp_make_pgp3_fingerprint (unsigned char *buff, size_t l,
+ unsigned char *digest)
{
unsigned char dummy;
SHA_CTX context;
- SHA1_Init(&context);
-
+ SHA1_Init (&context);
+
dummy = buff[0] & 0x3f;
- if(dummy == PT_SUBSECKEY || dummy == PT_SUBKEY || dummy == PT_SECKEY)
+ if (dummy == PT_SUBSECKEY || dummy == PT_SUBKEY || dummy == PT_SECKEY)
dummy = PT_PUBKEY;
dummy = (dummy << 2) | 0x81;
- SHA1_Update(&context, &dummy, 1);
+ SHA1_Update (&context, &dummy, 1);
dummy = ((l - 1) >> 8) & 0xff;
- SHA1_Update(&context, &dummy, 1);
- dummy = (l - 1) & 0xff;
- SHA1_Update(&context, &dummy, 1);
- SHA1_Update(&context, buff + 1, l - 1);
- SHA1_Final(digest, &context);
+ SHA1_Update (&context, &dummy, 1);
+ dummy = (l - 1) & 0xff;
+ SHA1_Update (&context, &dummy, 1);
+ SHA1_Update (&context, buff + 1, l - 1);
+ SHA1_Final (digest, &context);
}
-static void skip_bignum(unsigned char *buff, size_t l, size_t j,
- size_t *toff, size_t n)
+static void skip_bignum (unsigned char *buff, size_t l, size_t j,
+ size_t * toff, size_t n)
{
size_t len;
-
+
do
{
- len = (buff[j] << 8) + buff[j+1];
+ len = (buff[j] << 8) + buff[j + 1];
j += (len + 7) / 8 + 2;
- } while(j <= l && --n > 0);
-
- if(toff) *toff = j;
+ }
+ while (j <= l && --n > 0);
+
+ if (toff)
+ *toff = j;
}
-
-static KEYINFO *pgp_parse_pgp3_key(unsigned char *buff, size_t l)
+
+static pgp_key_t *pgp_parse_pgp3_key (unsigned char *buff, size_t l)
{
- KEYINFO *p;
+ pgp_key_t *p;
unsigned char alg;
unsigned char digest[SHA_DIGEST_LENGTH];
unsigned char scratch[LONG_STRING];
int i, k;
short len;
size_t j;
-
- p = pgp_new_keyinfo();
+
+ p = pgp_new_keyinfo ();
j = 2;
-
- for(i = 0; i < 4; i++)
+
+ for (i = 0; i < 4; i++)
gen_time = (gen_time << 8) + buff[j++];
p->gen_time = gen_time;
-
+
alg = buff[j++];
-
- p->algorithm = pgp_pkalgbytype(alg);
- p->flags |= pgp_get_abilities(alg);
+
+ p->algorithm = pgp_pkalgbytype (alg);
+ p->flags |= pgp_get_abilities (alg);
if (alg == 17)
- skip_bignum(buff, l, j, &j, 3);
- else if(alg == 16 || alg == 20 )
- skip_bignum(buff, l, j, &j, 2);
-
- len = (buff[j] << 8) + buff[j+1];
+ skip_bignum (buff, l, j, &j, 3);
+ else if (alg == 16 || alg == 20)
+ skip_bignum (buff, l, j, &j, 2);
+
+ len = (buff[j] << 8) + buff[j + 1];
p->keylen = len;
- if (alg >=1 && alg <= 3)
- skip_bignum(buff, l, j, &j, 2);
- else if(alg == 17 || alg == 16)
- skip_bignum(buff, l, j, &j, 1);
-
- pgp_make_pgp3_fingerprint(buff, j, digest);
+ if (alg >= 1 && alg <= 3)
+ skip_bignum (buff, l, j, &j, 2);
+ else if (alg == 17 || alg == 16)
+ skip_bignum (buff, l, j, &j, 1);
+
+ pgp_make_pgp3_fingerprint (buff, j, digest);
- for(k = 0; k < 2; k++)
+ for (k = 0; k < 2; k++)
{
- for(id = 0, i = SHA_DIGEST_LENGTH - 8 + k*4;
- i < SHA_DIGEST_LENGTH + (k - 1) * 4; i++)
+ for (id = 0, i = SHA_DIGEST_LENGTH - 8 + k * 4;
+ i < SHA_DIGEST_LENGTH + (k - 1) * 4; i++)
id = (id << 8) + digest[i];
-
- snprintf((char *)scratch + k * 8, sizeof(scratch) - k * 8, "%08lX", id);
+
+ snprintf ((char *) scratch + k * 8, sizeof (scratch) - k * 8, "%08lX", id);
}
-
- p->keyid = safe_strdup((char *)scratch);
-
+
+ p->keyid = safe_strdup ((char *) scratch);
+
return p;
}
-static KEYINFO *pgp_parse_keyinfo(unsigned char *buff, size_t l)
+static pgp_key_t *pgp_parse_keyinfo (unsigned char *buff, size_t l)
{
- if(!buff || l < 2)
+ if (!buff || l < 2)
return NULL;
dprint (5, (debugfile, " version: %d ", buff[1]));
-
- switch(buff[1])
+
+ switch (buff[1])
{
- case 2:
- case 3:
- return pgp_parse_pgp2_key(buff, l);
- case 4:
- return pgp_parse_pgp3_key(buff, l);
- default:
- return NULL;
+ case 2:
+ case 3:
+ return pgp_parse_pgp2_key (buff, l);
+ case 4:
+ return pgp_parse_pgp3_key (buff, l);
+ default:
+ return NULL;
}
}
-static int pgp_parse_pgp2_sig(unsigned char *buff, size_t l, KEYINFO *p)
+static int pgp_parse_pgp2_sig (unsigned char *buff, size_t l, pgp_key_t * p)
{
unsigned char sigtype;
long sig_gen_time;
unsigned long signerid;
size_t j;
int i;
-
- if(l < 22)
+
+ if (l < 22)
return -1;
-
+
j = 3;
sigtype = buff[j++];
-
+
sig_gen_time = 0;
- for(i = 0; i < 4; i++)
+ for (i = 0; i < 4; i++)
sig_gen_time = (sig_gen_time << 8) + buff[j++];
-
+
j += 4;
signerid = 0;
- for(i = 0; i < 4; i++)
+ for (i = 0; i < 4; i++)
signerid = (signerid << 8) + buff[j++];
-
- if(sigtype == 0x20 || sigtype == 0x28)
+
+ if (sigtype == 0x20 || sigtype == 0x28)
p->flags |= KEYFLAG_REVOKED;
-
+
return 0;
}
-static int pgp_parse_pgp3_sig(unsigned char *buff, size_t l, KEYINFO *p)
+static int pgp_parse_pgp3_sig (unsigned char *buff, size_t l, pgp_key_t * p)
{
unsigned char sigtype;
unsigned char pkalg;
size_t j;
int i;
short ii;
- short have_critical_spks=0;
-
- if(l < 7)
+ short have_critical_spks = 0;
+
+ if (l < 7)
return -1;
-
+
j = 2;
-
+
sigtype = buff[j++];
pkalg = buff[j++];
hashalg = buff[j++];
-
- for(ii = 0; ii < 2; ii++)
+
+ for (ii = 0; ii < 2; ii++)
{
size_t skl;
size_t nextone;
-
- ml = (buff[j] << 8) + buff[j+1];
+
+ ml = (buff[j] << 8) + buff[j + 1];
j += 2;
-
- if(j + ml > l) break;
-
+
+ if (j + ml > l)
+ break;
+
nextone = j;
- while(ml)
+ while (ml)
{
j = nextone;
skl = buff[j++];
- if(!--ml) break;
-
- if(skl >= 192)
+ if (!--ml)
+ break;
+
+ if (skl >= 192)
{
skl = (skl - 192) * 256 + buff[j++] + 192;
- if(!--ml) break;
+ if (!--ml)
+ break;
}
-
- if((int) ml - (int) skl < 0)
+
+ if ((int) ml - (int) skl < 0)
break;
ml -= skl;
-
+
nextone = j + skl;
skt = buff[j++];
-
- switch(skt & 0x7f)
+
+ switch (skt & 0x7f)
{
- case 2: /* creation time */
+ case 2: /* creation time */
{
- if(skl < 4)
+ if (skl < 4)
break;
sig_gen_time = 0;
- for(i = 0; i < 4; i++)
+ for (i = 0; i < 4; i++)
sig_gen_time = (sig_gen_time << 8) + buff[j++];
-
+
break;
}
- case 3: /* expiration time */
+ case 3: /* expiration time */
{
- if(skl < 4)
+ if (skl < 4)
break;
validity = 0;
- for(i = 0; i < 4; i++)
+ for (i = 0; i < 4; i++)
validity = (validity << 8) + buff[j++];
break;
}
- case 9: /* key expiration time */
+ case 9: /* key expiration time */
{
- if(skl < 4)
+ if (skl < 4)
break;
key_validity = 0;
- for(i = 0; i < 4; i++)
+ for (i = 0; i < 4; i++)
key_validity = (key_validity << 8) + buff[j++];
break;
}
- case 16: /* issuer key ID */
+ case 16: /* issuer key ID */
{
- if(skl < 8)
+ if (skl < 8)
break;
j += 4;
signerid = 0;
- for(i = 0; i < 4; i++)
+ for (i = 0; i < 4; i++)
signerid = (signerid << 8) + buff[j++];
break;
}
- case 10: /* CMR key */ break;
- case 4: /* exportable */
- case 5: /* trust */
- case 6: /* regexp */
- case 7: /* revocable */
- case 11: /* Pref. symm. alg. */
- case 12: /* revocation key */
- case 20: /* notation data */
- case 21: /* pref. hash */
- case 22: /* pref. comp.alg. */
- case 23: /* key server prefs. */
- case 24: /* pref. key server */
+ case 10: /* CMR key */
+ break;
+ case 4: /* exportable */
+ case 5: /* trust */
+ case 6: /* regexp */
+ case 7: /* revocable */
+ case 11: /* Pref. symm. alg. */
+ case 12: /* revocation key */
+ case 20: /* notation data */
+ case 21: /* pref. hash */
+ case 22: /* pref. comp.alg. */
+ case 23: /* key server prefs. */
+ case 24: /* pref. key server */
default:
{
- if(skt & 0x80)
+ if (skt & 0x80)
have_critical_spks = 1;
}
}
}
j = nextone;
}
-
- if(sigtype == 0x20 || sigtype == 0x28)
+
+ if (sigtype == 0x20 || sigtype == 0x28)
p->flags |= KEYFLAG_REVOKED;
- if(key_validity != -1 && time(NULL) > p->gen_time + key_validity)
+ if (key_validity != -1 && time (NULL) > p->gen_time + key_validity)
p->flags |= KEYFLAG_EXPIRED;
- if(have_critical_spks)
+ if (have_critical_spks)
p->flags |= KEYFLAG_CRITICAL;
return 0;
-
+
}
-
-static int pgp_parse_sig(unsigned char *buff, size_t l, KEYINFO *p)
+
+static int pgp_parse_sig (unsigned char *buff, size_t l, pgp_key_t * p)
{
- if(!buff || l < 2 || !p)
+ if (!buff || l < 2 || !p)
return -1;
-
- switch(buff[1])
+
+ switch (buff[1])
{
- case 2:
- case 3:
- return pgp_parse_pgp2_sig(buff, l, p);
- case 4:
- return pgp_parse_pgp3_sig(buff, l, p);
- default:
+ case 2:
+ case 3:
+ return pgp_parse_pgp2_sig (buff, l, p);
+ case 4:
+ return pgp_parse_pgp3_sig (buff, l, p);
+ default:
return -1;
}
}
-
-static KEYINFO *pgp_read_keyring(const char *fname)
+/* parse one key block, including all subkeys. */
+
+static pgp_key_t *pgp_parse_keyblock (FILE * fp)
{
- FILE *fp;
unsigned char *buff;
unsigned char pt = 0;
unsigned char last_pt;
size_t l;
- KEYINFO *db = NULL, **end, *p = NULL;
- KEYINFO *supkey = NULL;
- PGPUID *uid = NULL;
- LIST **addr = NULL;
- CHARSET *chs = mutt_get_charset(Charset);
+ short err = 0;
+
+ fpos_t pos;
- if(!(fp = fopen(fname, "r")))
- {
- mutt_perror("fopen");
- return NULL;
-
- }
+ pgp_key_t *root = NULL;
+ pgp_key_t **last = &root;
+ pgp_key_t *p = NULL;
+ pgp_uid_t *uid = NULL;
+ pgp_uid_t **addr = NULL;
+
+ CHARSET *chs = mutt_get_charset (Charset);
- end = &db;
+ fgetpos (fp, &pos);
- while((buff = pgp_read_packet(fp, &l)) != NULL)
+ while (!err && (buff = pgp_read_packet (fp, &l)) != NULL)
{
last_pt = pt;
pt = buff[0] & 0x3f;
- if(l < 1)
- continue;
-
- switch(pt)
+ /* check if we have read the complete key block. */
+
+ if ((pt == PT_SECKEY || pt == PT_PUBKEY) && root)
+ {
+ fsetpos (fp, &pos);
+ return root;
+ }
+
+ switch (pt)
{
case PT_SECKEY:
case PT_PUBKEY:
case PT_SUBKEY:
case PT_SUBSECKEY:
{
- switch (pt)
+ if (!(*last = p = pgp_parse_keyinfo (buff, l)))
{
- case PT_SECKEY: dprint (5, (debugfile, "PT_SECKEY: ")); break;
- case PT_PUBKEY: dprint (5, (debugfile, "PT_PUBKEY: ")); break;
- case PT_SUBKEY: dprint (5, (debugfile, "PT_SUBKEY: ")); break;
- case PT_SUBSECKEY: dprint (5, (debugfile, "PT_SUBSECKEY: ")); break;
+ err = 1;
+ break;
}
- if(p)
- end = &(p->next);
-
- if(!(*end = p = pgp_parse_keyinfo(buff, l)))
- break;
-
- dprint (5, (debugfile, " key-id: %s ", p->keyid));
-
+ last = &p->next;
addr = &p->address;
-
- if(pt == PT_SUBKEY || pt == PT_SUBSECKEY)
+
+ if (pt == PT_SUBKEY || pt == PT_SUBSECKEY)
{
p->flags |= KEYFLAG_SUBKEY;
- p->mainkey = supkey;
+ if (p != root)
+ p->parent = root;
}
- else
- supkey = p;
-
break;
}
-
+
case PT_SIG:
{
dprint (5, (debugfile, "PT_SIG\n"));
- pgp_parse_sig(buff, l, p);
+ pgp_parse_sig (buff, l, p);
break;
}
+
case PT_TRUST:
{
dprint (5, (debugfile, "PT_TRUST: "));
- if(last_pt == PT_SECKEY || last_pt == PT_PUBKEY ||
- last_pt == PT_SUBKEY || last_pt == PT_SUBSECKEY)
+ if (p && (last_pt == PT_SECKEY || last_pt == PT_PUBKEY ||
+ last_pt == PT_SUBKEY || last_pt == PT_SUBSECKEY))
{
- if(buff[1] & 0x20)
+ if (buff[1] & 0x20)
{
dprint (5, (debugfile, " disabling %s\n", p->keyid));
p->flags |= KEYFLAG_DISABLED;
}
}
- else if(last_pt == PT_NAME)
+ else if (last_pt == PT_NAME && uid)
{
uid->trust = buff[1];
- dprint (5, (debugfile, " setting trust for \"%s\" to %d.\n",
- uid->addr, uid->trust));
+ dprint (5, (debugfile, " setting trust for \"%s\" to %d.\n",
+ uid->addr, uid->trust));
}
break;
}
char *chr;
dprint (5, (debugfile, "PT_NAME: "));
-
- if(!addr) break;
-
- chr = safe_malloc(l);
- memcpy(chr, buff + 1, l - 1);
- chr[l-1] = '\0';
-
+
+ if (!addr)
+ break;
+
+ chr = safe_malloc (l);
+ memcpy (chr, buff + 1, l - 1);
+ chr[l - 1] = '\0';
+
dprint (5, (debugfile, "\"%s\"\n", chr));
-
- mutt_decode_utf8_string(chr, chs);
- *addr = mutt_new_list();
- (*addr)->data = safe_malloc(sizeof(PGPUID));
- uid = (PGPUID *) (*addr)->data;
+
+ mutt_decode_utf8_string (chr, chs);
+ *addr = uid = safe_calloc (sizeof (pgp_uid_t), 1); /* XXX */
uid->addr = chr;
+ uid->parent = p;
uid->trust = 0;
- addr = &(*addr)->next;
-
+ addr = &uid->next;
+
/* the following tags are generated by
* pgp 2.6.3in.
*/
-
- if(strstr(chr, "ENCR"))
+
+ if (strstr (chr, "ENCR"))
p->flags |= KEYFLAG_PREFER_ENCRYPTION;
- if(strstr(chr, "SIGN"))
+ if (strstr (chr, "SIGN"))
p->flags |= KEYFLAG_PREFER_SIGNING;
-
+
break;
}
}
- }
- fclose(fp);
-
-#ifdef DEBUG
- if (debuglevel >= 4)
- {
- KEYINFO *dbp;
- LIST *lp;
- fprintf (debugfile, "\n\npgp_read_keyring: START KEYRING DUMP.\n");
-
- for (dbp = db; dbp; dbp = dbp->next)
- {
- fprintf (debugfile, "%s [len=%d, flags=%d]\n", dbp->keyid, dbp->keylen, dbp->flags);
- for (lp = dbp->address; lp; lp=lp->next)
- {
- fprintf (debugfile, " %s [%d]\n", ((PGPUID *)lp->data)->addr,
- ((PGPUID *)lp->data)->trust);
- }
- }
-
- fprintf (debugfile, "\nEND KEYRING DUMP.\n\n");
+ fgetpos (fp, &pos);
}
-#endif
+
+ if (err)
+ pgp_free_key (&root);
- return db;
+ return root;
}
-KEYINFO *pgp_read_pubring(struct pgp_vinfo *pgp)
+int pgp_string_matches_hint (const char *s, LIST * hints)
{
- return pgp_read_keyring(NONULL(*pgp->pubring));
-}
+ if (!hints)
+ return 1;
-KEYINFO *pgp_read_secring(struct pgp_vinfo *pgp)
-{
- return pgp_read_keyring(NONULL(*pgp->secring));
+ for (; hints; hints = hints->next)
+ {
+ if (mutt_stristr (s, (char *) hints->data) != NULL)
+ return 1;
+ }
+
+ return 0;
}
-void pgp_close_keydb (KEYINFO **ki)
+/* Go through the key ring file and look for keys with
+ * matching IDs.
+ */
+
+pgp_key_t *pgp_get_candidates (struct pgp_vinfo * pgp, pgp_ring_t keyring,
+ LIST * hints)
{
- KEYINFO *tmp, *k = *ki;
- PGPUID *uid;
- LIST *p, *q;
-
- while (k)
+ char *ringfile;
+ FILE *rfp;
+ fpos_t pos, keypos;
+
+ unsigned char *buff = NULL;
+ unsigned char pt = 0;
+ size_t l = 0;
+
+ CHARSET *chs = mutt_get_charset (Charset);
+
+ pgp_key_t *keys = NULL;
+ pgp_key_t **last = &keys;
+ short err = 0;
+
+ switch (keyring)
+ {
+ case PGP_PUBRING:
+ ringfile = *pgp->pubring;
+ break;
+ case PGP_SECRING:
+ ringfile = *pgp->secring;
+ break;
+ default:
+ return NULL;
+ }
+
+ if ((rfp = fopen (ringfile, "r")) == NULL)
+ {
+ mutt_perror ("fopen");
+ return NULL;
+ }
+
+ fgetpos (rfp, &pos);
+ fgetpos (rfp, &keypos);
+
+ while (!err && (buff = pgp_read_packet (rfp, &l)) != NULL)
{
- if (k->keyid) safe_free ((void **)&k->keyid);
- for(q = k->address; q; q = p)
+ pt = buff[0] & 0x3f;
+
+ if (l < 1)
+ continue;
+
+ if ((pt == PT_SECKEY) || (pt == PT_PUBKEY))
+ {
+ keypos = pos;
+ }
+ else if (pt == PT_NAME)
{
- uid = (PGPUID *) q->data;
- p = q->next;
+ char *tmp = safe_malloc (l);
- safe_free((void **)&uid->addr);
- safe_free((void **)&q->data);
- safe_free((void **)&q);
+ memcpy (tmp, buff + 1, l - 1);
+ tmp[l - 1] = '\0';
+ mutt_decode_utf8_string (tmp, chs);
+
+ if (pgp_string_matches_hint (tmp, hints))
+ {
+ pgp_key_t *p;
+
+ fsetpos (rfp, &keypos);
+
+ /* Not bailing out here would lead us into an endless loop. */
+
+ if ((*last = pgp_parse_keyblock (rfp)) == NULL)
+ err = 1;
+
+ for (p = *last; p; p = p->next)
+ last = &p->next;
+ }
+
+ safe_free ((void **) &tmp);
}
- tmp = k;
- k = k->next;
- safe_free ((void **)&tmp);
+
+ fgetpos (rfp, &pos);
}
- *ki = NULL;
+
+ fclose (rfp);
+
+ return keys;
}
const char *elsestring,
unsigned long data,
format_flag flags);
+const char *mutt_stristr (const char *, const char *);
+
char *mutt_charset_hook (const char *);
char *mutt_expand_path (char *, size_t);