diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2016-06-17 15:39:00 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2016-06-23 18:54:28 +0200 |
commit | 0f5d372d5dbc3cb563dc14f49f4a5684918a07f8 (patch) | |
tree | d3321f9d5099f6b5a920d7cc9ddd0f1afb1b9763 | |
parent | 5787d2ce7326a74a8ce59c5faa762d14d3359888 (diff) | |
download | NetworkManager-0f5d372d5dbc3cb563dc14f49f4a5684918a07f8.tar.gz |
agent-manager: add possibility to manage the p11 socket requests
-rw-r--r-- | src/settings/nm-agent-manager.c | 146 | ||||
-rw-r--r-- | src/settings/nm-agent-manager.h | 13 |
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); |