Contents

1 Preface
1.1 Audience
1.2 Book Format
1.3 Acknowledgements
2 Introduction
3 Java Requirements, Dependencies and Maven POM snippet
3.1 Java Requirements
3.2 Mandatory Java Dependencies
3.3 Operating System Dependencies
3.4 Maven pom.xml snippet
4 Getting Started
4.1 Supported Operating Systems and Architectures
4.2 Step-by-step Installation Instructions
5 Configuration
5.1 Format of pam.d files
5.2 Example 32 bit net-sf-jpam file
5.3 Example 64 bit net-sf-jpam file
5.4 Configuring Popular Security Services
5.5 Installing Additional PAM Modules
5.6 More information
6 Features
6.1 High Quality
6.1.1 High Test Coverage
6.1.2 Automated Load, Limit and Performance System Tests
6.1.3 Specific Concurrency Testing
6.1.4 Production tested
6.1.5 Fully documented
6.1.6 Conservative Commit policy
6.1.7 Full public information on the history of every bug
6.1.8 Responsiveness to serious bugs
6.2 Open Source Licensing
6.2.1 Apache 2.0 license
7 Code Samples
7.1 Using the JPAM API
7.2 Using the JAAS API
7.3 Browse the JUnit Tests
8 Logging And Debugging
8.1 Commons Logging
8.2 libjpam.so Debugging
8.3 syslogd logging
9 Frequently Asked Questions
9.1 Does JPam run on JDK1.2?
9.2 JPam does not have a configuration for my OS/architecture. What can I do?
10 Limitations
11 Building JPam from Source
11.1 Building from source
11.2 RPM packaging (Optional)
11.3 Building the Site
12 About the JPam name and logo
Index

1 PrefaceContents

1.1 AudienceContents

The intended audience for this book is developers who use JPam. It should be able to be used to start from scratch, get up and running quickly, and also be useful for the more complex options.

JPam is a missing piece in the Java - Unix security puzzle. Another natural audience is therefore security specialists.

It is also intended for application and enterprise architects. JPam creates new possibilities. It is not necessary to front Java Application servers with Apache in order to plug in native security. You are no longer limited by the availability of Java implementations of security services.

1.2 Book FormatContents

This content is suitable for use as an online PDF or printed. Blank pages have been deliberately left to give a good flow.

1.3 AcknowledgementsContents

JPam has had contributions in the form of forum discussions, feature requests, bug reports, patches and code commits.

Rather than try and list the many hundreds of people who have contributed to JPam in some way it is better to link to the web site where contributions are acknowledged in the following ways:

2 IntroductionContents

JPam is a Java-PAM bridge. PAM, or Pluggable Authentication Modules, is a standard security architecture used on Linux, Solaris, Mac OS X and other Unix systems. JPam is the missing link between the two.

JPAM permits the use of PAM authentication facilities by Java applications running on those platforms. These facilities include:

3 Java Requirements, Dependencies and Maven POM snippetContents

3.1 Java RequirementsContents

JPam supports 1.4, 1.5 and 1.6 at runtime. JPam final releases are compiled with -target 1.4. This produces Java class data, version 48.0.

JPam does not work with JDK1.2 or JDK1.1. JAAS is not available for these JDKs. Moreover, JNI used a different interface prior to JDK1.2.

IBM 1.4.2.0 JVM is known to work although it places its native libraries in a different place. Add -Dnative.java.library.path=/usr/lib/jvm/java-ibm/jre/bin (or wherever the IBM JVM is installed ) to your Java command line.

3.2 Mandatory Java DependenciesContents

JPam requires commons-logging commons-logging is a very common dependency, and is therefore not included in the distribution.

Jpam also requires JAAS. Originally introduced as an optional package (JAAS 1.0) to version 1.3 of the Java 2 SDK, JAAS has now been integrated into the Java 2 SDK, version 1.4.

3.3 Operating System DependenciesContents

It has been reported that JPam relies on the presence of pam-devel-0.77-66.2 or similar RPMs.

3.4 Maven pom.xml snippetContents

JPam releases are placed in the central Maven repository.

The Maven snippet for JPam 1.0 is:

     <dependency>
        <groupId>net.sf.jpam</groupId>
        <artifactId>jpam</artifactId>
        <version>1.0</version>
     </dependency>

4 Getting StartedContents

4.1 Supported Operating Systems and ArchitecturesContents

JPam will create builds for the following:

4.2 Step-by-step Installation InstructionsContents

The steps are:

  1. Place the jpam-X.X.jar into your classpath.
  2. Ensure that any libraries required to satisfy dependencies are also in the classpath.
  3. As an optional step, configure an appropriate logging level.
  4. Copy the native library to the Java Native Libary Path. See the table below.
    OS and Architecture Native Library File Java Native Library Path
    Linux AMD64 server libjpam.so $JAVA_HOME/lib/amd64/server
    Linux i386 client libjpam.so $JAVA_HOME/lib/i386/client
    Linux i386 server libjpam.so $JAVA_HOME/lib/i386/server
    Linux x86 client libjpam.so $JAVA_HOME/lib/i386/client
    Linux x86 server libjpam.so $JAVA_HOME/lib/i386/server
    Mac OS X PPC libjpam.jnilib ~/Library/Java/Extensions
    Solaris sparc libjpam.so $JAVA_HOME/lib/sparc/client
    Solaris sparc libjpam.so $JAVA_HOME/lib/sparc/server

    Native Library Installation Location

    Alternately, JPam will search for the native library in the same directory as the JPam jar is located.

  5. If using the JAAS API, copy .java.login.config to your home directory.
  6. Configure a PAM module for use by JPam.

5 ConfigurationContents

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.

5.1 Format of pam.d filesContents

PAM configuration files have four columns:

5.2 Example 32 bit net-sf-jpam fileContents

An example which uses the standard Unix password PAM module is shown below.

#######################################################################
# Unix PAM Module
# ===============
#
# If using pam_unix you may need to change /etc/shadow to be readable by
# the user executing Jpam.
#######################################################################
auth required /lib/security/pam_unix_auth.so
account required /lib/security/pam_unix_acct.so
password required /lib/security/pam_unix_passwd.so
session required /lib/security/pam_unix_session.so

5.3 Example 64 bit net-sf-jpam fileContents

64 bit Linux distributions such as RedHat, Fedora, Suse and Novell Linux Desktop have adopted a convention of placing their 64 libraries in /lib64. The net-sf-jpam configuration file for these would look like:

#######################################################################
# Unix PAM Module
# ===============
#
# If using pam_unix you may need to change /etc/shadow to be readable by
# the user executing Jpam.
#######################################################################
auth required /lib64/security/pam_unix_auth.so
account required /lib64/security/pam_unix_acct.so
password required /lib64/security/pam_unix_passwd.so
session required /lib64/security/pam_unix_session.so

5.4 Configuring Popular Security ServicesContents

However, there are many more approaches than these two. There are hundreds of authentication systems accessible through PAM. See a list fo Linux here. Many of these are installed by default in the Linux distributions. For example Fedora Core 3 has 55 PAM modules in its /lib/security directory by default.

Some notable examples of PAM modules are:

Name Module Use
SecurId pam_securid.so Authenticates SecurId hardware tokens with the ACE Server. Available from RSA.
Unix pam_unix_+.so Authenticates using the configured auth Unix scheme. e.g. shadow passwords or NIS.
RADIUS pam_radius.so Authenticates using RADIUS servers.
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.

Popular Security Services

The path to the module shown above becomes the third column in the net-sf-jpam configuration line.

5.5 Installing Additional PAM ModulesContents

JPam will dynamically link to any Pam module which is installed on the operating system and specified in its configuration. No recompilation is required.

5.6 More informationContents

See http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/pam.html for information on configuring PAM.

6 FeaturesContents

6.1 High QualityContents

6.1.1 High Test CoverageContents

The JPam team believe that the first and most important quality measure is a well designed and comprehensive test suite.

JPam has a relatively high test coverage of source code. This has edged higher over time.

6.1.2 Automated Load, Limit and Performance System TestsContents

The JPam JUnit test suite contains some long-running system tests which place high load on different JPam subsystems to the point of failure and then are back off to just below that point. The same is done with limits such as the amount of Elements that can fit in a given heap size. The same is also done with performance testing of each subsystem and the whole together. The same is also done with network tests for cache replication.

The tests serve a number of purposes:

6.1.3 Specific Concurrency TestingContents

JPam also has concurrency testing, which uses 15 concurrent threads hammering a piece of code. The test suites are also run on multi-core or multi-cpu machines so that concurrency is real rather than simulated. Additionally, every concurrency related issue that has ever been anticipated or resulted in a bug report has a unit test which prevents the condition from recurring. There are no reported issues that have not been reproduced in a unit test.

Concurrency unit tests are somewhat difficult to write, and are often overlooked. The team considers these tests a major factor in JPam's quality.

6.1.4 Production testedContents

JPam has been in production for 18 months.

6.1.5 Fully documentedContents

A core belief held by the project team is that a project needs good documentation to be useful.

In JPam, this is manifested by:

6.1.6 Conservative Commit policyContents

Projects like Linux maintain their quality through a restricted change process, whereby changes are submitted as patches, then reviewed by the maintainer and included, or modified. JPam follows the same process.

6.1.7 Full public information on the history of every bugContents

Through the SourceForge project bug tracker, the full history of all bugs are shown, including current status. We take this for granted in an open source project, as this is typically a feature that all open source projects have, but this transparency makes it possible to gauge the quality and riskiness of a library, something not usually possible in commercial products.

6.1.8 Responsiveness to serious bugsContents

The JPam team is serious about quality. If one user is having a problem, it probably means others are too, or will have. The JPam team use JPam themselves in production. Every effort will be made to provide fixes for serious production problems as soon as possible. These will be committed to trunk. From there an affected user can apply the fix to their own branch.

6.2 Open Source LicensingContents

6.2.1 Apache 2.0 licenseContents

JPam's original Apache1.1 copyright and licensing was reviewed and approved by the Apache Software Foundation, making JPam suitable for use in Apache projects. JPam 1.0 is released under the updated Apache 2.0 license.

The Apache license is also friendly one, making it safe and easy to include JPam in other open source projects or commercial products.

7 Code SamplesContents

7.1 Using the JPAM APIContents

images/uml/Pam

Pam Class Diagram

Attempt to authenticate a username and password

    String user1Name = "test";
    String user1Credentials = "testPassword";
    Pam pam = new Pam();
    boolean authenticated = pam.authenticateSuccessful(user1Name, user1Credentials));

7.2 Using the JAAS APIContents

images/uml/JpamLoginModule

JPamLoginModule Class Diagram

Shows how to use the JAAS API together with a CallbackHandler.

    LoginContext loginContext = new LoginContext("net-sf-jpam", new JpamCallbackHandler());
    loginContext.login();
    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");
                }
            }
        }

    }

7.3 Browse the JUnit TestsContents

JPam comes with a comprehensive JUnit test suite, which not only tests the code, but shows you how to use JPam.

A link to browsable unit test source code for the major JPam classes is given per section. The unit tests are also in the src.zip in the JPam tarball.

8 Logging And DebuggingContents

8.1 Commons LoggingContents

JPam uses the Apache Commons Logging library for logging.

It acts as a thin bridge between logging statements in the code and logging infrastructure detected in the classpath. It will use in order of preference:

For normal production use, use the WARN level in log4J and the WARNING level for JDK1.4 logging.

8.2 libjpam.so DebuggingContents

If the DEBUG logging level is enabled, JPam will instruct libjpam.so to log messages to the console. This is very useful for identifying errors.

8.3 syslogd loggingContents

It can be useful to turn on syslogd for PAM logging. Library problems with PAM modules will then be logged.

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

Then simply tail /var/log/messages to see PAM logging.

9 Frequently Asked QuestionsContents

9.1 Does JPam run on JDK1.2?Contents

No, it is not supported.

9.2 JPam does not have a configuration for my OS/architecture. What can I do?Contents

It is easy to make the changes to the build.xml and makefile to support other architectures. Do it and submit a patch! Both Solaris and HP-UX support come from patches.

10 LimitationsContents

Jpam presently does not support advanced PAM conversations such as:

11 Building JPam from SourceContents

11.1 Building from sourceContents

To build JPam from source:

  1. Check the source out from the subversion repository.
  2. As root, install the pam-devel-0.77-66.2 package or similar is installed (Linux systems only)
  3. Create the following users on your machine:
  4. As root, copy src/config/architecture/net-sf-jpam* to /etc/pam.d
  5. Copy src/config/architecture/.java.login.config to your home directory
  6. Ensure you have a valid JAVA_HOME and ANT_HOME configured with binaries in your PATH
  7. From within the pam directory, type ant

11.2 RPM packaging (Optional)Contents

The source download and the CVS source contain a src/rpm directory containg an RPM spec file created in collaboration with developers at Red Hat. You can use this spec.file to build an rpm installable package for your architecture.

11.3 Building the SiteContents

(These instructions are for project maintainers)

You need the following unix utilities installed:

12 About the JPam name and logoContents

images/jpam_logo_trans

Logo

The JPam logo has a blue rectangle representing a Unix OS (blue is the Solaris colour), Java (the purple colour) and PAM (the small rectangles), which is what JPam is all about.


Index

A
Apache 2.0 license
Automated Load, Limit and Performance System Tests
B
Browse the JUnit Tests
C
Code Samples
Commons Logging
Configuration
Conservative Commit policy
F
Features
Full public information on the history of every bug
Fully documented
H
High Quality
High Test Coverage
J
Java Requirements
JDK1.2
JDK1.4 logging
L
libjpam.so Debugging
log4j
N
net-sf-jpam
O
Open Source Licensing
P
Production tested
R
Responsiveness to serious bugs
S
SimpleLog
Specific Concurrency Testing
syslogd logging
U
Using the JAAS API
Using the JPAM API