Skip to content

Commit

Permalink
TEIID-3643: fixing odbc for vdb based gss
Browse files Browse the repository at this point in the history
Conflicts:
	runtime/src/main/java/org/teiid/transport/LogonImpl.java
  • Loading branch information
shawkins authored and jolee committed Sep 30, 2015
1 parent 0c1c82a commit cc7270c
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 48 deletions.
2 changes: 2 additions & 0 deletions build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@ <h4>from ${project.version}</h4>
</li>
<li>[<a href='https://issues.jboss.org/browse/TEIID-3640'>TEIID-3640</a>] - Improper initialization when memory buffer size is over 2 GB.
</li>
<li>[<a href='https://issues.jboss.org/browse/TEIID-3643'>TEIID-3643</a>] - VDB based kerberos authentication does not work with ODBC
</li>
</ul>

<h4>from 8.0</h4>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.teiid.dqp.internal.process.DQPCore;
import org.teiid.net.socket.AuthenticationType;
import org.teiid.security.Credentials;
import org.teiid.security.GSSResult;
import org.teiid.security.SecurityHelper;


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.dqp.service;
package org.teiid.security;

import org.ietf.jgss.GSSCredential;

Expand All @@ -29,12 +29,12 @@ public class GSSResult {
private boolean authenticated;
private Object securityContext;
private String userName;
private GSSCredential delegationCredentail;
private GSSCredential delegationCredential;

public GSSResult(byte[] token, boolean authenticated, GSSCredential cred) {
this.serviceToken = token;
this.authenticated = authenticated;
this.delegationCredentail = cred;
this.delegationCredential = cred;
}

public boolean isAuthenticated() {
Expand All @@ -61,11 +61,11 @@ public void setUserName(String name) {
this.userName = name;
}

public GSSCredential getDelegationCredentail() {
return delegationCredentail;
public GSSCredential getDelegationCredential() {
return delegationCredential;
}

public void setDelegationCredentail(GSSCredential delegationCredentail) {
this.delegationCredentail = delegationCredentail;
public void setDelegationCredential(GSSCredential delegationCredentail) {
this.delegationCredential = delegationCredentail;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@
import org.jboss.security.negotiation.Constants;
import org.jboss.security.negotiation.common.NegotiationContext;
import org.jboss.security.negotiation.spnego.KerberosMessage;
import org.teiid.dqp.service.GSSResult;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.security.Credentials;
import org.teiid.security.GSSResult;
import org.teiid.services.SessionServiceImpl;
import org.teiid.services.TeiidLoginContext;

Expand Down
17 changes: 9 additions & 8 deletions runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
import org.teiid.client.RequestMessage.ResultsMode;
import org.teiid.client.security.ILogon;
import org.teiid.client.security.LogonException;
import org.teiid.client.security.LogonResult;
import org.teiid.client.util.ResultsFuture;
import org.teiid.core.util.ApplicationInfo;
import org.teiid.core.util.StringUtil;
Expand All @@ -59,11 +58,13 @@
import org.teiid.jdbc.TeiidDriver;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.net.TeiidURL;
import org.teiid.net.socket.AuthenticationType;
import org.teiid.net.socket.SocketServerConnection;
import org.teiid.odbc.PGUtil.PgColInfo;
import org.teiid.query.parser.SQLParserUtil;
import org.teiid.runtime.RuntimePlugin;
import org.teiid.security.GSSResult;
import org.teiid.transport.LocalServerConnection;
import org.teiid.transport.LogonImpl;
import org.teiid.transport.ODBCClientInstance;
Expand Down Expand Up @@ -224,7 +225,7 @@ private AuthenticationType getAuthenticationType(String user,
public void logon(String databaseName, String user, NullTerminatedStringDataInputStream data, SocketAddress remoteAddress) {
try {
java.util.Properties info = new java.util.Properties();
info.put("user", user); //$NON-NLS-1$
info.put(TeiidURL.CONNECTION.USER_NAME, user);

AuthenticationType authType = getAuthenticationType(user, databaseName);

Expand All @@ -234,13 +235,13 @@ public void logon(String databaseName, String user, NullTerminatedStringDataInpu
}
else if (authType.equals(AuthenticationType.GSS)) {
byte[] serviceToken = data.readServiceToken();
LogonResult result = this.logon.neogitiateGssLogin(this.props, serviceToken, false);
serviceToken = (byte[])result.getProperty(ILogon.KRB5TOKEN);
if (Boolean.TRUE.equals(result.getProperty(ILogon.KRB5_ESTABLISHED))) {
GSSResult result = this.logon.neogitiateGssLogin(serviceToken, databaseName, null, user);
serviceToken = result.getServiceToken();
if (result.isAuthenticated()) {
info.put(ILogon.KRB5TOKEN, serviceToken);
// if delegation is in progress, participate in it.
if (result.getProperty(GSSCredential.class.getName()) != null) {
info.put(GSSCredential.class.getName(), result.getProperty(GSSCredential.class.getName()));
if (result.getDelegationCredential() != null) {
info.put(GSSCredential.class.getName(), result.getDelegationCredential());
}
}
else {
Expand All @@ -255,7 +256,7 @@ else if (authType.equals(AuthenticationType.GSS)) {
String url = "jdbc:teiid:"+databaseName+";ApplicationName=ODBC"; //$NON-NLS-1$ //$NON-NLS-2$

if (password != null) {
info.put("password", password); //$NON-NLS-1$
info.put(TeiidURL.CONNECTION.PASSWORD, password);
}

if (remoteAddress instanceof InetSocketAddress) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
import org.teiid.core.util.PropertiesUtils;
import org.teiid.deployers.VDBRepository;
import org.teiid.dqp.internal.process.DQPCore;
import org.teiid.dqp.service.GSSResult;
import org.teiid.dqp.service.SessionService;
import org.teiid.dqp.service.SessionServiceException;
import org.teiid.logging.LogConstants;
Expand All @@ -60,6 +59,7 @@
import org.teiid.net.socket.AuthenticationType;
import org.teiid.runtime.RuntimePlugin;
import org.teiid.security.Credentials;
import org.teiid.security.GSSResult;
import org.teiid.security.SecurityHelper;


Expand Down
74 changes: 43 additions & 31 deletions runtime/src/main/java/org/teiid/transport/LogonImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,18 @@

import org.ietf.jgss.GSSCredential;
import org.teiid.adminapi.impl.SessionMetadata;
import org.teiid.client.security.*;
import org.teiid.client.security.ILogon;
import org.teiid.client.security.InvalidSessionException;
import org.teiid.client.security.LogonException;
import org.teiid.client.security.LogonResult;
import org.teiid.client.security.SessionToken;
import org.teiid.client.util.ResultsFuture;
import org.teiid.core.CoreConstants;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.util.Base64;
import org.teiid.core.util.LRUCache;
import org.teiid.dqp.internal.process.DQPWorkContext;
import org.teiid.dqp.internal.process.DQPWorkContext.Version;
import org.teiid.dqp.service.GSSResult;
import org.teiid.dqp.service.SessionService;
import org.teiid.dqp.service.SessionServiceException;
import org.teiid.jdbc.BaseDataSource;
Expand All @@ -52,6 +55,7 @@
import org.teiid.net.TeiidURL;
import org.teiid.net.socket.AuthenticationType;
import org.teiid.runtime.RuntimePlugin;
import org.teiid.security.GSSResult;
import org.teiid.security.Credentials;
import org.teiid.security.SecurityHelper;

Expand Down Expand Up @@ -168,42 +172,50 @@ public LogonResult neogitiateGssLogin(Properties connProps, byte[] serviceTicket
throw new LogonException(RuntimePlugin.Event.TEIID40055, RuntimePlugin.Util.gs(RuntimePlugin.Event.TEIID40055, "Kerberos")); //$NON-NLS-1$
}

try {
// Using SPENGO security domain establish a token and subject.
GSSResult result = service.neogitiateGssLogin(user, vdbName, vdbVersion, serviceTicket);
if (result == null) {
throw new LogonException(RuntimePlugin.Event.TEIID40014, RuntimePlugin.Util.gs(RuntimePlugin.Event.TEIID40014));
}

// Using SPENGO security domain establish a token and subject.
GSSResult result = neogitiateGssLogin(serviceTicket, vdbName, vdbVersion, user);
if (!result.isAuthenticated() || !createSession) {
LogonResult logonResult = new LogonResult(new SessionToken(0, "temp"), "internal", 0, "internal"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
logonResult.addProperty(ILogon.KRB5TOKEN, result.getServiceToken());
logonResult.addProperty(ILogon.KRB5_ESTABLISHED, new Boolean(result.isAuthenticated()));
if (result.isAuthenticated()) {
LogManager.logDetail(LogConstants.CTX_SECURITY, "Kerberos context established"); //$NON-NLS-1$
connProps.setProperty(TeiidURL.CONNECTION.USER_NAME, result.getUserName());
this.gssServiceTickets.put(Base64.encodeBytes(MD5(result.getServiceToken())), result.getSecurityContext());
logonResult.addProperty(GSSCredential.class.getName(), result.getDelegationCredential());
}

// kerberoes (odbc) will always return here from below block
if (!result.isAuthenticated() || !createSession) {
LogonResult logonResult = new LogonResult(new SessionToken(0, "temp"), "internal", 0, "internal"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
logonResult.addProperty(ILogon.KRB5TOKEN, result.getServiceToken());
logonResult.addProperty(ILogon.KRB5_ESTABLISHED, new Boolean(result.isAuthenticated()));
if (result.isAuthenticated()) {
logonResult.addProperty(GSSCredential.class.getName(), result.getDelegationCredentail());
}
return logonResult;
}

// GSS API (jdbc) will make the session in one single call
connProps.put(ILogon.KRB5TOKEN, result.getServiceToken());
if(result.getDelegationCredentail() != null){
connProps.put(GSSCredential.class.getName(), result.getDelegationCredentail());
}
LogonResult logonResult = logon(connProps);
return logonResult;
}

// GSS API (jdbc) will make the session in one single call
connProps.setProperty(TeiidURL.CONNECTION.USER_NAME, result.getUserName());
connProps.put(ILogon.KRB5TOKEN, result.getServiceToken());
if(result.getDelegationCredential() != null){
connProps.put(GSSCredential.class.getName(), result.getDelegationCredential());
}
LogonResult logonResult = logon(connProps);
return logonResult;
}

public GSSResult neogitiateGssLogin(byte[] serviceTicket, String vdbName,
String vdbVersion, String user) throws LogonException {
GSSResult result;
try {
result = service.neogitiateGssLogin(user, vdbName, vdbVersion, serviceTicket);
} catch (LoginException e) {
throw new LogonException(RuntimePlugin.Event.TEIID40014, e, RuntimePlugin.Util.gs(RuntimePlugin.Event.TEIID40014));
throw new LogonException(RuntimePlugin.Event.TEIID40014, e, RuntimePlugin.Util.gs(RuntimePlugin.Event.TEIID40014));
}

if (result == null) {
throw new LogonException(RuntimePlugin.Event.TEIID40014, RuntimePlugin.Util.gs(RuntimePlugin.Event.TEIID40014));
}

if (result.isAuthenticated()) {
LogManager.logDetail(LogConstants.CTX_SECURITY, "Kerberos context established"); //$NON-NLS-1$
this.gssServiceTickets.put(Base64.encodeBytes(MD5(result.getServiceToken())), result.getSecurityContext());
}
return result;
}

protected static byte[] MD5(byte[] content) {
try {
java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5"); //$NON-NLS-1$
Expand Down

0 comments on commit cc7270c

Please sign in to comment.