📄 dbus-security.c
字号:
"Authorization process was canceled");}static void auth_agent_cancel_requests(struct authorization_agent *agent){ GSList *l; for (l = agent->pending_requests; l != NULL; l = l->next) { struct auth_agent_req *req = l->data; auth_agent_req_cancel(req); auth_agent_req_free(req); }}static void auth_agent_call_cancel(struct auth_agent_req *req){ struct authorization_agent *agent = req->agent; DBusMessage *message; message = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.AuthorizationAgent", "Cancel"); if (!message) { error("Couldn't allocate D-Bus message"); return; } dbus_message_append_args(message, DBUS_TYPE_STRING, &req->adapter_path, DBUS_TYPE_STRING, &req->address, DBUS_TYPE_STRING, &req->service_path, DBUS_TYPE_STRING, &req->uuid, DBUS_TYPE_INVALID); dbus_message_set_no_reply(message, TRUE); send_message_and_unref(agent->conn, message);}static void auth_agent_free(struct authorization_agent *agent){ g_free(agent->name); g_free(agent->path); dbus_connection_unref(agent->conn); g_slist_free(agent->pending_requests); g_free(agent);}static struct authorization_agent *auth_agent_new(DBusConnection *conn, const char *name, const char *path){ struct authorization_agent *agent; agent = g_new0(struct authorization_agent, 1); agent->name = g_strdup(name); agent->path = g_strdup(path); agent->conn = dbus_connection_ref(conn); return agent;}static void default_auth_agent_exited(const char *name, void *data){ debug("%s exited without unregistering the " "default authorization agent", name); if (!default_auth_agent || strcmp(name, default_auth_agent->name)) { /* This should never happen! */ debug("default_auth_agent_exited: mismatch with " "actual default_auth_agent"); return; } auth_agent_cancel_requests(default_auth_agent); auth_agent_free(default_auth_agent); default_auth_agent = NULL;}static void auth_agent_release(struct authorization_agent *agent){ DBusMessage *message; debug("Releasing authorization agent %s, %s", agent->name, agent->path); message = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.AuthorizationAgent", "Release"); if (!message) { error("Couldn't allocate D-Bus message"); return; } dbus_message_set_no_reply(message, TRUE); send_message_and_unref(agent->conn, message); if (agent == default_auth_agent) name_listener_remove(agent->conn, agent->name, (name_cb_t) default_auth_agent_exited, NULL);}static DBusHandlerResult register_default_auth_agent(DBusConnection *conn, DBusMessage *msg, void *data){ DBusMessage *reply; const char *path; if (default_auth_agent) return error_auth_agent_already_exists(conn, msg); if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) return error_invalid_arguments(conn, msg, NULL); default_auth_agent = auth_agent_new(conn, dbus_message_get_sender(msg), path); if (!default_auth_agent) goto need_memory; reply = dbus_message_new_method_return(msg); if (!reply) goto need_memory; name_listener_add(conn, default_auth_agent->name, (name_cb_t) default_auth_agent_exited, NULL); info("Default authorization agent (%s, %s) registered", default_auth_agent->name, default_auth_agent->path); return send_message_and_unref(conn, reply);need_memory: if (default_auth_agent) { auth_agent_free(default_auth_agent); default_auth_agent = NULL; } return DBUS_HANDLER_RESULT_NEED_MEMORY;}static DBusHandlerResult unregister_default_auth_agent(DBusConnection *conn, DBusMessage *msg, void *data){ const char *path, *name; DBusMessage *reply; if (!default_auth_agent) return error_auth_agent_does_not_exist(conn, msg); if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) return error_invalid_arguments(conn, msg, NULL); name = dbus_message_get_sender(msg); if (strcmp(name, default_auth_agent->name) || strcmp(path, default_auth_agent->path)) return error_auth_agent_does_not_exist(conn, msg); reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; name_listener_remove(conn, default_auth_agent->name, (name_cb_t) default_auth_agent_exited, NULL); info("Default authorization agent (%s, %s) unregistered", default_auth_agent->name, default_auth_agent->path); auth_agent_cancel_requests(default_auth_agent); auth_agent_free(default_auth_agent); default_auth_agent = NULL; return send_message_and_unref(conn, reply);}static void auth_agent_req_reply(DBusPendingCall *call, void *data){ struct auth_agent_req *req = data; struct authorization_agent *agent = req->agent; DBusMessage *reply = dbus_pending_call_steal_reply(call); DBusMessage *message; DBusError err; debug("authorize reply"); dbus_error_init(&err); if (dbus_set_error_from_message(&err, reply)) { if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY)) auth_agent_call_cancel(req); error("Authorization agent replied with an error: %s, %s", err.name, err.message); dbus_error_free(&err); goto reject; } dbus_error_init(&err); if (!dbus_message_get_args(reply, &err, DBUS_TYPE_INVALID)) { error("Wrong authorization agent reply signature: %s", err.message); dbus_error_free(&err); goto reject; } message = dbus_message_new_method_return(req->msg); if (!message) goto reject; send_message_and_unref(agent->conn, message); debug("successfull reply was sent"); goto done;reject: error_rejected(agent->conn, req->msg);done: dbus_message_unref(reply); agent->pending_requests = g_slist_remove(agent->pending_requests, req); auth_agent_req_free(req); debug("auth_agent_reply: returning");}static DBusPendingCall *auth_agent_call_authorize(struct authorization_agent *agent, const char *adapter_path, const char *service_path, const char *address, const char *path){ DBusMessage *message; DBusPendingCall *call; message = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.AuthorizationAgent", "Authorize"); if (!message) { error("Couldn't allocate D-Bus message"); return NULL; } dbus_message_append_args(message, DBUS_TYPE_STRING, &adapter_path, DBUS_TYPE_STRING, &address, DBUS_TYPE_STRING, &service_path, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); if (dbus_connection_send_with_reply(agent->conn, message, &call, REQUEST_TIMEOUT) == FALSE) { error("D-Bus send failed"); dbus_message_unref(message); return NULL; } dbus_message_unref(message); return call;}DBusHandlerResult handle_authorize_request(DBusConnection *conn, DBusMessage *msg, struct service *service, const char *address, const char *uuid){ struct auth_agent_req *req; char adapter_path[PATH_MAX]; bdaddr_t bdaddr; int adapter_id; debug("handle_authorize_request"); if (!default_auth_agent) { debug("no default agent"); return error_auth_agent_does_not_exist(conn, msg); } str2ba(address, &bdaddr); adapter_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (adapter_id < 0) return error_not_connected(conn, msg); debug("Found %s connected to hci%d", address, adapter_id); snprintf(adapter_path, sizeof(adapter_path), "/org/bluez/hci%d", adapter_id); req = auth_agent_req_new(msg, default_auth_agent, adapter_path, address, service->object_path, uuid); req->call = auth_agent_call_authorize(default_auth_agent, adapter_path, service->object_path, address, uuid); if (!req->call) { auth_agent_req_free(req); return DBUS_HANDLER_RESULT_NEED_MEMORY; } dbus_pending_call_set_notify(req->call, auth_agent_req_reply, req, NULL); default_auth_agent->pending_requests = g_slist_append(default_auth_agent->pending_requests, req); debug("authorize request was forwarded"); return DBUS_HANDLER_RESULT_HANDLED;}static DBusHandlerResult auth_agent_send_cancel(DBusMessage *msg, struct authorization_agent *agent, const char *adapter_path, struct service *service, const char *address, const char *path){ struct auth_agent_req *req = NULL; DBusMessage *message; GSList *l; for (l = agent->pending_requests; l != NULL; l = l->next) { req = l->data; if (!strcmp(adapter_path, req->adapter_path) && !strcmp(address, req->address) && !strcmp(service->object_path, req->service_path) && !strcmp(path, req->uuid)) break; } if (!req) return error_does_not_exist(agent->conn, msg, "No such authorization process"); message = dbus_message_new_method_return(msg); if (!message) return DBUS_HANDLER_RESULT_NEED_MEMORY; auth_agent_call_cancel(req); auth_agent_req_cancel(req); agent->pending_requests = g_slist_remove(agent->pending_requests, req); auth_agent_req_free(req); return send_message_and_unref(agent->conn, message);}DBusHandlerResult cancel_authorize_request(DBusConnection *conn, DBusMessage *msg, struct service *service, const char *address, const char *path){ char adapter_path[PATH_MAX]; int adapter_id; bdaddr_t bdaddr; if (!default_auth_agent) return error_auth_agent_does_not_exist(conn, msg); str2ba(address, &bdaddr); adapter_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); if (adapter_id < 0) return error_not_connected(conn, msg); snprintf(adapter_path, sizeof(adapter_path), "/org/bluez/hci%d", adapter_id); return auth_agent_send_cancel(msg, default_auth_agent, adapter_path, service, address, path);}static DBusMethodVTable security_methods[] = { { "RegisterDefaultPasskeyAgent", register_default_passkey_agent, "s", "" }, { "UnregisterDefaultPasskeyAgent", unregister_default_passkey_agent, "s", "" }, { "RegisterPasskeyAgent", register_passkey_agent, "ss", "" }, { "UnregisterPasskeyAgent", unregister_passkey_agent, "ss", "" }, { "RegisterDefaultAuthorizationAgent", register_default_auth_agent, "s", "" }, { "UnregisterDefaultAuthorizationAgent", unregister_default_auth_agent, "s", "" }, { NULL, NULL, NULL, NULL }};dbus_bool_t security_init(DBusConnection *conn, const char *path){ return dbus_connection_register_interface(conn, path, SECURITY_INTERFACE, security_methods, NULL, NULL);}static DBusPendingCall *agent_request(const char *path, bdaddr_t *bda, struct passkey_agent *agent, dbus_bool_t numeric, int old_if){ DBusMessage *message; DBusPendingCall *call; char bda_str[18], *ptr = bda_str; message = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.PasskeyAgent", "Request"); if (message == NULL) { error("Couldn't allocate D-Bus message"); return NULL; } ba2str(bda, bda_str); if (old_if) dbus_message_append_args(message, DBUS_TYPE_STRING, &path, DBUS_TYPE_STRING, &ptr, DBUS_TYPE_INVALID); else dbus_message_append_args(message, DBUS_TYPE_STRING, &path, DBUS_TYPE_STRING, &ptr, DBUS_TYPE_BOOLEAN, &numeric, DBUS_TYPE_INVALID); if (dbus_connection_send_with_reply(agent->conn, message, &call, REQUEST_TIMEOUT) == FALSE) { error("D-Bus send failed"); dbus_message_unref(message); return NULL; } dbus_message_unref(message); return call;}static void passkey_agent_reply(DBusPendingCall *call, void *user_data){ struct pending_agent_request *req = user_data; struct passkey_agent *agent = req->agent; pin_code_reply_cp pr; DBusMessage *message; DBusError err; size_t len; char *pin; /* steal_reply will always return non-NULL since the callback * is only called after a reply has been received */ message = dbus_pending_call_steal_reply(call); dbus_error_init(&err); if (dbus_set_error_from_message(&err, message)) { if (!req->old_if && !strcmp(err.name, DBUS_ERROR_UNKNOWN_METHOD)) { debug("New Request API failed, trying old one"); req->old_if = 1; dbus_error_free(&err); dbus_pending_call_unref(req->call); req->call = agent_request(req->path, &req->bda, agent,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -