master password gsoc project

Richard Laager rlaager at
Sat Jun 7 00:28:03 EDT 2008

On Tue, 2008-06-03 at 09:58 +0200, Vivien Bernet-Rollande wrote:
> Some stuff might require renaming to better fit in pidgin's naming
> convention.

Indeed. ;)

> // callbacks take the account and the result of the operation.
> typedef void(*pw_callback_t)(PurpleAccount*, int);

Every callback everywhere needs to end with a "gpointer data" argument.
Every function where a callback is passed should also have a data
argument. You hang onto that data pointer and then pass it to the
callback. This allows callers to pass to their callback any arbitrary
data they wish.

You're also going to need different callbacks, though. For example, the
callback for the get_password call will need an argument where the
password will be passed. ;)

> // read/store a password using a master password
> typedef void(*pw_save_master_t)(PurpleAccount*, char *,
> pw_callback_t);
> typedef void(*pw_read_master_t)(PurpleAccount*, char *,
> pw_callback_t);

Is it necessary to have these separate callbacks? Instead, couldn't we
have a libpurple function that does the prompting? So the flow goes
something like this: The caller calls purple_get_password(). It calls
the get_password() function in the active backend. It needs a master
password, so it calls purple_..._prompt_for_password(). This prompts the
user for the password. When they enter it, the core's prompt callback
fires, which results in the backend's prompt being called which allows
it to open the safe and get the password and then call the original
caller's callback.

It's possible that this function could be the same function used to
prompt the user for an account password the first time (before it is
stored in a safe).

> // close safe (used to make sure we don't use memory when we've stopped
> using
> // the safe it. This one might not really require a callback, and could 
> return
> // an int.
> typedef void(*pw_close_t)(pw_callback_t);

You might as well make this async as well, if for no other reason than

In general, these functions can have a void return type. If the password
retrieval fails, the core would call the callback and tell it about the

> /*
> ** And, we can register our plugin.
> */
> int purple_password_storage_register(password_storage_info * info);

This function is just going to add a struct to a list, right?. There's
no way it can ever fail (where the program will keep running), so this
can have a return type of void.

See purple_log_logger_add(), for example.

> /*
> ** Also, callbacks used need to be able to return the following values :
> ** - ok
> ** - invalid master password
> ** - can't access safe
> ** - password not found
> ** Those will most likely just be #defined
> */

The error reporting should use GError:

If a backend returns an error, you propagate that up to the caller.

> ** More functions might be required, specifically if we want to have a per
> ** plugin "advanced" configuration interface, or just if I forgot something.

If we need an advanced configuration, I think it should use the same
code as the Plugins dialog's "Configure Plugin" button. (The plugins
will be hidden, so they won't show up in the Plugins dialog.)

> ** Since the main rule is to keep it simple, it should be pretty easy to
> ** add a function pointer or two in the structure.

Speaking of which... before this is merged, we'll need to throw in a
couple of reserved pointers.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: <>

More information about the Devel mailing list