com.microsoft.tfs.jni.NTLMEngine.java Source code

Java tutorial

Introduction

Here is the source code for com.microsoft.tfs.jni.NTLMEngine.java

Source

// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See License.txt in the repository root.

package com.microsoft.tfs.jni;

import java.text.MessageFormat;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.microsoft.tfs.jni.NTLM.NTLMState;
import com.microsoft.tfs.jni.internal.ntlm.JavaNTLM;
import com.microsoft.tfs.jni.internal.ntlm.NTLMException;
import com.microsoft.tfs.jni.internal.ntlm.NativeNTLM;
import com.microsoft.tfs.util.Check;

/**
 * This handles the NTLM2 authentication protocol. This class differs slightly
 * from the other JNI *Utils classes in that it does not provide a 1:1 mapping
 * between class methods and the corresponding native (or fallback) methods.
 * Instead it implements the AuthenticationEngine interface to provide a more
 * abstract and OO experience for callers.
 */
public class NTLMEngine implements AuthenticationEngine {
    private static final Log log = LogFactory.getLog(NTLMEngine.class);

    private static final NTLMEngine instance = new NTLMEngine();

    /**
     * @return the system's NegotiateEngine
     */
    public static NTLMEngine getInstance() {
        return NTLMEngine.instance;
    }

    /**
     * Can be {@link NativeNTLM} or {@link JavaNTLM}.
     */
    private final NTLM impl;

    private NTLMEngine() {
        NTLM i = null;
        try {
            if (NativeNTLM.isAvailable()) {
                i = new NativeNTLM();
            }
        } catch (final Exception e) {
            log.warn(MessageFormat.format("{0} reported itself available, but failed to load; falling back to {1}", //$NON-NLS-1$
                    NativeNTLM.class.getName(), JavaNTLM.class.getName()), e);
        }

        if (i == null) {
            i = new JavaNTLM();
        }

        impl = i;
    }

    @Override
    public boolean isAvailable() {
        // We can always use NativeNTLM or JavaNTLM.
        return true;
    }

    @Override
    public boolean supportsCredentialsDefault() {
        return impl.supportsCredentialsDefault();
    }

    @Override
    public boolean supportsCredentialsSpecified() {
        return impl.supportsCredentialsSpecified();
    }

    @Override
    public String getCredentialsDefault() {
        return impl.getCredentialsDefault();
    }

    @Override
    public AuthenticationClient newClient() throws AuthenticationException {
        return new NTLMClient();
    }

    public class NTLMClient implements AuthenticationClient {
        private final NTLMState state;

        private NTLMClient() throws NTLMException {
            state = impl.initialize();
        }

        @Override
        public void setCredentialsDefault() throws AuthenticationException {
            Check.notNull(state, "state"); //$NON-NLS-1$

            impl.setCredentialsDefault(state);
        }

        @Override
        public void setCredentialsSpecified(final String username, final String domain, final String password)
                throws AuthenticationException {
            impl.setCredentialsSpecified(state, username, domain, password);
        }

        @Override
        public void setTarget(final String target) throws AuthenticationException {
            impl.setTarget(state, target);
        }

        public void setLocalhost(final String localhost) throws AuthenticationException {
            impl.setLocalhost(state, localhost);
        }

        @Override
        public byte[] getToken(final byte[] inputToken) throws AuthenticationException {
            return impl.getToken(state, inputToken);
        }

        @Override
        public boolean isComplete() throws AuthenticationException {
            return impl.isComplete(state);
        }

        @Override
        public String getErrorMessage() {
            return impl.getErrorMessage(state);
        }

        @Override
        public void dispose() {
            try {
                impl.dispose(state);
            } catch (final Exception e) {
            }
        }
    }
}