Changeset 5438:8e2438ec5909

Show
Ignore:
Timestamp:
2008-07-01 17:20:02 (2 months ago)
Author:
Brendan Cully <brendan@…>
Branch:
HEAD
Message:

Support displaying application/pgp-keys with GPGME.
This was pretty convoluted because GPGME provides no way to examine a
key block without importing it. This code creates a temporary GPG home
in which to import the key in order to display it.

Files:
3 modified

Legend:

Unmodified
Added
Removed
  • crypt-gpgme.c

    r5437 r5438  
    18391839} 
    18401840 
     1841static int pgp_gpgme_extract_keys (gpgme_data_t keydata, FILE** fp) 
     1842{ 
     1843  /* there's no side-effect free way to view key data in GPGME, 
     1844   * so we import the key into a temporary keyring */ 
     1845  char tmpdir[_POSIX_PATH_MAX]; 
     1846  char tmpfile[_POSIX_PATH_MAX]; 
     1847  gpgme_ctx_t tmpctx; 
     1848  gpgme_error_t err; 
     1849  gpgme_engine_info_t engineinfo; 
     1850  gpgme_key_t key; 
     1851  gpgme_user_id_t uid; 
     1852  gpgme_subkey_t subkey; 
     1853  const char* shortid; 
     1854  int len; 
     1855  char date[STRING]; 
     1856  int more; 
     1857  int rc = -1; 
     1858 
     1859  snprintf (tmpdir, sizeof(tmpdir), "%s/mutt-gpgme-XXXXXX", Tempdir); 
     1860  if (!mkdtemp (tmpdir)) 
     1861  { 
     1862    dprint (1, (debugfile, "Error creating temporary GPGME home\n")); 
     1863    return rc; 
     1864  } 
     1865 
     1866  if ((err = gpgme_new (&tmpctx)) != GPG_ERR_NO_ERROR) 
     1867  { 
     1868    dprint (1, (debugfile, "Error creating GPGME context\n")); 
     1869    goto err_tmpdir; 
     1870  } 
     1871 
     1872  engineinfo = gpgme_ctx_get_engine_info (tmpctx); 
     1873  while (engineinfo && engineinfo->protocol != GPGME_PROTOCOL_OpenPGP) 
     1874    engineinfo = engineinfo->next; 
     1875  if (!engineinfo) 
     1876  { 
     1877    dprint (1, (debugfile, "Error finding GPGME PGP engine\n")); 
     1878    goto err_ctx; 
     1879  } 
     1880   
     1881  err = gpgme_ctx_set_engine_info (tmpctx, GPGME_PROTOCOL_OpenPGP, 
     1882                                   engineinfo->file_name, tmpdir); 
     1883  if (err != GPG_ERR_NO_ERROR) 
     1884  { 
     1885    dprint (1, (debugfile, "Error setting GPGME context home\n")); 
     1886    goto err_ctx; 
     1887  } 
     1888 
     1889  if ((err = gpgme_op_import (tmpctx, keydata)) != GPG_ERR_NO_ERROR) 
     1890  { 
     1891    dprint (1, (debugfile, "Error importing key\n")); 
     1892    goto err_ctx; 
     1893  } 
     1894 
     1895  mutt_mktemp (tmpfile); 
     1896  *fp = safe_fopen (tmpfile, "w+"); 
     1897  if (!*fp) 
     1898  { 
     1899    mutt_perror (tmpfile); 
     1900    goto err_ctx; 
     1901  } 
     1902  unlink (tmpfile); 
     1903 
     1904  err = gpgme_op_keylist_start (tmpctx, NULL, 0); 
     1905  while (!err) 
     1906  { 
     1907    if ((err = gpgme_op_keylist_next (tmpctx, &key))) 
     1908      break; 
     1909    uid = key->uids; 
     1910    subkey = key->subkeys; 
     1911    more = 0; 
     1912    while (subkey) 
     1913    { 
     1914      shortid = subkey->keyid; 
     1915      len = mutt_strlen (subkey->keyid); 
     1916      if (len > 8) 
     1917        shortid += len - 8; 
     1918      strftime (date, sizeof (date), "%Y-%m-%d", localtime (&subkey->timestamp)); 
     1919 
     1920      if (!more) 
     1921        fprintf (*fp, "%s %5.5s %d/%8s %s %s\n", more ? "sub" : "pub", 
     1922                 gpgme_pubkey_algo_name (subkey->pubkey_algo), subkey->length, 
     1923                 shortid, date, uid->uid); 
     1924      else 
     1925        fprintf (*fp, "%s %5.5s %d/%8s %s\n", more ? "sub" : "pub", 
     1926                 gpgme_pubkey_algo_name (subkey->pubkey_algo), subkey->length, 
     1927                 shortid, date);       
     1928      subkey = subkey->next; 
     1929      more = 1; 
     1930    } 
     1931    gpgme_key_release (key); 
     1932  } 
     1933  if (gpg_err_code (err) != GPG_ERR_EOF) 
     1934  { 
     1935    dprint (1, (debugfile, "Error listing keys\n")); 
     1936    goto err_fp; 
     1937  } 
     1938 
     1939  rc = 0; 
     1940 
     1941err_fp: 
     1942  if (rc) 
     1943  { 
     1944    fclose (*fp); 
     1945    *fp = NULL; 
     1946  } 
     1947err_ctx: 
     1948  gpgme_release (tmpctx); 
     1949err_tmpdir: 
     1950  mutt_rmtree (tmpdir); 
     1951 
     1952  return rc; 
     1953} 
    18411954 
    18421955/*  
     
    20652178          armored_data = file_to_data_object (s->fpin, m->offset, m->length); 
    20662179          /* Invoke PGP if needed */ 
    2067           if (!clearsign || (s->flags & M_VERIFY)) 
     2180          if (pgp_keyblock) 
     2181          { 
     2182            pgp_gpgme_extract_keys (armored_data, &pgpout); 
     2183          } 
     2184          else if (!clearsign || (s->flags & M_VERIFY)) 
    20682185            { 
    20692186              unsigned int sig_stat = 0; 
  • lib.c

    r5427 r5438  
    4242#include <fcntl.h> 
    4343#include <pwd.h> 
     44#include <dirent.h> 
    4445 
    4546#ifdef HAVE_SYSEXITS_H 
     
    575576  snprintf (newfile, nflen, "%s/%s", newdir, NONULL(basename)); 
    576577  return 0;   
     578} 
     579 
     580/* remove a directory and everything under it */ 
     581int mutt_rmtree (const char* path) 
     582{ 
     583  DIR* dirp; 
     584  struct dirent* de; 
     585  char cur[_POSIX_PATH_MAX]; 
     586  int rc = 0; 
     587 
     588  if (!(dirp = opendir (path))) 
     589  { 
     590    dprint (1, (debugfile, "mutt_rmtree: error opening directory %s\n", path)); 
     591    return -1; 
     592  } 
     593  while ((de = readdir (dirp))) 
     594  { 
     595    if (!strcmp (".", de->d_name) || !strcmp ("..", de->d_name)) 
     596      continue; 
     597 
     598    snprintf (cur, sizeof (cur), "%s/%s", path, de->d_name); 
     599    /* XXX make nonrecursive version */ 
     600    if (de->d_type == DT_DIR) 
     601      rc |= mutt_rmtree (cur); 
     602    else 
     603      rc |= unlink (cur); 
     604  } 
     605  closedir (dirp); 
     606 
     607  rc |= rmdir (path); 
     608 
     609  return rc; 
    577610} 
    578611 
  • lib.h

    r5427 r5438  
    172172int safe_fclose (FILE **); 
    173173int safe_fsync_close (FILE **); 
     174int mutt_rmtree (const char *); 
    174175 
    175176size_t mutt_quote_filename (char *, size_t, const char *);