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

📄 security.c

📁 这是Linux环境下的蓝牙源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2000-2001  Qualcomm Incorporated *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com> *  Copyright (C) 2002-2008  Marcel Holtmann <marcel@holtmann.org> * * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA * */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <errno.h>#include <ctype.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include <time.h>#include <sys/time.h>#include <sys/param.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <bluetooth/bluetooth.h>#include <bluetooth/hci.h>#include <bluetooth/hci_lib.h>#include <glib.h>#include <dbus/dbus.h>#include "hcid.h"#include "textfile.h"#include "adapter.h"#include "dbus-hci.h"struct g_io_info {	GIOChannel	*channel;	int		watch_id;	int		pin_length;};static struct g_io_info io_data[HCI_MAX_DEV];static GSList *hci_req_queue = NULL;struct hci_req_data *hci_req_data_new(int dev_id, const bdaddr_t *dba, uint16_t ogf, uint16_t ocf, int event, const void *cparam, int clen){	struct hci_req_data *data;	data = g_new0(struct hci_req_data, 1);	data->cparam = g_malloc(clen);	memcpy(data->cparam, cparam, clen);	bacpy(&data->dba, dba);	data->dev_id = dev_id;	data->status = REQ_PENDING;	data->ogf    = ogf;	data->ocf    = ocf;	data->event  = event;	data->clen   = clen;	return data;}static int hci_req_find_by_devid(const void *data, const void *user_data){	const struct hci_req_data *req = data;	const int *dev_id = user_data;	return (*dev_id - req->dev_id);}static void hci_req_queue_process(int dev_id){	int dd, ret_val;	/* send the next pending cmd */	dd = hci_open_dev(dev_id);	do {		struct hci_req_data *data;		GSList *l = g_slist_find_custom(hci_req_queue, &dev_id, hci_req_find_by_devid);		if (!l)			break;		data = l->data;		data->status = REQ_SENT;		ret_val = hci_send_cmd(dd, data->ogf, data->ocf, data->clen, data->cparam);		if (ret_val < 0) {			hci_req_queue = g_slist_remove(hci_req_queue, data);			g_free(data->cparam);			g_free(data);		}	} while(ret_val < 0);	hci_close_dev(dd);}void hci_req_queue_append(struct hci_req_data *data){	GSList *l;	struct hci_req_data *match;	hci_req_queue = g_slist_append(hci_req_queue, data);	l = g_slist_find_custom(hci_req_queue, &data->dev_id, hci_req_find_by_devid);	match = l->data;	if (match->status == REQ_SENT)		return;	hci_req_queue_process(data->dev_id);}void hci_req_queue_remove(int dev_id, bdaddr_t *dba){	GSList *cur, *next;	struct hci_req_data *req;	for (cur = hci_req_queue; cur != NULL; cur = next) {		req = cur->data;		next = cur->next;		if ((req->dev_id != dev_id) || (bacmp(&req->dba, dba)))			continue;		hci_req_queue = g_slist_remove(hci_req_queue, req);		g_free(req->cparam);		g_free(req);	}}static void check_pending_hci_req(int dev_id, int event){	struct hci_req_data *data;	GSList *l;	if (!hci_req_queue)		return;	/* find the first element(pending)*/	l = g_slist_find_custom(hci_req_queue, &dev_id, hci_req_find_by_devid);	if (!l)		return;	data = l->data;	/* skip if there is pending confirmation */	if (data->status == REQ_SENT) {		if (data->event != event)			return;		/* remove the confirmed cmd */		hci_req_queue = g_slist_remove(hci_req_queue, data);		g_free(data->cparam);		g_free(data);	}	hci_req_queue_process(dev_id);}static int get_handle(int dev, bdaddr_t *sba, bdaddr_t *dba, uint16_t *handle){	struct hci_conn_list_req *cl;	struct hci_conn_info *ci;	char addr[18];	int i;	cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl));	ba2str(sba, addr);	cl->dev_id = hci_devid(addr);	cl->conn_num = 10;	ci = cl->conn_info;	if (ioctl(dev, HCIGETCONNLIST, (void *) cl) < 0) {		g_free(cl);		return -EIO;	}	for (i = 0; i < cl->conn_num; i++, ci++) {		if (bacmp(&ci->bdaddr, dba) == 0) {			*handle = ci->handle;			g_free(cl);			return 0;		}	}	g_free(cl);	return -ENOENT;}static inline int get_bdaddr(int dev, bdaddr_t *sba, uint16_t handle, bdaddr_t *dba){	struct hci_conn_list_req *cl;	struct hci_conn_info *ci;	char addr[18];	int i;	cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl));	ba2str(sba, addr);	cl->dev_id = hci_devid(addr);	cl->conn_num = 10;	ci = cl->conn_info;	if (ioctl(dev, HCIGETCONNLIST, (void *) cl) < 0) {		g_free(cl);		return -EIO;	}	for (i = 0; i < cl->conn_num; i++, ci++)		if (ci->handle == handle) {			bacpy(dba, &ci->bdaddr);			g_free(cl);			return 0;		}	g_free(cl);	return -ENOENT;}static inline void update_lastseen(bdaddr_t *sba, bdaddr_t *dba){	time_t t;	struct tm *tm;	t = time(NULL);	tm = gmtime(&t);	write_lastseen_info(sba, dba, tm);}static inline void update_lastused(bdaddr_t *sba, bdaddr_t *dba){	time_t t;	struct tm *tm;	t = time(NULL);	tm = gmtime(&t);	write_lastused_info(sba, dba, tm);}/* Link Key handling */static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba){	struct hci_auth_info_req req;	unsigned char key[16];	char sa[18], da[18];	uint8_t type;	int err;	ba2str(sba, sa); ba2str(dba, da);	info("link_key_request (sba=%s, dba=%s)", sa, da);	memset(&req, 0, sizeof(req));	bacpy(&req.bdaddr, dba);	err = ioctl(dev, HCIGETAUTHINFO, (unsigned long) &req);	if (err < 0 && errno != EINVAL)		debug("HCIGETAUTHINFO failed %s (%d)",					strerror(errno), errno);	else		req.type = 0x00;	debug("kernel auth requirements = 0x%02x", req.type);	err = read_link_key(sba, dba, key, &type);	if (err < 0) {		/* Link key not found */		hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 6, dba);	} else {		/* Link key found */		link_key_reply_cp lr;		memcpy(lr.link_key, key, 16);		bacpy(&lr.bdaddr, dba);		debug("stored link key type = 0x%02x", type);		if ((type == 0x03 || type == 0x04) && (req.type & 0x01))			hci_send_cmd(dev, OGF_LINK_CTL,					OCF_LINK_KEY_NEG_REPLY, 6, dba);		else			hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_REPLY,						LINK_KEY_REPLY_CP_SIZE, &lr);	}}static void link_key_notify(int dev, bdaddr_t *sba, void *ptr){	evt_link_key_notify *evt = ptr;	bdaddr_t *dba = &evt->bdaddr;	char sa[18], da[18];	int dev_id, err;	ba2str(sba, sa); ba2str(dba, da);	info("link_key_notify (sba=%s, dba=%s)", sa, da);	dev_id = hci_devid(sa);	err = write_link_key(sba, dba, evt->link_key, evt->key_type,						io_data[dev_id].pin_length);	if (err < 0) {		uint16_t handle;		error("write_link_key: %s (%d)", strerror(-err), -err);		hcid_dbus_bonding_process_complete(sba, dba, HCI_MEMORY_FULL);		if (get_handle(dev, sba, dba, &handle) == 0) {			disconnect_cp cp;			memset(&cp, 0, sizeof(cp));			cp.handle = htobs(handle);			cp.reason = HCI_OE_LOW_RESOURCES;			hci_send_cmd(dev, OGF_LINK_CTL, OCF_DISCONNECT,						DISCONNECT_CP_SIZE, &cp);		}	} else		hcid_dbus_bonding_process_complete(sba, dba, 0);	io_data[dev_id].pin_length = -1;}static void return_link_keys(int dev, bdaddr_t *sba, void *ptr){	evt_return_link_keys *evt = ptr;	uint8_t num = evt->num_keys;	unsigned char key[16];	char sa[18], da[18];	bdaddr_t dba;	int i;	ba2str(sba, sa);	ptr++;	for (i = 0; i < num; i++) {		bacpy(&dba, ptr); ba2str(&dba, da);		memcpy(key, ptr + 6, 16);		info("return_link_keys (sba=%s, dba=%s)", sa, da);		ptr += 22;	}}/* Simple Pairing handling */static void user_confirm_request(int dev, bdaddr_t *sba, void *ptr){	evt_user_confirm_request *req = ptr;	if (hcid_dbus_user_confirm(sba, &req->bdaddr,					btohl(req->passkey)) < 0)		hci_send_cmd(dev, OGF_LINK_CTL,				OCF_USER_CONFIRM_NEG_REPLY, 6, ptr);}static void user_passkey_request(int dev, bdaddr_t *sba, void *ptr){	evt_user_passkey_request *req = ptr;	if (hcid_dbus_user_passkey(sba, &req->bdaddr) < 0)		hci_send_cmd(dev, OGF_LINK_CTL,				OCF_USER_PASSKEY_NEG_REPLY, 6, ptr);}static void user_passkey_notify(int dev, bdaddr_t *sba, void *ptr){	evt_user_passkey_notify *req = ptr;	hcid_dbus_user_notify(sba, &req->bdaddr, btohl(req->passkey));}static void remote_oob_data_request(int dev, bdaddr_t *sba, void *ptr){	hci_send_cmd(dev, OGF_LINK_CTL, OCF_REMOTE_OOB_DATA_NEG_REPLY, 6, ptr);}static void io_capa_request(int dev, bdaddr_t *sba, bdaddr_t *dba){	char sa[18], da[18];	uint8_t cap, auth;	ba2str(sba, sa); ba2str(dba, da);	info("io_capa_request (sba=%s, dba=%s)", sa, da);	if (hcid_dbus_get_io_cap(sba, dba, &cap, &auth) < 0) {		io_capability_neg_reply_cp cp;		memset(&cp, 0, sizeof(cp));		bacpy(&cp.bdaddr, dba);		cp.reason = HCI_PAIRING_NOT_ALLOWED;		hci_send_cmd(dev, OGF_LINK_CTL, OCF_IO_CAPABILITY_NEG_REPLY,					IO_CAPABILITY_NEG_REPLY_CP_SIZE, &cp);	} else {		io_capability_reply_cp cp;		memset(&cp, 0, sizeof(cp));		bacpy(&cp.bdaddr, dba);		cp.capability = cap;		cp.oob_data = 0x00;		cp.authentication = auth;		hci_send_cmd(dev, OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY,					IO_CAPABILITY_REPLY_CP_SIZE, &cp);	}}static void io_capa_response(int dev, bdaddr_t *sba, void *ptr){	evt_io_capability_response *evt = ptr;	char sa[18], da[18];	ba2str(sba, sa); ba2str(&evt->bdaddr, da);	info("io_capa_response (sba=%s, dba=%s)", sa, da);	hcid_dbus_set_io_cap(sba, &evt->bdaddr,				evt->capability, evt->authentication);}/* PIN code handling */void set_pin_length(bdaddr_t *sba, int length){	char addr[18];	int dev_id;	ba2str(sba, addr);	dev_id = hci_devid(addr);	io_data[dev_id].pin_length = length;}static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba){	pin_code_reply_cp pr;	struct hci_conn_info_req *cr;	struct hci_conn_info *ci;	char sa[18], da[18], pin[17];	int pinlen;	memset(&pr, 0, sizeof(pr));	bacpy(&pr.bdaddr, dba);	ba2str(sba, sa); ba2str(dba, da);	info("pin_code_request (sba=%s, dba=%s)", sa, da);	cr = g_malloc0(sizeof(*cr) + sizeof(*ci));	bacpy(&cr->bdaddr, dba);	cr->type = ACL_LINK;	if (ioctl(dev, HCIGETCONNINFO, (unsigned long) cr) < 0) {		error("Can't get conn info: %s (%d)", strerror(errno), errno);		goto reject;	}	ci = cr->conn_info;	memset(pin, 0, sizeof(pin));	pinlen = read_pin_code(sba, dba, pin);	if (pinlen > 0) {		set_pin_length(sba, pinlen);		memcpy(pr.pin_code, pin, pinlen);		pr.pin_len = pinlen;		hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY,				PIN_CODE_REPLY_CP_SIZE, &pr);	} else {		/* Request PIN from passkey agent */		if (hcid_dbus_request_pin(dev, sba, ci) < 0)			goto reject;	}	g_free(cr);	return;

⌨️ 快捷键说明

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