📄 sec_client.c
字号:
link_key_list.cur = new_link_key; /* Set current to new element */ link_key_list.first = new_link_key; /* Set first to new element */ link_key_list.count++;}s32 delete_link_key(link_key_information_type *link_key){ if (link_key_list.count == 1) { /* Last element */ D_PROC("Deleting last element\n"); link_key_list.count--; link_key_list.first = NULL; link_key_list.cur = NULL; link_key_list.last = NULL; kfree(link_key); return 0; } D_PROC("Deleting element in list\n"); link_key->prev->next = link_key->next; /* Take it out */ link_key->next->prev = link_key->prev; if (link_key_list.first == link_key) /* Update first pointer */ link_key_list.first = link_key->next; if (link_key_list.last == link_key) /* Update last pointer */ link_key_list.last = link_key->prev; link_key_list.cur = link_key->next; /* Update cur pointer */ link_key_list.count--; kfree(link_key); return 0; }#ifdef __KERNEL__s32sec_man_create_proc_file(void){ s32 procfs_status = -ENOENT; /* The sec_man_wq wait queue must be initialised before anyone tries to read from the /proc/sec_srv file, so we initialise the wait queue here */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) init_waitqueue_head(&sec_man_wq);#endif /* LINUX_VERSION_CODE */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) { struct proc_dir_entry *entry; procfs_status = -1; if ((entry = create_proc_entry(sec_man_proc_entry.name, sec_man_proc_entry.mode, &proc_root))) { /*---------------------------------------------------*/ /* If the proc entry was registered successfully, */ /* then set all the necessary structure information. */ /*---------------------------------------------------*/ entry->proc_iops = sec_man_proc_entry.proc_iops; entry->proc_fops = sec_man_proc_entry.proc_fops; entry->get_info = sec_man_proc_entry.get_info; procfs_status = 0; } }#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0) procfs_status = proc_register(&proc_root, &sec_man_proc_entry);#else procfs_status = proc_register_dynamic(&proc_root, &sec_man_proc_entry);#endif /* LINUX_VERSION_CODE */ if (procfs_status < 0) { D_ERR("Couldn't register proc file for security manager %d\n", procfs_status); } return procfs_status;}s32sec_man_remove_proc_file(void){#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) remove_proc_entry(sec_man_proc_entry.name, &proc_root);#else proc_unregister(&proc_root, sec_man_proc_entry.low_ino);#endif return 0;}#endif /* __KERNEL__ *//* fixme -- add return value for calling functions to indicate status of check */void sec_man_check(enum security_requests user, BD_ADDR bd_addr, u32 service_data, u32 user_data){#define FNC "sec_man_check: "#ifndef __KERNEL__ if (sec_man_sock < 0) { /* What to do if no security manager present?? */ D_ERR("%s, line %d No security manager present\n", __FILE__, __LINE__); /* *** NOTE *** * Make sure CONFIG_BLUETOOTH_USE_SECURITY_MANAGER is * undefined (either in kernel configuration or in btconfig.h) * if you don't know what this is... */ }#endif security_query.request_type = user; security_query.request_value = service_data; memcpy(security_query.remote_bd, bd_addr, BD_ADDRESS_SIZE); security_query.originator = BT_SEC_MAN; security_query.originator_data = user_data; security_query.request_result = GENERAL_FAILURE;#ifdef __KERNEL__ D_PROC("wake_up process %i (%s) awakening\n", current->pid, current->comm); wake_up_interruptible(&sec_man_wq); D_PROC("wake_up process %i (%s) woke up\n", current->pid, current->comm);#else sec_man_doquery(sec_man_sock, (u8*) &security_query);#endif #undef FNC}voidsec_man_event(enum security_requests user, BD_ADDR bd_addr, u8 event, u8 *param, u8 param_len){#define FNC "sec_man_event: " if (event == HCI_VALUE_RETURN_LINK_KEYS) { /* Ok, link key has to be stored locally */ link_key_information_type *link_key; unsigned char link_key_str[LINK_KEY_SIZE]; memcpy(link_key_str, param, LINK_KEY_SIZE); link_key = create_link_key(bd_addr, link_key_str); insert_link_key(link_key); D_PROC("sec_man_event: Number of elements in list: %d\n", link_key_list.count); } else {#ifndef __KERNEL__ if (sec_man_sock < 0) { /* What to do if no security manager present?? */ }#endif D_PROC("Called sec_man_event user:%d event:%02x\n", user, event); security_query.request_type = user; security_query.request_value = event; memcpy(security_query.remote_bd, bd_addr, BD_ADDRESS_SIZE); security_query.originator = BT_SEC_MAN; if (param_len > MAX_EVENT_DATA_LENGTH) { D_PROC("Event data length too long, %d byte\n", param_len); memcpy(security_query.event_param, param, MAX_EVENT_DATA_LENGTH); } else { memcpy(security_query.event_param, param, param_len); } security_query.request_result = GENERAL_FAILURE; #ifdef __KERNEL__ D_PROC("wake_up process %i (%s) awakening\n", current->pid, current->comm); wake_up_interruptible(&sec_man_wq); D_PROC("wake_up process %i (%s) woke up\n", current->pid, current->comm);#else sec_man_doquery(sec_man_sock, (u8*) &security_query);#endif }#undef FNC }void sec_man_get_cached_link_key(u8 *param){ link_key_information_type *link_key; link_key = get_first_link_key(); D_PROC("sec_man_get_cached_link_key: \n"); if (link_key != NULL) { memcpy(param, link_key->bd_addr, BD_ADDRESS_SIZE); memcpy(param + BD_ADDRESS_SIZE, link_key->link_key, LINK_KEY_SIZE); D_PROC("Returning bd address %02x:%02x:%02x:%02x:%02x:%02x", link_key->bd_addr[0], link_key->bd_addr[1], link_key->bd_addr[2], link_key->bd_addr[3], link_key->bd_addr[4], link_key->bd_addr[5]); delete_link_key(link_key); } else { memset(param, 0, BD_ADDRESS_SIZE + LINK_KEY_SIZE); }}/* -------------------- Local functions --------------------------- */#ifndef __KERNEL__int open_socket(char *name){ struct sockaddr_un server_address; s32 client_sockfd; s32 server_len; printf("Opening socket %s\n", name); client_sockfd = socket(AF_UNIX, SOCK_STREAM, 0); /* 'destination' socket */ server_address.sun_family = AF_UNIX; strcpy(server_address.sun_path, name); server_len = sizeof(server_address); if (connect(client_sockfd, (struct sockaddr *)&server_address, server_len) < 0) { perror("connect client socket"); D_ERR("Couldn't open socket, security manager can not be used\n"); return -1; } printf("Socket connected to %s\n", server_address.sun_path); return client_sockfd;}#endif#ifdef __KERNEL__s32 sec_man_proc_dir_entry_read(char *buf, char **start, off_t offset, s32 len, s32 unused){#define FNC "sec_proc_dir_entry_read: "#ifdef USE_NEW_PROC return sec_man_read(NULL, buf, len, 0);#else return sec_man_read(NULL, NULL, buf, len);#endif#undef FNC}#ifdef USE_NEW_PROCssize_t sec_man_read(struct file * file, char * buf, size_t count, loff_t *offset)#elses32 sec_man_read(struct inode *inode, struct file * file, char * buf, s32 count)#endif{#define FNC "sec_man_read: " s32 tmp; D_PROC(FNC" Someone is trying to read % d bytes from sec proc-file\n", count); if (security_query.originator == KERNEL) { D_PROC(FNC"Shutdown of stack in progress, nothing to read!\n"); return 1; } cli(); if (security_query.originator != BT_SEC_MAN) { D_PROC(FNC"No response yet, going to sleep\n"); interruptible_sleep_on(&sec_man_wq); } sti(); tmp = sizeof(struct security_query); memcpy(buf, &security_query, tmp); D_PROC(FNC"Returning %d bytes\n", tmp); security_query.originator = SEC_CLIENT; /* Change so we lock again */ return tmp; #undef FNC}#ifdef USE_NEW_PROCssize_t sec_man_write(struct file * file, const char * buf, size_t count, loff_t *offset)#elses32 sec_man_write(struct inode *inode, struct file * file, const char * buf, s32 count)#endif{#define FNC "sec_man_write: " struct security_query *sec_hdl; sec_hdl = (struct security_query *)(buf); D_PROC(FNC"Someone wrote %d bytes to sec proc-file\n",count); /* D_XMIT(FNC"preparing to send data to sec_con[%d]\n", secb_hdl->sec_con_id); */ if (sec_hdl->originator == BT_SEC_MAN) /* o.k. new request */ { /* Change so we do not receive old data */ security_query.originator = SEC_CLIENT; switch (sec_hdl->request_type) { case L2CAP: D_PROC(FNC"Message to L2CAP\n"); l2cap_process_sec_man_response(sec_hdl->request_result, sec_hdl->originator_data); break; case RFCOMM: D_PROC(FNC"Message to RFCOMM\n"); rfcomm_process_sec_man_response(sec_hdl->request_result, sec_hdl->originator_data, sec_hdl->request_value); break; default: /* print error */ break; } } return count;#undef FNC}#else /* __KERNEL__ */s32 sec_man_doquery(s32 fd, u8 *request){ s32 n; u8 tmpbuf[BUFFER_SIZE]; struct security_query *sec_hdl; sec_hdl = (struct security_query*) (request); syslog(LOG_INFO, "sec_man_doquery : sending request\n"); write(fd, request, sizeof(struct security_query)); n = read(fd, tmpbuf, BUFFER_SIZE); /* what if not all is written once */ if (n < sizeof(security_query)) { fprintf(stderr, "sec_man_doquery : only got partial response n:%d, db_hdl->len:%d\n", n, sizeof(struct security_query)); print_data("The request is:", request, sizeof(struct security_query)); return -1; } switch (sec_hdl->request_type) { case L2CAP: l2cap_process_sec_man_response(sec_hdl->request_result, sec_hdl->originator_data); break; case RFCOMM: rfcomm_process_sec_man_response(sec_hdl->request_result, sec_hdl->originator_data, sec_hdl->request_value); break; default: /* print error */ break; } return n;}#endif/****************** END OF FILE sec_client.c *********************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -