summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2016-06-17 15:39:00 +0200
committerLubomir Rintel <lkundrak@v3.sk>2016-06-23 18:54:28 +0200
commit0f5d372d5dbc3cb563dc14f49f4a5684918a07f8 (patch)
treed3321f9d5099f6b5a920d7cc9ddd0f1afb1b9763
parent5787d2ce7326a74a8ce59c5faa762d14d3359888 (diff)
downloadNetworkManager-0f5d372d5dbc3cb563dc14f49f4a5684918a07f8.tar.gz
agent-manager: add possibility to manage the p11 socket requests
-rw-r--r--src/settings/nm-agent-manager.c146
-rw-r--r--src/settings/nm-agent-manager.h13
2 files changed, 154 insertions, 5 deletions
diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c
index 158cad44ae..73ddd48880 100644
--- a/src/settings/nm-agent-manager.c
+++ b/src/settings/nm-agent-manager.c
@@ -81,6 +81,7 @@ NM_DEFINE_SINGLETON_INSTANCE (NMAgentManager);
typedef enum {
REQUEST_TYPE_INVALID,
REQUEST_TYPE_CON_GET,
+ REQUEST_TYPE_P11_GET,
REQUEST_TYPE_CON_SAVE,
REQUEST_TYPE_CON_DEL,
} RequestType;
@@ -89,9 +90,10 @@ static const char *
_request_type_to_string (RequestType request_type, gboolean verbose)
{
switch (request_type) {
- case REQUEST_TYPE_CON_GET: return verbose ? "getting" : "get";
- case REQUEST_TYPE_CON_SAVE: return verbose ? "saving" : "sav";
- case REQUEST_TYPE_CON_DEL: return verbose ? "deleting" : "del";
+ case REQUEST_TYPE_CON_GET: return verbose ? "getting secrets" : "get";
+ case REQUEST_TYPE_P11_GET: return verbose ? "getting p11-kit fd" : "p11";
+ case REQUEST_TYPE_CON_SAVE: return verbose ? "saving secrets" : "sav";
+ case REQUEST_TYPE_CON_DEL: return verbose ? "deleting secrets" : "del";
default: return "??";
}
}
@@ -133,6 +135,7 @@ static void request_remove_agent (Request *req, NMSecretAgent *agent, GSList **p
static void request_next_agent (Request *req);
static void _con_get_request_start (Request *req);
+static void _p11_get_request_start (Request *req);
static void _con_save_request_start (Request *req);
static void _con_del_request_start (Request *req);
@@ -478,6 +481,11 @@ struct _NMAgentManagerCallId {
} get;
};
} con;
+ struct {
+ char *uri;
+ NMAgentP11FdResultFunc callback;
+ gpointer callback_data;
+ } p11;
};
};
@@ -515,6 +523,10 @@ request_free (Request *req)
g_variant_unref (req->con.get.existing_secrets);
}
break;
+ case REQUEST_TYPE_P11_GET:
+ if (req->request_type == REQUEST_TYPE_P11_GET)
+ g_free (req->p11.uri);
+ break;
default:
g_assert_not_reached ();
}
@@ -567,6 +579,15 @@ req_complete_release (Request *req,
req->con.get.callback_data);
break;
+ case REQUEST_TYPE_P11_GET:
+ req->p11.callback (self,
+ agent_dbus_owner,
+ agent_username,
+ fd,
+ error,
+ req->p11.callback_data);
+
+ break;
case REQUEST_TYPE_CON_SAVE:
case REQUEST_TYPE_CON_DEL:
break;
@@ -602,7 +623,7 @@ req_complete (Request *req,
if (!g_hash_table_remove (priv->requests, req))
g_return_if_reached ();
- req_complete_release (req, secrets, -1, agent_dbus_owner, agent_username, error);
+ req_complete_release (req, secrets, fd, agent_dbus_owner, agent_username, error);
}
static void
@@ -728,7 +749,7 @@ request_next_agent (Request *req)
req->current = req->pending->data;
req->pending = g_slist_remove (req->pending, req->current);
- _LOGD (req->current, "agent %s secrets for request "LOG_REQ_FMT,
+ _LOGD (req->current, "agent %s for request "LOG_REQ_FMT,
_request_type_to_string (req->request_type, TRUE),
LOG_REQ_ARG (req));
@@ -736,6 +757,9 @@ request_next_agent (Request *req)
case REQUEST_TYPE_CON_GET:
_con_get_request_start (req);
break;
+ case REQUEST_TYPE_P11_GET:
+ _p11_get_request_start (req);
+ break;
case REQUEST_TYPE_CON_SAVE:
_con_save_request_start (req);
break;
@@ -781,6 +805,9 @@ request_remove_agent (Request *req, NMSecretAgent *agent, GSList **pending_reqs)
req->con.chain = NULL;
}
break;
+ case REQUEST_TYPE_P11_GET:
+ g_free (req->p11.uri);
+ break;
default:
g_assert_not_reached ();
}
@@ -1269,6 +1296,115 @@ nm_agent_manager_cancel_secrets (NMAgentManager *self,
/*************************************************************/
static void
+_p11_get_request_done (NMSecretAgent *agent,
+ NMSecretAgentCallId call_id,
+ GVariant *secrets,
+ int fd,
+ GError *error,
+ gpointer user_data)
+{
+ NMAgentManager *self;
+ Request *req = user_data;
+ const char *agent_dbus_owner;
+
+ g_return_if_fail (call_id == req->current_call_id);
+ g_return_if_fail (agent == req->current);
+ g_return_if_fail (req->request_type == REQUEST_TYPE_P11_GET);
+
+ self = req->self;
+
+ req->current_call_id = NULL;
+
+ if (error) {
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ _LOGD (agent, "p11-kit remoting fd request cancelled: "LOG_REQ_FMT,
+ LOG_REQ_ARG (req));
+ return;
+ }
+
+ _LOGD (agent, "agent failed p11-kit remoting fd request "LOG_REQ_FMT": %s",
+ LOG_REQ_ARG (req), error->message);
+ /* Try the next agent */
+ request_next_agent (req);
+ maybe_remove_agent_on_error (agent, error);
+ return;
+ }
+
+ _LOGD (agent, "agent returned p11-kit remoting fd %d for request "LOG_REQ_FMT, fd,
+ LOG_REQ_ARG (req));
+
+ agent_dbus_owner = nm_secret_agent_get_dbus_owner (agent);
+ req_complete (req, NULL, fd, NULL, agent_dbus_owner, NULL);
+}
+
+static void
+_p11_get_request_start (Request *req)
+{
+ req->current_call_id = nm_secret_agent_get_p11_fd (req->current,
+ req->p11.uri,
+ _p11_get_request_done,
+ req);
+ if (!req->current_call_id) {
+ g_warn_if_reached ();
+ request_next_agent (req);
+ }
+}
+
+/**
+ * nm_agent_manager_get_p11_fd:
+ * @self: The #NMAgentManager
+ * @subject: The #NMAuthSubject authentication subject
+ * @uri: The PKCS#11 URI (RFC 7512)
+ * @callback: #NMAgentP11FdResultFunc called when the request is serviced
+ * @callback_data: Opaque data to pass to the callback
+ *
+ * Get an open file descriptor connected to a p11-kit remoting agent
+ * that serves the module capable of handling the given URI.
+ *
+ * This function cannot fail. The callback will be invoked
+ * asynchronously, but it will always be invoked exactly once.
+ * Even for cancellation and disposing of @self. In those latter
+ * cases, the callback is invoked synchronously during the cancellation/
+ * disposal.
+ *
+ * Returns: a call-id to cancel the call.
+ */
+NMAgentManagerCallId
+nm_agent_manager_get_p11_fd (NMAgentManager *self,
+ NMAuthSubject *subject,
+ const char *uri,
+ NMAgentP11FdResultFunc callback,
+ gpointer callback_data)
+{
+ NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
+ Request *req;
+
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (uri != NULL, NULL);
+ g_return_val_if_fail (callback != NULL, NULL);
+
+ nm_log_dbg (LOGD_SETTINGS, "PKCS#11 remoting requested for URI %s", uri);
+
+ req = request_new (self,
+ REQUEST_TYPE_P11_GET,
+ NULL,
+ subject);
+
+ req->p11.uri = g_strdup (uri);
+ req->p11.callback = callback;
+ req->p11.callback_data = callback_data;
+
+ if (!nm_g_hash_table_add (priv->requests, req))
+ g_assert_not_reached ();
+
+ request_add_agents (self, req);
+ req->idle_id = g_idle_add (request_start, req);
+ return req;
+}
+
+/*************************************************************/
+
+static void
_con_save_request_done (NMSecretAgent *agent,
NMSecretAgentCallId call_id,
GVariant *secrets,
diff --git a/src/settings/nm-agent-manager.h b/src/settings/nm-agent-manager.h
index 8240a2b513..7a07d86596 100644
--- a/src/settings/nm-agent-manager.h
+++ b/src/settings/nm-agent-manager.h
@@ -63,6 +63,13 @@ typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager,
GError *error,
gpointer user_data);
+typedef void (*NMAgentP11FdResultFunc) (NMAgentManager *manager,
+ const char *agent_dbus_owner,
+ const char *agent_uname,
+ int fd,
+ GError *error,
+ gpointer user_data);
+
NMAgentManagerCallId nm_agent_manager_get_secrets (NMAgentManager *manager,
const char *path,
NMConnection *connection,
@@ -74,6 +81,12 @@ NMAgentManagerCallId nm_agent_manager_get_secrets (NMAgentManager *manager,
NMAgentSecretsResultFunc callback,
gpointer callback_data);
+NMAgentManagerCallId nm_agent_manager_get_p11_fd (NMAgentManager *self,
+ NMAuthSubject *subject,
+ const char *uri,
+ NMAgentP11FdResultFunc callback,
+ gpointer callback_data);
+
void nm_agent_manager_cancel_secrets (NMAgentManager *manager,
NMAgentManagerCallId request_id);