Last active
August 29, 2015 14:10
-
-
Save ghoff/f0675b40b7f0d686a980 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* u2f-detect | |
* read hid records looking for a usage page of 0xf1d0 and usage 1 | |
* returns true, to be used for udev-rules to set permissions on hidraw | |
* | |
* Copyright (c) 2014 Geoff Hoff http://github.com/ghoff | |
* includes code from hidraw and based on code from lsusb | |
* | |
* 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. | |
*/ | |
/* | |
* Hidraw Userspace Example | |
* | |
* Copyright (c) 2010 Alan Ott <alan@signal11.us> | |
* Copyright (c) 2010 Signal 11 Software | |
* | |
* The code may be used by anyone for any purpose, | |
* and can serve as a starting point for developing | |
* applications using hidraw. | |
*/ | |
/*****************************************************************************/ | |
/* | |
* lsusb.c -- lspci like utility for the USB bus | |
* | |
* Copyright (C) 1999-2001, 2003 | |
* Thomas Sailer (t.sailer@alumni.ethz.ch) | |
* Copyright (C) 2003-2005 David Brownell | |
* | |
* 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. | |
* | |
*/ | |
/*****************************************************************************/ | |
/* Linux */ | |
#include <linux/hidraw.h> | |
/* Unix */ | |
#include <sys/ioctl.h> | |
#include <fcntl.h> | |
#include <unistd.h> | |
/* C */ | |
#include <stdio.h> | |
#include <string.h> | |
unsigned int report_desc(unsigned char *b, int *i, | |
unsigned int *btype, unsigned int *btag) | |
{ | |
unsigned int j, bsize, data=0; | |
bsize = b[*i] & 0x03; | |
if (bsize == 3) | |
bsize = 4; | |
if (bsize > 0) { | |
for (j = 0; j < bsize; j++) { | |
data += (b[*i+1+j] << (8*j)); | |
} | |
} | |
*btype = (b[*i] >> 2) & 0x03; | |
*btag = b[*i] & ~0x03; /* 2 LSB bits encode length */ | |
*i += 1 + bsize; | |
return data; | |
} | |
#define TYPE_GLOBAL 1 | |
#define TYPE_LOCAL 2 | |
#define TAG_USAGE_PAGE 0x04 | |
#define TAG_USAGE 0x08 | |
static void dump_report_desc(unsigned char *b, int l) | |
{ | |
unsigned int btype, btag, data; | |
int i, fido=0; | |
for (i = 0; i < l; ) { | |
data = report_desc(b, &i, &btype, &btag); | |
if (btype == TYPE_LOCAL && btag == TAG_USAGE && data == 1 && fido) { | |
printf("ID_SECURITY_TOKEN=1\n"); | |
break; | |
} | |
fido=0; | |
if (btype == TYPE_GLOBAL && btag == TAG_USAGE_PAGE && data == 0xf1d0) { | |
fido=1; | |
} | |
} | |
} | |
int main(int argc, char **argv) | |
{ | |
int fd; | |
int res, desc_size = 0; | |
struct hidraw_report_descriptor rpt_desc; | |
if (argc != 2) { | |
printf("Usage: %s <hidraw device>\n",argv[0]); | |
return 1; | |
} | |
/* Open the Device with non-blocking reads. */ | |
fd = open(argv[1], O_RDONLY|O_NONBLOCK); | |
if (fd < 0) { | |
perror("Unable to open device"); | |
return 1; | |
} | |
memset(&rpt_desc, 0x0, sizeof(rpt_desc)); | |
/* Get Report Descriptor Size */ | |
res = ioctl(fd, HIDIOCGRDESCSIZE, &desc_size); | |
if (res < 0) | |
perror("HIDIOCGRDESCSIZE"); | |
/* Get Report Descriptor */ | |
rpt_desc.size = desc_size; | |
res = ioctl(fd, HIDIOCGRDESC, &rpt_desc); | |
if (res < 0) { | |
perror("HIDIOCGRDESC"); | |
} else { | |
dump_report_desc(rpt_desc.value, rpt_desc.size); | |
} | |
close(fd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This program should universally support Fido u2f devices by reading the USB report usage pages and looking for the code 0xF1D0 and the usage of 0x01. If it is set, the program will print the variable ID_SECURITY_TOKEN=1 which udev will check for.
Compile
gcc -Wall -o u2f-detect u2f-detect.c
Copy u2f-detect to /lib/udev
Edit /lib/udev/rules.d/70-u2f.rules and add this line
The existing 70-uaccess.rules will grant file access to local user to devices with the ID_SECURITY_TOKEN environment variable set. This has been tested on Ubuntu..