/** * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved * * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * https://opensso.dev.java.net/public/CDDLv1.0.html or * opensso/legal/CDDLv1.0.txt * See the License for the specific language governing * permission and limitations under the License. * * When distributing Covered Code, include this CDDL * Header Notice in each file and include the License file * at opensso/legal/CDDLv1.0.txt. * If applicable, add the following below the CDDL Header, * with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * $Id: PlainMechanismHandler.java,v 1.6 2008/08/06 17:29:24 exu Exp $ * */ package com.sun.identity.liberty.ws.authnsvc.mechanism; import javax.security.auth.callback.Callback; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import com.sun.identity.shared.configuration.SystemPropertiesManager; import com.sun.identity.shared.debug.Debug; import com.iplanet.sso.SSOException; import com.iplanet.sso.SSOToken; import com.iplanet.sso.SSOTokenManager; import com.sun.identity.authentication.AuthContext; import com.sun.identity.authentication.spi.AuthLoginException; import com.sun.identity.liberty.ws.authnsvc.AuthnSvcConstants; import com.sun.identity.liberty.ws.authnsvc.AuthnSvcService; import com.sun.identity.liberty.ws.authnsvc.AuthnSvcUtils; import com.sun.identity.liberty.ws.authnsvc.protocol.SASLRequest; import com.sun.identity.liberty.ws.authnsvc.protocol.SASLResponse; import com.sun.identity.liberty.ws.soapbinding.Message; import com.sun.identity.sm.SMSEntry; /** * The PlainMechanismHandler is a handler for 'PLAIN' * mechanism. */ public class PlainMechanismHandler implements MechanismHandler { public static Debug debug = Debug.getInstance("libIDWSF"); /** * Generates a SASL response according to the SASL request. * @param saslReq a SASL request * @param message a SOAP Message containing the SASL request * @param respMessageID messageID of SOAP Message response that will * contain returned SASL response * @return a SASL response */ public SASLResponse processSASLRequest(SASLRequest saslReq, Message message, String respMessageID) { if (debug.messageEnabled()) { debug.message("PlainMechanismHandler.processSASLRequest: "); } String refToMessageID = saslReq.getRefToMessageID(); boolean isFirstRequest = (refToMessageID == null || refToMessageID.length() == 0); if (debug.messageEnabled()) { debug.message("PlainMechanismHandler.processSASLRequest: " + "refToMessageID = " + refToMessageID); } SASLResponse saslResp = null; byte[] data = saslReq.getData(); if (data == null) { if (isFirstRequest) { saslResp = new SASLResponse(SASLResponse.CONTINUE); saslResp.setServerMechanism(AuthnSvcConstants.MECHANISM_PLAIN); } else { saslResp = new SASLResponse(SASLResponse.ABORT); } } else { String dataStr = null; try { dataStr = new String(data, "UTF-8"); } catch (Exception ex) { debug.error("PlainMechanismHandler.processSASLRequest: ", ex); } if (dataStr == null) { saslResp = new SASLResponse(SASLResponse.ABORT); } else { saslResp = authenticate(dataStr, message); } if (isFirstRequest) { saslResp.setServerMechanism(AuthnSvcConstants.MECHANISM_PLAIN); } } return saslResp; } private SASLResponse authenticate(String data, Message message) { int indexNul = data.indexOf('\0'); if (indexNul == -1) { return new SASLResponse(SASLResponse.ABORT); } int indexNul2 = data.indexOf('\0', indexNul + 1); if (indexNul2 == -1) { return new SASLResponse(SASLResponse.ABORT); } String authzID = data.substring(0, indexNul); String authnID = data.substring(indexNul + 1, indexNul2); String password = data.substring(indexNul2 + 1); if (authnID == null) { return new SASLResponse(SASLResponse.ABORT); } if (debug.messageEnabled()) { debug.message("PlainMechanismHandler.authenticate: " + "authzID = " + authzID + ", authnID = " + authnID); } String authModule = AuthnSvcService.getPlainMechanismAuthenticationModule(); if (debug.messageEnabled()) { debug.message("PlainMechanismHandler.authenticate: " + "authModule = " + authModule); } AuthContext authContext = null; try { authContext = new AuthContext(SMSEntry.getRootSuffix()); authContext.login(AuthContext.IndexType.MODULE_INSTANCE, authModule); } catch (AuthLoginException le) { debug.error("PlainMechanismHandler.authenticate: ", le); return new SASLResponse(SASLResponse.ABORT); } if (authContext.hasMoreRequirements()) { Callback[] callbacks = authContext.getRequirements(); if (callbacks != null) { fillInCallbacks(callbacks, authnID, password); authContext.submitRequirements(callbacks); } } AuthContext.Status loginStatus = authContext.getStatus(); if (debug.messageEnabled()) { debug.message( "PlainMechanismHandler.authenticate: login status = " + loginStatus); } if (loginStatus != AuthContext.Status.SUCCESS) { return new SASLResponse(SASLResponse.ABORT); } try { SSOToken token = authContext.getSSOToken(); String userDN = token.getPrincipal().getName(); SASLResponse saslResp = new SASLResponse(SASLResponse.OK); try { SSOTokenManager.getInstance().destroyToken(token); } catch (SSOException ssoex) { if (AuthnSvcUtils.debug.warningEnabled()) { AuthnSvcUtils.debug.warning( "PlainMechanismHandler.authenticate:", ssoex); } } if (!AuthnSvcUtils.setResourceOfferingAndCredentials( saslResp, message, userDN)) { return new SASLResponse(SASLResponse.ABORT); } return saslResp; } catch (Exception ex) { debug.error("PlainMechanismHandler.authenticate: ", ex); return new SASLResponse(SASLResponse.ABORT); } } private static void fillInCallbacks(Callback[] callbacks, String username, String password) { if (debug.messageEnabled()) { debug.message("PlainMechanismHandler.fillInCallbacks:"); } for(int i = 0; i < callbacks.length; i++) { Callback callback = callbacks[i]; if (callback instanceof NameCallback) { ((NameCallback)callback).setName(username); } else if (callback instanceof PasswordCallback) { ((PasswordCallback)callback).setPassword( password.toCharArray()); } } } }