Compile libpam-google-authenticator on Debian Linux

Introduction

The Google Authenticator project includes implementations of one-time passcode generators for several mobile platforms, as well as a pluggable authentication module (PAM). One-time passcodes are generated using open standards developed by the Initiative for Open Authentication (OATH) (which is unrelated to OAuth).

These implementations support the HMAC-Based One-time Password (HOTP) algorithm specified in RFC 4226 and the Time-based One-time Password (TOTP) algorithm specified in RFC 6238.

Some notes from the author:
When you talk to people about “Google-Authenticator” and that you can use it on a smartphone as Software Token they think the word “Google” stands for “Have to be always online”. This is not the case. Software- and Hardware One-Time-Passwords (OTP) usually work offline. Also the server side DOES NOT NEED TO BE ONLINE to authenticate users.

Google-Authenticator on the server side can use 16 digit base 32 (RFC 4648) encoded seeds. It turned out, that you can use 32 digit base 32 (RFC 4648) encoded seeds, too.

Compatible (and tested) Apps and hardware token on the client-side

Google Authenticator for Android, iOS and Blackberry

Gooze c100 event based hardware token

OATH Token iOS App

Install preriquisites

This document is based on:

Distributor ID: Debian
Description:    Debian GNU/Linux 6.0.5 (squeeze)
Release:        6.0.5
Codename:       squeeze

Depending on your system you need some packages on your machine before we begin. Since I wrote this documentation after I installed everything, it might be possible that I missed a dependency. If so, find out what is missing and install it. As far as I can remember I did:

apt-get install checkinstall git libqrencode-dev libqrencode3 libpam0g-dev

Get the source

Make sure you can connect to the internet from your box, then create a folder on your hard drive and get the source via a Mercury Repository. I did this with the following commands

cd
mkdir compile
cd compile
git clone https://code.google.com/p/google-authenticator/

The command should result in the following output (or similar):

Cloning into google-authenticator...
remote: Counting objects: 1038, done.
remote: Finding sources: 100% (1038/1038), done.
remote: Total 1038 (delta 499)
Receiving objects: 100% (1038/1038), 2.27 MiB | 702 KiB/s, done.
Resolving deltas: 100% (499/499), done.

Modification for 64bit

If you use a 64bit installation and you get this error, you have to change the Makefile a little bit to get it working since it searches for libdl.so in the wrong location.

First of all get the location of libdl.so on your machine with the following command:

find /usr/lib -name libdl.so

This results (on my system) in:

/usr/lib/i386-linux-gnu/libdl.so

Now you have to change all instances of

/usr/lib/libdl.so

to

/usr/lib/i386-linux-gnu/libdl.so  (change this to fit your system)

in

~/compile/google-authenticator/libpam/Makefile

On the latest Ubuntu 64bit systems you can use a variable to point to the correct location. Just use this sed command to do this:

cd
cd ~/compile/google-authenticator/libpam
sed -i "s@\(usr\/lib\/\\)\(libdl\.so\)@\1$(dpkg-architecture -qDEB_HOST_MULTIARCH)\/\2@g" Makefile

Modification of the login prompt

The original Login Prompt e.g. when using the Google Authenticator for SSH Logins is “Verification code: ”. If you want to change it, edit the following line in “pam_google_authenticator.c”

                                   .msg       = "Verification code: " };

and change it to whatever message you want to see, eg.:

                                   .msg       = "Google Authenticator Code: " };

Password prefixes

If you want to have a prefix before your password that users have to enter and that is checked before, change the following lines in pam_google_authenticator.c before compiling.

pam_google_authenticator.c

...
          // If forwarding the password to the next stacked PAM module,
          // we cannot tell the difference between an eight digit scratch
          // code or a two digit password immediately followed by a six
          // digit verification code. We have to loop and try both
          // options.
          saved_pw = request_pass(pamh, params.echocode,
                                  params.forward_pass ?
                                  "Password & verification code: " :
                                  "Verification code: ");
        }
        if (saved_pw) {
          pw = strdup(saved_pw);
        }
      }
      break;
    }
    if (!pw) {
      continue;
    }  
   //LINE 1413
   // remove the prefix (0815) from the password                                      //XXX
   // thanks to Eike, Bernhard and Hubert for helping me out                          //XXX
   if (strncmp(pw, "0815",4)==0) {                                                    //XXX
      strcpy(pw,pw+4);                                                                //XXX
   //        log_message(LOG_ERR, pamh, "removed prefix mode[%d] pw[%s]", mode, pw);  //XXX
   } else {                                                                           //XXX
     for (int ix=0; ix<strlen(pw); ix++) {                                            //XXX
        pw [ix]='x';                   //invalidate password if prefix does not match //XXX
     }                                                                                //XXX
   }                                                                                  //XXX
     // LINE 1414 We are often dealing with a combined password and verification
    // code. Separate them now.

    int pw_len = strlen(pw);
    int expected_len = mode & 1 ? 8 : 6;
...

Use this patch at your own risk! - It should work, but I am not a C-Developer! You could replace “0815” with what ever 4digit prefix you like.

Compile the source and create a debian package

A lot of tutorials will tell you how to make and install the code, but since we have aDebian system here, we like to create a Debian package. Here is how to achieve this.

                      
cd
cd compile/google-authenticator/libpam
make
checkinstall -y --maintainer=your@email.domain --pkgname=libpam-google-authenticator --pkgversion=1.0 --provides=libpam-google-authenticator --install=no -D make install

The result should be a .deb package. You can use this package for installation.

Install the package

dpkg -i libpam-google-authenticator_1.0-1_i386.deb   (the name can be different on your system)

Create a test token

Login as usual to your Linux box with your user account. Then start the following program:

google-authenticator -t

After completing the wizard your useraccount has now a file ~/.google_authenticator with a content looking like this:

6FCLSS7AAFKGLL43
" RATE_LIMIT 3 30
" WINDOW_SIZE 17
" DISALLOW_REUSE
" TOTP_AUTH
63140411
14951493
70660349
73155517
32312336

So if you configure your machine to use google authenticator, this file will be read for this specific user account.

Information about the google-authenticator token files

Since I could not find everything in the documentation I made a lot of experiments. Here is some information concerning the tokenfile format.

TOTP-Token (time-based)

BHB4KCBRJUA5WORJ
"RATE_LIMIT 3 30
" WINDOW_SIZE 10
" DISALLOW_REUSE
" TOTP_AUTH


LINE1
The first line contains the token secret. For Google-Authenticator this is usually a 16digit base32 string but can also have 32digits (base32).
Lines starting with " containg information about the token
"RATE_LIMIT 3 30 =  Limit logins to 3 per every 30 seconds
" WINDOW SIZE 10 =  One of the next 10 passwords (calculated with the server time) will work  
" DISALLOW_REUSE =  Do not allow reuse of previously used passwords.
" TOTP_AUTH      =  This is a time-based-token (totp)
HOTP-Token (event-based)

FP5BRZ34KK7XNXUE
" WINDOW_SIZE 17
" HOTP_COUNTER 91

The first line contains the token secret. For Google-Authenticator this is usually a 16digit base32 string but can also have 32digits (base32).
Lines starting with " containg information about the token
" WINDOW SIZE 17    =  One of the next 17 passwords (calculated with the server time) will work  
" HOTP_COUNTER 91   =  This is a event-based token (hotp). The next password is the 91st.

Interesting Info about the HOTP_COUNTER.
The HOTP_COUNTER increases by 1 if you login with correct OR incorrect credentials. So if the counter is at 91 and you enter 3x a wrong password, the counter is at 94. If you want to login, you have to make sure, that you use a password with a counter higher than 94 but lower than 91 + WINDOW_SIZE.
Because of this, I would not recommend hardware event-based tokens here. If you carry them arround and mistakely press the button to often and run out of the WINDOW_SIZE you have to manually resync the token (edit the file).

Security Hint

I would prefer using counter-based codes instead of time-based codes when using Software-Tokens. With counter-based codes you can reduce the possibility to duplicate the account on multiple devices, since it has “some kind” of protection against cloning due to the increasing of the counter on every good or bad login.

Also take a look at this entry http://code.google.com/p/google-authenticator/issues/detail?id=170.

public/linux/otp/setup_google-authenticator.txt · Last modified: 2015/08/11 08:20 (external edit)
CC Attribution-Share Alike 3.0 Unported
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0