2 * The Shibboleth License, Version 1. Copyright (c) 2002 University Corporation for Advanced Internet Development, Inc.
3 * All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted
4 * provided that the following conditions are met: Redistributions of source code must retain the above copyright
5 * notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the
6 * above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other
7 * materials provided with the distribution, if any, must include the following acknowledgment: "This product includes
8 * software developed by the University Corporation for Advanced Internet Development <http://www.ucaid.edu>Internet2
9 * Project. Alternately, this acknowledegement may appear in the software itself, if and wherever such third-party
10 * acknowledgments normally appear. Neither the name of Shibboleth nor the names of its contributors, nor Internet2,
11 * nor the University Corporation for Advanced Internet Development, Inc., nor UCAID may be used to endorse or promote
12 * products derived from this software without specific prior written permission. For written permission, please
13 * contact shibboleth@shibboleth.org Products derived from this software may not be called Shibboleth, Internet2,
14 * UCAID, or the University Corporation for Advanced Internet Development, nor may Shibboleth appear in their name,
15 * without prior written permission of the University Corporation for Advanced Internet Development. THIS SOFTWARE IS
16 * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES,
17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
18 * NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS
19 * WITH LICENSEE. IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY CORPORATION FOR ADVANCED
20 * INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
23 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
27 package edu.internet2.middleware.shibboleth.metadata.provider;
29 import java.net.MalformedURLException;
31 import java.security.NoSuchAlgorithmException;
32 import java.text.ParseException;
33 import java.text.SimpleDateFormat;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.Collections;
37 import java.util.HashMap;
38 import java.util.Iterator;
40 import java.util.TimeZone;
42 import javax.xml.namespace.QName;
44 import org.apache.log4j.Logger;
45 import org.apache.xml.security.encryption.EncryptionMethod;
46 import org.apache.xml.security.exceptions.XMLSecurityException;
47 import org.apache.xml.security.keys.KeyInfo;
48 import org.bouncycastle.util.encoders.Hex;
49 import org.opensaml.SAMLAttribute;
50 import org.opensaml.SAMLBinding;
51 import org.opensaml.SAMLBrowserProfile;
52 import org.opensaml.SAMLException;
53 import org.opensaml.XML;
54 import org.opensaml.artifact.Artifact;
55 import org.opensaml.artifact.SAMLArtifactType0001;
56 import org.opensaml.artifact.SAMLArtifactType0002;
57 import org.opensaml.artifact.Util;
58 import org.w3c.dom.Attr;
59 import org.w3c.dom.Element;
60 import org.w3c.dom.NamedNodeMap;
61 import org.w3c.dom.Node;
62 import org.w3c.dom.NodeList;
64 import edu.internet2.middleware.shibboleth.common.Constants;
65 import edu.internet2.middleware.shibboleth.metadata.*;
68 * @author Scott Cantor
70 public class XMLMetadataProvider implements Metadata {
72 private static Logger log = Logger.getLogger(XMLMetadataProvider.class.getName());
73 private Map /* <String,ArrayList<EntityDescriptor> > */ sites = new HashMap();
74 private Map /* <String,ArrayList<EntityDescriptor> > */ sources = new HashMap();
75 private XMLEntityDescriptor rootProvider = null;
76 private XMLEntitiesDescriptor rootGroup = null;
78 public XMLMetadataProvider(Element e) throws SAMLException {
79 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EntitiesDescriptor"))
80 rootGroup=new XMLEntitiesDescriptor(e,this, Long.MAX_VALUE, null);
81 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EntityDescriptor"))
82 rootProvider=new XMLEntityDescriptor(e,this, Long.MAX_VALUE, null);
83 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"SiteGroup"))
84 rootGroup=new XMLEntitiesDescriptor(e,this, Long.MAX_VALUE, null);
85 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"OriginSite"))
86 rootProvider=new XMLEntityDescriptor(e,this, Long.MAX_VALUE, null);
87 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"DestinationSite"))
88 rootProvider=new XMLEntityDescriptor(e,this, Long.MAX_VALUE, null);
90 log.error("Construction requires a valid SAML metadata file");
91 throw new MetadataException("Construction requires a valid SAML metadata file");
95 public EntityDescriptor lookup(String id) {
96 ArrayList list = (ArrayList)sites.get(id);
98 long now = System.currentTimeMillis();
99 for (int i=0; i<list.size(); i++) {
100 if (now < ((XMLEntityDescriptor)list.get(i)).getValidUntil())
101 return (EntityDescriptor)list.get(i);
107 public EntityDescriptor lookup(Artifact artifact) {
108 ArrayList list = null;
110 if (artifact instanceof SAMLArtifactType0001) {
111 list = (ArrayList)sources.get(((SAMLArtifactType0001)artifact).getSourceId());
113 else if (artifact instanceof SAMLArtifactType0002) {
114 list = (ArrayList)sources.get(((SAMLArtifactType0002)artifact).getSourceLocation().toString());
117 log.error("unsupported artifact type (" + artifact.getTypeCode().toString() + ")");
121 long now = System.currentTimeMillis();
122 for (int i=0; i<list.size(); i++) {
123 if (now < ((XMLEntityDescriptor)list.get(i)).getValidUntil())
124 return (EntityDescriptor)list.get(i);
130 class XMLEndpoint implements Endpoint {
131 private Element root = null;
132 private String binding = null;
133 private String location = null;
134 private String resploc = null;
136 XMLEndpoint(Element e) {
138 binding = XML.assign(e.getAttributeNS(null,"Binding"));
139 location = XML.assign(e.getAttributeNS(null,"Location"));
140 resploc = XML.assign(e.getAttributeNS(null,"ResponseLocation"));
143 XMLEndpoint(String binding, String location) {
144 this.binding = binding;
145 this.location = location;
148 public String getBinding() {
152 public String getLocation() {
156 public String getResponseLocation() {
160 public Element getElement() {
165 class XMLIndexedEndpoint extends XMLEndpoint implements IndexedEndpoint {
166 private int index = 0;
168 XMLIndexedEndpoint(Element e) {
170 index = Integer.parseInt(e.getAttributeNS(null,"index"));
173 public int getIndex() {
178 class XMLEndpointManager implements EndpointManager {
179 private ArrayList endpoints = new ArrayList();
180 Endpoint soft = null; // Soft default (not explicit)
181 Endpoint hard = null; // Hard default (explicit)
183 public Iterator getEndpoints() {
184 return endpoints.iterator();
187 public Endpoint getDefaultEndpoint() {
188 if (hard != null) return hard;
189 if (soft != null) return soft;
190 if (!endpoints.isEmpty()) return (Endpoint)endpoints.get(0);
194 public Endpoint getEndpointByIndex(int index) {
195 for (int i=0; i < endpoints.size(); i++) {
196 if (endpoints.get(i) instanceof IndexedEndpoint && index==((IndexedEndpoint)endpoints.get(i)).getIndex())
197 return (Endpoint)endpoints.get(i);
202 public Endpoint getEndpointByBinding(String binding) {
203 for (int i=0; i < endpoints.size(); i++) {
204 if (binding.equals(((Endpoint)endpoints.get(i)).getBinding()))
205 return (Endpoint)endpoints.get(i);
210 protected void add(Endpoint e) {
212 if (hard == null && e.getElement() != null) {
213 String v=XML.assign(e.getElement().getAttributeNS(null,"isDefault"));
214 if (v != null && (v.equals("1") || v.equals("true"))) // explicit default
216 else if (v == null && soft == null) // implicit default
219 else if (hard == null && soft == null) {
220 // No default yet, so this one qualifies as an implicit.
226 class XMLKeyDescriptor implements KeyDescriptor {
228 private int use = KeyDescriptor.UNSPECIFIED;
229 private KeyInfo keyInfo = null;
230 private ArrayList /* <XMLEncryptionMethod> */ methods = new ArrayList();
232 XMLKeyDescriptor(Element e) {
233 if (XML.safeCompare(e.getAttributeNS(null,"use"),"encryption"))
234 use = KeyDescriptor.ENCRYPTION;
235 else if (XML.safeCompare(e.getAttributeNS(null,"use"),"signing"))
236 use = KeyDescriptor.SIGNING;
238 e = XML.getFirstChildElement(e);
240 keyInfo = new KeyInfo(e, null);
242 catch (XMLSecurityException e1) {
243 log.error("unable to process ds:KeyInfo element: " + e1.getMessage());
246 e = XML.getNextSiblingElement(e);
247 while (e != null && XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EncryptionMethod")) {
248 methods.add(new XMLEncryptionMethod(e));
252 public int getUse() {
256 public Iterator getEncryptionMethods() {
257 return methods.iterator();
260 public KeyInfo getKeyInfo() {
265 class XMLEncryptionMethod implements EncryptionMethod {
268 String params = null;
271 public XMLEncryptionMethod(Element e) {
272 alg = XML.assign(e.getAttributeNS(null, "Algorithm"));
273 e = XML.getFirstChildElement(e);
275 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.XMLENC_NS,"KeySize")) {
276 if (e.hasChildNodes())
277 size = Integer.parseInt(e.getFirstChild().getNodeValue());
279 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.XMLENC_NS,"OAEParams")) {
280 if (e.hasChildNodes())
281 params = XML.assign(e.getFirstChild().getNodeValue());
283 e = XML.getNextSiblingElement(e);
287 public String getAlgorithm() {
291 public int getKeySize() {
295 public byte[] getOAEPparams() {
296 return params.getBytes();
299 public Iterator getEncryptionMethodInformation() {
303 public void setKeySize(int arg0) {
304 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
307 public void setOAEPparams(byte[] arg0) {
308 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
311 public void addEncryptionMethodInformation(Element arg0) {
312 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
315 public void removeEncryptionMethodInformation(Element arg0) {
316 throw new UnsupportedOperationException("EncryptionMethod implementation is read-only.");
320 class XMLKeyAuthority implements KeyAuthority {
321 private int depth = 1;
322 private ArrayList /* <KeyInfo> */ keys = new ArrayList();
324 XMLKeyAuthority(Element e) {
325 if (e.hasAttributeNS(null,"VerifyDepth"))
326 depth = Integer.parseInt(e.getAttributeNS(null,"VerifyDepth"));
327 e = XML.getFirstChildElement(e, XML.XMLSIG_NS, "KeyInfo");
330 keys.add(new KeyInfo(e, null));
332 catch (XMLSecurityException e1) {
333 log.error("unable to process ds:KeyInfo element: " + e1.getMessage());
335 e = XML.getNextSiblingElement(e, XML.XMLSIG_NS, "KeyInfo");
339 public int getVerifyDepth() {
343 public Iterator getKeyInfos() {
344 return keys.iterator();
349 class XMLOrganization implements Organization {
350 private Element root = null;
351 private HashMap /* <String,String> */ names = new HashMap();
352 private HashMap /* <String,String> */ displays = new HashMap();
353 private HashMap /* <String,URL> */ urls = new HashMap();
355 public XMLOrganization(Element e) throws MetadataException {
357 e=XML.getFirstChildElement(e);
359 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"OrganizationName")) {
360 if (e.hasChildNodes()) {
361 names.put(e.getAttributeNS(XML.XML_NS,"lang"),XML.assign(e.getFirstChild().getNodeValue()));
364 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"OrganizationDisplayName")) {
365 if (e.hasChildNodes()) {
366 displays.put(e.getAttributeNS(XML.XML_NS,"lang"),XML.assign(e.getFirstChild().getNodeValue()));
369 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"OrganizationURL")) {
370 if (e.hasChildNodes()) {
373 u = new URL(e.getFirstChild().getNodeValue());
375 catch (MalformedURLException e1) {
376 throw new MetadataException("OrganizationURL was invalid: " + e1);
378 urls.put(e.getAttributeNS(XML.XML_NS,"lang"),u);
381 e=XML.getNextSiblingElement(e);
385 public String getName() {
386 return getName("en");
389 public String getName(String lang) {
390 return (String)names.get(lang);
393 public String getDisplayName() {
394 return getDisplayName("en");
397 public String getDisplayName(String lang) {
398 return (String)displays.get(lang);
401 public URL getURL() {
405 public URL getURL(String lang) {
406 return (URL)urls.get(lang);
411 class XMLContactPerson implements ContactPerson {
412 private Element root = null;
414 private String company = null;
415 private String givenName = null;
416 private String surName = null;
417 private ArrayList /* <String> */ emails = new ArrayList();
418 private ArrayList /* <String> */ telephones = new ArrayList();
420 public XMLContactPerson(Element e) throws MetadataException {
422 String rawType = null;
424 // Old metadata or new?
425 if (XML.isElementNamed(root, edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Contact")) {
426 rawType = root.getAttributeNS(null,"Type");
427 surName = XML.assign(root.getAttributeNS(null,"Name"));
428 if (XML.isEmpty(surName)) {
429 throw new MetadataException("Contact is missing Name attribute.");
431 if (root.hasAttributeNS(null,"Email"))
432 emails.add(e.getAttributeNS(null,"Email"));
435 rawType = root.getAttributeNS(null,"contactType");
437 e=XML.getFirstChildElement(root);
439 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Company")) {
440 if (e.hasChildNodes())
441 company=XML.assign(e.getFirstChild().getNodeValue());
443 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"GivenName")) {
444 if (e.hasChildNodes())
445 givenName=XML.assign(e.getFirstChild().getNodeValue());
447 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SurName")) {
448 if (e.hasChildNodes())
449 surName=XML.assign(e.getFirstChild().getNodeValue());
451 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EmailAddress")) {
452 if (e.hasChildNodes())
453 emails.add(XML.assign(e.getFirstChild().getNodeValue()));
455 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"TelephoneNumber")) {
456 if (e.hasChildNodes())
457 telephones.add(XML.assign(e.getFirstChild().getNodeValue()));
459 e=XML.getNextSiblingElement(e);
463 if (rawType.equalsIgnoreCase("TECHNICAL")) {
464 type = ContactPerson.TECHNICAL;
465 } else if (rawType.equalsIgnoreCase("SUPPORT")) {
466 type = ContactPerson.SUPPORT;
467 } else if (rawType.equalsIgnoreCase("ADMINISTRATIVE")) {
468 type = ContactPerson.ADMINISTRATIVE;
469 } else if (rawType.equalsIgnoreCase("BILLING")) {
470 type = ContactPerson.BILLING;
471 } else if (rawType.equalsIgnoreCase("OTHER")) {
472 type = ContactPerson.OTHER;
474 throw new MetadataException("Contact has unknown contact type.");
478 public int getType() {
482 public String getGivenName() {
486 public String getSurName() {
490 public String getCompany() {
494 public Iterator getEmailAddresses() {
495 return emails.iterator();
498 public Iterator getTelephoneNumbers() {
499 return telephones.iterator();
502 public Element getElement() {
507 class Role implements RoleDescriptor {
508 private Element root = null;
509 private XMLEntityDescriptor provider = null;
510 private URL errorURL = null;
511 private Organization org = null;
512 private ArrayList /* <ContactPerson> */ contacts = new ArrayList();
513 private long validUntil = Long.MAX_VALUE;
514 protected ArrayList /* <String> */ protocolEnum = new ArrayList();
515 protected ArrayList /* <KeyDescriptor> */ keys = new ArrayList();
517 public Role(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
519 this.validUntil = validUntil;
520 this.provider = provider;
522 // Check the root element namespace. If SAML2, assume it's the std schema.
523 if (e != null && edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
525 if (e.hasAttributeNS(null,"validUntil")) {
526 SimpleDateFormat formatter = null;
527 String dateTime = XML.assign(e.getAttributeNS(null,"validUntil"));
528 int dot = dateTime.indexOf('.');
530 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
532 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
533 formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
535 validUntil=Math.min(validUntil,formatter.parse(dateTime).getTime());
537 catch (ParseException e1) {
538 log.warn("Role descriptor contains invalid expiration time");
542 if (e.hasAttributeNS(null,"errorURL")) {
544 errorURL=new URL(e.getAttributeNS(null,"errorURL"));
546 catch (MalformedURLException e1) {
547 log.error("Role descriptor contains malformed errorURL");
551 // Chop the protocol list into pieces...assume any whitespace can appear in between.
552 protocolEnum.addAll(Arrays.asList(e.getAttributeNS(null,"protocolSupportEnumeration").split("\\s")));
554 e = XML.getFirstChildElement(root,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
556 keys.add(new XMLKeyDescriptor(e));
557 e = XML.getNextSiblingElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
560 e = XML.getFirstChildElement(root,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Organization");
562 org=new XMLOrganization(e);
564 e = XML.getFirstChildElement(root,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ContactPerson");
566 contacts.add(new XMLContactPerson(e));
567 e = XML.getNextSiblingElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ContactPerson");
572 public EntityDescriptor getEntityDescriptor() {
576 public Iterator getProtocolSupportEnumeration() {
577 return protocolEnum.iterator();
580 public boolean hasSupport(String version) {
581 return protocolEnum.contains(version);
584 public boolean isValid() {
585 return System.currentTimeMillis() < validUntil;
588 public URL getErrorURL() {
589 return (errorURL != null) ? errorURL : provider.getErrorURL();
592 public Iterator getKeyDescriptors() {
593 return keys.iterator();
596 public Organization getOrganization() {
597 return (org != null) ? org : provider.getOrganization();
600 public Iterator getContactPersons() {
601 return (contacts.isEmpty()) ? provider.getContactPersons() : contacts.iterator();
604 public Element getElement() {
609 class SSORole extends Role implements SSODescriptor {
610 private XMLEndpointManager artifact = new XMLEndpointManager();
611 private XMLEndpointManager logout = new XMLEndpointManager();
612 private XMLEndpointManager nameid = new XMLEndpointManager();
613 private ArrayList /* <String> */ formats = new ArrayList();
615 public SSORole(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
616 super(provider, validUntil, e);
618 // Check the root element namespace. If SAML2, assume it's the std schema.
619 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
621 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ArtifactResolutionService");
622 for (i=0; i<nlist.getLength(); i++)
623 artifact.add(new XMLIndexedEndpoint((Element)nlist.item(i)));
625 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SingleLogoutService");
626 for (i=0; i<nlist.getLength(); i++)
627 logout.add(new XMLEndpoint((Element)nlist.item(i)));
629 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ManageNameIDService");
630 for (i=0; i<nlist.getLength(); i++)
631 nameid.add(new XMLEndpoint((Element)nlist.item(i)));
633 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"NameIDFormat");
634 for (i = 0; i < nlist.getLength(); i++) {
635 if (nlist.item(i).hasChildNodes()) {
636 Node tnode = nlist.item(i).getFirstChild();
637 if (tnode != null && tnode.getNodeType() == Node.TEXT_NODE) {
638 formats.add(tnode.getNodeValue());
644 // For old style, we just do SAML 1.1 compatibility with Shib handles.
645 protocolEnum.add(XML.SAML11_PROTOCOL_ENUM);
646 formats.add(Constants.SHIB_NAMEID_FORMAT_URI);
650 public EndpointManager getArtifactResolutionServiceManager() {
654 public EndpointManager getSingleLogoutServiceManager() {
658 public EndpointManager getManageNameIDServiceManager() {
662 public Iterator getNameIDFormats() {
663 return formats.iterator();
667 class IDPRole extends SSORole implements IDPSSODescriptor, ScopedRoleDescriptor {
668 private ArrayList /* <Scope> */ scopes = new ArrayList();
669 private XMLEndpointManager sso = new XMLEndpointManager();
670 private XMLEndpointManager mapping = new XMLEndpointManager();
671 private XMLEndpointManager idreq = new XMLEndpointManager();
672 private ArrayList /* <String> */ attrprofs = new ArrayList();
673 private ArrayList /* <SAMLAttribute> */ attrs = new ArrayList();
674 private boolean wantAuthnRequestsSigned = false;
675 private String sourceId = null;
677 public IDPRole(XMLEntityDescriptor provider, long validUntil, Element e) throws SAMLException {
678 super(provider, validUntil, e);
679 NodeList domains=null;
681 // Check the root element namespace. If SAML2, assume it's the std schema.
682 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
683 String flag=XML.assign(e.getAttributeNS(null,"WantAuthnRequestsSigned"));
684 wantAuthnRequestsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
686 // Check for extensions.
687 Element ext=XML.getFirstChildElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions");
689 Element ext1=XML.getFirstChildElement(ext,XML.SAML_ARTIFACT_SOURCEID,"SourceID");
690 if (ext1 != null && ext1.hasChildNodes())
691 sourceId=ext1.getFirstChild().getNodeValue();
692 // Save off any domain elements for later.
693 domains = ext.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"Scope");
697 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SingleSignOnService");
698 for (i=0; i<nlist.getLength(); i++)
699 sso.add(new XMLEndpoint((Element)(nlist.item(i))));
701 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"NameIDMappingService");
702 for (i=0; i<nlist.getLength(); i++)
703 mapping.add(new XMLEndpoint((Element)(nlist.item(i))));
705 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AssertionIDRequestService");
706 for (i=0; i<nlist.getLength(); i++)
707 idreq.add(new XMLEndpoint((Element)(nlist.item(i))));
709 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeProfile");
710 for (i=0; i<nlist.getLength(); i++) {
711 if (nlist.item(i).hasChildNodes())
712 attrprofs.add(nlist.item(i).getFirstChild().getNodeValue());
715 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"Attribute");
716 for (i=0; i<nlist.getLength(); i++) {
717 // For now, we need to convert these to plain SAML 1.1 attributes.
718 Element src=(Element)(nlist.item(i));
719 Element copy=e.getOwnerDocument().createElementNS(XML.SAML_NS,"Attribute");
720 copy.setAttributeNS(null,"AttributeName",src.getAttributeNS(null,"Name"));
721 copy.setAttributeNS(null,"AttributeNamespace",src.getAttributeNS(null,"NameFormat"));
722 src=XML.getFirstChildElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
723 while (src != null) {
724 src=XML.getNextSiblingElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
725 Element val=e.getOwnerDocument().createElementNS(XML.SAML_NS,"AttributeValue");
726 NamedNodeMap attrs = src.getAttributes();
727 for (int j=0; j<attrs.getLength(); j++)
728 val.setAttributeNodeNS((Attr)(e.getOwnerDocument().importNode(attrs.item(j),true)));
729 while (src.hasChildNodes())
730 val.appendChild(src.getFirstChild());
731 copy.appendChild(val);
733 attrs.add(SAMLAttribute.getInstance(copy));
737 attrprofs.add(Constants.SHIB_ATTRIBUTE_NAMESPACE_URI);
739 domains = e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Domain");
740 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"HandleService");
741 for (i=0; i<nlist.getLength(); i++) {
742 // Manufacture an endpoint for the "Shib" binding.
744 new XMLEndpoint(Constants.SHIB_AUTHNREQUEST_PROFILE_URI,((Element)nlist.item(i)).getAttributeNS(null,"Location"))
747 // We're going to "mock up" a KeyDescriptor that contains the specified Name as a ds:KeyName.
748 Element kd=e.getOwnerDocument().createElementNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
749 Element ki=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyInfo");
750 Element kn=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyName");
752 e.getOwnerDocument().createTextNode(((Element)nlist.item(i)).getAttributeNS(null,"Name"))
756 kd.setAttributeNS(null,"use","signing");
757 keys.add(new XMLKeyDescriptor(kd));
761 if (domains != null) {
762 for (int i=0; i < domains.getLength(); i++) {
763 String dom=(domains.item(i).hasChildNodes()) ? domains.item(i).getFirstChild().getNodeValue() : null;
765 String regexp=XML.assign(((Element)domains.item(i)).getAttributeNS(null,"regexp"));
767 new Scope(dom,(XML.safeCompare(regexp,"true") || XML.safeCompare(regexp,"1")))
774 public Iterator getScopes() {
775 return scopes.iterator();
778 public boolean getWantAuthnRequestsSigned() {
779 return wantAuthnRequestsSigned;
782 public EndpointManager getSingleSignOnServiceManager() {
786 public EndpointManager getNameIDMappingServiceManager() {
790 public EndpointManager getAssertionIDRequestServiceManager() {
794 public Iterator getAttributeProfiles() {
795 return attrprofs.iterator();
798 public Iterator getAttributes() {
799 return attrs.iterator();
803 class AARole extends Role implements AttributeAuthorityDescriptor, ScopedRoleDescriptor {
804 private ArrayList /* <Scope> */ scopes = new ArrayList();
805 private XMLEndpointManager query = new XMLEndpointManager();
806 private XMLEndpointManager idreq = new XMLEndpointManager();
807 private ArrayList /* <String> */ attrprofs = new ArrayList();
808 private ArrayList /* <String> */ formats = new ArrayList();
809 private ArrayList /* <SAMLAttribute> */ attrs = new ArrayList();
811 public AARole(XMLEntityDescriptor provider, long validUntil, Element e) throws SAMLException {
812 super(provider, validUntil, e);
813 NodeList domains=null;
815 // Check the root element namespace. If SAML2, assume it's the std schema.
816 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
818 // Check for extensions.
819 Element ext=XML.getFirstChildElement(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions");
821 // Save off any domain elements for later.
822 domains = ext.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"Scope");
826 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeService");
827 for (i=0; i<nlist.getLength(); i++)
828 query.add(new XMLEndpoint((Element)(nlist.item(i))));
830 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AssertionIDRequestService");
831 for (i=0; i<nlist.getLength(); i++)
832 idreq.add(new XMLEndpoint((Element)(nlist.item(i))));
834 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeProfile");
835 for (i=0; i<nlist.getLength(); i++) {
836 if (nlist.item(i).hasChildNodes())
837 attrprofs.add(nlist.item(i).getFirstChild().getNodeValue());
840 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"Attribute");
841 for (i=0; i<nlist.getLength(); i++) {
842 // For now, we need to convert these to plain SAML 1.1 attributes.
843 Element src=(Element)(nlist.item(i));
844 Element copy=e.getOwnerDocument().createElementNS(XML.SAML_NS,"Attribute");
845 copy.setAttributeNS(null,"AttributeName",src.getAttributeNS(null,"Name"));
846 copy.setAttributeNS(null,"AttributeNamespace",src.getAttributeNS(null,"NameFormat"));
847 src=XML.getFirstChildElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
848 while (src != null) {
849 src=XML.getNextSiblingElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
850 Element val=e.getOwnerDocument().createElementNS(XML.SAML_NS,"AttributeValue");
851 NamedNodeMap attrs = src.getAttributes();
852 for (int j=0; j<attrs.getLength(); j++)
853 val.setAttributeNodeNS((Attr)(e.getOwnerDocument().importNode(attrs.item(j),true)));
854 while (src.hasChildNodes())
855 val.appendChild(src.getFirstChild());
856 copy.appendChild(val);
858 attrs.add(SAMLAttribute.getInstance(copy));
862 // For old style, we just do SAML 1.1 compatibility with Shib handles.
863 protocolEnum.add(XML.SAML11_PROTOCOL_ENUM);
864 formats.add(Constants.SHIB_NAMEID_FORMAT_URI);
865 attrprofs.add(Constants.SHIB_ATTRIBUTE_NAMESPACE_URI);
866 domains = e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Domain");
868 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AttributeAuthority");
869 for (i=0; i<nlist.getLength(); i++) {
870 // Manufacture an endpoint for the SOAP binding.
874 ((Element)nlist.item(i)).getAttributeNS(null,"Location")
878 // We're going to "mock up" a KeyDescriptor that contains the specified Name as a ds:KeyName.
879 Element kd=e.getOwnerDocument().createElementNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
880 Element ki=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyInfo");
881 Element kn=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyName");
883 e.getOwnerDocument().createTextNode(((Element)nlist.item(i)).getAttributeNS(null,"Name"))
887 kd.setAttributeNS(null,"use","signing");
888 keys.add(new XMLKeyDescriptor(kd));
892 if (domains != null) {
893 for (int i=0; i < domains.getLength(); i++) {
894 String dom=(domains.item(i).hasChildNodes()) ? domains.item(i).getFirstChild().getNodeValue() : null;
896 String regexp=XML.assign(((Element)domains.item(i)).getAttributeNS(null,"regexp"));
898 new Scope(dom,(XML.safeCompare(regexp,"true") || XML.safeCompare(regexp,"1")))
905 public Iterator getScopes() {
906 return scopes.iterator();
909 public EndpointManager getAttributeServiceManager() {
913 public EndpointManager getAssertionIDRequestServiceManager() {
917 public Iterator getAttributeProfiles() {
918 return attrprofs.iterator();
921 public Iterator getAttributes() {
922 return attrs.iterator();
925 public Iterator getNameIDFormats() {
926 return formats.iterator();
930 class SPRole extends SSORole implements SPSSODescriptor {
931 private boolean authnRequestsSigned = false;
932 private boolean wantAssertionsSigned = false;
933 private XMLEndpointManager asc = new XMLEndpointManager();
935 public SPRole(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
936 super(provider, validUntil, e);
938 // Check the root element namespace. If SAML2, assume it's the std schema.
939 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
940 String flag=XML.assign(e.getAttributeNS(null,"AuthnRequestsSigned"));
941 authnRequestsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
942 flag=XML.assign(e.getAttributeNS(null,"WantAssertionsSigned"));
943 wantAssertionsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
946 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AssertionConsumerService");
947 for (i=0; i<nlist.getLength(); i++)
948 asc.add(new XMLIndexedEndpoint((Element)(nlist.item(i))));
951 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"Attribute");
952 for (i=0; i<nlist.getLength(); i++) {
953 // For now, we need to convert these to plain SAML 1.1 attributes.
954 Element src=(Element)(nlist.item(i));
955 Element copy=e.getOwnerDocument().createElementNS(XML.SAML_NS,"Attribute");
956 copy.setAttributeNS(null,"AttributeName",src.getAttributeNS(null,"Name"));
957 copy.setAttributeNS(null,"AttributeNamespace",src.getAttributeNS(null,"NameFormat"));
958 src=XML.getFirstChildElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
959 while (src != null) {
960 src=XML.getNextSiblingElement(src,edu.internet2.middleware.shibboleth.common.XML.SAML2ASSERT_NS,"AttributeValue");
961 Element val=e.getOwnerDocument().createElementNS(XML.SAML_NS,"AttributeValue");
962 NamedNodeMap attrs = src.getAttributes();
963 for (int j=0; j<attrs.getLength(); j++)
964 val.setAttributeNodeNS((Attr)(e.getOwnerDocument().importNode(attrs.item(j),true)));
965 while (src.hasChildNodes())
966 val.appendChild(src.getFirstChild());
967 copy.appendChild(val);
969 attrs.add(SAMLAttribute.getInstance(copy));
975 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AssertionConsumerServiceURL");
976 for (i=0; i<nlist.getLength(); i++) {
977 // Manufacture an endpoint for the POST profile.
979 new XMLEndpoint(SAMLBrowserProfile.PROFILE_POST_URI,((Element)nlist.item(i)).getAttributeNS(null,"Location"))
983 nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AttributeRequester");
984 for (i=0; i<nlist.getLength(); i++) {
985 // We're going to "mock up" a KeyDescriptor that contains the specified Name as a ds:KeyName.
986 Element kd=e.getOwnerDocument().createElementNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"KeyDescriptor");
987 Element ki=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyInfo");
988 Element kn=e.getOwnerDocument().createElementNS(XML.XMLSIG_NS,"KeyName");
990 e.getOwnerDocument().createTextNode(((Element)nlist.item(i)).getAttributeNS(null,"Name"))
994 kd.setAttributeNS(null,"use","signing");
995 keys.add(new XMLKeyDescriptor(kd));
1000 public boolean getAuthnRequestsSigned() {
1001 return authnRequestsSigned;
1004 public boolean getWantAssertionsSigned() {
1005 return wantAssertionsSigned;
1008 public EndpointManager getAssertionConsumerServiceManager() {
1012 public Iterator getAttributeConsumingServices() {
1013 // TODO Auto-generated method stub
1017 public AttributeConsumingService getDefaultAttributeConsumingService() {
1018 // TODO Auto-generated method stub
1022 public AttributeConsumingService getAttributeConsumingServiceByID(String id) {
1023 // TODO Auto-generated method stub
1028 class AttributeRequesterRole extends Role implements AttributeRequesterDescriptor {
1029 private boolean wantAssertionsSigned = false;
1030 private ArrayList /* <String> */ formats = new ArrayList();
1032 public AttributeRequesterRole(XMLEntityDescriptor provider, long validUntil, Element e) throws MetadataException {
1033 super(provider, validUntil, e);
1035 String flag=XML.assign(e.getAttributeNS(null,"WantAssertionsSigned"));
1036 wantAssertionsSigned=(XML.safeCompare(flag,"1") || XML.safeCompare(flag,"true"));
1038 NodeList nlist=e.getElementsByTagNameNS(edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"NameIDFormat");
1039 for (int i = 0; i < nlist.getLength(); i++) {
1040 if (nlist.item(i).hasChildNodes()) {
1041 Node tnode = nlist.item(i).getFirstChild();
1042 if (tnode != null && tnode.getNodeType() == Node.TEXT_NODE) {
1043 formats.add(tnode.getNodeValue());
1049 public boolean getWantAssertionsSigned() {
1050 return wantAssertionsSigned;
1053 public Iterator getNameIDFormats() {
1054 return formats.iterator();
1057 public Iterator getAttributeConsumingServices() {
1058 // TODO Auto-generated method stub
1062 public AttributeConsumingService getDefaultAttributeConsumingService() {
1063 // TODO Auto-generated method stub
1067 public AttributeConsumingService getAttributeConsumingServiceByID(String id) {
1068 // TODO Auto-generated method stub
1073 class XMLEntityDescriptor implements ExtendedEntityDescriptor {
1074 private Element root = null;
1075 private EntitiesDescriptor parent = null;
1076 private String id = null;
1077 private URL errorURL = null;
1078 private Organization org = null;
1079 private ArrayList /* <ContactPerson> */ contacts = new ArrayList();
1080 private ArrayList /* <RoleDescriptor> */ roles = new ArrayList();
1081 private AffiliationDescriptor affiliation = null;
1082 private HashMap /* <String,String> */ locs = new HashMap();
1083 private long validUntil = Long.MAX_VALUE;
1084 private ArrayList /* <KeyAuthority> */ keyauths = new ArrayList();
1086 public XMLEntityDescriptor(Element e, XMLMetadataProvider wrapper, long validUntil, EntitiesDescriptor parent) throws SAMLException {
1088 this.parent = parent;
1089 this.validUntil = validUntil;
1091 // Check the root element namespace. If SAML2, assume it's the std schema.
1092 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
1093 id=e.getAttributeNS(null,"entityID");
1095 if (e.hasAttributeNS(null,"validUntil")) {
1096 SimpleDateFormat formatter = null;
1097 String dateTime = XML.assign(e.getAttributeNS(null,"validUntil"));
1098 int dot = dateTime.indexOf('.');
1100 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
1102 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
1103 formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
1105 validUntil=Math.min(validUntil,formatter.parse(dateTime).getTime());
1107 catch (ParseException e1) {
1108 log.warn("Entity descriptor contains invalid expiration time");
1112 Element child=XML.getFirstChildElement(e);
1113 while (child != null) {
1114 // Process the various kinds of children that we care about...
1115 if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions")) {
1116 Element ext = XML.getFirstChildElement(child,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1117 while (ext != null) {
1118 keyauths.add(new XMLKeyAuthority(ext));
1119 ext = XML.getNextSiblingElement(ext,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1122 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"ContactPerson")) {
1123 contacts.add(new XMLContactPerson(child));
1125 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Organization")) {
1126 org=new XMLOrganization(child);
1128 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AdditionalMetadataLocation")) {
1129 Node loc=child.getFirstChild();
1131 locs.put(child.getAttributeNS(null,"namespace"),loc.getNodeValue());
1133 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"IDPSSODescriptor")) {
1134 roles.add(new IDPRole(this,validUntil,child));
1136 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"AttributeAuthorityDescriptor")) {
1137 roles.add(new AARole(this,validUntil,child));
1139 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"SPSSODescriptor")) {
1140 roles.add(new SPRole(this,validUntil,child));
1142 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"RoleDescriptor")) {
1143 QName xsitype = XML.getQNameAttribute(child,XML.XSI_NS,"type");
1144 if (edu.internet2.middleware.shibboleth.common.XML.SAML2METAEXT_NS.equals(xsitype.getNamespaceURI()) &&
1145 "AttributeRequesterDescriptorType".equals(xsitype.getLocalPart()))
1146 roles.add(new AttributeRequesterRole(this,validUntil,child));
1148 child = XML.getNextSiblingElement(child);
1152 id=e.getAttributeNS(null,"Name");
1153 if (e.hasAttributeNS(null,"ErrorURL")) {
1155 errorURL=new URL(e.getAttributeNS(null,"ErrorURL"));
1157 catch (MalformedURLException e1) {
1158 log.error("Site descriptor contains invalid ErrorURL");
1162 boolean idp=false,aa=false,sp=false; // only want to build a role once
1163 Element child=XML.getFirstChildElement(e);
1164 while (child != null) {
1165 // Process the various kinds of OriginSite children that we care about...
1166 if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"Contact")) {
1167 contacts.add(new XMLContactPerson(child));
1169 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"HandleService") && !idp) {
1170 // Create the IDP role if needed.
1171 roles.add(new IDPRole(this, validUntil, e));
1174 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AttributeAuthority") && !aa) {
1175 // Create the AA role if needed.
1176 roles.add(new AARole(this, validUntil, e));
1179 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AssertionConsumerServiceURL") && !sp) {
1180 // Create the SP role if needed.
1181 roles.add(new SPRole(this, validUntil, e));
1184 else if (XML.isElementNamed(child,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"AttributeRequester") && !sp) {
1185 // Create the SP role if needed.
1186 roles.add(new SPRole(this, validUntil, e));
1189 child = XML.getNextSiblingElement(child);
1193 // Each map entry is a list of the descriptors with this ID.
1195 if (wrapper.sites.containsKey(id)) {
1196 list = (ArrayList)wrapper.sites.get(id);
1199 list = new ArrayList();
1200 wrapper.sites.put(id,list);
1204 // Look for an IdP role, and register the artifact source ID and endpoints.
1206 for (int i=0; i<roles.size(); i++) {
1207 if (roles.get(i) instanceof IDPRole) {
1208 idp = (IDPRole)roles.get(i);
1209 if (idp.sourceId != null) {
1210 if (wrapper.sources.containsKey(idp.sourceId)) {
1211 list = (ArrayList)wrapper.sources.get(idp.sourceId);
1214 list = new ArrayList();
1215 wrapper.sources.put(idp.sourceId,list);
1222 sourceId = new String(Hex.encode(Util.generateSourceId(id)));
1224 catch (NoSuchAlgorithmException e1) {
1225 log.error("caught exception while encoding sourceId: " + e1.getMessage());
1228 if (wrapper.sources.containsKey(sourceId)) {
1229 list = (ArrayList)wrapper.sources.get(sourceId);
1232 list = new ArrayList();
1233 wrapper.sources.put(sourceId,list);
1237 Iterator locs=idp.getArtifactResolutionServiceManager().getEndpoints();
1238 while (locs.hasNext()) {
1239 String loc=((Endpoint)locs.next()).getLocation();
1240 if (wrapper.sources.containsKey(loc)) {
1241 list = (ArrayList)wrapper.sources.get(loc);
1244 list = new ArrayList();
1245 wrapper.sources.put(loc,list);
1253 public String getId() {
1257 public boolean isValid() {
1258 return System.currentTimeMillis() < validUntil;
1261 public Iterator getRoleDescriptors() {
1262 return roles.iterator();
1265 public RoleDescriptor getRoleByType(Class type, String protocol) {
1266 for (int i=0; i<roles.size(); i++) {
1267 RoleDescriptor role = (RoleDescriptor)roles.get(i);
1268 if (type.isInstance(role) && role.hasSupport(protocol))
1274 public IDPSSODescriptor getIDPSSODescriptor(String protocol) {
1275 return (IDPSSODescriptor)getRoleByType(IDPSSODescriptor.class, protocol);
1278 public SPSSODescriptor getSPSSODescriptor(String protocol) {
1279 return (SPSSODescriptor)getRoleByType(SPSSODescriptor.class, protocol);
1282 public AuthnAuthorityDescriptor getAuthnAuthorityDescriptor(String protocol) {
1283 return (AuthnAuthorityDescriptor)getRoleByType(AuthnAuthorityDescriptor.class, protocol);
1286 public AttributeAuthorityDescriptor getAttributeAuthorityDescriptor(String protocol) {
1287 return (AttributeAuthorityDescriptor)getRoleByType(AttributeAuthorityDescriptor.class, protocol);
1290 public AttributeRequesterDescriptor getAttributeRequesterDescriptor(String protocol) {
1291 return (AttributeRequesterDescriptor)getRoleByType(AttributeRequesterDescriptor.class, protocol);
1294 public PDPDescriptor getPDPDescriptor(String protocol) {
1295 return (PDPDescriptor)getRoleByType(PDPDescriptor.class, protocol);
1298 public AffiliationDescriptor getAffiliationDescriptor() {
1302 public Organization getOrganization() {
1306 public Iterator getContactPersons() {
1307 return contacts.iterator();
1310 public Map getAdditionalMetadataLocations() {
1311 return Collections.unmodifiableMap(locs);
1314 public EntitiesDescriptor getEntitiesDescriptor() {
1318 public Element getElement() {
1322 public long getValidUntil() {
1326 public URL getErrorURL() {
1330 public Iterator getKeyAuthorities() {
1331 return keyauths.iterator();
1335 class XMLEntitiesDescriptor implements ExtendedEntitiesDescriptor {
1336 private Element root = null;
1337 private EntitiesDescriptor parent = null;
1338 private String name = null;
1339 private ArrayList /* <EntitiesDescriptor> */ groups = new ArrayList();
1340 private ArrayList /* <EntityDescriptor> */ providers = new ArrayList();
1341 private long validUntil = Long.MAX_VALUE;
1342 private ArrayList /* <KeyAuthority> */ keyauths = new ArrayList();
1344 public XMLEntitiesDescriptor(Element e, XMLMetadataProvider wrapper, long validUntil, EntitiesDescriptor parent) throws SAMLException {
1346 this.parent = parent;
1347 this.validUntil = validUntil;
1348 name = XML.assign(e.getAttributeNS(null, "Name"));
1350 // Check the root element namespace. If SAML2, assume it's the std schema.
1351 if (edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS.equals(e.getNamespaceURI())) {
1353 if (e.hasAttributeNS(null,"validUntil")) {
1354 SimpleDateFormat formatter = null;
1355 String dateTime = XML.assign(e.getAttributeNS(null,"validUntil"));
1356 int dot = dateTime.indexOf('.');
1358 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
1360 formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
1361 formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
1363 validUntil=Math.min(validUntil,formatter.parse(dateTime).getTime());
1365 catch (ParseException e1) {
1366 log.warn("Entities descriptor contains invalid expiration time");
1370 e = XML.getFirstChildElement(e);
1372 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"Extensions")) {
1373 Element ext = XML.getFirstChildElement(e,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1374 while (ext != null) {
1375 keyauths.add(new XMLKeyAuthority(ext));
1376 ext = XML.getNextSiblingElement(ext,edu.internet2.middleware.shibboleth.common.XML.SHIBMETA_NS,"KeyAuthority");
1379 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EntitiesDescriptor"))
1380 groups.add(new XMLEntitiesDescriptor(e, wrapper, this.validUntil, this));
1381 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SAML2META_NS,"EntityDescriptor"))
1382 providers.add(new XMLEntityDescriptor(e, wrapper, this.validUntil, this));
1383 e = XML.getNextSiblingElement(e);
1387 e = XML.getFirstChildElement(e);
1389 if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"SiteGroup"))
1390 groups.add(new XMLEntitiesDescriptor(e, wrapper, this.validUntil, this));
1391 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"OriginSite"))
1392 providers.add(new XMLEntityDescriptor(e, wrapper, this.validUntil, this));
1393 else if (XML.isElementNamed(e,edu.internet2.middleware.shibboleth.common.XML.SHIB_NS,"DestinationSite"))
1394 providers.add(new XMLEntityDescriptor(e, wrapper, this.validUntil, this));
1395 e = XML.getNextSiblingElement(e);
1400 public String getName() {
1404 public boolean isValid() {
1405 return System.currentTimeMillis() < validUntil;
1408 public EntitiesDescriptor getEntitiesDescriptor() {
1412 public Iterator getEntitiesDescriptors() {
1413 return groups.iterator();
1416 public Iterator getEntityDescriptors() {
1417 return providers.iterator();
1420 public Element getElement() {
1424 public Iterator getKeyAuthorities() {
1425 return keyauths.iterator();