More name mapping updates.
authorwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Tue, 20 Jan 2004 04:06:22 +0000 (04:06 +0000)
committerwassa <wassa@ab3bd59b-922f-494d-bb5f-6f0a3c29deca>
Tue, 20 Jan 2004 04:06:22 +0000 (04:06 +0000)
git-svn-id: https://subversion.switch.ch/svn/shibboleth/java-idp/trunk@825 ab3bd59b-922f-494d-bb5f-6f0a3c29deca

17 files changed:
src/edu/internet2/middleware/shibboleth/common/BaseNameIdentifierMapping.java
src/edu/internet2/middleware/shibboleth/common/IdentityProvider.java
src/edu/internet2/middleware/shibboleth/common/NameIdentifierMapping.java
src/edu/internet2/middleware/shibboleth/common/NameMapper.java
src/edu/internet2/middleware/shibboleth/common/ShibPOSTProfile.java
src/edu/internet2/middleware/shibboleth/hs/HSNameMapper.java
src/edu/internet2/middleware/shibboleth/hs/HandleRepository.java [deleted file]
src/edu/internet2/middleware/shibboleth/hs/HandleRepositoryException.java [deleted file]
src/edu/internet2/middleware/shibboleth/hs/HandleRepositoryFactory.java [deleted file]
src/edu/internet2/middleware/shibboleth/hs/InvalidHandleException.java [deleted file]
src/edu/internet2/middleware/shibboleth/hs/provider/AQHNameIdentifierMapping.java [moved from src/edu/internet2/middleware/shibboleth/hs/provider/BaseHandleRepository.java with 60% similarity]
src/edu/internet2/middleware/shibboleth/hs/provider/CryptoShibHandle.java [moved from src/edu/internet2/middleware/shibboleth/hs/provider/CryptoHandleRepository.java with 56% similarity]
src/edu/internet2/middleware/shibboleth/hs/provider/IdentityHandleRepository.java [deleted file]
src/edu/internet2/middleware/shibboleth/hs/provider/MemoryHandleRepository.java [deleted file]
src/edu/internet2/middleware/shibboleth/hs/provider/SharedMemoryShibHandle.java
tests/edu/internet2/middleware/shibboleth/hs/provider/HandleRepositoryTests.java [deleted file]
tests/edu/internet2/middleware/shibboleth/hs/provider/NameMapperTests.java [new file with mode: 0644]

index 046bba1..2398ca6 100644 (file)
@@ -83,7 +83,7 @@ public abstract class BaseNameIdentifierMapping implements NameIdentifierMapping
                }
 
                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.");
index 826525a..d080d71 100644 (file)
@@ -51,5 +51,5 @@ package edu.internet2.middleware.shibboleth.common;
  * @author Walter Hoehn
  */
 public interface IdentityProvider {
-
+       String getId();
 }
index b8c08bb..a104097 100644 (file)
@@ -55,6 +55,8 @@ import org.opensaml.SAMLNameIdentifier;
  * @author Walter Hoehn
  */
 public interface NameIdentifierMapping {
+       
+       public static final String mappingNamespace = "urn:mace:shibboleth:origin.config:1.0";
 
        public URI getNameIdentifierFormat();
 
index 4be94e3..391162c 100644 (file)
 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
  */
@@ -63,6 +68,7 @@ public class NameMapper {
        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 {
@@ -75,7 +81,7 @@ public class NameMapper {
                                Class.forName("edu.internet2.middleware.shibboleth.hs.provider.SharedMemoryShibHandle"));
 
                        registeredMappingTypes.put(
-                               "PassThruNameIdentifier",
+                               "Principal",
                                Class.forName("edu.internet2.middleware.shibboleth.common.PrincipalNameIdentifier"));
 
                } catch (ClassNotFoundException e) {
@@ -130,10 +136,24 @@ public class NameMapper {
        }
 
        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);
        }
 
@@ -162,4 +182,19 @@ public class NameMapper {
 
        }
 
+       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);
+       }
+
 }
index 3e7580c..af1dc3a 100755 (executable)
@@ -181,7 +181,7 @@ public class ShibPOSTProfile
             {
                 SAMLStatement s=(SAMLStatement)is.next();
                 if (s instanceof SAMLAuthenticationStatement)
-                    return ((SAMLAuthenticationStatement)s).getSubject().getNameQualifier();
+                    return ((SAMLAuthenticationStatement)s).getSubject().getName().getName();
             }
         }
         return null;
@@ -234,11 +234,11 @@ public class ShibPOSTProfile
 
         // 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?
index ebc52d5..b1a26fe 100644 (file)
@@ -49,8 +49,15 @@ package edu.internet2.middleware.shibboleth.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
@@ -68,8 +75,23 @@ public class HSNameMapper extends NameMapper {
                        }
                }
        }
-       
+
        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);
+       }
 }
diff --git a/src/edu/internet2/middleware/shibboleth/hs/HandleRepository.java b/src/edu/internet2/middleware/shibboleth/hs/HandleRepository.java
deleted file mode 100644 (file)
index 6166ad0..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/* 
- * 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;
-
-}
diff --git a/src/edu/internet2/middleware/shibboleth/hs/HandleRepositoryException.java b/src/edu/internet2/middleware/shibboleth/hs/HandleRepositoryException.java
deleted file mode 100644 (file)
index dbf0cf7..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/* 
- * 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);
-       }
-}
diff --git a/src/edu/internet2/middleware/shibboleth/hs/HandleRepositoryFactory.java b/src/edu/internet2/middleware/shibboleth/hs/HandleRepositoryFactory.java
deleted file mode 100644 (file)
index 6f872e0..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/* 
- * 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
-            );
-       }
-}
diff --git a/src/edu/internet2/middleware/shibboleth/hs/InvalidHandleException.java b/src/edu/internet2/middleware/shibboleth/hs/InvalidHandleException.java
deleted file mode 100644 (file)
index 7b80566..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* 
- * 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);
-       }
-
-}
@@ -1,83 +1,81 @@
-/* 
- * 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 "
@@ -87,18 +85,19 @@ public abstract class BaseHandleRepository implements HandleRepository {
                        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 {
@@ -109,8 +108,11 @@ 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;
@@ -1,50 +1,48 @@
-/* 
- * 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;
@@ -66,7 +64,6 @@ import java.security.SecureRandom;
 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;
 
@@ -77,151 +74,154 @@ import javax.crypto.SecretKey;
 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);
@@ -252,99 +252,58 @@ public class CryptoHandleRepository extends BaseHandleRepository implements Hand
                        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 {
@@ -356,12 +315,12 @@ public class CryptoHandleRepository extends BaseHandleRepository implements Hand
                        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;
@@ -373,22 +332,52 @@ public class CryptoHandleRepository extends BaseHandleRepository implements Hand
 
                } 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 {
 
diff --git a/src/edu/internet2/middleware/shibboleth/hs/provider/IdentityHandleRepository.java b/src/edu/internet2/middleware/shibboleth/hs/provider/IdentityHandleRepository.java
deleted file mode 100644 (file)
index 76a6789..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/* 
- * 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);
-       }
-}
diff --git a/src/edu/internet2/middleware/shibboleth/hs/provider/MemoryHandleRepository.java b/src/edu/internet2/middleware/shibboleth/hs/provider/MemoryHandleRepository.java
deleted file mode 100644 (file)
index ddb707b..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/* 
- * 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.");
-                               }
-                       }
-               }
-       }
-
-}
index 1ab8a20..76ba2b8 100644 (file)
  */
 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;
@@ -62,22 +69,14 @@ import edu.internet2.middleware.shibboleth.hs.HSNameIdentifierMapping;
 /**
  * @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(
@@ -96,8 +95,12 @@ public class SharedMemoryShibHandle extends BaseNameIdentifierMapping implements
                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);
+               }
 
        }
 
@@ -128,5 +131,83 @@ public class SharedMemoryShibHandle extends BaseNameIdentifierMapping implements
                }
        }
 
+}
+
+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.");
+                               }
+                       }
+               }
+       }
 
 }
diff --git a/tests/edu/internet2/middleware/shibboleth/hs/provider/HandleRepositoryTests.java b/tests/edu/internet2/middleware/shibboleth/hs/provider/HandleRepositoryTests.java
deleted file mode 100644 (file)
index b512582..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/* 
- * 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());
-               }
-       }
-
-}
diff --git a/tests/edu/internet2/middleware/shibboleth/hs/provider/NameMapperTests.java b/tests/edu/internet2/middleware/shibboleth/hs/provider/NameMapperTests.java
new file mode 100644 (file)
index 0000000..50aa7f9
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * 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 {
+
+}