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.URI;
48 import org.opensaml.artifact.Util;
49 import org.w3c.dom.Attr;
50 import org.w3c.dom.Element;
51 import org.w3c.dom.NamedNodeMap;
52 import org.w3c.dom.Node;
53 import org.w3c.dom.NodeList;
55 import edu.internet2.middleware.shibboleth.common.Constants;
56 import edu.internet2.middleware.shibboleth.metadata.*;
59 * @author Scott Cantor
61 public class XMLMetadataProvider implements Metadata {
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 byte[] sourceId = ((SAMLArtifactType0001)artifact).getSourceId();
111 String sourceString = new String(Hex.encode(sourceId));
112 list = (ArrayList)sources.get(sourceString);
114 else if (artifact instanceof SAMLArtifactType0002) {
115 URI sourceLocation = ((SAMLArtifactType0002)artifact).getSourceLocation();
116 String sourceLocationString = sourceLocation.toString();
117 list = (ArrayList)sources.get(sourceLocationString);
120 log.error("unsupported artifact type (" + artifact.getTypeCode().toString() + ")");
124 long now = System.currentTimeMillis();
125 for (int i=0; i<list.size(); i++) {
126 if (now < ((XMLEntityDescriptor)list.get(i)).getValidUntil())
127 return (EntityDescriptor)list.get(i);
129 if (!strict && list.size() > 0)
130 return (EntityDescriptor)list.get(0);
135 public EntityDescriptor lookup(String id) {
136 return lookup(id, true);
139 public EntityDescriptor lookup(Artifact artifact) {
140 return lookup(artifact, true);
143 public EntityDescriptor getRootEntity() {
147 public EntitiesDescriptor getRootEntities() {
151 class XMLEndpoint implements Endpoint {
152 private Element root = null;
153 private String binding = null;
154 private String location = null;
155 private String resploc = null;
157 XMLEndpoint(Element e) {
159 binding = XML.assign(e.getAttributeNS(null,"Binding"));
160 location = XML.assign(e.getAttributeNS(null,"Location"));
161 resploc = XML.assign(e.getAttributeNS(null,"ResponseLocation"));
164 XMLEndpoint(String binding, String location) {
165 this.binding = binding;
166 this.location = location;
169 public String getBinding() {
173 public String getLocation() {
177 public String getResponseLocation() {
181 public Element getElement() {
186 class XMLIndexedEndpoint extends XMLEndpoint implements IndexedEndpoint {
187 private int index = 0;
189 XMLIndexedEndpoint(Element e) {
191 index = Integer.parseInt(e.getAttributeNS(null,"index"));
194 public int getIndex() {
199 class XMLEndpointManager implements EndpointManager {
200 private ArrayList endpoints = new ArrayList();
201 Endpoint soft = null; // Soft default (not explicit)
202 Endpoint hard = null; // Hard default (explicit)
204 public Iterator getEndpoints() {
205 return endpoints.iterator();
208 public Endpoint getDefaultEndpoint() {
209 if (hard != null) return hard;
210 if (soft != null) return soft;
211 if (!endpoints.isEmpty()) return (Endpoint)endpoints.get(0);
215 public Endpoint getEndpointByIndex(int index) {
216 for (int i=0; i < endpoints.size(); i++) {
217 if (endpoints.get(i) instanceof IndexedEndpoint && index==((IndexedEndpoint)endpoints.get(i)).getIndex())
218 return (Endpoint)endpoints.get(i);
223 public Endpoint getEndpointByBinding(String binding) {
224 for (int i=0; i < endpoints.size(); i++) {
225 if (binding.equals(((Endpoint)endpoints.get(i)).getBinding()))
226 return (Endpoint)endpoints.get(i);
231 protected void add(Endpoint e) {
233 if (hard == null && e.getElement() != null) {
234 String v=XML.assign(e.getElement().getAttributeNS(null,"isDefault"));
235 if (v != null && (v.equals("1") || v.equals("true"))) // explicit default
237 else if (v == null && soft == null) // implicit default
240 else if (hard == null && soft == null) {
241 // No default yet, so this one qualifies as an implicit.
247 class XMLKeyDescriptor implements KeyDescriptor {
249 private int use = KeyDescriptor.UNSPECIFIED;
250 private KeyInfo keyInfo = null;
251 private ArrayList /* <XMLEncryptionMethod> */ methods = new ArrayList();
253 XMLKeyDescriptor(Element e) {
254 if (XML.safeCompare(e.getAttributeNS(null,"use"),"encryption"))
255 use = KeyDescriptor.ENCRYPTION;
256 else if (XML.safeCompare(e.getAttributeNS(null,"use"),"signing"))
257 use = KeyDescriptor.SIGNING;
259 e = XML.getFirstChildElement(e);
261 keyInfo = new KeyInfo(e, null);
263 catch (XMLSecurityException e1) {
264 log.error("unable to process ds:KeyInfo element: " + e1.getMessage());
267 e = XML.getNextSiblingElement(e);
268 while (e != null && XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EncryptionMethod")) {
269 methods.add(new XMLEncryptionMethod(e));
273 public int getUse() {
277 public Iterator getEncryptionMethods() {
278 return methods.iterator();
281 public KeyInfo getKeyInfo() {
286 class XMLEncryptionMethod implements EncryptionMethod {
289 String params = null;
292 public XMLEncryptionMethod(Element e) {
293 alg = XML.assign(e.getAttributeNS(null, "Algorithm"));
294 e = XML.getFirstChildElement(e);
296 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.XMLENC_NS,"KeySize")) {
297 if (e.hasChildNodes())
298 size = Integer.parseInt(e.getFirstChild().getNodeValue());
300 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.XMLENC_NS,"OAEParams")) {
301 if (e.hasChildNodes())
302 params = XML.assign(e.getFirstChild().getNodeValue());
304 e = XML.getNextSiblingElement(e);
308 public String getAlgorithm() {
312 public int getKeySize() {
316 public byte[] getOAEPparams() {
317 return params.getBytes();
320 public Iterator getEncryptionMethodInformation() {
324 public void setKeySize(int arg0) {
325 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
328 public void setOAEPparams(byte[] arg0) {
329 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
332 public void addEncryptionMethodInformation(Element arg0) {
333 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
336 public void removeEncryptionMethodInformation(Element arg0) {
337 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
341 class XMLKeyAuthority implements KeyAuthority {
342 private int depth = 1;
343 private ArrayList /* <KeyInfo> */ keys = new ArrayList();
345 XMLKeyAuthority(Element e) {
346 if (e.hasAttributeNS(null,"VerifyDepth"))
347 depth = Integer.parseInt(e.getAttributeNS(null,"VerifyDepth"));
348 e = XML.getFirstChildElement(e, XML.XMLSIG_NS, "KeyInfo");
351 keys.add(new KeyInfo(e, null));
353 catch (XMLSecurityException e1) {
354 log.error("unable to process ds:KeyInfo element: " + e1.getMessage());
356 e = XML.getNextSiblingElement(e, XML.XMLSIG_NS, "KeyInfo");
360 public int getVerifyDepth() {
364 public Iterator getKeyInfos() {
365 return keys.iterator();
370 class XMLOrganization implements Organization {
371 private HashMap /* <String,String> */ names = new HashMap();
372 private HashMap /* <String,String> */ displays = new HashMap();
373 private HashMap /* <String,URL> */ urls = new HashMap();
375 public XMLOrganization(Element e) throws MetadataException {
376 // Old metadata or new?
377 if (XML.isElementNamed(e, edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Alias")) {
378 if (e.hasChildNodes()) {
379 names.put("en",XML.assign(e.getFirstChild().getNodeValue()));
380 displays.put("en",XML.assign(e.getFirstChild().getNodeValue()));
384 e=XML.getFirstChildElement(e);
386 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"OrganizationName")) {
387 if (e.hasChildNodes()) {
388 names.put(e.getAttributeNS(XML.XML_NS,"lang"),XML.assign(e.getFirstChild().getNodeValue()));
391 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"OrganizationDisplayName")) {
392 if (e.hasChildNodes()) {
393 displays.put(e.getAttributeNS(XML.XML_NS,"lang"),XML.assign(e.getFirstChild().getNodeValue()));
396 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"OrganizationURL")) {
397 if (e.hasChildNodes()) {
400 u = new URL(e.getFirstChild().getNodeValue());
402 catch (MalformedURLException e1) {
403 throw new MetadataException("OrganizationURL was invalid: " + e1);
405 urls.put(e.getAttributeNS(XML.XML_NS,"lang"),u);
408 e=XML.getNextSiblingElement(e);
413 public String getName() {
414 return getName("en");
417 public String getName(String lang) {
418 return (String)names.get(lang);
421 public String getDisplayName() {
422 return getDisplayName("en");
425 public String getDisplayName(String lang) {
426 return (String)displays.get(lang);
429 public URL getURL() {
433 public URL getURL(String lang) {
434 return (URL)urls.get(lang);
439 class XMLContactPerson implements ContactPerson {
440 private Element root = null;
442 private String company = null;
443 private String givenName = null;
444 private String surName = null;
445 private ArrayList /* <String> */ emails = new ArrayList();
446 private ArrayList /* <String> */ telephones = new ArrayList();
448 public XMLContactPerson(Element e) throws MetadataException {
450 String rawType = null;
452 // Old metadata or new?
453 if (XML.isElementNamed(root, edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Contact")) {
454 rawType = root.getAttributeNS(null,"Type");
455 surName = XML.assign(root.getAttributeNS(null,"Name"));
456 if (XML.isEmpty(surName)) {
457 throw new MetadataException("Contact is missing Name attribute.");
459 if (root.hasAttributeNS(null,"Email"))
460 emails.add(e.getAttributeNS(null,"Email"));
463 rawType = root.getAttributeNS(null,"contactType");
464 e=XML.getFirstChildElement(root);
466 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Company")) {
467 if (e.hasChildNodes())
468 company=XML.assign(e.getFirstChild().getNodeValue());
470 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"GivenName")) {
471 if (e.hasChildNodes())
472 givenName=XML.assign(e.getFirstChild().getNodeValue());
474 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SurName")) {
475 if (e.hasChildNodes())
476 surName=XML.assign(e.getFirstChild().getNodeValue());
478 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EmailAddress")) {
479 if (e.hasChildNodes())
480 emails.add(XML.assign(e.getFirstChild().getNodeValue()));
482 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"TelephoneNumber")) {
483 if (e.hasChildNodes())
484 telephones.add(XML.assign(e.getFirstChild().getNodeValue()));
486 e=XML.getNextSiblingElement(e);
490 if (rawType.equalsIgnoreCase("TECHNICAL")) {
491 type = ContactPerson.TECHNICAL;
492 } else if (rawType.equalsIgnoreCase("SUPPORT")) {
493 type = ContactPerson.SUPPORT;
494 } else if (rawType.equalsIgnoreCase("ADMINISTRATIVE")) {
495 type = ContactPerson.ADMINISTRATIVE;
496 } else if (rawType.equalsIgnoreCase("BILLING")) {
497 type = ContactPerson.BILLING;
498 } else if (rawType.equalsIgnoreCase("OTHER")) {
499 type = ContactPerson.OTHER;
501 throw new MetadataException("Contact has unknown contact type.");
505 public int getType() {
509 public String getGivenName() {
513 public String getSurName() {
517 public String getCompany() {
521 public Iterator getEmailAddresses() {
522 return emails.iterator();
525 public Iterator getTelephoneNumbers() {
526 return telephones.iterator();
529 public Element getElement() {
534 class Role implements RoleDescriptor {
535 private Element root = null;
536 private XMLEntityDescriptor provider = null;
537 private URL errorURL = null;
538 private Organization org = null;
539 private ArrayList /* <ContactPerson> */ contacts = new ArrayList();
540 private long validUntil = Long.MAX_VALUE;
541 protected ArrayList /* <String> */ protocolEnum = new ArrayList();
542 protected ArrayList /* <KeyDescriptor> */ keys = new ArrayList();
544 public Role(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
546 this.validUntil = validUntil;
547 this.provider = provider;
549 // Check the root element namespace. If SAML2, assume it's the std schema.
550 if (e != null && edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
552 if (e.hasAttributeNS(null,"validUntil")) {
553 SimpleDateFormat formatter = null;
554 String dateTime = XML.assign(e.getAttributeNS(null,"validUntil"));
555 int dot = dateTime.indexOf('.');
557 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
559 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
560 formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
562 this.validUntil=Math.min(validUntil,formatter.parse(dateTime).getTime());
564 catch (ParseException e1) {
565 log.warn("Role descriptor contains invalid expiration time");
569 if (e.hasAttributeNS(null,"errorURL")) {
571 errorURL=new URL(e.getAttributeNS(null,"errorURL"));
573 catch (MalformedURLException e1) {
574 log.error("Role descriptor contains malformed errorURL");
578 // Chop the protocol list into pieces...assume any whitespace can appear in between.
579 protocolEnum.addAll(Arrays.asList(e.getAttributeNS(null,"protocolSupportEnumeration").split("\\s")));
581 e = XML.getFirstChildElement(root,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
583 keys.add(new XMLKeyDescriptor(e));
584 e = XML.getNextSiblingElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
587 e = XML.getFirstChildElement(root,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Organization");
589 org=new XMLOrganization(e);
591 e = XML.getFirstChildElement(root,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ContactPerson");
593 contacts.add(new XMLContactPerson(e));
594 e = XML.getNextSiblingElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ContactPerson");
599 public EntityDescriptor getEntityDescriptor() {
603 public Iterator getProtocolSupportEnumeration() {
604 return protocolEnum.iterator();
607 public boolean hasSupport(String version) {
608 return protocolEnum.contains(version);
611 public boolean isValid() {
612 return System.currentTimeMillis() < validUntil;
615 public URL getErrorURL() {
616 return (errorURL != null) ? errorURL : provider.getErrorURL();
619 public Iterator getKeyDescriptors() {
620 return keys.iterator();
623 public Organization getOrganization() {
624 return (org != null) ? org : provider.getOrganization();
627 public Iterator getContactPersons() {
628 return (contacts.isEmpty()) ? provider.getContactPersons() : contacts.iterator();
631 public Element getElement() {
636 class SSORole extends Role implements SSODescriptor {
637 private XMLEndpointManager artifact = new XMLEndpointManager();
638 private XMLEndpointManager logout = new XMLEndpointManager();
639 private XMLEndpointManager nameid = new XMLEndpointManager();
640 private ArrayList /* <String> */ formats = new ArrayList();
642 public SSORole(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
643 super(provider, validUntil, e);
645 // Check the root element namespace. If SAML2, assume it's the std schema.
646 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
648 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ArtifactResolutionService");
649 for (i=0; i<nlist.getLength(); i++)
650 artifact.add(new XMLIndexedEndpoint((Element)nlist.item(i)));
652 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SingleLogoutService");
653 for (i=0; i<nlist.getLength(); i++)
654 logout.add(new XMLEndpoint((Element)nlist.item(i)));
656 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ManageNameIDService");
657 for (i=0; i<nlist.getLength(); i++)
658 nameid.add(new XMLEndpoint((Element)nlist.item(i)));
660 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"NameIDFormat");
661 for (i = 0; i < nlist.getLength(); i++) {
662 if (nlist.item(i).hasChildNodes()) {
663 Node tnode = nlist.item(i).getFirstChild();
664 if (tnode != null && tnode.getNodeType() == Node.TEXT_NODE) {
665 formats.add(tnode.getNodeValue());
671 // For old style, we just do SAML 1.1 compatibility with Shib handles.
672 protocolEnum.add(XML.SAML11_PROTOCOL_ENUM);
673 formats.add(Constants.SHIB_NAMEID_FORMAT_URI);
677 public EndpointManager getArtifactResolutionServiceManager() {
681 public EndpointManager getSingleLogoutServiceManager() {
685 public EndpointManager getManageNameIDServiceManager() {
689 public Iterator getNameIDFormats() {
690 return formats.iterator();
694 class IDPRole extends SSORole implements IDPSSODescriptor, ScopedRoleDescriptor {
695 private ArrayList /* <Scope> */ scopes = new ArrayList();
696 private XMLEndpointManager sso = new XMLEndpointManager();
697 private XMLEndpointManager mapping = new XMLEndpointManager();
698 private XMLEndpointManager idreq = new XMLEndpointManager();
699 private ArrayList /* <String> */ attrprofs = new ArrayList();
700 private ArrayList /* <SAMLAttribute> */ attrs = new ArrayList();
701 private boolean wantAuthnRequestsSigned = false;
702 private String sourceId = null;
704 public IDPRole(XMLEntityDescriptor provider, long validUntil, Element e) throws SAMLException {
705 super(provider, validUntil, e);
706 NodeList domains=null;
708 // Check the root element namespace. If SAML2, assume it's the std schema.
709 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
710 String flag=XML.assign(e.getAttributeNS(null,"WantAuthnRequestsSigned"));
711 wantAuthnRequestsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
713 // Check for extensions.
714 Element ext=XML.getFirstChildElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions");
716 Element ext1=XML.getFirstChildElement(ext,XML.SAML_ARTIFACT_SOURCEID,"SourceID");
717 if (ext1 != null && ext1.hasChildNodes())
718 sourceId=ext1.getFirstChild().getNodeValue();
719 // Save off any domain elements for later.
720 domains = ext.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"Scope");
724 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SingleSignOnService");
725 for (i=0; i<nlist.getLength(); i++)
726 sso.add(new XMLEndpoint((Element)(nlist.item(i))));
728 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"NameIDMappingService");
729 for (i=0; i<nlist.getLength(); i++)
730 mapping.add(new XMLEndpoint((Element)(nlist.item(i))));
732 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AssertionIDRequestService");
733 for (i=0; i<nlist.getLength(); i++)
734 idreq.add(new XMLEndpoint((Element)(nlist.item(i))));
736 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeProfile");
737 for (i=0; i<nlist.getLength(); i++) {
738 if (nlist.item(i).hasChildNodes())
739 attrprofs.add(nlist.item(i).getFirstChild().getNodeValue());
742 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"Attribute");
743 for (i=0; i<nlist.getLength(); i++) {
744 // For now, we need to convert these to plain SAML 1.1 attributes.
745 Element src=(Element)(nlist.item(i));
746 Element copy=e.getOwnerDocument().createElementNS(XML.SAML_NS,"Attribute");
747 copy.setAttributeNS(null,"AttributeName",src.getAttributeNS(null,"Name"));
748 copy.setAttributeNS(null,"AttributeNamespace",src.getAttributeNS(null,"NameFormat"));
749 src=XML.getFirstChildElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
750 while (src != null) {
751 Element val=e.getOwnerDocument().createElementNS(XML.SAML_NS,"AttributeValue");
752 NamedNodeMap attrs = src.getAttributes();
753 for (int j=0; j<attrs.getLength(); j++)
754 val.setAttributeNodeNS((Attr)(e.getOwnerDocument().importNode(attrs.item(j),true)));
755 while (src.hasChildNodes())
756 val.appendChild(src.getFirstChild());
757 copy.appendChild(val);
758 src=XML.getNextSiblingElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
760 attrs.add(SAMLAttribute.getInstance(copy));
764 protocolEnum.add(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS);
765 attrprofs.add(Constants.SHIB_ATTRIBUTE_NAMESPACE_URI);
767 domains = e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Domain");
768 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"HandleService");
769 for (i=0; i<nlist.getLength(); i++) {
770 // Manufacture an endpoint for the "Shib" binding.
772 new XMLEndpoint(Constants.SHIB_AUTHNREQUEST_PROFILE_URI,((Element)nlist.item(i)).getAttributeNS(null,"Location"))
775 // We're going to "mock up" a KeyDescriptor that contains the specified Name as a ds:KeyName.
776 Element kd=e.getOwnerDocument().createElementNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
777 Element ki=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyInfo");
778 Element kn=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyName");
780 e.getOwnerDocument().createTextNode(((Element)nlist.item(i)).getAttributeNS(null,"Name"))
784 kd.setAttributeNS(null,"use","signing");
785 keys.add(new XMLKeyDescriptor(kd));
789 if (domains != null) {
790 for (int i=0; i < domains.getLength(); i++) {
791 String dom=(domains.item(i).hasChildNodes()) ? domains.item(i).getFirstChild().getNodeValue() : null;
793 String regexp=XML.assign(((Element)domains.item(i)).getAttributeNS(null,"regexp"));
795 new Scope(dom,(XML.safeCompare(regexp,"true") || XML.safeCompare(regexp,"1")))
802 public Iterator getScopes() {
803 return scopes.iterator();
806 public boolean getWantAuthnRequestsSigned() {
807 return wantAuthnRequestsSigned;
810 public EndpointManager getSingleSignOnServiceManager() {
814 public EndpointManager getNameIDMappingServiceManager() {
818 public EndpointManager getAssertionIDRequestServiceManager() {
822 public Iterator getAttributeProfiles() {
823 return attrprofs.iterator();
826 public Iterator getAttributes() {
827 return attrs.iterator();
831 class AARole extends Role implements AttributeAuthorityDescriptor, ScopedRoleDescriptor {
832 private ArrayList /* <Scope> */ scopes = new ArrayList();
833 private XMLEndpointManager query = new XMLEndpointManager();
834 private XMLEndpointManager idreq = new XMLEndpointManager();
835 private ArrayList /* <String> */ attrprofs = new ArrayList();
836 private ArrayList /* <String> */ formats = new ArrayList();
837 private ArrayList /* <SAMLAttribute> */ attrs = new ArrayList();
839 public AARole(XMLEntityDescriptor provider, long validUntil, Element e) throws SAMLException {
840 super(provider, validUntil, e);
841 NodeList domains=null;
843 // Check the root element namespace. If SAML2, assume it's the std schema.
844 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
846 // Check for extensions.
847 Element ext=XML.getFirstChildElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions");
849 // Save off any domain elements for later.
850 domains = ext.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"Scope");
854 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeService");
855 for (i=0; i<nlist.getLength(); i++)
856 query.add(new XMLEndpoint((Element)(nlist.item(i))));
858 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AssertionIDRequestService");
859 for (i=0; i<nlist.getLength(); i++)
860 idreq.add(new XMLEndpoint((Element)(nlist.item(i))));
862 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeProfile");
863 for (i=0; i<nlist.getLength(); i++) {
864 if (nlist.item(i).hasChildNodes())
865 attrprofs.add(nlist.item(i).getFirstChild().getNodeValue());
868 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"Attribute");
869 for (i=0; i<nlist.getLength(); i++) {
870 // For now, we need to convert these to plain SAML 1.1 attributes.
871 Element src=(Element)(nlist.item(i));
872 Element copy=e.getOwnerDocument().createElementNS(XML.SAML_NS,"Attribute");
873 copy.setAttributeNS(null,"AttributeName",src.getAttributeNS(null,"Name"));
874 copy.setAttributeNS(null,"AttributeNamespace",src.getAttributeNS(null,"NameFormat"));
875 src=XML.getFirstChildElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
876 while (src != null) {
877 Element val=e.getOwnerDocument().createElementNS(XML.SAML_NS,"AttributeValue");
878 NamedNodeMap attrs = src.getAttributes();
880 for (int j=0; j<attrs.getLength(); j++)
881 val.setAttributeNodeNS((Attr)(e.getOwnerDocument().importNode(attrs.item(j),true)));
883 while (src.hasChildNodes())
884 val.appendChild(src.getFirstChild());
885 copy.appendChild(val);
886 src=XML.getNextSiblingElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
888 attrs.add(SAMLAttribute.getInstance(copy));
892 // For old style, we just do SAML 1.1 compatibility with Shib handles.
893 protocolEnum.add(XML.SAML11_PROTOCOL_ENUM);
894 formats.add(Constants.SHIB_NAMEID_FORMAT_URI);
895 attrprofs.add(Constants.SHIB_ATTRIBUTE_NAMESPACE_URI);
896 domains = e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Domain");
898 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AttributeAuthority");
899 for (i=0; i<nlist.getLength(); i++) {
900 // Manufacture an endpoint for the SOAP binding.
904 ((Element)nlist.item(i)).getAttributeNS(null,"Location")
908 // We're going to "mock up" a KeyDescriptor that contains the specified Name as a ds:KeyName.
909 Element kd=e.getOwnerDocument().createElementNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
910 Element ki=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyInfo");
911 Element kn=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyName");
913 e.getOwnerDocument().createTextNode(((Element)nlist.item(i)).getAttributeNS(null,"Name"))
917 kd.setAttributeNS(null,"use","signing");
918 keys.add(new XMLKeyDescriptor(kd));
922 if (domains != null) {
923 for (int i=0; i < domains.getLength(); i++) {
924 String dom=(domains.item(i).hasChildNodes()) ? domains.item(i).getFirstChild().getNodeValue() : null;
926 String regexp=XML.assign(((Element)domains.item(i)).getAttributeNS(null,"regexp"));
928 new Scope(dom,(XML.safeCompare(regexp,"true") || XML.safeCompare(regexp,"1")))
935 public Iterator getScopes() {
936 return scopes.iterator();
939 public EndpointManager getAttributeServiceManager() {
943 public EndpointManager getAssertionIDRequestServiceManager() {
947 public Iterator getAttributeProfiles() {
948 return attrprofs.iterator();
951 public Iterator getAttributes() {
952 return attrs.iterator();
955 public Iterator getNameIDFormats() {
956 return formats.iterator();
960 class SPRole extends SSORole implements SPSSODescriptor {
961 private boolean authnRequestsSigned = false;
962 private boolean wantAssertionsSigned = false;
963 private XMLEndpointManager asc = new XMLEndpointManager();
965 public SPRole(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
966 super(provider, validUntil, e);
968 // Check the root element namespace. If SAML2, assume it's the std schema.
969 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
970 String flag=XML.assign(e.getAttributeNS(null,"AuthnRequestsSigned"));
971 authnRequestsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
972 flag=XML.assign(e.getAttributeNS(null,"WantAssertionsSigned"));
973 wantAssertionsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
976 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AssertionConsumerService");
977 for (i=0; i<nlist.getLength(); i++)
978 asc.add(new XMLIndexedEndpoint((Element)(nlist.item(i))));
981 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"Attribute");
982 for (i=0; i<nlist.getLength(); i++) {
983 // For now, we need to convert these to plain SAML 1.1 attributes.
984 Element src=(Element)(nlist.item(i));
985 Element copy=e.getOwnerDocument().createElementNS(XML.SAML_NS,"Attribute");
986 copy.setAttributeNS(null,"AttributeName",src.getAttributeNS(null,"Name"));
987 copy.setAttributeNS(null,"AttributeNamespace",src.getAttributeNS(null,"NameFormat"));
988 src=XML.getFirstChildElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
989 while (src != null) {
990 src=XML.getNextSiblingElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
991 Element val=e.getOwnerDocument().createElementNS(XML.SAML_NS,"AttributeValue");
992 NamedNodeMap attrs = src.getAttributes();
993 for (int j=0; j<attrs.getLength(); j++)
994 val.setAttributeNodeNS((Attr)(e.getOwnerDocument().importNode(attrs.item(j),true)));
995 while (src.hasChildNodes())
996 val.appendChild(src.getFirstChild());
997 copy.appendChild(val);
999 attrs.add(SAMLAttribute.getInstance(copy));
1005 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AssertionConsumerServiceURL");
1006 for (i=0; i<nlist.getLength(); i++) {
1007 // Manufacture an endpoint for the POST profile.
1009 new XMLEndpoint(SAMLBrowserProfile.PROFILE_POST_URI,((Element)nlist.item(i)).getAttributeNS(null,"Location"))
1013 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AttributeRequester");
1014 for (i=0; i<nlist.getLength(); i++) {
1015 // We're going to "mock up" a KeyDescriptor that contains the specified Name as a ds:KeyName.
1016 Element kd=e.getOwnerDocument().createElementNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
1017 Element ki=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyInfo");
1018 Element kn=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyName");
1020 e.getOwnerDocument().createTextNode(((Element)nlist.item(i)).getAttributeNS(null,"Name"))
1024 kd.setAttributeNS(null,"use","signing");
1025 keys.add(new XMLKeyDescriptor(kd));
1030 public boolean getAuthnRequestsSigned() {
1031 return authnRequestsSigned;
1034 public boolean getWantAssertionsSigned() {
1035 return wantAssertionsSigned;
1038 public EndpointManager getAssertionConsumerServiceManager() {
1042 public Iterator getAttributeConsumingServices() {
1043 // TODO Auto-generated method stub
1047 public AttributeConsumingService getDefaultAttributeConsumingService() {
1048 // TODO Auto-generated method stub
1052 public AttributeConsumingService getAttributeConsumingServiceByID(String id) {
1053 // TODO Auto-generated method stub
1058 class AttributeRequesterRole extends Role implements AttributeRequesterDescriptor {
1059 private boolean wantAssertionsSigned = false;
1060 private ArrayList /* <String> */ formats = new ArrayList();
1062 public AttributeRequesterRole(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
1063 super(provider, validUntil, e);
1065 String flag=XML.assign(e.getAttributeNS(null,"WantAssertionsSigned"));
1066 wantAssertionsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
1068 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"NameIDFormat");
1069 for (int i = 0; i < nlist.getLength(); i++) {
1070 if (nlist.item(i).hasChildNodes()) {
1071 Node tnode = nlist.item(i).getFirstChild();
1072 if (tnode != null && tnode.getNodeType() == Node.TEXT_NODE) {
1073 formats.add(tnode.getNodeValue());
1079 public boolean getWantAssertionsSigned() {
1080 return wantAssertionsSigned;
1083 public Iterator getNameIDFormats() {
1084 return formats.iterator();
1087 public Iterator getAttributeConsumingServices() {
1088 // TODO Auto-generated method stub
1092 public AttributeConsumingService getDefaultAttributeConsumingService() {
1093 // TODO Auto-generated method stub
1097 public AttributeConsumingService getAttributeConsumingServiceByID(String id) {
1098 // TODO Auto-generated method stub
1103 class XMLEntityDescriptor implements ExtendedEntityDescriptor {
1104 private Element root = null;
1105 private EntitiesDescriptor parent = null;
1106 private String id = null;
1107 private URL errorURL = null;
1108 private Organization org = null;
1109 private ArrayList /* <ContactPerson> */ contacts = new ArrayList();
1110 private ArrayList /* <RoleDescriptor> */ roles = new ArrayList();
1111 private AffiliationDescriptor affiliation = null;
1112 private HashMap /* <String,String> */ locs = new HashMap();
1113 private long validUntil = Long.MAX_VALUE;
1114 private ArrayList /* <KeyAuthority> */ keyauths = new ArrayList();
1116 public XMLEntityDescriptor(Element e, XMLMetadataProvider wrapper, long validUntil, EntitiesDescriptor parent) throws SAMLException {
1118 this.parent = parent;
1119 this.validUntil = validUntil;
1121 // Check the root element namespace. If SAML2, assume it's the std schema.
1122 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
1123 id=e.getAttributeNS(null,"entityID");
1125 if (e.hasAttributeNS(null,"validUntil")) {
1126 SimpleDateFormat formatter = null;
1127 String dateTime = XML.assign(e.getAttributeNS(null,"validUntil"));
1128 int dot = dateTime.indexOf('.');
1130 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
1132 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
1133 formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
1135 this.validUntil=Math.min(validUntil,formatter.parse(dateTime).getTime());
1137 catch (ParseException e1) {
1138 log.warn("Entity descriptor contains invalid expiration time");
1142 Element child=XML.getFirstChildElement(e);
1143 while (child != null) {
1144 // Process the various kinds of children that we care about...
1145 if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions")) {
1146 Element ext = XML.getFirstChildElement(child,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1147 while (ext != null) {
1148 keyauths.add(new XMLKeyAuthority(ext));
1149 ext = XML.getNextSiblingElement(ext,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1152 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ContactPerson")) {
1153 contacts.add(new XMLContactPerson(child));
1155 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Organization")) {
1156 org=new XMLOrganization(child);
1158 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AdditionalMetadataLocation")) {
1159 Node loc=child.getFirstChild();
1161 locs.put(child.getAttributeNS(null,"namespace"),loc.getNodeValue());
1163 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"IDPSSODescriptor")) {
1164 roles.add(new IDPRole(this,validUntil,child));
1166 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeAuthorityDescriptor")) {
1167 roles.add(new AARole(this,validUntil,child));
1169 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SPSSODescriptor")) {
1170 roles.add(new SPRole(this,validUntil,child));
1172 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"RoleDescriptor")) {
1173 QName xsitype = XML.getQNameAttribute(child,XML.XSI_NS,"type");
1174 if (edu.internet2.middleware.shibboleth.common.XML.SAML2METAEXT_NS.equals(xsitype.getNamespaceURI()) &&
1175 "AttributeRequesterDescriptorType".equals(xsitype.getLocalPart()))
1176 roles.add(new AttributeRequesterRole(this,validUntil,child));
1178 child = XML.getNextSiblingElement(child);
1182 id=e.getAttributeNS(null,"Name");
1183 if (e.hasAttributeNS(null,"ErrorURL")) {
1185 errorURL=new URL(e.getAttributeNS(null,"ErrorURL"));
1187 catch (MalformedURLException e1) {
1188 log.error("Site descriptor contains invalid ErrorURL");
1192 boolean idp=false,aa=false,sp=false; // only want to build a role once
1193 Element child=XML.getFirstChildElement(e);
1194 while (child != null) {
1195 // Process the various kinds of OriginSite children that we care about...
1196 if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Contact")) {
1197 contacts.add(new XMLContactPerson(child));
1199 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"HandleService") && !idp) {
1200 // Create the IDP role if needed.
1201 roles.add(new IDPRole(this, validUntil, e));
1204 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AttributeAuthority") && !aa) {
1205 // Create the AA role if needed.
1206 roles.add(new AARole(this, validUntil, e));
1209 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AssertionConsumerServiceURL") && !sp) {
1210 // Create the SP role if needed.
1211 roles.add(new SPRole(this, validUntil, e));
1214 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AttributeRequester") && !sp) {
1215 // Create the SP role if needed.
1216 roles.add(new SPRole(this, validUntil, e));
1219 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Alias") && (org == null)) {
1220 // Create the Organization.
1221 org = new XMLOrganization(child);
1223 child = XML.getNextSiblingElement(child);
1227 // Each map entry is a list of the descriptors with this ID.
1229 if (wrapper.sites.containsKey(id)) {
1230 list = (ArrayList)wrapper.sites.get(id);
1233 list = new ArrayList();
1234 wrapper.sites.put(id,list);
1238 // Look for an IdP role, and register the artifact source ID and endpoints.
1240 for (int i=0; i<roles.size(); i++) {
1241 if (roles.get(i) instanceof IDPRole) {
1242 idp = (IDPRole)roles.get(i);
1243 if (idp.sourceId != null) {
1244 if (wrapper.sources.containsKey(idp.sourceId)) {
1245 list = (ArrayList)wrapper.sources.get(idp.sourceId);
1248 list = new ArrayList();
1249 wrapper.sources.put(idp.sourceId,list);
1256 sourceId = new String(Hex.encode(Util.generateSourceId(id)));
1258 catch (NoSuchAlgorithmException e1) {
1259 log.error("caught exception while encoding sourceId: " + e1.getMessage());
1262 if (wrapper.sources.containsKey(sourceId)) {
1263 list = (ArrayList)wrapper.sources.get(sourceId);
1266 list = new ArrayList();
1267 wrapper.sources.put(sourceId,list);
1271 Iterator locs=idp.getArtifactResolutionServiceManager().getEndpoints();
1272 while (locs.hasNext()) {
1273 String loc=((Endpoint)locs.next()).getLocation();
1274 if (wrapper.sources.containsKey(loc)) {
1275 list = (ArrayList)wrapper.sources.get(loc);
1278 list = new ArrayList();
1279 wrapper.sources.put(loc,list);
1287 public String getId() {
1291 public boolean isValid() {
1292 return System.currentTimeMillis() < validUntil;
1295 public Iterator getRoleDescriptors() {
1296 return roles.iterator();
1299 public RoleDescriptor getRoleByType(Class type, String protocol) {
1300 for (int i=0; i<roles.size(); i++) {
1301 RoleDescriptor role = (RoleDescriptor)roles.get(i);
1302 if (type.isInstance(role) && role.hasSupport(protocol))
1308 public IDPSSODescriptor getIDPSSODescriptor(String protocol) {
1309 return (IDPSSODescriptor)getRoleByType(IDPSSODescriptor.class, protocol);
1312 public SPSSODescriptor getSPSSODescriptor(String protocol) {
1313 return (SPSSODescriptor)getRoleByType(SPSSODescriptor.class, protocol);
1316 public AuthnAuthorityDescriptor getAuthnAuthorityDescriptor(String protocol) {
1317 return (AuthnAuthorityDescriptor)getRoleByType(AuthnAuthorityDescriptor.class, protocol);
1320 public AttributeAuthorityDescriptor getAttributeAuthorityDescriptor(String protocol) {
1321 return (AttributeAuthorityDescriptor)getRoleByType(AttributeAuthorityDescriptor.class, protocol);
1324 public AttributeRequesterDescriptor getAttributeRequesterDescriptor(String protocol) {
1325 return (AttributeRequesterDescriptor)getRoleByType(AttributeRequesterDescriptor.class, protocol);
1328 public PDPDescriptor getPDPDescriptor(String protocol) {
1329 return (PDPDescriptor)getRoleByType(PDPDescriptor.class, protocol);
1332 public AffiliationDescriptor getAffiliationDescriptor() {
1336 public Organization getOrganization() {
1340 public Iterator getContactPersons() {
1341 return contacts.iterator();
1344 public Map getAdditionalMetadataLocations() {
1345 return Collections.unmodifiableMap(locs);
1348 public EntitiesDescriptor getEntitiesDescriptor() {
1352 public Element getElement() {
1356 public long getValidUntil() {
1360 public URL getErrorURL() {
1364 public Iterator getKeyAuthorities() {
1365 return keyauths.iterator();
1369 class XMLEntitiesDescriptor implements ExtendedEntitiesDescriptor {
1370 private Element root = null;
1371 private EntitiesDescriptor parent = null;
1372 private String name = null;
1373 private ArrayList /* <EntitiesDescriptor> */ groups = new ArrayList();
1374 private ArrayList /* <EntityDescriptor> */ providers = new ArrayList();
1375 private long validUntil = Long.MAX_VALUE;
1376 private ArrayList /* <KeyAuthority> */ keyauths = new ArrayList();
1378 public XMLEntitiesDescriptor(Element e, XMLMetadataProvider wrapper, long validUntil, EntitiesDescriptor parent) throws SAMLException {
1380 this.parent = parent;
1381 this.validUntil = validUntil;
1382 name = XML.assign(e.getAttributeNS(null, "Name"));
1384 // Check the root element namespace. If SAML2, assume it's the std schema.
1385 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
1387 if (e.hasAttributeNS(null,"validUntil")) {
1388 SimpleDateFormat formatter = null;
1389 String dateTime = XML.assign(e.getAttributeNS(null,"validUntil"));
1390 int dot = dateTime.indexOf('.');
1392 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
1394 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
1395 formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
1397 this.validUntil=Math.min(validUntil,formatter.parse(dateTime).getTime());
1399 catch (ParseException e1) {
1400 log.warn("Entities descriptor contains invalid expiration time");
1404 e = XML.getFirstChildElement(e);
1406 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions")) {
1407 Element ext = XML.getFirstChildElement(e,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1408 while (ext != null) {
1409 keyauths.add(new XMLKeyAuthority(ext));
1410 ext = XML.getNextSiblingElement(ext,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1413 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EntitiesDescriptor"))
1414 groups.add(new XMLEntitiesDescriptor(e, wrapper, this.validUntil, this));
1415 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EntityDescriptor"))
1416 providers.add(new XMLEntityDescriptor(e, wrapper, this.validUntil, this));
1417 e = XML.getNextSiblingElement(e);
1421 e = XML.getFirstChildElement(e);
1423 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"SiteGroup"))
1424 groups.add(new XMLEntitiesDescriptor(e, wrapper, this.validUntil, this));
1425 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"OriginSite"))
1426 providers.add(new XMLEntityDescriptor(e, wrapper, this.validUntil, this));
1427 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"DestinationSite"))
1428 providers.add(new XMLEntityDescriptor(e, wrapper, this.validUntil, this));
1429 e = XML.getNextSiblingElement(e);
1434 public String getName() {
1438 public boolean isValid() {
1439 return System.currentTimeMillis() < validUntil;
1442 public EntitiesDescriptor getEntitiesDescriptor() {
1446 public Iterator getEntitiesDescriptors() {
1447 return groups.iterator();
1450 public Iterator getEntityDescriptors() {
1451 return providers.iterator();
1454 public Element getElement() {
1458 public Iterator getKeyAuthorities() {
1459 return keyauths.iterator();