package net.sourceforge.solexatools.authentication; import java.io.IOException; import java.util.HashMap; import javax.security.auth.Subject; 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.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginException; import com.sun.security.auth.module.Krb5LoginModule; /** * <p> * UNCKerberos class. * </p> * * @author boconnor * @version $Id: $Id */ public class UNCKerberos extends Authentication { /** * {@inheritDoc} * * Get boolean true/false based on onyen/password pair. No exception is thrown. * * @return */ @Override public boolean loginSuccess(String uid, String password) { String user = uid; if (uid.contains("@")) { String[] t = uid.split("\\@"); user = t[0]; } try { return (getSubject(user, password, null) != null); } catch (Exception e) { e.printStackTrace(); System.err.println(e.getMessage()); } return (false); } // does the heavy-lifting for methods, above /** * <p> * getSubject. * </p> * * @param uid * a {@link java.lang.String} object. * @param password * a {@link java.lang.String} object. * @param keytabfile * a {@link java.lang.String} object. * @return a {@link javax.security.auth.Subject} object. * @throws javax.security.auth.login.LoginException * if any. */ protected Subject getSubject(String uid, String password, String keytabfile) throws LoginException { try { Subject jSubject = null; if (password != null) { Krb5LoginModule lm = new com.sun.security.auth.module.Krb5LoginModule(); HashMap options = new HashMap(); jSubject = new Subject(); options.put("doNotPrompt", "false"); // options.put("debug", "true"); lm.initialize(jSubject, new NamePasswordCallbackHandler(uid, password), null, options); lm.logout(); lm.login(); lm.commit(); } else { // use the old way for keytabs Krb5LoginModule lm = new com.sun.security.auth.module.Krb5LoginModule(); HashMap options = new HashMap(); jSubject = new Subject(); options.put("principal", uid); options.put("keyTab", keytabfile); options.put("useTicketCache", "false"); options.put("useKeyTab", "true"); options.put("storeKey", "true"); options.put("doNotPrompt", "true"); // options.put("debug", "true"); lm.initialize(jSubject, null, null, options); lm.logout(); lm.login(); lm.commit(); } return jSubject; } catch (LoginException e) { throw e; } } /** * <p> * isConfigError. * </p> * * @param e * a {@link java.lang.Throwable} object. * @return a boolean. */ protected boolean isConfigError(Throwable e) { boolean rval = false; Throwable t = e.getCause(); if (t != null) { rval = isConfigError(t); } if (!rval) { StackTraceElement[] ste = e.getStackTrace(); for (StackTraceElement e1 : ste) { String s = e1.getClassName(); if ("sun.security.krb5.Config".equals(s)) { rval = true; break; } } } return rval; } protected class NamePasswordCallbackHandler implements CallbackHandler { String username; String password; public NamePasswordCallbackHandler(String onyen, String pwd) { super(); username = onyen; password = pwd; } @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { boolean n = false; boolean p = false; for (Callback c : callbacks) { if (c instanceof NameCallback) { NameCallback nc = (NameCallback) c; nc.setName(username); n = true; } else if (c instanceof PasswordCallback) { PasswordCallback pc = (PasswordCallback) c; // pc.setPassword( password.toCharArray() ); byte[] bytes = password.getBytes(); int length = password.length(); char[] passwordChars = new char[length]; for (int j = 0; j < length; j++) { passwordChars[j] = (char) bytes[j];// password.charAt(j); } pc.setPassword(passwordChars); p = true; } if (n && p) { break; } } } } }