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

📄 security.c

📁 蓝牙bluez-utils-2.25.tar.gz网上很少找到这个版本的了
💻 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-2006  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 <malloc.h>#include <string.h>#include <signal.h>#include <syslog.h>#include <time.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <bluetooth/bluetooth.h>#include <bluetooth/hci.h>#include <bluetooth/hci_lib.h>#include "glib-ectomy.h"#include "hcid.h"#include "lib.h"static GIOChannel *io_chan[HCI_MAX_DEV];static int pairing;void toggle_pairing(int enable){	if (enable)		pairing = hcid.pairing;	else		pairing = 0;	syslog(LOG_INFO, "Pairing %s", pairing ? "enabled" : "disabled");}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 = malloc(10 * sizeof(*ci) + sizeof(*cl));	if (!cl)		return -ENOMEM;	ba2str(sba, addr);	cl->dev_id = hci_devid(addr);	cl->conn_num = 10;	ci = cl->conn_info;	if (ioctl(dev, HCIGETCONNLIST, (void *) cl) < 0) {		free(cl);		return -EIO;	}	for (i = 0; i < cl->conn_num; i++, ci++)		if (ci->handle == handle) {			bacpy(dba, &ci->bdaddr);			free(cl);			return 0;		}	free(cl);	return -ENOENT;}/* Link Key handling *//* This function is not reentrable */static struct link_key *__get_link_key(int f, bdaddr_t *sba, bdaddr_t *dba){	static struct link_key k;	struct link_key *key = NULL;	int r;	while ((r = read_n(f, &k, sizeof(k)))) {		if (r < 0) {			syslog(LOG_ERR, "Link key database read failed: %s (%d)",							strerror(errno), errno);			break;		}		if (!bacmp(&k.sba, sba) && !bacmp(&k.dba, dba)) {			key = &k;			break;		}	}	return key;}static struct link_key *get_link_key(bdaddr_t *sba, bdaddr_t *dba){	struct link_key *key = NULL;	int f;	f = open(hcid.key_file, O_RDONLY);	if (f >= 0)		key = __get_link_key(f, sba, dba);	else if (errno != ENOENT)		syslog(LOG_ERR, "Link key database open failed: %s (%d)",							strerror(errno), errno);	close(f);	return key;}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);	syslog(LOG_INFO, "link_key_request (sba=%s, dba=%s)", sa, da);	err = read_link_key(sba, dba, key);	if (err < 0) {		struct link_key *linkkey = get_link_key(sba, dba);		if (linkkey) {			memcpy(key, linkkey->key, 16);			linkkey->time = time(0);			err = 0;		}	}	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);	}}#if 0static void save_link_key(struct link_key *key){	struct link_key *exist;	char sa[18], da[18];	int f, err;	f = open(hcid.key_file, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);	if (f < 0) {		syslog(LOG_ERR, "Link key database open failed: %s (%d)",							strerror(errno), errno);		return;	}	/* Check if key already exist */	exist = __get_link_key(f, &key->sba, &key->dba);	err = 0;	if (exist) {		off_t o = lseek(f, 0, SEEK_CUR);		err = lseek(f, o - sizeof(*key), SEEK_SET);	} else		err = fcntl(f, F_SETFL, O_APPEND);	if (err < 0) {		syslog(LOG_ERR, "Link key database seek failed: %s (%d)",							strerror(errno), errno);		goto failed;	}	if (write_n(f, key, sizeof(*key)) < 0) {		syslog(LOG_ERR, "Link key database write failed: %s (%d)",							strerror(errno), errno);	}	ba2str(&key->sba, sa); ba2str(&key->dba, da);	syslog(LOG_INFO, "%s link key %s %s", exist ? "Replacing" : "Saving", sa, da);failed:	close(f);}#endifstatic void link_key_notify(int dev, bdaddr_t *sba, void *ptr){	evt_link_key_notify *evt = ptr;	bdaddr_t *dba = &evt->bdaddr;	struct link_key key;	char sa[18], da[18];	ba2str(sba, sa); ba2str(dba, da);	syslog(LOG_INFO, "link_key_notify (sba=%s, dba=%s)", sa, da);	memcpy(key.key, evt->link_key, 16);	bacpy(&key.sba, sba);	bacpy(&key.dba, dba);	key.type = evt->key_type;	key.time = time(0);#if 0	save_link_key(&key);#endif	write_link_key(sba, dba, evt->link_key, evt->key_type);}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);		syslog(LOG_INFO, "return_link_keys (sba=%s, dba=%s)", sa, da);		ptr += 22;	}}/* PIN code handling */static int read_default_pin_code(void){	char buf[17];	FILE *f; 	int len;	if (!(f = fopen(hcid.pin_file, "r"))) {		syslog(LOG_ERR, "Can't open PIN file %s: %s (%d)",					hcid.pin_file, strerror(errno), errno);		return -1;	}	if (fgets(buf, sizeof(buf), f)) {		strtok(buf, "\n\r");		len = strlen(buf); 		memcpy(hcid.pin_code, buf, len);		hcid.pin_len = len;	} else {		syslog(LOG_ERR, "Can't read PIN file %s: %s (%d)",					hcid.pin_file, strerror(errno), errno);		len = -1;	}	fclose(f);	return len;}/*  PIN helper is an external app that asks user for a PIN. It can   implement its own PIN  code generation policy and methods like  PIN look up in some database, etc.   HCId expects following output from PIN helper:	PIN:12345678	-	PIN code	ERR		-	No PIN available*/static void call_pin_helper(int dev, bdaddr_t *sba, struct hci_conn_info *ci){	pin_code_reply_cp pr;	struct sigaction sa;	char addr[18], str[512], *pin, name[249], tmp[497], *ptr;	FILE *pipe;	int i, ret, len;	/* Run PIN helper in the separate process */	switch (fork()) {		case 0:			break;		case -1:			syslog(LOG_ERR, "Can't fork PIN helper: %s (%d)",							strerror(errno), errno);		default:			return;	}	if (access(hcid.pin_helper, R_OK | X_OK)) {		syslog(LOG_ERR, "Can't exec PIN helper %s: %s (%d)",					hcid.pin_helper, strerror(errno), errno);		goto reject;	}	memset(name, 0, sizeof(name));	read_device_name(sba, &ci->bdaddr, name);	//hci_remote_name(dev, &ci->bdaddr, sizeof(name), name, 0);	memset(tmp, 0, sizeof(tmp));	ptr = tmp;	for (i = 0; i < 248 && name[i]; i++)		if (isprint(name[i])) {			switch (name[i]) {			case '"':			case '`':			case '$':			case '|':			case '>':			case '<':			case '&':			case ';':			case '\\':				*ptr++ = '\\';			}			*ptr++ = name[i];		} else {			name[i] = '.';			*ptr++ = '.';		}	ba2str(&ci->bdaddr, addr);	snprintf(str, sizeof(str), "%s %s %s \"%s\"", hcid.pin_helper,					ci->out ? "out" : "in", addr, tmp);	setenv("PATH", "/bin:/usr/bin:/usr/local/bin", 1);	memset(&sa, 0, sizeof(sa));	sa.sa_flags = SA_NOCLDSTOP;	sa.sa_handler = SIG_DFL;	sigaction(SIGCHLD, &sa, NULL);	pipe = popen(str, "r");	if (!pipe) {		syslog(LOG_ERR, "Can't exec PIN helper: %s (%d)",							strerror(errno), errno);		goto reject;	}	pin = fgets(str, sizeof(str), pipe);	ret = pclose(pipe);	if (!pin || strlen(pin) < 5)		goto nopin;	strtok(pin, "\n\r");	if (strncmp("PIN:", pin, 4))		goto nopin;	pin += 4;	len  = strlen(pin);	memset(&pr, 0, sizeof(pr));	bacpy(&pr.bdaddr, &ci->bdaddr);	memcpy(pr.pin_code, pin, len);	pr.pin_len = len;	hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY,			PIN_CODE_REPLY_CP_SIZE, &pr);	exit(0);nopin:	if (!pin || strncmp("ERR", pin, 3))		syslog(LOG_ERR, "PIN helper exited abnormally with code %d", ret);reject:	hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr);	exit(0);}static void request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci){#ifdef ENABLE_DBUS	if (hcid.dbus_pin_helper) {		hcid_dbus_request_pin(dev, ci);		return;	}#endif	call_pin_helper(dev, sba, ci);}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);	syslog(LOG_INFO, "pin_code_request (sba=%s, dba=%s)", sa, da);	cr = malloc(sizeof(*cr) + sizeof(*ci));	if (!cr)		return;	bacpy(&cr->bdaddr, dba);	cr->type = ACL_LINK;	if (ioctl(dev, HCIGETCONNINFO, (unsigned long) cr) < 0) {		syslog(LOG_ERR, "Can't get conn info: %s (%d)",							strerror(errno), errno);		goto reject;	}	ci = cr->conn_info;	memset(pin, 0, sizeof(pin));

⌨️ 快捷键说明

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