/* * idpc - IDP as a C CGI program * Copyright (C) 2004 Entr'ouvert * * Author: Frederic Peters * * 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; }