Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7089889

Krb5LoginModule.login() throws an exception if used without a keytab

    XMLWordPrintable

Details

    • b120
    • 7
    • b10
    • x86
    • windows_7
    • Verified

    Backports

      Description

        FULL PRODUCT VERSION :
        java version "1.7.0"
        Java(TM) SE Runtime Environment (build 1.7.0-b147)
        Java HotSpot(TM) Client VM (build 21.0-b17, mixed mode, sharing)

        A DESCRIPTION OF THE PROBLEM :
        The call to LoginContext.login() fails with an exception if the LoginContext is configured to use Krb5LoginModule with the following options:

        storeKey="true"
        useKeyTab="false"
        isInitiator="false"

        This appears to be a regression due to an attempt to solve bug '6941083'.

        The following source code is taken from Kb5LoginModule.attemptAuthentication(false):

        if (ktab == null) {
                promptForPass(getPasswdFromSharedState);
                builder = new KrbAsReqBuilder(principal, password);
                if (isInitiator) {
                        // XXX Even if isInitiator=false, it might be
                        // better to do an AS-REQ so that keys can be
                        // updated with PA info
                        cred = builder.action().getCreds();
                }
                if (storeKey) {
                        encKeys = builder.getKeys();
                        // When encKeys is empty, the login actually fails.
                        // For compatibility, exception is thrown in commit().
                }
        }

        This code path results builder.getGeys() being called while the builder's state is 'INIT'.
        The builder asserts via checkState() that the state is REQ_OK, hence an exception.

        This is a regression, as JRE6 and prior versions called EncryptionKey.acquireSecretKeys()
        to obtain the keys in this case.

        REGRESSION. Last worked in version 6u26

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        See the executable test case below. Program should be run on a Windows machine that is joined to a domain. Replace 'REALM', 'KDC', 'DOMAIN_USER' and 'DOMAIN_USER_PWD' as appropriate before running

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        "Login succeeded" printed to console
        ACTUAL -
        "Login failed" printed to console.
        Exception stacktrace printed to strerr

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        javax.security.auth.login.LoginException: java.lang.IllegalStateException: Cannot get keys at REQ_OK state
        at sun.security.krb5.KrbAsReqBuilder.checkState(Unknown Source)
        at sun.security.krb5.KrbAsReqBuilder.getKeys(Unknown Source)
        at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Unknown Source)
        at com.sun.security.auth.module.Krb5LoginModule.login(Unknown Source)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at javax.security.auth.login.LoginContext.invoke(Unknown Source)
        at javax.security.auth.login.LoginContext.access$000(Unknown Source)
        at javax.security.auth.login.LoginContext$4.run(Unknown Source)
        at javax.security.auth.login.LoginContext$4.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.login.LoginContext.invokePriv(Unknown Source)
        at javax.security.auth.login.LoginContext.login(Unknown Source)
        at LoginModuleExample.main(LoginModuleExample.java:43)

        at javax.security.auth.login.LoginContext.invoke(Unknown Source)
        at javax.security.auth.login.LoginContext.access$000(Unknown Source)
        at javax.security.auth.login.LoginContext$4.run(Unknown Source)
        at javax.security.auth.login.LoginContext$4.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.login.LoginContext.invokePriv(Unknown Source)
        at javax.security.auth.login.LoginContext.login(Unknown Source)
        at LoginModuleExample.main(LoginModuleExample.java:43)

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.util.HashMap;
        import java.util.Map;

        import javax.security.auth.callback.Callback;
        import javax.security.auth.callback.CallbackHandler;
        import javax.security.auth.callback.NameCallback;
        import javax.security.auth.callback.PasswordCallback;
        import javax.security.auth.login.AppConfigurationEntry;
        import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
        import javax.security.auth.login.Configuration;
        import javax.security.auth.login.LoginContext;

        import com.sun.security.auth.module.Krb5LoginModule;

        public class LoginModuleExample {

        // Replace with the realm and KDC of the Windows domain.
        private static final String REALM = "DEV-DEM.RECOMMIND.COM";
        private static final String KDC = "AU-DEV-DC01.dev-dem.recommind.com";

        // Replace with the username and password of any account on the
        // above domain. Account needs to be enabled and not locked out.
        private static final String DOMAIN_USER = "sgr";
        private static final String DOMAIN_USER_PWD = "0rodriguez)";

        private static final String EXAMPLE_SERVER_LOGIN = "example-server";

        /**
        * @param args
        */
        public static void main(String[] args) {

        System.setProperty("java.security.krb5.realm", REALM);
        System.setProperty("java.security.krb5.kdc", KDC);

        Configuration.setConfiguration(new CustomConfiguration());

        try {
        CallbackHandler handler = getUsernamePasswordHandler(DOMAIN_USER, DOMAIN_USER_PWD);

        LoginContext loginContext = new LoginContext(EXAMPLE_SERVER_LOGIN, handler);

        loginContext.login();

        System.out.println("Login succeeded");
        }
        catch (Exception e) {

        System.out.println("Login failed");
        e.printStackTrace();
        }

        }

        private static CallbackHandler getUsernamePasswordHandler(final String username, final String password) {

        final CallbackHandler handler = new CallbackHandler() {

        public void handle(final Callback[] callback) {
        for (int i = 0; i < callback.length; i++) {
        if (callback[i] instanceof NameCallback) {
        final NameCallback nameCallback = (NameCallback) callback[i];
        nameCallback.setName(username);
        }
        else if (callback[i] instanceof PasswordCallback) {
        final PasswordCallback passCallback = (PasswordCallback) callback[i];
        passCallback.setPassword(password.toCharArray());
        }
        }
        }
        };

        return handler;
        }

        final static class CustomConfiguration extends Configuration {

        @Override
        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {

        AppConfigurationEntry[] entries = new AppConfigurationEntry[0];

        if (name.equals(EXAMPLE_SERVER_LOGIN)) {
        String krbModule = Krb5LoginModule.class.getName();
        LoginModuleControlFlag flag = LoginModuleControlFlag.REQUIRED;
        Map<String, String> options = new HashMap<String, String>();

        options.put("storeKey", "true");
        options.put("useKeyTab", "false");
        options.put("isInitiator", "false");

        AppConfigurationEntry entry = new AppConfigurationEntry(krbModule, flag, options);

        entries = new AppConfigurationEntry[] { entry };
        }

        return entries;
        }
        }
        }

        ---------- END SOURCE ----------

        Attachments

          Issue Links

            Activity

              People

                weijun Weijun Wang
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: