Summary |
Admin |
Home Page |
Forums |
Tracker |
Bugs |
Support |
Patches |
RFE |
Lists |
Tasks |
Docs |
News |
CVS |
Files |
Contents
Overview
JPAM is a Java-PAM bridge. PAM, or Pluggable Authentication
Modules, is a standard security architecture used on Unix, Linux and
Mac OS X systems.
JPAM permits the use of PAM authentication facilities by Java
applications running on those platforms.
These facilities include:
- account
- auth
- password
- session
Jpam is a Java-PAM bridge.
JPAM has its own proprietary API via the PAM class but also supports
JAAS.
PAM
PAM, or Pluggable Authentication Modules, is the standard security
architecture used
on Unix, Linux and Mac OS X systems.
JPAM permits the use of PAM authentication services to Java
applications running on those platforms.
PAM was created in 1996 by Sun Microsystems. For more on PAM see the
following resources:
PAM is available on all Unix systems, from Solaris to Linux to Mac OS X.
Jpam provides the integration with PAM. Any Java application that
needs to do authentication can potentially use jpam.
Commonly Java application authenticate using one of the following
approaches and APIs:
- Database username and password tables; JDBC
- LDAP, such as Novell NDS, open LDAP or Active Directory; JNDI
However, there are many more approaches than these two. There are
hundreds of authentication systems accessible through PAM. See a list
for Linux
here.
Many of these are installed by default in the Linux distributions.
Fedora Core 3 has 54 PAM modules in its /lib/security directory ready
for use. Some notable examples of PAM modules are:
Name
|
Module
|
Use
|
SecurId
|
pam_securid.so
|
Authenticates SecurId hardware
tokens with the RSAACE Server. Available from RSA as a free
download. These have been tested with JPAM
|
Unix
|
pam_unix_*.so |
Authenticates using configured
Unix scheme. This can be shadow passwords or NIS, depending on how the
machine was configured. Tested with JPAM.
|
RADIUS
|
pam_radius.so |
Authenticates using RADIUS
servers. Tested with JPAM.
|
CryptoCard
|
pam_smxs.so
|
Authenticates using CryptoCard
RB1 hardware tokens and similar
|
Samba
|
pam_winbind.so
|
Authenticates using Windows and
Samba servers.
|
Kerberos
|
pam_krb5.so
|
Authenticates with
Kerberos/Active Directory
|
LDAP
|
pam_ldap.so
|
Authenticates with LDAP servers
(from Java you could also use the JNDI API)
|
SafeWord
|
pam_safeword.so
|
Authenticates SafeWord tokens
|
DigiPass
|
pam_radius.so
|
DigiPass uses the Free Radius
PAM module to authenticate DigiPass hardware tokens. DigiPass is from
Vasco. These have been tested with JPAM.
|
Requirements
Jpam supports:
- JDK 1.4 and 1.5.
- JDK 1.3 with the JAAS 1.0
library.
- JDK 1.2. JAAS is not available for JDK1.2 but JPAM can be used
directly rather than through the JAAS implementation.
Dependencies
Apache Commons
Logging is required for logging. This tool supports all of the
common logging frameworks.
Operating Systems
& Architectures
Operating Systems
JPAM supports:
- RedHat 9
- Fedora Core 1, 2 and 3
- Generic Linux
- Mac OS X
In addition, JPAM can be easily ported to any Unix-like operating
system.
Windows does not use the PAM security concept hence Jpam is not
applicable to Windows.
Architectures
Binary distributions are available for:
- i386
- amd64
- ppc (Mac OS X)
A source distribution is available which with the addition of an Ant
property file for an architecture will build for that distribution.
JPAM is portable to any architecture for which both Java and PAM are
available.
JavaDoc
JavaDoc is distributed with all binary and source distributions.
It is also available online
here.
Configuration
The distribution contains an example pam.d configuration file
called net-sf-jpam.
To configure jpam, edit net-sf-jpam and copy it to /etc/pam.d. Follow
the instructions in that
file for the PAM module you configure.
See http://jpam.sourceforge.net/documentation/#configuration for more
information.
Limitations
Currently JPAM provides basic authentication services such as:
- Does the user exist?
- Are they allowed to log in?
- Are their credentials correct?
Jpam does not support advanced PAM conversations such as:
- change password on first login
- change password after password expired
However with the features already supported, JPAM is ready for many
Java applications.
JAAS
Jpam comes with a
JAAS
implementation.
JAAS stands for Java Authentication And Authorization Service. It
is a Java analogue to PAM. PAM was also invented by Sun Microsystems.
JAAS comes with some sample binary authentication modules. It has been
left to vendors to provide specific implementations. JPAM fills a gap
in the market by making the 70 plus PAM modules already available on
Linux accessible to JAAS.
JPAM's implementation of JAAS's LoginModule is
JpamLoginModule.
JPAM may also be used directly, circumventing JAAS, via its PAM class.
Configuring JAAS
JAAS uses login configuration files.
The JRE's java.security file specifies the default login configuration
file as follows:
# Default login configuration file# login.config.url.1=file:${user.home}/.java.login.config
|
To use JpamLoginModule with this defaul setting copy the supplied
.java.login.config file to
your home directory.
Its contents are reproduced below:
net-sf-jpam {
net.sf.jpam.jaas.JpamLoginModule required;
};
|
Sample Code
JPAM includes a number of tests to verify that the JpamLoginModule is
functioning correctly. See the full test
here.
The sample shown below shows how to:
- Create a new JAAS LoginContext and login.
- How to implement the required CallBackHandler for communication
with the JpamLoginModule.
/**
* Checks that we can login.
* <p/>
* In this test, login is successful and commit
is called.
* @throws LoginException
*/
public void testLoginContext() throws LoginException
{
LoginContext loginContext;
loginContext = new
LoginContext("net-sf-jpam", new JpamCallbackHandler());
loginContext.login();
}
/**
* The application must implement the
CallbackHandler.
* <p/>
* <p> This application is
text-based. Therefore it displays information
* to the user using the OutputStreams
System.out and System.err,
* and gathers input from the user using the
InputStream, System.in.
*/
class JpamCallbackHandler implements CallbackHandler
{
/**
* Invoke an array of
Callbacks.
* <p/>
* <p/>
*
* @param callbacks an
array of <code>Callback</code> objects which contain
*
the information requested by an underlying security
*
service to be retrieved or displayed.
* @throws
java.io.IOException
if an input or output error occurs. <p>
* @throws
UnsupportedCallbackException if the implementation of this
*
method does not support one or more of the Callbacks
*
specified in the <code>callbacks</code> parameter.
*/
public void
handle(Callback[] callbacks)
throws IOException, UnsupportedCallbackException {
for
(int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof TextOutputCallback) {
// display the message according to the specified type
TextOutputCallback toc = (TextOutputCallback) callbacks[i];
switch (toc.getMessageType()) {
case TextOutputCallback.INFORMATION:
System.out.println(toc.getMessage());
break;
case TextOutputCallback.ERROR:
System.out.println("ERROR: " + toc.getMessage());
break;
case TextOutputCallback.WARNING:
System.out.println("WARNING: " + toc.getMessage());
break;
default:
throw new IOException("Unsupported message type: "
+ toc.getMessageType());
}
} else if (callbacks[i] instanceof NameCallback) {
// prompt the user for a username
NameCallback nc = (NameCallback) callbacks[i];
nc.setName(user1Name);
} else if (callbacks[i] instanceof PasswordCallback) {
// prompt the user for sensitive information
PasswordCallback pc = (PasswordCallback) callbacks[i];
pc.setPassword(callbackCredentials.toCharArray());
} else {
throw new UnsupportedCallbackException
(callbacks[i], "Unrecognized Callback");
}
}
}
}
|
Extending JPAM
There are two main ways JPAM can be extended:
- Porting to new architectures
- Adding in PAM modules
Porting to New
Architectures
JPAM uses native C code to communicate with PAM. The C code is compiled
into a shared library. These are architecture dependent. To port to a
new architecture:
- Add an ANT properties file for the architecture
- Add a new target to the src/c/makefile.
For most Unix-based systems that should be it.
Adding new PAM modules
Though not included in the binary distributions, SecurId and Radius
have both been tested.
Debugging
JPAM consists of Java code, native code accessed through JNI and then
PAM. When extending JPAM, it will be useful to turn on logging across
all of these tiers.
Java and Native Code
Logging
If the DEBUG logging level is enabled, jpam will show logging from
Java. Because JPAM uses commons-logging, setting logging to DEBUG
depends on your logging toolkit. For JDK1.4 logging, set your
logging.properties to
fine
.
If DEBUG is set, libjpam.so will
also log messages. As native code it does not use Java logging. It will
log its messages to <stdout>.
PAM Logging
It is also useful to get PAM to log what it is doing.
To enable syslogd for PAM logging, add "auth.notice" to the
/var/log/messages line in /etc/syslog.conf.
e.g.
*.info;mail.none;authpriv.none;cron.none;auth.notice
/var/log/messages |
