/* * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.security.auth.module; import javax.security.auth.x500.X500Principal;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.PushbackInputStream;import java.net.MalformedURLException;import java.net.URL;import java.security.AuthProvider;import java.security.GeneralSecurityException;import java.security.Key;import java.security.KeyStore;import java.security.KeyStoreException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.Principal;import java.security.PrivateKey;import java.security.Provider;import java.security.UnrecoverableKeyException;import java.security.cert.*;import java.security.cert.X509Certificate;import java.util.Arrays;import java.util.Iterator;import java.util.LinkedList;import java.util.Map;import java.util.ResourceBundle;import javax.security.auth.Destroyable;import javax.security.auth.DestroyFailedException;import javax.security.auth.Subject;import javax.security.auth.x500.*;import javax.security.auth.Subject;import javax.security.auth.x500.*;import javax.security.auth.callback.Callback;import javax.security.auth.callback.CallbackHandler;import javax.security.auth.callback.ConfirmationCallback;import javax.security.auth.callback.NameCallback;import javax.security.auth.callback.PasswordCallback;import javax.security.auth.callback.TextOutputCallback;import javax.security.auth.callback.UnsupportedCallbackException;import javax.security.auth.login.FailedLoginException;import javax.security.auth.login.LoginException;import javax.security.auth.spi.LoginModule; import sun.security.util.AuthResources;import sun.security.util.Password; /** * Provides a JAAS login module that prompts for a key store alias and * populates the subject with the alias's principal and credentials. Stores * an <code>X500Principal</code> for the subject distinguished name of the * first certificate in the alias's credentials in the subject's principals, * the alias's certificate path in the subject's public credentials, and a * <code>X500PrivateCredential</code> whose certificate is the first * certificate in the alias's certificate path and whose private key is the * alias's private key in the subject's private credentials. <p> * * Recognizes the following options in the configuration file: * <dl> * * <dt> <code>keyStoreURL</code> </dt> * <dd> A URL that specifies the location of the key store. Defaults to * a URL pointing to the .keystore file in the directory specified by the * <code>user.home</code> system property. The input stream from this * URL is passed to the <code>KeyStore.load</code> method. * "NONE" may be specified if a <code>null</code> stream must be * passed to the <code>KeyStore.load</code> method. * "NONE" should be specified if the KeyStore resides * on a hardware token device, for example.</dd> * * <dt> <code>keyStoreType</code> </dt> * <dd> The key store type. If not specified, defaults to the result of * calling <code>KeyStore.getDefaultType()</code>. * If the type is "PKCS11", then keyStoreURL must be "NONE" * and privateKeyPasswordURL must not be specified.</dd> * * <dt> <code>keyStoreProvider</code> </dt> * <dd> The key store provider. If not specified, uses the standard search * order to find the provider. </dd> * * <dt> <code>keyStoreAlias</code> </dt> * <dd> The alias in the key store to login as. Required when no callback * handler is provided. No default value. </dd> * * <dt> <code>keyStorePasswordURL</code> </dt> * <dd> A URL that specifies the location of the key store password. Required * when no callback handler is provided and * <code>protected</code> is false. * No default value. </dd> * * <dt> <code>privateKeyPasswordURL</code> </dt> * <dd> A URL that specifies the location of the specific private key password * needed to access the private key for this alias. * The keystore password * is used if this value is needed and not specified. </dd> * * <dt> <code>protected</code> </dt> * <dd> This value should be set to "true" if the KeyStore * has a separate, protected authentication path * (for example, a dedicated PIN-pad attached to a smart card). * Defaults to "false". If "true" keyStorePasswordURL and * privateKeyPasswordURL must not be specified.</dd> * * </dl> */public class KeyStoreLoginModule implements LoginModule { static final java.util.ResourceBundle rb = java.util.ResourceBundle.getBundle("sun.security.util.AuthResources"); /* -- Fields -- */ private static final int UNINITIALIZED = 0; private static final int INITIALIZED = 1; private static final int AUTHENTICATED = 2; private static final int LOGGED_IN = 3; private static final int PROTECTED_PATH = 0; private static final int TOKEN = 1; private static final int NORMAL = 2; private static final String NONE = "NONE"; private static final String P11KEYSTORE = "PKCS11"; private static final TextOutputCallback bannerCallback = new TextOutputCallback (TextOutputCallback.INFORMATION, rb.getString("Please.enter.keystore.information")); private final ConfirmationCallback confirmationCallback = new ConfirmationCallback (ConfirmationCallback.INFORMATION, ConfirmationCallback.OK_CANCEL_OPTION, ConfirmationCallback.OK); private Subject subject; private CallbackHandler callbackHandler; private Map sharedState; private Map<String, ?> options; private char[] keyStorePassword; private char[] privateKeyPassword; private KeyStore keyStore; private String keyStoreURL; private String keyStoreType; private String keyStoreProvider; private String keyStoreAlias; private String keyStorePasswordURL; private String privateKeyPasswordURL; private boolean debug; private javax.security.auth.x500.X500Principal principal; private Certificate[] fromKeyStore; private java.security.cert.CertPath certP = null; private X500PrivateCredential privateCredential; private int status = UNINITIALIZED; private boolean nullStream = false; private boolean token = false; private boolean protectedPath = false; /* -- Methods -- */ /** * Initialize this <code>LoginModule</code>. * * <p> * * @param subject the <code>Subject</code> to be authenticated. <p> * * @param callbackHandler a <code>CallbackHandler</code> for communicating * with the end user (prompting for usernames and * passwords, for example), * which may be <code>null</code>. <p> * * @param sharedState shared <code>LoginModule</code> state. <p> * * @param options options specified in the login * <code>Configuration</code> for this particular * <code>LoginModule</code>. */ public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String,?> sharedState, Map<String,?> options) { this.subject = subject; this.callbackHandler = callbackHandler; this.sharedState = sharedState; this.options = options; processOptions(); status = INITIALIZED; } private void processOptions() { keyStoreURL = (String) options.get("keyStoreURL"); if (keyStoreURL == null) { keyStoreURL = "file:" + System.getProperty("user.home").replace( File.separatorChar, '/') + '/' + ".keystore"; } else if (NONE.equals(keyStoreURL)) { nullStream = true; } keyStoreType = (String) options.get("keyStoreType"); if (keyStoreType == null) { keyStoreType = KeyStore.getDefaultType(); } if (P11KEYSTORE.equalsIgnoreCase(keyStoreType)) { token = true; } keyStoreProvider = (String) options.get("keyStoreProvider"); keyStoreAlias = (String) options.get("keyStoreAlias"); keyStorePasswordURL = (String) options.get("keyStorePasswordURL"); privateKeyPasswordURL = (String) options.get("privateKeyPasswordURL"); protectedPath = "true".equalsIgnoreCase((String)options.get ("protected")); debug = "true".equalsIgnoreCase((String) options.get("debug")); if (debug) { debugPrint(null); debugPrint("keyStoreURL=" + keyStoreURL); debugPrint("keyStoreType=" + keyStoreType); debugPrint("keyStoreProvider=" + keyStoreProvider); debugPrint("keyStoreAlias=" + keyStoreAlias); debugPrint("keyStorePasswordURL=" + keyStorePasswordURL); debugPrint("privateKeyPasswordURL=" + privateKeyPasswordURL); debugPrint("protectedPath=" + protectedPath); debugPrint(null); } } /** * Authenticate the user. * * <p> Get the Keystore alias and relevant passwords. * Retrieve the alias's principal and credentials from the Keystore. * * <p> * * @exception FailedLoginException if the authentication fails. <p> * * @return true in all cases (this <code>LoginModule</code> * should not be ignored). */ public boolean login() throws LoginException { switch (status) { case UNINITIALIZED: default: throw new LoginException("The login module is not initialized"); case INITIALIZED: case AUTHENTICATED: if (token && !nullStream) { throw new LoginException ("if keyStoreType is " + P11KEYSTORE + " then keyStoreURL must be " + NONE); } if (token && privateKeyPasswordURL != null) { throw new LoginException ("if keyStoreType is " + P11KEYSTORE + " then privateKeyPasswordURL must not be specified"); } if (protectedPath && (keyStorePasswordURL != null || privateKeyPasswordURL != null)) { throw new LoginException ("if protected is true then keyStorePasswordURL and " + "privateKeyPasswordURL must not be specified"); } // get relevant alias and password info if (protectedPath) { getAliasAndPasswords(PROTECTED_PATH); } else if (token) { getAliasAndPasswords(TOKEN); } else { getAliasAndPasswords(NORMAL); } // log into KeyStore to retrieve data, // then clear passwords try { getKeyStoreInfo(); } finally { if (privateKeyPassword != null && privateKeyPassword != keyStorePassword) { Arrays.fill(privateKeyPassword, '\0'); privateKeyPassword = null; } if (keyStorePassword != null) { Arrays.fill(keyStorePassword, '\0'); keyStorePassword = null; } } status = AUTHENTICATED; return true; case LOGGED_IN: return true; } } /** Get the alias and passwords to use for looking up in the KeyStore. */ private void getAliasAndPasswords(int env) throws LoginException { if (callbackHandler == null) { // No callback handler - check for alias and password options switch (env) { case PROTECTED_PATH: checkAlias(); break; case TOKEN: checkAlias(); checkStorePass(); break; case NORMAL: checkAlias(); checkStorePass(); checkKeyPass(); break; } } else { // Callback handler available - prompt for alias and passwords NameCallback aliasCallback; if (keyStoreAlias == null || keyStoreAlias.length() == 0) { aliasCallback = new NameCallback( rb.getString("Keystore.alias.")); } else { aliasCallback = new NameCallback(rb.getString("Keystore.alias."), keyStoreAlias); } PasswordCallback storePassCallback = null; PasswordCallback keyPassCallback = null; switch (env) { case PROTECTED_PATH: break; case NORMAL: keyPassCallback = new PasswordCallback (rb.getString("Private.key.password.optional."), false); // fall thru case TOKEN: storePassCallback = new PasswordCallback (rb.getString("Keystore.password."), false); break; } prompt(aliasCallback, storePassCallback, keyPassCallback); } if (debug) { debugPrint("alias=" + keyStoreAlias); } } private void checkAlias() throws LoginException { if (keyStoreAlias == null) { throw new LoginException ("Need to specify an alias option to use " + "KeyStoreLoginModule non-interactively."); } } private void checkStorePass() throws LoginException { if (keyStorePasswordURL == null) { throw new LoginException ("Need to specify keyStorePasswordURL option to use " + "KeyStoreLoginModule non-interactively."); } InputStream in = null; try { in = new URL(keyStorePasswordURL).openStream(); keyStorePassword = Password.readPassword(in); } catch (IOException e) { LoginException le = new LoginException ("Problem accessing keystore password \"" + keyStorePasswordURL + "\""); le.initCause(e); throw le; } finally { if (in != null) { try { in.close(); } catch (IOException ioe) { LoginException le = new LoginException( "Problem closing the keystore password stream"); le.initCause(ioe); throw le; } } } } private void checkKeyPass() throws LoginException { if (privateKeyPasswordURL == null) { privateKeyPassword = keyStorePassword; } else { InputStream in = null; try { in = new URL(privateKeyPasswordURL).openStream(); privateKeyPassword = Password.readPassword(in); } catch (IOException e) { LoginException le = new LoginException ("Problem accessing private key password \"" + privateKeyPasswordURL + "\""); le.initCause(e); throw le; } finally { if (in != null) { try { in.close(); } catch (IOException ioe) { LoginException le = new LoginException( "Problem closing the private key password stream"); le.initCause(ioe); throw le; } } } } } private void prompt(NameCallback aliasCallback, PasswordCallback storePassCallback, PasswordCallback keyPassCallback) throws LoginException { if (storePassCallback == null) { // only prompt for alias try { callbackHandler.handle( new Callback[] { bannerCallback, aliasCallback, confirmationCallback }); } catch (IOException e) { LoginException le = new LoginException ("Problem retrieving keystore alias"); le.initCause(e); throw le; } catch (UnsupportedCallbackException e) { throw new LoginException( "Error: " + e.getCallback().toString() + " is not available to retrieve authentication " + " information from the user"); } int confirmationResult = confirmationCallback.getSelectedIndex(); if (confirmationResult == ConfirmationCallback.CANCEL) { throw new LoginException("Login cancelled"); } saveAlias(aliasCallback); } else if (keyPassCallback == null) { // prompt for alias and key store passwordLines 1–500 of 947. Load more
/* * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.security.auth.module; import javax.security.auth.x500.X500Principal; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream; import java.net.MalformedURLException; import java.net.URL; import java.security.AuthProvider; import java.security.GeneralSecurityException; import java.security.Key; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.PrivateKey; import java.security.Provider; import java.security.UnrecoverableKeyException; import java.security.cert.*; import java.security.cert.X509Certificate; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import java.util.ResourceBundle; import javax.security.auth.Destroyable; import javax.security.auth.DestroyFailedException; import javax.security.auth.Subject; import javax.security.auth.x500.*; import javax.security.auth.Subject; import javax.security.auth.x500.*; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.ConfirmationCallback; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.TextOutputCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; import sun.security.util.AuthResources; import sun.security.util.Password; /** * Provides a JAAS login module that prompts for a key store alias and * populates the subject with the alias's principal and credentials. Stores * an <code>X500Principal</code> for the subject distinguished name of the * first certificate in the alias's credentials in the subject's principals, * the alias's certificate path in the subject's public credentials, and a * <code>X500PrivateCredential</code> whose certificate is the first * certificate in the alias's certificate path and whose private key is the * alias's private key in the subject's private credentials. <p> * * Recognizes the following options in the configuration file: * <dl> * * <dt> <code>keyStoreURL</code> </dt> * <dd> A URL that specifies the location of the key store. Defaults to * a URL pointing to the .keystore file in the directory specified by the * <code>user.home</code> system property. The input stream from this * URL is passed to the <code>KeyStore.load</code> method. * "NONE" may be specified if a <code>null</code> stream must be * passed to the <code>KeyStore.load</code> method. * "NONE" should be specified if the KeyStore resides * on a hardware token device, for example.</dd> * * <dt> <code>keyStoreType</code> </dt> * <dd> The key store type. If not specified, defaults to the result of * calling <code>KeyStore.getDefaultType()</code>. * If the type is "PKCS11", then keyStoreURL must be "NONE" * and privateKeyPasswordURL must not be specified.</dd> * * <dt> <code>keyStoreProvider</code> </dt> * <dd> The key store provider. If not specified, uses the standard search * order to find the provider. </dd> * * <dt> <code>keyStoreAlias</code> </dt> * <dd> The alias in the key store to login as. Required when no callback * handler is provided. No default value. </dd> * * <dt> <code>keyStorePasswordURL</code> </dt> * <dd> A URL that specifies the location of the key store password. Required * when no callback handler is provided and * <code>protected</code> is false. * No default value. </dd> * * <dt> <code>privateKeyPasswordURL</code> </dt> * <dd> A URL that specifies the location of the specific private key password * needed to access the private key for this alias. * The keystore password * is used if this value is needed and not specified. </dd> * * <dt> <code>protected</code> </dt> * <dd> This value should be set to "true" if the KeyStore * has a separate, protected authentication path * (for example, a dedicated PIN-pad attached to a smart card). * Defaults to "false". If "true" keyStorePasswordURL and * privateKeyPasswordURL must not be specified.</dd> * * </dl> */ public class KeyStoreLoginModule implements LoginModule { static final java.util.ResourceBundle rb = java.util.ResourceBundle.getBundle("sun.security.util.AuthResources"); /* -- Fields -- */ private static final int UNINITIALIZED = 0; private static final int INITIALIZED = 1; private static final int AUTHENTICATED = 2; private static final int LOGGED_IN = 3; private static final int PROTECTED_PATH = 0; private static final int TOKEN = 1; private static final int NORMAL = 2; private static final String NONE = "NONE"; private static final String P11KEYSTORE = "PKCS11"; private static final TextOutputCallback bannerCallback = new TextOutputCallback (TextOutputCallback.INFORMATION, rb.getString("Please.enter.keystore.information")); private final ConfirmationCallback confirmationCallback = new ConfirmationCallback (ConfirmationCallback.INFORMATION, ConfirmationCallback.OK_CANCEL_OPTION, ConfirmationCallback.OK); private Subject subject; private CallbackHandler callbackHandler; private Map sharedState; private Map<String, ?> options; private char[] keyStorePassword; private char[] privateKeyPassword; private KeyStore keyStore; private String keyStoreURL; private String keyStoreType; private String keyStoreProvider; private String keyStoreAlias; private String keyStorePasswordURL; private String privateKeyPasswordURL; private boolean debug; private javax.security.auth.x500.X500Principal principal; private Certificate[] fromKeyStore; private java.security.cert.CertPath certP = null; private X500PrivateCredential privateCredential; private int status = UNINITIALIZED; private boolean nullStream = false; private boolean token = false; private boolean protectedPath = false; /* -- Methods -- */ /** * Initialize this <code>LoginModule</code>. * * <p> * * @param subject the <code>Subject</code> to be authenticated. <p> * * @param callbackHandler a <code>CallbackHandler</code> for communicating * with the end user (prompting for usernames and * passwords, for example), * which may be <code>null</code>. <p> * * @param sharedState shared <code>LoginModule</code> state. <p> * * @param options options specified in the login * <code>Configuration</code> for this particular * <code>LoginModule</code>. */ public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String,?> sharedState, Map<String,?> options) { this.subject = subject; this.callbackHandler = callbackHandler; this.sharedState = sharedState; this.options = options; processOptions(); status = INITIALIZED; } private void processOptions() { keyStoreURL = (String) options.get("keyStoreURL"); if (keyStoreURL == null) { keyStoreURL = "file:" + System.getProperty("user.home").replace( File.separatorChar, '/') + '/' + ".keystore"; } else if (NONE.equals(keyStoreURL)) { nullStream = true; } keyStoreType = (String) options.get("keyStoreType"); if (keyStoreType == null) { keyStoreType = KeyStore.getDefaultType(); } if (P11KEYSTORE.equalsIgnoreCase(keyStoreType)) { token = true; } keyStoreProvider = (String) options.get("keyStoreProvider"); keyStoreAlias = (String) options.get("keyStoreAlias"); keyStorePasswordURL = (String) options.get("keyStorePasswordURL"); privateKeyPasswordURL = (String) options.get("privateKeyPasswordURL"); protectedPath = "true".equalsIgnoreCase((String)options.get ("protected")); debug = "true".equalsIgnoreCase((String) options.get("debug")); if (debug) { debugPrint(null); debugPrint("keyStoreURL=" + keyStoreURL); debugPrint("keyStoreType=" + keyStoreType); debugPrint("keyStoreProvider=" + keyStoreProvider); debugPrint("keyStoreAlias=" + keyStoreAlias); debugPrint("keyStorePasswordURL=" + keyStorePasswordURL); debugPrint("privateKeyPasswordURL=" + privateKeyPasswordURL); debugPrint("protectedPath=" + protectedPath); debugPrint(null); } } /** * Authenticate the user. * * <p> Get the Keystore alias and relevant passwords. * Retrieve the alias's principal and credentials from the Keystore. * * <p> * * @exception FailedLoginException if the authentication fails. <p> * * @return true in all cases (this <code>LoginModule</code> * should not be ignored). */ public boolean login() throws LoginException { switch (status) { case UNINITIALIZED: default: throw new LoginException("The login module is not initialized"); case INITIALIZED: case AUTHENTICATED: if (token && !nullStream) { throw new LoginException ("if keyStoreType is " + P11KEYSTORE + " then keyStoreURL must be " + NONE); } if (token && privateKeyPasswordURL != null) { throw new LoginException ("if keyStoreType is " + P11KEYSTORE + " then privateKeyPasswordURL must not be specified"); } if (protectedPath && (keyStorePasswordURL != null || privateKeyPasswordURL != null)) { throw new LoginException ("if protected is true then keyStorePasswordURL and " + "privateKeyPasswordURL must not be specified"); } // get relevant alias and password info if (protectedPath) { getAliasAndPasswords(PROTECTED_PATH); } else if (token) { getAliasAndPasswords(TOKEN); } else { getAliasAndPasswords(NORMAL); } // log into KeyStore to retrieve data, // then clear passwords try { getKeyStoreInfo(); } finally { if (privateKeyPassword != null && privateKeyPassword != keyStorePassword) { Arrays.fill(privateKeyPassword, '\0'); privateKeyPassword = null; } if (keyStorePassword != null) { Arrays.fill(keyStorePassword, '\0'); keyStorePassword = null; } } status = AUTHENTICATED; return true; case LOGGED_IN: return true; } } /** Get the alias and passwords to use for looking up in the KeyStore. */ private void getAliasAndPasswords(int env) throws LoginException { if (callbackHandler == null) { // No callback handler - check for alias and password options switch (env) { case PROTECTED_PATH: checkAlias(); break; case TOKEN: checkAlias(); checkStorePass(); break; case NORMAL: checkAlias(); checkStorePass(); checkKeyPass(); break; } } else { // Callback handler available - prompt for alias and passwords NameCallback aliasCallback; if (keyStoreAlias == null || keyStoreAlias.length() == 0) { aliasCallback = new NameCallback( rb.getString("Keystore.alias.")); } else { aliasCallback = new NameCallback(rb.getString("Keystore.alias."), keyStoreAlias); } PasswordCallback storePassCallback = null; PasswordCallback keyPassCallback = null; switch (env) { case PROTECTED_PATH: break; case NORMAL: keyPassCallback = new PasswordCallback (rb.getString("Private.key.password.optional."), false); // fall thru case TOKEN: storePassCallback = new PasswordCallback (rb.getString("Keystore.password."), false); break; } prompt(aliasCallback, storePassCallback, keyPassCallback); } if (debug) { debugPrint("alias=" + keyStoreAlias); } } private void checkAlias() throws LoginException { if (keyStoreAlias == null) { throw new LoginException ("Need to specify an alias option to use " + "KeyStoreLoginModule non-interactively."); } } private void checkStorePass() throws LoginException { if (keyStorePasswordURL == null) { throw new LoginException ("Need to specify keyStorePasswordURL option to use " + "KeyStoreLoginModule non-interactively."); } InputStream in = null; try { in = new URL(keyStorePasswordURL).openStream(); keyStorePassword = Password.readPassword(in); } catch (IOException e) { LoginException le = new LoginException ("Problem accessing keystore password \"" + keyStorePasswordURL + "\""); le.initCause(e); throw le; } finally { if (in != null) { try { in.close(); } catch (IOException ioe) { LoginException le = new LoginException( "Problem closing the keystore password stream"); le.initCause(ioe); throw le; } } } } private void checkKeyPass() throws LoginException { if (privateKeyPasswordURL == null) { privateKeyPassword = keyStorePassword; } else { InputStream in = null; try { in = new URL(privateKeyPasswordURL).openStream(); privateKeyPassword = Password.readPassword(in); } catch (IOException e) { LoginException le = new LoginException ("Problem accessing private key password \"" + privateKeyPasswordURL + "\""); le.initCause(e); throw le; } finally { if (in != null) { try { in.close(); } catch (IOException ioe) { LoginException le = new LoginException( "Problem closing the private key password stream"); le.initCause(ioe); throw le; } } } } } private void prompt(NameCallback aliasCallback, PasswordCallback storePassCallback, PasswordCallback keyPassCallback) throws LoginException { if (storePassCallback == null) { // only prompt for alias try { callbackHandler.handle( new Callback[] { bannerCallback, aliasCallback, confirmationCallback }); } catch (IOException e) { LoginException le = new LoginException ("Problem retrieving keystore alias"); le.initCause(e); throw le; } catch (UnsupportedCallbackException e) { throw new LoginException( "Error: " + e.getCallback().toString() + " is not available to retrieve authentication " + " information from the user"); } int confirmationResult = confirmationCallback.getSelectedIndex(); if (confirmationResult == ConfirmationCallback.CANCEL) { throw new LoginException("Login cancelled"); } saveAlias(aliasCallback); } else if (keyPassCallback == null) { // prompt for alias and key store password