microsoft / mssql-jdbc

The Microsoft JDBC Driver for SQL Server is a Type 4 JDBC driver that provides database connectivity with SQL Server through the standard JDBC application program interfaces (APIs).
MIT License
1.06k stars 428 forks source link

Connection when both "Force Enryption" and "Extended Protection" are active #963

Open michaelenglert opened 5 years ago

michaelenglert commented 5 years ago

Question

I'm trying to connect to a SQL Server (2012) using Windows Authentication where both Force Enryption is set to true and Extended Protection is set to required.

What I'm getting on the Client side is:

Login failed. The login is from an untrusted domain and cannot
be used with Windows authentication.
ClientConnectionId:<redacted>

Server side:

SSPI handshake failed with error code 0x80090346, state 46 while 
establishing a connection with integrated security; the connection 
has been closed. Reason: The Channel Bindings from this client are
missing or do not match the established Transport Layer Security (TLS) 
Channel. The service might be under attack, or the data provider
or client operating system might need to be upgraded to support
Extended Protection. Closing the connection. Client's supplied SSPI
channel bindings were incorrect
[CLIENT: <redacted>]

I've tried many different configuration options (client side) including:

All results in the same error combination. OS instances are identical on Windows Sever 2012 R2 latest SP.

Any hints would be highly appreciated.

Thanks Michael

cheenamalhotra commented 5 years ago

Hi @michaelenglert

Please confirm if Client (Windows Server 2012 R2 in your case) has enabled Extended Protection support.

This blog will be worth looking into on how to enable it: https://blogs.technet.microsoft.com/srd/2009/12/08/extended-protection-for-authentication/

More details about Windows Update required for Extended Protection support: https://support.microsoft.com/en-us/help/973917/description-of-the-update-that-implements-extended-protection-for-auth

michaelenglert commented 5 years ago

Hi @cheenamalhotra,

confirmed as this is enabled by default in Windows Server 2012 R2.

cheenamalhotra commented 5 years ago

Just to put myself better on this, the error you are receiving "The login is from an untrusted domain and cannot be used with Windows authentication" is coming due to lack of configuration on client side.

From the links above, you may wanna check

Since you are working with Kerberos negotiation, it is expected to be supported by default, further configuration for LmCompatibilityLevel may not be mandatory.

On the contrary, please also confirm:

Please also provide your connection string with repro code if possible in a standalone Java class.

michaelenglert commented 5 years ago

thanks for helping @cheenamalhotra

Using this Connection String jdbc:sqlserver://192.168.56.101:1433;serverSpn=MSSQLSvc/WIN-097Q29SOILR.corp.michi.com:1433;integratedSecurity=true;authenticationScheme=JavaKerberos;trustServerCertificate=true

I've checked the Kerberos setup using the Kerberos config tool and also registered the registry key HKLM\System\CurrentControlSet\Control\LSA\SuppressExtendedProtection to 0

cheenamalhotra commented 5 years ago

Hi @michaelenglert

I hope you wanted to mention error occurs if Force Encryption is set to true and are you not passing encrypt=true in connection string?

michaelenglert commented 5 years ago

Hi @cheenamalhotra

I'm sorry. I lost track of all the different setups. Same error happens also with encrypt=true in

michaelenglert commented 5 years ago

Hi @cheenamalhotra it would be great if you have another hint for me :-)

cheenamalhotra commented 5 years ago

Hi @michaelenglert

I'll try to reproduce this in my environment, as I'm not entirely sure if this is a configuration problem or something else. Let me know if you have any pointers to problem root cause.

michaelenglert commented 5 years ago

that would be awesome @cheenamalhotra there is not much I did on the setup. Here's what I did on the Server side:

On the Client Side I tried/used:

cheenamalhotra commented 5 years ago

Thanks @michaelenglert for the details.

Out of curiosity, have you tried to connect with any of the other SQL Server drivers?

cheenamalhotra commented 5 years ago

Hi @michaelenglert

I configured Force Protocol Encryption + Extended Protection on SQL Server 2012 and am able to connect using Kerberos.

I could connect with below properties set using SQLServerDataSource.

TrustStore trustStore = new TrustStore();
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("<your server name>");
ds.setTrustStore(trustStore.getFileName());
ds.setTrustStorePassword(TrustStore.TRUST_STORE_PASSWORD);
ds.setIntegratedSecurity(true);
ds.setEncrypt(true);
try (Connection con = ds.getConnection()) {
     System.out.println("Connected");
}

Also, it works without adding ds.setAuthenticationScheme("JavaKerberos"); as default Negotiation is set to Kerberos.

cheenamalhotra commented 5 years ago

I followed same steps defined in https://blogs.technet.microsoft.com/srd/2009/12/08/extended-protection-for-authentication/ for configuring Client and Server. No extra configurations were needed.

On the contrary, if you face any problems with Certificate validation, you may try to provide "trustServerCertificate=true" in connection and can avoid setting any TrustStore.

cheenamalhotra commented 5 years ago

Ok, looks like I am able to reproduce the error now, but the issue isn't dependent on Force Encryption Turned On/Off but on Extended Protection when set to "Required" on SQL Server Instance configuration window.

Anyways, I'll investigate more into it and let you know soon!

cheenamalhotra commented 5 years ago

Hi @michaelenglert

Upon investigations I discovered that in order to work with both Extended Protection and Encryption on Connection, client needs to supply Channel Binding which is accomplished by the client transferring the SPN and the CBT to the server in a tamperproof fashion. In absence of which server will not accept any requests from client. More details can be found here.

As of now, the driver does not implement Channel Binding and thus this combination of Extended Protection + Force Encryption during connection is not supported. Turning one of them OFF will result in a successful connection, as you must have figured out too.

michaelenglert commented 5 years ago

Hi @cheenamalhotra

Thanks. I really appreciate that you took the time to investigate this!!

Does it make sense to convert this question to an enhancement request then?!

Thanks again Michael

michaelenglert commented 5 years ago

thanks @cheenamalhotra

salen2000 commented 5 years ago

Hi @cheenamalhotra I encountered the exactly problem. I don't quite understand the statement you post above, "As of now, the driver does not implement Channel Binding and thus this combination of Extended Protection + Force Encryption during connection is not supported." My question is in order to make the connection support both "Extended Protection + Force Encryption", what should I do on the client side?

thank you in advance!

rene-ye commented 5 years ago

Hi @salen2000, you can't do anything on the client side as of now. Changes to the driver are needed to make this work.

salen2000 commented 5 years ago

Hi @salen2000, you can't do anything on the client side as of now. Changes to the driver are needed to make this work.

Thanks Rene, I found some article mentioned the "Extended Protection" is only supported by "SQL Native Client" (i.e. one of the driver, that only support ODBC and OLE DB), however, because I am using JDBC (another driver) to connect to SQL server. Can I conclude, by using JDBC as of now, I cannot connect SQL Server with both "Extended Protection + Force Encryption" enabled? This is the link about SQL Native Client https://docs.microsoft.com/en-us/sql/relational-databases/native-client/sql-server-native-client?view=sql-server-2017 This is the link about Extended Protection only Support SQL Server Native Client https://docs.microsoft.com/en-us/sql/tools/configuration-manager/protocols-for-mssqlserver-properties-advanced-tab?view=sql-server-2017

cheenamalhotra commented 5 years ago

Hi @salen2000

Yes that is true for JDBC Driver, as I mentioned above as well, not with NTLM and Kerberos authentication. Other authentication modes are unaffected.

ricardoaviz commented 5 years ago

Hello cheenamalhotra, Thanks for all valuable contributions from you side on this issue.

Do we have anyone working on this issue?

This is stuck now for 8 months and I don’t see any solution or roadmap to solve this.

Is it possible to prioritize this?

Thanks! With best regards,

Ricardo Aviz Siemens

David-Engel commented 5 years ago

@ricardoaviz Adding channel binding support (and thus, extended protection support) to the JDBC driver is on our future roadmap, but we do not have a specific timeline for it at this time. I've bumped it up the list a bit and I do think it's an important security feature but we'll have to see where it makes the cut when planning future releases.

vinaykariyappa1 commented 4 years ago

com.microsoft.sqlserver.jdbc.SQLServerException: Login failed. The login is from an untrusted domain and cannot be used with Windows authentication. ClientConnectionId:dd5204e9-85ad-4625-be53-758b67062a5c at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:262)

Is this issue is resolved in any other new version of JDBC driver...

ricardoaviz commented 4 years ago

Hi Vinay,

What is your post about?

Can you please clarify your post?

Tks

vinaykariyappa1 commented 4 years ago

Jre version we are using 1.8 Jdbc we are using 7.2 jdbc:sqlserver://;servername=server_name;integratedSecurity=true; placed sqljdbc_auth.dll to C:\Program Files\Java\jre\bin and C:\Program Files\Java\jdk\bin folder. getting below error "This Driver is not configured for integrated authentication". kindly help to resolve this issue. will JDBC driver support integratedSecurity????

ulvii commented 4 years ago

Hi @vinaykariyappa1 , Driver already supports Windows integrated authentication, try setting -Djava.library.path=path_to_DLL in your VM arguments.

gstanchev commented 4 years ago

Hi, we've ran into same situation. Any expectations when channel binding support would be added to the driver?

peterbae commented 4 years ago

It's in the backlog, but we don't have plans on adding this to the driver for now. We will look into working on this in the next upcoming semester.

postfach33 commented 3 years ago

Hello @peterbae . Any updates on this issue?

postfach33 commented 3 years ago

@ricardoaviz Adding channel binding support (and thus, extended protection support) to the JDBC driver is on our future roadmap, but we do not have a specific timeline for it at this time. I've bumped it up the list a bit and I do think it's an important security feature but we'll have to see where it makes the cut when planning future releases.

Hello @David-Engel . are there any news to this topic?

David-Engel commented 3 years ago

@postfach33 There are no updates to share at this time. This issue is still in the backlog.

mariush17 commented 3 years ago

@David-Engel and @peterbae Is there any timeline to implement the channel binding feature into the JDBC driver? We are working with Java in a Linux environment and need to access SQL Server databases with Extended Protection and Forced Encryption as this is a requirement from our organization. The implementation of the channel binding feature would help us a lot!

David-Engel commented 3 years ago

@mariush17 I'm sorry, there is no current timeline for this feature in the JDBC driver.

juantarquino-ssb commented 3 years ago

@David-Engel any news on adding support for channel binding feature into the JDBC driver?

VeryVerySpicy commented 3 years ago

@juantarquino-ssb Sorry but no update as of yet.

juantarquino-ssb commented 2 years ago

Is there any workaround for using integrated authentication with servers that have those two things enabled? or an alternative driver that does support channel binding for sql server? This issue is preventing us from using Java internally to connect to sql servers because we need to use integrated authentication in Windows.

lilgreenbird commented 2 years ago

Hi @juantarquino-ssb

Channel binding support is on our radar, however unfortunately it did not make the cut for this semester, we will look will into this again when we plan for the next semester.

fyi, we do take into account user requests when we do planning, so if there is any feature you would like implemented we encourage you do fill out our survey. Thanks.

tkyc commented 2 years ago

Just an update for those following the thread, we are still in the middle of investigating this.

From my initial investigation, to enable channel bindings in the driver I applied the following fix to the intAuthHandShake to KerbAuthentication.java file:

InetAddress initiator = InetAddress.getLocalHost();
InetAddress acceptor = InetAddress.getByName(con.activeConnectionProperties
                    .getProperty(SQLServerDriverStringProperty.SERVER_NAME.toString()));

ChannelBinding cb = new ChannelBinding(initiator, acceptor, null);
peerContext.setChannelBinding(cb);

However, the above change doesn't seem to have an impact and I still receive the login error. I'll continually post updates as I investigate.

Updates (I'll post brief updates in this post to avoid spam)

Neustradamus commented 2 years ago

@ all: It is official for TLS 1.3 Binding!

Details:

Thanks in advance.

dineubr commented 2 years ago

Just an update for those following the thread, we are still in the middle of investigating this.

From my initial investigation, to enable channel bindings in the driver I applied the following fix to the intAuthHandShake to KerbAuthentication.java file:

InetAddress initiator = InetAddress.getLocalHost();
InetAddress acceptor = InetAddress.getByName(con.activeConnectionProperties
                    .getProperty(SQLServerDriverStringProperty.SERVER_NAME.toString()));

ChannelBinding cb = new ChannelBinding(initiator, acceptor, null);
peerContext.setChannelBinding(cb);

However, the above change doesn't seem to have an impact and I still receive the login error. I'll continually post updates as I investigate.

Updates (I'll post brief updates in this post to avoid spam)

  • Aug 17th 2022 - Issue is still on my radar, investigating the difference between the JDBC driver and other drivers to narrow down cause

Hi @tkyc, Would you have any updates regarding this investigation?

Regards, Dineu

Jeffery-Wasty commented 2 years ago

Hi @dineubr,

We're still working on this. Terry released an update in an edit to his most recent comment:

Updates (I'll post brief updates in this post to avoid spam)

  • Aug 17th 2022 - Issue is still on my radar, investigating the difference between the JDBC driver and other drivers to narrow down cause
tkyc commented 2 years ago

Hey all, this will be the final update on channel binding/extended protection.

Channel binding is fully implemented and is proven to be working within the JDBC driver. However, there are still a few caveats to the implementation. As of right now, we are limited by the JDK. The JDK does not provide a way to get the clientVerifyData byte array in the TLS finished message (this byte array is used to calculate the channel binding information which is passed to the server in authentication). There was a ticket/request to expose the clientVerifyData byte array in the JDK, but it was rejected. However, it is possible to get around this by using reflection or using bouncy-castle's API to get the clientVerifyData.

In the case of reflection, it is too fragile and will require more overhead on our part to maintain (eg. we'll need to test this on all driver supported JDKs and even then it might only work on a select few specific JDK versions). And, since reflection is used, we need to use the --add-opens and --add-exports flags during runtime otherwise an exception is thrown.

In the case of using the bouncy-castle API, after discussing with the team, we'll need an approval from the security team which isn't likely to happen (we had past issues getting approval to use bouncy-castle). Regardless, even if bouncy-castle was approved for use, it only solves part of the problem (exposing the clientVerifyData for use). We would still need to use the --add-exports flag at runtime to expose the internal JDK class TlsChannelBindingImpl for use (again, this is another problem with the JDK).

For now, we'll need put this feature on hold as we are limited by the JDK.

TL;DR

Channel binding is implemented and is proven to be working, but isn't likely to be merged because of JDK blockers.

Reflection is used to get clientVerifyData byte array which is used to calculate channel binding data to send to server (JDK doesn't expose clientVerifyData from the TLS finished message).

Need to use flag at runtime to import internal JDK ChannelBinding class TlsChannelBindingImpl to zero address field byte arrays. (zeroing the address field byte arrays is a channel binding implementation detail within the driver).

Wiki doc with more details about channel binding feature

martin-guth commented 1 year ago

I stumbled across this issue as well. A pity that it is now waiting on external factors. Please clarify: I have tested with the following configs at the server:

Why is Extended Protection: Allowed not possible? AFAIK this is the setting at the server side which does not enforce Extended Protection.

David-Engel commented 1 year ago

Java is missing public APIs that allow channel binding to be implemented. The POC described above was accomplished via methods that are not suitable to production-level code.

user1oc commented 10 months ago

Hi are there any updates on this issue? As per the last comment from @David-Engel and @tkyc, this feature was put on hold.

David-Engel commented 10 months ago

@user1oc No new updates. Lack of appropriate public Java APIs is still a blocker for this issue. I don't see that changing any time soon.

ecki commented 10 months ago

BTW it’s also an issue for http and ldap and really needs reconsideration on openjdk level. Maybe escalate it to the Microsoft Java team?

tkyc commented 10 months ago

@ecki Yeah, we've considered that as an option, but for now even with support from the Microsoft Java team I don't see the openjdk team consenting to the required Java API changes to make this happen as these types of changes were requested in the past.

ecki commented 10 months ago

Force Encryption: On; Extended Protection: Allowed --> Same error ...why?

@martin-guth thats indeed problematic, I suspect the SSPI on the client think it can/should negotiate it and then Java does not add the token therefore corrupting the handshake which the server uses to abort. Would maybe a good idea to filter it out in the driver so it does not get negotiated.

postfach33 commented 2 months ago

I would actually relabel the Issue from 'Enhancement' to 'Security Issue' as we are forced to downgrade the complete Instance, because if just 1 Client still can't use Channel binding nowadays, all other clients have to use the downgraded security as well.