2 * Copyright 2001-2007 Internet2
\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
8 * http://www.apache.org/licenses/LICENSE-2.0
\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
17 /* siterefresh.cpp - command-line tool to refresh and verify metadata
\r
22 $Id:siterefresh.cpp 2252 2007-05-20 20:20:57Z cantor $
\r
25 #if defined (_MSC_VER) || defined(__BORLANDC__)
\r
26 # include "config_win32.h"
\r
28 # include "config.h"
\r
32 # define _CRT_NONSTDC_NO_DEPRECATE 1
\r
33 # define _CRT_SECURE_NO_DEPRECATE 1
\r
36 #include <saml/SAMLConfig.h>
\r
37 #include <saml/saml2/metadata/Metadata.h>
\r
38 #include <saml/util/SAMLConstants.h>
\r
39 #include <xmltooling/logging.h>
\r
40 #include <xmltooling/XMLToolingConfig.h>
\r
41 #include <xmltooling/signature/Signature.h>
\r
42 #include <xmltooling/util/XMLHelper.h>
\r
45 #include <xercesc/framework/LocalFileInputSource.hpp>
\r
46 #include <xercesc/framework/URLInputSource.hpp>
\r
47 #include <xercesc/framework/StdInInputSource.hpp>
\r
48 #include <xercesc/framework/Wrapper4InputSource.hpp>
\r
50 using namespace xmlsignature;
\r
51 using namespace xmlconstants;
\r
52 using namespace xmltooling::logging;
\r
53 using namespace xmltooling;
\r
54 using namespace samlconstants;
\r
55 using namespace opensaml::saml2md;
\r
56 using namespace opensaml;
\r
57 using namespace xercesc;
\r
58 using namespace std;
\r
60 template<class T> T* buildPlugin(const char* path, PluginManager<T,string,const DOMElement*>& mgr)
\r
63 DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);
64 XercesJanitor<DOMDocument> janitor(doc);
66 static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);
67 auto_ptr_char type(doc->getDocumentElement()->getAttributeNS(NULL,_type));
68 if (type.get() && *type.get())
69 return mgr.newPlugin(type.get(), doc->getDocumentElement());
70 throw XMLToolingException("Missing type in plugin configuration.");
73 CredentialResolver* buildSimpleResolver(const char* key, const char* cert)
\r
75 static const XMLCh _CredentialResolver[] = UNICODE_LITERAL_18(C,r,e,d,e,n,t,i,a,l,R,e,s,o,l,v,e,r);
\r
76 static const XMLCh _certificate[] = UNICODE_LITERAL_11(c,e,r,t,i,f,i,c,a,t,e);
\r
77 static const XMLCh _key[] = UNICODE_LITERAL_3(k,e,y);
\r
79 DOMDocument* doc = XMLToolingConfig::getConfig().getParser().newDocument();
\r
80 XercesJanitor<DOMDocument> janitor(doc);
\r
81 DOMElement* root = doc->createElementNS(NULL, _CredentialResolver);
\r
83 auto_ptr_XMLCh widenit(key);
\r
84 root->setAttributeNS(NULL, _key, widenit.get());
\r
87 auto_ptr_XMLCh widenit(cert);
\r
88 root->setAttributeNS(NULL, _certificate, widenit.get());
\r
91 return XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(FILESYSTEM_CREDENTIAL_RESOLVER, root);
\r
94 int main(int argc,char* argv[])
\r
97 char* url_param=NULL;
\r
98 char* path_param=NULL;
\r
99 char* key_param=NULL;
\r
100 char* cert_param=NULL;
\r
101 char* cr_param=NULL;
\r
102 char* t_param=NULL;
\r
103 char* id_param=NULL;
\r
105 // metadata lookup options
\r
106 char* m_param=NULL;
\r
109 const XMLCh* protocol = NULL;
\r
110 char* rname = NULL;
\r
113 for (int i=1; i<argc; i++) {
\r
114 if (!strcmp(argv[i],"-u") && i+1<argc)
\r
115 url_param=argv[++i];
\r
116 else if (!strcmp(argv[i],"-f") && i+1<argc)
\r
117 path_param=argv[++i];
\r
118 else if (!strcmp(argv[i],"-id") && i+1<argc)
\r
119 id_param=argv[++i];
\r
120 else if (!strcmp(argv[i],"-s"))
\r
122 else if (!strcmp(argv[i],"-k") && i+1<argc)
\r
123 key_param=argv[++i];
\r
124 else if (!strcmp(argv[i],"-c") && i+1<argc)
\r
125 cert_param=argv[++i];
\r
126 else if (!strcmp(argv[i],"-R") && i+1<argc)
\r
127 cr_param=argv[++i];
\r
128 else if (!strcmp(argv[i],"-T") && i+1<argc)
\r
130 else if (!strcmp(argv[i],"-M") && i+1<argc)
\r
132 else if (!strcmp(argv[i],"-i") && i+1<argc)
\r
134 else if (!strcmp(argv[i],"-p") && i+1<argc)
\r
136 else if (!strcmp(argv[i],"-r") && i+1<argc)
\r
138 else if (!strcmp(argv[i],"-ns") && i+1<argc)
\r
140 else if (!strcmp(argv[i],"-saml10"))
\r
141 protocol=samlconstants::SAML10_PROTOCOL_ENUM;
\r
142 else if (!strcmp(argv[i],"-saml11"))
\r
143 protocol=samlconstants::SAML11_PROTOCOL_ENUM;
\r
144 else if (!strcmp(argv[i],"-saml2"))
\r
145 protocol=samlconstants::SAML20P_NS;
\r
146 else if (!strcmp(argv[i],"-idp"))
\r
147 rname="IDPSSODescriptor";
\r
148 else if (!strcmp(argv[i],"-aa"))
\r
149 rname="AttributeAuthorityDescriptor";
\r
150 else if (!strcmp(argv[i],"-pdp"))
\r
151 rname="PDPDescriptor";
\r
152 else if (!strcmp(argv[i],"-sp"))
\r
153 rname="SPSSODescriptor";
\r
156 if (!verify && !key_param && !cr_param) {
\r
157 cerr << "either -k or -R option required when signing, see documentation for usage" << endl;
\r
161 SAMLConfig& conf=SAMLConfig::getConfig();
\r
164 XMLToolingConfig& xmlconf = XMLToolingConfig::getConfig();
\r
165 Category& log = Category::getInstance("OpenSAML.Utility.SAMLSign");
\r
170 // Parse the specified document.
\r
171 static XMLCh base[]={chLatin_f, chLatin_i, chLatin_l, chLatin_e, chColon, chForwardSlash, chForwardSlash, chForwardSlash, chNull};
\r
172 DOMDocument* doc=NULL;
\r
174 URLInputSource src(base,url_param);
\r
175 Wrapper4InputSource dsrc(&src,false);
\r
176 doc=xmlconf.getParser().parse(dsrc);
\r
178 else if (path_param) {
\r
179 auto_ptr_XMLCh widenit(path_param);
\r
180 LocalFileInputSource src(base,widenit.get());
\r
181 Wrapper4InputSource dsrc(&src,false);
\r
182 doc=xmlconf.getParser().parse(dsrc);
\r
185 StdInInputSource src;
\r
186 Wrapper4InputSource dsrc(&src,false);
\r
187 doc=xmlconf.getParser().parse(dsrc);
\r
191 XercesJanitor<DOMDocument> jan(doc);
\r
192 auto_ptr<XMLObject> sourcewrapper(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true));
\r
195 // Navigate to the selected node, or use the root if no ID specified.
\r
196 // Then make sure it's a SignableSAMLObject.
\r
197 XMLObject* source = sourcewrapper.get();
\r
199 auto_ptr_XMLCh widenit(id_param);
\r
200 source = XMLHelper::getXMLObjectById(*source, widenit.get());
\r
202 throw XMLToolingException("Element with ID ($1) not found.", params(1,id_param));
\r
204 SignableObject* signable = dynamic_cast<SignableObject*>(source);
\r
206 throw XMLToolingException("Input is not a signable SAML object.");
\r
211 // Build a resolver to supply a credential.
\r
212 auto_ptr<CredentialResolver> cr(
\r
213 cr_param ? buildPlugin(cr_param, xmlconf.CredentialResolverManager) : buildSimpleResolver(key_param, cert_param)
\r
216 CredentialCriteria cc;
\r
217 cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL);
\r
218 const Credential* cred = cr->resolve(&cc);
\r
220 throw XMLSecurityException("Unable to resolve a signing credential.");
\r
222 // Attach new signature.
\r
223 Signature* sig = SignatureBuilder::buildSignature();
224 signable->setSignature(sig);
226 // Sign response while re-marshalling.
227 vector<Signature*> sigs(1,sig);
228 XMLHelper::serialize(signable->marshall((DOMDocument*)NULL,&sigs,cred), cout);
231 catch(exception& e) {
\r
232 log.errorStream() << "caught an exception: " << e.what() << CategoryStream::ENDLINE;
\r
235 catch(XMLException& e) {
\r
236 auto_ptr_char temp(e.getMessage());
\r
237 log.errorStream() << "caught a Xerces exception: " << temp.get() << CategoryStream::ENDLINE;
\r