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

📄 dbus-security.c

📁 Linux的蓝牙操作工具。配合bluez-lib使用
💻 C
📖 第 1 页 / 共 3 页
字号:
							FALSE, 1);			if (!req->call)				goto fail;			dbus_message_unref(message);			dbus_pending_call_set_notify(req->call,							passkey_agent_reply,							req, NULL);			return;		}		error("Passkey agent replied with an error: %s, %s",				err.name, err.message);		dbus_error_free(&err);		goto fail;	}	dbus_error_init(&err);	if (!dbus_message_get_args(message, &err,				DBUS_TYPE_STRING, &pin,				DBUS_TYPE_INVALID)) {		error("Wrong passkey reply signature: %s", err.message);		dbus_error_free(&err);		goto fail;	}	len = strlen(pin);	if (len > 16 || len < 1) {		error("Invalid passkey length from handler");		goto fail;	}	set_pin_length(&req->sba, len);	memset(&pr, 0, sizeof(pr));	bacpy(&pr.bdaddr, &req->bda);	memcpy(pr.pin_code, pin, len);	pr.pin_len = len;	hci_send_cmd(req->dev, OGF_LINK_CTL,			OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr);	goto done;fail:	hci_send_cmd(req->dev, OGF_LINK_CTL,			OCF_PIN_CODE_NEG_REPLY, 6, &req->bda);done:	if (message)		dbus_message_unref(message);	agent->pending_requests = g_slist_remove(agent->pending_requests, req);	dbus_pending_call_cancel(req->call);	if (req->call)		dbus_pending_call_unref(req->call);	g_free(req->path);	g_free(req);	if (agent != default_agent) {		agent->adapter->passkey_agents = g_slist_remove(agent->adapter->passkey_agents,								agent);		passkey_agent_free(agent);	}}static int call_passkey_agent(DBusConnection *conn,				struct passkey_agent *agent, int dev,				const char *path, bdaddr_t *sba,				bdaddr_t *dba){	struct pending_agent_request *req;	if (!agent) {		debug("call_passkey_agent(): no agent available");		goto send;	}	debug("Calling PasskeyAgent.Request: name=%s, path=%s",						agent->name, agent->path);	req = g_new0(struct pending_agent_request, 1);	req->dev = dev;	bacpy(&req->sba, sba);	bacpy(&req->bda, dba);	req->agent = agent;	req->path = g_strdup(path);	req->call = agent_request(path, dba, agent, FALSE, 0);	if (!req->call)		goto failed;	dbus_pending_call_set_notify(req->call, passkey_agent_reply, req, NULL);	agent->pending_requests = g_slist_append(agent->pending_requests, req);	return 0;failed:	g_free(req->path);	g_free(req);send:	hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba);	return -1;}int handle_passkey_request(DBusConnection *conn, int dev, const char *path,					bdaddr_t *sba, bdaddr_t *dba){	struct passkey_agent *agent = default_agent;	struct adapter *adapter = NULL;	GSList *l;	char addr[18];	void *data;	dbus_connection_get_object_user_data(conn, path, &data);	if (!data)		goto done;	adapter = data;	if (!bacmp(&adapter->agents_disabled, dba))		goto done;	ba2str(dba, addr);	for (l = adapter->passkey_agents; l != NULL; l = l->next) {		struct passkey_agent *a = l->data;		if (a != default_agent && g_slist_length(a->pending_requests) >= 1)			continue;		if (!strcmp(a->addr, addr)) {			agent = a;			break;		}	}done:	return call_passkey_agent(conn, agent, dev, path, sba, dba);}static DBusPendingCall *agent_confirm(const char *path, bdaddr_t *bda,					struct passkey_agent *agent,					const char *value){	DBusMessage *message;	DBusPendingCall *call;	char bda_str[18], *ptr = bda_str;	message = dbus_message_new_method_call(agent->name, agent->path,					"org.bluez.PasskeyAgent", "Confirm");	if (message == NULL) {		error("Couldn't allocate D-Bus message");		return NULL;	}	ba2str(bda, bda_str);	dbus_message_append_args(message,				DBUS_TYPE_STRING, &path,				DBUS_TYPE_STRING, &ptr,				DBUS_TYPE_STRING, &value,				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 confirm_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;	int len;	/* 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)) {		error("Passkey agent replied with an error: %s, %s",				err.name, err.message);		dbus_error_free(&err);		goto fail;	}	dbus_error_init(&err);	if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) {		error("Wrong confirm reply signature: %s", err.message);		dbus_error_free(&err);		goto fail;	}	len = strlen(req->pin);	set_pin_length(&req->sba, len);	memset(&pr, 0, sizeof(pr));	bacpy(&pr.bdaddr, &req->bda);	memcpy(pr.pin_code, req->pin, len);	pr.pin_len = len;	hci_send_cmd(req->dev, OGF_LINK_CTL,			OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr);	goto done;fail:	hci_send_cmd(req->dev, OGF_LINK_CTL,			OCF_PIN_CODE_NEG_REPLY, 6, &req->bda);done:	if (message)		dbus_message_unref(message);	agent->pending_requests = g_slist_remove(agent->pending_requests, req);	dbus_pending_call_cancel(req->call);	if (req->call)		dbus_pending_call_unref(req->call);	g_free(req->pin);	g_free(req->path);	g_free(req);	if (agent != default_agent) {		agent->adapter->passkey_agents = g_slist_remove(agent->adapter->passkey_agents,								agent);		passkey_agent_free(agent);	}}static int call_confirm_agent(DBusConnection *conn,				struct passkey_agent *agent, int dev,				const char *path, bdaddr_t *sba,				bdaddr_t *dba, const char *pin){	struct pending_agent_request *req;	if (!agent) {		debug("call_passkey_agent(): no agent available");		goto send;	}	debug("Calling PasskeyAgent.Confirm: name=%s, path=%s",						agent->name, agent->path);	req = g_new0(struct pending_agent_request, 1);	req->dev = dev;	bacpy(&req->sba, sba);	bacpy(&req->bda, dba);	req->agent = agent;	req->path = g_strdup(path);	req->pin = g_strdup(pin);	req->call = agent_confirm(path, dba, agent, pin);	if (!req->call)		goto failed;	dbus_pending_call_set_notify(req->call, confirm_agent_reply, req, NULL);	agent->pending_requests = g_slist_append(agent->pending_requests, req);	return 0;failed:	g_free(req->pin);	g_free(req->path);	g_free(req);send:	hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba);	return -1;}int handle_confirm_request(DBusConnection *conn, int dev, const char *path,				bdaddr_t *sba, bdaddr_t *dba, const char *pin){	struct passkey_agent *agent = default_agent;	struct adapter *adapter = NULL;	GSList *l;	char addr[18];	void *data;	dbus_connection_get_object_user_data(conn, path, &data);	if (!data)		goto done;	adapter = data;	if (!bacmp(&adapter->agents_disabled, dba))		goto done;	ba2str(dba, addr);	for (l = adapter->passkey_agents; l != NULL; l = l->next) {		struct passkey_agent *a = l->data;		if (a != default_agent && g_slist_length(a->pending_requests) >= 1)			continue;		if (!strcmp(a->addr, addr)) {			agent = a;			break;		}	}done:	return call_confirm_agent(conn, agent, dev, path, sba, dba, pin);}static void send_cancel_request(struct pending_agent_request *req){	DBusMessage *message;	char address[18], *ptr = address;	message = dbus_message_new_method_call(req->agent->name, req->agent->path,			"org.bluez.PasskeyAgent", "Cancel");	if (message == NULL) {		error("Couldn't allocate D-Bus message");		return;	}	ba2str(&req->bda, address);	dbus_message_append_args(message,			DBUS_TYPE_STRING, &req->path,			DBUS_TYPE_STRING, &ptr,			DBUS_TYPE_INVALID);	dbus_message_set_no_reply(message, TRUE);	send_message_and_unref(req->agent->conn, message);	debug("PasskeyAgent.Request(%s, %s) was canceled", req->path, address);	dbus_pending_call_cancel(req->call);	dbus_pending_call_unref(req->call);	g_free(req->pin);	g_free(req->path);	g_free(req);}static void release_agent(struct passkey_agent *agent){	DBusMessage *message;	debug("Releasing agent %s, %s", agent->name, agent->path);	message = dbus_message_new_method_call(agent->name, agent->path,			"org.bluez.PasskeyAgent", "Release");	if (message == NULL) {		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_agent)		name_listener_remove(agent->conn, agent->name,				(name_cb_t) default_agent_exited, NULL);	else {		struct passkey_agent ref;		/* Only remove the name listener if there are no more agents for this name */		memset(&ref, 0, sizeof(ref));		ref.name = agent->name;		if (!g_slist_find_custom(agent->adapter->passkey_agents, &ref, (GCompareFunc) agent_cmp))			name_listener_remove(agent->conn, ref.name,					(name_cb_t) agent_exited, agent->adapter);	}}void release_default_agent(void){	if (!default_agent)		return;	passkey_agent_free(default_agent);	default_agent = NULL;}void release_default_auth_agent(void){	if (!default_auth_agent)		return;	auth_agent_cancel_requests(default_auth_agent);	auth_agent_release(default_auth_agent);	auth_agent_free(default_auth_agent);	default_auth_agent = NULL;}void release_passkey_agents(struct adapter *adapter, bdaddr_t *bda){	GSList *l, *next;	for (l = adapter->passkey_agents; l != NULL; l = next) {		struct passkey_agent *agent = l->data;		next = l->next;		if (bda && agent->addr) {			bdaddr_t tmp;			str2ba(agent->addr, &tmp);			if (bacmp(&tmp, bda))				continue;		}		adapter->passkey_agents = g_slist_remove(adapter->passkey_agents, agent);		passkey_agent_free(agent);	}}void cancel_passkey_agent_requests(GSList *agents, const char *path,					bdaddr_t *addr){	GSList *l, *next;	/* First check the default agent */	for (l = default_agent ? default_agent->pending_requests : NULL; l != NULL; l = next) {		struct pending_agent_request *req = l->data;		next = l->next;		if (!strcmp(path, req->path) && (!addr || !bacmp(addr, &req->bda))) {			send_cancel_request(req);			default_agent->pending_requests = g_slist_remove(default_agent->pending_requests,									req);		}	}	/* and then the adapter specific agents */	for (; agents != NULL; agents = agents->next) {		struct passkey_agent *agent = agents->data;		for (l = agent->pending_requests; l != NULL; l = next) {			struct pending_agent_request *req = l->data;			next = l->next;			if (!strcmp(path, req->path) && (!addr || !bacmp(addr, &req->bda))) {				send_cancel_request(req);				agent->pending_requests = g_slist_remove(agent->pending_requests, req);			}		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -