2 * Copyright 2001-2005 Internet2
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * shibrpc-server.cpp -- SHIBRPC Server implementation. Originally created
19 * as shibrpc-server-stubs.c; make sure that the function
20 * prototypes here match those in shibrpc.x.
22 * Created by: Derek Atkins <derek@ihtfp.com>
27 #include <saml/saml.h>
28 #include <shib-target/shibrpc.h>
30 // eventually we might be able to support autoconf via cygwin...
31 #if defined (_MSC_VER) || defined(__BORLANDC__)
32 # include "config_win32.h"
37 #include <shib-target/shib-target.h>
39 #ifdef HAVE_LIBDMALLOCXX
45 #include "shar-utils.h"
49 using namespace shibboleth;
50 using namespace shibtarget;
51 using namespace shibd::logging;
53 extern IListener* g_MemoryListener;
55 static string get_threadid (const char* proc)
57 static u_long counter = 0;
59 buf << "[" << counter++ << "] " << proc;
63 static Category& get_category (void)
65 return Category::getInstance("shibd.Listener");
68 extern "C" bool_t shibrpc_ping_2_svc(int *argp, int *result, struct svc_req *rqstp)
70 g_MemoryListener->ping(*argp);
75 extern "C" bool_t shibrpc_get_session_2_svc(
76 shibrpc_get_session_args_2 *argp,
77 shibrpc_get_session_ret_2 *result,
81 Category& log = get_category();
82 string ctx = get_threadid("sessionGet");
85 if (!argp || !result) {
86 log.error("RPC Argument Error");
90 memset(result, 0, sizeof (*result));
91 result->provider_id = strdup("");
92 result->auth_statement = strdup("");
93 result->attr_response_pre = strdup("");
94 result->attr_response_post = strdup("");
96 IConfig* conf=ShibTargetConfig::getConfig().getINI();
98 const IApplication* app=conf->getApplication(argp->application_id);
100 // Something's horribly wrong.
101 log.error("couldn't find application (%s) for session", argp->application_id);
102 SAMLException ex("Unable to locate application for session, deleted?");
105 result->status=strdup(os.str().c_str());
109 ISessionCacheEntry* entry=NULL;
112 g_MemoryListener->sessionGet(app,argp->cookie,argp->client_addr,&entry);
114 // Set profile and provider
115 result->profile = entry->getProfile();
116 free(result->provider_id);
117 result->provider_id = strdup(entry->getProviderId());
119 // Now grab the serialized authentication statement and responses
121 os << *(entry->getAuthnStatement());
122 free(result->auth_statement);
123 result->auth_statement = strdup(os.str().c_str());
125 ISessionCacheEntry::CachedResponse responses=entry->getResponse();
126 if (!responses.empty()) {
128 os << *responses.unfiltered;
129 free(result->attr_response_pre);
130 result->attr_response_pre = strdup(os.str().c_str());
133 os << *responses.filtered;
134 free(result->attr_response_post);
135 result->attr_response_post = strdup(os.str().c_str());
138 // Ok, just release it.
141 result->status=strdup("");
143 catch (SAMLException &e) {
144 log.error("caught exception while retrieving session: %s", e.what());
146 // If the entry is set, it happened after the call.
149 conf->getSessionCache()->remove(argp->cookie);
153 result->status = strdup(os.str().c_str());
157 log.error("caught unexpected exception while retrieving session");
159 // If the entry is set, it happened after the call.
162 conf->getSessionCache()->remove(argp->cookie);
164 InvalidSessionException ex("An unexpected error occurred while validating your session, and you must re-authenticate.");
167 result->status = strdup(os.str().c_str());
175 shibrpc_new_session_2_svc(
176 shibrpc_new_session_args_2 *argp,
177 shibrpc_new_session_ret_2 *result,
178 struct svc_req *rqstp
181 Category& log = get_category();
182 string ctx=get_threadid("sessionNew");
185 if (!argp || !result) {
186 log.error("Invalid RPC Arguments");
190 // Initialize the result structure
191 memset (result, 0, sizeof(*result));
192 result->cookie = strdup ("");
193 result->target = strdup ("");
194 result->provider_id = strdup("");
196 // Access the application config.
197 IConfig* conf=ShibTargetConfig::getConfig().getINI();
199 const IApplication* app=conf->getApplication(argp->application_id);
201 // Something's horribly wrong. Flush the session.
202 log.error("couldn't find application for session");
203 SAMLException ex("Unable to locate application for session, deleted?");
206 result->status=strdup(os.str().c_str());
211 // Delagate the work...
212 string target,cookie,provider_id;
213 g_MemoryListener->sessionNew(
215 argp->supported_profiles,
224 // And let the user know.
225 if (result->cookie) free(result->cookie);
226 if (result->target) free(result->target);
227 if (result->provider_id) free(result->provider_id);
228 result->cookie = strdup(cookie.c_str());
229 result->target = strdup(target.c_str());
230 result->provider_id = strdup(provider_id.c_str());
231 result->status = strdup("");
233 catch (SAMLException& e) {
234 log.error("caught exception while creating session: %s", e.what());
237 result->status = strdup(os.str().c_str());
241 log.error("caught unexpected exception while creating session");
242 SAMLException e("An unexpected error occurred while creating your session.");
245 result->status = strdup(os.str().c_str());
253 shibrpc_end_session_2_svc(
254 shibrpc_end_session_args_2 *argp,
255 shibrpc_end_session_ret_2 *result,
256 struct svc_req *rqstp
259 Category& log = get_category();
260 string ctx = get_threadid("sessionEnd");
263 if (!argp || !result) {
264 log.error("RPC Argument Error");
268 memset(result, 0, sizeof (*result));
270 IConfig* conf=ShibTargetConfig::getConfig().getINI();
274 g_MemoryListener->sessionEnd(NULL,argp->cookie);
275 result->status=strdup("");
277 catch (SAMLException& e) {
278 log.error("caught exception while ending session: %s", e.what());
281 result->status = strdup(os.str().c_str());
285 log.error("caught unexpected exception while ending session");
286 SAMLException ex("An unexpected error occurred while ending your session.");
289 result->status = strdup(os.str().c_str());
297 shibrpc_prog_2_freeresult (SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result)
299 xdr_free (xdr_result, result);
302 * Insert additional freeing code here, if needed