Bug 5980 - If SAML Principal is the same as local username, GRAM fails
: If SAML Principal is the same as local username, GRAM fails
Status: RESOLVED FIXED
: GridShib
GT plugin
: 0.6
: Macintosh All
: P3 normal
: beta
Assigned To:
:
:
:
: 5568
  Show dependency treegraph
 
Reported: 2008-04-03 15:48 by
Modified: 2008-04-25 21:12 (History)


Attachments


Note

You need to log in before you can comment on or make changes to this bug.


Description From 2008-04-03 15:48:00
Context is using GridShibPDP (<authz
value="secctxecho:org.globus.gridshib.GridShibPDP"/>) and grid-mapfile override
(<parameter name="secctxecho-consultDefaultGridmap" value="true"/>).

If a user's local name and their SAML NameIdentifier are the same, the local
name apparently doesn't end up in the security context and and GRAM fails.

An example will help explain. On the target host, in the grid-mapfile, I have
the following. The DN shown is the DN in my SAML-decorated credential.

# grep Test /etc/grid-security/grid-mapfile 
"/C=US/O=SomeOrg/OU=User/CN=TestUser" vwelch

Now, on the client system, I create a SAML-decorated certificate with the same
username as in the grid-mapfile:
% $GRIDSHIB_HOME/bin/gridshib-saml-issuer \
    --x509 \
    --sender-vouches \
    --user vwelch \
    --outfile /tmp/x509up_u501 \
    --authn \
    --authnMethod urn:oasis:names:tc:SAML:1.0:am:password \
    --authnInstant ${DATE} \
    --address 11.22.33.44

And echo it on the target system:
% $GLOBUS_LOCATION/bin/gridshibecho -s
https://gridshib-sp.ncsa.uiuc.edu:8443/wsrf/services/SecurityContextEchoService
...snipping all but Principals...
Principal {
  name='/C=US/O=SomeOrg/OU=User/CN=TestUser'
  type='Globus'
}
Principal {
  name='vwelch'
  type='SAML'
}

We see just two Principals, one of type Globus and one of Type SAML. If I try
to use this credential with GRAM it fails (see appended for details).

Now, I create a SAML-decorated certificate with a different username:
% $GRIDSHIB_HOME/bin/gridshib-saml-issuer \
    --x509 \
    --sender-vouches \
    --user joeuser \
    --outfile /tmp/x509up_u501 \
    --authn \
    --authnMethod urn:oasis:names:tc:SAML:1.0:am:password \
    --authnInstant ${DATE} \
    --address 11.22.33.44

And echo it as before:
% $GLOBUS_LOCATION/bin/gridshibecho -s
https://gridshib-sp.ncsa.uiuc.edu:8443/wsrf/services/SecurityContextEchoService
...snipping all except Principals...
Principal {
  name='/C=US/O=SomeOrg/OU=User/CN=TestUser'
  type='Globus'
}
Principal {
  name='joeuser'
  type='SAML'
}
Principal {
  name='vwelch'
  type='UserName'
}

So now we have a third principal of type UserName and GRAM will work as
expected. Seems like the identical names seem to create destructive
interference.

For the record, here's the GRAM failure if you try to use the first credential
(with the SAML name == local user name):

% globusrun-ws -F gridshib-sp.ncsa.uiuc.edu -submit -c /bin/true
Submitting job...Failed.
globusrun-ws: Error submitting job
globus_soap_message_module: SOAP Fault
Fault code: soapenv:Server.userException
Fault string: java.rmi.RemoteException: Job creation failed.; nested exception
is: 
        java.lang.NullPointerException

And in the container logs:

  2008-04-03 14:48:07,247 ERROR factory.ManagedJobFactoryService
[ServiceThread-10,createManagedJob:346] Job creation failed.
java.lang.NullPointerException
at
org.globus.exec.service.factory.ManagedJobFactoryService.createManagedJob(ManagedJobFactoryService.java:210)
...snip...
------- Comment #1 From 2008-04-03 16:43:34 -------
Thanks for that long explanation.  Here's what's going on under the covers.

A JAAS Subject (javax.security.auth.Subject) includes a Set of Principals.  We
have three implementations of the Principal interface
(java.security.Principal):

org.globus.gsi.jaas.GlobusPrincipal
org.globus.gsi.jaas.UserNamePrincipal
org.globus.gridshib.gt.security.SAMLPrincipal

All three extend org.globus.gsi.jaas.SimplePrincipal.  

http://viewcvs.globus.org/viewcvs.cgi/jglobus/src/org/globus/gsi/jaas/?root=Java+COG

The superclass SimplePrincipal provides an equals method (because it implements
Principal), but none of the subclasses override this method.  Thus the
implementations are indistinguishable from one another.  Two Principals with
the same name can not co-exist in the Set.

The bug is actually a Globus bug.  GlobusPrincipal and UserNamePrincipal should
override the equals method of the superclass and enforce type checking.  A
GlobusPrincipal can only be equal to another GlobusPrincipal.  Same goes for
UserNamePrincipal and SAMLPrincipal.

I can fix SAMLPrincipal easy enough (I should have done this to begin with),
and we can file a bug against GlobusPrincipal and UserNamePrincipal, but you
already see what the problem is, I'm sure.  This fix won't happen anytime soon.
 We need to consider our options.

------- Comment #2 From 2008-04-03 17:07:22 -------
I've overridden the equals method in the SAMLPrincipal class:

public boolean equals(Object o) {

    if (!(o instanceof SAMLPrincipal)) {
        return false;
    }

    String name = ((SAMLPrincipal)o).getName();
    if (this.getName() == null) {
        return (this.getName() == name);
    } else {
        return this.getName().equals(name);
    }
}
------- Comment #3 From 2008-04-03 17:18:10 -------
By the way, the following is a bug in GRAM and should be reported as such.

(In reply to comment #0)
> 
> For the record, here's the GRAM failure if you try to use the first credential
> (with the SAML name == local user name):
> 
> % globusrun-ws -F gridshib-sp.ncsa.uiuc.edu -submit -c /bin/true
> Submitting job...Failed.
> globusrun-ws: Error submitting job
> globus_soap_message_module: SOAP Fault
> Fault code: soapenv:Server.userException
> Fault string: java.rmi.RemoteException: Job creation failed.; nested exception
> is: 
>         java.lang.NullPointerException
> 
> And in the container logs:
> 
>   2008-04-03 14:48:07,247 ERROR factory.ManagedJobFactoryService
> [ServiceThread-10,createManagedJob:346] Job creation failed.
> java.lang.NullPointerException
> at
> org.globus.exec.service.factory.ManagedJobFactoryService.createManagedJob(ManagedJobFactoryService.java:210)
> ...snip...
> 
------- Comment #4 From 2008-04-03 17:59:02 -------
Bug 5981 is related to this bug.
------- Comment #5 From 2008-04-03 18:59:18 -------
One approach, I suppose, is to extend org.globus.gsi.jaas.UserNamePrincipal:

package org.globus.gridshib.gt.security;
public class UserNamePrincipal extends org.globus.gsi.jaas.UserNamePrincipal;

This required minor modifications to three classes

ClassicGridShibPDPImpl
GridShibPushPDPImpl
SAMLMapPIPImpl

We could do the same to GlobusPrincipal, but the chance of a name clash in the
case of a GlobusPrincipal is pretty slim, I suspect.
------- Comment #6 From 2008-04-04 08:41:53 -------
What you've done looks reasonable to me. This would never come up before
because Globus and User names are never reasonably going to be the same string,
so this was lying in the weeds for something like a SAML name.

I agree this is a more general globus bug and I suggest just changing ownership
of the bug.

WRT comment #3, I agree and I will open a GRAM bug. 
------- Comment #7 From 2008-04-04 09:01:02 -------
(In reply to comment #3)
> By the way, the following is a bug in GRAM and should be reported as such.

Bug 5982
------- Comment #8 From 2008-04-04 12:21:40 -------
Committed the files mentioned in Comment #5 to gridshib_gt_0_6_0_branch.

Tested the patch in my sandbox and it seems to work fine.  Will leave this bug
open until Von says it works for him.
------- Comment #9 From 2008-04-06 12:57:14 -------
As a workaround to Bug 5981, we've implemented a subclass of
org.globus.gsi.jaas.UserNamePrincipal:

http://viewcvs.globus.org/viewcvs.cgi/gridshib/gt/interceptors/java/source/src/org/globus/gridshib/gt/security/UserNamePrincipal.java?view=log&pathrev=gridshib_gt_0_6_0_branch

Note the equals method:

/**
 * Instances of this class and class
 * org.globus.gsi.jaas.UserNamePrincipal
 * belong to the same equivalence class.
 */
public boolean equals(Object o) {

    if (!(o instanceof org.globus.gsi.jaas.UserNamePrincipal)) {
        return false;
    }

    String name = ((org.globus.gsi.jaas.UserNamePrincipal)o).getName();
    if (this.getName() == null) {
        return (this.getName() == name);
    } else {
        return this.getName().equals(name);
    }
}
------- Comment #10 From 2008-04-16 08:09:41 -------
(In reply to comment #8)
> 
> Will leave this bug open until Von says it works for him.

Terry Fleury has tested GRAM with GS4GT v0.6.0 RC installed on top of CTSS4
(GT4.0.5).  Works fine.  Issue resolved.