So, I have this el-cheapo RFID scanner and some RFID tags.

I thought to myself, You know what would be neat? Enabling and disabling the lock screen with this thing.

So the package arrived and I tore it apart and hooked it up.

This device emulates a USB keyboard (that explains the driver-less thing they were pushing) and essentially types out the card ID and hits enter.

I thought I could just open a constant stream from /dev/stdin (a la keylogger) and watch for when the card I want was punched in. Thats what lead me to creating this stupid simple script:


cat /dev/stdin | while read line  
  if [ "$line" == "0000996716" ]  
     then echo "Correct!"  

Which worked!

I then changed the THEN statement to the gnome-screensaver unlock command, gnome-screensaver-command -d.

And locked my screen manually (Ctrl-Alt-L) Swiped my card aaand.... nothing. The scanner had just typed the card # in the password field and hit enter, resulting in a 'password incorrect' to show up on the lock screen.

So I unlocked my screen via the password and noticed there was nothing on the terminal screen.

So I opened a direct pipe to /dev/stdin and locked my screen. Unlocked it with my password and... nothing again.

Why isn't this doing what I expect? Does /dev/stdin not contain information that is being typed during the lock screen? If not, what does?

  • Thinking out loud here, but since this emulated a USB keyboard, would it be possible to have 2 passwords attached to my user account? The script (posted above, slightly modified) can lock the scree, while the secondary password is set to the card id, allowing it to unlock the screen? I just have have my primary password be set to a bunch of numbers haha – user2183032 Jun 2 '13 at 4:06
  • Using two passwords is never a good idea, because it lowers security instead of improving it. Numeric passwords aren't good too, those can be broken very fast. – gronostaj Jun 2 '13 at 6:22
  • Is there some file in /dev where I can read the input from? /dev/input/event* gives me garbage. – user2183032 Jun 2 '13 at 7:01

Well you guys suck :P It was kinda specific and niche but I wont hold it against you ;)

Anywho, for the full run down.

I had bought this neat little unit which describes itself as 'driverless' like in the original post. This means it acts like a USB keyboard (and registeres itself as such in /dev/input/event*). This made it almost useless to me as I couldn’t interact with the device any way when the lock screen was active, I needed to read the keystrokes from the device as they were being 'input' by the reader Cat-ing /dev/input/event3 (my reader) gave me garbage, or so I though.

Then I ran into this piece of code here: http://itech-planet.net/content/reading-device-input-directly-fromto-devinputeventx-ubuntu-c with no? author that I can see, but most of the credit for the legwork in this application goes to him/her. Thanks! Simplifying this code I was able to read the raw input from my own keyboard, with the secret phrase being 'secret' and proceeded to capture the keystrokes into a variable and look for when 'enter' was hit to check the string against the stored value for the code.

This code is essentially a glorified keylogger pointing to a different 'keyboard' and scanning what it 'types' to a matching phrase. Much like how the FBI sifts though millions of AOL IM's from a 13-yo girl looking for terrorists!

When it hits the matching phrase, it triggers the if statement and runs the rest of the corresponding code. I've commented it the best I can, if you have any issues, email/pm/im/yell loudly at me.

Not like you read any of that, you just want the code! Well, here it is!


sudo ./[file] -u [your username] -d [location to device] -t [tag id]

So I, being Tyler, with my device at /dev/input/event3 and my tag being 0000996716 would have:

sudo ./input -u tyler -d /dev/input/event3 -t 0000996716


#include <linux/input.h>  
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int getStatus(){
  FILE *fp;
  char path[128];
  fp = popen("sudo -u tyler gnome-screensaver-command -q", "r");

  fgets(path, sizeof(path)-1, fp);
  if(strcmp("The screensaver is inactive\n",path)==0) 
    return 1;//if screensaver is disabled
  else if(strcmp("The screensaver is active\n",path)==0) 
    return 0;//if screensaver is enabled
    return -1;//wat

int main(int argc, char **argv)
//char array that stores the keys in order up to like 40 something, DO NOT MESS WITH THE ORDER OF THIS ARRAY. ITS IMPORTANT.
    char arr[]={' ',' ','1','2','3','4','5','6','7','8','9','0','-','=','\b','\t','q','w','e','r','t','y','u','i','o','p','[',']','\n',' ','a','s','d','f','g','h','j','k','l',';',',','`',' ','\\','z','x','c','v','b','n','m',',','.','/',' ','*',' ',' '};
    char inp[256];//input string to check what you type.
    int fd;//file pointer to the /dev/input device
char usr[32];//stores your username to run screensaver command as you. Root user (sudo) can NOT lock the screen.
char tag[32];//stores the tag ID for the RFID
char dev[32];//stores the device location, /dev/input/eventX
char lcom[96];//locking command builder string
char ucom[96];//unlocking command builder string
//processes arguments, dont ask.
   int idx = 0;
   for (idx = 1; idx < argc;  idx++) {
       if (strcmp(argv[idx], "-u") == 0) {
          printf("User = %s\n", usr);
       } else if (strcmp(argv[idx], "-t") == 0) {
          printf("Tag = %s\n", tag);
       } else if (strcmp(argv[idx], "-d") == 0) {
          printf("Device = %s\n", dev);
      fd = open(dev, O_RDONLY);
       } else {}
    //build commands
    strcpy(lcom,"sudo -u ");
    strcat(lcom," gnome-screensaver-command -l");
    strcpy(ucom,"sudo -u ");
    strcat(ucom," gnome-screensaver-command -d");
    struct input_event ev;
    int cursor=0;
    while (1)
        read(fd, &ev, sizeof(struct input_event));
        if(ev.type == 1)//only key ID event
            if(ev.value == 0)//only not repeat
        if(ev.code== 28||ev.code==14){//if code is enter or bsp, reset the counter and compare
            inp[cursor]='\0';//terminate string
            if(strcmp(inp,tag)==0){//if input string equals tag, strcmp works funny lol
                int status=getStatus();//find out what the screensaver is doing
                if(status==1){//screensaver is unlocked, so lock it
                else if(status==0){//screensaver is locked, so unlock it!
                else printf("Wat happened");//???
            else{//if not enter or bsp, log it      
    //fflush(stdout);this was here for debug purposes, since apparently I dont know how STDOUT works lol

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.