From 3ea8df6c702611bf7e08a63d0e2b9f7fb4fd0289 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 8 Jul 2023 16:33:45 +0300 Subject: [PATCH 1/3] device: implement access control to the boards Limit access control to the boards according to the passed username. If the user has no access, the board becoms completely invisible: it is not listed, it is not possible to fetch board description, etc. Signed-off-by: Dmitry Baryshkov --- cdba-server.c | 9 ++++++--- device.c | 38 +++++++++++++++++++++++++++++++++++--- device.h | 15 ++++++++++++--- device_parser.c | 22 ++++++++++++++++++++++ 4 files changed, 75 insertions(+), 9 deletions(-) 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")) { From 5164ca92346a3b56e0166c9b6b06da3a9e4d3131 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 8 Jul 2023 17:11:32 +0300 Subject: [PATCH 2/3] README: update config file syntax Describe optional user/group/device mapping in the config file example. Signed-off-by: Dmitry Baryshkov --- README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README b/README index 2278c3b..9930a09 100644 --- a/README +++ b/README @@ -43,6 +43,8 @@ devices: fastboot_set_active: true - board: evb2k + users: + - username console: /dev/ttyUSB0 fastboot: abcdef3 fastboot_set_active: true From 926ca248fd95ac946508bca7a511d50ae4a13de2 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 8 Jul 2023 17:12:21 +0300 Subject: [PATCH 3/3] cdba-shell: set the CDBA_USER variable Set and export the CDBA_USER variable to enable ACL in cdba-server. Signed-off-by: Dmitry Baryshkov --- shell/cdba-shell | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 shell/cdba-shell diff --git a/shell/cdba-shell b/shell/cdba-shell old mode 100644 new mode 100755 index b23c197..d6c9992 --- a/shell/cdba-shell +++ b/shell/cdba-shell @@ -1,10 +1,10 @@ #!/bin/sh -user=$1 +export CDBA_USER="$1" cmd=${SSH_ORIGINAL_COMMAND%% *} if [ "$cmd" = "git-upload-pack" -o "$cmd" = "git-receive-pack" ]; then - if grep -Fxq $user $HOME/admins ; then + if grep -Fxq $CDBA_USER $HOME/admins ; then exec sh -c "$SSH_ORIGINAL_COMMAND" fi