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

📄 security.c

📁 Linux的蓝牙操作工具。配合bluez-lib使用
💻 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-2007  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 int pairing = HCID_PAIRING_MULTI;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 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){	unsigned char key[16];	char sa[18], da[18];	int err;	ba2str(sba, sa); ba2str(dba, da);	info("link_key_request (sba=%s, dba=%s)", sa, da);	err = read_link_key(sba, dba, key);	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);		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;	ba2str(sba, sa); ba2str(dba, da);	info("link_key_notify (sba=%s, dba=%s)", sa, da);	dev_id = hci_devid(sa);	write_link_key(sba, dba, evt->link_key, evt->key_type,						io_data[dev_id].pin_length);	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){	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){	hci_send_cmd(dev, OGF_LINK_CTL, OCF_USER_PASSKEY_NEG_REPLY, 6, ptr);}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){	io_capability_neg_reply_cp cp;	char sa[18], da[18];	ba2str(sba, sa); ba2str(dba, da);	info("io_capa_request (sba=%s, dba=%s)", sa, da);	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);}/* 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;	unsigned char key[16];	char sa[18], da[18], pin[17];	int err, 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 (pairing == HCID_PAIRING_ONCE) {		err = read_link_key(sba, dba, key);		if (!err) {			ba2str(dba, da);			error("PIN code request for already paired device %s", da);			goto reject;		}	} else if (pairing == HCID_PAIRING_NONE)		goto reject;	if (hcid.security == HCID_SEC_AUTO) {		if (!ci->out) {			/* Incomming connection */			set_pin_length(sba, hcid.pin_len);			memcpy(pr.pin_code, hcid.pin_code, hcid.pin_len);			pr.pin_len = hcid.pin_len;			hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY,				PIN_CODE_REPLY_CP_SIZE, &pr);		} else {			/* Outgoing connection */			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 */				hcid_dbus_request_pin(dev, sba, ci);			}		}	} else {		if (pinlen > 0) {			/* Confirm PIN by passkey agent */			hcid_dbus_confirm_pin(dev, sba, ci, pin);		} else {			/* Request PIN from passkey agent */ 			hcid_dbus_request_pin(dev, sba, ci);		}	}	hcid_dbus_pending_pin_req_add(sba, &ci->bdaddr);	g_free(cr);	return;reject:	g_free(cr);	hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba);	return;}static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr){	evt_cmd_status *evt = ptr;	uint16_t opcode = btohs(evt->opcode);	if (evt->status)		return;	if (opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY))		hcid_dbus_inquiry_start(sba);}static inline void cmd_complete(int dev, bdaddr_t *sba, void *ptr){	evt_cmd_complete *evt = ptr;	uint16_t opcode = btohs(evt->opcode);	uint8_t status;	switch (opcode) {	case cmd_opcode_pack(OGF_LINK_CTL, OCF_PERIODIC_INQUIRY):		status = *((uint8_t *) ptr + EVT_CMD_COMPLETE_SIZE);		hcid_dbus_periodic_inquiry_start(sba, status);		break;	case cmd_opcode_pack(OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY):		status = *((uint8_t *) ptr + EVT_CMD_COMPLETE_SIZE);		hcid_dbus_periodic_inquiry_exit(sba, status);		break;	case cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL):		hcid_dbus_inquiry_complete(sba);		break;	case cmd_opcode_pack(OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME):

⌨️ 快捷键说明

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