📄 security.c
字号:
hcid_dbus_setname_complete(sba); break; case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE): hcid_dbus_setscan_enable_complete(sba); break; case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV): hcid_dbus_write_class_complete(sba); break; case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SIMPLE_PAIRING_MODE): hcid_dbus_write_simple_pairing_mode_complete(sba); break; case cmd_opcode_pack(OGF_LINK_CTL, OCF_PIN_CODE_REPLY): case cmd_opcode_pack(OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY): hcid_dbus_pin_code_reply(sba, ptr); break; };}static inline void remote_name_information(int dev, bdaddr_t *sba, void *ptr){ evt_remote_name_req_complete *evt = ptr; bdaddr_t dba; char name[249]; memset(name, 0, sizeof(name)); bacpy(&dba, &evt->bdaddr); if (!evt->status) { char *end; memcpy(name, evt->name, 248); /* It's ok to cast end between const and non-const since * we know it points to inside of name which is non-const */ if (!g_utf8_validate(name, -1, (const char **) &end)) *end = '\0'; write_device_name(sba, &dba, name); } hcid_dbus_remote_name(sba, &dba, evt->status, name);}static inline void remote_version_information(int dev, bdaddr_t *sba, void *ptr){ evt_read_remote_version_complete *evt = ptr; bdaddr_t dba; if (evt->status) return; if (get_bdaddr(dev, sba, btohs(evt->handle), &dba) < 0) return; write_version_info(sba, &dba, btohs(evt->manufacturer), evt->lmp_ver, btohs(evt->lmp_subver));}static inline void inquiry_complete(int dev, bdaddr_t *sba, void *ptr){ hcid_dbus_inquiry_complete(sba);}static inline void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr){ uint8_t num = *(uint8_t *) ptr++; int i; for (i = 0; i < num; i++) { inquiry_info *info = ptr; uint32_t class = info->dev_class[0] | (info->dev_class[1] << 8) | (info->dev_class[2] << 16); hcid_dbus_inquiry_result(sba, &info->bdaddr, class, 0, NULL); update_lastseen(sba, &info->bdaddr); ptr += INQUIRY_INFO_SIZE; }}static inline void inquiry_result_with_rssi(int dev, bdaddr_t *sba, int plen, void *ptr){ uint8_t num = *(uint8_t *) ptr++; int i; if (!num) return; if ((plen - 1) / num == INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE) { for (i = 0; i < num; i++) { inquiry_info_with_rssi_and_pscan_mode *info = ptr; uint32_t class = info->dev_class[0] | (info->dev_class[1] << 8) | (info->dev_class[2] << 16); hcid_dbus_inquiry_result(sba, &info->bdaddr, class, info->rssi, NULL); update_lastseen(sba, &info->bdaddr); ptr += INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE; } } else { for (i = 0; i < num; i++) { inquiry_info_with_rssi *info = ptr; uint32_t class = info->dev_class[0] | (info->dev_class[1] << 8) | (info->dev_class[2] << 16); hcid_dbus_inquiry_result(sba, &info->bdaddr, class, info->rssi, NULL); update_lastseen(sba, &info->bdaddr); ptr += INQUIRY_INFO_WITH_RSSI_SIZE; } }}static inline void extended_inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr){ uint8_t num = *(uint8_t *) ptr++; int i; for (i = 0; i < num; i++) { extended_inquiry_info *info = ptr; uint32_t class = info->dev_class[0] | (info->dev_class[1] << 8) | (info->dev_class[2] << 16); hcid_dbus_inquiry_result(sba, &info->bdaddr, class, info->rssi, info->data); update_lastseen(sba, &info->bdaddr); ptr += EXTENDED_INQUIRY_INFO_SIZE; }}static inline void remote_features_information(int dev, bdaddr_t *sba, void *ptr){ evt_read_remote_features_complete *evt = ptr; bdaddr_t dba; if (evt->status) return; if (get_bdaddr(dev, sba, btohs(evt->handle), &dba) < 0) return; write_features_info(sba, &dba, evt->features);}static inline void conn_complete(int dev, int dev_id, bdaddr_t *sba, void *ptr){ evt_conn_complete *evt = ptr; char filename[PATH_MAX]; remote_name_req_cp cp_name; struct hci_req_data *data; char local_addr[18], peer_addr[18], *str; if (evt->link_type != ACL_LINK) return; hcid_dbus_conn_complete(sba, evt->status, evt->handle, &evt->bdaddr); if (evt->status) return; update_lastused(sba, &evt->bdaddr); /* Request remote name */ memset(&cp_name, 0, sizeof(cp_name)); bacpy(&cp_name.bdaddr, &evt->bdaddr); cp_name.pscan_rep_mode = 0x02; data = hci_req_data_new(dev_id, &evt->bdaddr, OGF_LINK_CTL, OCF_REMOTE_NAME_REQ, EVT_REMOTE_NAME_REQ_COMPLETE, &cp_name, REMOTE_NAME_REQ_CP_SIZE); hci_req_queue_append(data); /* check if the remote version needs be requested */ ba2str(sba, local_addr); ba2str(&evt->bdaddr, peer_addr); create_name(filename, sizeof(filename), STORAGEDIR, local_addr, "manufacturers"); str = textfile_get(filename, peer_addr); if (!str) { read_remote_version_cp cp; cp.handle = evt->handle; data = hci_req_data_new(dev_id, &evt->bdaddr, OGF_LINK_CTL, OCF_READ_REMOTE_VERSION, EVT_READ_REMOTE_VERSION_COMPLETE, &cp, READ_REMOTE_VERSION_CP_SIZE); hci_req_queue_append(data); } else free(str);}static inline void disconn_complete(int dev, bdaddr_t *sba, void *ptr){ evt_disconn_complete *evt = ptr; hcid_dbus_disconn_complete(sba, evt->status, evt->handle, evt->reason);}static inline void auth_complete(int dev, bdaddr_t *sba, void *ptr){ evt_auth_complete *evt = ptr; bdaddr_t dba; if (get_bdaddr(dev, sba, btohs(evt->handle), &dba) < 0) return; if (evt->status) hcid_dbus_bonding_process_complete(sba, &dba, evt->status);}static inline void conn_request(int dev, bdaddr_t *sba, void *ptr){ evt_conn_request *evt = ptr; uint32_t class = evt->dev_class[0] | (evt->dev_class[1] << 8) | (evt->dev_class[2] << 16); hcid_dbus_remote_class(sba, &evt->bdaddr, class); write_remote_class(sba, &evt->bdaddr, class);}static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data){ unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf; struct hci_dev_info *di = data; int type, dev; size_t len; hci_event_hdr *eh; GIOError err; if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) { g_io_channel_unref(chan); return FALSE; } if ((err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len))) { if (err == G_IO_ERROR_AGAIN) return TRUE; g_io_channel_unref(chan); return FALSE; } type = *ptr++; if (type != HCI_EVENT_PKT) return TRUE; eh = (hci_event_hdr *) ptr; ptr += HCI_EVENT_HDR_SIZE; dev = g_io_channel_unix_get_fd(chan); ioctl(dev, HCIGETDEVINFO, (void *) di); if (hci_test_bit(HCI_RAW, &di->flags)) return TRUE; switch (eh->evt) { case EVT_CMD_STATUS: cmd_status(dev, &di->bdaddr, ptr); break; case EVT_CMD_COMPLETE: cmd_complete(dev, &di->bdaddr, ptr); break; case EVT_REMOTE_NAME_REQ_COMPLETE: remote_name_information(dev, &di->bdaddr, ptr); break; case EVT_READ_REMOTE_VERSION_COMPLETE: remote_version_information(dev, &di->bdaddr, ptr); break; case EVT_READ_REMOTE_FEATURES_COMPLETE: remote_features_information(dev, &di->bdaddr, ptr); break; case EVT_INQUIRY_COMPLETE: inquiry_complete(dev, &di->bdaddr, ptr); break; case EVT_INQUIRY_RESULT: inquiry_result(dev, &di->bdaddr, eh->plen, ptr); break; case EVT_INQUIRY_RESULT_WITH_RSSI: inquiry_result_with_rssi(dev, &di->bdaddr, eh->plen, ptr); break; case EVT_EXTENDED_INQUIRY_RESULT: extended_inquiry_result(dev, &di->bdaddr, eh->plen, ptr); break; case EVT_CONN_COMPLETE: conn_complete(dev, di->dev_id, &di->bdaddr, ptr); break; case EVT_DISCONN_COMPLETE: disconn_complete(dev, &di->bdaddr, ptr); break; case EVT_AUTH_COMPLETE: auth_complete(dev, &di->bdaddr, ptr); break; case EVT_CONN_REQUEST: conn_request(dev, &di->bdaddr, ptr); break; } /* Check for pending command request */ check_pending_hci_req(di->dev_id, eh->evt); if (hci_test_bit(HCI_SECMGR, &di->flags)) return TRUE; switch (eh->evt) { case EVT_PIN_CODE_REQ: pin_code_request(dev, &di->bdaddr, (bdaddr_t *) ptr); break; case EVT_LINK_KEY_REQ: link_key_request(dev, &di->bdaddr, (bdaddr_t *) ptr); break; case EVT_LINK_KEY_NOTIFY: link_key_notify(dev, &di->bdaddr, ptr); break; case EVT_RETURN_LINK_KEYS: return_link_keys(dev, &di->bdaddr, ptr); break; case EVT_IO_CAPABILITY_REQUEST: io_capa_request(dev, &di->bdaddr, (bdaddr_t *) ptr); break; case EVT_USER_CONFIRM_REQUEST: user_confirm_request(dev, &di->bdaddr, ptr); break; case EVT_USER_PASSKEY_REQUEST: user_passkey_request(dev, &di->bdaddr, ptr); break; case EVT_REMOTE_OOB_DATA_REQUEST: remote_oob_data_request(dev, &di->bdaddr, ptr); break; } return TRUE;}void start_security_manager(int hdev){ GIOChannel *chan = io_data[hdev].channel; struct hci_dev_info *di; struct hci_filter flt; read_stored_link_key_cp cp; int dev; if (chan) return; info("Starting security manager %d", hdev); if ((dev = hci_open_dev(hdev)) < 0) { error("Can't open device hci%d: %s (%d)", hdev, strerror(errno), errno); return; } /* Set filter */ hci_filter_clear(&flt); hci_filter_set_ptype(HCI_EVENT_PKT, &flt); hci_filter_set_event(EVT_CMD_STATUS, &flt); hci_filter_set_event(EVT_CMD_COMPLETE, &flt); hci_filter_set_event(EVT_PIN_CODE_REQ, &flt); hci_filter_set_event(EVT_LINK_KEY_REQ, &flt); hci_filter_set_event(EVT_LINK_KEY_NOTIFY, &flt); hci_filter_set_event(EVT_RETURN_LINK_KEYS, &flt); hci_filter_set_event(EVT_IO_CAPABILITY_REQUEST, &flt); hci_filter_set_event(EVT_IO_CAPABILITY_RESPONSE, &flt); hci_filter_set_event(EVT_USER_CONFIRM_REQUEST, &flt); hci_filter_set_event(EVT_USER_PASSKEY_REQUEST, &flt); hci_filter_set_event(EVT_REMOTE_OOB_DATA_REQUEST, &flt); hci_filter_set_event(EVT_USER_PASSKEY_NOTIFY, &flt); hci_filter_set_event(EVT_KEYPRESS_NOTIFY, &flt); hci_filter_set_event(EVT_SIMPLE_PAIRING_COMPLETE, &flt); hci_filter_set_event(EVT_AUTH_COMPLETE, &flt); hci_filter_set_event(EVT_REMOTE_NAME_REQ_COMPLETE, &flt); hci_filter_set_event(EVT_READ_REMOTE_VERSION_COMPLETE, &flt); hci_filter_set_event(EVT_READ_REMOTE_FEATURES_COMPLETE, &flt); hci_filter_set_event(EVT_REMOTE_HOST_FEATURES_NOTIFY, &flt); hci_filter_set_event(EVT_INQUIRY_COMPLETE, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT, &flt); hci_filter_set_event(EVT_INQUIRY_RESULT_WITH_RSSI, &flt); hci_filter_set_event(EVT_EXTENDED_INQUIRY_RESULT, &flt); hci_filter_set_event(EVT_CONN_REQUEST, &flt); hci_filter_set_event(EVT_CONN_COMPLETE, &flt); hci_filter_set_event(EVT_DISCONN_COMPLETE, &flt); if (setsockopt(dev, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { error("Can't set filter on hci%d: %s (%d)", hdev, strerror(errno), errno); close(dev); return; } di = g_new(struct hci_dev_info, 1); if (hci_devinfo(hdev, di) < 0) { error("Can't get device info: %s (%d)", strerror(errno), errno); close(dev); g_free(di); return; } chan = g_io_channel_unix_new(dev); g_io_channel_set_close_on_unref(chan, TRUE); io_data[hdev].watch_id = g_io_add_watch_full(chan, G_PRIORITY_HIGH, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR, io_security_event, di, (GDestroyNotify) g_free); io_data[hdev].channel = chan; io_data[hdev].pin_length = -1; if (hci_test_bit(HCI_RAW, &di->flags)) return; bacpy(&cp.bdaddr, BDADDR_ANY); cp.read_all = 1; hci_send_cmd(dev, OGF_HOST_CTL, OCF_READ_STORED_LINK_KEY, READ_STORED_LINK_KEY_CP_SIZE, (void *) &cp);}void stop_security_manager(int hdev){ GIOChannel *chan = io_data[hdev].channel; if (!chan) return; info("Stopping security manager %d", hdev); g_source_remove(io_data[hdev].watch_id); g_io_channel_unref(io_data[hdev].channel); io_data[hdev].watch_id = -1; io_data[hdev].channel = NULL; io_data[hdev].pin_length = -1;}void init_security_data(void){ pairing = hcid.pairing;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -