From 16ed82e6660901304b5016b9c291fde6d9aac1ab Mon Sep 17 00:00:00 2001 From: Pavel Kajaba Date: Wed, 25 Nov 2015 10:23:56 +0100 Subject: Made edits to work under latest version (1205) --- SSPIClient.patch | 268 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 SSPIClient.patch (limited to 'SSPIClient.patch') diff --git a/SSPIClient.patch b/SSPIClient.patch new file mode 100644 index 0000000..8d37658 --- /dev/null +++ b/SSPIClient.patch @@ -0,0 +1,268 @@ +diff --git a/org/postgresql/sspi/SSPIClient.java b/org/postgresql/sspi/SSPIClient.java +index 208018a..f71e8c9 100644 +--- a/org/postgresql/sspi/SSPIClient.java ++++ b/org/postgresql/sspi/SSPIClient.java +@@ -9,23 +9,8 @@ import org.postgresql.util.HostSpec; + import org.postgresql.util.PSQLException; + import org.postgresql.util.PSQLState; + +-import com.sun.jna.LastErrorException; +-import com.sun.jna.Platform; +-import com.sun.jna.platform.win32.Sspi; +-import com.sun.jna.platform.win32.Sspi.SecBufferDesc; +-import com.sun.jna.platform.win32.Win32Exception; +- +-import waffle.windows.auth.IWindowsAuthProvider; +-import waffle.windows.auth.IWindowsCredentialsHandle; +-import waffle.windows.auth.IWindowsSecurityContext; +-import waffle.windows.auth.impl.WindowsAccountImpl; +-import waffle.windows.auth.impl.WindowsAuthProviderImpl; +-import waffle.windows.auth.impl.WindowsCredentialsHandleImpl; +-import waffle.windows.auth.impl.WindowsSecurityContextImpl; +- + /** +- * Use Waffle-JNI to support SSPI authentication when PgJDBC is running on a Windows +- * client and talking to a Windows server. ++ * Empty class + * + * SSPI is not supported on a non-Windows client. + * +@@ -35,227 +20,59 @@ import waffle.windows.auth.impl.WindowsSecurityContextImpl; + */ + public class SSPIClient { + +- public static String SSPI_DEFAULT_SPN_SERVICE_CLASS = "POSTGRES"; +- +- private final Logger logger; +- private final PGStream pgStream; +- private final String spnServiceClass; +- private final boolean enableNegotiate; +- +- private IWindowsCredentialsHandle clientCredentials; +- private WindowsSecurityContextImpl sspiContext; +- private String targetName; +- +- + /** + * Instantiate an SSPIClient for authentication of a connection. + * +- * SSPIClient is not re-usable across connections. +- * +- * It is safe to instantiate SSPIClient even if Waffle and JNA are missing +- * or on non-Windows platforms, however you may not call any methods other than +- * isSSPISupported(). +- * + * @param pgStream PostgreSQL connection stream ++ * + * @param spnServiceClass SSPI SPN service class, defaults to POSTGRES if null + * @param logger + */ + public SSPIClient(PGStream pgStream, + String spnServiceClass, + boolean enableNegotiate, +- Logger logger) { +- this.logger = logger; +- this.pgStream = pgStream; +- +- /* If blank or unspecified, SPN service class should be POSTGRES */ +- String realServiceClass = spnServiceClass; +- if (spnServiceClass != null && spnServiceClass.isEmpty()) +- spnServiceClass = null; +- if (spnServiceClass == null) +- spnServiceClass = SSPI_DEFAULT_SPN_SERVICE_CLASS; +- this.spnServiceClass = spnServiceClass; +- +- /* If we're forcing Kerberos (no spnego), disable SSPI negotiation */ +- this.enableNegotiate = enableNegotiate; +- } ++ Logger logger) {} + + /** +- * Test whether we can attempt SSPI authentication. If false, ++ * Empty method, since there is no support for SSPI in Linux. If false, + * do not attempt to call any other SSPIClient methods. + * +- * @return true if it's safe to attempt SSPI authentication ++ * @return always false + */ + public boolean isSSPISupported() { +- try { +- /* +- * SSPI is windows-only. Attempt to use JNA to identify the platform. +- * If Waffle is missing we won't have JNA and this will throw a +- * NoClassDefFoundError. +- */ +- if (!Platform.isWindows()) +- { +- logger.debug("SSPI not supported: non-Windows host"); +- return false; +- } +- /* Waffle must be on the CLASSPATH */ +- Class.forName("waffle.windows.auth.impl.WindowsSecurityContextImpl"); +- return true; +- } catch (NoClassDefFoundError ex) { +- if (logger.logDebug()) +- logger.debug("SSPI unavailable (no Waffle/JNA libraries?)", ex); +- return false; +- } catch (ClassNotFoundException ex) { +- if (logger.logDebug()) +- logger.debug("SSPI unavailable (no Waffle/JNA libraries?)", ex); +- return false; +- } ++ return false; + } + +- private String makeSPN() throws PSQLException +- { +- final HostSpec hs = pgStream.getHostSpec(); +- +- try { +- return NTDSAPIWrapper.instance.DsMakeSpn( +- spnServiceClass, hs.getHost(), +- null, (short)hs.getPort(), null); +- } catch (LastErrorException ex) { +- throw new PSQLException("SSPI setup failed to determine SPN", +- PSQLState.CONNECTION_UNABLE_TO_CONNECT, ex); +- } ++ private String makeSPN() throws PSQLException{ ++ return ""; + } + + + /** +- * Respond to an authentication request from the back-end +- * for SSPI authentication (AUTH_REQ_SSPI). ++ * Not supported on Linux does nothing. + * + * @throws SQLException on SSPI authentication handshake failure + * @throws IOException on network I/O issues + */ + public void startSSPI() throws SQLException, IOException { +- +- /* +- * We usually use SSPI negotiation (spnego), but it's disabled if the client +- * asked for GSSPI and usespngo isn't explicitly turned on. +- */ +- final String securityPackage = enableNegotiate ? "negotiate" : "kerberos"; +- +- logger.debug("Beginning SSPI/Kerberos negotiation with SSPI package: " + securityPackage); +- +- try { +- /* +- * Acquire a handle for the local Windows login credentials for the current user +- * +- * See AcquireCredentialsHandle (http://msdn.microsoft.com/en-us/library/windows/desktop/aa374712%28v=vs.85%29.aspx) +- * +- * This corresponds to pg_SSPI_startup in libpq/fe-auth.c . +- */ +- try { +- clientCredentials = WindowsCredentialsHandleImpl.getCurrent(securityPackage); +- clientCredentials.initialize(); +- } catch (Win32Exception ex) { +- throw new PSQLException( +- "Could not obtain local Windows credentials for SSPI", +- PSQLState.CONNECTION_UNABLE_TO_CONNECT /* TODO: Should be authentication error */, +- ex); +- } +- +- try { +- targetName = makeSPN(); +- +- if (logger.logDebug()) +- { +- logger.debug("SSPI target name: " + targetName); +- } +- +- sspiContext = new WindowsSecurityContextImpl(); +- sspiContext.setPrincipalName(targetName); +- sspiContext.setCredentialsHandle(clientCredentials.getHandle()); +- sspiContext.setSecurityPackage(securityPackage); +- sspiContext.initialize(null, null, targetName); +- } catch (Win32Exception ex) { +- throw new PSQLException( +- "Could not initialize SSPI security context", +- PSQLState.CONNECTION_UNABLE_TO_CONNECT /* TODO: Should be auth error */, +- ex); +- } +- +- sendSSPIResponse(sspiContext.getToken()); +- logger.debug("Sent first SSPI negotiation message"); +- } catch (NoClassDefFoundError ex) { +- throw new PSQLException( +- "SSPI cannot be used, Waffle or its dependencies are missing from the classpath", +- PSQLState.NOT_IMPLEMENTED, ex); +- } + } + + /** +- * Continue an existing authentication conversation with +- * the back-end in resonse to an authentication request +- * of type AUTH_REQ_GSS_CONT. +- * ++ * Not supported on Linux does nothing. ++ * + * @param msgLength Length of message to read, excluding length word and message type word + * @throws SQLException + * @throws IOException + */ + public void continueSSPI(int msgLength) throws SQLException, IOException { +- +- if (sspiContext == null) +- throw new IllegalStateException( +- "Cannot continue SSPI authentication that we didn't begin"); +- +- logger.debug("Continuing SSPI negotiation"); +- +- /* Read the response token from the server */ +- byte[] receivedToken = pgStream.Receive(msgLength); +- +- SecBufferDesc continueToken = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, receivedToken); +- +- sspiContext.initialize(sspiContext.getHandle(), continueToken, targetName); +- +- /* +- * Now send the response token. If negotiation is complete +- * there may be zero bytes to send, in which case we shouldn't +- * send a reply as the server is not expecting one; see fe-auth.c +- * in libpq for details. +- */ +- byte[] responseToken = sspiContext.getToken(); +- if (responseToken.length > 0) +- { +- sendSSPIResponse(responseToken); +- logger.debug("Sent SSPI negotiation continuation message"); +- } else { +- logger.debug("SSPI authentication complete, no reply required"); +- } + } + + private void sendSSPIResponse(byte[] outToken) throws IOException { +- /* +- * The sspiContext now contains a token we can send to the server to +- * start the handshake. Send a 'password' message containing the +- * required data; the server knows we're doing SSPI negotiation +- * and will deal with it appropriately. +- */ +- pgStream.SendChar('p'); +- pgStream.SendInteger4(4 + outToken.length); +- pgStream.Send(outToken); +- pgStream.flush(); + } + + /** +- * Clean up native win32 resources after completion or failure of +- * SSPI authentication. This SSPIClient instance becomes unusable +- * after disposal. ++ * Not supported on Linux does nothing. + */ + public void dispose() { +- if (sspiContext != null) { +- sspiContext.dispose(); +- sspiContext = null; +- } +- if (clientCredentials != null) { +- clientCredentials.dispose(); +- clientCredentials = null; +- } + } + } -- cgit