diff --git a/cdba-server.c b/cdba-server.c index af45f79..ceec6a0 100644 --- a/cdba-server.c +++ b/cdba-server.c @@ -47,6 +47,7 @@ #include "list.h" static bool quit_invoked; +static const char *username; struct device *selected_device; @@ -121,7 +122,7 @@ static void msg_select_board(const void *param) { struct msg reply = { MSG_SELECT_BOARD, 0 }; - selected_device = device_open(param, &fastboot_ops); + selected_device = device_open(param, username, &fastboot_ops); if (!selected_device) { fprintf(stderr, "failed to open %s\n", (const char *)param); quit_invoked = true; @@ -231,10 +232,10 @@ static int handle_stdin(int fd, void *buf) device_send_break(selected_device); break; case MSG_LIST_DEVICES: - device_list_devices(); + device_list_devices(username); break; case MSG_BOARD_INFO: - device_info(msg->data, msg->len); + device_info(username, msg->data, msg->len); break; default: fprintf(stderr, "unk %d len %d\n", msg->type, msg->len); @@ -364,6 +365,8 @@ int main(int argc, char **argv) signal(SIGPIPE, sigpipe_handler); + username = getenv("CDBA_USER"); + ret = device_parser(".cdba"); if (ret) { ret = device_parser("/etc/cdba"); diff --git a/device.c b/device.c index 76d9660..cc14e52 100644 --- a/device.c +++ b/device.c @@ -83,7 +83,27 @@ static void device_lock(struct device *device) err(1, "failed to lock lockfile %s", lock); } +static bool device_check_access(struct device *device, + const char *username) +{ + struct device_user *user; + + if (!device->users) + return true; + + if (!username) + return false; + + list_for_each_entry(user, device->users, node) { + if (!strcmp(user->username, username)) + return true; + } + + return false; +} + struct device *device_open(const char *board, + const char *username, struct fastboot_ops *fastboot_ops) { struct device *device; @@ -98,6 +118,9 @@ struct device *device_open(const char *board, found: assert(device->open || device->console_dev); + if (!device_check_access(device, username)) + return NULL; + device_lock(device); if (device->open) { @@ -269,7 +292,7 @@ void device_send_break(struct device *device) device->send_break(device); } -void device_list_devices(void) +void device_list_devices(const char *username) { struct device *device; struct msg hdr; @@ -277,6 +300,9 @@ void device_list_devices(void) char buf[80]; list_for_each_entry(device, &devices, node) { + if (!device_check_access(device, username)) + continue; + if (device->name) len = snprintf(buf, sizeof(buf), "%-20s %s", device->board, device->name); else @@ -293,7 +319,7 @@ void device_list_devices(void) write(STDOUT_FILENO, &hdr, sizeof(hdr)); } -void device_info(const void *data, size_t dlen) +void device_info(const char *username, const void *data, size_t dlen) { struct device *device; struct msg hdr; @@ -301,7 +327,13 @@ void device_info(const void *data, size_t dlen) size_t len = 0; list_for_each_entry(device, &devices, node) { - if (!strncmp(device->board, data, dlen) && device->description) { + if (strncmp(device->board, data, dlen)) + continue; + + if (!device_check_access(device, username)) + continue; + + if (device->description) { description = device->description; len = strlen(device->description); break; diff --git a/device.h b/device.h index 2c89f51..5321b70 100644 --- a/device.h +++ b/device.h @@ -15,6 +15,7 @@ struct device { char *name; char *serial; char *description; + struct list_head *users; unsigned voltage; bool tickle_mmc; bool usb_always_on; @@ -45,9 +46,17 @@ struct device { struct list_head node; }; +struct device_user { + const char *username; + + struct list_head node; +}; + void device_add(struct device *device); -struct device *device_open(const char *board, struct fastboot_ops *fastboot_ops); +struct device *device_open(const char *board, + const char *username, + struct fastboot_ops *fastboot_ops); void device_close(struct device *dev); int device_power(struct device *device, bool on); @@ -60,8 +69,8 @@ void device_boot(struct device *device, const void *data, size_t len); void device_fastboot_boot(struct device *device); void device_fastboot_flash_reboot(struct device *device); void device_send_break(struct device *device); -void device_list_devices(void); -void device_info(const void *data, size_t dlen); +void device_list_devices(const char *username); +void device_info(const char *username, const void *data, size_t dlen); enum { DEVICE_KEY_FASTBOOT, diff --git a/device_parser.c b/device_parser.c index 32ff49c..7956682 100644 --- a/device_parser.c +++ b/device_parser.c @@ -90,6 +90,28 @@ static void parse_board(struct device_parser *dp) dev = calloc(1, sizeof(*dev)); while (accept(dp, YAML_SCALAR_EVENT, key)) { + if (!strcmp(key, "users")) { + dev->users = calloc(1, sizeof(*dev->users)); + list_init(dev->users); + + if (accept(dp, YAML_SCALAR_EVENT, value)) + continue; + + expect(dp, YAML_SEQUENCE_START_EVENT, NULL); + + while (accept(dp, YAML_SCALAR_EVENT, key)) { + struct device_user *user = calloc(1, sizeof(*user)); + + user->username = strdup(key); + + list_add(dev->users, &user->node); + } + + expect(dp, YAML_SEQUENCE_END_EVENT, NULL); + + continue; + } + expect(dp, YAML_SCALAR_EVENT, value); if (!strcmp(key, "board")) {