Fix regression with gpgsm 2.0 due to "OPTION with-secret".
* src/engine-gpgsm.c (gpgsm_assuan_simple_command): Do not terminate on a status lines. -- This bug has been with us since the support for gpgsm: If there is no status line handler but a status line is received anyway the command handling loop terminates and thus the command/answer order gets out of sync. In the case of the bug report this is triggered by sending an option which starts the agent and that starting emits a "PROGRESS" status line. The solution is not to stop reading after a status line but record a possible error code and return that only after OK or ERR. GnuPG-bug-id: 1795 Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
7addffc082
commit
ddbd54ef88
@ -564,7 +564,7 @@ gpgsm_assuan_simple_command (assuan_context_t ctx, char *cmd,
|
||||
engine_status_handler_t status_fnc,
|
||||
void *status_fnc_value)
|
||||
{
|
||||
gpg_error_t err;
|
||||
gpg_error_t err, cb_err;
|
||||
char *line;
|
||||
size_t linelen;
|
||||
|
||||
@ -572,6 +572,7 @@ gpgsm_assuan_simple_command (assuan_context_t ctx, char *cmd,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
cb_err = 0;
|
||||
do
|
||||
{
|
||||
err = assuan_read_line (ctx, &line, &linelen);
|
||||
@ -584,32 +585,45 @@ gpgsm_assuan_simple_command (assuan_context_t ctx, char *cmd,
|
||||
if (linelen >= 2
|
||||
&& line[0] == 'O' && line[1] == 'K'
|
||||
&& (line[2] == '\0' || line[2] == ' '))
|
||||
return 0;
|
||||
return cb_err;
|
||||
else if (linelen >= 4
|
||||
&& line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
|
||||
&& line[3] == ' ')
|
||||
err = atoi (&line[4]);
|
||||
{
|
||||
/* We prefer a callback generated error because that one is
|
||||
more related to gpgme and thus probably more important
|
||||
than the error returned by the engine. */
|
||||
err = cb_err? cb_err : atoi (&line[4]);
|
||||
}
|
||||
else if (linelen >= 2
|
||||
&& line[0] == 'S' && line[1] == ' ')
|
||||
{
|
||||
char *rest;
|
||||
gpgme_status_code_t r;
|
||||
/* After an error from a status callback we skip all further
|
||||
status lines. */
|
||||
if (!cb_err)
|
||||
{
|
||||
char *rest;
|
||||
gpgme_status_code_t r;
|
||||
|
||||
rest = strchr (line + 2, ' ');
|
||||
if (!rest)
|
||||
rest = line + linelen; /* set to an empty string */
|
||||
else
|
||||
*(rest++) = 0;
|
||||
rest = strchr (line + 2, ' ');
|
||||
if (!rest)
|
||||
rest = line + linelen; /* set to an empty string */
|
||||
else
|
||||
*(rest++) = 0;
|
||||
|
||||
r = _gpgme_parse_status (line + 2);
|
||||
r = _gpgme_parse_status (line + 2);
|
||||
|
||||
if (r >= 0 && status_fnc)
|
||||
err = status_fnc (status_fnc_value, r, rest);
|
||||
else
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
if (r >= 0 && status_fnc)
|
||||
cb_err = status_fnc (status_fnc_value, r, rest);
|
||||
}
|
||||
}
|
||||
else
|
||||
err = gpg_error (GPG_ERR_GENERAL);
|
||||
{
|
||||
/* Invalid line or INQUIRY. We can't do anything else than
|
||||
to stop. As with ERR we prefer a status callback
|
||||
generated error code, though. */
|
||||
err = cb_err ? cb_err : gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
}
|
||||
while (!err);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user