Fix backslashes in SHIBSP_PREFIX variable by manually creating it during the script...
[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/util/SPConstants.h>\r
39 #include <saml/saml2/metadata/Metadata.h>\r
40 #include <xmltooling/logging.h>\r
41 \r
42 using namespace shibsp;\r
43 using namespace opensaml::saml2md;\r
44 using namespace opensaml;\r
45 using namespace xmltooling::logging;\r
46 using namespace xmltooling;\r
47 using namespace std;\r
48 \r
49 void usage()\r
50 {\r
51     cerr << "usage: mdquery -e <entityID> [-a <app id> -nostrict]" << endl;\r
52     cerr << "       mdquery -e <entityID> -r <role> -p <protocol> [-a <app id> -ns <namespace> -nostrict]" << endl;\r
53 }\r
54 \r
55 int main(int argc,char* argv[])\r
56 {\r
57     char* entityID = NULL;\r
58     char* appID = "default";\r
59     bool strict = true;\r
60     char* prot = NULL;\r
61     const XMLCh* protocol = NULL;\r
62     char* rname = NULL;\r
63     char* rns = NULL;\r
64 \r
65     for (int i=1; i<argc; i++) {\r
66         if (!strcmp(argv[i],"-e") && i+1<argc)\r
67             entityID=argv[++i];\r
68         else if (!strcmp(argv[i],"-a") && i+1<argc)\r
69             appID=argv[++i];\r
70         else if (!strcmp(argv[i],"-p") && i+1<argc)\r
71             prot=argv[++i];\r
72         else if (!strcmp(argv[i],"-r") && i+1<argc)\r
73             rname=argv[++i];\r
74         else if (!strcmp(argv[i],"-ns") && i+1<argc)\r
75             rns=argv[++i];\r
76         else if (!strcmp(argv[i],"-saml10"))\r
77             protocol=samlconstants::SAML10_PROTOCOL_ENUM;\r
78         else if (!strcmp(argv[i],"-saml11"))\r
79             protocol=samlconstants::SAML11_PROTOCOL_ENUM;\r
80         else if (!strcmp(argv[i],"-saml2"))\r
81             protocol=samlconstants::SAML20P_NS;\r
82         else if (!strcmp(argv[i],"-idp"))\r
83             rname="IDPSSODescriptor";\r
84         else if (!strcmp(argv[i],"-aa"))\r
85             rname="AttributeAuthorityDescriptor";\r
86         else if (!strcmp(argv[i],"-pdp"))\r
87             rname="PDPDescriptor";\r
88         else if (!strcmp(argv[i],"-sp"))\r
89             rname="SPSSODescriptor";\r
90         else if (!strcmp(argv[i],"-nostrict"))\r
91             strict = false;\r
92     }\r
93 \r
94     if (!entityID) {\r
95         usage();\r
96         exit(-10);\r
97     }\r
98 \r
99     char* path=getenv("SHIBSP_SCHEMAS");\r
100     if (!path)\r
101         path=SHIBSP_SCHEMAS;\r
102     char* config=getenv("SHIBSP_CONFIG");\r
103     if (!config)\r
104         config=SHIBSP_CONFIG;\r
105 \r
106     XMLToolingConfig::getConfig().log_config(getenv("SHIBSP_LOGGING") ? getenv("SHIBSP_LOGGING") : SHIBSP_LOGGING);\r
107 \r
108     SPConfig& conf=SPConfig::getConfig();\r
109     conf.setFeatures(SPConfig::Metadata | SPConfig::OutOfProcess);\r
110     if (!conf.init(path))\r
111         return -1;\r
112 \r
113     if (rname) {\r
114         if (!protocol) {\r
115             if (prot)\r
116                 protocol = XMLString::transcode(prot);\r
117         }\r
118         if (!protocol) {\r
119             conf.term();\r
120             usage();\r
121             exit(-10);\r
122         }\r
123     }\r
124 \r
125     try {\r
126         static const XMLCh _path[] = UNICODE_LITERAL_4(p,a,t,h);\r
127         static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);\r
128         xercesc::DOMDocument* dummydoc=XMLToolingConfig::getConfig().getParser().newDocument();\r
129         XercesJanitor<xercesc::DOMDocument> docjanitor(dummydoc);\r
130         xercesc::DOMElement* dummy = dummydoc->createElementNS(NULL,_path);\r
131         auto_ptr_XMLCh src(config);\r
132         dummy->setAttributeNS(NULL,_path,src.get());\r
133         dummy->setAttributeNS(NULL,validate,xmlconstants::XML_ONE);\r
134         conf.setServiceProvider(conf.ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER,dummy));\r
135         conf.getServiceProvider()->init();\r
136     }\r
137     catch (exception&) {\r
138         conf.term();\r
139         return -2;\r
140     }\r
141 \r
142     ServiceProvider* sp=conf.getServiceProvider();\r
143     sp->lock();\r
144 \r
145     Category& log = Category::getInstance(SHIBSP_LOGCAT".Utility.MDQuery");\r
146 \r
147     const Application* app = sp->getApplication(appID);\r
148     if (!app) {\r
149         log.error("unknown application ID (%s)", appID);\r
150         sp->unlock();\r
151         conf.term();\r
152         return -3;\r
153     }\r
154 \r
155     app->getMetadataProvider()->lock();\r
156     MetadataProvider::Criteria mc(entityID, NULL, NULL, strict);\r
157     if (rname) {\r
158         const XMLCh* ns = rns ? XMLString::transcode(rns) : samlconstants::SAML20MD_NS;\r
159         auto_ptr_XMLCh n(rname);\r
160         QName q(ns, n.get());\r
161         mc.role = &q;\r
162         mc.protocol = protocol;\r
163         const RoleDescriptor* role = app->getMetadataProvider()->getEntityDescriptor(mc).second;\r
164         if (role)\r
165             XMLHelper::serialize(role->marshall(), cout, true);\r
166         else\r
167             log.error("compatible role %s not found for (%s)", q.toString().c_str(), entityID);\r
168     }\r
169     else {\r
170         const EntityDescriptor* entity = app->getMetadataProvider()->getEntityDescriptor(mc).first;\r
171         if (entity)\r
172             XMLHelper::serialize(entity->marshall(), cout, true);\r
173         else\r
174             log.error("no metadata found for (%s)", entityID);\r
175     }\r
176 \r
177     app->getMetadataProvider()->unlock();\r
178 \r
179     sp->unlock();\r
180     conf.term();\r
181     return 0;\r
182 }\r