001: // jTDS JDBC Driver for Microsoft SQL Server and Sybase
002: // Copyright (C) 2004 The jTDS Project
003: //
004: // This library is free software; you can redistribute it and/or
005: // modify it under the terms of the GNU Lesser General Public
006: // License as published by the Free Software Foundation; either
007: // version 2.1 of the License, or (at your option) any later version.
008: //
009: // This library is distributed in the hope that it will be useful,
010: // but WITHOUT ANY WARRANTY; without even the implied warranty of
011: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: // Lesser General Public License for more details.
013: //
014: // You should have received a copy of the GNU Lesser General Public
015: // License along with this library; if not, write to the Free Software
016: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: //
018: package net.sourceforge.jtds.util;
019:
020: import java.sql.SQLException;
021:
022: /**
023: * A JNI client to SSPI based CPP program (DLL) that returns the user
024: * credentials for NTLM authentication.
025: * <p/>
026: * The DLL name is ntlmauth.dll.
027: *
028: * @author Magendran Sathaiah (mahi@aztec.soft.net)
029: */
030: public class SSPIJNIClient {
031: /** Singleton instance. */
032: private static SSPIJNIClient this Instance;
033:
034: /** SSPI native library loaded flag. */
035: private static boolean libraryLoaded;
036:
037: /** SSPI client initialized flag. */
038: private boolean initialized;
039:
040: /** Initializes the SSPI client. */
041: private native void initialize();
042:
043: /** Uninitializes the SSPI client. */
044: private native void unInitialize();
045:
046: /**
047: * Prepares the NTLM TYPE-1 message and returns it as a
048: * <code>byte[]</code>.
049: */
050: private native byte[] prepareSSORequest();
051:
052: /**
053: * Prepares the NTLM TYPE-3 message using the current user's credentials.
054: * <p>
055: * It needs the challenge BLOB and it's size as input. The challenge BLOB
056: * is nothig but the TYPE-2 message that is received from the SQL Server.
057: *
058: * @param buf challenge BLOB
059: * @param size challenge BLOB size
060: * @return NTLM TYPE-3 message
061: */
062: private native byte[] prepareSSOSubmit(byte[] buf, long size);
063:
064: static {
065: try {
066: System.loadLibrary("ntlmauth");
067: SSPIJNIClient.libraryLoaded = true;
068: } catch (UnsatisfiedLinkError err) {
069: Logger.println("Unable to load library: " + err);
070: }
071: }
072:
073: /**
074: * Private constructor for singleton.
075: */
076: private SSPIJNIClient() {
077: //empty constructor
078: }
079:
080: /**
081: * Returns the singleton <code>SSPIJNIClient</code> instance.
082: *
083: * @throws SQLException if an error occurs during initialization
084: */
085: public static SSPIJNIClient getInstance() throws Exception {
086:
087: if (this Instance == null) {
088: if (!libraryLoaded) {
089: throw new Exception(
090: "Native SSPI library not loaded. "
091: + "Check the java.library.path system property.");
092: }
093: this Instance = new SSPIJNIClient();
094: this Instance.invokeInitialize();
095: }
096: return this Instance;
097: }
098:
099: /**
100: * Calls <code>#initialize()</code> if the SSPI client is not already inited.
101: */
102: public void invokeInitialize() {
103: if (!initialized) {
104: initialize();
105: initialized = true;
106: }
107: }
108:
109: /**
110: * Calls <code>#unInitialize()</code> if the SSPI client is inited.
111: */
112: public void invokeUnInitialize() {
113: if (initialized) {
114: unInitialize();
115: initialized = false;
116: }
117: }
118:
119: /**
120: * Calls <code>#prepareSSORequest()</code> to prepare the NTLM TYPE-1 message.
121: *
122: * @throws Exception if an error occurs during the call or the SSPI client
123: * is uninitialized
124: */
125: public byte[] invokePrepareSSORequest() throws Exception {
126: if (!initialized) {
127: throw new Exception("SSPI Not Initialized");
128: }
129: return prepareSSORequest();
130: }
131:
132: /**
133: * Calls <code>#prepareSSOSubmit(byte[], long)</code> to prepare the NTLM TYPE-3
134: * message.
135: *
136: * @throws Exception if an error occurs during the call or the SSPI client
137: * is uninitialized
138: */
139: public byte[] invokePrepareSSOSubmit(byte[] buf) throws Exception {
140: if (!initialized) {
141: throw new Exception("SSPI Not Initialized");
142: }
143: return prepareSSOSubmit(buf, buf.length);
144: }
145: }
|