3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-27 03:09:38 +01:00

agent: Ask passphrase from the user agent

Add support for asking passphrase information from the registered
user agent.
This commit is contained in:
Jukka Rissanen 2015-03-02 16:19:05 +02:00 committed by Denis Kenzior
parent e6e4649a40
commit c275fca1e3
2 changed files with 112 additions and 0 deletions

View File

@ -30,10 +30,14 @@
#include "src/dbus.h" #include "src/dbus.h"
#include "src/agent.h" #include "src/agent.h"
static unsigned int next_request_id = 0;
/* Agent dbus request is done from iwd towards the agent */ /* Agent dbus request is done from iwd towards the agent */
struct agent_request { struct agent_request {
struct l_dbus_message *message; struct l_dbus_message *message;
unsigned int id;
void *user_data; void *user_data;
void *user_callback;
}; };
struct agent { struct agent {
@ -48,6 +52,18 @@ struct agent {
static struct agent *default_agent = NULL; static struct agent *default_agent = NULL;
/*
* How long we wait for user to input things.
* Return value is in seconds.
*
* This should probably be configurable by user via
* config file/command line option/env variable.
*/
static unsigned int agent_timeout_input_request(void)
{
return 120;
}
static void send_request(struct agent *agent, const char *request) static void send_request(struct agent *agent, const char *request)
{ {
struct l_dbus_message *message; struct l_dbus_message *message;
@ -82,6 +98,26 @@ static void agent_request_free(void *user_data)
l_free(request); l_free(request);
} }
static void passphrase_reply(struct l_dbus_message *reply,
struct agent_request *request)
{
const char *error, *text;
char *passphrase = NULL;
enum agent_result result = AGENT_RESULT_FAILED;
agent_request_passphrase_func_t user_callback = request->user_callback;
if (l_dbus_message_get_error(reply, &error, &text))
goto done;
if (!l_dbus_message_get_arguments(reply, "s", &passphrase))
goto done;
result = AGENT_RESULT_OK;
done:
user_callback(result, passphrase, request->user_data);
}
static void agent_finalize_pending(struct agent *agent, static void agent_finalize_pending(struct agent *agent,
struct l_dbus_message *reply) struct l_dbus_message *reply)
{ {
@ -94,6 +130,8 @@ static void agent_finalize_pending(struct agent *agent,
pending = l_queue_pop_head(agent->requests); pending = l_queue_pop_head(agent->requests);
passphrase_reply(reply, pending);
agent_request_free(pending); agent_request_free(pending);
} }
@ -174,6 +212,67 @@ static void agent_send_next_request(struct agent *agent)
return; return;
} }
static unsigned int agent_queue_request(struct agent *agent,
struct l_dbus_message *message, int timeout,
agent_request_passphrase_func_t callback,
void *user_data)
{
struct agent_request *request;
request = l_new(struct agent_request, 1);
request->message = message;
request->id = ++next_request_id;
request->user_data = user_data;
request->user_callback = callback;
agent->timeout_secs = timeout;
l_queue_push_tail(agent->requests, request);
if (l_queue_length(agent->requests) == 1)
agent_send_next_request(agent);
return request->id;
}
/**
* agent_request_passphrase:
* @path: object path related to this request (like network object path)
* @callback: user callback called when the request is ready
* @user_data: user defined data
*
* Called when a passphrase information is needed from the user. Returns an
* id that can be used to cancel the request.
*/
unsigned int agent_request_passphrase(const char *path,
agent_request_passphrase_func_t callback,
void *user_data)
{
struct l_dbus_message *message;
struct agent *agent;
agent = default_agent;
if (!agent || !callback)
return 0;
l_debug("agent %p owner %s path %s", agent, agent->owner, agent->path);
message = l_dbus_message_new_method_call(dbus_get_bus(),
agent->owner,
agent->path,
IWD_AGENT_INTERFACE,
"RequestPassphrase");
l_dbus_message_set_arguments(message, "o", path);
return agent_queue_request(agent, message,
agent_timeout_input_request(),
callback,
user_data);
}
static void agent_disconnect(struct l_dbus *dbus, void *user_data) static void agent_disconnect(struct l_dbus *dbus, void *user_data)
{ {
struct agent *agent = user_data; struct agent *agent = user_data;

View File

@ -22,6 +22,19 @@
#include <stdbool.h> #include <stdbool.h>
enum agent_result {
AGENT_RESULT_OK,
AGENT_RESULT_FAILED,
};
typedef void (*agent_request_passphrase_func_t) (enum agent_result result,
const char *passphrase,
void *user_data);
bool agent_init(void); bool agent_init(void);
void agent_exit(void); void agent_exit(void);
bool agent_setup(struct l_dbus_interface *interface); bool agent_setup(struct l_dbus_interface *interface);
unsigned int agent_request_passphrase(const char *path,
agent_request_passphrase_func_t callback,
void *user_data);