⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbus-security.c

📁 Linux的蓝牙操作工具。配合bluez-lib使用
💻 C
📖 第 1 页 / 共 3 页
字号:
			"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 + -