2 * The Shibboleth License, Version 1.
4 * University Corporation for Advanced Internet Development, Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
11 * Redistributions of source code must retain the above copyright notice, this
12 * list of conditions and the following disclaimer.
14 * Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution, if any, must include
17 * the following acknowledgment: "This product includes software developed by
18 * the University Corporation for Advanced Internet Development
19 * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
20 * may appear in the software itself, if and wherever such third-party
21 * acknowledgments normally appear.
23 * Neither the name of Shibboleth nor the names of its contributors, nor
24 * Internet2, nor the University Corporation for Advanced Internet Development,
25 * Inc., nor UCAID may be used to endorse or promote products derived from this
26 * software without specific prior written permission. For written permission,
27 * please contact shibboleth@shibboleth.org
29 * Products derived from this software may not be called Shibboleth, Internet2,
30 * UCAID, or the University Corporation for Advanced Internet Development, nor
31 * may Shibboleth appear in their name, without prior written permission of the
32 * University Corporation for Advanced Internet Development.
35 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
36 * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
38 * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
39 * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
40 * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
41 * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
42 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 * shib-rm.cpp -- Resource Manager interface
53 * Created By: Derek Atkins <derek@ihtfp.com>
64 #include <xercesc/util/Base64.hpp>
65 #include <log4cpp/Category.hh>
70 class shibtarget::RMPriv
73 RMPriv(RPCHandle *rpc, RMConfig cfg);
78 log4cpp::Category* log;
81 RMPriv::RMPriv(RPCHandle *rpc, RMConfig cfg)
83 string ctx = "shibtarget.RM";
84 log = &(log4cpp::Category::getInstance(ctx));
91 RM::RM(RPCHandle *rpc, RMConfig cfg)
93 m_priv = new RMPriv(rpc, cfg);
94 m_priv->log->info("Created new RM module");
102 RPCError* RM::getAssertions(const char* cookie, const char* ip, const char* resource,
103 vector<SAMLAssertion*> &assertions,
104 SAMLAuthenticationStatement **statement)
106 saml::NDC ndc("getAssertions");
107 m_priv->log->info ("get assertions...");
109 if (!cookie || *cookie == '\0') {
110 m_priv->log->error ("no cookie");
111 return new RPCError(-1, "No such cookie");
115 m_priv->log->error ("no ip address");
116 return new RPCError(-1, "No IP Address");
119 m_priv->log->info ("request from %s for \"%s\"", ip, resource);
120 m_priv->log->debug ("session cookie: %s", cookie);
122 shibrpc_get_assertions_args_1 arg;
123 arg.cookie.cookie = (char*)cookie;
124 arg.cookie.client_addr = (char*)ip;
125 arg.checkIPAddress = m_priv->m_config.checkIPAddress;
126 arg.application_id = (char *)resource;
128 shibrpc_get_assertions_ret_1 ret;
129 memset (&ret, 0, sizeof(ret));
131 // Loop on the RPC in case we lost contact the first time through
135 clnt = m_priv->m_rpc->connect();
136 if (shibrpc_get_assertions_1 (&arg, &ret, clnt) != RPC_SUCCESS) {
137 // FAILED. Release, disconnect, and try again.
138 m_priv->log->debug ("RPC Failure: %p (%p): %s", m_priv, clnt,
139 clnt_spcreateerror (""));
140 m_priv->m_rpc->release();
141 m_priv->m_rpc->disconnect();
145 m_priv->log->error ("RPC Failure: %p, %p", m_priv, clnt);
146 return new RPCError(-1, "RPC Failure");
149 // SUCCESS. Release the lock.
150 m_priv->m_rpc->release();
153 } while (retry >= 0);
155 m_priv->log->debug ("RPC completed with status %d (%p)", ret.status.status, m_priv);
157 RPCError* retval = NULL;
158 if (ret.status.status)
159 retval = new RPCError(&ret.status);
163 for (u_int i = 0; i < ret.assertions.assertions_len; i++) {
164 istringstream attrstream(ret.assertions.assertions_val[i].xml_string);
165 SAMLAssertion *as = NULL;
166 // m_priv->log->debug("Trying to decode assertion %d: %s", i,
167 // ret.assertions.assertions_val[i].xml_string);
168 m_priv->log->debugStream() << "Trying to decode assertion " << i
169 << ": " << ret.assertions.assertions_val[i].xml_string <<
170 log4cpp::CategoryStream::ENDLINE;
171 as = new SAMLAssertion(attrstream);
175 // XXX: Should move this audience check up to the RPC server side, and cache each assertion one
176 // by one instead of the whole response.
178 Iterator<SAMLCondition*> conds=as->getConditions();
179 while (conds.hasNext())
181 SAMLAudienceRestrictionCondition* cond=dynamic_cast<SAMLAudienceRestrictionCondition*>(conds.next());
182 if (!cond->eval(dynamic_cast<STConfig&>(ShibTargetConfig::getConfig()).getPolicies()))
184 m_priv->log->warn("Assertion failed AudienceRestrictionCondition check, skipping it...");
189 assertions.push_back(as);
193 // return the Authentication Statement
195 istringstream authstream(ret.auth_statement.xml_string);
196 SAMLAuthenticationStatement *auth = NULL;
198 m_priv->log->debugStream() <<
199 "Trying to decode authentication statement: " <<
200 ret.auth_statement.xml_string << log4cpp::CategoryStream::ENDLINE;
201 auth = new SAMLAuthenticationStatement(authstream);
203 // Save off the statement
207 } catch (SAMLException& e) {
208 m_priv->log->error ("SAML Exception: %s", e.what());
211 throw ShibTargetException(SHIBRPC_SAML_EXCEPTION, os.str());
212 } catch (XMLException& e) {
213 m_priv->log->error ("XML Exception: %s", e.getMessage());
214 auto_ptr<char> msg(XMLString::transcode(e.getMessage()));
215 throw ShibTargetException (SHIBRPC_XML_EXCEPTION, msg.get());
217 } catch (ShibTargetException &e) {
218 retval = new RPCError(e);
222 retval = new RPCError();
225 clnt_freeres (clnt, (xdrproc_t)xdr_shibrpc_get_assertions_ret_1, (caddr_t)&ret);
227 m_priv->log->debug ("returning..");
231 void RM::serialize(SAMLAssertion &assertion, string &result)
233 saml::NDC ndc("RM::serialize");
238 char* assn = (char*) os.str().c_str();
239 XMLByte* serialized = Base64::encode(reinterpret_cast<XMLByte*>(assn), os.str().length(), &outlen);
240 result = (char*) serialized;
241 XMLString::release(&serialized);