Linux PAM module for Dallas Semiconductor's iButtons - v2.1alfa
Jose Rufino - rufino@ipb.pt, September 4th 1999

--------------------------------------------------------------------------------
  <Read this file carefully in order to properly operate with this software>
--------------------------------------------------------------------------------

INDEX

1- SCOPE & DISCLAIMER

2- HARDWARE & OS

3- INSTALLATION, CONFIGURATION & TESTING

4- HOW IT WORKS

4.1- /etc/pam.d/passwd and /etc/pam.d/login

4.2- autologin feature

4.3- pam_sm_authenticate

4.4- pam_sm_chauthtok

5- CREDITS

6- LICENSING

--------------------------------------------------------------------------------

1- SCOPE & DISCLAIMER:

This software (specifically pam_ibutton.c) implements a Linux PAM module
providing Authentication (auth) and Password (password) services for the
DS1993 Dallas Semiconductors iButton.

Currently only supports the "login" and "passwd" commands via properly
configuring /etc/pam.d/login and /etc/pam.d/passwd.  It may work with other
PAM-aware applications but it hasn't been tested to do so. You are on your own.

The package also offers an autologin feature: a patched version of mingetty
 - pam_ibutton_mingetty - allows for the use of an iButton to automatically
login at selected terminal lines (see more of this bellow).

Keep in mind that the security approach took by this module is primitive.
This module was developed mainly to test a few ideas. Please, don't ask too 
much from it.

--------------------------------------------------------------------------------

2- HARDWARE & OS:

These were the parts used to develop the module:
- DS9097U-009 Serial Port Adapter
- DS1402D-DR8 Blue Dot Receptor
- DS1993L-F50 4k Memory iButtons

They are necessary to work with the module.
You may order these parts directly from http://www.ibutton.com

The module should work also with the DS1992, DS1994 and DS1996 iButtons.
Other buttons and parts may work but are unsupported.

The module was developed under Linux RedHat 6.x.
It may not work on other platforms and/or Linux variants.

--------------------------------------------------------------------------------

3- INSTALLATION, CONFIGURATION & TESTING

[ Remember I am assuming a RedHat 6.x system PAM directory structure ]

Untar the package and do
# make
(ignore any warnings)

Then
# make install

This will automatically:
- link /dev/iButton to /dev/ttyS0; so please make sure you are using COM1
- backup the login and passwd original PAM files under /etc/pam.d
- replace the previous files with updated ones
- place the new module pam_ibutton.so in /lib/security 
- place a patched mingetty - pam_ibutton_mingetty - in /usr/sbin
  (further manual editing of /etc/inittab is still needed; see bellow)

Change /dev/iButton permissions accordingly if you want to allow others, 
than root, to play with the module.

To launch pam_ibutton_mingetty at boot time, having it associated with a
terminal line such as tty2, for instance, you must edit /etc/inittab and 
replace the line
2:2345:respawn:/sbin/mingetty tty2
with
2:2345:respawn:/usr/sbin/pam_ibutton_mingetty tty2
Then
#telinit q
so that init can re-examine the /etc/inittab file. After that, you can play
right away with the autologin feature without needing to reboot the system.

Assuming the configuration has been properly done, you can test the module.
Place one or two buttons in the blue dot receptor, invoke passwd (as root or
on the behalf of another user, or as the user himself), choose one button by
serial number (which you can look up at the bottom of the button), and the
necessary authentication information will be placed in the button.

After that, you can play with login or autologin. If you use login, you can
explicitly give "ibutton" as your logname. If you use autologin, select the
proper terminal (Alt + Ctrl + F2, for instance) and "ibutton" will be used
automatically as your logname. In both cases, you will have to select a button.
Depending on the authentication info kept there, you will be logged in as a
certain user.

Although the supported buttons all have different memory amounts, they have
at least one 32 byte page. In turn, this version of the module needs only 16
bytes which, by the way, are a MD5 hash (more of this later). Once this is
experimental software the 1st 16 bytes of the iButton memory will ALWAYS be
overwritten, regardless of their previous content.

--------------------------------------------------------------------------------

4- HOW IT WORKS:

--------------------------------------------------------------------------------

4.1- /etc/pam.d/passwd and /etc/pam.d/login

First, let's take a quick look at the updated /etc/pam.d files. You should
be already familiar with PAM if you want to fully understand their meaning.
I'll only provide a quick briefing about my own modifications.

The new /etc/pam.d/passwd is:

#%PAM-1.0
auth       required     /lib/security/pam_pwdb.so shadow nullok
account    required     /lib/security/pam_pwdb.so
password   required     /lib/security/pam_cracklib.so retry=3
password   required     /lib/security/pam_pwdb.so use_authtok nullok md5 shadow
password   required     /lib/security/pam_ibutton.so debug   

Notice the last line were we require the successful update of the iButton
when we try to update a password. If you find this behavior too restrictive,
just comment the line and everything will work as before.

The new /etc/pam.d/login is:

#%PAM-1.0
auth       required     /lib/security/pam_securetty.so
auth       sufficient   /lib/security/pam_ibutton.so debug
auth       required     /lib/security/pam_pwdb.so shadow nullok
auth       required     /lib/security/pam_nologin.so
account    required     /lib/security/pam_pwdb.so
password   required     /lib/security/pam_cracklib.so
password   required     /lib/security/pam_pwdb.so nullok use_authtok md5 shadow
session    required     /lib/security/pam_pwdb.so
session    optional     /lib/security/pam_console.so  

Notice the second line: there we intercept the username (given at the mingetty
login prompt or enforced to be "ibutton" by pam_ibutton_mingetty) to see if it
matches "ibutton" which means an iButton based authentication is being required.
If this is the case, the success of this iButton based authentication is 
considered "sufficient" as far as the other auth stacked modules are concerned.

A more in-depth description about the internals of the pam_ibutton.so module
is given in the section 4.??

--------------------------------------------------------------------------------

4.2- the autologin feature

Traditionally, logging into the system starts with mingetty taking control of a
terminal line. This involves setting up all the relevant terminal parameters,
asking for a logname an then execing the login program with that logname as a
parameter. Then, login asks for a password and if the password is right one is
finally given a shell and is logged on the system.

Instead, you can use a patched version of mingetty - pam_ibutton_mingetty -,
which sets up the terminal parameters and then execs login with the special
logname "ibutton", forcing an iButton based authentication to take place.

--------------------------------------------------------------------------------

4.3- pam_sm_authenticate:

Considering the previously shown configuration files (4.1), this function will
be invoked by "login" after the module pam_securetty has played his role; notice
that this happens just before pam_pwdb takes control; this is because we may
want to avoid pam_pwdb to ask the password for the user entered at the login
prompt; in fact, if the username is "ibutton" (a non-real user, but a kind of
virtual user) then pam_sm_authenticate is being asked to perform another kind
of authentication; with a user name different from "ibutton", the function
pam_sm_authenticate returns immediately and pam_pwdb will ask the password in
the usual way.

When performing the new authentication method, pam_sm_authenticate will probe
the 1-wire MicroLAN bus and will show the serial number of all the devices
found. The user will then select one device, by serial number. The device first
16 bytes are then read and the real authentication procedure takes place.

The authentication is successful if there is a match between these 16 bytes
and a hash produced by reading every /etc/shadow entry (while there isn't a
match) and applying MD5 to the triple <local IP address, ROM of the selected
iButton, current /etc/shadow entry>.

If we found a match, then we know the real user who is trying to log in: it is
the user from the matching /etc/shadow entry. We then set the PAM_USER item 
to this user and successfully return, giving control to the subsequent PAM
modules (not the auth ones anymore, because our success is sufficient to the
auth kind).

Otherwise, the module sets PAM_USER to "nobody" and returns an error.

This authentication scheme has some advantages:

- there is no need to keep any authentication information outside the iButton;
  no additional per user files / information is necessary ;

- a lost iButton is almost perfectly anonymous; the hash doesn't tell anything
  about the owner, once the MD5 kept in there is, by principle, irreversible;
  therefore, only the superuser of the system to which the button relates can
  identify the button's owner, by testing all entries from /etc/shadow; this
  would be pointless for the superuser, of course, because he doesn't need the
  button to access the system, nor the button can be used to access any other
  system (except for this notable exception: there is another system with the
  same IP address, probably forged, where, by coincidence, there is also a 
  matching /etc/shadow entry);

- it is enough for a user to change his password in order to prevent a lost
  iButoon to be used to access the system on his behalf: changing the password 
  will change the user's /etc/shadow entry, and so the MD5 hash kept on the
  iButton, which is based, among other things, on the old password, will be
  rendered useless;

- trying to forge another user's iButton is impossible, even for the superuser;
  the MD5 hash is also based on the iButton's serial number (ROM), which is
  factory lasered, and so can not be changed; 

- a login system solely based on this authentication system can prevent 
  unauthorized logins when a users password is guessed: without the iButton,
  no login is allowed, because no password is asked through the keyboard;

--------------------------------------------------------------------------------

4.4- pam_sm_chauthtok

Accordingly with the new /etc/pam.d/passwd (see above), the password services of
the pam_ibutton module will be invoked at the very end of the other modules.
This is because a password must respect a set of properties and this is assured
by the previous modules. So, when pam_ibutton takes control the pam_sm_chauthtok
function basically has to make up a new MD5 hash and save it in the iButton.

First, the 1-wire MicroLAN bus is probed and the devices serial numbers shown.
If nothing is found, though, pam_sm_chauthtok fails, by default, also preventing
/etc/shadow from being updated and so the user's password remains unchanged.
This can be avoided by commenting out the line

password   required     /lib/security/pam_ibutton.so debug   

at the file /etc/pam.d/passwd. If something is found, the user will then select
the device, by serial number. Now, it could be possible to check if the chosen
iButton really belongs to the user: the MD5 hash kept in there should match an
hash based on the user's /etc/shadow entry which is about to be modified. We
don't care, however. If the button belongs to another user, then it is "lost",
which, in practical terms, is the same as to be considered "empty".

Once the button is chosen, and /etc/shadow has been updated (which we know for
sure the 2nd time pam_sm_chauthtok is called - more about this on page 13 of
 "The Linux-PAM Module Writer's Guide" -), the new MD5 hash is written in the
button.

--------------------------------------------------------------------------------

5- CREDITS:

- Trevor Schroeder <tschroed@acm.org> for showing that this PAM-iButton stuff
  was a viable thing; in the end I came up with a different approach but 
  taking a look at his code did put me in the right direction and saved me a
  lot of time; you can pick up his module at
  http://www.zweknu.org/~tschroed/iButton-PAM

- Dallas Semiconductors who provides, for free, the MicroLAN library mlpb103,
  giving low level support for the iButton; the demo files (tst*.c) were also
  most useful in order to learn how to use the library (I left the reused code
  with the original // style comments); you can pick up the library from
  http://www.ibutton.com/software/softauth/utilities.html

--------------------------------------------------------------------------------

6- LICENSING:

GNU GPL (see the file COPYING)
