On Tue, Oct 28, 2014 at 3:46 PM, Andy Lutomirski <l...@amacapital.net> wrote: > So far, hidraw_id detects U2F tokens and sets: > ID_U2F_TOKEN=1 > ID_SECURITY_TOKEN=1 > > This causes the uaccess rules to apply to U2F devices.
This works for the Plug-up security key, too. --Andy > --- > > I've never written any udev code before. Feedback welcome. > > If you think this doesn't belong in udev, I can try to find it another home. > > .gitignore | 1 + > Makefile.am | 11 ++++ > rules/60-hidraw.rules | 7 ++ > src/udev/hidraw_id/Makefile | 1 + > src/udev/hidraw_id/hidraw_id.c | 144 > +++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 164 insertions(+) > create mode 100644 rules/60-hidraw.rules > create mode 120000 src/udev/hidraw_id/Makefile > create mode 100644 src/udev/hidraw_id/hidraw_id.c > > diff --git a/.gitignore b/.gitignore > index f119b574c777..4bd3cdf08f0d 100644 > --- a/.gitignore > +++ b/.gitignore > @@ -34,6 +34,7 @@ > /exported > /exported-* > /gtk-doc.make > +/hidraw_id > /hostnamectl > /install-tree > /journalctl > diff --git a/Makefile.am b/Makefile.am > index fae946a388af..9f64687d32b1 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -3542,6 +3542,17 @@ udevlibexec_PROGRAMS += \ > ata_id > > # > ------------------------------------------------------------------------------ > +hidraw_id_SOURCES = \ > + src/udev/hidraw_id/hidraw_id.c > + > +hidraw_id_LDADD = \ > + libudev-internal.la \ > + libsystemd-shared.la > + > +udevlibexec_PROGRAMS += \ > + hidraw_id > + > +# > ------------------------------------------------------------------------------ > cdrom_id_SOURCES = \ > src/udev/cdrom_id/cdrom_id.c > > diff --git a/rules/60-hidraw.rules b/rules/60-hidraw.rules > new file mode 100644 > index 000000000000..1ee9c812f711 > --- /dev/null > +++ b/rules/60-hidraw.rules > @@ -0,0 +1,7 @@ > +# do not edit this file, it will be overwritten on update > + > +ACTION=="remove", GOTO="hidraw_end" > + > +SUBSYSTEM=="hidraw", IMPORT{program}="hidraw_id --udev" > + > +LABEL="keyboard_end" > diff --git a/src/udev/hidraw_id/Makefile b/src/udev/hidraw_id/Makefile > new file mode 120000 > index 000000000000..d0b0e8e0086f > --- /dev/null > +++ b/src/udev/hidraw_id/Makefile > @@ -0,0 +1 @@ > +../Makefile > \ No newline at end of file > diff --git a/src/udev/hidraw_id/hidraw_id.c b/src/udev/hidraw_id/hidraw_id.c > new file mode 100644 > index 000000000000..e32f222f22f9 > --- /dev/null > +++ b/src/udev/hidraw_id/hidraw_id.c > @@ -0,0 +1,144 @@ > +/* > + * Copyright (c) Andrew Lutomirski, 2014 > + * > + * This program is free software: you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation, either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#include <stdio.h> > +#include <string.h> > +#include <sys/types.h> > +#include <sys/stat.h> > +#include <fcntl.h> > +#include <unistd.h> > + > +#include "libudev.h" > +#include "libudev-private.h" > + > +_printf_(6,0) > +static void log_fn(struct udev *udev, int priority, > + const char *file, int line, const char *fn, > + const char *format, va_list args) > +{ > + log_metav(priority, file, line, fn, format, args); > +} > + > +int main(int argc, char **argv) > +{ > + struct udev *udev; > + struct udev_device *dev, *hiddev; > + char path[4096]; > + unsigned char desc[4096]; > + int desclen; > + int fd = -1; > + int i; > + int ret = 1; > + unsigned int usage_page = 0; > + int is_u2f_token = 0; > + > + if (argc != 2) { > + fprintf(stderr, "Usage: hidraw_id SYSFS_PATH|--udev\n"); > + return 1; > + } > + > + log_parse_environment(); > + log_open(); > + > + udev = udev_new(); > + > + udev_set_log_fn(udev, log_fn); > + > + if (!strcmp(argv[1], "--udev")) > + dev = udev_device_new_from_environment(udev); > + else > + dev = udev_device_new_from_syspath(udev, argv[1]); > + > + if (!dev) > + goto out; > + > + hiddev = udev_device_get_parent(dev); > + if (!hiddev) > + goto out; > + > + if (snprintf(path, sizeof(path), "%s/report_descriptor", > + udev_device_get_syspath(hiddev)) > (int)sizeof(path)) > + return 1; > + > + fd = open(path, O_RDONLY | O_NOFOLLOW); > + if (fd == -1) > + goto out; > + > + desclen = read(fd, desc, sizeof(desc)); > + if (desclen <= 0) > + goto out; > + > + /* Parse the report descriptor. */ > + for (i = 0; i < desclen; ) { > + unsigned char tag = desc[i] >> 4; > + unsigned char type = (desc[i] >> 2) & 0x3; > + unsigned char sizecode = desc[i] & 0x3; > + int size, j; > + unsigned int value = 0; > + > + if (desc[i] == 0xfe) { > + /* Long item; skip it. */ > + if (i + 1 >= desclen) { > + log_error("bad report_descriptor"); > + goto out; > + } > + i += (desc[i+1] + 3); /* Can't overflow. */ > + continue; > + } > + > + size = (sizecode < 3 ? sizecode : 4); > + if (i + 1 + size > desclen) { > + log_error("bad report_descriptor"); > + goto out; > + } > + > + for (j = 0; j < size; j++) > + value |= (desc[i + 1 + j] << 8*j); > + > + if (type == 1 && tag == 0) > + usage_page = value; > + > + /* > + * Detect U2F tokens. See: > + * > https://fidoalliance.org/specs/fido-u2f-HID-protocol-v1.0-rd-20141008.pdf > + * http://www.usb.org/developers/hidpage/HUTRR48.pdf > + */ > + > + if (type == 2 && tag == 0) { > + if (usage_page == 0xf1d0 && value == 0x1) > + is_u2f_token = 1; > + } > + > + i += 1 + size; > + } > + > + if (is_u2f_token) > + printf("ID_U2F_TOKEN=1\nID_SECURITY_TOKEN=1\n"); > + > + ret = 0; > + > +out: > + if (fd != -1) > + close(fd); > + if (dev) > + udev_device_unref(dev); > + udev_unref(udev); > + > + log_close(); > + > + return ret; > +} > -- > 1.9.3 > -- Andy Lutomirski AMA Capital Management, LLC _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel