33435ccfb95e442297dc45b95912f36292757887
[shibboleth/sp.git] / util / mdquery.cpp
1 /*\r
2  *  Copyright 2001-2007 Internet2\r
3  * \r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 /**\r
18  * mdquery.cpp\r
19  * \r
20  * SAML Metadata Query tool layered on SP configuration\r
21  */\r
22 \r
23 #if defined (_MSC_VER) || defined(__BORLANDC__)\r
24 # include "config_win32.h"\r
25 #else\r
26 # include "config.h"\r
27 #endif\r
28 \r
29 #ifdef WIN32\r
30 # define _CRT_NONSTDC_NO_DEPRECATE 1\r
31 # define _CRT_SECURE_NO_DEPRECATE 1\r
32 #endif\r
33 \r
34 #include <shibsp/Application.h>\r
35 #include <shibsp/exceptions.h>\r
36 #include <shibsp/SPConfig.h>\r
37 #include <shibsp/ServiceProvider.h>\r
38 #include <shibsp/metadata/MetadataProviderCriteria.h>\r
39 #include <shibsp/util/SPConstants.h>\r
40 #include <saml/saml2/metadata/Metadata.h>\r
41 #include <xmltooling/logging.h>\r
42 \r
43 using namespace shibsp;\r
44 using namespace opensaml::saml2md;\r
45 using namespace opensaml;\r
46 using namespace xmltooling::logging;\r
47 using namespace xmltooling;\r
48 using namespace std;\r
49 \r
50 void usage()\r
51 {\r
52     cerr << "usage: mdquery -e <entityID> [-a <app id> -nostrict]" << endl;\r
53     cerr << "       mdquery -e <entityID> -r <role> -p <protocol> [-a <app id> -ns <namespace> -nostrict]" << endl;\r
54 }\r
55 \r
56 int main(int argc,char* argv[])\r
57 {\r
58     char* entityID = NULL;\r
59     char* appID = "default";\r
60     bool strict = true;\r
61     char* prot = NULL;\r
62     const XMLCh* protocol = NULL;\r
63     char* rname = NULL;\r
64     char* rns = NULL;\r
65 \r
66     for (int i=1; i<argc; i++) {\r
67         if (!strcmp(argv[i],"-e") && i+1<argc)\r
68             entityID=argv[++i];\r
69         else if (!strcmp(argv[i],"-a") && i+1<argc)\r
70             appID=argv[++i];\r
71         else if (!strcmp(argv[i],"-p") && i+1<argc)\r
72             prot=argv[++i];\r
73         else if (!strcmp(argv[i],"-r") && i+1<argc)\r
74             rname=argv[++i];\r
75         else if (!strcmp(argv[i],"-ns") && i+1<argc)\r
76             rns=argv[++i];\r
77         else if (!strcmp(argv[i],"-saml10"))\r
78             protocol=samlconstants::SAML10_PROTOCOL_ENUM;\r
79         else if (!strcmp(argv[i],"-saml11"))\r
80             protocol=samlconstants::SAML11_PROTOCOL_ENUM;\r
81         else if (!strcmp(argv[i],"-saml2"))\r
82             protocol=samlconstants::SAML20P_NS;\r
83         else if (!strcmp(argv[i],"-idp"))\r
84             rname="IDPSSODescriptor";\r
85         else if (!strcmp(argv[i],"-aa"))\r
86             rname="AttributeAuthorityDescriptor";\r
87         else if (!strcmp(argv[i],"-pdp"))\r
88             rname="PDPDescriptor";\r
89         else if (!strcmp(argv[i],"-sp"))\r
90             rname="SPSSODescriptor";\r
91         else if (!strcmp(argv[i],"-nostrict"))\r
92             strict = false;\r
93     }\r
94 \r
95     if (!entityID) {\r
96         usage();\r
97         exit(-10);\r
98     }\r
99 \r
100     char* path=getenv("SHIBSP_SCHEMAS");\r
101     if (!path)\r
102         path=SHIBSP_SCHEMAS;\r
103     char* config=getenv("SHIBSP_CONFIG");\r
104     if (!config)\r
105         config=SHIBSP_CONFIG;\r
106 \r
107     XMLToolingConfig::getConfig().log_config(getenv("SHIBSP_LOGGING") ? getenv("SHIBSP_LOGGING") : SHIBSP_LOGGING);\r
108 \r
109     SPConfig& conf=SPConfig::getConfig();\r
110     conf.setFeatures(SPConfig::Metadata | SPConfig::Trust | SPConfig::OutOfProcess | SPConfig::Credentials);\r
111     if (!conf.init(path))\r
112         return -1;\r
113 \r
114     if (rname) {\r
115         if (!protocol) {\r
116             if (prot)\r
117                 protocol = XMLString::transcode(prot);\r
118         }\r
119         if (!protocol) {\r
120             conf.term();\r
121             usage();\r
122             exit(-10);\r
123         }\r
124     }\r
125 \r
126     try {\r
127         static const XMLCh _path[] = UNICODE_LITERAL_4(p,a,t,h);\r
128         static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);\r
129         xercesc::DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();\r
130         XercesJanitor<xercesc::DOMDocument> docjanitor(dummydoc);\r
131         xercesc::DOMElement* dummy = dummydoc->createElementNS(NULL,_path);\r
132         auto_ptr_XMLCh src(config);\r
133         dummy->setAttributeNS(NULL,_path,src.get());\r
134         dummy->setAttributeNS(NULL,validate,xmlconstants::XML_ONE);\r
135         conf.setServiceProvider(conf.ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));\r
136         conf.getServiceProvider()->init();\r
137     }\r
138     catch (exception&) {\r
139         conf.term();\r
140         return -2;\r
141     }\r
142 \r
143     ServiceProvider* sp=conf.getServiceProvider();\r
144     sp->lock();\r
145 \r
146     Category& log = Category::getInstance(SHIBSP_LOGCAT".Utility.MDQuery");\r
147 \r
148     const Application* app = sp->getApplication(appID);\r
149     if (!app) {\r
150         log.error("unknown application ID (%s)", appID);\r
151         sp->unlock();\r
152         conf.term();\r
153         return -3;\r
154     }\r
155 \r
156     app->getMetadataProvider()->lock();\r
157     MetadataProviderCriteria mc(*app, entityID, NULL, NULL, strict);\r
158     if (rname) {\r
159         const XMLCh* ns = rns ? XMLString::transcode(rns) : samlconstants::SAML20MD_NS;\r
160         auto_ptr_XMLCh n(rname);\r
161         QName q(ns, n.get());\r
162         mc.role = &q;\r
163         mc.protocol = protocol;\r
164         const RoleDescriptor* role = app->getMetadataProvider()->getEntityDescriptor(mc).second;\r
165         if (role)\r
166             XMLHelper::serialize(role->marshall(), cout, true);\r
167         else\r
168             log.error("compatible role %s not found for (%s)", q.toString().c_str(), entityID);\r
169     }\r
170     else {\r
171         const EntityDescriptor* entity = app->getMetadataProvider()->getEntityDescriptor(mc).first;\r
172         if (entity)\r
173             XMLHelper::serialize(entity->marshall(), cout, true);\r
174         else\r
175             log.error("no metadata found for (%s)", entityID);\r
176     }\r
177 \r
178     app->getMetadataProvider()->unlock();\r
179 \r
180     sp->unlock();\r
181     conf.term();\r
182     return 0;\r
183 }\r