assuan interface for gpgme

Marcus Brinkmann marcus.brinkmann at ruhr-uni-bochum.de
Wed Feb 18 12:02:24 CET 2009


Hi,

I have a couple of interface change suggestions for the assuan operations.
They fall into two groups: Correctness with the asynchronous variant and
consistency with the other interfaces.

Werner Koch wrote:
> This callback is used for 'INQUIRE ' lines.  NAME is the name of the
> inquiry and ARGS gives the rest of the line.  An inquiry is used by a
> server to retrieve additional data from the client.  If the client has
> this data available it needs to use the SENDFNC to send the data back to
> the server like this:
> 
>     err = sendfnc (sendfnc_value, my_data, my_datalen);

I think we should use a gpgme_assuan_send function that does the dispatch to
the sendfnc.  We use user provided function pointers in the interface, but
this would introduce gpgme provided function pointers in the interface as
well, and I don't think that's necessary.  One reason is that this way we can
catch all calls into GPGME with a regex breakpoint on gpgme_*.

> If the server returns an error this error should be the return value of
> the inquiry.  This send function may be called as often as required.

This is fine for the synchronous variant, but I have some doubts about the
validity of this interface in the asynchronous variant, as sending inquire
data may block.

Instead, the user could indicate if there is more data to be returned by
setting a flag in a return value slot, and GPGME can keep calling the inquire
callback when sending data is possible until the user is satisfied.

If we also provide a buffer for the user to fill, then no send callback is
necessary.

[...]

> To make the synchronous and asynchronous versions similar, the error
> code from gpgme_op_assuan_transact does only return errors pertaining to
> the use Assuan connection and gpgme itself; it does not return the
> result of the actual Assuan command (OK or ERR).  To get that result you
> use:
> 
>     err = gpgme_op_assuan_result (ctx);
> 
> which returns 0 for the 'OK' line and an gpg-error code for the 'ERR
> <n>' line.

For consistency and extensibility, we should return a struct, just as with all
the other result functions.

> The connection is kept open regardless of this return
> value.

[...]

> and because we do not want to send another command, we close the
> connection by releasing the context:
>   
>     gpgme_release (ctx);

We should add a gpgme_op_assuan_end function, as we have for keylistings.  No
need to trash a perfectly reasonably context to disconnect.

> The remaining question is how to use a different socket than the default
> one sued for gpg-agent.  We use the engine set_info function to
> accomplish this: Right after creating the context you may call
> 
>      err = gpgme_ctx_set_engine_info (ctx, GPGME_PROTOCOL_ASSUAN,
>                                       "/tmp/foo/socket",
>                                       "");
> 
> to connect to an Assuan server listening on socket /tmp/foo/socket.
> Note that the last parameter is an empty string.  If you would use NULL,
> here the gpgme default value would be used which is an option to run the
> initial Assuan commands used for gpg-agent.  Right, we are re-using
> HOME_DIR parameter to pass flags to the engine.

I don't think home_dir should be overloaded in this way.  In fact, there is no
need to have this mechanism: Options can be passed as assuan commands using
transact the normal way, that's the whole purpose of the protocol.  Using
default options for the default gpg-agent is a convenience that is arguably
worth to have, but setting any engine infos explicitly should void this
convenience behavior as well.  My preference however would be to just require
home_dir to be NULL at all times, and to not have any default commands, and
instead provide a convenience function

gpgme_error_t gpgme_op_assuan_init_gpg_agent (ctx);

or similar that sends the default commands for a gpg-agent connection.  That
way there is no inconsistency and no difficulty in understanding and extending
the interface.  This also avoids sending commands at connection time, which is
good for reliability in the asynchronous variant (in case the server blocks
errornously).

Thanks,
Marcus




More information about the Gnupg-devel mailing list