From 6f17a991407cbcc8c7dcc458fe5fa79b29a79b7e Mon Sep 17 00:00:00 2001 From: Ramesh Reddy Date: Wed, 18 Mar 2015 12:06:55 -0500 Subject: [PATCH] TEIID-3389: adding code to participate in kerberos delegation when the GSSCredential is available in the AccessContext of the subject --- .../docs/teiid/teiid-releasenotes.html | 1 + .../src/main/java/org/teiid/gss/MakeGSS.java | 84 +++++++++++++------ 2 files changed, 58 insertions(+), 27 deletions(-) diff --git a/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html b/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html index 9ec097755e..59be1c454d 100644 --- a/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html +++ b/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html @@ -27,6 +27,7 @@

Highlights

Compatibility Issues

diff --git a/client/src/main/java/org/teiid/gss/MakeGSS.java b/client/src/main/java/org/teiid/gss/MakeGSS.java index a54856e615..c9d64a7d0d 100644 --- a/client/src/main/java/org/teiid/gss/MakeGSS.java +++ b/client/src/main/java/org/teiid/gss/MakeGSS.java @@ -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; @@ -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 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; } @@ -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() { @@ -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