Skip to content

Commit

Permalink
Update SQLServerConnection to store password hash for NTLM (#1095)
Browse files Browse the repository at this point in the history
* update SQLServerConnection to store ntlm password hash
  • Loading branch information
lilgreenbird authored Jun 27, 2019
1 parent c34b6e3 commit 7819c9c
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 10 deletions.
20 changes: 14 additions & 6 deletions src/main/java/com/microsoft/sqlserver/jdbc/NTLMAuthentication.java
Original file line number Diff line number Diff line change
Expand Up @@ -283,15 +283,15 @@ private class NTLMContext {
* if error occurs
*/
NTLMContext(final SQLServerConnection con, final String domainName, final String userName,
final String password, final String workstation) throws SQLServerException {
final byte[] passwordHash, final String workstation) throws SQLServerException {

this.domainName = domainName.toUpperCase();
this.domainUbytes = unicode(this.domainName);

this.userNameUbytes = null != userName ? unicode(userName) : null;
this.upperUserName = null != userName ? userName.toUpperCase() : null;

this.passwordHash = null != password ? md4(unicode(password)) : null;
this.passwordHash = passwordHash;

this.workstation = workstation;

Expand Down Expand Up @@ -332,9 +332,9 @@ private class NTLMContext {
* if error occurs
*/
NTLMAuthentication(final SQLServerConnection con, final String domainName, final String userName,
final String password, final String workstation) throws SQLServerException {
final byte[] passwordHash, final String workstation) throws SQLServerException {
if (null == context) {
this.context = new NTLMContext(con, domainName, userName, password, workstation);
this.context = new NTLMContext(con, domainName, userName, passwordHash, workstation);
}
}

Expand Down Expand Up @@ -612,7 +612,7 @@ private byte[] hmacMD5(final byte[] key, final byte[] data) throws InvalidKeyExc
* input string
* @return MD4 hash
*/
private byte[] md4(final byte[] str) {
private static byte[] md4(final byte[] str) {
MD4 md = new MD4();
md.reset();
md.update(str);
Expand All @@ -626,7 +626,7 @@ private byte[] md4(final byte[] str) {
* string to convert to unicode
* @return unicode of string
*/
private byte[] unicode(final String str) {
private static byte[] unicode(final String str) {
return (null != str) ? str.getBytes(java.nio.charset.StandardCharsets.UTF_16LE) : null;
}

Expand Down Expand Up @@ -890,4 +890,12 @@ private byte[] generateNtlmNegotiate() {

return msg;
}

public static byte[] getNtlmPasswordHash(String password) throws SQLServerException {
if (null == password) {
throw new SQLServerException(SQLServerException.getErrString("R_NtlmNoUserPasswordDomain"), null);
}

return md4(unicode(password));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,8 @@ static synchronized List<String> getColumnEncryptionTrustedMasterKeyPaths(String
Properties activeConnectionProperties; // the active set of connection properties
private boolean integratedSecurity = SQLServerDriverBooleanProperty.INTEGRATED_SECURITY.getDefaultValue();
private boolean ntlmAuthentication = false;
private byte[] ntlmPasswordHash = null;

private AuthenticationScheme intAuthScheme = AuthenticationScheme.nativeAuthentication;
private GSSCredential impersonatedUserCred;
private boolean isUserCreatedCredential;
Expand Down Expand Up @@ -3691,12 +3693,16 @@ private void logon(LogonCommand command) throws SQLServerException {
currentConnectPlaceHolder.getPortNumber());
}
} else if (ntlmAuthentication) {
if (null == ntlmPasswordHash) {
ntlmPasswordHash = NTLMAuthentication.getNtlmPasswordHash(
activeConnectionProperties.getProperty(SQLServerDriverStringProperty.PASSWORD.toString()));
activeConnectionProperties.remove(SQLServerDriverStringProperty.PASSWORD.toString());
}

authentication = new NTLMAuthentication(this,
activeConnectionProperties.getProperty(SQLServerDriverStringProperty.DOMAIN.toString()),
activeConnectionProperties.getProperty(SQLServerDriverStringProperty.USER.toString()),
activeConnectionProperties.getProperty(SQLServerDriverStringProperty.PASSWORD.toString()),
hostName);
activeConnectionProperties.remove(SQLServerDriverStringProperty.PASSWORD.toString());
ntlmPasswordHash, hostName);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ private void getServerFqdn(SQLServerConnection con) {
private void sendBadToken(byte[] badField, int offset) throws SQLException {
try (SQLServerConnection con = (SQLServerConnection) PrepUtil.getConnection(connectionStringNTLM)) {
getServerFqdn(con);
SSPIAuthentication auth = new NTLMAuthentication(con, "domainName", "userName", "password", "hostname");
SSPIAuthentication auth = new NTLMAuthentication(con, "domainName", "userName", new byte[1], "hostname");
boolean[] done = {false};
byte[] badToken = getChallengeToken(offset, badField);
auth.generateClientContext(badToken, done);
Expand Down

0 comments on commit 7819c9c

Please sign in to comment.