Workaround Krb5LoginModule printing to System.out when tryFirstPass is
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / auth / SpnegoLoginModule.java
index e24e5b45b6a1f456c36753daf1e2c377c210bdf3..e5f367d23f1e77cdba3ed26fe806006e8b06a00e 100644 (file)
@@ -12,6 +12,7 @@ import org.argeo.cms.internal.runtime.CmsContextImpl;
 import org.ietf.jgss.GSSContext;
 import org.ietf.jgss.GSSException;
 import org.ietf.jgss.GSSManager;
+import org.ietf.jgss.GSSName;
 
 import com.sun.security.jgss.GSSUtil;
 
@@ -35,38 +36,33 @@ public class SpnegoLoginModule implements LoginModule {
        @Override
        public boolean login() throws LoginException {
                byte[] spnegoToken = (byte[]) sharedState.get(CmsAuthUtils.SHARED_STATE_SPNEGO_TOKEN);
-               if (spnegoToken == null)
+               if (spnegoToken == null) {
+                       if (!sharedState.containsKey(CmsAuthUtils.SHARED_STATE_NAME)) {
+                               // workaround: set shared state name to empty
+                               // in order to avoid Krb5LoginModule printing to System.out
+                               // TODO ask upstream to only log in debug mode
+                               sharedState.put(CmsAuthUtils.SHARED_STATE_NAME, "");
+                       }
                        return false;
+               }
                gssContext = checkToken(spnegoToken);
                if (gssContext == null)
                        return false;
                else {
-//                     if (!sharedState.containsKey(CmsAuthUtils.SHARED_STATE_NAME)) {
-//                             try {
-//                                     GSSName name = gssContext.getSrcName();
-//                                     String username = name.toString();
-//                                     // TODO deal with connecting service
-//                                     // TODO generate IPA DN?
-//                                     username = username.substring(0, username.lastIndexOf('@'));
-//                                     sharedState.put(CmsAuthUtils.SHARED_STATE_NAME, username);
-//                             } catch (GSSException e) {
-//                                     throw new IllegalStateException("Cannot retrieve SPNEGO name", e);
-//                             }
-//                     }
+                       if (!sharedState.containsKey(CmsAuthUtils.SHARED_STATE_NAME)) {
+                               try {
+                                       if (gssContext.getCredDelegState()) {
+                                               // commit will succeeed only if we have credential delegation
+                                               GSSName name = gssContext.getSrcName();
+                                               String username = name.toString();
+                                               sharedState.put(CmsAuthUtils.SHARED_STATE_NAME, username);
+                                       }
+                               } catch (GSSException e) {
+                                       throw new IllegalStateException("Cannot retrieve SPNEGO name", e);
+                               }
+                       }
                        return true;
                }
-               // try {
-               // String clientName = gssContext.getSrcName().toString();
-               // String role = clientName.substring(clientName.indexOf('@') + 1);
-               //
-               // log.debug("SpnegoUserRealm: established a security context");
-               // log.debug("Client Principal is: " + gssContext.getSrcName());
-               // log.debug("Server Principal is: " + gssContext.getTargName());
-               // log.debug("Client Default Role: " + role);
-               // } catch (GSSException e) {
-               // // TODO Auto-generated catch block
-               // e.printStackTrace();
-               // }
        }
 
        @Override
@@ -75,13 +71,12 @@ public class SpnegoLoginModule implements LoginModule {
                        return false;
 
                try {
-//                     Class<?> gssUtilsClass = Class.forName("com.sun.security.jgss.GSSUtil");
-//                     Method createSubjectMethod = gssUtilsClass.getMethod("createSubject", GSSName.class, GSSCredential.class);
                        Subject gssSubject;
                        if (gssContext.getCredDelegState())
                                gssSubject = (Subject) GSSUtil.createSubject(gssContext.getSrcName(), gssContext.getDelegCred());
                        else
                                gssSubject = (Subject) GSSUtil.createSubject(gssContext.getSrcName(), null);
+                       // without credential delegation we won't have access to the Kerberos key
                        subject.getPrincipals().addAll(gssSubject.getPrincipals());
                        subject.getPrivateCredentials().addAll(gssSubject.getPrivateCredentials());
                        return true;
@@ -123,7 +118,6 @@ public class SpnegoLoginModule implements LoginModule {
                GSSManager manager = GSSManager.getInstance();
                try {
                        GSSContext gContext = manager.createContext(CmsContextImpl.getCmsContext().getAcceptorCredentials());
-
                        if (gContext == null) {
                                log.debug("SpnegoUserRealm: failed to establish GSSContext");
                        } else {