Added some rarely used methods to sync metadata API with C++
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / serviceprovider / ServiceProviderConfig.java
index fa85875..c607515 100644 (file)
@@ -178,14 +178,17 @@ import x0.maceShibbolethTargetConfig1.HostDocument.Host.Scheme.Enum;
 import x0.maceShibbolethTargetConfig1.PathDocument.Path;
 import edu.internet2.middleware.shibboleth.aap.AAP;
 import edu.internet2.middleware.shibboleth.aap.AttributeRule;
+import edu.internet2.middleware.shibboleth.aap.provider.XMLAAPProvider;
 import edu.internet2.middleware.shibboleth.common.Credentials;
-import edu.internet2.middleware.shibboleth.common.ShibResource;
+import edu.internet2.middleware.shibboleth.common.PluggableConfigurationComponent;
 import edu.internet2.middleware.shibboleth.common.ShibbolethConfigurationException;
 import edu.internet2.middleware.shibboleth.common.Trust;
 import edu.internet2.middleware.shibboleth.common.provider.ShibbolethTrust;
+import edu.internet2.middleware.shibboleth.metadata.EntitiesDescriptor;
 import edu.internet2.middleware.shibboleth.metadata.EntityDescriptor;
 import edu.internet2.middleware.shibboleth.metadata.Metadata;
 import edu.internet2.middleware.shibboleth.metadata.RoleDescriptor;
+import edu.internet2.middleware.shibboleth.metadata.provider.XMLMetadataProvider;
 import edu.internet2.middleware.shibboleth.xml.Parser;
 
 /**
@@ -203,7 +206,8 @@ public class ServiceProviderConfig {
        // Map key prefix for inline plugin configuration elements 
        private static final String INLINEURN = "urn:inlineBS:ID";
     
-    private static Logger log = Logger.getLogger(ContextListener.SHIBBOLETH_INIT+".Config");
+    private static Logger initlog = Logger.getLogger(ContextListener.SHIBBOLETH_INIT+".Config");
+    private static Logger reqlog = Logger.getLogger(ServiceProviderConfig.class);
 
        private SPConfigType  // The XMLBean from the main config file
                config = null;    
@@ -223,6 +227,7 @@ public class ServiceProviderConfig {
                new TreeMap/*<String, Metadata>*/();
        
        public void addOrReplaceMetadataImplementor(String uri, Metadata m) {
+               initlog.info("addOrReplaceMetadataImplementor " + uri+ " as "+m.getClass());
            entityLocators.put(uri, m);
        }
        
@@ -234,6 +239,7 @@ public class ServiceProviderConfig {
                new TreeMap/*<String, AAP>*/();
        
        public void addOrReplaceAAPImplementor(String uri, AAP a) {
+               initlog.info("addOrReplaceAAPImplementor " + uri+ " as "+a.getClass());
            attributePolicies.put(uri,a);
        }
        
@@ -245,6 +251,7 @@ public class ServiceProviderConfig {
                new TreeMap/*<String, Trust>*/();
        
        public void addOrReplaceTrustImplementor(String uri, Trust t) {
+               initlog.info("addOrReplaceTrustImplementor " + uri+ " as "+t.getClass());
            certificateValidators.put(uri,t);
        }
        
@@ -322,14 +329,17 @@ public class ServiceProviderConfig {
                        throws ShibbolethConfigurationException {
            
            if (config!=null) {
-                       log.error("ServiceProviderConfig.loadConfigObjects may not be called twice for the same object.");
+                       initlog.error("ServiceProviderConfig.loadConfigObjects may not be called twice for the same object.");
                        throw new ShibbolethConfigurationException("Cannot reload configuration into same object.");
                }
+           
+           initlog.info("Loading SP configuration from "+configFilePath);
 
                Document configDoc;
         try {
                        configDoc = Parser.loadDom(configFilePath, true);
                } catch (Exception e) {
+                       initlog.error("XML Parser error "+e.toString());
             throw new ShibbolethConfigurationException("XML error in "+configFilePath);
         }
         loadConfigBean(configDoc);
@@ -392,6 +402,7 @@ public class ServiceProviderConfig {
             }
         }
            
+        reqlog.debug("mapRequest mapped "+urlreq+" into "+applicationId);
            return applicationId;
        }
 
@@ -410,32 +421,39 @@ public class ServiceProviderConfig {
                Element documentElement = configDoc.getDocumentElement();
                // reprocess the already validated DOM to create a bean with typed fields
                // dump the trash (comments, processing instructions, extra whitespace)
-               
                try {
                        if (documentElement.getLocalName().equals("ShibbolethTargetConfig")) {
+                               initlog.debug("SP Configuration file is in 1.2 syntax.");
                                ShibbolethTargetConfigDocument configBeanDoc;
                                configBeanDoc = ShibbolethTargetConfigDocument.Factory.parse(configDoc,
                                                new XmlOptions().setLoadStripComments().setLoadStripProcinsts().setLoadStripWhitespace());
                                config = configBeanDoc.getShibbolethTargetConfig();
                        } else if (documentElement.getLocalName().equals("SPConfig")) {
+                               initlog.debug("SP Configuration file is in 1.3 syntax.");
                                SPConfigDocument configBeanDoc;
                                configBeanDoc = SPConfigDocument.Factory.parse(configDoc,
                                                new XmlOptions().setLoadStripComments().setLoadStripProcinsts().setLoadStripWhitespace());
                                config = configBeanDoc.getSPConfig();
                        } else {
+                               initlog.error("Root element not ShibbolethTargetConfig or SPConfig");
                                throw new XmlException("Root element not ShibbolethTargetConfig or SPConfig");
                        }
                } catch (XmlException e) {
                        // Since the DOM was already validated against the schema, errors will not typically occur here
-                       log.error("Error while parsing shibboleth configuration");
+                       initlog.error("Error while parsing shibboleth configuration");
                        throw new ShibbolethConfigurationException("Error while parsing shibboleth configuration");
                }
                
-               try {
-                       String loggerUrl = config.getLogger();
-                       PropertyConfigurator.configure(new URL(loggerUrl));
-               } catch (Exception e) {
-                       log.error("Cannot process logger attribute of SP configuration file.",e);
+               String loggerUrlString = config.getLogger();
+               if (loggerUrlString!=null) {
+                       try {
+                               URL loggerURL = new URL(loggerUrlString);
+                               initlog.warn("logging is being reconfigured by "+ loggerUrlString);
+                               PropertyConfigurator.configure(loggerURL);
+                       } catch (MalformedURLException e) {
+                               // This error is not serious enough to prevent initialization
+                               initlog.error("Ignoring invalid value for logger attribute "+loggerUrlString );
+                       }
                }
                
                Applications apps = config.getApplications(); // <Applications>
@@ -482,8 +500,10 @@ public class ServiceProviderConfig {
                anyError |= processCredentials();
                anyError |= processPluggableRequestMapProvider();
                
-               if (anyError)
+               if (anyError) {
+                       initlog.error("SP Initialization terminated due to configuration errors");
                    throw new ShibbolethConfigurationException("Errors processing configuration file, see log");
+               }
        }
 
        
@@ -503,7 +523,7 @@ public class ServiceProviderConfig {
                        String pluggabletype = pluggable[i].getType();
                if (!pluggabletype.equals(
                        "edu.internet2.middleware.shibboleth.common.Credentials")) {
-                               log.error("Unsupported CredentialsProvider type "+pluggabletype);
+                               initlog.error("Unsupported CredentialsProvider type "+pluggabletype);
                                anyError=true;
                                continue;
                }
@@ -515,8 +535,7 @@ public class ServiceProviderConfig {
                 Node credentialsNode=credentialsProviderNode.getFirstChild();
                 credentials = new Credentials((Element)credentialsNode);
             } catch(Exception e) {
-                log.error("Cannot process Credentials element of Shibboleth configuration");
-                log.error(e);
+                initlog.error("Cannot process Credentials element of Shibboleth configuration",e);
                 anyError=true;
                 continue;
             }
@@ -601,15 +620,16 @@ public class ServiceProviderConfig {
        
        if (!pluggabletype.equals(builtinName)) {
            // Not the builtin type, try to load user class by name
+               initlog.info("loading user-specified pluggable class "+pluggabletype);
            try {
                 implclass = Class.forName(pluggabletype);
             } catch (ClassNotFoundException e) {
-                       log.error("Type value "+pluggabletype+" not found as supplied Java class");
+                       initlog.error("Type value "+pluggabletype+" not found as supplied Java class");
                    return null;
             }
            if (!interfaceClass.isAssignableFrom(implclass)||
                 !PluggableConfigurationComponent.class.isAssignableFrom(implclass)) {
-                       log.error(pluggabletype+" class does not support required interfaces.");
+                       initlog.error(pluggabletype+" class does not support required interfaces.");
                    return null;
            }
        }
@@ -618,7 +638,7 @@ public class ServiceProviderConfig {
         try {
             impl = (PluggableConfigurationComponent) implclass.newInstance();
         } catch (Exception e) {
-            log.error("Unable to instantiate "+pluggabletype);
+            initlog.error("Unable to instantiate "+pluggabletype);
             return null;
         }
        
@@ -629,10 +649,10 @@ public class ServiceProviderConfig {
                try {
                        Node fragment = pluggable.newDomNode();        // XML-Fragment node
                        Node pluggableNode = fragment.getFirstChild(); // PluggableType 
-                       Node contentNode=pluggableNode.getFirstChild();// root element
+                       Element contentNode=(Element) pluggableNode.getFirstChild();// root element
                        impl.initialize(contentNode);
                } catch (Exception e) {
-                       log.error("XML error " + e);
+                       initlog.error("XML error " + e);
                        return null;
                }
                
@@ -646,9 +666,9 @@ public class ServiceProviderConfig {
                        Document extdoc = Parser.loadDom(uri,true);
                        if (extdoc==null)
                            return null;
-                       impl.initialize(extdoc);
+                       impl.initialize(extdoc.getDocumentElement());
                } catch (Exception e) {
-                       log.error("XML error " + e);
+                       initlog.error("XML error " + e);
                        return null;
                }
        }
@@ -682,7 +702,7 @@ public class ServiceProviderConfig {
                }
                for (int i = 0;i<pluggable.length;i++) {
                    String uri = processPluggable(pluggable[i],
-                           XMLMetadataImpl.class,
+                           XMLMetadataProvider.class,
                            Metadata.class,
                            XMLFEDERATIONPROVIDERTYPE,
                            entityLocators);
@@ -708,12 +728,12 @@ public class ServiceProviderConfig {
                        Document sitedoc = Parser.loadDom(uri,true);
                        if (sitedoc==null)
                            return false;
-                       XMLMetadataImpl impl = new XMLMetadataImpl();
-                       impl.initialize(sitedoc);
+                       XMLMetadataProvider impl = new XMLMetadataProvider();
+                       impl.initialize(sitedoc.getDocumentElement());
                        addOrReplaceMetadataImplementor(uri,impl);
                } catch (Exception e) {
-                       log.error("Error while parsing Metadata file "+uri);
-                       log.error("XML error " + e);
+                       initlog.error("Error while parsing Metadata file "+uri);
+                       initlog.error("XML error " + e);
                        return false;
                }
            return true;
@@ -729,7 +749,7 @@ public class ServiceProviderConfig {
                PluggableType[] pluggable = appinfo.getApplicationConfig().getAAPProviderArray();
                for (int i = 0;i<pluggable.length;i++) {
                    String uri = processPluggable(pluggable[i],
-                           XMLAAPImpl.class,
+                               XMLAAPProvider.class,
                            AAP.class,
                            XMLAAPPROVIDERTYPE,
                            attributePolicies);
@@ -756,12 +776,12 @@ public class ServiceProviderConfig {
                        if (aapdoc==null)
                            return false;
                        AttributeAcceptancePolicyDocument aap = AttributeAcceptancePolicyDocument.Factory.parse(aapdoc);
-                       XMLAAPImpl impl = new XMLAAPImpl();
-                       impl.initialize(aapdoc);
+                       XMLAAPProvider impl = new XMLAAPProvider();
+                       impl.initialize(aapdoc.getDocumentElement());
                        addOrReplaceAAPImplementor(uri,impl);
                } catch (Exception e) {
-                       log.error("Error while parsing AAP file "+uri);
-                       log.error("XML error " + e);
+                       initlog.error("Error while parsing AAP file "+uri);
+                       initlog.error("XML error " + e);
                        return false;
                }
            return true;
@@ -785,7 +805,7 @@ public class ServiceProviderConfig {
                PluggableType[] pluggable = appinfo.getApplicationConfig().getTrustProviderArray();
                for (int i = 0;i<pluggable.length;i++) {
                    String uri = processPluggable(pluggable[i],
-                           ShibbolethTrustPluggable.class,
+                           ShibbolethTrust.class,
                            Trust.class,
                            XMLTRUSTPROVIDERTYPE,
                            certificateValidators);
@@ -805,14 +825,14 @@ public class ServiceProviderConfig {
         if (shire==null)
             shire = config.getLocal();
         if (shire==null) {
-            log.error("No Local element.");
+            initlog.error("No SHIRE or Local element.");
             return true;
         }
            PluggableType mapProvider = shire.getRequestMapProvider();
            
            String pluggabletype = mapProvider.getType();
            if (!pluggabletype.equals(XMLREQUESTMAPPROVIDERTYPE)) {
-               log.error("Unsupported RequestMapProvider type "+pluggabletype);
+               initlog.error("Unsupported RequestMapProvider type "+pluggabletype);
                return true;
            }
            
@@ -831,8 +851,8 @@ public class ServiceProviderConfig {
                    
                    requestMapDoc = RequestMapDocument.Factory.parse(contentNode);
                } catch (Exception e) {
-                   log.error("Error while parsing inline RequestMap");
-                   log.error("XML error " + e);
+                   initlog.error("Error while parsing inline RequestMap");
+                   initlog.error("XML error " + e);
                    return true;
                }
                
@@ -843,8 +863,8 @@ public class ServiceProviderConfig {
                        return true;
                    requestMapDoc = RequestMapDocument.Factory.parse(mapdoc);
                } catch (Exception e) {
-                   log.error("Error while parsing RequestMap file "+uri);
-                   log.error("XML error " + e);
+                   initlog.error("Error while parsing RequestMap file "+uri);
+                   initlog.error("XML error " + e);
                    return true;
                }
            }
@@ -947,29 +967,51 @@ public class ServiceProviderConfig {
                 * @param id ID of the IdP entity
                 * @return EntityDescriptor metadata object for that site.
                 */
-        public EntityDescriptor lookup(String id) {
+        public EntityDescriptor lookup(String id, boolean strict) {
                        Iterator iuris = groupUris.iterator();
                        while (iuris.hasNext()) {
                                String uri =(String) iuris.next();
                                Metadata locator=getMetadataImplementor(uri);
-                               EntityDescriptor entity = locator.lookup(id);
-                               if (entity!=null)
+                               EntityDescriptor entity = locator.lookup(id, strict);
+                               if (entity!=null) {
+                                       reqlog.debug("Metadata.lookup resolved Entity "+ id);
                                        return entity;
+                               }
                        }
+                       reqlog.warn("Metadata.lookup failed to resolve Entity "+ id);
                        return null;
                }
 
-        public EntityDescriptor lookup(Artifact artifact) {
+        public EntityDescriptor lookup(Artifact artifact, boolean strict) {
             Iterator iuris = groupUris.iterator();
             while (iuris.hasNext()) {
                 String uri =(String) iuris.next();
                 Metadata locator=getMetadataImplementor(uri);
-                EntityDescriptor entity = locator.lookup(artifact);
-                if (entity!=null)
+                EntityDescriptor entity = locator.lookup(artifact, strict);
+                if (entity!=null) {
+                                       reqlog.debug("Metadata.lookup resolved Artifact "+ artifact);
                     return entity;
+                }
             }
+                       reqlog.warn("Metadata.lookup failed to resolve Artifact "+ artifact);
             return null;
         }
+
+               public EntityDescriptor lookup(String id) {
+                       return lookup(id,true);
+               }
+
+               public EntityDescriptor lookup(Artifact artifact) {
+                       return lookup(artifact,true);
+               }
+
+               public EntityDescriptor getRootEntity() {
+                       return null;
+               }
+
+               public EntitiesDescriptor getRootEntities() {
+                       return null;
+               }
         
                /**
                 * Return the current array of objects that implement the Trust interface
@@ -1022,13 +1064,13 @@ public class ServiceProviderConfig {
                    // Foreach AAP in the collection
                        AAP[] providers = getAAPProviders();
             if (providers.length == 0) {
-                log.info("no filters specified, accepting entire assertion");
+                reqlog.info("no filters specified, accepting entire assertion");
                 return;
             }
                        for (int i=0;i<providers.length;i++) {
                                AAP aap = providers[i];
                                if (aap.anyAttribute()) {
-                    log.info("any attribute enabled, accepting entire assertion");
+                    reqlog.info("any attribute enabled, accepting entire assertion");
                                        continue;
                 }
             }
@@ -1055,14 +1097,14 @@ public class ServiceProviderConfig {
                                     rule.apply(attribute,role);
                                 }
                                 catch (SAMLException ex) {
-                                    log.info("no values remain, removing attribute");
+                                    reqlog.info("no values remain, removing attribute");
                                                                attributeStatement.removeAttribute(iattribute--);
                                     break;
                                 }
                             }
                         }
                         if (!ruleFound) {
-                            log.warn("no rule found for attribute (" + attribute.getName() + "), filtering it out");
+                            reqlog.warn("no rule found for attribute (" + attribute.getName() + "), filtering it out");
                             attributeStatement.removeAttribute(iattribute--);
                         }
                         iattribute++;
@@ -1074,7 +1116,7 @@ public class ServiceProviderConfig {
                                        }
                     catch (SAMLException ex) {
                         // The statement is now defunct.
-                        log.info("no attributes remain, removing statement");
+                        reqlog.info("no attributes remain, removing statement");
                                                assertion.removeStatement(istatement);
                                        }
                                }
@@ -1118,6 +1160,7 @@ public class ServiceProviderConfig {
                                if (trust.validate(token,role))
                                        return true;
                        }
+                       reqlog.warn("SAML object failed Trust validation.");
                        return false;
                }
                
@@ -1143,6 +1186,7 @@ public class ServiceProviderConfig {
                                if (trust.validate(certificateEE,certificateChain,descriptor))
                                        return true;
                        }
+                       reqlog.warn("X.509 Certificate failed Trust validate");
                        return false;
                }
 
@@ -1153,6 +1197,7 @@ public class ServiceProviderConfig {
                                if (trust.validate(certificateEE,certificateChain,descriptor,checkName))
                                        return true;
                        }
+                       reqlog.warn("X.509 Certificate failed Trust validate");
                        return false;
                }