2 * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package edu.internet2.middleware.shibboleth.metadata.provider;
19 import java.net.MalformedURLException;
21 import java.security.NoSuchAlgorithmException;
22 import java.text.ParseException;
23 import java.text.SimpleDateFormat;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.Iterator;
30 import java.util.TimeZone;
32 import javax.xml.namespace.QName;
34 import org.apache.log4j.Logger;
35 import org.apache.xml.security.encryption.EncryptionMethod;
36 import org.apache.xml.security.exceptions.XMLSecurityException;
37 import org.apache.xml.security.keys.KeyInfo;
38 import org.bouncycastle.util.encoders.Hex;
39 import org.opensaml.SAMLAttribute;
40 import org.opensaml.SAMLBinding;
41 import org.opensaml.SAMLBrowserProfile;
42 import org.opensaml.SAMLException;
43 import org.opensaml.XML;
44 import org.opensaml.artifact.Artifact;
45 import org.opensaml.artifact.SAMLArtifactType0001;
46 import org.opensaml.artifact.SAMLArtifactType0002;
47 import org.opensaml.artifact.Util;
48 import org.w3c.dom.Attr;
49 import org.w3c.dom.Element;
50 import org.w3c.dom.NamedNodeMap;
51 import org.w3c.dom.Node;
52 import org.w3c.dom.NodeList;
54 import edu.internet2.middleware.shibboleth.common.Constants;
55 import edu.internet2.middleware.shibboleth.common.PluggableConfigurationComponent;
56 import edu.internet2.middleware.shibboleth.metadata.*;
59 * @author Scott Cantor
61 public class XMLMetadataProvider implements Metadata, PluggableConfigurationComponent {
63 private static Logger log = Logger.getLogger(XMLMetadataProvider.class.getName());
64 private Map /* <String,ArrayList<EntityDescriptor> > */ sites = new HashMap();
65 private Map /* <String,ArrayList<EntityDescriptor> > */ sources = new HashMap();
66 private XMLEntityDescriptor rootProvider = null;
67 private XMLEntitiesDescriptor rootGroup = null;
69 public XMLMetadataProvider(Element e) throws SAMLException {
73 public XMLMetadataProvider() {} // Must call initialize
75 public void initialize(Element e) throws SAMLException {
76 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EntitiesDescriptor"))
77 rootGroup=new XMLEntitiesDescriptor(e,this, Long.MAX_VALUE, null);
78 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EntityDescriptor"))
79 rootProvider=new XMLEntityDescriptor(e,this, Long.MAX_VALUE, null);
80 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"SiteGroup"))
81 rootGroup=new XMLEntitiesDescriptor(e,this, Long.MAX_VALUE, null);
82 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"OriginSite"))
83 rootProvider=new XMLEntityDescriptor(e,this, Long.MAX_VALUE, null);
84 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"DestinationSite"))
85 rootProvider=new XMLEntityDescriptor(e,this, Long.MAX_VALUE, null);
87 log.error("Construction requires a valid SAML metadata file");
88 throw new MetadataException("Construction requires a valid SAML metadata file");
92 public EntityDescriptor lookup(String id, boolean strict) {
93 ArrayList list = (ArrayList)sites.get(id);
95 long now = System.currentTimeMillis();
96 for (int i=0; i<list.size(); i++) {
97 if (now < ((XMLEntityDescriptor)list.get(i)).getValidUntil())
98 return (EntityDescriptor)list.get(i);
100 if (!strict && list.size() > 0)
101 return (EntityDescriptor)list.get(0);
106 public EntityDescriptor lookup(Artifact artifact, boolean strict) {
107 ArrayList list = null;
109 if (artifact instanceof SAMLArtifactType0001) {
110 list = (ArrayList)sources.get(((SAMLArtifactType0001)artifact).getSourceId());
112 else if (artifact instanceof SAMLArtifactType0002) {
113 list = (ArrayList)sources.get(((SAMLArtifactType0002)artifact).getSourceLocation().toString());
116 log.error("unsupported artifact type (" + artifact.getTypeCode().toString() + ")");
120 long now = System.currentTimeMillis();
121 for (int i=0; i<list.size(); i++) {
122 if (now < ((XMLEntityDescriptor)list.get(i)).getValidUntil())
123 return (EntityDescriptor)list.get(i);
125 if (!strict && list.size() > 0)
126 return (EntityDescriptor)list.get(0);
131 public EntityDescriptor lookup(String id) {
132 return lookup(id, true);
135 public EntityDescriptor lookup(Artifact artifact) {
136 return lookup(artifact, true);
139 public EntityDescriptor getRootEntity() {
143 public EntitiesDescriptor getRootEntities() {
147 class XMLEndpoint implements Endpoint {
148 private Element root = null;
149 private String binding = null;
150 private String location = null;
151 private String resploc = null;
153 XMLEndpoint(Element e) {
155 binding = XML.assign(e.getAttributeNS(null,"Binding"));
156 location = XML.assign(e.getAttributeNS(null,"Location"));
157 resploc = XML.assign(e.getAttributeNS(null,"ResponseLocation"));
160 XMLEndpoint(String binding, String location) {
161 this.binding = binding;
162 this.location = location;
165 public String getBinding() {
169 public String getLocation() {
173 public String getResponseLocation() {
177 public Element getElement() {
182 class XMLIndexedEndpoint extends XMLEndpoint implements IndexedEndpoint {
183 private int index = 0;
185 XMLIndexedEndpoint(Element e) {
187 index = Integer.parseInt(e.getAttributeNS(null,"index"));
190 public int getIndex() {
195 class XMLEndpointManager implements EndpointManager {
196 private ArrayList endpoints = new ArrayList();
197 Endpoint soft = null; // Soft default (not explicit)
198 Endpoint hard = null; // Hard default (explicit)
200 public Iterator getEndpoints() {
201 return endpoints.iterator();
204 public Endpoint getDefaultEndpoint() {
205 if (hard != null) return hard;
206 if (soft != null) return soft;
207 if (!endpoints.isEmpty()) return (Endpoint)endpoints.get(0);
211 public Endpoint getEndpointByIndex(int index) {
212 for (int i=0; i < endpoints.size(); i++) {
213 if (endpoints.get(i) instanceof IndexedEndpoint && index==((IndexedEndpoint)endpoints.get(i)).getIndex())
214 return (Endpoint)endpoints.get(i);
219 public Endpoint getEndpointByBinding(String binding) {
220 for (int i=0; i < endpoints.size(); i++) {
221 if (binding.equals(((Endpoint)endpoints.get(i)).getBinding()))
222 return (Endpoint)endpoints.get(i);
227 protected void add(Endpoint e) {
229 if (hard == null && e.getElement() != null) {
230 String v=XML.assign(e.getElement().getAttributeNS(null,"isDefault"));
231 if (v != null && (v.equals("1") || v.equals("true"))) // explicit default
233 else if (v == null && soft == null) // implicit default
236 else if (hard == null && soft == null) {
237 // No default yet, so this one qualifies as an implicit.
243 class XMLKeyDescriptor implements KeyDescriptor {
245 private int use = KeyDescriptor.UNSPECIFIED;
246 private KeyInfo keyInfo = null;
247 private ArrayList /* <XMLEncryptionMethod> */ methods = new ArrayList();
249 XMLKeyDescriptor(Element e) {
250 if (XML.safeCompare(e.getAttributeNS(null,"use"),"encryption"))
251 use = KeyDescriptor.ENCRYPTION;
252 else if (XML.safeCompare(e.getAttributeNS(null,"use"),"signing"))
253 use = KeyDescriptor.SIGNING;
255 e = XML.getFirstChildElement(e);
257 keyInfo = new KeyInfo(e, null);
259 catch (XMLSecurityException e1) {
260 log.error("unable to process ds:KeyInfo element: " + e1.getMessage());
263 e = XML.getNextSiblingElement(e);
264 while (e != null && XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EncryptionMethod")) {
265 methods.add(new XMLEncryptionMethod(e));
269 public int getUse() {
273 public Iterator getEncryptionMethods() {
274 return methods.iterator();
277 public KeyInfo getKeyInfo() {
282 class XMLEncryptionMethod implements EncryptionMethod {
285 String params = null;
288 public XMLEncryptionMethod(Element e) {
289 alg = XML.assign(e.getAttributeNS(null, "Algorithm"));
290 e = XML.getFirstChildElement(e);
292 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.XMLENC_NS,"KeySize")) {
293 if (e.hasChildNodes())
294 size = Integer.parseInt(e.getFirstChild().getNodeValue());
296 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.XMLENC_NS,"OAEParams")) {
297 if (e.hasChildNodes())
298 params = XML.assign(e.getFirstChild().getNodeValue());
300 e = XML.getNextSiblingElement(e);
304 public String getAlgorithm() {
308 public int getKeySize() {
312 public byte[] getOAEPparams() {
313 return params.getBytes();
316 public Iterator getEncryptionMethodInformation() {
320 public void setKeySize(int arg0) {
321 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
324 public void setOAEPparams(byte[] arg0) {
325 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
328 public void addEncryptionMethodInformation(Element arg0) {
329 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
332 public void removeEncryptionMethodInformation(Element arg0) {
333 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
337 class XMLKeyAuthority implements KeyAuthority {
338 private int depth = 1;
339 private ArrayList /* <KeyInfo> */ keys = new ArrayList();
341 XMLKeyAuthority(Element e) {
342 if (e.hasAttributeNS(null,"VerifyDepth"))
343 depth = Integer.parseInt(e.getAttributeNS(null,"VerifyDepth"));
344 e = XML.getFirstChildElement(e, XML.XMLSIG_NS, "KeyInfo");
347 keys.add(new KeyInfo(e, null));
349 catch (XMLSecurityException e1) {
350 log.error("unable to process ds:KeyInfo element: " + e1.getMessage());
352 e = XML.getNextSiblingElement(e, XML.XMLSIG_NS, "KeyInfo");
356 public int getVerifyDepth() {
360 public Iterator getKeyInfos() {
361 return keys.iterator();
366 class XMLOrganization implements Organization {
367 private HashMap /* <String,String> */ names = new HashMap();
368 private HashMap /* <String,String> */ displays = new HashMap();
369 private HashMap /* <String,URL> */ urls = new HashMap();
371 public XMLOrganization(Element e) throws MetadataException {
372 // Old metadata or new?
373 if (XML.isElementNamed(e, edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Alias")) {
374 if (e.hasChildNodes()) {
375 names.put("en",XML.assign(e.getFirstChild().getNodeValue()));
376 displays.put("en",XML.assign(e.getFirstChild().getNodeValue()));
380 e=XML.getFirstChildElement(e);
382 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"OrganizationName")) {
383 if (e.hasChildNodes()) {
384 names.put(e.getAttributeNS(XML.XML_NS,"lang"),XML.assign(e.getFirstChild().getNodeValue()));
387 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"OrganizationDisplayName")) {
388 if (e.hasChildNodes()) {
389 displays.put(e.getAttributeNS(XML.XML_NS,"lang"),XML.assign(e.getFirstChild().getNodeValue()));
392 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"OrganizationURL")) {
393 if (e.hasChildNodes()) {
396 u = new URL(e.getFirstChild().getNodeValue());
398 catch (MalformedURLException e1) {
399 throw new MetadataException("OrganizationURL was invalid: " + e1);
401 urls.put(e.getAttributeNS(XML.XML_NS,"lang"),u);
404 e=XML.getNextSiblingElement(e);
409 public String getName() {
410 return getName("en");
413 public String getName(String lang) {
414 return (String)names.get(lang);
417 public String getDisplayName() {
418 return getDisplayName("en");
421 public String getDisplayName(String lang) {
422 return (String)displays.get(lang);
425 public URL getURL() {
429 public URL getURL(String lang) {
430 return (URL)urls.get(lang);
435 class XMLContactPerson implements ContactPerson {
436 private Element root = null;
438 private String company = null;
439 private String givenName = null;
440 private String surName = null;
441 private ArrayList /* <String> */ emails = new ArrayList();
442 private ArrayList /* <String> */ telephones = new ArrayList();
444 public XMLContactPerson(Element e) throws MetadataException {
446 String rawType = null;
448 // Old metadata or new?
449 if (XML.isElementNamed(root, edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Contact")) {
450 rawType = root.getAttributeNS(null,"Type");
451 surName = XML.assign(root.getAttributeNS(null,"Name"));
452 if (XML.isEmpty(surName)) {
453 throw new MetadataException("Contact is missing Name attribute.");
455 if (root.hasAttributeNS(null,"Email"))
456 emails.add(e.getAttributeNS(null,"Email"));
459 rawType = root.getAttributeNS(null,"contactType");
460 e=XML.getFirstChildElement(root);
462 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Company")) {
463 if (e.hasChildNodes())
464 company=XML.assign(e.getFirstChild().getNodeValue());
466 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"GivenName")) {
467 if (e.hasChildNodes())
468 givenName=XML.assign(e.getFirstChild().getNodeValue());
470 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SurName")) {
471 if (e.hasChildNodes())
472 surName=XML.assign(e.getFirstChild().getNodeValue());
474 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EmailAddress")) {
475 if (e.hasChildNodes())
476 emails.add(XML.assign(e.getFirstChild().getNodeValue()));
478 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"TelephoneNumber")) {
479 if (e.hasChildNodes())
480 telephones.add(XML.assign(e.getFirstChild().getNodeValue()));
482 e=XML.getNextSiblingElement(e);
486 if (rawType.equalsIgnoreCase("TECHNICAL")) {
487 type = ContactPerson.TECHNICAL;
488 } else if (rawType.equalsIgnoreCase("SUPPORT")) {
489 type = ContactPerson.SUPPORT;
490 } else if (rawType.equalsIgnoreCase("ADMINISTRATIVE")) {
491 type = ContactPerson.ADMINISTRATIVE;
492 } else if (rawType.equalsIgnoreCase("BILLING")) {
493 type = ContactPerson.BILLING;
494 } else if (rawType.equalsIgnoreCase("OTHER")) {
495 type = ContactPerson.OTHER;
497 throw new MetadataException("Contact has unknown contact type.");
501 public int getType() {
505 public String getGivenName() {
509 public String getSurName() {
513 public String getCompany() {
517 public Iterator getEmailAddresses() {
518 return emails.iterator();
521 public Iterator getTelephoneNumbers() {
522 return telephones.iterator();
525 public Element getElement() {
530 class Role implements RoleDescriptor {
531 private Element root = null;
532 private XMLEntityDescriptor provider = null;
533 private URL errorURL = null;
534 private Organization org = null;
535 private ArrayList /* <ContactPerson> */ contacts = new ArrayList();
536 private long validUntil = Long.MAX_VALUE;
537 protected ArrayList /* <String> */ protocolEnum = new ArrayList();
538 protected ArrayList /* <KeyDescriptor> */ keys = new ArrayList();
540 public Role(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
542 this.validUntil = validUntil;
543 this.provider = provider;
545 // Check the root element namespace. If SAML2, assume it's the std schema.
546 if (e != null && edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
548 if (e.hasAttributeNS(null,"validUntil")) {
549 SimpleDateFormat formatter = null;
550 String dateTime = XML.assign(e.getAttributeNS(null,"validUntil"));
551 int dot = dateTime.indexOf('.');
553 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
555 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
556 formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
558 this.validUntil=Math.min(validUntil,formatter.parse(dateTime).getTime());
560 catch (ParseException e1) {
561 log.warn("Role descriptor contains invalid expiration time");
565 if (e.hasAttributeNS(null,"errorURL")) {
567 errorURL=new URL(e.getAttributeNS(null,"errorURL"));
569 catch (MalformedURLException e1) {
570 log.error("Role descriptor contains malformed errorURL");
574 // Chop the protocol list into pieces...assume any whitespace can appear in between.
575 protocolEnum.addAll(Arrays.asList(e.getAttributeNS(null,"protocolSupportEnumeration").split("\\s")));
577 e = XML.getFirstChildElement(root,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
579 keys.add(new XMLKeyDescriptor(e));
580 e = XML.getNextSiblingElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
583 e = XML.getFirstChildElement(root,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Organization");
585 org=new XMLOrganization(e);
587 e = XML.getFirstChildElement(root,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ContactPerson");
589 contacts.add(new XMLContactPerson(e));
590 e = XML.getNextSiblingElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ContactPerson");
595 public EntityDescriptor getEntityDescriptor() {
599 public Iterator getProtocolSupportEnumeration() {
600 return protocolEnum.iterator();
603 public boolean hasSupport(String version) {
604 return protocolEnum.contains(version);
607 public boolean isValid() {
608 return System.currentTimeMillis() < validUntil;
611 public URL getErrorURL() {
612 return (errorURL != null) ? errorURL : provider.getErrorURL();
615 public Iterator getKeyDescriptors() {
616 return keys.iterator();
619 public Organization getOrganization() {
620 return (org != null) ? org : provider.getOrganization();
623 public Iterator getContactPersons() {
624 return (contacts.isEmpty()) ? provider.getContactPersons() : contacts.iterator();
627 public Element getElement() {
632 class SSORole extends Role implements SSODescriptor {
633 private XMLEndpointManager artifact = new XMLEndpointManager();
634 private XMLEndpointManager logout = new XMLEndpointManager();
635 private XMLEndpointManager nameid = new XMLEndpointManager();
636 private ArrayList /* <String> */ formats = new ArrayList();
638 public SSORole(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
639 super(provider, validUntil, e);
641 // Check the root element namespace. If SAML2, assume it's the std schema.
642 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
644 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ArtifactResolutionService");
645 for (i=0; i<nlist.getLength(); i++)
646 artifact.add(new XMLIndexedEndpoint((Element)nlist.item(i)));
648 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SingleLogoutService");
649 for (i=0; i<nlist.getLength(); i++)
650 logout.add(new XMLEndpoint((Element)nlist.item(i)));
652 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ManageNameIDService");
653 for (i=0; i<nlist.getLength(); i++)
654 nameid.add(new XMLEndpoint((Element)nlist.item(i)));
656 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"NameIDFormat");
657 for (i = 0; i < nlist.getLength(); i++) {
658 if (nlist.item(i).hasChildNodes()) {
659 Node tnode = nlist.item(i).getFirstChild();
660 if (tnode != null && tnode.getNodeType() == Node.TEXT_NODE) {
661 formats.add(tnode.getNodeValue());
667 // For old style, we just do SAML 1.1 compatibility with Shib handles.
668 protocolEnum.add(XML.SAML11_PROTOCOL_ENUM);
669 formats.add(Constants.SHIB_NAMEID_FORMAT_URI);
673 public EndpointManager getArtifactResolutionServiceManager() {
677 public EndpointManager getSingleLogoutServiceManager() {
681 public EndpointManager getManageNameIDServiceManager() {
685 public Iterator getNameIDFormats() {
686 return formats.iterator();
690 class IDPRole extends SSORole implements IDPSSODescriptor, ScopedRoleDescriptor {
691 private ArrayList /* <Scope> */ scopes = new ArrayList();
692 private XMLEndpointManager sso = new XMLEndpointManager();
693 private XMLEndpointManager mapping = new XMLEndpointManager();
694 private XMLEndpointManager idreq = new XMLEndpointManager();
695 private ArrayList /* <String> */ attrprofs = new ArrayList();
696 private ArrayList /* <SAMLAttribute> */ attrs = new ArrayList();
697 private boolean wantAuthnRequestsSigned = false;
698 private String sourceId = null;
700 public IDPRole(XMLEntityDescriptor provider, long validUntil, Element e) throws SAMLException {
701 super(provider, validUntil, e);
702 NodeList domains=null;
704 // Check the root element namespace. If SAML2, assume it's the std schema.
705 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
706 String flag=XML.assign(e.getAttributeNS(null,"WantAuthnRequestsSigned"));
707 wantAuthnRequestsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
709 // Check for extensions.
710 Element ext=XML.getFirstChildElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions");
712 Element ext1=XML.getFirstChildElement(ext,XML.SAML_ARTIFACT_SOURCEID,"SourceID");
713 if (ext1 != null && ext1.hasChildNodes())
714 sourceId=ext1.getFirstChild().getNodeValue();
715 // Save off any domain elements for later.
716 domains = ext.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"Scope");
720 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SingleSignOnService");
721 for (i=0; i<nlist.getLength(); i++)
722 sso.add(new XMLEndpoint((Element)(nlist.item(i))));
724 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"NameIDMappingService");
725 for (i=0; i<nlist.getLength(); i++)
726 mapping.add(new XMLEndpoint((Element)(nlist.item(i))));
728 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AssertionIDRequestService");
729 for (i=0; i<nlist.getLength(); i++)
730 idreq.add(new XMLEndpoint((Element)(nlist.item(i))));
732 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeProfile");
733 for (i=0; i<nlist.getLength(); i++) {
734 if (nlist.item(i).hasChildNodes())
735 attrprofs.add(nlist.item(i).getFirstChild().getNodeValue());
738 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"Attribute");
739 for (i=0; i<nlist.getLength(); i++) {
740 // For now, we need to convert these to plain SAML 1.1 attributes.
741 Element src=(Element)(nlist.item(i));
742 Element copy=e.getOwnerDocument().createElementNS(XML.SAML_NS,"Attribute");
743 copy.setAttributeNS(null,"AttributeName",src.getAttributeNS(null,"Name"));
744 copy.setAttributeNS(null,"AttributeNamespace",src.getAttributeNS(null,"NameFormat"));
745 src=XML.getFirstChildElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
746 while (src != null) {
747 src=XML.getNextSiblingElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
748 Element val=e.getOwnerDocument().createElementNS(XML.SAML_NS,"AttributeValue");
749 NamedNodeMap attrs = src.getAttributes();
750 for (int j=0; j<attrs.getLength(); j++)
751 val.setAttributeNodeNS((Attr)(e.getOwnerDocument().importNode(attrs.item(j),true)));
752 while (src.hasChildNodes())
753 val.appendChild(src.getFirstChild());
754 copy.appendChild(val);
756 attrs.add(SAMLAttribute.getInstance(copy));
760 protocolEnum.add(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS);
761 attrprofs.add(Constants.SHIB_ATTRIBUTE_NAMESPACE_URI);
763 domains = e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Domain");
764 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"HandleService");
765 for (i=0; i<nlist.getLength(); i++) {
766 // Manufacture an endpoint for the "Shib" binding.
768 new XMLEndpoint(Constants.SHIB_AUTHNREQUEST_PROFILE_URI,((Element)nlist.item(i)).getAttributeNS(null,"Location"))
771 // We're going to "mock up" a KeyDescriptor that contains the specified Name as a ds:KeyName.
772 Element kd=e.getOwnerDocument().createElementNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
773 Element ki=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyInfo");
774 Element kn=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyName");
776 e.getOwnerDocument().createTextNode(((Element)nlist.item(i)).getAttributeNS(null,"Name"))
780 kd.setAttributeNS(null,"use","signing");
781 keys.add(new XMLKeyDescriptor(kd));
785 if (domains != null) {
786 for (int i=0; i < domains.getLength(); i++) {
787 String dom=(domains.item(i).hasChildNodes()) ? domains.item(i).getFirstChild().getNodeValue() : null;
789 String regexp=XML.assign(((Element)domains.item(i)).getAttributeNS(null,"regexp"));
791 new Scope(dom,(XML.safeCompare(regexp,"true") || XML.safeCompare(regexp,"1")))
798 public Iterator getScopes() {
799 return scopes.iterator();
802 public boolean getWantAuthnRequestsSigned() {
803 return wantAuthnRequestsSigned;
806 public EndpointManager getSingleSignOnServiceManager() {
810 public EndpointManager getNameIDMappingServiceManager() {
814 public EndpointManager getAssertionIDRequestServiceManager() {
818 public Iterator getAttributeProfiles() {
819 return attrprofs.iterator();
822 public Iterator getAttributes() {
823 return attrs.iterator();
827 class AARole extends Role implements AttributeAuthorityDescriptor, ScopedRoleDescriptor {
828 private ArrayList /* <Scope> */ scopes = new ArrayList();
829 private XMLEndpointManager query = new XMLEndpointManager();
830 private XMLEndpointManager idreq = new XMLEndpointManager();
831 private ArrayList /* <String> */ attrprofs = new ArrayList();
832 private ArrayList /* <String> */ formats = new ArrayList();
833 private ArrayList /* <SAMLAttribute> */ attrs = new ArrayList();
835 public AARole(XMLEntityDescriptor provider, long validUntil, Element e) throws SAMLException {
836 super(provider, validUntil, e);
837 NodeList domains=null;
839 // Check the root element namespace. If SAML2, assume it's the std schema.
840 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
842 // Check for extensions.
843 Element ext=XML.getFirstChildElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions");
845 // Save off any domain elements for later.
846 domains = ext.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"Scope");
850 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeService");
851 for (i=0; i<nlist.getLength(); i++)
852 query.add(new XMLEndpoint((Element)(nlist.item(i))));
854 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AssertionIDRequestService");
855 for (i=0; i<nlist.getLength(); i++)
856 idreq.add(new XMLEndpoint((Element)(nlist.item(i))));
858 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeProfile");
859 for (i=0; i<nlist.getLength(); i++) {
860 if (nlist.item(i).hasChildNodes())
861 attrprofs.add(nlist.item(i).getFirstChild().getNodeValue());
864 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"Attribute");
865 for (i=0; i<nlist.getLength(); i++) {
866 // For now, we need to convert these to plain SAML 1.1 attributes.
867 Element src=(Element)(nlist.item(i));
868 Element copy=e.getOwnerDocument().createElementNS(XML.SAML_NS,"Attribute");
869 copy.setAttributeNS(null,"AttributeName",src.getAttributeNS(null,"Name"));
870 copy.setAttributeNS(null,"AttributeNamespace",src.getAttributeNS(null,"NameFormat"));
871 src=XML.getFirstChildElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
872 while (src != null) {
873 src=XML.getNextSiblingElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
874 Element val=e.getOwnerDocument().createElementNS(XML.SAML_NS,"AttributeValue");
875 NamedNodeMap attrs = src.getAttributes();
876 for (int j=0; j<attrs.getLength(); j++)
877 val.setAttributeNodeNS((Attr)(e.getOwnerDocument().importNode(attrs.item(j),true)));
878 while (src.hasChildNodes())
879 val.appendChild(src.getFirstChild());
880 copy.appendChild(val);
882 attrs.add(SAMLAttribute.getInstance(copy));
886 // For old style, we just do SAML 1.1 compatibility with Shib handles.
887 protocolEnum.add(XML.SAML11_PROTOCOL_ENUM);
888 formats.add(Constants.SHIB_NAMEID_FORMAT_URI);
889 attrprofs.add(Constants.SHIB_ATTRIBUTE_NAMESPACE_URI);
890 domains = e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Domain");
892 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AttributeAuthority");
893 for (i=0; i<nlist.getLength(); i++) {
894 // Manufacture an endpoint for the SOAP binding.
898 ((Element)nlist.item(i)).getAttributeNS(null,"Location")
902 // We're going to "mock up" a KeyDescriptor that contains the specified Name as a ds:KeyName.
903 Element kd=e.getOwnerDocument().createElementNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
904 Element ki=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyInfo");
905 Element kn=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyName");
907 e.getOwnerDocument().createTextNode(((Element)nlist.item(i)).getAttributeNS(null,"Name"))
911 kd.setAttributeNS(null,"use","signing");
912 keys.add(new XMLKeyDescriptor(kd));
916 if (domains != null) {
917 for (int i=0; i < domains.getLength(); i++) {
918 String dom=(domains.item(i).hasChildNodes()) ? domains.item(i).getFirstChild().getNodeValue() : null;
920 String regexp=XML.assign(((Element)domains.item(i)).getAttributeNS(null,"regexp"));
922 new Scope(dom,(XML.safeCompare(regexp,"true") || XML.safeCompare(regexp,"1")))
929 public Iterator getScopes() {
930 return scopes.iterator();
933 public EndpointManager getAttributeServiceManager() {
937 public EndpointManager getAssertionIDRequestServiceManager() {
941 public Iterator getAttributeProfiles() {
942 return attrprofs.iterator();
945 public Iterator getAttributes() {
946 return attrs.iterator();
949 public Iterator getNameIDFormats() {
950 return formats.iterator();
954 class SPRole extends SSORole implements SPSSODescriptor {
955 private boolean authnRequestsSigned = false;
956 private boolean wantAssertionsSigned = false;
957 private XMLEndpointManager asc = new XMLEndpointManager();
959 public SPRole(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
960 super(provider, validUntil, e);
962 // Check the root element namespace. If SAML2, assume it's the std schema.
963 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
964 String flag=XML.assign(e.getAttributeNS(null,"AuthnRequestsSigned"));
965 authnRequestsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
966 flag=XML.assign(e.getAttributeNS(null,"WantAssertionsSigned"));
967 wantAssertionsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
970 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AssertionConsumerService");
971 for (i=0; i<nlist.getLength(); i++)
972 asc.add(new XMLIndexedEndpoint((Element)(nlist.item(i))));
975 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"Attribute");
976 for (i=0; i<nlist.getLength(); i++) {
977 // For now, we need to convert these to plain SAML 1.1 attributes.
978 Element src=(Element)(nlist.item(i));
979 Element copy=e.getOwnerDocument().createElementNS(XML.SAML_NS,"Attribute");
980 copy.setAttributeNS(null,"AttributeName",src.getAttributeNS(null,"Name"));
981 copy.setAttributeNS(null,"AttributeNamespace",src.getAttributeNS(null,"NameFormat"));
982 src=XML.getFirstChildElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
983 while (src != null) {
984 src=XML.getNextSiblingElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
985 Element val=e.getOwnerDocument().createElementNS(XML.SAML_NS,"AttributeValue");
986 NamedNodeMap attrs = src.getAttributes();
987 for (int j=0; j<attrs.getLength(); j++)
988 val.setAttributeNodeNS((Attr)(e.getOwnerDocument().importNode(attrs.item(j),true)));
989 while (src.hasChildNodes())
990 val.appendChild(src.getFirstChild());
991 copy.appendChild(val);
993 attrs.add(SAMLAttribute.getInstance(copy));
999 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AssertionConsumerServiceURL");
1000 for (i=0; i<nlist.getLength(); i++) {
1001 // Manufacture an endpoint for the POST profile.
1003 new XMLEndpoint(SAMLBrowserProfile.PROFILE_POST_URI,((Element)nlist.item(i)).getAttributeNS(null,"Location"))
1007 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AttributeRequester");
1008 for (i=0; i<nlist.getLength(); i++) {
1009 // We're going to "mock up" a KeyDescriptor that contains the specified Name as a ds:KeyName.
1010 Element kd=e.getOwnerDocument().createElementNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
1011 Element ki=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyInfo");
1012 Element kn=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyName");
1014 e.getOwnerDocument().createTextNode(((Element)nlist.item(i)).getAttributeNS(null,"Name"))
1018 kd.setAttributeNS(null,"use","signing");
1019 keys.add(new XMLKeyDescriptor(kd));
1024 public boolean getAuthnRequestsSigned() {
1025 return authnRequestsSigned;
1028 public boolean getWantAssertionsSigned() {
1029 return wantAssertionsSigned;
1032 public EndpointManager getAssertionConsumerServiceManager() {
1036 public Iterator getAttributeConsumingServices() {
1037 // TODO Auto-generated method stub
1041 public AttributeConsumingService getDefaultAttributeConsumingService() {
1042 // TODO Auto-generated method stub
1046 public AttributeConsumingService getAttributeConsumingServiceByID(String id) {
1047 // TODO Auto-generated method stub
1052 class AttributeRequesterRole extends Role implements AttributeRequesterDescriptor {
1053 private boolean wantAssertionsSigned = false;
1054 private ArrayList /* <String> */ formats = new ArrayList();
1056 public AttributeRequesterRole(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
1057 super(provider, validUntil, e);
1059 String flag=XML.assign(e.getAttributeNS(null,"WantAssertionsSigned"));
1060 wantAssertionsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
1062 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"NameIDFormat");
1063 for (int i = 0; i < nlist.getLength(); i++) {
1064 if (nlist.item(i).hasChildNodes()) {
1065 Node tnode = nlist.item(i).getFirstChild();
1066 if (tnode != null && tnode.getNodeType() == Node.TEXT_NODE) {
1067 formats.add(tnode.getNodeValue());
1073 public boolean getWantAssertionsSigned() {
1074 return wantAssertionsSigned;
1077 public Iterator getNameIDFormats() {
1078 return formats.iterator();
1081 public Iterator getAttributeConsumingServices() {
1082 // TODO Auto-generated method stub
1086 public AttributeConsumingService getDefaultAttributeConsumingService() {
1087 // TODO Auto-generated method stub
1091 public AttributeConsumingService getAttributeConsumingServiceByID(String id) {
1092 // TODO Auto-generated method stub
1097 class XMLEntityDescriptor implements ExtendedEntityDescriptor {
1098 private Element root = null;
1099 private EntitiesDescriptor parent = null;
1100 private String id = null;
1101 private URL errorURL = null;
1102 private Organization org = null;
1103 private ArrayList /* <ContactPerson> */ contacts = new ArrayList();
1104 private ArrayList /* <RoleDescriptor> */ roles = new ArrayList();
1105 private AffiliationDescriptor affiliation = null;
1106 private HashMap /* <String,String> */ locs = new HashMap();
1107 private long validUntil = Long.MAX_VALUE;
1108 private ArrayList /* <KeyAuthority> */ keyauths = new ArrayList();
1110 public XMLEntityDescriptor(Element e, XMLMetadataProvider wrapper, long validUntil, EntitiesDescriptor parent) throws SAMLException {
1112 this.parent = parent;
1113 this.validUntil = validUntil;
1115 // Check the root element namespace. If SAML2, assume it's the std schema.
1116 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
1117 id=e.getAttributeNS(null,"entityID");
1119 if (e.hasAttributeNS(null,"validUntil")) {
1120 SimpleDateFormat formatter = null;
1121 String dateTime = XML.assign(e.getAttributeNS(null,"validUntil"));
1122 int dot = dateTime.indexOf('.');
1124 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
1126 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
1127 formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
1129 this.validUntil=Math.min(validUntil,formatter.parse(dateTime).getTime());
1131 catch (ParseException e1) {
1132 log.warn("Entity descriptor contains invalid expiration time");
1136 Element child=XML.getFirstChildElement(e);
1137 while (child != null) {
1138 // Process the various kinds of children that we care about...
1139 if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions")) {
1140 Element ext = XML.getFirstChildElement(child,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1141 while (ext != null) {
1142 keyauths.add(new XMLKeyAuthority(ext));
1143 ext = XML.getNextSiblingElement(ext,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1146 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ContactPerson")) {
1147 contacts.add(new XMLContactPerson(child));
1149 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Organization")) {
1150 org=new XMLOrganization(child);
1152 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AdditionalMetadataLocation")) {
1153 Node loc=child.getFirstChild();
1155 locs.put(child.getAttributeNS(null,"namespace"),loc.getNodeValue());
1157 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"IDPSSODescriptor")) {
1158 roles.add(new IDPRole(this,validUntil,child));
1160 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeAuthorityDescriptor")) {
1161 roles.add(new AARole(this,validUntil,child));
1163 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SPSSODescriptor")) {
1164 roles.add(new SPRole(this,validUntil,child));
1166 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"RoleDescriptor")) {
1167 QName xsitype = XML.getQNameAttribute(child,XML.XSI_NS,"type");
1168 if (edu.internet2.middleware.shibboleth.common.XML.SAML2METAEXT_NS.equals(xsitype.getNamespaceURI()) &&
1169 "AttributeRequesterDescriptorType".equals(xsitype.getLocalPart()))
1170 roles.add(new AttributeRequesterRole(this,validUntil,child));
1172 child = XML.getNextSiblingElement(child);
1176 id=e.getAttributeNS(null,"Name");
1177 if (e.hasAttributeNS(null,"ErrorURL")) {
1179 errorURL=new URL(e.getAttributeNS(null,"ErrorURL"));
1181 catch (MalformedURLException e1) {
1182 log.error("Site descriptor contains invalid ErrorURL");
1186 boolean idp=false,aa=false,sp=false; // only want to build a role once
1187 Element child=XML.getFirstChildElement(e);
1188 while (child != null) {
1189 // Process the various kinds of OriginSite children that we care about...
1190 if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Contact")) {
1191 contacts.add(new XMLContactPerson(child));
1193 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"HandleService") && !idp) {
1194 // Create the IDP role if needed.
1195 roles.add(new IDPRole(this, validUntil, e));
1198 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AttributeAuthority") && !aa) {
1199 // Create the AA role if needed.
1200 roles.add(new AARole(this, validUntil, e));
1203 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AssertionConsumerServiceURL") && !sp) {
1204 // Create the SP role if needed.
1205 roles.add(new SPRole(this, validUntil, e));
1208 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AttributeRequester") && !sp) {
1209 // Create the SP role if needed.
1210 roles.add(new SPRole(this, validUntil, e));
1213 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Alias") && (org == null)) {
1214 // Create the Organization.
1215 org = new XMLOrganization(child);
1217 child = XML.getNextSiblingElement(child);
1221 // Each map entry is a list of the descriptors with this ID.
1223 if (wrapper.sites.containsKey(id)) {
1224 list = (ArrayList)wrapper.sites.get(id);
1227 list = new ArrayList();
1228 wrapper.sites.put(id,list);
1232 // Look for an IdP role, and register the artifact source ID and endpoints.
1234 for (int i=0; i<roles.size(); i++) {
1235 if (roles.get(i) instanceof IDPRole) {
1236 idp = (IDPRole)roles.get(i);
1237 if (idp.sourceId != null) {
1238 if (wrapper.sources.containsKey(idp.sourceId)) {
1239 list = (ArrayList)wrapper.sources.get(idp.sourceId);
1242 list = new ArrayList();
1243 wrapper.sources.put(idp.sourceId,list);
1250 sourceId = new String(Hex.encode(Util.generateSourceId(id)));
1252 catch (NoSuchAlgorithmException e1) {
1253 log.error("caught exception while encoding sourceId: " + e1.getMessage());
1256 if (wrapper.sources.containsKey(sourceId)) {
1257 list = (ArrayList)wrapper.sources.get(sourceId);
1260 list = new ArrayList();
1261 wrapper.sources.put(sourceId,list);
1265 Iterator locs=idp.getArtifactResolutionServiceManager().getEndpoints();
1266 while (locs.hasNext()) {
1267 String loc=((Endpoint)locs.next()).getLocation();
1268 if (wrapper.sources.containsKey(loc)) {
1269 list = (ArrayList)wrapper.sources.get(loc);
1272 list = new ArrayList();
1273 wrapper.sources.put(loc,list);
1281 public String getId() {
1285 public boolean isValid() {
1286 return System.currentTimeMillis() < validUntil;
1289 public Iterator getRoleDescriptors() {
1290 return roles.iterator();
1293 public RoleDescriptor getRoleByType(Class type, String protocol) {
1294 for (int i=0; i<roles.size(); i++) {
1295 RoleDescriptor role = (RoleDescriptor)roles.get(i);
1296 if (type.isInstance(role) && role.hasSupport(protocol))
1302 public IDPSSODescriptor getIDPSSODescriptor(String protocol) {
1303 return (IDPSSODescriptor)getRoleByType(IDPSSODescriptor.class, protocol);
1306 public SPSSODescriptor getSPSSODescriptor(String protocol) {
1307 return (SPSSODescriptor)getRoleByType(SPSSODescriptor.class, protocol);
1310 public AuthnAuthorityDescriptor getAuthnAuthorityDescriptor(String protocol) {
1311 return (AuthnAuthorityDescriptor)getRoleByType(AuthnAuthorityDescriptor.class, protocol);
1314 public AttributeAuthorityDescriptor getAttributeAuthorityDescriptor(String protocol) {
1315 return (AttributeAuthorityDescriptor)getRoleByType(AttributeAuthorityDescriptor.class, protocol);
1318 public AttributeRequesterDescriptor getAttributeRequesterDescriptor(String protocol) {
1319 return (AttributeRequesterDescriptor)getRoleByType(AttributeRequesterDescriptor.class, protocol);
1322 public PDPDescriptor getPDPDescriptor(String protocol) {
1323 return (PDPDescriptor)getRoleByType(PDPDescriptor.class, protocol);
1326 public AffiliationDescriptor getAffiliationDescriptor() {
1330 public Organization getOrganization() {
1334 public Iterator getContactPersons() {
1335 return contacts.iterator();
1338 public Map getAdditionalMetadataLocations() {
1339 return Collections.unmodifiableMap(locs);
1342 public EntitiesDescriptor getEntitiesDescriptor() {
1346 public Element getElement() {
1350 public long getValidUntil() {
1354 public URL getErrorURL() {
1358 public Iterator getKeyAuthorities() {
1359 return keyauths.iterator();
1363 class XMLEntitiesDescriptor implements ExtendedEntitiesDescriptor {
1364 private Element root = null;
1365 private EntitiesDescriptor parent = null;
1366 private String name = null;
1367 private ArrayList /* <EntitiesDescriptor> */ groups = new ArrayList();
1368 private ArrayList /* <EntityDescriptor> */ providers = new ArrayList();
1369 private long validUntil = Long.MAX_VALUE;
1370 private ArrayList /* <KeyAuthority> */ keyauths = new ArrayList();
1372 public XMLEntitiesDescriptor(Element e, XMLMetadataProvider wrapper, long validUntil, EntitiesDescriptor parent) throws SAMLException {
1374 this.parent = parent;
1375 this.validUntil = validUntil;
1376 name = XML.assign(e.getAttributeNS(null, "Name"));
1378 // Check the root element namespace. If SAML2, assume it's the std schema.
1379 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
1381 if (e.hasAttributeNS(null,"validUntil")) {
1382 SimpleDateFormat formatter = null;
1383 String dateTime = XML.assign(e.getAttributeNS(null,"validUntil"));
1384 int dot = dateTime.indexOf('.');
1386 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
1388 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
1389 formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
1391 this.validUntil=Math.min(validUntil,formatter.parse(dateTime).getTime());
1393 catch (ParseException e1) {
1394 log.warn("Entities descriptor contains invalid expiration time");
1398 e = XML.getFirstChildElement(e);
1400 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions")) {
1401 Element ext = XML.getFirstChildElement(e,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1402 while (ext != null) {
1403 keyauths.add(new XMLKeyAuthority(ext));
1404 ext = XML.getNextSiblingElement(ext,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1407 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EntitiesDescriptor"))
1408 groups.add(new XMLEntitiesDescriptor(e, wrapper, this.validUntil, this));
1409 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EntityDescriptor"))
1410 providers.add(new XMLEntityDescriptor(e, wrapper, this.validUntil, this));
1411 e = XML.getNextSiblingElement(e);
1415 e = XML.getFirstChildElement(e);
1417 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"SiteGroup"))
1418 groups.add(new XMLEntitiesDescriptor(e, wrapper, this.validUntil, this));
1419 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"OriginSite"))
1420 providers.add(new XMLEntityDescriptor(e, wrapper, this.validUntil, this));
1421 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"DestinationSite"))
1422 providers.add(new XMLEntityDescriptor(e, wrapper, this.validUntil, this));
1423 e = XML.getNextSiblingElement(e);
1428 public String getName() {
1432 public boolean isValid() {
1433 return System.currentTimeMillis() < validUntil;
1436 public EntitiesDescriptor getEntitiesDescriptor() {
1440 public Iterator getEntitiesDescriptors() {
1441 return groups.iterator();
1444 public Iterator getEntityDescriptors() {
1445 return providers.iterator();
1448 public Element getElement() {
1452 public Iterator getKeyAuthorities() {
1453 return keyauths.iterator();