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/soap_end_point.c

323 lines
7.7 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"
struct req {
lassoRequestType type;
char* (*request_function) (LassoServer*, char*);
};
char* req_login(LassoServer *server, char *soap_msg);
char* req_logout(LassoServer *server, char *soap_msg);
char* req_defederation(LassoServer *server, char *soap_msg);
char* req_register_name_identifier(LassoServer *server, char *soap_msg);
char* req_name_identifier_mapping(LassoServer *server, char *soap_msg);
struct req requests[] = {
{lassoRequestTypeLogin, req_login},
{lassoRequestTypeLogout, req_logout},
{lassoRequestTypeDefederation, req_defederation},
{lassoRequestTypeRegisterNameIdentifier, req_register_name_identifier},
{lassoRequestTypeNameIdentifierMapping, req_name_identifier_mapping},
/* {lassoRequestTypeLecp, req_lecp}, */
/* LECP requests go to single sign on service URL */
{0, NULL}
};
#define SOAP_204 "[soap204]"
char* req_login(LassoServer *server, char *soap_msg)
{
LassoLogin *login;
char *assertion_dump = NULL;
int rc;
login = lasso_login_new(server);
rc = lasso_login_process_request_msg(login, soap_msg);
if (rc) {
fprintf(stderr, "process_request_msg failed\n");
return NULL;
}
rc = db_get_assertion(login->assertionArtifact, &assertion_dump);
if (rc) {
fprintf(stderr, "db_get_assertion failed\n");
} else {
rc = lasso_login_set_assertion_from_dump(login, assertion_dump);
if (rc) {
fprintf(stderr, "set_assertion_from_dump failed\n");
}
rc = db_remove_assertion(login->assertionArtifact);
if (rc) {
fprintf(stderr, "db_remove_assertion failed\n");
}
}
rc = lasso_login_build_response_msg(login);
assertion_dump = strdup(LASSO_PROFILE(login)->msg_body);
lasso_login_destroy(login);
return assertion_dump;
}
char* req_logout(LassoServer *server, char *soap_msg)
{
LassoLogout *logout = NULL;
int rc;
char *other_sp;
char *answer = NULL;
char *soap_answer = NULL;
logout = lasso_logout_new(server, lassoProviderTypeIdp);
rc = lasso_logout_process_request_msg(logout,
soap_msg, lassoHttpMethodSoap);
if (rc) {
fprintf(stderr, "process_request_msg failed\n");
goto cleanup;
}
rc = set_profile_auto(LASSO_PROFILE(logout));
if (rc) {
fprintf(stderr, "set_profile_auto failed\n");
goto cleanup;
}
rc = lasso_logout_validate_request(logout);
if (rc == LASSO_LOGOUT_ERROR_UNSUPPORTED_PROFILE) {
/* some SP don't support SOAP logout; fuck off */
rc = lasso_logout_build_request_msg(logout);
if (rc) {
fprintf(stderr, "build_request_msg failed\n");
goto cleanup;
}
answer = strdup(LASSO_PROFILE(logout)->msg_body);
goto cleanup;
}
if (rc) {
fprintf(stderr, "logout validate request failed\n");
goto cleanup;
}
rc = save_profile_dumps(LASSO_PROFILE(logout));
if (rc) {
fprintf(stderr, "save_profile_dumps failed\n");
goto cleanup;
}
other_sp = lasso_logout_get_next_providerID(logout);
while (other_sp) {
fprintf(stderr, "Other SP: %s\n", other_sp);
rc = lasso_logout_init_request(logout, other_sp,
lassoHttpMethodAny);
if (rc) {
fprintf(stderr, "init_request failed\n");
goto cleanup;
}
rc = lasso_logout_build_request_msg(logout);
if (rc) {
fprintf(stderr, "build_request failed\n");
goto cleanup;
}
soap_answer = soap_request(LASSO_PROFILE(logout)->msg_url,
LASSO_PROFILE(logout)->msg_body, NULL);
if (soap_answer == NULL) {
fprintf(stderr, "soap_request failed\n");
goto cleanup;
}
rc = lasso_logout_process_response_msg(logout,
soap_answer, lassoHttpMethodSoap);
if (rc) {
free(soap_answer);
fprintf(stderr, "logout_process_response_msg failed\n");
goto cleanup;
}
free(soap_answer);
other_sp = lasso_logout_get_next_providerID(logout);
}
fprintf(stderr, "done\n");
rc = lasso_logout_build_response_msg(logout);
if (rc) {
fprintf(stderr, "build_response failed\n");
goto cleanup;
}
answer = strdup(LASSO_PROFILE(logout)->msg_body);
cleanup:
if (logout) {
lasso_logout_destroy(logout);
}
return answer;
}
char* req_defederation(LassoServer *server, char *soap_msg)
{
LassoDefederation *termination = NULL;
LassoIdentity *identity;
int rc;
termination = lasso_defederation_new(server, lassoProviderTypeIdp);
rc = lasso_defederation_process_notification_msg(
termination, soap_msg, lassoHttpMethodSoap);
if (rc) {
fprintf(stderr, "process_notifification_msg failed\n");
return NULL;
}
rc = set_profile_auto(LASSO_PROFILE(termination));
if (rc) {
fprintf(stderr, "set_profile_auto failed\n");
lasso_defederation_destroy(termination);
return NULL;
}
rc = lasso_defederation_validate_notification(termination);
if (rc) {
fprintf(stderr, "validate_notification failed\n");
lasso_defederation_destroy(termination);
return NULL;
}
rc = save_profile_dumps(LASSO_PROFILE(termination));
if (rc) {
lasso_defederation_destroy(termination);
fprintf(stderr, "save_profile_dumps failed\n");
return NULL;
}
lasso_defederation_destroy(termination);
return SOAP_204;
}
char* req_register_name_identifier(LassoServer *server, char *soap_msg)
{
return NULL;
}
char* req_name_identifier_mapping(LassoServer *server, char *soap_msg)
{
return NULL;
}
int soap_end_point()
{
LassoServer *server;
int clen = 0;
char *soap_msg, *soap_answer = NULL;
char *http_verb;
lassoRequestType req_type;
int i;
http_verb = getenv("REQUEST_METHOD");
if (http_verb == NULL) {
return error_page("No HTTP verb");
}
if (strcmp(http_verb, "POST") != 0) {
return error_page("Must be POST");
}
if (getenv("CONTENT_TYPE") &&
strcmp(getenv("CONTENT_TYPE"), "text/xml") != 0) {
return error_page("Content-Type must be text/xml");
}
server = get_config_server();
if (server == NULL) {
return error_page("Failed to get server configuration");
}
clen = atoi(getenv("CONTENT_LENGTH"));
soap_msg = malloc(clen+1);
soap_msg[clen] = 0;
fread(soap_msg, clen, 1, stdin);
fprintf(stderr, "Got message:\n%s\n", soap_msg);
req_type = lasso_profile_get_request_type_from_soap_msg(soap_msg);
for (i=0; requests[i].type && requests[i].type != req_type; i++) ;
if (! requests[i].type) {
return error_page("Wrong soap req type");
}
soap_answer = requests[i].request_function(server, soap_msg);
lasso_server_destroy(server);
free(soap_msg);
if (soap_answer == NULL) {
fprintf(stderr, "soap_answer was NULL\n");
return error_page("error in soap end point");
}
if (strcmp(soap_answer, SOAP_204) == 0) {
printf("Status: 204\n\n");
return 0;
}
clen = strlen(soap_answer);
printf("Content-type: text/xml\n");
printf("Content-length: %d\n\n", clen);
fputs(soap_answer, stdout);
free(soap_answer);
return 0;
}
int main(int argc, char *argv[])
{
int rc;
if (argc > 1 && handle_args(argc, argv) ) {
handle_args(argc, argv);
return 0;
}
rc = init_config();
if (rc) {
return error_page("Failed to init configuration");
}
lasso_init();
rc = db_init();
if (rc) {
error_page("Failed to init database access");
goto shutdown;
}
rc = soap_end_point();
shutdown:
db_finish();
lasso_shutdown();
return rc;
}