diff options
-rw-r--r-- | hcid/dbus.c | 4 | ||||
-rw-r--r-- | hcid/hcid.h | 22 | ||||
-rw-r--r-- | hcid/security.c | 28 | ||||
-rw-r--r-- | hcid/storage.c | 506 |
4 files changed, 84 insertions, 476 deletions
diff --git a/hcid/dbus.c b/hcid/dbus.c index d8a07dd9..7f98c32f 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -170,7 +170,7 @@ failed: OCF_PIN_CODE_NEG_REPLY, 6, &ci->bdaddr); } -void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer, const uint32_t class, const int8_t rssi) +void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) { DBusMessage *message; #ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS @@ -217,7 +217,7 @@ failed: return; } -void hcid_dbus_remote_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name) +void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) { DBusMessage *message; #ifndef HAVE_DBUS_MESSAGE_APPEND_ARGS diff --git a/hcid/hcid.h b/hcid/hcid.h index 3ba69833..4a433984 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -123,21 +123,21 @@ void toggle_pairing(int enable); #ifdef ENABLE_DBUS gboolean hcid_dbus_init(void); void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci); -void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer, const uint32_t class, const int8_t rssi); -void hcid_dbus_remote_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name); +void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi); +void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name); #else -static inline void hcid_dbus_inquiry_result(const bdaddr_t *local, const bdaddr_t *peer, uint32_t class, const int8_t rssi) +static inline void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi) { } -static inline void hcid_dbus_remote_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name) +static inline void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, char *name) { } #endif -int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name); -int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name); -int write_version_info(const bdaddr_t *local, const bdaddr_t *peer, const uint16_t manufacturer, const uint8_t lmp_ver, const uint16_t lmp_subver); -int write_features_info(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *features); -int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type); -int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *key); -int read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin); +int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name); +int read_device_name(bdaddr_t *local, bdaddr_t *peer, char *name); +int write_version_info(bdaddr_t *local, bdaddr_t *peer, uint16_t manufacturer, uint8_t lmp_ver, uint16_t lmp_subver); +int write_features_info(bdaddr_t *local, bdaddr_t *peer, unsigned char *features); +int write_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key, int type); +int read_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key); +int read_pin_code(bdaddr_t *local, bdaddr_t *peer, char *pin); diff --git a/hcid/security.c b/hcid/security.c index fb4c813e..ab22f14d 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -69,7 +69,7 @@ void toggle_pairing(int enable) syslog(LOG_INFO, "Pairing %s", pairing ? "enabled" : "disabled"); } -static int get_bdaddr(int dev, bdaddr_t *sba, uint16_t handle, bdaddr_t *dba) +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; @@ -340,8 +340,10 @@ static void call_pin_helper(int dev, bdaddr_t *sba, struct hci_conn_info *ci) *ptr++ = '\\'; } *ptr++ = name[i]; - } else + } else { + name[i] = '.'; *ptr++ = '.'; + } ba2str(&ci->bdaddr, addr); snprintf(str, sizeof(str), "%s %s %s \"%s\"", hcid.pin_helper, @@ -475,20 +477,26 @@ reject: return; } -static void remote_name_information(int dev, bdaddr_t *sba, void *ptr) +static inline void remote_name_information(int dev, bdaddr_t *sba, void *ptr) { evt_remote_name_req_complete *evt = ptr; - bdaddr_t *dba = &evt->bdaddr; + char name[249]; + bdaddr_t dba; if (evt->status) return; - hcid_dbus_remote_name(sba, dba, (char *) evt->name); + memset(name, 0, sizeof(name)); + memcpy(name, evt->name, 248); + + bacpy(&dba, &evt->bdaddr); + + hcid_dbus_remote_name(sba, &dba, name); - write_device_name(sba, dba, (char *) evt->name); + write_device_name(sba, &dba, name); } -static void remote_version_information(int dev, bdaddr_t *sba, void *ptr) +static inline void remote_version_information(int dev, bdaddr_t *sba, void *ptr) { evt_read_remote_version_complete *evt = ptr; bdaddr_t dba; @@ -503,7 +511,7 @@ static void remote_version_information(int dev, bdaddr_t *sba, void *ptr) evt->lmp_ver, btohs(evt->lmp_subver)); } -static void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr) +static inline void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr) { uint8_t num = *(uint8_t *) ptr++; int i; @@ -520,7 +528,7 @@ static void inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr) } } -static void inquiry_result_with_rssi(int dev, bdaddr_t *sba, int plen, void *ptr) +static inline void inquiry_result_with_rssi(int dev, bdaddr_t *sba, int plen, void *ptr) { uint8_t num = *(uint8_t *) ptr++; int i; @@ -555,7 +563,7 @@ static void inquiry_result_with_rssi(int dev, bdaddr_t *sba, int plen, void *ptr } } -static void remote_features_information(int dev, bdaddr_t *sba, void *ptr) +static inline void remote_features_information(int dev, bdaddr_t *sba, void *ptr) { evt_read_remote_features_complete *evt = ptr; bdaddr_t dba; diff --git a/hcid/storage.c b/hcid/storage.c index 459ebff6..63bf3397 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -48,129 +48,16 @@ #include "textfile.h" #include "hcid.h" -struct list { - bdaddr_t bdaddr; - unsigned char *data; - size_t size; - struct list *next; -}; - -static struct list *list_add(struct list *list, const bdaddr_t *bdaddr, - const char *data, const size_t size) -{ - struct list *temp = list, *last = list; - - if (!bacmp(bdaddr, BDADDR_ANY)) - return list; - - while (temp) { - if (!bacmp(&temp->bdaddr, bdaddr)) { - if (temp->data) - free(temp->data); - - temp->data = malloc(size); - if (temp->data) { - memcpy(temp->data, data, size); - temp->size = size; - } else - temp->size = 0; - - return list; - } - temp = temp->next; - } - - temp = malloc(sizeof(*temp)); - if (!temp) - return list; - - memset(temp, 0, sizeof(*temp)); - - bacpy(&temp->bdaddr, bdaddr); - temp->data = malloc(size); - if (temp->data) { - memcpy(temp->data, data, size); - temp->size = size; - } else - temp->size = 0; - - temp->next = NULL; - - if (!list) - return temp; - - while (last->next) - last = last->next; - - last->next = temp; - - return list; -} - -static struct list *list_free(struct list *list) -{ - struct list *temp = list; - - if (!list) - return NULL; - - while (list->next) { - temp = list; - list = list->next; - if (temp->data) - free(temp->data); - free(temp); - } - - return NULL; -} - -#define list_foreach(list, entry) \ - for (entry = list; entry; entry = entry->next) - -static int create_dirs(const char *filename, mode_t mode) -{ - struct stat st; - char dir[PATH_MAX + 1], *prev, *next; - int err; - - err = stat(filename, &st); - if (!err && S_ISREG(st.st_mode)) - return 0; - - memset(dir, 0, PATH_MAX + 1); - strcat(dir, "/"); - - prev = strchr(filename, '/'); - - while (prev) { - next = strchr(prev + 1, '/'); - if (!next) - break; - - if (next - prev == 1) { - prev = next; - continue; - } - - strncat(dir, prev + 1, next - prev); - mkdir(dir, mode); - - prev = next; - } - - return 0; -} - -int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *name) +int write_device_name(bdaddr_t *local, bdaddr_t *peer, char *name) { char filename[PATH_MAX + 1], addr[18], str[249]; int i; memset(str, 0, sizeof(str)); - strncpy(str, name, 248); - for (i = 0; i < 248 && str[i]; i++) - if (!isprint(str[i])) + for (i = 0; i < 248 && name[i]; i++) + if (isprint(name[i])) + str[i] = name[i]; + else str[i] = '.'; ba2str(local, addr); @@ -180,9 +67,10 @@ int write_device_name(const bdaddr_t *local, const bdaddr_t *peer, const char *n return textfile_put(filename, addr, str); } -int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) +int read_device_name(bdaddr_t *local, bdaddr_t *peer, char *name) { char filename[PATH_MAX + 1], addr[18], *str; + int len; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/names", STORAGEDIR, addr); @@ -192,386 +80,98 @@ int read_device_name(const bdaddr_t *local, const bdaddr_t *peer, char *name) if (!str) return -ENOENT; - memset(name, 0, 249); - strncpy(name, str, 248); + len = strlen(str); + if (len > 248) + str[248] = '\0'; + strcpy(name, str); return 0; } -int write_version_info(const bdaddr_t *local, const bdaddr_t *peer, const uint16_t manufacturer, const uint8_t lmp_ver, const uint16_t lmp_subver) +int write_version_info(bdaddr_t *local, bdaddr_t *peer, uint16_t manufacturer, uint8_t lmp_ver, uint16_t lmp_subver) { - struct list *temp, *list = NULL; - char filename[PATH_MAX + 1], addr[18], str[16], *buf, *ptr; - bdaddr_t bdaddr; - struct stat st; - int fd, pos, err = 0; - - ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/manufacturers", STORAGEDIR, addr); - - umask(S_IWGRP | S_IWOTH); - create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - - fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (fd < 0) - return -errno; - - if (flock(fd, LOCK_EX) < 0) { - err = -errno; - goto close; - } - - if (fstat(fd, &st) < 0) { - err = -errno; - goto unlock; - } - - buf = malloc(st.st_size + 100); - if (!buf) { - err = -ENOMEM; - goto unlock; - } - - if (st.st_size > 0) { - read(fd, buf, st.st_size); - - ptr = buf; - - memset(str, 0, sizeof(str)); - while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { - str2ba(addr, &bdaddr); - str[sizeof(str) - 1] = '\0'; - - list = list_add(list, &bdaddr, str, sizeof(str)); - - memset(str, 0, sizeof(str)); - ptr += pos; - if (ptr - buf >= st.st_size) - break; - }; - - lseek(fd, 0, SEEK_SET); - ftruncate(fd, 0); - } + char filename[PATH_MAX + 1], addr[18], str[16]; memset(str, 0, sizeof(str)); sprintf(str, "%d %d %d", manufacturer, lmp_ver, lmp_subver); - list = list_add(list, peer, str, sizeof(str)); - if (!list) { - err = -EIO; - goto unlock; - } - - list_foreach(list, temp) { - ba2str(&temp->bdaddr, addr); - if (temp->data && temp->size > 0) { - memset(buf, 0, 100); - snprintf(buf, 99, "%s %s\n", addr, temp->data); - write(fd, buf, strlen(buf)); - } - } - -unlock: - flock(fd, LOCK_UN); + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/manufacturers", STORAGEDIR, addr); -close: - close(fd); - list_free(list); - return err; + ba2str(peer, addr); + return textfile_put(filename, addr, str); } -int write_features_info(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *features) +int write_features_info(bdaddr_t *local, bdaddr_t *peer, unsigned char *features) { - struct list *temp, *list = NULL; - char filename[PATH_MAX + 1], addr[18], str[17], *buf, *ptr; - bdaddr_t bdaddr; - struct stat st; - int i, fd, pos, err = 0; - - ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/features", STORAGEDIR, addr); - - umask(S_IWGRP | S_IWOTH); - create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - - fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (fd < 0) - return -errno; - - if (flock(fd, LOCK_EX) < 0) { - err = -errno; - goto close; - } - - if (fstat(fd, &st) < 0) { - err = -errno; - goto unlock; - } - - buf = malloc(st.st_size + 100); - if (!buf) { - err = -ENOMEM; - goto unlock; - } - - if (st.st_size > 0) { - read(fd, buf, st.st_size); - - ptr = buf; - - memset(str, 0, sizeof(str)); - while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { - str2ba(addr, &bdaddr); - str[sizeof(str) - 1] = '\0'; - - list = list_add(list, &bdaddr, str, sizeof(str)); - - memset(str, 0, sizeof(str)); - ptr += pos; - if (ptr - buf >= st.st_size) - break; - }; - - lseek(fd, 0, SEEK_SET); - ftruncate(fd, 0); - } + char filename[PATH_MAX + 1], addr[18], str[17]; + int i; memset(str, 0, sizeof(str)); for (i = 0; i < 8; i++) sprintf(str + (i * 2), "%2.2X", features[i]); - list = list_add(list, peer, str, sizeof(str)); - if (!list) { - err = -EIO; - goto unlock; - } - - list_foreach(list, temp) { - ba2str(&temp->bdaddr, addr); - if (temp->data && temp->size > 0) { - memset(buf, 0, 100); - snprintf(buf, 99, "%s %s\n", addr, temp->data); - write(fd, buf, strlen(buf)); - } - } - -unlock: - flock(fd, LOCK_UN); + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/features", STORAGEDIR, addr); -close: - close(fd); - list_free(list); - return err; + ba2str(peer, addr); + return textfile_put(filename, addr, str); } -int write_link_key(const bdaddr_t *local, const bdaddr_t *peer, const unsigned char *key, const int type) +int write_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key, int type) { - struct list *temp, *list = NULL; - char filename[PATH_MAX + 1], addr[18], str[35], *buf, *ptr; - bdaddr_t bdaddr; - struct stat st; - int i, fd, pos, err = 0; - - ba2str(local, addr); - snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr); - - umask(S_IWGRP | S_IWOTH); - create_dirs(filename, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); - - fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); - if (fd < 0) - return -errno; - - if (flock(fd, LOCK_EX) < 0) { - err = -errno; - goto close; - } - - if (fstat(fd, &st) < 0) { - err = -errno; - goto unlock; - } - - buf = malloc(st.st_size + 100); - if (!buf) { - err = -ENOMEM; - goto unlock; - } - - if (st.st_size > 0) { - read(fd, buf, st.st_size); - - ptr = buf; - - memset(str, 0, sizeof(str)); - while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { - str2ba(addr, &bdaddr); - str[sizeof(str) - 1] = '\0'; - - list = list_add(list, &bdaddr, str, sizeof(str)); - - memset(str, 0, sizeof(str)); - ptr += pos; - if (ptr - buf >= st.st_size) - break; - }; - - lseek(fd, 0, SEEK_SET); - ftruncate(fd, 0); - } + char filename[PATH_MAX + 1], addr[18], str[35]; + int i; memset(str, 0, sizeof(str)); for (i = 0; i < 16; i++) sprintf(str + (i * 2), "%2.2X", key[i]); sprintf(str + 32, " %d", type); - list = list_add(list, peer, str, sizeof(str)); - if (!list) { - err = -EIO; - goto unlock; - } - - list_foreach(list, temp) { - ba2str(&temp->bdaddr, addr); - if (temp->data && temp->size > 0) { - memset(buf, 0, 100); - snprintf(buf, 99, "%s %s\n", addr, temp->data); - write(fd, buf, strlen(buf)); - } - } - -unlock: - flock(fd, LOCK_UN); + ba2str(local, addr); + snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr); -close: - close(fd); - list_free(list); - return err; + ba2str(peer, addr); + return textfile_put(filename, addr, str); } -int read_link_key(const bdaddr_t *local, const bdaddr_t *peer, unsigned char *key) +int read_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key) { - char filename[PATH_MAX + 1], addr[18], str[35], tmp[3], *buf, *ptr; - bdaddr_t bdaddr; - struct stat st; - int i, fd, pos, err = -ENOENT; + char filename[PATH_MAX + 1], addr[18], tmp[3], *str; + int i; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/linkkeys", STORAGEDIR, addr); - fd = open(filename, O_RDONLY); - if (fd < 0) - return -errno; - - if (flock(fd, LOCK_SH) < 0) { - err = -errno; - goto close; - } - - if (fstat(fd, &st) < 0) { - err = -errno; - goto unlock; - } - - buf = malloc(st.st_size); - if (!buf) { - err = -ENOMEM; - goto unlock; - } + ba2str(peer, addr); + str = textfile_get(filename, addr); + if (!str) + return -ENOENT; - if (st.st_size > 0) { - read(fd, buf, st.st_size); - - ptr = buf; - - memset(str, 0, sizeof(str)); - while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { - str2ba(addr, &bdaddr); - str[sizeof(str) - 1] = '\0'; - - if (!bacmp(&bdaddr, peer)) { - memset(tmp, 0, sizeof(tmp)); - for (i = 0; i < 16; i++) { - memcpy(tmp, str + (i * 2), 2); - key[i] = (uint8_t) strtol(tmp, NULL, 16); - } - err = 0; - break; - } - - memset(str, 0, sizeof(str)); - ptr += pos; - if (ptr - buf >= st.st_size) - break; - }; + memset(tmp, 0, sizeof(tmp)); + for (i = 0; i < 16; i++) { + memcpy(tmp, str + (i * 2), 2); + key[i] = (uint8_t) strtol(tmp, NULL, 16); } -unlock: - flock(fd, LOCK_UN); - -close: - close(fd); - return err; + return 0; } -int read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin) +int read_pin_code(bdaddr_t *local, bdaddr_t *peer, char *pin) { - char filename[PATH_MAX + 1], addr[18], str[17], *buf, *ptr; - bdaddr_t bdaddr; - struct stat st; - int fd, pos, err = -ENOENT; + char filename[PATH_MAX + 1], addr[18], *str; + int len; ba2str(local, addr); snprintf(filename, PATH_MAX, "%s/%s/pincodes", STORAGEDIR, addr); - fd = open(filename, O_RDONLY); - if (fd < 0) - return -errno; - - if (flock(fd, LOCK_SH) < 0) { - err = -errno; - goto close; - } - - if (fstat(fd, &st) < 0) { - err = -errno; - goto unlock; - } - - buf = malloc(st.st_size); - if (!buf) { - err = -ENOMEM; - goto unlock; - } - - if (st.st_size > 0) { - read(fd, buf, st.st_size); - - ptr = buf; - - memset(str, 0, sizeof(str)); - while (sscanf(ptr, "%17s %[^\n]\n%n", addr, str, &pos) != EOF) { - str2ba(addr, &bdaddr); - str[sizeof(str) - 1] = '\0'; - - if (!bacmp(&bdaddr, peer)) { - strncpy(pin, str, 16); - err = strlen(pin); - break; - } - - memset(str, 0, sizeof(str)); - ptr += pos; - if (ptr - buf >= st.st_size) - break; - }; - } + ba2str(peer, addr); + str = textfile_get(filename, addr); + if (!str) + return -ENOENT; -unlock: - flock(fd, LOCK_UN); + strncpy(pin, str, 16); + len = strlen(pin); -close: - close(fd); - return err; + return len; } |