First, let's answer some questions which are often asked.
What does OTPasswd protect you from?
By adding a second factor of authentication OTPasswd secures you from passive and active keylogging. By passive I mean that a keylogger computer stores keypresses in a file which is later reviewed by attacker who seeks for passwords. Even if he finds your static unix password he won't be able to login without one-time passwords.
By active keylogging I understand a program (or human) which listens for the password/passcode as you are entering them. Then after he knows credentials he might use them before you, or hold you back from using them so he can do it later. Each time you're presented with passcode prompt the passcode is already reserved for your explicit use.
What OTPasswd does not protect you from?
Certainly man-in-the-middle attacks and hacked SSH clients. If somebody manages to make you run a prepared ssh client which after authentication will handle your session over to somebody else you can't do anything to protect yourself. To be perfectly secure use your own SSH executables and verify server key fingerprint. When using passcards it's nice to note key fingerprint on the back of the passcard.
After creating my key I have to pass OTP authentication on every login even when I log from a trusted machine!
If you have a trusted machine from which you often log into your remote system use ssh keys. Generate them with ssh-keygen, and copy your new ~/.ssh/id_rsa.pub into ~/.ssh/authorized_keys on remote computer. When SSH authenticates user with keys it omits PAM.
Can I use the same OTP state on multiple machines? (a cluster?)
MySQL and LDAP backends are in plans (I welcome any help on this topic). I even already have an OID from IANA for LDAP: 188.8.131.52.4.1.36601. Still if you want a solution now, there's still hope.
You'd need to set DB=global, on one central server export /etc/otpasswd directory over NFS and make sure that 'otpasswd' user on all stations has the same UID. NFS takes care of locking which is done with a file /etc/otpasswd/otshadow.lck so this just seems to work (I've actually tested it briefly and, well, it worked).
Few problems, same answer:
My authentication times out before OOB channel delivers passcode! I don't want to use OOB so when the attacker learns my static password he can easily use up all of my printed passcodes!
There was once idea that failed auth attempts should not increment user counter. This has some really nasty security problems and was removed early. Instead There's a simple idea (not yet implemented) of authentication using two one-time passcodes (A and B) which will fix this two problems.
Failure to enter the A passcode won't use it up. Attacker might even try to guess it since he has infinite number of trials. But when it is entered correctly system asks about the B passcode and this one is reserved for this auth session only, and will be used up after fail.
If the attacker intercepts the A code and enters it before the user, user won't be asked to enter B passcode.
What is the OTPasswd license?
OTPasswd is currently licensed under the GNU General Public License version 3 or any later version. If there were any practical reasons for dual-licensing the code under BSD license (like including it natively in FreeBSD or similar) I can think about it.
- On DB=user if you create state as root using -u option users won't be able to read their state. (Fixed in repository, in >=0.7rc2)
- Versions prior to 0.7 have bug in the static password handling which will increase possibility of breaking the password.
- See ChangeLog for more information.
Why OTPasswd has to be SUID-root?
It doesn't unless you want to store user state in global database in /etc. You can use storage in users' homes and no SUID is required, but you won't be able to enforce any policy on users. To store data inside /etc we must have elevated privileges.
But why SUID-root, can't it be just SGID to some other user (otpasswd)?
I started development with SGID-otpasswd approach but had to give it up. User has some control over SGID binaries and can send them SIGSTOP signal which could enable user to stop otpasswd while it held a lock on global DB and DoS authentication. AFAIR at least.
Why not SUID-otpasswd then?
In this scenario binary is owned by the user 'otpasswd'. If anybody manages to break it he could possibly place arbitraly code inside this binary and wait for administrator to run it with root privileges.
Since we are SUID-root binary and config file is owned by root, and after reading it we can drop our privileges to otpasswd user so any teoretical attacker will only be able to alter state database. He will be able also to delete config file, but not to modify it.
Why does it have to be /etc/otpasswd and not simply /etc or /etc/security?
It's because of lock files. OTPasswd agent must be able to create lock file in a secure location so it must have ownership of the directory. There are many problems with keeping temporary files in /tmp so I've given this idea up.
Why is there an agent and utility and not simply a SUID utility?
- User musn't be able to stop execution of OTPasswd after it had locked DB. It could render whole system inaccessible to other users. It's difficult to achieve with monolitic approach because user can alter stdout, stdin files etc. Securing this problems usually made OTPasswd less usable for user, he couldn't redirect it's output to file or couldn't kill it with Control-C.
- Less "difficult" code is executed as privileged. OTPasswd agent doesn't have to parse user input, translate it's messages with gettext, generate passcards etc.
- It's kind of practical. Code is prepared for implementation of GUI which will interact with agent. Most of the "common" code was moved into the agent already.
When using DB=user no otpasswd code is run with root privileges?
No. SSH during authentication calls PAM as uid 0 so PAM module always runs with root privileges. Still it's interface is much simpler and therefore it's much harder to find some attack vectors. It's crucial to parse user-editable state file in a secure way though.