| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
package com.sun.security.sasl;  | 
 | 
 | 
 | 
import javax.security.sasl.*;  | 
 | 
import com.sun.security.sasl.util.PolicyUtils;  | 
 | 
 | 
 | 
import java.util.Map;  | 
 | 
import java.io.IOException;  | 
 | 
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;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
  */  | 
 | 
final public class ClientFactoryImpl implements SaslClientFactory { | 
 | 
    private static final String myMechs[] = { | 
 | 
        "EXTERNAL",  | 
 | 
        "CRAM-MD5",  | 
 | 
        "PLAIN",  | 
 | 
    };  | 
 | 
 | 
 | 
    private static final int mechPolicies[] = { | 
 | 
          | 
 | 
        PolicyUtils.NOPLAINTEXT|PolicyUtils.NOACTIVE|PolicyUtils.NODICTIONARY,  | 
 | 
        PolicyUtils.NOPLAINTEXT|PolicyUtils.NOANONYMOUS,      | 
 | 
        PolicyUtils.NOANONYMOUS,                              | 
 | 
    };  | 
 | 
 | 
 | 
    private static final int EXTERNAL = 0;  | 
 | 
    private static final int CRAMMD5 = 1;  | 
 | 
    private static final int PLAIN = 2;  | 
 | 
 | 
 | 
    public ClientFactoryImpl() { | 
 | 
    }  | 
 | 
 | 
 | 
    public SaslClient createSaslClient(String[] mechs,  | 
 | 
        String authorizationId,  | 
 | 
        String protocol,  | 
 | 
        String serverName,  | 
 | 
        Map<String,?> props,  | 
 | 
        CallbackHandler cbh) throws SaslException { | 
 | 
 | 
 | 
            for (int i = 0; i < mechs.length; i++) { | 
 | 
                if (mechs[i].equals(myMechs[EXTERNAL])  | 
 | 
                    && PolicyUtils.checkPolicy(mechPolicies[EXTERNAL], props)) { | 
 | 
                    return new ExternalClient(authorizationId);  | 
 | 
 | 
 | 
                } else if (mechs[i].equals(myMechs[CRAMMD5])  | 
 | 
                    && PolicyUtils.checkPolicy(mechPolicies[CRAMMD5], props)) { | 
 | 
 | 
 | 
                    Object[] uinfo = getUserInfo("CRAM-MD5", authorizationId, cbh); | 
 | 
 | 
 | 
                      | 
 | 
                    return new CramMD5Client((String) uinfo[0],  | 
 | 
                        (byte []) uinfo[1]);  | 
 | 
 | 
 | 
                } else if (mechs[i].equals(myMechs[PLAIN])  | 
 | 
                    && PolicyUtils.checkPolicy(mechPolicies[PLAIN], props)) { | 
 | 
 | 
 | 
                    Object[] uinfo = getUserInfo("PLAIN", authorizationId, cbh); | 
 | 
 | 
 | 
                      | 
 | 
                    return new PlainClient(authorizationId,  | 
 | 
                        (String) uinfo[0], (byte []) uinfo[1]);  | 
 | 
                }  | 
 | 
            }  | 
 | 
            return null;  | 
 | 
    };  | 
 | 
 | 
 | 
    public String[] getMechanismNames(Map<String,?> props) { | 
 | 
        return PolicyUtils.filterMechs(myMechs, mechPolicies, props);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private Object[] getUserInfo(String prefix, String authorizationId,  | 
 | 
        CallbackHandler cbh) throws SaslException { | 
 | 
        if (cbh == null) { | 
 | 
            throw new SaslException(  | 
 | 
                "Callback handler to get username/password required");  | 
 | 
        }  | 
 | 
        try { | 
 | 
            String userPrompt = prefix + " authentication id: ";  | 
 | 
            String passwdPrompt = prefix + " password: ";  | 
 | 
 | 
 | 
            NameCallback ncb = authorizationId == null?  | 
 | 
                new NameCallback(userPrompt) :  | 
 | 
                new NameCallback(userPrompt, authorizationId);  | 
 | 
 | 
 | 
            PasswordCallback pcb = new PasswordCallback(passwdPrompt, false);  | 
 | 
 | 
 | 
            cbh.handle(new Callback[]{ncb,pcb}); | 
 | 
 | 
 | 
            char[] pw = pcb.getPassword();  | 
 | 
 | 
 | 
            byte[] bytepw;  | 
 | 
            String authId;  | 
 | 
 | 
 | 
            if (pw != null) { | 
 | 
                bytepw = new String(pw).getBytes("UTF8"); | 
 | 
                pcb.clearPassword();  | 
 | 
            } else { | 
 | 
                bytepw = null;  | 
 | 
            }  | 
 | 
 | 
 | 
            authId = ncb.getName();  | 
 | 
 | 
 | 
            return new Object[]{authId, bytepw}; | 
 | 
 | 
 | 
        } catch (IOException e) { | 
 | 
            throw new SaslException("Cannot get password", e); | 
 | 
        } catch (UnsupportedCallbackException e) { | 
 | 
            throw new SaslException("Cannot get userid/password", e); | 
 | 
        }  | 
 | 
    }  | 
 | 
}  |