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,
|
engine_status_handler_t status_fnc,
|
||||||
void *status_fnc_value)
|
void *status_fnc_value)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err, cb_err;
|
||||||
char *line;
|
char *line;
|
||||||
size_t linelen;
|
size_t linelen;
|
||||||
|
|
||||||
@ -572,6 +572,7 @@ gpgsm_assuan_simple_command (assuan_context_t ctx, char *cmd,
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
cb_err = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
err = assuan_read_line (ctx, &line, &linelen);
|
err = assuan_read_line (ctx, &line, &linelen);
|
||||||
@ -584,13 +585,22 @@ gpgsm_assuan_simple_command (assuan_context_t ctx, char *cmd,
|
|||||||
if (linelen >= 2
|
if (linelen >= 2
|
||||||
&& line[0] == 'O' && line[1] == 'K'
|
&& line[0] == 'O' && line[1] == 'K'
|
||||||
&& (line[2] == '\0' || line[2] == ' '))
|
&& (line[2] == '\0' || line[2] == ' '))
|
||||||
return 0;
|
return cb_err;
|
||||||
else if (linelen >= 4
|
else if (linelen >= 4
|
||||||
&& line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
|
&& line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
|
||||||
&& line[3] == ' ')
|
&& 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
|
else if (linelen >= 2
|
||||||
&& line[0] == 'S' && line[1] == ' ')
|
&& line[0] == 'S' && line[1] == ' ')
|
||||||
|
{
|
||||||
|
/* After an error from a status callback we skip all further
|
||||||
|
status lines. */
|
||||||
|
if (!cb_err)
|
||||||
{
|
{
|
||||||
char *rest;
|
char *rest;
|
||||||
gpgme_status_code_t r;
|
gpgme_status_code_t r;
|
||||||
@ -604,12 +614,16 @@ gpgsm_assuan_simple_command (assuan_context_t ctx, char *cmd,
|
|||||||
r = _gpgme_parse_status (line + 2);
|
r = _gpgme_parse_status (line + 2);
|
||||||
|
|
||||||
if (r >= 0 && status_fnc)
|
if (r >= 0 && status_fnc)
|
||||||
err = status_fnc (status_fnc_value, r, rest);
|
cb_err = status_fnc (status_fnc_value, r, rest);
|
||||||
else
|
}
|
||||||
err = gpg_error (GPG_ERR_GENERAL);
|
|
||||||
}
|
}
|
||||||
else
|
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);
|
while (!err);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user