This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
idpc/src/federation_termination.c

220 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"),
lassoHttpMethodRedirect);
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, lassoHttpMethodSoap);
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,
lassoProviderTypeIdp);
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;
}