}
String id = ((Element) config).getAttribute("id");
- if (id != null && (!(this instanceof HSNameIdentifierMapping))) {
+ if (id != null && (!id.equals("")) && (!(this instanceof HSNameIdentifierMapping))) {
log.error(
"\"id\" attribute is not valid for Name Mapping implementations that do are not used for Name Identifer Creation.");
throw new NameIdentifierMappingException("Invalid mapping information specified.");
* @author Walter Hoehn
*/
public interface IdentityProvider {
-
+ String getId();
}
* @author Walter Hoehn
*/
public interface NameIdentifierMapping {
+
+ public static final String mappingNamespace = "urn:mace:shibboleth:origin.config:1.0";
public URI getNameIdentifierFormat();
package edu.internet2.middleware.shibboleth.common;
import java.lang.reflect.Constructor;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
+import org.opensaml.SAMLNameIdentifier;
import org.w3c.dom.Element;
+import edu.internet2.middleware.shibboleth.hs.provider.SharedMemoryShibHandle;
+
/**
* @author Walter Hoehn
*/
private static Logger log = Logger.getLogger(NameMapper.class.getName());
private Map byFormat = new HashMap();
private static Map registeredMappingTypes = Collections.synchronizedMap(new HashMap());
+ protected boolean initialized = false;
static {
try {
Class.forName("edu.internet2.middleware.shibboleth.hs.provider.SharedMemoryShibHandle"));
registeredMappingTypes.put(
- "PassThruNameIdentifier",
+ "Principal",
Class.forName("edu.internet2.middleware.shibboleth.common.PrincipalNameIdentifier"));
} catch (ClassNotFoundException e) {
}
public void addNameMapping(NameIdentifierMapping mapping) {
+
+ initialized = true;
+ if (byFormat.containsKey(mapping.getNameIdentifierFormat())) {
+ log.error("Attempted to register multiple Name Mappings with the same format. Skipping duplicates...");
+ return;
+ }
byFormat.put(mapping.getNameIdentifierFormat(), mapping);
+
}
- public NameIdentifierMapping getNameIdentifierMapping(String format) {
+ public NameIdentifierMapping getNameIdentifierMapping(URI format) {
+ if (!initialized) {
+ try {
+ return new SharedMemoryShibHandle(null);
+ } catch (NameIdentifierMappingException e) {
+ return null;
+ }
+ }
return (NameIdentifierMapping) byFormat.get(format);
}
}
+ public AuthNPrincipal getPrincipal(SAMLNameIdentifier nameId, ServiceProvider sProv, IdentityProvider idProv)
+ throws NameIdentifierMappingException, InvalidNameIdentifierException {
+
+ NameIdentifierMapping mapping = null;
+ try {
+ mapping = getNameIdentifierMapping(new URI(nameId.getFormat()));
+ } catch (URISyntaxException e) {
+ log.error("Invalid Name Identifier format.");
+ }
+ if (mapping == null) {
+ throw new InvalidNameIdentifierException("Name Identifier format not registered.");
+ }
+ return mapping.getPrincipal(nameId, sProv, idProv);
+ }
+
}
{
SAMLStatement s=(SAMLStatement)is.next();
if (s instanceof SAMLAuthenticationStatement)
- return ((SAMLAuthenticationStatement)s).getSubject().getNameQualifier();
+ return ((SAMLAuthenticationStatement)s).getSubject().getName().getName();
}
}
return null;
// Examine the subject information.
SAMLSubject subject = sso.getSubject();
- if (subject.getNameQualifier() == null)
+ if (subject.getName().getName() == null)
throw new InvalidAssertionException(SAMLException.RESPONDER, "ShibPOSTProfile.accept() requires subject name qualifier");
originSite.setLength(0);
- originSite.append(subject.getNameQualifier());
+ originSite.append(subject.getName().getName());
String handleService = assertion.getIssuer();
// Is this a trusted HS?
import java.util.HashMap;
import java.util.Map;
+import org.opensaml.SAMLNameIdentifier;
+
+import edu.internet2.middleware.shibboleth.common.AuthNPrincipal;
+import edu.internet2.middleware.shibboleth.common.IdentityProvider;
+import edu.internet2.middleware.shibboleth.common.InvalidNameIdentifierException;
import edu.internet2.middleware.shibboleth.common.NameIdentifierMapping;
+import edu.internet2.middleware.shibboleth.common.NameIdentifierMappingException;
import edu.internet2.middleware.shibboleth.common.NameMapper;
+import edu.internet2.middleware.shibboleth.common.ServiceProvider;
/**
* @author Walter Hoehn
}
}
}
-
+
public HSNameIdentifierMapping getNameIdentifierMappingById(String id) {
return (HSNameIdentifierMapping) byId.get(id);
}
+
+ public SAMLNameIdentifier getNameIdentifierName(
+ String id,
+ AuthNPrincipal principal,
+ ServiceProvider sProv,
+ IdentityProvider idProv)
+ throws NameIdentifierMappingException {
+
+ HSNameIdentifierMapping mapping = getNameIdentifierMappingById(id);
+
+ if (mapping == null) {
+ throw new InvalidNameIdentifierException("Name Identifier id not registered.");
+ }
+ return mapping.getNameIdentifierName(principal, sProv, idProv);
+ }
}
+++ /dev/null
-/*
- * The Shibboleth License, Version 1.
- * Copyright (c) 2002
- * University Corporation for Advanced Internet Development, Inc.
- * All rights reserved
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution, if any, must include
- * the following acknowledgment: "This product includes software developed by
- * the University Corporation for Advanced Internet Development
- * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
- * may appear in the software itself, if and wherever such third-party
- * acknowledgments normally appear.
- *
- * Neither the name of Shibboleth nor the names of its contributors, nor
- * Internet2, nor the University Corporation for Advanced Internet Development,
- * Inc., nor UCAID may be used to endorse or promote products derived from this
- * software without specific prior written permission. For written permission,
- * please contact shibboleth@shibboleth.org
- *
- * Products derived from this software may not be called Shibboleth, Internet2,
- * UCAID, or the University Corporation for Advanced Internet Development, nor
- * may Shibboleth appear in their name, without prior written permission of the
- * University Corporation for Advanced Internet Development.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
- * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
- * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package edu.internet2.middleware.shibboleth.hs;
-
-import edu.internet2.middleware.shibboleth.common.AuthNPrincipal;
-
-/**
- * Defines a mechanism for communicating identities between the Shibboleth Handle
- * Service and Attribute Authority. Implementations must be thread-safe.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public interface HandleRepository {
-
- /**
- * Creates an opaque identifier that may be shared with target sites and subsequently
- * used in attribute requests for the given <code>AuthNPrincipal</code>.
- * @throws HandleRepositoryException if a Attribute Query Handle could not be created.
- */
- public String getHandle(AuthNPrincipal principal, StringBuffer format) throws HandleRepositoryException;
-
- /**
- * Finds the <code>AuthNPrincipal</code> associated with a given opaque identifier.
- * @throws InvalidHandleException if the specified handle is expired, unknown, or cannot
- * be resolved to a <code>AuthNPrincipal</code>
- * @throws HandleRepositoryException if the <code>HandleRepository</code> encounters an internal error
- */
- public AuthNPrincipal getPrincipal(String handle, String format) throws HandleRepositoryException, InvalidHandleException;
-
-}
+++ /dev/null
-/*
- * The Shibboleth License, Version 1.
- * Copyright (c) 2002
- * University Corporation for Advanced Internet Development, Inc.
- * All rights reserved
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution, if any, must include
- * the following acknowledgment: "This product includes software developed by
- * the University Corporation for Advanced Internet Development
- * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
- * may appear in the software itself, if and wherever such third-party
- * acknowledgments normally appear.
- *
- * Neither the name of Shibboleth nor the names of its contributors, nor
- * Internet2, nor the University Corporation for Advanced Internet Development,
- * Inc., nor UCAID may be used to endorse or promote products derived from this
- * software without specific prior written permission. For written permission,
- * please contact shibboleth@shibboleth.org
- *
- * Products derived from this software may not be called Shibboleth, Internet2,
- * UCAID, or the University Corporation for Advanced Internet Development, nor
- * may Shibboleth appear in their name, without prior written permission of the
- * University Corporation for Advanced Internet Development.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
- * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
- * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package edu.internet2.middleware.shibboleth.hs;
-
-/**
- * Indicates an error occurred while manipulating an instance of <code>HandleRepository</code>
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class HandleRepositoryException extends Exception {
-
- public HandleRepositoryException(String message) {
- super(message);
- }
-}
+++ /dev/null
-/*
- * The Shibboleth License, Version 1.
- * Copyright (c) 2002
- * University Corporation for Advanced Internet Development, Inc.
- * All rights reserved
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution, if any, must include
- * the following acknowledgment: "This product includes software developed by
- * the University Corporation for Advanced Internet Development
- * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
- * may appear in the software itself, if and wherever such third-party
- * acknowledgments normally appear.
- *
- * Neither the name of Shibboleth nor the names of its contributors, nor
- * Internet2, nor the University Corporation for Advanced Internet Development,
- * Inc., nor UCAID may be used to endorse or promote products derived from this
- * software without specific prior written permission. For written permission,
- * please contact shibboleth@shibboleth.org
- *
- * Products derived from this software may not be called Shibboleth, Internet2,
- * UCAID, or the University Corporation for Advanced Internet Development, nor
- * may Shibboleth appear in their name, without prior written permission of the
- * University Corporation for Advanced Internet Development.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
- * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
- * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package edu.internet2.middleware.shibboleth.hs;
-
-import java.lang.reflect.Constructor;
-import java.util.Properties;
-
-import org.apache.log4j.Logger;
-
-/**
- * Factory for generating instances of <code>HandleRepository</code>. Configuration
- * is delegated to the Handle Repository. Runtime options are passed to concrete constructors
- * via a <code>Properties</code> object.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-
-public class HandleRepositoryFactory {
-
- private static Logger log = Logger.getLogger(HandleRepositoryFactory.class.getName());
-
- public static HandleRepository getInstance(String className, Properties props) throws HandleRepositoryException {
- if (className == null) {
- throw new HandleRepositoryException("No Handle Repository implementation specified.");
- }
- try {
- Class implementorClass = Class.forName(className);
- Class[] params = new Class[] { Properties.class };
- Constructor implementorConstructor = implementorClass.getConstructor(params);
- Object[] args = new Object[] { props };
- log.debug("Initializing Handle Repository of type (" + implementorClass.getName() + ").");
- return (HandleRepository) implementorConstructor.newInstance(args);
-
- } catch (NoSuchMethodException nsme) {
- log.error(
- "Failed to instantiate an Handle Repository: HandleRepository "
- + "implementation must contain a constructor that accepts a Properties bundle for "
- + "configuration data.");
- throw new HandleRepositoryException("Failed to instantiate a Handle Repository.");
- } catch (Exception e) {
-
- log.error("Failed to instantiate a Handle Repository: " + e + ":" + e.getCause());
- throw new HandleRepositoryException("Failed to instantiate a Handle Repository: " + e);
-
- }
- }
-
- public static HandleRepository getInstance(Properties props) throws HandleRepositoryException {
-
- if (props.getProperty("edu.internet2.middleware.shibboleth.hs.HandleRepository.implementation") == null) {
- throw new HandleRepositoryException("No Handle Repository implementation specified.");
- }
- return getInstance(
- props.getProperty("edu.internet2.middleware.shibboleth.hs.HandleRepository.implementation"),
- props
- );
- }
-}
+++ /dev/null
-/*
- * The Shibboleth License, Version 1.
- * Copyright (c) 2002
- * University Corporation for Advanced Internet Development, Inc.
- * All rights reserved
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution, if any, must include
- * the following acknowledgment: "This product includes software developed by
- * the University Corporation for Advanced Internet Development
- * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
- * may appear in the software itself, if and wherever such third-party
- * acknowledgments normally appear.
- *
- * Neither the name of Shibboleth nor the names of its contributors, nor
- * Internet2, nor the University Corporation for Advanced Internet Development,
- * Inc., nor UCAID may be used to endorse or promote products derived from this
- * software without specific prior written permission. For written permission,
- * please contact shibboleth@shibboleth.org
- *
- * Products derived from this software may not be called Shibboleth, Internet2,
- * UCAID, or the University Corporation for Advanced Internet Development, nor
- * may Shibboleth appear in their name, without prior written permission of the
- * University Corporation for Advanced Internet Development.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
- * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
- * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package edu.internet2.middleware.shibboleth.hs;
-
-/**
- * Indicates that the<code>HandleRepository</code> could not retrieve an <code>AuthNPrincipal</code>
- * for the given handle.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class InvalidHandleException extends HandleRepositoryException {
-
- public InvalidHandleException(String message) {
- super(message);
- }
-
-}
-/*
- * The Shibboleth License, Version 1.
- * Copyright (c) 2002
- * University Corporation for Advanced Internet Development, Inc.
- * All rights reserved
+/*
+ * The Shibboleth License, Version 1. Copyright (c) 2002 University Corporation
+ * for Advanced Internet Development, Inc. All rights reserved
*
*
- * Redistribution and use in source and binary forms, with or without
+ * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
- * Redistributions of source code must retain the above copyright notice, this
+ * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution, if any, must include
- * the following acknowledgment: "This product includes software developed by
- * the University Corporation for Advanced Internet Development
- * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
- * may appear in the software itself, if and wherever such third-party
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu> Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
* acknowledgments normally appear.
*
- * Neither the name of Shibboleth nor the names of its contributors, nor
- * Internet2, nor the University Corporation for Advanced Internet Development,
- * Inc., nor UCAID may be used to endorse or promote products derived from this
- * software without specific prior written permission. For written permission,
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
* please contact shibboleth@shibboleth.org
*
- * Products derived from this software may not be called Shibboleth, Internet2,
- * UCAID, or the University Corporation for Advanced Internet Development, nor
- * may Shibboleth appear in their name, without prior written permission of the
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
* University Corporation for Advanced Internet Development.
*
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
- * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
- * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
package edu.internet2.middleware.shibboleth.hs.provider;
import java.io.Serializable;
-import java.util.Properties;
import org.apache.log4j.Logger;
+import org.w3c.dom.Element;
import edu.internet2.middleware.shibboleth.common.AuthNPrincipal;
-import edu.internet2.middleware.shibboleth.hs.HandleRepository;
-import edu.internet2.middleware.shibboleth.hs.HandleRepositoryException;
+import edu.internet2.middleware.shibboleth.common.BaseNameIdentifierMapping;
+import edu.internet2.middleware.shibboleth.common.NameIdentifierMappingException;
/**
- * <code>HandleRepository</code> shared implementation code.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
+ * @author Walter Hoehn
*/
-public abstract class BaseHandleRepository implements HandleRepository {
-
+public abstract class AQHNameIdentifierMapping extends BaseNameIdentifierMapping {
+
+ private static Logger log = Logger.getLogger(AQHNameIdentifierMapping.class.getName());
/** Time in seconds for which handles are valid */
protected long handleTTL = 1800;
- private static Logger log = Logger.getLogger(BaseHandleRepository.class.getName());
+ private String id;
+
+ public AQHNameIdentifierMapping(Element config) throws NameIdentifierMappingException {
+ super(config);
+ String id = ((Element) config).getAttribute("id");
+ if (id != null || !id.equals("")) {
+ this.id = id;
+ }
- protected BaseHandleRepository(Properties properties) throws HandleRepositoryException {
+ String rawTTL = ((Element) config).getAttribute("handleTTL");
try {
- if (properties.getProperty("edu.internet2.middleware.shibboleth.hs.BaseHandleRepository.handleTTL")
- != null) {
- handleTTL =
- Long.parseLong(
- properties.getProperty(
- "edu.internet2.middleware.shibboleth.hs.BaseHandleRepository.handleTTL",
- null));
+ if (rawTTL != null && !rawTTL.equals("")) {
+ handleTTL = Long.parseLong(rawTTL);
if (handleTTL < 30) {
log.warn(
"You have set the Attribute Query Handle \"Time To Live\' to a very low "
log.debug("Attribute Query Handle TTL set to (" + handleTTL + ") milliseconds.");
} catch (NumberFormatException nfe) {
- log.error(
- "Value for (edu.internet2.middleware.shibboleth.hs.BaseHandleRepository.handleTTL) must be a long integer.");
- throw new HandleRepositoryException("Value for (edu.internet2.middleware.shibboleth.hs.BaseHandleRepository.handleTTL) must be a long integer.");
+ log.error("Value for attribute \"handleTTL\" mus be a long integer.");
+ throw new NameIdentifierMappingException("Could not load Name Identifier Mapping with configured data.");
}
}
-
+
protected HandleEntry createHandleEntry(AuthNPrincipal principal) {
return new HandleEntry(principal, handleTTL);
}
-
-
-
+
+ public String getId() {
+ return id;
+ }
+
}
class HandleEntry implements Serializable {
/**
* Creates a HandleEntry
- * @param principal the principal represented by this entry.
- * @param TTL the time, in seconds, for which the handle should be valid.
+ *
+ * @param principal
+ * the principal represented by this entry.
+ * @param TTL
+ * the time, in seconds, for which the handle should be valid.
*/
protected HandleEntry(AuthNPrincipal principal, long TTL) {
this.principal = principal;
-/*
- * The Shibboleth License, Version 1.
- * Copyright (c) 2002
- * University Corporation for Advanced Internet Development, Inc.
- * All rights reserved
+/*
+ * The Shibboleth License, Version 1. Copyright (c) 2002 University Corporation
+ * for Advanced Internet Development, Inc. All rights reserved
*
*
- * Redistribution and use in source and binary forms, with or without
+ * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
- * Redistributions of source code must retain the above copyright notice, this
+ * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution, if any, must include
- * the following acknowledgment: "This product includes software developed by
- * the University Corporation for Advanced Internet Development
- * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
- * may appear in the software itself, if and wherever such third-party
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu> Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
* acknowledgments normally appear.
*
- * Neither the name of Shibboleth nor the names of its contributors, nor
- * Internet2, nor the University Corporation for Advanced Internet Development,
- * Inc., nor UCAID may be used to endorse or promote products derived from this
- * software without specific prior written permission. For written permission,
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
* please contact shibboleth@shibboleth.org
*
- * Products derived from this software may not be called Shibboleth, Internet2,
- * UCAID, or the University Corporation for Advanced Internet Development, nor
- * may Shibboleth appear in their name, without prior written permission of the
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
* University Corporation for Advanced Internet Development.
*
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
- * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
- * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package edu.internet2.middleware.shibboleth.hs.provider;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Arrays;
-import java.util.Properties;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.crypto.spec.IvParameterSpec;
import org.apache.log4j.Logger;
+import org.opensaml.SAMLException;
+import org.opensaml.SAMLNameIdentifier;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import edu.internet2.middleware.shibboleth.common.AuthNPrincipal;
-import edu.internet2.middleware.shibboleth.common.Constants;
+import edu.internet2.middleware.shibboleth.common.IdentityProvider;
+import edu.internet2.middleware.shibboleth.common.InvalidNameIdentifierException;
+import edu.internet2.middleware.shibboleth.common.NameIdentifierMappingException;
+import edu.internet2.middleware.shibboleth.common.ServiceProvider;
import edu.internet2.middleware.shibboleth.common.ShibResource;
-import edu.internet2.middleware.shibboleth.hs.HandleRepository;
-import edu.internet2.middleware.shibboleth.hs.HandleRepositoryException;
-import edu.internet2.middleware.shibboleth.hs.InvalidHandleException;
+import edu.internet2.middleware.shibboleth.hs.HSNameIdentifierMapping;
/**
- * <code>HandleRepository</code> implementation that employs the use of a shard secret
- * in order to transmit identity information.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
+ * @author Walter Hoehn
*/
-public class CryptoHandleRepository extends BaseHandleRepository implements HandleRepository {
+public class CryptoShibHandle extends AQHNameIdentifierMapping implements HSNameIdentifierMapping {
- private static Logger log = Logger.getLogger(CryptoHandleRepository.class.getName());
+ private static Logger log = Logger.getLogger(CryptoShibHandle.class.getName());
protected SecretKey secret;
private SecureRandom random = new SecureRandom();
-
- public CryptoHandleRepository(Properties properties) throws HandleRepositoryException {
- super(properties);
+
+ public CryptoShibHandle(Element config) throws NameIdentifierMappingException {
+ super(config);
try {
- checkRequiredParams(properties);
+ String keyStorePath = getElementConfigData(config, "KeyStorePath");
+ String keyStorePassword = getElementConfigData(config, "KeyStorePassword");
+ String keyStoreKeyAlias = getElementConfigData(config, "KeyStoreKeyAlias");
+ String keyStoreKeyPassword = getElementConfigData(config, "KeyStoreKeyPassword");
+
KeyStore keyStore = KeyStore.getInstance("JCEKS");
keyStore.load(
- new ShibResource(
- properties.getProperty(
- "edu.internet2.middleware.shibboleth.hs.provider.CryptoHandleRepository.keyStorePath"),
- this.getClass())
- .getInputStream(),
- properties
- .getProperty("edu.internet2.middleware.shibboleth.hs.provider.CryptoHandleRepository.keyStorePassword")
- .toCharArray());
- secret =
- (SecretKey) keyStore.getKey(
- properties.getProperty(
- "edu.internet2.middleware.shibboleth.hs.provider.CryptoHandleRepository.keyStoreKeyAlias"),
- properties
- .getProperty("edu.internet2.middleware.shibboleth.hs.provider.CryptoHandleRepository.keyStoreKeyPassword")
- .toCharArray());
-
- //Before we finish initilization, make sure that things are working
+ new ShibResource(keyStorePath, this.getClass()).getInputStream(),
+ keyStorePassword.toCharArray());
+ secret = (SecretKey) keyStore.getKey(keyStoreKeyAlias, keyStoreKeyPassword.toCharArray());
+
+ //Before we finish initilization, make sure that things are
+ // working
testEncryption();
if (usingDefaultSecret()) {
log.warn(
- "You are running the Crypto Handle Repository with the default secret key. This is UNSAFE! Please change "
+ "You are running Crypto AQH Name Mapping with the default secret key. This is UNSAFE! Please change "
+ "this configuration and restart the origin.");
}
} catch (KeyStoreException e) {
log.error(
- "An error occurred while loading the java keystore. Unable to initialize Crypto Handle Repository: "
- + e);
- throw new HandleRepositoryException("An error occurred while loading the java keystore. Unable to initialize Crypto Handle Repository.");
+ "An error occurred while loading the java keystore. Unable to initialize Crypto Name Mapping: " + e);
+ throw new NameIdentifierMappingException("An error occurred while loading the java keystore. Unable to initialize Crypto Name Mapping.");
} catch (CertificateException e) {
- log.error(
- "The java keystore contained corrupted data. Unable to initialize Crypto Handle Repository: " + e);
- throw new HandleRepositoryException("The java keystore contained corrupted data. Unable to initialize Crypto Handle Repository.");
+ log.error("The java keystore contained corrupted data. Unable to initialize Crypto Name Mapping: " + e);
+ throw new NameIdentifierMappingException("The java keystore contained corrupted data. Unable to initialize Crypto Name Mapping.");
} catch (NoSuchAlgorithmException e) {
log.error(
- "Appropriate JCE provider not found in the java environment. Unable to initialize Crypto Handle Repository: "
+ "Appropriate JCE provider not found in the java environment. Unable to initialize Crypto Name Mapping: "
+ e);
- throw new HandleRepositoryException("Appropriate JCE provider not found in the java environment. Unable to initialize Crypto Handle Repository.");
+ throw new NameIdentifierMappingException("Appropriate JCE provider not found in the java environment. Unable to initialize Crypto Name Mapping.");
} catch (IOException e) {
log.error(
- "An error accessing while loading the java keystore. Unable to initialize Crypto Handle Repository: "
- + e);
- throw new HandleRepositoryException("An error occurred while accessing the java keystore. Unable to initialize Crypto Handle Repository.");
+ "An error accessing while loading the java keystore. Unable to initialize Crypto Name Mapping: " + e);
+ throw new NameIdentifierMappingException("An error occurred while accessing the java keystore. Unable to initialize Crypto Name Mapping.");
} catch (UnrecoverableKeyException e) {
log.error(
"Secret could not be loaded from the java keystore. Verify that the alias and password are correct: "
+ e);
- throw new HandleRepositoryException("Secret could not be loaded from the java keystore. Verify that the alias and password are correct. ");
+ throw new NameIdentifierMappingException("Secret could not be loaded from the java keystore. Verify that the alias and password are correct. ");
}
}
- private boolean usingDefaultSecret() {
- byte[] defaultKey =
- new byte[] {
- (byte) 0xC7,
- (byte) 0x49,
- (byte) 0x80,
- (byte) 0xD3,
- (byte) 0x02,
- (byte) 0x4A,
- (byte) 0x61,
- (byte) 0xEF,
- (byte) 0x25,
- (byte) 0x5D,
- (byte) 0xE3,
- (byte) 0x2F,
- (byte) 0x57,
- (byte) 0x51,
- (byte) 0x20,
- (byte) 0x15,
- (byte) 0xC7,
- (byte) 0x49,
- (byte) 0x80,
- (byte) 0xD3,
- (byte) 0x02,
- (byte) 0x4A,
- (byte) 0x61,
- (byte) 0xEF };
- byte[] encodedKey = secret.getEncoded();
- return Arrays.equals(defaultKey, encodedKey);
- }
+ public AuthNPrincipal getPrincipal(SAMLNameIdentifier nameId, ServiceProvider sProv, IdentityProvider idProv)
+ throws NameIdentifierMappingException, InvalidNameIdentifierException {
- private void checkRequiredParams(Properties params) throws HandleRepositoryException {
- StringBuffer missingProperties = new StringBuffer();
- String[] requiredProperties =
- {
- "edu.internet2.middleware.shibboleth.hs.provider.CryptoHandleRepository.keyStorePath",
- "edu.internet2.middleware.shibboleth.hs.provider.CryptoHandleRepository.keyStorePassword",
- "edu.internet2.middleware.shibboleth.hs.provider.CryptoHandleRepository.keyStoreKeyAlias",
- "edu.internet2.middleware.shibboleth.hs.provider.CryptoHandleRepository.keyStoreKeyPassword" };
-
- for (int i = 0; i < requiredProperties.length; i++) {
- if (params.getProperty(requiredProperties[i]) == null) {
- missingProperties.append("\"");
- missingProperties.append(requiredProperties[i]);
- missingProperties.append("\" ");
+ try {
+ //Separate the IV and handle
+ byte[] in = new BASE64Decoder().decodeBuffer(nameId.getName());
+ if (in.length < 9) {
+ log.debug("Attribute Query Handle is malformed (not enough bytes).");
+ throw new InvalidNameIdentifierException("Attribute Query Handle is malformed (not enough bytes).");
}
- }
- if (missingProperties.length() > 0) {
+ byte[] iv = new byte[8];
+ System.arraycopy(in, 0, iv, 0, 8);
+ byte[] encryptedHandle = new byte[in.length - iv.length];
+ System.arraycopy(in, 8, encryptedHandle, 0, in.length - iv.length);
+
+ Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
+ IvParameterSpec ivSpec = new IvParameterSpec(iv);
+ cipher.init(Cipher.DECRYPT_MODE, secret, ivSpec);
+
+ byte[] objectArray = cipher.doFinal(encryptedHandle);
+ GZIPInputStream zipBytesIn = new GZIPInputStream(new ByteArrayInputStream(objectArray));
+
+ ObjectInputStream objectStream = new ObjectInputStream(zipBytesIn);
+
+ HMACHandleEntry handleEntry = (HMACHandleEntry) objectStream.readObject();
+ objectStream.close();
+
+ if (handleEntry.isExpired()) {
+ log.debug("Attribute Query Handle is expired.");
+ throw new InvalidNameIdentifierException("Attribute Query Handle is expired.");
+ }
+
+ Mac mac = Mac.getInstance("HmacSHA1");
+ mac.init(secret);
+ if (!handleEntry.isValid(mac)) {
+ log.warn("Attribute Query Handle failed integrity check.");
+ throw new InvalidNameIdentifierException("Attribute Query Handle failed integrity check.");
+ }
+
+ log.debug("Attribute Query Handle recognized.");
+ return handleEntry.principal;
+
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Appropriate JCE provider not found in the java environment. Could not load Algorithm: " + e);
+ throw new InvalidNameIdentifierException("Appropriate JCE provider not found in the java environment. Could not load Algorithm.");
+ } catch (NoSuchPaddingException e) {
log.error(
- "Missing configuration data. The following configuration properites are required for the Crypto Handle Repository and have not been set: "
- + missingProperties.toString());
- throw new HandleRepositoryException("Missing configuration data.");
+ "Appropriate JCE provider not found in the java environment. Could not load Padding method: " + e);
+ throw new InvalidNameIdentifierException("Appropriate JCE provider not found in the java environment. Could not load Padding method.");
+ } catch (InvalidKeyException e) {
+ log.error("Could not use the supplied secret key: " + e);
+ throw new InvalidNameIdentifierException("Could not use the supplied secret key.");
+ } catch (GeneralSecurityException e) {
+ log.warn("Unable to decrypt the supplied Attribute Query Handle: " + e);
+ throw new InvalidNameIdentifierException("Unable to decrypt the supplied Attribute Query Handle.");
+ } catch (ClassNotFoundException e) {
+ log.warn("The supplied Attribute Query Handle does not represent a serialized AuthNPrincipal: " + e);
+ throw new InvalidNameIdentifierException("The supplied Attribute Query Handle does not represent a serialized AuthNPrincipal.");
+ } catch (IOException e) {
+ log.warn("The AuthNPrincipal could not be de-serialized from the supplied Attribute Query Handle: " + e);
+ throw new InvalidNameIdentifierException("The AuthNPrincipal could not be de-serialized from the supplied Attribute Query Handle.");
}
}
- /**
- * @see edu.internet2.middleware.shibboleth.hs.HandleRepository#getHandle(Principal)
- */
- public String getHandle(AuthNPrincipal principal, StringBuffer format) throws HandleRepositoryException {
+ public SAMLNameIdentifier getNameIdentifierName(
+ AuthNPrincipal principal,
+ ServiceProvider sProv,
+ IdentityProvider idProv)
+ throws NameIdentifierMappingException {
try {
- if (principal == null || format == null) {
- log.error("A principal and format buffer must be supplied for Attribute Query Handle creation.");
- throw new IllegalArgumentException("A principal and format buffer must be supplied for Attribute Query Handle creation.");
+ if (principal == null) {
+ log.error("A principal must be supplied for Attribute Query Handle creation.");
+ throw new IllegalArgumentException("A principal must be supplied for Attribute Query Handle creation.");
}
HandleEntry handleEntry = createHandleEntry(principal);
String handle = new BASE64Encoder().encode(outStream.toByteArray());
outStream.close();
- format.setLength(0);
- format.append(Constants.SHIB_NAMEID_FORMAT_URI);
-
- return handle.replaceAll(System.getProperty("line.separator"), "");
+ try {
+ return new SAMLNameIdentifier(
+ handle.replaceAll(System.getProperty("line.separator"), ""),
+ idProv.getId(),
+ getNameIdentifierFormat().toString());
+ } catch (SAMLException e) {
+ throw new NameIdentifierMappingException("Unable to generate Attribute Query Handle: " + e);
+ }
} catch (KeyException e) {
log.error("Could not use the supplied secret key: " + e);
- throw new HandleRepositoryException("Could not use the supplied secret key.");
+ throw new NameIdentifierMappingException("Could not use the supplied secret key.");
} catch (GeneralSecurityException e) {
log.error("Appropriate JCE provider not found in the java environment. Could not load Cipher: " + e);
- throw new HandleRepositoryException("Appropriate JCE provider not found in the java environment. Could not load Cipher.");
+ throw new NameIdentifierMappingException("Appropriate JCE provider not found in the java environment. Could not load Cipher.");
} catch (IOException e) {
log.error("Could not serialize Principal for handle creation: " + e);
- throw new HandleRepositoryException("Could not serialize Principal for Attribute Query Handle creation.");
+ throw new NameIdentifierMappingException("Could not serialize Principal for Attribute Query Handle creation.");
}
}
- /**
- * @see edu.internet2.middleware.shibboleth.hs.HandleRepository#getPrincipal(String)
- */
- public AuthNPrincipal getPrincipal(String handle, String format)
- throws HandleRepositoryException, InvalidHandleException {
- if (!Constants.SHIB_NAMEID_FORMAT_URI.equals(format)) {
- log.debug(
- "This Repository does not understand handles with a format URI of "
- + (format == null ? "null" : format));
- throw new InvalidHandleException(
- "This Repository does not understand handles with a format URI of "
- + (format == null ? "null" : format));
+ private String getElementConfigData(Element e, String itemName) throws NameIdentifierMappingException {
+
+ //TODO move to namespace aware method
+ //NodeList itemElements =
+ // e.getElementsByTagNameNS(NameIdentifierMapping.mappingNamespace,
+ // itemName);
+ NodeList itemElements = e.getElementsByTagName(itemName);
+ if (itemElements.getLength() < 1) {
+ log.error(itemName + " not specified.");
+ throw new NameIdentifierMappingException(
+ "Crypto Name Mapping requires a <" + itemName + "> specification.");
}
- try {
- //Separate the IV and handle
- byte[] in = new BASE64Decoder().decodeBuffer(handle);
- if (in.length < 9) {
- log.debug("Attribute Query Handle is malformed (not enough bytes).");
- throw new InvalidHandleException("Attribute Query Handle is malformed (not enough bytes).");
- }
- byte[] iv = new byte[8];
- System.arraycopy(in, 0, iv, 0, 8);
- byte[] encryptedHandle = new byte[in.length - iv.length];
- System.arraycopy(in, 8, encryptedHandle, 0, in.length - iv.length);
-
- Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
- IvParameterSpec ivSpec = new IvParameterSpec(iv);
- cipher.init(Cipher.DECRYPT_MODE, secret, ivSpec);
-
- byte[] objectArray = cipher.doFinal(encryptedHandle);
- GZIPInputStream zipBytesIn = new GZIPInputStream(new ByteArrayInputStream(objectArray));
-
- ObjectInputStream objectStream = new ObjectInputStream(zipBytesIn);
-
- HMACHandleEntry handleEntry = (HMACHandleEntry) objectStream.readObject();
- objectStream.close();
-
- if (handleEntry.isExpired()) {
- log.debug("Attribute Query Handle is expired.");
- throw new InvalidHandleException("Attribute Query Handle is expired.");
- }
-
- Mac mac = Mac.getInstance("HmacSHA1");
- mac.init(secret);
- if (!handleEntry.isValid(mac)) {
- log.warn("Attribute Query Handle failed integrity check.");
- throw new InvalidHandleException("Attribute Query Handle failed integrity check.");
- }
-
- log.debug("Attribute Query Handle recognized.");
- return handleEntry.principal;
+ if (itemElements.getLength() > 1) {
+ log.error("Multiple " + itemName + " specifications, using first.");
+ }
- } catch (NoSuchAlgorithmException e) {
- log.error("Appropriate JCE provider not found in the java environment. Could not load Algorithm: " + e);
- throw new HandleRepositoryException("Appropriate JCE provider not found in the java environment. Could not load Algorithm.");
- } catch (NoSuchPaddingException e) {
- log.error(
- "Appropriate JCE provider not found in the java environment. Could not load Padding method: " + e);
- throw new HandleRepositoryException("Appropriate JCE provider not found in the java environment. Could not load Padding method.");
- } catch (InvalidKeyException e) {
- log.error("Could not use the supplied secret key: " + e);
- throw new HandleRepositoryException("Could not use the supplied secret key.");
- } catch (GeneralSecurityException e) {
- log.warn("Unable to decrypt the supplied Attribute Query Handle: " + e);
- throw new InvalidHandleException("Unable to decrypt the supplied Attribute Query Handle.");
- } catch (ClassNotFoundException e) {
- log.warn("The supplied Attribute Query Handle does not represent a serialized AuthNPrincipal: " + e);
- throw new InvalidHandleException("The supplied Attribute Query Handle does not represent a serialized AuthNPrincipal.");
- } catch (IOException e) {
- log.warn("The AuthNPrincipal could not be de-serialized from the supplied Attribute Query Handle: " + e);
- throw new InvalidHandleException("The AuthNPrincipal could not be de-serialized from the supplied Attribute Query Handle.");
+ Node tnode = itemElements.item(0).getFirstChild();
+ String item = null;
+ if (tnode != null && tnode.getNodeType() == Node.TEXT_NODE) {
+ item = tnode.getNodeValue();
+ }
+ if (item == null || item.equals("")) {
+ log.error(itemName + " not specified.");
+ throw new NameIdentifierMappingException(
+ "Crypto Name Mapping requires a <" + itemName + "> specification.");
}
+ return item;
}
- private void testEncryption() throws HandleRepositoryException {
+ private void testEncryption() throws NameIdentifierMappingException {
String decrypted;
try {
decrypted = new String(cipher.doFinal(cipherText));
} catch (Exception e) {
log.error("Round trip encryption/decryption test unsuccessful: " + e);
- throw new HandleRepositoryException("Round trip encryption/decryption test unsuccessful.");
+ throw new NameIdentifierMappingException("Round trip encryption/decryption test unsuccessful.");
}
if (decrypted == null || !decrypted.equals("test")) {
log.error("Round trip encryption/decryption test unsuccessful. Decrypted text did not match.");
- throw new HandleRepositoryException("Round trip encryption/decryption test unsuccessful.");
+ throw new NameIdentifierMappingException("Round trip encryption/decryption test unsuccessful.");
}
byte[] code;
} catch (Exception e) {
log.error("Message Authentication test unsuccessful: " + e);
- throw new HandleRepositoryException("Message Authentication test unsuccessful.");
+ throw new NameIdentifierMappingException("Message Authentication test unsuccessful.");
}
if (code == null) {
log.error("Message Authentication test unsuccessful.");
- throw new HandleRepositoryException("Message Authentication test unsuccessful.");
+ throw new NameIdentifierMappingException("Message Authentication test unsuccessful.");
}
}
-}
-
+ private boolean usingDefaultSecret() {
+ byte[] defaultKey =
+ new byte[] {
+ (byte) 0xC7,
+ (byte) 0x49,
+ (byte) 0x80,
+ (byte) 0xD3,
+ (byte) 0x02,
+ (byte) 0x4A,
+ (byte) 0x61,
+ (byte) 0xEF,
+ (byte) 0x25,
+ (byte) 0x5D,
+ (byte) 0xE3,
+ (byte) 0x2F,
+ (byte) 0x57,
+ (byte) 0x51,
+ (byte) 0x20,
+ (byte) 0x15,
+ (byte) 0xC7,
+ (byte) 0x49,
+ (byte) 0x80,
+ (byte) 0xD3,
+ (byte) 0x02,
+ (byte) 0x4A,
+ (byte) 0x61,
+ (byte) 0xEF };
+ byte[] encodedKey = secret.getEncoded();
+ return Arrays.equals(defaultKey, encodedKey);
+ }
+}
/**
- * <code>HandleEntry</code> extension class that performs message authentication.
- *
+ * <code>HandleEntry</code> extension class that performs message
+ * authentication.
+ *
*/
class HMACHandleEntry extends HandleEntry implements Serializable {
+++ /dev/null
-/*
- * The Shibboleth License, Version 1.
- * Copyright (c) 2002
- * University Corporation for Advanced Internet Development, Inc.
- * All rights reserved
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution, if any, must include
- * the following acknowledgment: "This product includes software developed by
- * the University Corporation for Advanced Internet Development
- * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
- * may appear in the software itself, if and wherever such third-party
- * acknowledgments normally appear.
- *
- * Neither the name of Shibboleth nor the names of its contributors, nor
- * Internet2, nor the University Corporation for Advanced Internet Development,
- * Inc., nor UCAID may be used to endorse or promote products derived from this
- * software without specific prior written permission. For written permission,
- * please contact shibboleth@shibboleth.org
- *
- * Products derived from this software may not be called Shibboleth, Internet2,
- * UCAID, or the University Corporation for Advanced Internet Development, nor
- * may Shibboleth appear in their name, without prior written permission of the
- * University Corporation for Advanced Internet Development.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
- * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
- * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package edu.internet2.middleware.shibboleth.hs.provider;
-
-import java.util.Properties;
-
-import org.apache.log4j.Logger;
-
-import edu.internet2.middleware.shibboleth.common.AuthNPrincipal;
-import edu.internet2.middleware.shibboleth.common.Constants;
-import edu.internet2.middleware.shibboleth.hs.HandleRepository;
-import edu.internet2.middleware.shibboleth.hs.HandleRepositoryException;
-import edu.internet2.middleware.shibboleth.hs.HandleRepositoryFactory;
-import edu.internet2.middleware.shibboleth.hs.InvalidHandleException;
-
-/**
- * <code>HandleRepository</code> implementation that uses principal names as handles
- *
- * @author Scott Cantor (cantor.2@osu.edu)
- */
-public class IdentityHandleRepository extends BaseHandleRepository implements HandleRepository {
-
- private static Logger log = Logger.getLogger(IdentityHandleRepository.class.getName());
-
- private String format = null;
- private HandleRepository generator = null;
-
- public IdentityHandleRepository(Properties properties) throws HandleRepositoryException {
- super(properties);
- format = properties.getProperty(
- "edu.internet2.middleware.shibboleth.hs.IdentityHandleRepository.formatURI",
- Constants.SHIB_NAMEID_FORMAT_URI
- );
- String className = properties.getProperty(
- "edu.internet2.middleware.shibboleth.hs.IdentityHandleRepository.handleGenerator",
- null
- );
- if (className != null) {
- generator = HandleRepositoryFactory.getInstance(className, properties);
- log.debug("Handle generation will be implemented by (" + className + ")");
- }
- log.debug("Attribute Query Handle TTL set to (" + handleTTL + ") milliseconds.");
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.hs.HandleRepository#getHandle(Principal)
- */
- public String getHandle(AuthNPrincipal principal, StringBuffer format) throws HandleRepositoryException {
- //Delegate handle creation?
- if (generator != null) {
- return generator.getHandle(principal, format);
- }
-
- if (principal == null || format == null) {
- log.error("A principal and format buffer must be supplied for Attribute Query Handle creation.");
- throw new IllegalArgumentException("A principal and format buffer must be supplied for Attribute Query Handle creation.");
- }
-
- format.setLength(0);
- format.append(this.format);
-
- return principal.getName();
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.hs.HandleRepository#getPrincipal(String)
- */
- public AuthNPrincipal getPrincipal(String handle, String format) throws HandleRepositoryException, InvalidHandleException {
- if (format != null && format.equals(Constants.SHIB_NAMEID_FORMAT_URI)) {
- return generator.getPrincipal(handle, format);
- }
-
- return new AuthNPrincipal(handle);
- }
-}
+++ /dev/null
-/*
- * The Shibboleth License, Version 1.
- * Copyright (c) 2002
- * University Corporation for Advanced Internet Development, Inc.
- * All rights reserved
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution, if any, must include
- * the following acknowledgment: "This product includes software developed by
- * the University Corporation for Advanced Internet Development
- * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
- * may appear in the software itself, if and wherever such third-party
- * acknowledgments normally appear.
- *
- * Neither the name of Shibboleth nor the names of its contributors, nor
- * Internet2, nor the University Corporation for Advanced Internet Development,
- * Inc., nor UCAID may be used to endorse or promote products derived from this
- * software without specific prior written permission. For written permission,
- * please contact shibboleth@shibboleth.org
- *
- * Products derived from this software may not be called Shibboleth, Internet2,
- * UCAID, or the University Corporation for Advanced Internet Development, nor
- * may Shibboleth appear in their name, without prior written permission of the
- * University Corporation for Advanced Internet Development.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
- * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
- * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package edu.internet2.middleware.shibboleth.hs.provider;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.Map.Entry;
-
-import org.apache.log4j.Logger;
-import org.doomdark.uuid.UUIDGenerator;
-
-import edu.internet2.middleware.shibboleth.common.AuthNPrincipal;
-import edu.internet2.middleware.shibboleth.common.Constants;
-import edu.internet2.middleware.shibboleth.hs.HandleRepository;
-import edu.internet2.middleware.shibboleth.hs.HandleRepositoryException;
-import edu.internet2.middleware.shibboleth.hs.InvalidHandleException;
-
-/**
- * <code>HandleRepository</code> implementation that uses a static cache. This requires
- * that the HS and AA run in the same JVM.
- *
- * @author Walter Hoehn (wassa@columbia.edu)
- */
-public class MemoryHandleRepository extends BaseHandleRepository implements HandleRepository {
-
- protected HandleCache cache = HandleCache.instance();
- private static Logger log = Logger.getLogger(MemoryHandleRepository.class.getName());
-
- public MemoryHandleRepository(Properties properties) throws HandleRepositoryException {
- super(properties);
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.hs.HandleRepository#getHandle(Principal)
- */
- public String getHandle(AuthNPrincipal principal, StringBuffer format) throws HandleRepositoryException {
-
- if (principal == null || format == null) {
- log.error("A principal and format buffer must be supplied for Attribute Query Handle creation.");
- throw new IllegalArgumentException("A principal and format buffer must be supplied for Attribute Query Handle creation.");
- }
-
- String handle = UUIDGenerator.getInstance().generateRandomBasedUUID().toString();
- log.debug("Assigning handle (" + handle + ") to principal (" + principal.getName() + ").");
- synchronized (cache.handleEntries) {
- cache.handleEntries.put(handle, createHandleEntry(principal));
- }
-
- format.setLength(0);
- format.append(Constants.SHIB_NAMEID_FORMAT_URI);
-
- return handle;
- }
-
- /**
- * @see edu.internet2.middleware.shibboleth.hs.HandleRepository#getPrincipal(String)
- */
- public AuthNPrincipal getPrincipal(String handle, String format) throws InvalidHandleException {
- if (!Constants.SHIB_NAMEID_FORMAT_URI.equals(format)) {
- log.debug("This Repository does not understand handles with a format URI of " + (format==null ? "null" : format));
- throw new InvalidHandleException("This Repository does not understand handles with a format URI of " + (format==null ? "null" : format));
- }
- synchronized (cache.handleEntries) {
- if (!cache.handleEntries.containsKey(handle)) {
- log.debug("The Repository does not contain an entry for this Attribute Query Handle.");
- throw new InvalidHandleException("The Repository does not contain an entry for this Attribute Query Handle.");
- }
- }
- HandleEntry handleEntry;
- synchronized (cache.handleEntries) {
- handleEntry = (HandleEntry) cache.handleEntries.get(handle);
- }
- if (handleEntry.isExpired()) {
- log.debug("Attribute Query Handle is expired.");
- synchronized (cache.handleEntries) {
- cache.handleEntries.remove(handle);
- }
- throw new InvalidHandleException("Attribute Query Handle is expired.");
- } else {
- log.debug("Attribute Query Handle recognized.");
- return handleEntry.principal;
- }
- }
-}
-class HandleCache {
-
- protected Map handleEntries = new HashMap();
- private static HandleCache instance;
- protected MemoryRepositoryCleaner cleaner = new MemoryRepositoryCleaner();
- private static Logger log = Logger.getLogger(HandleCache.class.getName());
-
- protected HandleCache() {
- }
-
- public static synchronized HandleCache instance() {
- if (instance == null) {
- instance = new HandleCache();
- return instance;
- }
- return instance;
- }
- /**
- * @see java.lang.Object#finalize()
- */
- protected void finalize() throws Throwable {
- super.finalize();
- synchronized (cleaner) {
- cleaner.shutdown = true;
- cleaner.interrupt();
- }
- }
-
- private class MemoryRepositoryCleaner extends Thread {
-
- private boolean shutdown = false;
-
- public MemoryRepositoryCleaner() {
- super();
- log.debug("Starting Memory Repository Cleanup Thread.");
- start();
- }
-
- public void run() {
- try {
- sleep(1 * 60 * 1000);
- } catch (InterruptedException e) {
- log.debug("Memory Repository Cleanup interrupted.");
- }
- while (true) {
- try {
- if (shutdown) {
- log.debug("Stopping Memory Repository Cleanup Thread.");
- return;
- }
- Set needsDeleting = new HashSet();
- synchronized (handleEntries) {
- Iterator iterator = handleEntries.entrySet().iterator();
- while (iterator.hasNext()) {
- Entry entry = (Entry) iterator.next();
- HandleEntry handleEntry = (HandleEntry) entry.getValue();
- if (handleEntry.isExpired()) {
- needsDeleting.add(entry.getKey());
- }
- }
- //release the lock to be friendly
- Iterator deleteIterator = needsDeleting.iterator();
- while (deleteIterator.hasNext()) {
- synchronized (handleEntries) {
- log.debug("Expiring an Attribute Query Handle from the Memory Repository.");
- handleEntries.remove(deleteIterator.next());
- }
- }
- }
- sleep(1 * 60 * 1000);
- } catch (InterruptedException e) {
- log.debug("Memory Repository Cleanup interrupted.");
- }
- }
- }
- }
-
-}
*/
package edu.internet2.middleware.shibboleth.hs.provider;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
import org.apache.log4j.Logger;
import org.doomdark.uuid.UUIDGenerator;
+import org.opensaml.SAMLException;
import org.opensaml.SAMLNameIdentifier;
import org.w3c.dom.Element;
import edu.internet2.middleware.shibboleth.common.AuthNPrincipal;
-import edu.internet2.middleware.shibboleth.common.BaseNameIdentifierMapping;
import edu.internet2.middleware.shibboleth.common.IdentityProvider;
import edu.internet2.middleware.shibboleth.common.InvalidNameIdentifierException;
import edu.internet2.middleware.shibboleth.common.NameIdentifierMappingException;
/**
* @author Walter Hoehn
*/
-public class SharedMemoryShibHandle extends BaseNameIdentifierMapping implements HSNameIdentifierMapping {
-//TODO need to move the guts of this class out of the HandleRepository implementations
- private String id;
+public class SharedMemoryShibHandle extends AQHNameIdentifierMapping implements HSNameIdentifierMapping {
+
protected HandleCache cache = HandleCache.instance();
private static Logger log = Logger.getLogger(SharedMemoryShibHandle.class.getName());
public SharedMemoryShibHandle(Element config) throws NameIdentifierMappingException {
super(config);
- String id = ((Element) config).getAttribute("id");
- if (id != null || !id.equals("")) {
- this.id = id;
- }
- }
-
- public String getId() {
- return id;
+ //If we add anything to this constructor,
}
public SAMLNameIdentifier getNameIdentifierName(
synchronized (cache.handleEntries) {
cache.handleEntries.put(handle, createHandleEntry(principal));
}
-
- return new SAMLNameIdentifier(handle, "qualifier", getNameIdentifierFormat().toString());
+
+ try {
+ return new SAMLNameIdentifier(handle, idProv.getId(), getNameIdentifierFormat().toString());
+ } catch (SAMLException e) {
+ throw new NameIdentifierMappingException("Unable to generate Attribute Query Handle: " + e);
+ }
}
}
}
+}
+
+class HandleCache {
+
+ protected Map handleEntries = new HashMap();
+ private static HandleCache instance;
+ protected MemoryRepositoryCleaner cleaner = new MemoryRepositoryCleaner();
+ private static Logger log = Logger.getLogger(HandleCache.class.getName());
+
+ protected HandleCache() {
+ }
+
+ public static synchronized HandleCache instance() {
+ if (instance == null) {
+ instance = new HandleCache();
+ return instance;
+ }
+ return instance;
+ }
+ /**
+ * @see java.lang.Object#finalize()
+ */
+ protected void finalize() throws Throwable {
+ super.finalize();
+ synchronized (cleaner) {
+ cleaner.shutdown = true;
+ cleaner.interrupt();
+ }
+ }
+
+ private class MemoryRepositoryCleaner extends Thread {
+
+ private boolean shutdown = false;
+
+ public MemoryRepositoryCleaner() {
+ super();
+ log.debug("Starting memory-based shib handle cache cleanup thread.");
+ start();
+ }
+
+ public void run() {
+ try {
+ sleep(1 * 60 * 1000);
+ } catch (InterruptedException e) {
+ log.debug("Memory-based shib handle cache cleanup interrupted.");
+ }
+ while (true) {
+ try {
+ if (shutdown) {
+ log.debug("Stopping Memory-based shib handle cache cleanup thread.");
+ return;
+ }
+ Set needsDeleting = new HashSet();
+ synchronized (handleEntries) {
+ Iterator iterator = handleEntries.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Entry entry = (Entry) iterator.next();
+ HandleEntry handleEntry = (HandleEntry) entry.getValue();
+ if (handleEntry.isExpired()) {
+ needsDeleting.add(entry.getKey());
+ }
+ }
+ //release the lock to be friendly
+ Iterator deleteIterator = needsDeleting.iterator();
+ while (deleteIterator.hasNext()) {
+ synchronized (handleEntries) {
+ log.debug("Expiring an Attribute Query Handle from the memory cache.");
+ handleEntries.remove(deleteIterator.next());
+ }
+ }
+ }
+ sleep(1 * 60 * 1000);
+ } catch (InterruptedException e) {
+ log.debug("Memory-based shib handle cache cleanup interrupted.");
+ }
+ }
+ }
+ }
}
+++ /dev/null
-/*
- * The Shibboleth License, Version 1.
- * Copyright (c) 2002
- * University Corporation for Advanced Internet Development, Inc.
- * All rights reserved
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution, if any, must include
- * the following acknowledgment: "This product includes software developed by
- * the University Corporation for Advanced Internet Development
- * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
- * may appear in the software itself, if and wherever such third-party
- * acknowledgments normally appear.
- *
- * Neither the name of Shibboleth nor the names of its contributors, nor
- * Internet2, nor the University Corporation for Advanced Internet Development,
- * Inc., nor UCAID may be used to endorse or promote products derived from this
- * software without specific prior written permission. For written permission,
- * please contact shibboleth@shibboleth.org
- *
- * Products derived from this software may not be called Shibboleth, Internet2,
- * UCAID, or the University Corporation for Advanced Internet Development, nor
- * may Shibboleth appear in their name, without prior written permission of the
- * University Corporation for Advanced Internet Development.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
- * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
- * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package edu.internet2.middleware.shibboleth.hs.provider;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.util.Date;
-import java.util.Properties;
-
-import junit.framework.TestCase;
-
-import org.apache.log4j.BasicConfigurator;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-
-import edu.internet2.middleware.shibboleth.common.AuthNPrincipal;
-import edu.internet2.middleware.shibboleth.hs.HandleRepository;
-import edu.internet2.middleware.shibboleth.hs.HandleRepositoryException;
-import edu.internet2.middleware.shibboleth.hs.HandleRepositoryFactory;
-
-/**
- * Validation suite for the <code>HandleRepository</code> implementations.
- *
- * @ author Walter Hoehn(wassa@columbia.edu)
- */
-
-public class HandleRepositoryTests extends TestCase {
-
- private static Logger log = Logger.getLogger(HandleRepositoryTests.class.getName());
-
- public HandleRepositoryTests(String name) {
- super(name);
- BasicConfigurator.resetConfiguration();
- BasicConfigurator.configure();
- Logger.getRootLogger().setLevel(Level.OFF);
- }
-
- public static void main(String[] args) {
- junit.textui.TestRunner.run(HandleRepositoryTests.class);
- BasicConfigurator.configure();
- Logger.getRootLogger().setLevel(Level.OFF);
- }
-
- /**
- * @see junit.framework.TestCase#setUp()
- */
- protected void setUp() throws Exception {
- super.setUp();
- }
-
- public void testBasicCryptoRepository() {
-
- try {
- Properties props = new Properties();
- File file = new File("data/handle.jks");
-
- props.setProperty(
- "edu.internet2.middleware.shibboleth.hs.HandleRepository.implementation",
- "edu.internet2.middleware.shibboleth.hs.provider.CryptoHandleRepository");
- props.setProperty(
- "edu.internet2.middleware.shibboleth.hs.provider.CryptoHandleRepository.keyStorePath",
- file.toURL().toString());
- props.setProperty(
- "edu.internet2.middleware.shibboleth.hs.provider.CryptoHandleRepository.keyStorePassword",
- "shibhs");
- props.setProperty(
- "edu.internet2.middleware.shibboleth.hs.provider.CryptoHandleRepository.keyStoreKeyAlias",
- "handleKey");
- props.setProperty(
- "edu.internet2.middleware.shibboleth.hs.provider.CryptoHandleRepository.keyStoreKeyPassword",
- "shibhs");
- props.setProperty("edu.internet2.middleware.shibboleth.hs.BaseHandleRepository.handleTTL", "1800");
-
- HandleRepository repository = HandleRepositoryFactory.getInstance(props);
-
- Date beforeGeneration = new Date();
- StringBuffer format = new StringBuffer();
- String handle = repository.getHandle(new AuthNPrincipal("foo"), format);
- Date afterGeneration = new Date();
-
- Date beforeMarshalling = new Date();
- AuthNPrincipal principal = repository.getPrincipal(handle, format.toString());
- assertEquals("Round-trip handle validation failed.", principal.getName(), "foo");
- Date afterMarshalling = new Date();
-
- log.debug("Before Handle Generation: " + beforeGeneration + "-" + beforeGeneration.getTime());
- log.debug("After Handle Generation: " + afterGeneration + "-" + afterGeneration.getTime());
- log.debug("Before Handle Marshalling: " + beforeMarshalling + "-" + beforeMarshalling.getTime());
- log.debug("After Handle Marshalling: " + afterMarshalling + "-" + afterMarshalling.getTime());
-
- } catch (MalformedURLException e) {
- fail("Error in test specification: " + e.getMessage());
- } catch (HandleRepositoryException e) {
- fail("Error exercising Handle Repository: " + e.getMessage());
- }
- }
-
-}
--- /dev/null
+/*
+ * The Shibboleth License, Version 1. Copyright (c) 2002 University Corporation
+ * for Advanced Internet Development, Inc. All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution, if any, must include
+ * the following acknowledgment: "This product includes software developed by
+ * the University Corporation for Advanced Internet Development
+ * <http://www.ucaid.edu> Internet2 Project. Alternately, this acknowledegement
+ * may appear in the software itself, if and wherever such third-party
+ * acknowledgments normally appear.
+ *
+ * Neither the name of Shibboleth nor the names of its contributors, nor
+ * Internet2, nor the University Corporation for Advanced Internet Development,
+ * Inc., nor UCAID may be used to endorse or promote products derived from this
+ * software without specific prior written permission. For written permission,
+ * please contact shibboleth@shibboleth.org
+ *
+ * Products derived from this software may not be called Shibboleth, Internet2,
+ * UCAID, or the University Corporation for Advanced Internet Development, nor
+ * may Shibboleth appear in their name, without prior written permission of the
+ * University Corporation for Advanced Internet Development.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
+ * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
+ * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package edu.internet2.middleware.shibboleth.hs.provider;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.net.MalformedURLException;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.apache.xerces.parsers.DOMParser;
+import org.opensaml.SAMLNameIdentifier;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import edu.internet2.middleware.shibboleth.common.AuthNPrincipal;
+import edu.internet2.middleware.shibboleth.common.IdentityProvider;
+import edu.internet2.middleware.shibboleth.common.NameIdentifierMappingException;
+import edu.internet2.middleware.shibboleth.common.NameMapper;
+import edu.internet2.middleware.shibboleth.common.ServiceProvider;
+import edu.internet2.middleware.shibboleth.hs.HSNameMapper;
+
+/**
+ * Validation suite for the <code>NameMapper</code>.
+ *
+ * @author Walter Hoehn(wassa@columbia.edu)
+ */
+
+public class NameMapperTests extends TestCase {
+
+ private static Logger log = Logger.getLogger(NameMapperTests.class.getName());
+ private DOMParser parser = new DOMParser();
+
+ public NameMapperTests(String name) {
+ super(name);
+ BasicConfigurator.resetConfiguration();
+ BasicConfigurator.configure();
+ Logger.getRootLogger().setLevel(Level.DEBUG);
+ }
+
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(NameMapperTests.class);
+ BasicConfigurator.configure();
+ Logger.getRootLogger().setLevel(Level.DEBUG);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ try {
+
+ //TODO turn on validation
+ parser.setFeature("http://xml.org/sax/features/validation", false);
+ parser.setFeature("http://apache.org/xml/features/validation/schema", false);
+ parser.setEntityResolver(new EntityResolver() {
+ public InputSource resolveEntity(String publicId, String systemId) throws SAXException {
+
+ if (systemId.endsWith("shibboleth-arp-1.0.xsd")) {
+ InputStream stream;
+ try {
+ stream = new FileInputStream("src/schemas/shibboleth-arp-1.0.xsd");
+ if (stream != null) {
+ return new InputSource(stream);
+ }
+ throw new SAXException("Could not load entity: Null input stream");
+ } catch (FileNotFoundException e) {
+ throw new SAXException("Could not load entity: " + e);
+ }
+ } else {
+ return null;
+ }
+ }
+ });
+
+ parser.setErrorHandler(new ErrorHandler() {
+ public void error(SAXParseException arg0) throws SAXException {
+ throw new SAXException("Error parsing xml file: " + arg0);
+ }
+ public void fatalError(SAXParseException arg0) throws SAXException {
+ throw new SAXException("Error parsing xml file: " + arg0);
+ }
+ public void warning(SAXParseException arg0) throws SAXException {
+ throw new SAXException("Error parsing xml file: " + arg0);
+ }
+ });
+ } catch (Exception e) {
+ fail("Failed to setup xml parser: " + e);
+ }
+ }
+ public void testCryptoMapping() {
+
+ try {
+
+ HSNameMapper nameMapper = new HSNameMapper();
+
+ File file = new File("data/handle.jks");
+
+ String rawConfig =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<NameMapping id=\"cryptotest\" format=\"urn:mace:shibboleth:1.0:nameIdentifier\""
+ + " type=\"CryptoHandleGenerator\" handleTTL=\"1800\">"
+ + " <KeyStorePath>"
+ + file.toURL().toString()
+ + "</KeyStorePath>"
+ + " <KeyStorePassword>shibhs</KeyStorePassword>"
+ + " <KeyStoreKeyAlias>handlekey</KeyStoreKeyAlias>"
+ + " <KeyStoreKeyPassword>shibhs</KeyStoreKeyPassword>"
+ + " </NameMapping>";
+
+ parser.parse(new InputSource(new StringReader(rawConfig)));
+ nameMapper.addNameMapping(parser.getDocument().getDocumentElement());
+
+ SAMLNameIdentifier nameId =
+ nameMapper.getNameIdentifierName("cryptotest", new AuthNPrincipal("testprincipal"), null, null);
+
+ AuthNPrincipal principal = nameMapper.getPrincipal(nameId, null, null);
+ assertEquals("Round-trip handle validation failed.", principal.getName(), "testprincipal");
+
+ } catch (MalformedURLException e) {
+ fail("Error in test specification: " + e.getMessage());
+ } catch (NameIdentifierMappingException e) {
+ fail("Error exercising NameMaper: " + e.getMessage());
+ } catch (Exception e) {
+ fail("Error exercising NameMaper: " + e.getMessage());
+ }
+
+ }
+ public void testDefaultConfig() {
+
+ try {
+
+ HSNameMapper nameMapper = new HSNameMapper();
+/*
+ String rawConfig =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<NameMapping id=\"memorytest\" format=\"urn:mace:shibboleth:1.0:nameIdentifier\""
+ + " type=\"SharedMemoryShibHandle\" handleTTL=\"1800\"/>";
+*/
+ //parser.parse(new InputSource(new StringReader(rawConfig)));
+ //nameMapper.addNameMapping(parser.getDocument().getDocumentElement());
+
+ //TODO fix
+ SAMLNameIdentifier nameId =
+ nameMapper.getNameIdentifierName(
+ "",
+ new AuthNPrincipal("testprincipal"),
+ new BasicServiceProvider(),
+ new BasicIdentityProvider("urn-x:testid"));
+
+ AuthNPrincipal principal =
+ nameMapper.getPrincipal(nameId, new BasicServiceProvider(), new BasicIdentityProvider("urn-x:testid"));
+
+ assertEquals("Round-trip handle validation failed.", principal.getName(), "testprincipal");
+
+ } catch (NameIdentifierMappingException e) {
+ fail("Error exercising NameMaper: " + e.getMessage());
+ } catch (Exception e) {
+ fail("Error exercising NameMaper: " + e.getMessage());
+ }
+ }
+ public void testMemoryMapping() {
+
+ try {
+
+ HSNameMapper nameMapper = new HSNameMapper();
+
+ String rawConfig =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<NameMapping id=\"memorytest\" format=\"urn:mace:shibboleth:1.0:nameIdentifier\""
+ + " type=\"SharedMemoryShibHandle\" handleTTL=\"1800\"/>";
+
+ parser.parse(new InputSource(new StringReader(rawConfig)));
+ nameMapper.addNameMapping(parser.getDocument().getDocumentElement());
+
+ SAMLNameIdentifier nameId =
+ nameMapper.getNameIdentifierName(
+ "memorytest",
+ new AuthNPrincipal("testprincipal"),
+ new BasicServiceProvider(),
+ new BasicIdentityProvider("urn-x:testid"));
+
+ AuthNPrincipal principal =
+ nameMapper.getPrincipal(nameId, new BasicServiceProvider(), new BasicIdentityProvider("urn-x:testid"));
+
+ assertEquals("Round-trip handle validation failed.", principal.getName(), "testprincipal");
+
+ } catch (MalformedURLException e) {
+ fail("Error in test specification: " + e.getMessage());
+ } catch (NameIdentifierMappingException e) {
+ fail("Error exercising NameMaper: " + e.getMessage());
+ } catch (Exception e) {
+ fail("Error exercising NameMaper: " + e.getMessage());
+ }
+ }
+
+ public void testPrincipalMapping() {
+
+ try {
+
+ NameMapper nameMapper = new NameMapper();
+
+ String format = "urn-x:test:NameIdFormat1";
+ String rawConfig =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ + "<NameMapping format=\""
+ + format
+ + "\""
+ + " type=\"Principal\"/>";
+
+ parser.parse(new InputSource(new StringReader(rawConfig)));
+ nameMapper.addNameMapping(parser.getDocument().getDocumentElement());
+
+ SAMLNameIdentifier nameId = new SAMLNameIdentifier("testprincipal", "urn-x:testid", format);
+ AuthNPrincipal principal =
+ nameMapper.getPrincipal(nameId, new BasicServiceProvider(), new BasicIdentityProvider("urn-x:testid"));
+
+ assertEquals("Round-trip handle validation failed.", principal.getName(), "testprincipal");
+
+ } catch (MalformedURLException e) {
+ fail("Error in test specification: " + e.getMessage());
+ } catch (NameIdentifierMappingException e) {
+ fail("Error exercising NameMaper: " + e.getMessage());
+ } catch (Exception e) {
+ fail("Error exercising NameMaper: " + e.getMessage());
+ }
+
+ }
+}
+
+class BasicIdentityProvider implements IdentityProvider {
+ String id;
+
+ public BasicIdentityProvider(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+}
+class BasicServiceProvider implements ServiceProvider {
+
+}