Caps-Lock, security and PAM (Pluggable Authentication Module)

When logging into my desktop system (running Ubuntu), every once in a while the Caps-Lock key accidentally being pressed keeps me from successfully logging in to my system. While being just a minor and rare annoyance, its stuck in the back of my mind and I started wondering if something could and should be done about it.
I started wondering, what if I would make the log-in password caps-lock insensitive on my system. The first thing we need to understand is that caps-lock insensitive isn’t the same as case insensitive. If my password is ‘TomtiDom14′, a caps-lock insensitive password chack should match only ‘TomtiDom14′ and ‘tOMTIdOM14′. So unlike case-insensitive where there would be 256 different valid passwords, seriously degrading security for you password by dropping a single bit of entropy for each dual case character in your password, a caps-lock insensitive password takes away only a single bit of entropy for the whole password. While loosing a single bit of entropy in theory cuts the amount of time or resources needed to brute-force crack your password in half, this is not really that relevant if we take the approach that caps-lock insensitivity is an authentication system issue. We are thus not talking about making our password hash caps-lock insensitive, what would indeed be a bad idea that cuts brute-force time in half if someone were to get his/her hands on the hash of your password. We are talking about an authentication system that should simply , in failure, try the case-inverted version of the presented password. Authentication systems have excellent measures for rate-limiting or even blocking brute-force attacks, so a single bit of entropy should not be that much of a problem for our approach.

Looking at the usability increase however, we can see what happens when someone by accident has his caps-lock key pressed and tries to enter a password. Chances are that he/she won’t think about checking the caps-lock led. No, the first thing he/she will think would be making a type. So the password will be typed in caps-inverted one or more consecutive times. Then he/she will start to wonder if he/she didn’t have the password mixed up with an other password. He/she will than try that password, maybe two or 3 times, than maybe a third one. In the end, the user might have entered a number of false passwords sufficient to trigger a complete lock-out. So while making our authentication caps-lock insensitive slightly decreases the security of the password, and while accidentally having the caps-lock pressed tends to be a rare condition, the usability consequences of not having a caps-lock insensitive authentication systems end up being rather big.

So now that we have established that having a caps-lock insensitive authentication system for our passwords is a quite desirable goal, we need to look at how we can establish such a system.

On (Ubuntu) Linux, the authentication system is a modular system that uses so called Plugable Authentication Modules (PAM). There are many authentication modules available, and looking at the source code of the PAM system there appeared no central place to elegantly solve the problem in a simple way. I thus chose to fix the problem for myself by looking just at stand-alone systems using the basic pam_unix module. Fixing the problem for other modules can probably be done in a similar way. Although solving the problem in individual modules may not be the most elegant solution, it does show that its almost trivial to do so in a somewhat less elegant way.

Before we can change the way the pam_unix PAM module validates passwords, we need to get our hands on the sources of the PAM system. On my Ubuntu system I hag to use the following command to get the source.

bzr branch https://code.launchpad.net/~ubuntu-core-dev/pam/ubuntu

cd ubuntu

./configure

I had to add a -lfl flag to the LIBS definition in a few Makefile files to make the code-base build on my system. Now for the almost trivial fix. After that I could build the source tree:

cd modules pam_unix

make clean

Now for the patch to pam_unix. The file ‘support.c’ defines a function named ‘_unix_verify_password’  that seems like the perfect place for our patch.

A few pages down in this function we see an invocation of the function ‘verify_pwd_hash’. This function validates the password as it was originally typed against a password hash stored in the system. By adding a litle piece of code after this invocation, we can add a second invocation of the same function with a caps inverted version of our password.  The additional code looks as follows:


/* If the first check fails, lets try with inverted case. */
if (retval != PAM_SUCCESS) {
/*Allocate a string for the case inverted password.*/
char * capsinvertedpass= (char *) calloc(strlen(p)+1,0);
if (capsinvertedpass==0) {
pam_syslog(pamh, LOG_CRIT, "no memory for caps inverted password.");
} else {
size_t ip_index=0;
size_t ip_len=strlen(p);
/* Case invert every character */
for (ip_index=0;ip_index<ip_len;ip_index++) {
char ip_c=p[ip_index];
char ip_c2=ip_c;
/* Lowercase all upcase characters */
if ((!(ip_c < 'A')) && (!(ip_c > 'Z'))) {
ip_c2 = ip_c - 'A' + 'a'; /*uppercase to lower*/
} else {
/* Uppercase all lowercase characters */
if ( (!(ip_c < 'a')) && (!(ip_c > 'z'))) {
ip_c2 = ip_c - 'a' + 'A'; /*lower case to upper*/
}
}
/* Put the updated character value in the new password string.
capsinvertedpass[ip_index]=ip_c2;
}
/* Try again once more with the caps inverted passord*/
retval = verify_pwd_hash(capsinvertedpass, salt, off(UNIX__NONULL, ctrl));
free(capsinvertedpass);
}
}

Now we build the code again and move our updated module to the proper library.

make

sudo mv /lib/x86_64-linux-gnu/security/pam_unix.so /lib/x86_64-linux-gnu/security/pam_unix.so.original

sudo mv .libs/pam_unix.so /lib/x86_64-linux-gnu/security/pam_unix.so

sudo chown root:root /lib/x86_64-linux-gnu/security/pam_unix.so

sudo chmod 644  /lib/x86_64-linux-gnu/security/pam_unix.so

Now just to make sure everything is still working ok, we call login:

sudo login

Everything worked fine, and its relatively simple to do. We can now log in with or withour the caps-lock active. Its a quite simple patch that should be almost as simple for other PAM modules. I hope the above description will help others achieve the same. I feel that although an accidental caps-lock is rare, its sufficiently annoying when it happens to want a patch like the one described above. There is a minor security implication, but IMO the usability benefits outweigh the effective loss of a single bit of entropy.

About these ads

One response to “Caps-Lock, security and PAM (Pluggable Authentication Module)

  1. Made some minor improvements so that helper unix_chkpwd works also and put the caps-lock tolerant pam_unix code on github:
    https://github.com/pibara/pam_unix

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s