218 lines
5.1 KiB
C
218 lines
5.1 KiB
C
/*
|
|
* idpc - IDP as a C CGI program
|
|
* Copyright (C) 2004 Entr'ouvert
|
|
*
|
|
* Author: Frederic Peters <fpeters@entrouvert.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include "idpc.h"
|
|
|
|
/* the Federation Termination service URL handles several profiles:
|
|
* 1a. initiated by IdP, HTTP-Redirect (fig10, page40)
|
|
* 1b. initiated by IdP, SOAP (fig11, page43)
|
|
* 2a. initiated by SP, HTTP-Redirect
|
|
* [!2b. initiated by SP, SOAP is handled in soapEndpoint!]
|
|
*/
|
|
|
|
int defederation_http(LassoDefederation *termination)
|
|
{
|
|
/* SP-initiated; HTTP-Redirect-Based Profile */
|
|
int rc;
|
|
LassoIdentity *identity;
|
|
|
|
rc = lasso_defederation_process_notification_msg(
|
|
termination, getenv("QUERY_STRING"));
|
|
if (rc) {
|
|
return error_page("process_notification_msg failed");
|
|
}
|
|
|
|
rc = set_profile_auto(LASSO_PROFILE(termination));
|
|
if (rc) {
|
|
return error_page("set_profile_auto failed");
|
|
}
|
|
|
|
rc = lasso_defederation_build_notification_msg(termination);
|
|
if (rc) {
|
|
return error_page("build notification msg");
|
|
}
|
|
|
|
rc = save_profile_dumps(LASSO_PROFILE(termination));
|
|
if (rc) {
|
|
return error_page("save_profile_dumps failed");
|
|
}
|
|
|
|
printf("Location: %s\n\nRedirected",
|
|
LASSO_PROFILE(termination)->msg_url);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int defederation_init(LassoDefederation *termination,
|
|
char* serviceProviderId)
|
|
{
|
|
/* IdP-initiated */
|
|
int rc;
|
|
LassoIdentity *identity;
|
|
struct authentication *auth;
|
|
char *user_id;
|
|
char *user_dump, *session_dump;
|
|
|
|
auth = get_authentication(
|
|
get_config_string("//idpc:authenticationMethod"));
|
|
if (auth == NULL) {
|
|
return error_page("Wrong authentication");
|
|
}
|
|
|
|
user_id = auth->auth_function();
|
|
|
|
if (user_id == NULL) {
|
|
/* anyway */
|
|
return error_page("Error authenticating");
|
|
}
|
|
|
|
/* retrieve user_dump and session_dump */
|
|
rc = db_get_dumps(user_id, &user_dump, &session_dump);
|
|
if (rc) {
|
|
return error_page("Error getting dumps from db");
|
|
}
|
|
|
|
if (user_dump && user_dump[0]) {
|
|
rc = lasso_profile_set_identity_from_dump(
|
|
LASSO_PROFILE(termination), user_dump);
|
|
if (rc) {
|
|
return error_page("set identity failed");
|
|
}
|
|
free(user_dump);
|
|
user_dump = NULL;
|
|
}
|
|
|
|
if (session_dump && session_dump[0]) {
|
|
rc = lasso_profile_set_session_from_dump(
|
|
LASSO_PROFILE(termination), session_dump);
|
|
if (rc) {
|
|
return error_page("set session failed");
|
|
}
|
|
free(session_dump);
|
|
session_dump = NULL;
|
|
}
|
|
|
|
rc = lasso_defederation_init_notification(termination,
|
|
serviceProviderId, LASSO_HTTP_METHOD_SOAP);
|
|
if (rc) {
|
|
return error_page("init_notification failed");
|
|
}
|
|
|
|
rc = save_profile_dumps(LASSO_PROFILE(termination));
|
|
if (rc) {
|
|
return error_page("save_profile_dumps failed");
|
|
}
|
|
|
|
if (1) {
|
|
/* HTTP-Redirect-Based Profile */
|
|
rc = lasso_defederation_build_notification_msg(termination);
|
|
if (rc) {
|
|
return error_page("build_notification_msg");
|
|
}
|
|
|
|
printf("Location: %s\n\nRedirected",
|
|
LASSO_PROFILE(termination)->msg_url);
|
|
} else {
|
|
/* SOAP/HTTP-Based Profile */
|
|
|
|
/* TODO */
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int defederation()
|
|
{
|
|
int i;
|
|
char **params;
|
|
char *spId = NULL;
|
|
LassoDefederation *termination;
|
|
LassoServer *server;
|
|
int rc;
|
|
|
|
/* query string may be ?sp=<service provider to terminate> for
|
|
* an IdP initiated federation termination */
|
|
params = urlencoded_to_strings(getenv("QUERY_STRING"));
|
|
for (i=0; params[i]; i++) {
|
|
if (strncmp(params[i], "sp=", 3) == 0) {
|
|
spId = strdup(params[i]+3);
|
|
}
|
|
free(params[i]);
|
|
}
|
|
free(params);
|
|
|
|
server = get_config_server();
|
|
if (server == NULL) {
|
|
lasso_server_destroy(server);
|
|
return error_page("Failed to get server configuration");
|
|
}
|
|
|
|
termination = lasso_defederation_new(server);
|
|
if (termination == NULL) {
|
|
lasso_server_destroy(server);
|
|
return error_page("lasso_defederation_new failed");
|
|
}
|
|
|
|
if (spId) {
|
|
/* service provider specified means the termination is
|
|
* initiated now, on the idp */
|
|
rc = defederation_init(termination, spId);
|
|
free(spId);
|
|
} else {
|
|
/* no spId; this is http-redirect profile; coming from SP */
|
|
rc = defederation_http(termination);
|
|
}
|
|
|
|
lasso_defederation_destroy(termination);
|
|
lasso_server_destroy(server);
|
|
|
|
return rc;
|
|
}
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int rc;
|
|
|
|
if (argc > 1 && handle_args(argc, argv) ) {
|
|
return 0;
|
|
}
|
|
|
|
rc = init_config();
|
|
if (rc != 0) {
|
|
return error_page("Failed to init configuration");
|
|
}
|
|
lasso_init();
|
|
rc = db_init();
|
|
if (rc != 0) {
|
|
error_page("Failed to init database access");
|
|
goto shutdown;
|
|
}
|
|
rc = defederation();
|
|
shutdown:
|
|
db_finish();
|
|
lasso_shutdown();
|
|
return rc;
|
|
}
|
|
|