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.common.PluggableConfigurationComponent;
57 import edu.internet2.middleware.shibboleth.metadata.*;
60 * @author Scott Cantor
62 public class XMLMetadataProvider implements Metadata, PluggableConfigurationComponent {
64 private static Logger log = Logger.getLogger(XMLMetadataProvider.class.getName());
65 private Map /* <String,ArrayList<EntityDescriptor> > */ sites = new HashMap();
66 private Map /* <String,ArrayList<EntityDescriptor> > */ sources = new HashMap();
67 private XMLEntityDescriptor rootProvider = null;
68 private XMLEntitiesDescriptor rootGroup = null;
70 public XMLMetadataProvider(Element e) throws SAMLException {
74 public XMLMetadataProvider() {} // Must call initialize
76 public void initialize(Element e) throws SAMLException {
77 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EntitiesDescriptor"))
78 rootGroup=new XMLEntitiesDescriptor(e,this, Long.MAX_VALUE, null);
79 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EntityDescriptor"))
80 rootProvider=new XMLEntityDescriptor(e,this, Long.MAX_VALUE, null);
81 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"SiteGroup"))
82 rootGroup=new XMLEntitiesDescriptor(e,this, Long.MAX_VALUE, null);
83 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"OriginSite"))
84 rootProvider=new XMLEntityDescriptor(e,this, Long.MAX_VALUE, null);
85 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"DestinationSite"))
86 rootProvider=new XMLEntityDescriptor(e,this, Long.MAX_VALUE, null);
88 log.error("Construction requires a valid SAML metadata file");
89 throw new MetadataException("Construction requires a valid SAML metadata file");
93 public EntityDescriptor lookup(String id, boolean strict) {
94 ArrayList list = (ArrayList)sites.get(id);
96 long now = System.currentTimeMillis();
97 for (int i=0; i<list.size(); i++) {
98 if (now < ((XMLEntityDescriptor)list.get(i)).getValidUntil())
99 return (EntityDescriptor)list.get(i);
101 if (!strict && list.size() > 0)
102 return (EntityDescriptor)list.get(0);
107 public EntityDescriptor lookup(Artifact artifact, boolean strict) {
108 ArrayList list = null;
110 if (artifact instanceof SAMLArtifactType0001) {
111 byte[] sourceId = ((SAMLArtifactType0001)artifact).getSourceId();
112 String sourceString = new String(Hex.encode(sourceId));
113 list = (ArrayList)sources.get(sourceString);
115 else if (artifact instanceof SAMLArtifactType0002) {
116 URI sourceLocation = ((SAMLArtifactType0002)artifact).getSourceLocation();
117 String sourceLocationString = sourceLocation.toString();
118 list = (ArrayList)sources.get(sourceLocationString);
121 log.error("unsupported artifact type (" + artifact.getTypeCode().toString() + ")");
125 long now = System.currentTimeMillis();
126 for (int i=0; i<list.size(); i++) {
127 if (now < ((XMLEntityDescriptor)list.get(i)).getValidUntil())
128 return (EntityDescriptor)list.get(i);
130 if (!strict && list.size() > 0)
131 return (EntityDescriptor)list.get(0);
136 public EntityDescriptor lookup(String id) {
137 return lookup(id, true);
140 public EntityDescriptor lookup(Artifact artifact) {
141 return lookup(artifact, true);
144 public EntityDescriptor getRootEntity() {
148 public EntitiesDescriptor getRootEntities() {
152 class XMLEndpoint implements Endpoint {
153 private Element root = null;
154 private String binding = null;
155 private String location = null;
156 private String resploc = null;
158 XMLEndpoint(Element e) {
160 binding = XML.assign(e.getAttributeNS(null,"Binding"));
161 location = XML.assign(e.getAttributeNS(null,"Location"));
162 resploc = XML.assign(e.getAttributeNS(null,"ResponseLocation"));
165 XMLEndpoint(String binding, String location) {
166 this.binding = binding;
167 this.location = location;
170 public String getBinding() {
174 public String getLocation() {
178 public String getResponseLocation() {
182 public Element getElement() {
187 class XMLIndexedEndpoint extends XMLEndpoint implements IndexedEndpoint {
188 private int index = 0;
190 XMLIndexedEndpoint(Element e) {
192 index = Integer.parseInt(e.getAttributeNS(null,"index"));
195 public int getIndex() {
200 class XMLEndpointManager implements EndpointManager {
201 private ArrayList endpoints = new ArrayList();
202 Endpoint soft = null; // Soft default (not explicit)
203 Endpoint hard = null; // Hard default (explicit)
205 public Iterator getEndpoints() {
206 return endpoints.iterator();
209 public Endpoint getDefaultEndpoint() {
210 if (hard != null) return hard;
211 if (soft != null) return soft;
212 if (!endpoints.isEmpty()) return (Endpoint)endpoints.get(0);
216 public Endpoint getEndpointByIndex(int index) {
217 for (int i=0; i < endpoints.size(); i++) {
218 if (endpoints.get(i) instanceof IndexedEndpoint && index==((IndexedEndpoint)endpoints.get(i)).getIndex())
219 return (Endpoint)endpoints.get(i);
224 public Endpoint getEndpointByBinding(String binding) {
225 for (int i=0; i < endpoints.size(); i++) {
226 if (binding.equals(((Endpoint)endpoints.get(i)).getBinding()))
227 return (Endpoint)endpoints.get(i);
232 protected void add(Endpoint e) {
234 if (hard == null && e.getElement() != null) {
235 String v=XML.assign(e.getElement().getAttributeNS(null,"isDefault"));
236 if (v != null && (v.equals("1") || v.equals("true"))) // explicit default
238 else if (v == null && soft == null) // implicit default
241 else if (hard == null && soft == null) {
242 // No default yet, so this one qualifies as an implicit.
248 class XMLKeyDescriptor implements KeyDescriptor {
250 private int use = KeyDescriptor.UNSPECIFIED;
251 private KeyInfo keyInfo = null;
252 private ArrayList /* <XMLEncryptionMethod> */ methods = new ArrayList();
254 XMLKeyDescriptor(Element e) {
255 if (XML.safeCompare(e.getAttributeNS(null,"use"),"encryption"))
256 use = KeyDescriptor.ENCRYPTION;
257 else if (XML.safeCompare(e.getAttributeNS(null,"use"),"signing"))
258 use = KeyDescriptor.SIGNING;
260 e = XML.getFirstChildElement(e);
262 keyInfo = new KeyInfo(e, null);
264 catch (XMLSecurityException e1) {
265 log.error("unable to process ds:KeyInfo element: " + e1.getMessage());
268 e = XML.getNextSiblingElement(e);
269 while (e != null && XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EncryptionMethod")) {
270 methods.add(new XMLEncryptionMethod(e));
274 public int getUse() {
278 public Iterator getEncryptionMethods() {
279 return methods.iterator();
282 public KeyInfo getKeyInfo() {
287 class XMLEncryptionMethod implements EncryptionMethod {
290 String params = null;
293 public XMLEncryptionMethod(Element e) {
294 alg = XML.assign(e.getAttributeNS(null, "Algorithm"));
295 e = XML.getFirstChildElement(e);
297 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.XMLENC_NS,"KeySize")) {
298 if (e.hasChildNodes())
299 size = Integer.parseInt(e.getFirstChild().getNodeValue());
301 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.XMLENC_NS,"OAEParams")) {
302 if (e.hasChildNodes())
303 params = XML.assign(e.getFirstChild().getNodeValue());
305 e = XML.getNextSiblingElement(e);
309 public String getAlgorithm() {
313 public int getKeySize() {
317 public byte[] getOAEPparams() {
318 return params.getBytes();
321 public Iterator getEncryptionMethodInformation() {
325 public void setKeySize(int arg0) {
326 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
329 public void setOAEPparams(byte[] arg0) {
330 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
333 public void addEncryptionMethodInformation(Element arg0) {
334 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
337 public void removeEncryptionMethodInformation(Element arg0) {
338 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
342 class XMLKeyAuthority implements KeyAuthority {
343 private int depth = 1;
344 private ArrayList /* <KeyInfo> */ keys = new ArrayList();
346 XMLKeyAuthority(Element e) {
347 if (e.hasAttributeNS(null,"VerifyDepth"))
348 depth = Integer.parseInt(e.getAttributeNS(null,"VerifyDepth"));
349 e = XML.getFirstChildElement(e, XML.XMLSIG_NS, "KeyInfo");
352 keys.add(new KeyInfo(e, null));
354 catch (XMLSecurityException e1) {
355 log.error("unable to process ds:KeyInfo element: " + e1.getMessage());
357 e = XML.getNextSiblingElement(e, XML.XMLSIG_NS, "KeyInfo");
361 public int getVerifyDepth() {
365 public Iterator getKeyInfos() {
366 return keys.iterator();
371 class XMLOrganization implements Organization {
372 private HashMap /* <String,String> */ names = new HashMap();
373 private HashMap /* <String,String> */ displays = new HashMap();
374 private HashMap /* <String,URL> */ urls = new HashMap();
376 public XMLOrganization(Element e) throws MetadataException {
377 // Old metadata or new?
378 if (XML.isElementNamed(e, edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Alias")) {
379 if (e.hasChildNodes()) {
380 names.put("en",XML.assign(e.getFirstChild().getNodeValue()));
381 displays.put("en",XML.assign(e.getFirstChild().getNodeValue()));
385 e=XML.getFirstChildElement(e);
387 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"OrganizationName")) {
388 if (e.hasChildNodes()) {
389 names.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,"OrganizationDisplayName")) {
393 if (e.hasChildNodes()) {
394 displays.put(e.getAttributeNS(XML.XML_NS,"lang"),XML.assign(e.getFirstChild().getNodeValue()));
397 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"OrganizationURL")) {
398 if (e.hasChildNodes()) {
401 u = new URL(e.getFirstChild().getNodeValue());
403 catch (MalformedURLException e1) {
404 throw new MetadataException("OrganizationURL was invalid: " + e1);
406 urls.put(e.getAttributeNS(XML.XML_NS,"lang"),u);
409 e=XML.getNextSiblingElement(e);
414 public String getName() {
415 return getName("en");
418 public String getName(String lang) {
419 return (String)names.get(lang);
422 public String getDisplayName() {
423 return getDisplayName("en");
426 public String getDisplayName(String lang) {
427 return (String)displays.get(lang);
430 public URL getURL() {
434 public URL getURL(String lang) {
435 return (URL)urls.get(lang);
440 class XMLContactPerson implements ContactPerson {
441 private Element root = null;
443 private String company = null;
444 private String givenName = null;
445 private String surName = null;
446 private ArrayList /* <String> */ emails = new ArrayList();
447 private ArrayList /* <String> */ telephones = new ArrayList();
449 public XMLContactPerson(Element e) throws MetadataException {
451 String rawType = null;
453 // Old metadata or new?
454 if (XML.isElementNamed(root, edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Contact")) {
455 rawType = root.getAttributeNS(null,"Type");
456 surName = XML.assign(root.getAttributeNS(null,"Name"));
457 if (XML.isEmpty(surName)) {
458 throw new MetadataException("Contact is missing Name attribute.");
460 if (root.hasAttributeNS(null,"Email"))
461 emails.add(e.getAttributeNS(null,"Email"));
464 rawType = root.getAttributeNS(null,"contactType");
465 e=XML.getFirstChildElement(root);
467 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Company")) {
468 if (e.hasChildNodes())
469 company=XML.assign(e.getFirstChild().getNodeValue());
471 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"GivenName")) {
472 if (e.hasChildNodes())
473 givenName=XML.assign(e.getFirstChild().getNodeValue());
475 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SurName")) {
476 if (e.hasChildNodes())
477 surName=XML.assign(e.getFirstChild().getNodeValue());
479 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EmailAddress")) {
480 if (e.hasChildNodes())
481 emails.add(XML.assign(e.getFirstChild().getNodeValue()));
483 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"TelephoneNumber")) {
484 if (e.hasChildNodes())
485 telephones.add(XML.assign(e.getFirstChild().getNodeValue()));
487 e=XML.getNextSiblingElement(e);
491 if (rawType.equalsIgnoreCase("TECHNICAL")) {
492 type = ContactPerson.TECHNICAL;
493 } else if (rawType.equalsIgnoreCase("SUPPORT")) {
494 type = ContactPerson.SUPPORT;
495 } else if (rawType.equalsIgnoreCase("ADMINISTRATIVE")) {
496 type = ContactPerson.ADMINISTRATIVE;
497 } else if (rawType.equalsIgnoreCase("BILLING")) {
498 type = ContactPerson.BILLING;
499 } else if (rawType.equalsIgnoreCase("OTHER")) {
500 type = ContactPerson.OTHER;
502 throw new MetadataException("Contact has unknown contact type.");
506 public int getType() {
510 public String getGivenName() {
514 public String getSurName() {
518 public String getCompany() {
522 public Iterator getEmailAddresses() {
523 return emails.iterator();
526 public Iterator getTelephoneNumbers() {
527 return telephones.iterator();
530 public Element getElement() {
535 class Role implements RoleDescriptor {
536 private Element root = null;
537 private XMLEntityDescriptor provider = null;
538 private URL errorURL = null;
539 private Organization org = null;
540 private ArrayList /* <ContactPerson> */ contacts = new ArrayList();
541 private long validUntil = Long.MAX_VALUE;
542 protected ArrayList /* <String> */ protocolEnum = new ArrayList();
543 protected ArrayList /* <KeyDescriptor> */ keys = new ArrayList();
545 public Role(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
547 this.validUntil = validUntil;
548 this.provider = provider;
550 // Check the root element namespace. If SAML2, assume it's the std schema.
551 if (e != null && edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
553 if (e.hasAttributeNS(null,"validUntil")) {
554 SimpleDateFormat formatter = null;
555 String dateTime = XML.assign(e.getAttributeNS(null,"validUntil"));
556 int dot = dateTime.indexOf('.');
558 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
560 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
561 formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
563 this.validUntil=Math.min(validUntil,formatter.parse(dateTime).getTime());
565 catch (ParseException e1) {
566 log.warn("Role descriptor contains invalid expiration time");
570 if (e.hasAttributeNS(null,"errorURL")) {
572 errorURL=new URL(e.getAttributeNS(null,"errorURL"));
574 catch (MalformedURLException e1) {
575 log.error("Role descriptor contains malformed errorURL");
579 // Chop the protocol list into pieces...assume any whitespace can appear in between.
580 protocolEnum.addAll(Arrays.asList(e.getAttributeNS(null,"protocolSupportEnumeration").split("\\s")));
582 e = XML.getFirstChildElement(root,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
584 keys.add(new XMLKeyDescriptor(e));
585 e = XML.getNextSiblingElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
588 e = XML.getFirstChildElement(root,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Organization");
590 org=new XMLOrganization(e);
592 e = XML.getFirstChildElement(root,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ContactPerson");
594 contacts.add(new XMLContactPerson(e));
595 e = XML.getNextSiblingElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ContactPerson");
600 public EntityDescriptor getEntityDescriptor() {
604 public Iterator getProtocolSupportEnumeration() {
605 return protocolEnum.iterator();
608 public boolean hasSupport(String version) {
609 return protocolEnum.contains(version);
612 public boolean isValid() {
613 return System.currentTimeMillis() < validUntil;
616 public URL getErrorURL() {
617 return (errorURL != null) ? errorURL : provider.getErrorURL();
620 public Iterator getKeyDescriptors() {
621 return keys.iterator();
624 public Organization getOrganization() {
625 return (org != null) ? org : provider.getOrganization();
628 public Iterator getContactPersons() {
629 return (contacts.isEmpty()) ? provider.getContactPersons() : contacts.iterator();
632 public Element getElement() {
637 class SSORole extends Role implements SSODescriptor {
638 private XMLEndpointManager artifact = new XMLEndpointManager();
639 private XMLEndpointManager logout = new XMLEndpointManager();
640 private XMLEndpointManager nameid = new XMLEndpointManager();
641 private ArrayList /* <String> */ formats = new ArrayList();
643 public SSORole(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
644 super(provider, validUntil, e);
646 // Check the root element namespace. If SAML2, assume it's the std schema.
647 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
649 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ArtifactResolutionService");
650 for (i=0; i<nlist.getLength(); i++)
651 artifact.add(new XMLIndexedEndpoint((Element)nlist.item(i)));
653 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SingleLogoutService");
654 for (i=0; i<nlist.getLength(); i++)
655 logout.add(new XMLEndpoint((Element)nlist.item(i)));
657 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ManageNameIDService");
658 for (i=0; i<nlist.getLength(); i++)
659 nameid.add(new XMLEndpoint((Element)nlist.item(i)));
661 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"NameIDFormat");
662 for (i = 0; i < nlist.getLength(); i++) {
663 if (nlist.item(i).hasChildNodes()) {
664 Node tnode = nlist.item(i).getFirstChild();
665 if (tnode != null && tnode.getNodeType() == Node.TEXT_NODE) {
666 formats.add(tnode.getNodeValue());
672 // For old style, we just do SAML 1.1 compatibility with Shib handles.
673 protocolEnum.add(XML.SAML11_PROTOCOL_ENUM);
674 formats.add(Constants.SHIB_NAMEID_FORMAT_URI);
678 public EndpointManager getArtifactResolutionServiceManager() {
682 public EndpointManager getSingleLogoutServiceManager() {
686 public EndpointManager getManageNameIDServiceManager() {
690 public Iterator getNameIDFormats() {
691 return formats.iterator();
695 class IDPRole extends SSORole implements IDPSSODescriptor, ScopedRoleDescriptor {
696 private ArrayList /* <Scope> */ scopes = new ArrayList();
697 private XMLEndpointManager sso = new XMLEndpointManager();
698 private XMLEndpointManager mapping = new XMLEndpointManager();
699 private XMLEndpointManager idreq = new XMLEndpointManager();
700 private ArrayList /* <String> */ attrprofs = new ArrayList();
701 private ArrayList /* <SAMLAttribute> */ attrs = new ArrayList();
702 private boolean wantAuthnRequestsSigned = false;
703 private String sourceId = null;
705 public IDPRole(XMLEntityDescriptor provider, long validUntil, Element e) throws SAMLException {
706 super(provider, validUntil, e);
707 NodeList domains=null;
709 // Check the root element namespace. If SAML2, assume it's the std schema.
710 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
711 String flag=XML.assign(e.getAttributeNS(null,"WantAuthnRequestsSigned"));
712 wantAuthnRequestsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
714 // Check for extensions.
715 Element ext=XML.getFirstChildElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions");
717 Element ext1=XML.getFirstChildElement(ext,XML.SAML_ARTIFACT_SOURCEID,"SourceID");
718 if (ext1 != null && ext1.hasChildNodes())
719 sourceId=ext1.getFirstChild().getNodeValue();
720 // Save off any domain elements for later.
721 domains = ext.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"Scope");
725 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SingleSignOnService");
726 for (i=0; i<nlist.getLength(); i++)
727 sso.add(new XMLEndpoint((Element)(nlist.item(i))));
729 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"NameIDMappingService");
730 for (i=0; i<nlist.getLength(); i++)
731 mapping.add(new XMLEndpoint((Element)(nlist.item(i))));
733 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AssertionIDRequestService");
734 for (i=0; i<nlist.getLength(); i++)
735 idreq.add(new XMLEndpoint((Element)(nlist.item(i))));
737 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeProfile");
738 for (i=0; i<nlist.getLength(); i++) {
739 if (nlist.item(i).hasChildNodes())
740 attrprofs.add(nlist.item(i).getFirstChild().getNodeValue());
743 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"Attribute");
744 for (i=0; i<nlist.getLength(); i++) {
745 // For now, we need to convert these to plain SAML 1.1 attributes.
746 Element src=(Element)(nlist.item(i));
747 Element copy=e.getOwnerDocument().createElementNS(XML.SAML_NS,"Attribute");
748 copy.setAttributeNS(null,"AttributeName",src.getAttributeNS(null,"Name"));
749 copy.setAttributeNS(null,"AttributeNamespace",src.getAttributeNS(null,"NameFormat"));
750 src=XML.getFirstChildElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
751 while (src != null) {
752 src=XML.getNextSiblingElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
753 Element val=e.getOwnerDocument().createElementNS(XML.SAML_NS,"AttributeValue");
754 NamedNodeMap attrs = src.getAttributes();
755 for (int j=0; j<attrs.getLength(); j++)
756 val.setAttributeNodeNS((Attr)(e.getOwnerDocument().importNode(attrs.item(j),true)));
757 while (src.hasChildNodes())
758 val.appendChild(src.getFirstChild());
759 copy.appendChild(val);
761 attrs.add(SAMLAttribute.getInstance(copy));
765 protocolEnum.add(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS);
766 attrprofs.add(Constants.SHIB_ATTRIBUTE_NAMESPACE_URI);
768 domains = e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Domain");
769 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"HandleService");
770 for (i=0; i<nlist.getLength(); i++) {
771 // Manufacture an endpoint for the "Shib" binding.
773 new XMLEndpoint(Constants.SHIB_AUTHNREQUEST_PROFILE_URI,((Element)nlist.item(i)).getAttributeNS(null,"Location"))
776 // We're going to "mock up" a KeyDescriptor that contains the specified Name as a ds:KeyName.
777 Element kd=e.getOwnerDocument().createElementNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
778 Element ki=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyInfo");
779 Element kn=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyName");
781 e.getOwnerDocument().createTextNode(((Element)nlist.item(i)).getAttributeNS(null,"Name"))
785 kd.setAttributeNS(null,"use","signing");
786 keys.add(new XMLKeyDescriptor(kd));
790 if (domains != null) {
791 for (int i=0; i < domains.getLength(); i++) {
792 String dom=(domains.item(i).hasChildNodes()) ? domains.item(i).getFirstChild().getNodeValue() : null;
794 String regexp=XML.assign(((Element)domains.item(i)).getAttributeNS(null,"regexp"));
796 new Scope(dom,(XML.safeCompare(regexp,"true") || XML.safeCompare(regexp,"1")))
803 public Iterator getScopes() {
804 return scopes.iterator();
807 public boolean getWantAuthnRequestsSigned() {
808 return wantAuthnRequestsSigned;
811 public EndpointManager getSingleSignOnServiceManager() {
815 public EndpointManager getNameIDMappingServiceManager() {
819 public EndpointManager getAssertionIDRequestServiceManager() {
823 public Iterator getAttributeProfiles() {
824 return attrprofs.iterator();
827 public Iterator getAttributes() {
828 return attrs.iterator();
832 class AARole extends Role implements AttributeAuthorityDescriptor, ScopedRoleDescriptor {
833 private ArrayList /* <Scope> */ scopes = new ArrayList();
834 private XMLEndpointManager query = new XMLEndpointManager();
835 private XMLEndpointManager idreq = new XMLEndpointManager();
836 private ArrayList /* <String> */ attrprofs = new ArrayList();
837 private ArrayList /* <String> */ formats = new ArrayList();
838 private ArrayList /* <SAMLAttribute> */ attrs = new ArrayList();
840 public AARole(XMLEntityDescriptor provider, long validUntil, Element e) throws SAMLException {
841 super(provider, validUntil, e);
842 NodeList domains=null;
844 // Check the root element namespace. If SAML2, assume it's the std schema.
845 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
847 // Check for extensions.
848 Element ext=XML.getFirstChildElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions");
850 // Save off any domain elements for later.
851 domains = ext.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"Scope");
855 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeService");
856 for (i=0; i<nlist.getLength(); i++)
857 query.add(new XMLEndpoint((Element)(nlist.item(i))));
859 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AssertionIDRequestService");
860 for (i=0; i<nlist.getLength(); i++)
861 idreq.add(new XMLEndpoint((Element)(nlist.item(i))));
863 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeProfile");
864 for (i=0; i<nlist.getLength(); i++) {
865 if (nlist.item(i).hasChildNodes())
866 attrprofs.add(nlist.item(i).getFirstChild().getNodeValue());
869 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"Attribute");
870 for (i=0; i<nlist.getLength(); i++) {
871 // For now, we need to convert these to plain SAML 1.1 attributes.
872 Element src=(Element)(nlist.item(i));
873 Element copy=e.getOwnerDocument().createElementNS(XML.SAML_NS,"Attribute");
874 copy.setAttributeNS(null,"AttributeName",src.getAttributeNS(null,"Name"));
875 copy.setAttributeNS(null,"AttributeNamespace",src.getAttributeNS(null,"NameFormat"));
876 src=XML.getFirstChildElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
877 while (src != null) {
878 src=XML.getNextSiblingElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
879 Element val=e.getOwnerDocument().createElementNS(XML.SAML_NS,"AttributeValue");
880 NamedNodeMap attrs = src.getAttributes();
881 for (int j=0; j<attrs.getLength(); j++)
882 val.setAttributeNodeNS((Attr)(e.getOwnerDocument().importNode(attrs.item(j),true)));
883 while (src.hasChildNodes())
884 val.appendChild(src.getFirstChild());
885 copy.appendChild(val);
887 attrs.add(SAMLAttribute.getInstance(copy));
891 // For old style, we just do SAML 1.1 compatibility with Shib handles.
892 protocolEnum.add(XML.SAML11_PROTOCOL_ENUM);
893 formats.add(Constants.SHIB_NAMEID_FORMAT_URI);
894 attrprofs.add(Constants.SHIB_ATTRIBUTE_NAMESPACE_URI);
895 domains = e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Domain");
897 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AttributeAuthority");
898 for (i=0; i<nlist.getLength(); i++) {
899 // Manufacture an endpoint for the SOAP binding.
903 ((Element)nlist.item(i)).getAttributeNS(null,"Location")
907 // We're going to "mock up" a KeyDescriptor that contains the specified Name as a ds:KeyName.
908 Element kd=e.getOwnerDocument().createElementNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
909 Element ki=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyInfo");
910 Element kn=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyName");
912 e.getOwnerDocument().createTextNode(((Element)nlist.item(i)).getAttributeNS(null,"Name"))
916 kd.setAttributeNS(null,"use","signing");
917 keys.add(new XMLKeyDescriptor(kd));
921 if (domains != null) {
922 for (int i=0; i < domains.getLength(); i++) {
923 String dom=(domains.item(i).hasChildNodes()) ? domains.item(i).getFirstChild().getNodeValue() : null;
925 String regexp=XML.assign(((Element)domains.item(i)).getAttributeNS(null,"regexp"));
927 new Scope(dom,(XML.safeCompare(regexp,"true") || XML.safeCompare(regexp,"1")))
934 public Iterator getScopes() {
935 return scopes.iterator();
938 public EndpointManager getAttributeServiceManager() {
942 public EndpointManager getAssertionIDRequestServiceManager() {
946 public Iterator getAttributeProfiles() {
947 return attrprofs.iterator();
950 public Iterator getAttributes() {
951 return attrs.iterator();
954 public Iterator getNameIDFormats() {
955 return formats.iterator();
959 class SPRole extends SSORole implements SPSSODescriptor {
960 private boolean authnRequestsSigned = false;
961 private boolean wantAssertionsSigned = false;
962 private XMLEndpointManager asc = new XMLEndpointManager();
964 public SPRole(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
965 super(provider, validUntil, e);
967 // Check the root element namespace. If SAML2, assume it's the std schema.
968 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
969 String flag=XML.assign(e.getAttributeNS(null,"AuthnRequestsSigned"));
970 authnRequestsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
971 flag=XML.assign(e.getAttributeNS(null,"WantAssertionsSigned"));
972 wantAssertionsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
975 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AssertionConsumerService");
976 for (i=0; i<nlist.getLength(); i++)
977 asc.add(new XMLIndexedEndpoint((Element)(nlist.item(i))));
980 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"Attribute");
981 for (i=0; i<nlist.getLength(); i++) {
982 // For now, we need to convert these to plain SAML 1.1 attributes.
983 Element src=(Element)(nlist.item(i));
984 Element copy=e.getOwnerDocument().createElementNS(XML.SAML_NS,"Attribute");
985 copy.setAttributeNS(null,"AttributeName",src.getAttributeNS(null,"Name"));
986 copy.setAttributeNS(null,"AttributeNamespace",src.getAttributeNS(null,"NameFormat"));
987 src=XML.getFirstChildElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
988 while (src != null) {
989 src=XML.getNextSiblingElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
990 Element val=e.getOwnerDocument().createElementNS(XML.SAML_NS,"AttributeValue");
991 NamedNodeMap attrs = src.getAttributes();
992 for (int j=0; j<attrs.getLength(); j++)
993 val.setAttributeNodeNS((Attr)(e.getOwnerDocument().importNode(attrs.item(j),true)));
994 while (src.hasChildNodes())
995 val.appendChild(src.getFirstChild());
996 copy.appendChild(val);
998 attrs.add(SAMLAttribute.getInstance(copy));
1004 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AssertionConsumerServiceURL");
1005 for (i=0; i<nlist.getLength(); i++) {
1006 // Manufacture an endpoint for the POST profile.
1008 new XMLEndpoint(SAMLBrowserProfile.PROFILE_POST_URI,((Element)nlist.item(i)).getAttributeNS(null,"Location"))
1012 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AttributeRequester");
1013 for (i=0; i<nlist.getLength(); i++) {
1014 // We're going to "mock up" a KeyDescriptor that contains the specified Name as a ds:KeyName.
1015 Element kd=e.getOwnerDocument().createElementNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
1016 Element ki=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyInfo");
1017 Element kn=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyName");
1019 e.getOwnerDocument().createTextNode(((Element)nlist.item(i)).getAttributeNS(null,"Name"))
1023 kd.setAttributeNS(null,"use","signing");
1024 keys.add(new XMLKeyDescriptor(kd));
1029 public boolean getAuthnRequestsSigned() {
1030 return authnRequestsSigned;
1033 public boolean getWantAssertionsSigned() {
1034 return wantAssertionsSigned;
1037 public EndpointManager getAssertionConsumerServiceManager() {
1041 public Iterator getAttributeConsumingServices() {
1042 // TODO Auto-generated method stub
1046 public AttributeConsumingService getDefaultAttributeConsumingService() {
1047 // TODO Auto-generated method stub
1051 public AttributeConsumingService getAttributeConsumingServiceByID(String id) {
1052 // TODO Auto-generated method stub
1057 class AttributeRequesterRole extends Role implements AttributeRequesterDescriptor {
1058 private boolean wantAssertionsSigned = false;
1059 private ArrayList /* <String> */ formats = new ArrayList();
1061 public AttributeRequesterRole(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
1062 super(provider, validUntil, e);
1064 String flag=XML.assign(e.getAttributeNS(null,"WantAssertionsSigned"));
1065 wantAssertionsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
1067 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"NameIDFormat");
1068 for (int i = 0; i < nlist.getLength(); i++) {
1069 if (nlist.item(i).hasChildNodes()) {
1070 Node tnode = nlist.item(i).getFirstChild();
1071 if (tnode != null && tnode.getNodeType() == Node.TEXT_NODE) {
1072 formats.add(tnode.getNodeValue());
1078 public boolean getWantAssertionsSigned() {
1079 return wantAssertionsSigned;
1082 public Iterator getNameIDFormats() {
1083 return formats.iterator();
1086 public Iterator getAttributeConsumingServices() {
1087 // TODO Auto-generated method stub
1091 public AttributeConsumingService getDefaultAttributeConsumingService() {
1092 // TODO Auto-generated method stub
1096 public AttributeConsumingService getAttributeConsumingServiceByID(String id) {
1097 // TODO Auto-generated method stub
1102 class XMLEntityDescriptor implements ExtendedEntityDescriptor {
1103 private Element root = null;
1104 private EntitiesDescriptor parent = null;
1105 private String id = null;
1106 private URL errorURL = null;
1107 private Organization org = null;
1108 private ArrayList /* <ContactPerson> */ contacts = new ArrayList();
1109 private ArrayList /* <RoleDescriptor> */ roles = new ArrayList();
1110 private AffiliationDescriptor affiliation = null;
1111 private HashMap /* <String,String> */ locs = new HashMap();
1112 private long validUntil = Long.MAX_VALUE;
1113 private ArrayList /* <KeyAuthority> */ keyauths = new ArrayList();
1115 public XMLEntityDescriptor(Element e, XMLMetadataProvider wrapper, long validUntil, EntitiesDescriptor parent) throws SAMLException {
1117 this.parent = parent;
1118 this.validUntil = validUntil;
1120 // Check the root element namespace. If SAML2, assume it's the std schema.
1121 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
1122 id=e.getAttributeNS(null,"entityID");
1124 if (e.hasAttributeNS(null,"validUntil")) {
1125 SimpleDateFormat formatter = null;
1126 String dateTime = XML.assign(e.getAttributeNS(null,"validUntil"));
1127 int dot = dateTime.indexOf('.');
1129 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
1131 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
1132 formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
1134 this.validUntil=Math.min(validUntil,formatter.parse(dateTime).getTime());
1136 catch (ParseException e1) {
1137 log.warn("Entity descriptor contains invalid expiration time");
1141 Element child=XML.getFirstChildElement(e);
1142 while (child != null) {
1143 // Process the various kinds of children that we care about...
1144 if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions")) {
1145 Element ext = XML.getFirstChildElement(child,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1146 while (ext != null) {
1147 keyauths.add(new XMLKeyAuthority(ext));
1148 ext = XML.getNextSiblingElement(ext,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1151 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ContactPerson")) {
1152 contacts.add(new XMLContactPerson(child));
1154 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Organization")) {
1155 org=new XMLOrganization(child);
1157 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AdditionalMetadataLocation")) {
1158 Node loc=child.getFirstChild();
1160 locs.put(child.getAttributeNS(null,"namespace"),loc.getNodeValue());
1162 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"IDPSSODescriptor")) {
1163 roles.add(new IDPRole(this,validUntil,child));
1165 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeAuthorityDescriptor")) {
1166 roles.add(new AARole(this,validUntil,child));
1168 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SPSSODescriptor")) {
1169 roles.add(new SPRole(this,validUntil,child));
1171 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"RoleDescriptor")) {
1172 QName xsitype = XML.getQNameAttribute(child,XML.XSI_NS,"type");
1173 if (edu.internet2.middleware.shibboleth.common.XML.SAML2METAEXT_NS.equals(xsitype.getNamespaceURI()) &&
1174 "AttributeRequesterDescriptorType".equals(xsitype.getLocalPart()))
1175 roles.add(new AttributeRequesterRole(this,validUntil,child));
1177 child = XML.getNextSiblingElement(child);
1181 id=e.getAttributeNS(null,"Name");
1182 if (e.hasAttributeNS(null,"ErrorURL")) {
1184 errorURL=new URL(e.getAttributeNS(null,"ErrorURL"));
1186 catch (MalformedURLException e1) {
1187 log.error("Site descriptor contains invalid ErrorURL");
1191 boolean idp=false,aa=false,sp=false; // only want to build a role once
1192 Element child=XML.getFirstChildElement(e);
1193 while (child != null) {
1194 // Process the various kinds of OriginSite children that we care about...
1195 if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Contact")) {
1196 contacts.add(new XMLContactPerson(child));
1198 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"HandleService") && !idp) {
1199 // Create the IDP role if needed.
1200 roles.add(new IDPRole(this, validUntil, e));
1203 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AttributeAuthority") && !aa) {
1204 // Create the AA role if needed.
1205 roles.add(new AARole(this, validUntil, e));
1208 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AssertionConsumerServiceURL") && !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,"AttributeRequester") && !sp) {
1214 // Create the SP role if needed.
1215 roles.add(new SPRole(this, validUntil, e));
1218 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Alias") && (org == null)) {
1219 // Create the Organization.
1220 org = new XMLOrganization(child);
1222 child = XML.getNextSiblingElement(child);
1226 // Each map entry is a list of the descriptors with this ID.
1228 if (wrapper.sites.containsKey(id)) {
1229 list = (ArrayList)wrapper.sites.get(id);
1232 list = new ArrayList();
1233 wrapper.sites.put(id,list);
1237 // Look for an IdP role, and register the artifact source ID and endpoints.
1239 for (int i=0; i<roles.size(); i++) {
1240 if (roles.get(i) instanceof IDPRole) {
1241 idp = (IDPRole)roles.get(i);
1242 if (idp.sourceId != null) {
1243 if (wrapper.sources.containsKey(idp.sourceId)) {
1244 list = (ArrayList)wrapper.sources.get(idp.sourceId);
1247 list = new ArrayList();
1248 wrapper.sources.put(idp.sourceId,list);
1255 sourceId = new String(Hex.encode(Util.generateSourceId(id)));
1257 catch (NoSuchAlgorithmException e1) {
1258 log.error("caught exception while encoding sourceId: " + e1.getMessage());
1261 if (wrapper.sources.containsKey(sourceId)) {
1262 list = (ArrayList)wrapper.sources.get(sourceId);
1265 list = new ArrayList();
1266 wrapper.sources.put(sourceId,list);
1270 Iterator locs=idp.getArtifactResolutionServiceManager().getEndpoints();
1271 while (locs.hasNext()) {
1272 String loc=((Endpoint)locs.next()).getLocation();
1273 if (wrapper.sources.containsKey(loc)) {
1274 list = (ArrayList)wrapper.sources.get(loc);
1277 list = new ArrayList();
1278 wrapper.sources.put(loc,list);
1286 public String getId() {
1290 public boolean isValid() {
1291 return System.currentTimeMillis() < validUntil;
1294 public Iterator getRoleDescriptors() {
1295 return roles.iterator();
1298 public RoleDescriptor getRoleByType(Class type, String protocol) {
1299 for (int i=0; i<roles.size(); i++) {
1300 RoleDescriptor role = (RoleDescriptor)roles.get(i);
1301 if (type.isInstance(role) && role.hasSupport(protocol))
1307 public IDPSSODescriptor getIDPSSODescriptor(String protocol) {
1308 return (IDPSSODescriptor)getRoleByType(IDPSSODescriptor.class, protocol);
1311 public SPSSODescriptor getSPSSODescriptor(String protocol) {
1312 return (SPSSODescriptor)getRoleByType(SPSSODescriptor.class, protocol);
1315 public AuthnAuthorityDescriptor getAuthnAuthorityDescriptor(String protocol) {
1316 return (AuthnAuthorityDescriptor)getRoleByType(AuthnAuthorityDescriptor.class, protocol);
1319 public AttributeAuthorityDescriptor getAttributeAuthorityDescriptor(String protocol) {
1320 return (AttributeAuthorityDescriptor)getRoleByType(AttributeAuthorityDescriptor.class, protocol);
1323 public AttributeRequesterDescriptor getAttributeRequesterDescriptor(String protocol) {
1324 return (AttributeRequesterDescriptor)getRoleByType(AttributeRequesterDescriptor.class, protocol);
1327 public PDPDescriptor getPDPDescriptor(String protocol) {
1328 return (PDPDescriptor)getRoleByType(PDPDescriptor.class, protocol);
1331 public AffiliationDescriptor getAffiliationDescriptor() {
1335 public Organization getOrganization() {
1339 public Iterator getContactPersons() {
1340 return contacts.iterator();
1343 public Map getAdditionalMetadataLocations() {
1344 return Collections.unmodifiableMap(locs);
1347 public EntitiesDescriptor getEntitiesDescriptor() {
1351 public Element getElement() {
1355 public long getValidUntil() {
1359 public URL getErrorURL() {
1363 public Iterator getKeyAuthorities() {
1364 return keyauths.iterator();
1368 class XMLEntitiesDescriptor implements ExtendedEntitiesDescriptor {
1369 private Element root = null;
1370 private EntitiesDescriptor parent = null;
1371 private String name = null;
1372 private ArrayList /* <EntitiesDescriptor> */ groups = new ArrayList();
1373 private ArrayList /* <EntityDescriptor> */ providers = new ArrayList();
1374 private long validUntil = Long.MAX_VALUE;
1375 private ArrayList /* <KeyAuthority> */ keyauths = new ArrayList();
1377 public XMLEntitiesDescriptor(Element e, XMLMetadataProvider wrapper, long validUntil, EntitiesDescriptor parent) throws SAMLException {
1379 this.parent = parent;
1380 this.validUntil = validUntil;
1381 name = XML.assign(e.getAttributeNS(null, "Name"));
1383 // Check the root element namespace. If SAML2, assume it's the std schema.
1384 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
1386 if (e.hasAttributeNS(null,"validUntil")) {
1387 SimpleDateFormat formatter = null;
1388 String dateTime = XML.assign(e.getAttributeNS(null,"validUntil"));
1389 int dot = dateTime.indexOf('.');
1391 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
1393 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
1394 formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
1396 this.validUntil=Math.min(validUntil,formatter.parse(dateTime).getTime());
1398 catch (ParseException e1) {
1399 log.warn("Entities descriptor contains invalid expiration time");
1403 e = XML.getFirstChildElement(e);
1405 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions")) {
1406 Element ext = XML.getFirstChildElement(e,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1407 while (ext != null) {
1408 keyauths.add(new XMLKeyAuthority(ext));
1409 ext = XML.getNextSiblingElement(ext,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1412 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EntitiesDescriptor"))
1413 groups.add(new XMLEntitiesDescriptor(e, wrapper, this.validUntil, this));
1414 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EntityDescriptor"))
1415 providers.add(new XMLEntityDescriptor(e, wrapper, this.validUntil, this));
1416 e = XML.getNextSiblingElement(e);
1420 e = XML.getFirstChildElement(e);
1422 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"SiteGroup"))
1423 groups.add(new XMLEntitiesDescriptor(e, wrapper, this.validUntil, this));
1424 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"OriginSite"))
1425 providers.add(new XMLEntityDescriptor(e, wrapper, this.validUntil, this));
1426 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"DestinationSite"))
1427 providers.add(new XMLEntityDescriptor(e, wrapper, this.validUntil, this));
1428 e = XML.getNextSiblingElement(e);
1433 public String getName() {
1437 public boolean isValid() {
1438 return System.currentTimeMillis() < validUntil;
1441 public EntitiesDescriptor getEntitiesDescriptor() {
1445 public Iterator getEntitiesDescriptors() {
1446 return groups.iterator();
1449 public Iterator getEntityDescriptors() {
1450 return providers.iterator();
1453 public Element getElement() {
1457 public Iterator getKeyAuthorities() {
1458 return keyauths.iterator();