2006-02-22 Marcus Brinkmann <marcus@g10code.de>
* rungpg.c (read_colon_line): Invoke colon preprocess handler if it is set. (colon_preprocessor_t): New type. (struct engine_gpg): New member colon.preprocess_fnc. (gpg_keylist_preprocess): New function. * keylist.c (keylist_colon_handler): Allow short key IDs.
This commit is contained in:
parent
9829cffc3c
commit
2f4b385332
5
TODO
5
TODO
@ -5,9 +5,6 @@ Hey Emacs, this is -*- outline -*- mode!
|
|||||||
The test is currently disabled there and in gpg/t-import.
|
The test is currently disabled there and in gpg/t-import.
|
||||||
** When gpg supports it, write binary subpackets directly,
|
** When gpg supports it, write binary subpackets directly,
|
||||||
and parse SUBPACKET status lines.
|
and parse SUBPACKET status lines.
|
||||||
** External key listing for OpenPGP.
|
|
||||||
This probably requires changes at gpg.
|
|
||||||
|
|
||||||
|
|
||||||
* ABI's to break:
|
* ABI's to break:
|
||||||
** gpgme_edit_cb_t: Add "processed" return argument
|
** gpgme_edit_cb_t: Add "processed" return argument
|
||||||
@ -81,7 +78,7 @@ Hey Emacs, this is -*- outline -*- mode!
|
|||||||
release everything properly at a reset and at an error. Think hard
|
release everything properly at a reset and at an error. Think hard
|
||||||
about where to guarantee what (ie, what happens if start fails, are
|
about where to guarantee what (ie, what happens if start fails, are
|
||||||
the fds unregistered immediately - i think so?)
|
the fds unregistered immediately - i think so?)
|
||||||
** Optimize the case where a data object has an underlying fd we can pass
|
** Optimize the case where a data object has 0an underlying fd we can pass
|
||||||
directly to the engine. This will be automatic with socket I/O and
|
directly to the engine. This will be automatic with socket I/O and
|
||||||
descriptor passing.
|
descriptor passing.
|
||||||
** Move code common to all engines up from gpg to engine.
|
** Move code common to all engines up from gpg to engine.
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
2006-02-22 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
* rungpg.c (read_colon_line): Invoke colon preprocess handler if
|
||||||
|
it is set.
|
||||||
|
(colon_preprocessor_t): New type.
|
||||||
|
(struct engine_gpg): New member colon.preprocess_fnc.
|
||||||
|
(gpg_keylist_preprocess): New function.
|
||||||
|
* keylist.c (keylist_colon_handler): Allow short key IDs.
|
||||||
|
|
||||||
2006-02-15 Marcus Brinkmann <marcus@g10code.de>
|
2006-02-15 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* w32-io.c (create_writer): Make C->have_data a manually resetted
|
* w32-io.c (create_writer): Make C->have_data a manually resetted
|
||||||
|
@ -176,7 +176,8 @@ set_mainkey_trust_info (gpgme_key_t key, const char *src)
|
|||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
/* Note that gpg 1.3 won't print that anymore but only uses
|
/* Note that gpg 1.3 won't print that anymore but only uses
|
||||||
the capabilities field. */
|
the capabilities field. However, it is still used for
|
||||||
|
external key listings. */
|
||||||
key->disabled = 1;
|
key->disabled = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -493,8 +494,9 @@ keylist_colon_handler (void *priv, char *line)
|
|||||||
subkey->pubkey_algo = i;
|
subkey->pubkey_algo = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Field 5 has the long keyid. */
|
/* Field 5 has the long keyid. Allow short key IDs for the
|
||||||
if (fields >= 5 && strlen (field[4]) == DIM(subkey->_keyid) - 1)
|
output of an external keyserver listing. */
|
||||||
|
if (fields >= 5 && strlen (field[4]) <= DIM(subkey->_keyid) - 1)
|
||||||
strcpy (subkey->_keyid, field[4]);
|
strcpy (subkey->_keyid, field[4]);
|
||||||
|
|
||||||
/* Field 6 has the timestamp (seconds). */
|
/* Field 6 has the timestamp (seconds). */
|
||||||
|
124
gpgme/rungpg.c
124
gpgme/rungpg.c
@ -65,6 +65,8 @@ struct fd_data_map_s
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef gpgme_error_t (*colon_preprocessor_t) (char *line, char **rline);
|
||||||
|
|
||||||
struct engine_gpg
|
struct engine_gpg
|
||||||
{
|
{
|
||||||
char *file_name;
|
char *file_name;
|
||||||
@ -95,6 +97,7 @@ struct engine_gpg
|
|||||||
engine_colon_line_handler_t fnc; /* this indicate use of this structrue */
|
engine_colon_line_handler_t fnc; /* this indicate use of this structrue */
|
||||||
void *fnc_value;
|
void *fnc_value;
|
||||||
void *tag;
|
void *tag;
|
||||||
|
colon_preprocessor_t preprocess_fnc;
|
||||||
} colon;
|
} colon;
|
||||||
|
|
||||||
char **argv;
|
char **argv;
|
||||||
@ -1013,14 +1016,27 @@ read_colon_line (engine_gpg_t gpg)
|
|||||||
{
|
{
|
||||||
/* (we require that the last line is terminated by a LF)
|
/* (we require that the last line is terminated by a LF)
|
||||||
and we skip empty lines. Note: we use UTF8 encoding
|
and we skip empty lines. Note: we use UTF8 encoding
|
||||||
and escaping of special characters We require at
|
and escaping of special characters. We require at
|
||||||
least one colon to cope with some other printed
|
least one colon to cope with some other printed
|
||||||
information. */
|
information. */
|
||||||
*p = 0;
|
*p = 0;
|
||||||
if (*buffer && strchr (buffer, ':'))
|
if (*buffer && strchr (buffer, ':'))
|
||||||
{
|
{
|
||||||
|
char *line = NULL;
|
||||||
|
|
||||||
|
if (gpg->colon.preprocess_fnc)
|
||||||
|
{
|
||||||
|
gpgme_error_t err;
|
||||||
|
|
||||||
|
err = gpg->colon.preprocess_fnc (buffer, &line);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
assert (gpg->colon.fnc);
|
assert (gpg->colon.fnc);
|
||||||
gpg->colon.fnc (gpg->colon.fnc_value, buffer);
|
gpg->colon.fnc (gpg->colon.fnc_value, line ? line : buffer);
|
||||||
|
if (line)
|
||||||
|
free (line);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* To reuse the buffer for the next line we have to
|
/* To reuse the buffer for the next line we have to
|
||||||
@ -1613,6 +1629,93 @@ gpg_import (void *engine, gpgme_data_t keydata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The output for external keylistings in GnuPG is different from all
|
||||||
|
the other key listings. We catch this here with a special
|
||||||
|
preprocessor that reformats the colon handler lines. */
|
||||||
|
static gpgme_error_t
|
||||||
|
gpg_keylist_preprocess (char *line, char **r_line)
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
RT_NONE, RT_INFO, RT_PUB, RT_UID
|
||||||
|
}
|
||||||
|
rectype = RT_NONE;
|
||||||
|
#define NR_FIELDS 16
|
||||||
|
char *field[NR_FIELDS];
|
||||||
|
int fields = 0;
|
||||||
|
|
||||||
|
*r_line = NULL;
|
||||||
|
|
||||||
|
while (line && fields < NR_FIELDS)
|
||||||
|
{
|
||||||
|
field[fields++] = line;
|
||||||
|
line = strchr (line, ':');
|
||||||
|
if (line)
|
||||||
|
*(line++) = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp (field[0], "info"))
|
||||||
|
rectype = RT_INFO;
|
||||||
|
else if (!strcmp (field[0], "pub"))
|
||||||
|
rectype = RT_PUB;
|
||||||
|
else if (!strcmp (field[0], "uid"))
|
||||||
|
rectype = RT_UID;
|
||||||
|
else
|
||||||
|
rectype = RT_NONE;
|
||||||
|
|
||||||
|
switch (rectype)
|
||||||
|
{
|
||||||
|
case RT_INFO:
|
||||||
|
/* FIXME: Eventually, check the version number at least. */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case RT_PUB:
|
||||||
|
if (fields < 7)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* The format is:
|
||||||
|
|
||||||
|
pub:<keyid>:<algo>:<keylen>:<creationdate>:<expirationdate>:<flags>
|
||||||
|
|
||||||
|
as defined in 5.2. Machine Readable Indexes of the OpenPGP
|
||||||
|
HTTP Keyserver Protocol (draft).
|
||||||
|
|
||||||
|
We want:
|
||||||
|
pub:o<flags>:<keylen>:<algo>:<keyid>:<creatdate>:<expdate>::::::::
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (asprintf (r_line, "pub:o%s:%s:%s:%s:%s:%s::::::::",
|
||||||
|
field[6], field[3], field[2], field[1],
|
||||||
|
field[4], field[5]) < 0)
|
||||||
|
return gpg_error_from_errno (errno);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case RT_UID:
|
||||||
|
/* The format is:
|
||||||
|
|
||||||
|
uid:<escaped uid string>:<creationdate>:<expirationdate>:<flags>
|
||||||
|
|
||||||
|
as defined in 5.2. Machine Readable Indexes of the OpenPGP
|
||||||
|
HTTP Keyserver Protocol (draft).
|
||||||
|
|
||||||
|
We want:
|
||||||
|
uid:o<flags>::::<creatdate>:<expdate>:::<uid>:
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (asprintf (r_line, "uid:o%s::::%s:%s:::%s:",
|
||||||
|
field[4], field[2], field[3], field[1]) < 0)
|
||||||
|
return gpg_error_from_errno (errno);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case RT_NONE:
|
||||||
|
/* Unknown record. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static gpgme_error_t
|
static gpgme_error_t
|
||||||
gpg_keylist (void *engine, const char *pattern, int secret_only,
|
gpg_keylist (void *engine, const char *pattern, int secret_only,
|
||||||
gpgme_keylist_mode_t mode)
|
gpgme_keylist_mode_t mode)
|
||||||
@ -1620,6 +1723,13 @@ gpg_keylist (void *engine, const char *pattern, int secret_only,
|
|||||||
engine_gpg_t gpg = engine;
|
engine_gpg_t gpg = engine;
|
||||||
gpgme_error_t err;
|
gpgme_error_t err;
|
||||||
|
|
||||||
|
if (mode & GPGME_KEYLIST_MODE_EXTERN)
|
||||||
|
{
|
||||||
|
if ((mode & GPGME_KEYLIST_MODE_LOCAL)
|
||||||
|
|| secret_only)
|
||||||
|
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
err = add_arg (gpg, "--with-colons");
|
err = add_arg (gpg, "--with-colons");
|
||||||
if (!err)
|
if (!err)
|
||||||
err = add_arg (gpg, "--fixed-list-mode");
|
err = add_arg (gpg, "--fixed-list-mode");
|
||||||
@ -1635,9 +1745,19 @@ gpg_keylist (void *engine, const char *pattern, int secret_only,
|
|||||||
err = add_arg (gpg, "show-sig-subpackets=\"20,26\"");
|
err = add_arg (gpg, "show-sig-subpackets=\"20,26\"");
|
||||||
}
|
}
|
||||||
if (!err)
|
if (!err)
|
||||||
|
{
|
||||||
|
if (mode & GPGME_KEYLIST_MODE_EXTERN)
|
||||||
|
{
|
||||||
|
err = add_arg (gpg, "--search-keys");
|
||||||
|
gpg->colon.preprocess_fnc = gpg_keylist_preprocess;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
err = add_arg (gpg, secret_only ? "--list-secret-keys"
|
err = add_arg (gpg, secret_only ? "--list-secret-keys"
|
||||||
: ((mode & GPGME_KEYLIST_MODE_SIGS)
|
: ((mode & GPGME_KEYLIST_MODE_SIGS)
|
||||||
? "--check-sigs" : "--list-keys"));
|
? "--check-sigs" : "--list-keys"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Tell the gpg object about the data. */
|
/* Tell the gpg object about the data. */
|
||||||
if (!err)
|
if (!err)
|
||||||
|
Loading…
Reference in New Issue
Block a user