Skip to content

Commit

Permalink
TEIID-3389: adding code to participate in kerberos delegation when th…
Browse files Browse the repository at this point in the history
…e GSSCredential is available in the AccessContext of the subject
  • Loading branch information
rareddy committed Mar 18, 2015
1 parent f32128f commit 6f17a99
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 27 deletions.
1 change: 1 addition & 0 deletions build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
Expand Up @@ -27,6 +27,7 @@ <H2><A NAME="Highlights"></A>Highlights</H2>
<ul>
<li>TEIID-3372 <b>Multiple metadata</b> - elements can now be used to configure a vdb.
<li>TEIID-3369 <b>Custom query rewrite</b> - via a configurable PreParser.
<li>TEIID-3389 <b>Kerberos Delegation</b> JDBC driver can now participate in kerberos delegation based authentication
</ul>

<h2><a name="Compatibility">Compatibility Issues</a></h2>
Expand Down
84 changes: 57 additions & 27 deletions client/src/main/java/org/teiid/gss/MakeGSS.java
Expand Up @@ -32,18 +32,17 @@

package org.teiid.gss;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;

import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.*;
import org.teiid.client.security.ILogon;
import org.teiid.client.security.LogonException;
import org.teiid.client.security.LogonResult;
Expand Down Expand Up @@ -118,33 +117,55 @@ else if ((realm != null && kdc == null) || (realm == null && kdc != null)) {
errors.append(JDBCPlugin.Util.getString("system_prop_missing", "java.security.auth.login.config")); //$NON-NLS-1$ //$NON-NLS-2$
errors.append(nl);
}

if (errors.length() > 0) {
throw new LogonException(JDBCPlugin.Event.TEIID20005, errors.toString());
}

String user = props.getProperty(TeiidURL.CONNECTION.USER_NAME);
String password = props.getProperty(TeiidURL.CONNECTION.PASSWORD);

try {
LoginContext lc = new LoginContext(jaasApplicationName, new GSSCallbackHandler(user, password));
lc.login();

Subject sub = lc.getSubject();
PrivilegedAction action = new GssAction(logon, kerberosPrincipalName, props);
String user = props.getProperty(TeiidURL.CONNECTION.USER_NAME);
String password = props.getProperty(TeiidURL.CONNECTION.PASSWORD);

boolean performAuthentication = true;
GSSCredential gssCredential = null;
Subject sub = Subject.getSubject(AccessController.getContext());
if(sub != null) {
Set<GSSCredential> gssCreds = sub.getPrivateCredentials(GSSCredential.class);
if (gssCreds != null && gssCreds.size() > 0) {
gssCredential = gssCreds.iterator().next();
performAuthentication = false;
if (logger.isLoggable(Level.FINE)) {
logger.fine("GSS Authentication using delegated credential"); //$NON-NLS-1$
}
}
else {
if (logger.isLoggable(Level.FINE)) {
logger.fine("No delegation credential found in the subject"); //$NON-NLS-1$
}
}
}

if (performAuthentication) {
if (errors.length() > 0) {
throw new LogonException(JDBCPlugin.Event.TEIID20005, errors.toString());
}

LoginContext lc = new LoginContext(jaasApplicationName, new GSSCallbackHandler(user, password));
lc.login();

sub = lc.getSubject();
}

PrivilegedAction action = new GssAction(logon, kerberosPrincipalName, props, user, gssCredential);
result = Subject.doAs(sub, action);
} catch (Exception e) {
throw new LogonException(JDBCPlugin.Event.TEIID20005, e, JDBCPlugin.Util.gs(JDBCPlugin.Event.TEIID20005));
}

if (result instanceof LogonException)
throw (LogonException)result;
else if (result instanceof TeiidComponentException)
throw (TeiidComponentException)result;
else if (result instanceof CommunicationException)
throw (CommunicationException)result;
else if (result instanceof Exception)
throw new LogonException(JDBCPlugin.Event.TEIID20005, (Exception)result, JDBCPlugin.Util.gs(JDBCPlugin.Event.TEIID20005));
if (result instanceof LogonException) {
throw (LogonException)result;
} else if (result instanceof TeiidComponentException) {
throw (TeiidComponentException)result;
} else if (result instanceof CommunicationException) {
throw (CommunicationException)result;
} else if (result instanceof Exception) {
throw new LogonException(JDBCPlugin.Event.TEIID20005, (Exception)result, JDBCPlugin.Util.gs(JDBCPlugin.Event.TEIID20005));
}

return (LogonResult)result;
}
Expand All @@ -157,11 +178,15 @@ class GssAction implements PrivilegedAction {
private final ILogon logon;
private final String kerberosPrincipalName;
private Properties props;
private GSSCredential gssCredential;
private String user;

public GssAction(ILogon pgStream, String kerberosPrincipalName, Properties props) {
public GssAction(ILogon pgStream, String kerberosPrincipalName, Properties props, String user, GSSCredential gssCredential) {
this.logon = pgStream;
this.kerberosPrincipalName = kerberosPrincipalName;
this.props = props;
this.user = user;
this.gssCredential = gssCredential;
}

public Object run() {
Expand All @@ -179,8 +204,13 @@ public Object run() {
// null on second param means the serverName is already in the native format.
//GSSName serverName = manager.createName(this.kerberosPrincipalName, null);
GSSName serverName = manager.createName(this.kerberosPrincipalName, KERBEROS_V5_PRINCIPAL_NAME);

GSSCredential clientCreds = null;
if (this.gssCredential != null) {
clientCreds = this.gssCredential;
}

GSSContext secContext = manager.createContext(serverName, desiredMechs[0], null, GSSContext.DEFAULT_LIFETIME);
GSSContext secContext = manager.createContext(serverName, desiredMechs[0], clientCreds, GSSContext.DEFAULT_LIFETIME);
secContext.requestMutualAuth(true);
secContext.requestConf(true); // Will use confidentiality later
secContext.requestInteg(true); // Will use integrity later
Expand Down

0 comments on commit 6f17a99

Please sign in to comment.