Move config logic into an "XML" SP plugin, divorce shibd and modules from old libs.
[shibboleth/cpp-sp.git] / test / shibtest.cpp
index 7e4041c..19b343e 100644 (file)
 /*
- * The Shibboleth License, Version 1.
- * Copyright (c) 2002
- * University Corporation for Advanced Internet Development, Inc.
- * All rights reserved
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution, if any, must include
- * the following acknowledgment: "This product includes software developed by
- * the University Corporation for Advanced Internet Development
- * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
- * may appear in the software itself, if and wherever such third-party
- * acknowledgments normally appear.
- *
- * Neither the name of Shibboleth nor the names of its contributors, nor
- * Internet2, nor the University Corporation for Advanced Internet Development,
- * Inc., nor UCAID may be used to endorse or promote products derived from this
- * software without specific prior written permission. For written permission,
- * please contact shibboleth@shibboleth.org
- *
- * Products derived from this software may not be called Shibboleth, Internet2,
- * UCAID, or the University Corporation for Advanced Internet Development, nor
- * may Shibboleth appear in their name, without prior written permission of the
- * University Corporation for Advanced Internet Development.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
- * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
- * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
+#ifdef WIN32
+# define _CRT_NONSTDC_NO_DEPRECATE 1
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
 
-#include "../shib/shib.h"
+#include <shib-target/shib-target.h>
+#include <shibsp/SPConfig.h>
+#include <shibsp/util/SPConstants.h>
 
-using namespace std;
+using namespace shibsp;
+using namespace shibtarget;
+using namespace opensaml::saml2md;
 using namespace saml;
-using namespace shibboleth;
+using namespace std;
 
 int main(int argc,char* argv[])
 {
-    SAMLConfig& conf1=SAMLConfig::getConfig();
-    ShibConfig& conf2=ShibConfig::getConfig();
     char* h_param=NULL;
     char* q_param=NULL;
-    char* url_param=NULL;
-    char* r_param=NULL;
-    char* ca_param=NULL;
-    char* path="";
-
-    for (int i=1; i<argc; i++)
-    {
-        if (!strcmp(argv[i],"-d") && i+1<argc)
+    char* f_param=NULL;
+    char* a_param=NULL;
+    char* path=NULL;
+    char* config=NULL;
+
+    for (int i=1; i<argc; i++) {
+        if (!strcmp(argv[i],"-c") && i+1<argc)
+            config=argv[++i];
+        else if (!strcmp(argv[i],"-d") && i+1<argc)
             path=argv[++i];
         else if (!strcmp(argv[i],"-h") && i+1<argc)
             h_param=argv[++i];
         else if (!strcmp(argv[i],"-q") && i+1<argc)
             q_param=argv[++i];
+        else if (!strcmp(argv[i],"-f") && i+1<argc)
+            f_param=argv[++i];
         else if (!strcmp(argv[i],"-a") && i+1<argc)
-            url_param=argv[++i];
-        else if (!strcmp(argv[i],"-r") && i+1<argc)
-            r_param=argv[++i];
-        else if (!strcmp(argv[i],"-ca") && i+1<argc)
-            ca_param=argv[++i];
+            a_param=argv[++i];
     }
 
-    if (!h_param || !q_param || !url_param)
-    {
-        cerr << "usage: shibtest -h <handle> -q <origin_site> -a <AA URL> [-r <resource URL> -d <schema path>]" << endl;
+    if (!h_param || !q_param) {
+        cerr << "usage: shibtest -h <handle> -q <origin_site> [-f <format URI> -a <application_id> -d <schema path> -c <config>]" << endl;
         exit(0);
     }
+    
+    if (!path)
+        path=getenv("SHIBSCHEMAS");
+    if (!path)
+        path=SHIB_SCHEMAS;
+    if (!config)
+        config=getenv("SHIBCONFIG");
+    if (!config)
+        config=SHIB_CONFIG;
+    if (!a_param)
+        a_param="default";
+
+    ShibTargetConfig& conf=ShibTargetConfig::getConfig();
+    SPConfig::getConfig().setFeatures(
+        SPConfig::Metadata |
+        SPConfig::Trust |
+        SPConfig::Credentials |
+        SPConfig::AttributeResolver |
+        SPConfig::OutOfProcess |
+        SPConfig::Caching
+        );
+    if (!conf.init(path) || !conf.load(config))
+        return -10;
+
+    ServiceProvider* sp=SPConfig::getConfig().getServiceProvider();
+    xmltooling::Locker locker(sp);
+
+    try {
+        const IApplication* app=dynamic_cast<const IApplication*>(sp->getApplication(a_param));
+        if (!app)
+            throw SAMLException("specified <Application> section not found in configuration");
+
+        auto_ptr_XMLCh domain(q_param);
+        auto_ptr_XMLCh handle(h_param);
+        auto_ptr_XMLCh format(f_param);
+        auto_ptr_XMLCh resource(app->getString("providerId").second);
+
+        auto_ptr<SAMLRequest> req(
+            new SAMLRequest(
+                new SAMLAttributeQuery(
+                    new SAMLSubject(
+                        new SAMLNameIdentifier(
+                            handle.get(),
+                            domain.get(),
+                            format.get() ? format.get() : shibspconstants::SHIB1_NAMEID_FORMAT_URI
+                            )
+                        ),
+                    resource.get()
+                    )
+                )
+            );
+
+        MetadataProvider* m=app->getMetadataProvider();
+        xmltooling::Locker locker(m);
+        const EntityDescriptor* site=m->getEntityDescriptor(domain.get());
+        if (!site)
+            throw MetadataException("Unable to locate specified origin site's metadata.");
+
+        // Try to locate an AA role.
+        const AttributeAuthorityDescriptor* AA=site->getAttributeAuthorityDescriptor(saml::XML::SAML11_PROTOCOL_ENUM);
+        if (!AA)
+            throw MetadataException("Unable to locate metadata for origin site's Attribute Authority.");
+
+        ShibHTTPHook::ShibHTTPHookCallContext ctx(app->getCredentialUse(site),AA);
+
+        SAMLResponse* response=NULL;
+        const vector<AttributeService*>& endpoints=AA->getAttributeServices();
+        for (vector<AttributeService*>::const_iterator ep=endpoints.begin(); !response && ep!=endpoints.end(); ++ep) {
+            try {
+                // Get a binding object for this protocol.
+                const SAMLBinding* binding = app->getBinding((*ep)->getBinding());
+                if (!binding) {
+                    continue;
+                }
+                response=binding->send((*ep)->getLocation(), *(req.get()), &ctx);
+            }
+            catch (exception&) {
+            }
+        }
 
-    conf1.schema_dir=path;
-    if (ca_param)
-        conf1.binding_defaults.ssl_calist=ca_param;
-    if (!conf1.init())
-        cerr << "unable to initialize SAML runtime" << endl;
-
-    if (!conf2.init())
-        cerr << "unable to initialize Shibboleth runtime" << endl;
-
-    // conf2.addMetadata("edu.internet2.middleware.shibboleth.metadata.XML","http://wayf.internet2.edu/shibboleth/sites.xml");
+        if (!response)
+            throw opensaml::BindingException("unable to successfully query for attributes");
 
-    try
-    {
-        auto_ptr<XMLCh> url(XMLString::transcode(url_param));
-        SAMLAuthorityBinding binfo(saml::QName(saml::XML::SAMLP_NS,L(AttributeQuery)),SAMLBinding::SAML_SOAP_HTTPS,url.get());
-        auto_ptr<XMLCh> domain(XMLString::transcode(q_param));
-        auto_ptr<XMLCh> handle(XMLString::transcode(h_param));
-        auto_ptr<XMLCh> resource(XMLString::transcode(r_param));
-        SAMLRequest* req=new SAMLRequest(Iterator<saml::QName>(),new SAMLAttributeQuery (new SAMLSubject(handle.get(),domain.get()),resource.get()));
-
-        SAMLBinding* pBinding=SAMLBindingFactory::getInstance();
-        SAMLResponse* resp=pBinding->send(binfo,*req);
-        delete pBinding;
-
-        Iterator<SAMLAssertion*> i=resp->getAssertions();
+        Iterator<SAMLAssertion*> i=response->getAssertions();
         if (i.hasNext())
         {
             SAMLAssertion* a=i.next();
             cout << "Issuer: "; xmlout(cout,a->getIssuer()); cout << endl;
-            const XMLDateTime* exp=a->getNotOnOrAfter();
+            const SAMLDateTime* exp=a->getNotOnOrAfter();
             cout << "Expires: ";
             if (exp)
-              xmlout(cout,exp->toString());
+              xmlout(cout,exp->getRawData());
             else
                 cout << "None";
             cout << endl;
@@ -130,7 +159,8 @@ int main(int argc,char* argv[])
                 SAMLAttributeStatement* s=dynamic_cast<SAMLAttributeStatement*>(j.next());
                 if (s)
                 {
-                    const SAMLSubject* sub=s->getSubject();
+                    const SAMLNameIdentifier* sub=s->getSubject()->getNameIdentifier();
+                    cout << "Format: "; xmlout(cout,sub->getFormat()); cout << endl;
                     cout << "Domain: "; xmlout(cout,sub->getNameQualifier()); cout << endl;
                     cout << "Handle: "; xmlout(cout,sub->getName()); cout << endl;
 
@@ -139,34 +169,23 @@ int main(int argc,char* argv[])
                     {
                         SAMLAttribute* attr=attrs.next();
                         cout << "Attribute Name: "; xmlout(cout,attr->getName()); cout << endl;
-                        Iterator<xstring> vals=attr->getValues();
+                        Iterator<const XMLCh*> vals=attr->getValues();
                         while (vals.hasNext())
                         {
                             cout << "Attribute Value: ";
-                            xmlout(cout,vals.next().c_str());
+                            xmlout(cout,vals.next());
                             cout << endl;
                         }
                     }
                 }
             }
         }
-
-        delete resp;
     }
-    catch(SAMLException& e)
+    catch(exception& e)
     {
-        cerr << "caught a SAML exception: " << e << endl;
+        cerr << "caught an exception: " << e.what() << endl;
     }
-    catch(XMLException& e)
-    {
-        cerr << "caught an XML exception: "; xmlout(cerr,e.getMessage()); cerr << endl;
-    }
-/*    catch(...)
-    {
-        cerr << "caught an unknown exception" << endl;
-    }*/
 
-    conf2.term();
-    conf1.term();
+    conf.shutdown();
     return 0;
 }