Skip to content
Permalink
Browse files

[CONJ-378] client can provide SPN (GSSAPI)

(cherry picked from commit 4a373e6)
  • Loading branch information...
rusher committed Jan 28, 2019
1 parent e28186c commit 2a78c5cf4f099b1db6562df6ecc3117d8d310989
@@ -1,35 +1,38 @@
= Changelog
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#173|1.7.3]] Released on 09 mar. 2018
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#172|1.7.2]] Released on 20 feb. 2018
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#171|1.7.1]] Released on 22 dec. 2017
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#170|1.7.0]] Released on 08 nov. 2017
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#165|1.6.5]] Released on 24 sept. 2017
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#164|1.6.4]] Released on 05 sept. 2017
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#163|1.6.3]] Released on 29 Jul. 2017
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#162|1.6.2]] Released on 27 Jun. 2017
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#161|1.6.1]] Released on 05 Jun. 2017
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#201|2.0.1]] Released on 10 May 2017
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#160|1.6.0]] Released on 10 May 2017
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#200|2.0.0]] Released on 11 Apr. 2017
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#158|1.5.9]] Released on 09 Mar. 2017
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#158|1.5.8]] Released on 10 Fev 2017
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#157|1.5.7]] Released on 12 Jan. 2016
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#156|1.5.6]] Released on 21 Dec. 2016
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#155|1.5.5]] Released on 07 Nov. 2016
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#154|1.5.4]] Released on 10 Oct. 2016
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#153|1.5.3]] Released on 03 Oct. 2016
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#152|1.5.2]] Released on 31 aug. 2016
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#151|1.5.1]] RC released on 15 aug. 2016
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#150|1.5.0]] RC released on 28 jul. 2016
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#146|1.4.6]] Released on 13 june 2016
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#146|1.4.5]] Released on 18 mai 2016
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#144|1.4.4]] Released on 04 mai 2016
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#143|1.4.3]] Released on 22 april 2016
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#142|1.4.2]] Released on 08 april 2016
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#141|1.4.1]] Released on 07 april 2016
* [[https://github.com/MariaDB/mariadb-connector-j/documentation/changelog.creole#140|1.4.0]] Released on 31 march 2016
---
== 1.8.0

Evolutions
* [CONJ-675] permit multiple alternative authentication methods for the same user (future MariaDB 10.4 feature)
* {CONJ-678] permit indication of truststore/keystore type (JKS/PKCS12), then not relying on java default type
* [CONJ-378] GSSAPI: client can provide SPN
* [CONJ-667] Support MYSQL_TYPE_JSON datatype
* [CONJ-652] faster results buffering socket available
* [CONJ-659] improve text performance reading date/time/timestamp resultset
* [CONJ-670] ability to Refresh SSL certificate
New options
|=useReadAheadInput|use a buffered inputSteam that read socket available data. \\//Default: true//|
|=keyStoreType|indicate key store type (JKS/PKCS12). default is null, then using java default type.|
|=trustStoreType|indicate trust store type (JKS/PKCS12). default is null, then using java default type|
|=servicePrincipalName|when using GSSAPI authentication, SPN (Service Principal Name) use the server SPN information. When set, connector will use this value, ignoring server information|

Bugs
* [CONJ-646] possible NullPointerException when connection lost to database using aurora configuration with one node
* [CONJ-672] batch using multi-send can hang when using query timeout
* [CONJ-544] disable SSL session resumption when using SSL
* [CONJ-589] correcting Clob.length() for utf8mb4
* [CONJ-649] datasource connectTimeout URL parameter is not honoured
* [CONJ-650] Correction on resultset.getObject(columnName, byte[].class) when value is NULL
* [CONJ-665] old MySQL (<5.5.3) doesn't support utf8mb4, using utf8 on 3 bytes as connection charset by default
* [CONJ-671] MariaDb bulk threads occupy full cpu(99%) while db connections broken
* [CONJ-673] abording a connection while fetching a query still does read whole resultset
* [CONJ-669] SQLSyntaxErrorException when querying on empty column name
* [CONJ-674] make dumpQueriesOnException = false by default as per documentation
minor:
* [CONJ-644] small optimization when validating galera connection
* [CONJ-625] add coverage test
* [CONJ-654] DatabaseMetaData.getDriverName() returns connector/J with a lowercase c
== 1.7.4

@@ -67,6 +67,7 @@

private static final GssapiAuth gssapiAuth;
private byte[] authData;
private String optionServicePrincipalName;

static {
GssapiAuth init;
@@ -79,8 +80,9 @@
}


public SendGssApiAuthPacket(byte[] authData) {
public SendGssApiAuthPacket(byte[] authData, String servicePrincipalName) {
this.authData = authData;
this.optionServicePrincipalName = servicePrincipalName;
}

/**
@@ -96,13 +98,16 @@ public SendGssApiAuthPacket(byte[] authData) {
*/
public Buffer process(PacketOutputStream out, PacketInputStream in, AtomicInteger sequence) throws IOException, SQLException {
Buffer buffer = new Buffer(authData);
final String serverPrincipalName = buffer.readStringNullEnd(StandardCharsets.UTF_8);

//using provided connection string SPN if set, or if not, using to server information
final String servicePrincipalName = (optionServicePrincipalName != null && !optionServicePrincipalName.isEmpty())
? optionServicePrincipalName : buffer.readStringNullEnd(StandardCharsets.UTF_8);
String mechanisms = buffer.readStringNullEnd(StandardCharsets.UTF_8);
if (mechanisms.isEmpty()) {
mechanisms = "Kerberos";
}

gssapiAuth.authenticate(out, in, sequence, serverPrincipalName, mechanisms);
gssapiAuth.authenticate(out, in, sequence, servicePrincipalName, mechanisms);

buffer = in.getPacket(true);
sequence.set(in.getLastPacketSeq());
@@ -62,6 +62,6 @@
public interface GssapiAuth {

void authenticate(PacketOutputStream writer, PacketInputStream in, AtomicInteger sequence,
String serverPrincipalName, String mechanisms) throws SQLException, IOException;
String servicePrincipalName, String mechanisms) throws SQLException, IOException;

}
@@ -81,17 +81,17 @@
* @param out out stream
* @param in in stream
* @param sequence packet sequence
* @param serverPrincipalName principal name
* @param servicePrincipalName service principal name
* @param mechanisms gssapi mechanism
* @throws IOException if socket error
* @throws SQLException in any Exception occur
*/
public void authenticate(final PacketOutputStream out, final PacketInputStream in, final AtomicInteger sequence,
final String serverPrincipalName, String mechanisms) throws SQLException, IOException {
final String servicePrincipalName, String mechanisms) throws SQLException, IOException {

if ("".equals(serverPrincipalName)) {
if ("".equals(servicePrincipalName)) {
throw new SQLException("No principal name defined on server. "
+ "Please set server variable \"gssapi-principal-name\"", "28000");
+ "Please set server variable \"gssapi-principal-name\" or set option \"servicePrincipalName\"", "28000");
}

if (System.getProperty("java.security.auth.login.config") == null) {
@@ -125,7 +125,7 @@ public void authenticate(final PacketOutputStream out, final PacketInputStream i
Oid krb5Mechanism = new Oid("1.2.840.113554.1.2.2");

GSSManager manager = GSSManager.getInstance();
GSSName peerName = manager.createName(serverPrincipalName, GSSName.NT_USER_NAME);
GSSName peerName = manager.createName(servicePrincipalName, GSSName.NT_USER_NAME);
GSSContext context =
manager.createContext(peerName,
krb5Mechanism,
@@ -71,16 +71,16 @@
* @param out out stream
* @param in in stream
* @param sequence packet sequence
* @param serverPrincipalName principal name
* @param servicePrincipalName principal name
* @param mechanisms gssapi mechanism
* @throws IOException if socket error
*/
public void authenticate(final PacketOutputStream out, final PacketInputStream in, final AtomicInteger sequence,
final String serverPrincipalName, final String mechanisms) throws IOException {
final String servicePrincipalName, final String mechanisms) throws IOException {

// initialize a security context on the client
IWindowsSecurityContext clientContext = WindowsSecurityContextImpl
.getCurrent(mechanisms, serverPrincipalName);
.getCurrent(mechanisms, servicePrincipalName);

do {

@@ -97,7 +97,7 @@ public void authenticate(final PacketOutputStream out, final PacketInputStream i
byte[] tokenForTheClientOnTheServer = buffer.readRawBytes(buffer.remaining());
Sspi.SecBufferDesc continueToken = new Sspi.SecBufferDesc(Sspi.SECBUFFER_TOKEN,
tokenForTheClientOnTheServer);
clientContext.initialize(clientContext.getHandle(), continueToken, serverPrincipalName);
clientContext.initialize(clientContext.getHandle(), continueToken, servicePrincipalName);
}

} while (clientContext.isContinue());
@@ -820,7 +820,7 @@ private void authentication(byte exchangeCharset, long clientCapabilities, byte
//Authentication according to plugin.
//see AuthenticationProviderHolder for implement other plugin
authenticationPlugin = AuthenticationProviderHolder.getAuthenticationProvider()
.processAuthPlugin(plugin, password, authData, options.passwordCharacterEncoding);
.processAuthPlugin(plugin, password, authData, options);
} else {
authenticationPlugin = new OldPasswordPlugin(
this.password,
@@ -55,6 +55,7 @@
import java.sql.SQLException;

import org.mariadb.jdbc.internal.com.send.authentication.AuthenticationPlugin;
import org.mariadb.jdbc.internal.util.Options;


/**
@@ -104,7 +105,7 @@ public static void setAuthenticationProvider(AuthenticationProvider newProvider)
AuthenticationPlugin processAuthPlugin(String plugin,
String password,
byte[] authData,
String passwordCharacterEncoding)
Options options)
throws SQLException;
}

@@ -62,6 +62,7 @@
import org.mariadb.jdbc.internal.com.send.authentication.OldPasswordPlugin;
import org.mariadb.jdbc.internal.com.send.authentication.SendGssApiAuthPacket;
import org.mariadb.jdbc.internal.com.send.authentication.SendPamAuthPacket;
import org.mariadb.jdbc.internal.util.Options;

public class DefaultAuthenticationProvider {

@@ -78,26 +79,28 @@
* @param plugin plugin name
* @param password password
* @param authData auth data
* @param passwordCharacterEncoding password character encoding
* @param options connection string options
* @return authentication response according to parameters
* @throws SQLException if error occur.
*/
public static AuthenticationPlugin processAuthPlugin(String plugin, String password,
byte[] authData, String passwordCharacterEncoding)
public static AuthenticationPlugin processAuthPlugin(String plugin,
String password,
byte[] authData,
Options options)
throws SQLException {
switch (plugin) {
case MYSQL_NATIVE_PASSWORD:
return new NativePasswordPlugin(password, authData, passwordCharacterEncoding);
return new NativePasswordPlugin(password, authData, options.passwordCharacterEncoding);
case MYSQL_OLD_PASSWORD:
return new OldPasswordPlugin(password, authData);
case MYSQL_CLEAR_PASSWORD:
return new ClearPasswordPlugin(password, passwordCharacterEncoding);
return new ClearPasswordPlugin(password, options.passwordCharacterEncoding);
case DIALOG:
return new SendPamAuthPacket(password, authData, passwordCharacterEncoding);
return new SendPamAuthPacket(password, authData, options.passwordCharacterEncoding);
case GSSAPI_CLIENT:
return new SendGssApiAuthPacket(authData);
return new SendGssApiAuthPacket(authData, options.servicePrincipalName);
case MYSQL_ED25519_PASSWORD:
return new Ed25519PasswordPlugin(password, authData, passwordCharacterEncoding);
return new Ed25519PasswordPlugin(password, authData, options.passwordCharacterEncoding);

default:
throw new SQLException(
@@ -128,6 +128,7 @@
public boolean autocommit = true;
public boolean includeInnodbStatusInDeadlockExceptions;
public boolean includeThreadDumpInDeadlockExceptions;
public String servicePrincipalName;

//logging options
public boolean log;

0 comments on commit 2a78c5c

Please sign in to comment.
You can’t perform that action at this time.