2004-10-27 11:49:13 +02:00
|
|
|
/* $Id$
|
2004-07-06 03:07:32 +02:00
|
|
|
*
|
|
|
|
* Lasso - A free implementation of the Liberty Alliance specifications.
|
|
|
|
*
|
2007-05-30 19:17:45 +02:00
|
|
|
* Copyright (C) 2004-2007 Entr'ouvert
|
2004-07-06 03:07:32 +02:00
|
|
|
* http://lasso.entrouvert.org
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2005-01-22 16:57:56 +01:00
|
|
|
* Authors: See AUTHORS file in top-level directory.
|
2004-07-06 03:07:32 +02:00
|
|
|
*
|
|
|
|
* 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.
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2004-07-06 03:07:32 +02:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2004-12-12 19:15:01 +01:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2004-07-06 03:07:32 +02:00
|
|
|
* GNU General Public License for more details.
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2004-07-06 03:07:32 +02:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2004-12-12 19:15:01 +01:00
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
2004-07-06 03:07:32 +02:00
|
|
|
*/
|
|
|
|
|
2008-05-15 23:17:44 +02:00
|
|
|
/**
|
|
|
|
* SECTION:login
|
|
|
|
* @short_description: Single Sign-On and Federation Profile
|
|
|
|
*
|
|
|
|
* The Single Sign On process allows a user to log in once to an identity
|
|
|
|
* provider (IdP), and to be then transparently loged in to the required
|
|
|
|
* service providers (SP) belonging to the IP "circle of trust". Subordinating
|
|
|
|
* different identities of the same user within a circle of trust to a unique
|
|
|
|
* IP is called "Identity Federation". The liberty Alliance specifications
|
|
|
|
* allows, thanks to this federation, strong and unique authentication coupled
|
|
|
|
* with control by the user of his personal informations. The explicit user
|
|
|
|
* agreement is necessary before proceeding to Identity Federation.
|
|
|
|
*
|
|
|
|
* <para>
|
|
|
|
* The service provider must implement the following process:
|
|
|
|
* <itemizedlist>
|
2010-02-10 01:34:04 +01:00
|
|
|
* <listitem><para>creating an authentication request with
|
2008-05-15 23:17:44 +02:00
|
|
|
* lasso_login_init_authn_request();</para></listitem>
|
|
|
|
* <listitem><para>sending it to the identity provider with
|
|
|
|
* lasso_login_build_authn_request_msg();</para></listitem>
|
|
|
|
* <listitem><para>receiving and processing the answer:
|
|
|
|
* <itemizedlist>
|
|
|
|
* <listitem>either an authentication response with
|
|
|
|
* lasso_login_process_authn_response_msg()</listitem>
|
|
|
|
* <listitem>or an artifact with lasso_login_init_request() then sending the
|
|
|
|
* request to the IdP with lasso_login_build_request_msg() and processing the
|
|
|
|
* new answer with lasso_login_process_response_msg().</listitem>
|
|
|
|
* </itemizedlist>
|
|
|
|
* </para></listitem>
|
|
|
|
* </itemizedlist>
|
2008-09-12 17:06:58 +02:00
|
|
|
* </para>
|
2010-02-10 01:34:04 +01:00
|
|
|
*
|
|
|
|
* <para>Our first example shows how to initiate a request toward an ID-FF 1.2 or SAML 2.0 identity
|
|
|
|
* provider. It supposes that we already initialized a #LassoServer object with the metadatas or our
|
|
|
|
* provider (and its private key if we want to sign the request), and that we added the metadatas of
|
|
|
|
* the targetted IdP with the method lasso_server_add_provider(). </para>
|
|
|
|
*
|
2008-05-15 23:17:44 +02:00
|
|
|
* <example>
|
|
|
|
* <title>Service Provider Login URL</title>
|
|
|
|
* <programlisting>
|
2010-04-19 13:51:28 +02:00
|
|
|
* LassoLogin *login;
|
2010-02-10 01:34:04 +01:00
|
|
|
* int rc; // hold return codes
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2008-05-15 23:17:44 +02:00
|
|
|
* login = lasso_login_new(server);
|
2010-02-10 01:34:04 +01:00
|
|
|
* rc = lasso_login_init_authn_request(login, "http://identity-provider-id/",
|
2008-05-15 23:17:44 +02:00
|
|
|
* LASSO_HTTP_METHOD_REDIRECT);
|
2010-02-10 01:34:04 +01:00
|
|
|
* if (rc != 0) {
|
|
|
|
* ... // handle errors, most of them are related to bad initialization
|
|
|
|
* }
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2008-05-15 23:17:44 +02:00
|
|
|
* // customize AuthnRequest
|
2010-02-10 01:34:04 +01:00
|
|
|
* // protocolProfile is the protocolProfile of the provider http://identity-provider-id/
|
|
|
|
* if (protocolProfile == LASSO_LIBERTY_1_2) {
|
2010-04-19 13:51:28 +02:00
|
|
|
* LassoLibAuthnRequest *request = LASSO_LIB_AUTHN_REQUEST(LASSO_PROFILE(login)->request);
|
2010-02-10 01:34:04 +01:00
|
|
|
* request->NameIDPolicy = strdup(LASSO_LIB_NAMEID_POLICY_TYPE_FEDERATED);
|
|
|
|
* request->ForceAuthn = TRUE;
|
|
|
|
* request->IsPassive = FALSE;
|
|
|
|
* // tell the IdP how to return the response
|
|
|
|
* request->ProtocolProfile = strdup(LASSO_LIB_PROTOCOL_PROFILE_BRWS_ART);
|
|
|
|
* } else if (protocolProfile == LASSO_SAML_2_0) {
|
2010-04-19 13:51:28 +02:00
|
|
|
* LassoSamlp2AuthnRequest *request = LASSO_SAMLP2_AUTHN_REQUEST(LASSO_PROFILE(login)->request);
|
2010-02-10 01:34:04 +01:00
|
|
|
* if (request->NameIDPolicy->Format) {
|
2010-04-22 13:19:32 +02:00
|
|
|
* g_free(request->NameIDPolicy->Format);
|
2010-02-10 01:34:04 +01:00
|
|
|
* }
|
2010-04-19 13:51:28 +02:00
|
|
|
* request->NameIDPolicy->Format = g_strdup(LASSO_NAME_IDENTIFIER_FORMAT_PERSISTENT);
|
2010-04-22 02:44:31 +02:00
|
|
|
* // Allow creation of new federation
|
|
|
|
* //
|
2010-02-10 01:34:04 +01:00
|
|
|
* request->NameIDPolicy->AllowCreate = 1;
|
|
|
|
* request->ForceAuthn = TRUE;
|
|
|
|
* request->IsPassive = FALSE;
|
|
|
|
* // tell the IdP how to return the response
|
|
|
|
* if (request->ProtocolBinding) {
|
2010-04-22 13:19:32 +02:00
|
|
|
* g_free(request->ProtocolBinding);
|
2010-02-10 01:34:04 +01:00
|
|
|
* }
|
|
|
|
* // here we expect an artifact response, it could be post, redirect or PAOS.
|
2010-04-19 13:51:28 +02:00
|
|
|
* request->ProtocolBinding = g_strdup(LASSO_SAML2_METADATA_BINDING_ARTIFACT);
|
2010-02-10 01:34:04 +01:00
|
|
|
}
|
|
|
|
* // Lasso will choose whether to sign the request by looking at the IdP
|
|
|
|
* // metadatas and at our metadatas, but you can always force him to sign or to
|
|
|
|
* // not sign using the method lasso_profile_set_signature_hint() on the
|
2010-04-19 13:51:28 +02:00
|
|
|
* // LassoLogin object.
|
2010-02-10 01:34:04 +01:00
|
|
|
*
|
|
|
|
* rc = lasso_login_build_authn_request_msg(login);
|
|
|
|
* if (rc != 0) {
|
|
|
|
.... // handle errors
|
2010-04-19 13:51:28 +02:00
|
|
|
// could be that the requested binding (POST, Redirect, etc..) is not supported (LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE)
|
|
|
|
// or that we could not sign the request (LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED).
|
2010-02-10 01:34:04 +01:00
|
|
|
* }
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2008-05-15 23:17:44 +02:00
|
|
|
* // redirect user to identity provider
|
2010-02-10 01:34:04 +01:00
|
|
|
// we chose the Redirect binding, so we have to generate a redirect HTTP response to the URL returned by Lasso
|
2008-05-15 23:17:44 +02:00
|
|
|
* printf("Location: %s\n\nRedirected to IdP\n", LASSO_PROFILE(login)->msg_url);
|
|
|
|
* </programlisting>
|
|
|
|
* </example>
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2010-02-10 01:34:04 +01:00
|
|
|
* <para>Next example shows how to receive the response from the identity
|
|
|
|
* provider for ID-FF 1.2.</para>
|
|
|
|
*
|
2008-05-15 23:17:44 +02:00
|
|
|
* <example>
|
2010-02-10 01:34:04 +01:00
|
|
|
* <title>Service Provider Assertion Consumer Service URL for ID-FF 1.2</title>
|
2008-05-15 23:17:44 +02:00
|
|
|
* <programlisting>
|
|
|
|
* LassoLogin *login;
|
|
|
|
* char *request_method = getenv("REQUEST_METHOD");
|
|
|
|
* char *artifact_msg = NULL, *lares = NULL, *lareq = NULL;
|
|
|
|
* char *name_identifier;
|
|
|
|
* lassoHttpMethod method;
|
2010-02-10 01:34:04 +01:00
|
|
|
* int rc = 0;
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2008-05-15 23:17:44 +02:00
|
|
|
* login = lasso_login_new(server);
|
|
|
|
* if (strcmp(request_method, "GET") == 0) {
|
|
|
|
* artifact_msg = getenv("QUERY_STRING");
|
|
|
|
* method = LASSO_HTTP_METHOD_REDIRECT;
|
|
|
|
* } else {
|
|
|
|
* // read submitted form; if it has a LAREQ field, put it in lareq,
|
|
|
|
* // if it has a LARES field, put it in lares
|
|
|
|
* if (lareq) {
|
|
|
|
* artifact_msg = lareq;
|
|
|
|
* } else if (lares) {
|
|
|
|
* response_msg = lares;
|
|
|
|
* } else {
|
|
|
|
* // bail out
|
|
|
|
* }
|
|
|
|
* method = LASSO_HTTP_METHOD_POST;
|
|
|
|
* }
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2008-05-15 23:17:44 +02:00
|
|
|
* if (artifact_msg) {
|
2010-02-10 01:34:04 +01:00
|
|
|
* // we received an artifact response,
|
|
|
|
* // it means we did not really receive the response,
|
|
|
|
* // only a token to redeem the real response from the identity
|
|
|
|
* // provider through a SOAP resolution call
|
|
|
|
* rc = lasso_login_init_request(login, artifact_msg, method);
|
|
|
|
* if (rc != 0) {
|
|
|
|
* ... // handle errors
|
|
|
|
* // there is usually no error at this step, only
|
|
|
|
* // if the IdP response is malformed
|
|
|
|
* }
|
|
|
|
* rc = lasso_login_build_request_msg(login);
|
|
|
|
* if (rc != 0) {
|
|
|
|
* ... // handle errors
|
|
|
|
* // as for AuthnRequest generation, it generally is caused
|
|
|
|
* // by a bad initialization like an impossibility to load
|
|
|
|
* // the private key.
|
|
|
|
* }
|
2008-05-15 23:17:44 +02:00
|
|
|
* // makes a SOAP call, soap_call is NOT a Lasso function
|
|
|
|
* soap_answer_msg = soap_call(LASSO_PROFILE(login)->msg_url,
|
|
|
|
* LASSO_PROFILE(login)->msg_body);
|
2010-02-10 01:34:04 +01:00
|
|
|
* rc = lasso_login_process_response_msg(login, soap_answer_msg);
|
|
|
|
* if (rc != 0) {
|
|
|
|
* ... // handle errors
|
|
|
|
* // here you can know if the IdP refused the request,
|
|
|
|
* }
|
2008-05-15 23:17:44 +02:00
|
|
|
* } else if (response_msg) {
|
|
|
|
* lasso_login_process_authn_response_msg(login, response_msg);
|
|
|
|
* }
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2008-05-15 23:17:44 +02:00
|
|
|
* // looks up name_identifier in local file, database, whatever and gets back
|
|
|
|
* // two things: identity_dump and session_dump
|
|
|
|
* name_identifier = LASSO_PROFILE(login)->nameIdentifier
|
|
|
|
* lasso_profile_set_identity_from_dump(LASSO_PROFILE(login), identity_dump);
|
|
|
|
* lasso_profile_set_session_from_dump(LASSO_PROFILE(login), session_dump);
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2008-05-15 23:17:44 +02:00
|
|
|
* lasso_login_accept_sso(login);
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2008-05-15 23:17:44 +02:00
|
|
|
* if (lasso_profile_is_identity_dirty(LASSO_PROFILE(login))) {
|
|
|
|
* LassoIdentity *identity;
|
|
|
|
* char *identity_dump;
|
|
|
|
* identity = lasso_profile_get_identity(LASSO_PROFILE(login));
|
|
|
|
* identity_dump = lasso_identity_dump(identity);
|
|
|
|
* // record identity_dump in file, database...
|
|
|
|
* }
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2008-05-15 23:17:44 +02:00
|
|
|
* if (lasso_profile_is_session_dirty(LASSO_PROFILE(login))) {
|
|
|
|
* LassoSession *session;
|
|
|
|
* char *session_dump;
|
|
|
|
* session = lasso_profile_get_session(LASSO_PROFILE(login));
|
|
|
|
* session_dump = lasso_session_dump(session);
|
|
|
|
* // record session_dump in file, database...
|
|
|
|
* }
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2008-05-15 23:17:44 +02:00
|
|
|
* // redirect user anywhere
|
|
|
|
* printf("Location: %s\n\nRedirected to site root\n", login->msg_url);
|
|
|
|
* </programlisting>
|
|
|
|
* </example>
|
2010-02-10 01:34:04 +01:00
|
|
|
*
|
2010-04-22 02:44:31 +02:00
|
|
|
* <p>The implement an IdP you must create a single sign-on service endpoint, the needed APIs for
|
|
|
|
* this are lasso_login_process_authn_request_msg(), lasso_login_validate_request_msg(),
|
|
|
|
* lasso_login_build_assertion(), lasso_login_build_authn_response_msg() and
|
|
|
|
* lasso_login_build_artifact_msg(). You will have to chose between
|
|
|
|
* lasso_login_build_authn_response_msg() and lasso_login_build_artifact_msg() depending on the
|
|
|
|
* requested protocol for the response by the service provider</p>
|
|
|
|
*
|
|
|
|
* <example>
|
|
|
|
* <title>Identity provider single sign-on service</title>
|
|
|
|
* <programlisting>
|
|
|
|
* LassoLogin *login;
|
|
|
|
* char *request_method = getenv("REQUEST_METHOD");
|
|
|
|
* char *artifact_msg = NULL, *lares = NULL, *lareq = NULL;
|
|
|
|
* char *name_identifier;
|
|
|
|
* lassoHttpMethod method;
|
|
|
|
* int rc = 0;
|
|
|
|
*
|
|
|
|
* login = lasso_login_new(server);
|
|
|
|
* if (strcmp(request_method, 'GET')) { // AuthnRequest send with the HTTP-Redirect binding
|
|
|
|
* //
|
|
|
|
* lasso_profile_set_signature_verify_hint(LASSO_PROFILE(login),
|
|
|
|
* LASSO_PROFILE_SIGNATURE_VERIFY_HINT_FORCE);
|
|
|
|
* rc = lasso_process_authn_request_msg(login, getenv("QUERY_STRING"));
|
|
|
|
* if (rc != 0) {
|
|
|
|
* // handle errors
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* } else {
|
|
|
|
*
|
|
|
|
* </programlisting>
|
|
|
|
* </example>
|
2010-02-10 01:34:04 +01:00
|
|
|
*
|
2008-09-12 17:06:58 +02:00
|
|
|
*/
|
2008-05-15 23:17:44 +02:00
|
|
|
|
2004-07-22 12:24:41 +02:00
|
|
|
#include <xmlsec/base64.h>
|
|
|
|
|
2008-08-01 16:08:54 +02:00
|
|
|
#include <config.h>
|
2009-08-26 17:14:32 +02:00
|
|
|
#include "lasso_config.h"
|
|
|
|
#include "../utils.h"
|
|
|
|
#include "../debug.h"
|
|
|
|
#include "login.h"
|
|
|
|
#include "provider.h"
|
|
|
|
#include "../xml/private.h"
|
|
|
|
#include "../xml/lib_authentication_statement.h"
|
|
|
|
#include "../xml/lib_subject.h"
|
|
|
|
#include "../xml/saml_advice.h"
|
|
|
|
#include "../xml/saml_attribute.h"
|
|
|
|
#include "../xml/saml_attribute_value.h"
|
|
|
|
#include "../xml/saml_audience_restriction_condition.h"
|
|
|
|
#include "../xml/saml_conditions.h"
|
|
|
|
#include "../xml/samlp_response.h"
|
|
|
|
#include "../xml/saml-2.0/saml2_encrypted_element.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "profileprivate.h"
|
|
|
|
#include "providerprivate.h"
|
|
|
|
#include "serverprivate.h"
|
|
|
|
#include "sessionprivate.h"
|
|
|
|
#include "identityprivate.h"
|
|
|
|
#include "loginprivate.h"
|
|
|
|
#include "../saml-2.0/loginprivate.h"
|
2004-07-23 15:28:08 +02:00
|
|
|
|
2005-03-18 21:58:34 +01:00
|
|
|
#ifdef LASSO_WSF_ENABLED
|
2009-08-26 17:14:32 +02:00
|
|
|
#include "../id-wsf/id_ff_extensions_private.h"
|
2005-03-18 21:58:34 +01:00
|
|
|
#endif
|
|
|
|
|
2005-01-28 11:25:19 +01:00
|
|
|
|
2005-01-28 16:57:56 +01:00
|
|
|
static void lasso_login_build_assertion_artifact(LassoLogin *login);
|
2005-01-28 11:25:19 +01:00
|
|
|
|
2004-07-06 03:07:32 +02:00
|
|
|
/*****************************************************************************/
|
2004-10-27 11:49:13 +02:00
|
|
|
/* static methods/functions */
|
2004-07-06 03:07:32 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
2004-08-09 12:53:47 +02:00
|
|
|
/**
|
2004-09-22 15:21:29 +02:00
|
|
|
* lasso_login_build_assertion:
|
2004-12-22 13:48:05 +01:00
|
|
|
* @login: a #LassoLogin
|
2004-12-31 11:51:17 +01:00
|
|
|
* @authenticationMethod: the authentication method
|
|
|
|
* @authenticationInstant: the time at which the authentication took place
|
|
|
|
* @notBefore: the earliest time instant at which the assertion is valid
|
|
|
|
* @notOnOrAfter: the time instant at which the assertion has expired
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2004-12-31 11:51:17 +01:00
|
|
|
* Builds an assertion and stores it in profile session.
|
|
|
|
* @authenticationInstant, reauthenticateOnOrAfter, @notBefore and
|
|
|
|
* @notOnOrAfter may be NULL. If @authenticationInstant is NULL, the current
|
|
|
|
* time will be used. Time values must be encoded in UTC.
|
2004-10-27 11:49:13 +02:00
|
|
|
*
|
2010-03-27 18:39:56 +01:00
|
|
|
* Construct the authentication assertion for the response. It must be called after validating the
|
|
|
|
* request using lasso_login_validate_request_msg(). The created assertion is accessed using
|
|
|
|
* lasso_login_get_assertion().
|
|
|
|
*
|
2009-04-27 10:19:00 +02:00
|
|
|
* Return value: 0 on success; or
|
2010-03-27 18:39:56 +01:00
|
|
|
* <itemizedlist>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if login is not a #LassoLogin object,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_PROFILE_ERROR_IDENTITY_NOT_FOUND if no identity object was found in the login profile object.
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_PROFILE_ERROR_MISSING_RESPONSE if no response object is present ( it is normally initialized
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* by lasso_login_process_authn_request_msg() )
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_PROFILE_ERROR_FEDERATION_NOT_FOUND if a #LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT or #LASSO_SAML2_NAME_IDENTIFIER_FORMAT_ENCRYPTED NameID format is asked and no corresponding federation was found in the #LassoIdentity object,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND if encryption is needed and the request issuing provider is unknown (it as not been registered in the #LassoServer object),
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_DS_ERROR_ENCRYPTION_FAILED if encryption is needed but it failed,
|
|
|
|
* </para></listitem>
|
|
|
|
* </itemizedlist>
|
2009-04-27 10:19:00 +02:00
|
|
|
*
|
2004-08-09 12:53:47 +02:00
|
|
|
**/
|
2004-12-14 20:20:20 +01:00
|
|
|
int
|
2004-10-27 11:49:13 +02:00
|
|
|
lasso_login_build_assertion(LassoLogin *login,
|
|
|
|
const char *authenticationMethod,
|
|
|
|
const char *authenticationInstant,
|
|
|
|
const char *reauthenticateOnOrAfter,
|
|
|
|
const char *notBefore,
|
|
|
|
const char *notOnOrAfter)
|
2004-07-15 18:00:49 +02:00
|
|
|
{
|
2004-12-19 21:34:22 +01:00
|
|
|
LassoSamlAssertion *assertion;
|
2004-10-27 11:49:13 +02:00
|
|
|
LassoLibAuthenticationStatement *as;
|
2005-01-28 16:57:56 +01:00
|
|
|
LassoSamlNameIdentifier *nameIdentifier = NULL;
|
2004-10-27 11:49:13 +02:00
|
|
|
LassoProfile *profile;
|
2004-12-14 20:20:20 +01:00
|
|
|
LassoFederation *federation;
|
2007-12-05 11:48:49 +01:00
|
|
|
LassoProvider *provider = NULL;
|
|
|
|
LassoSaml2EncryptedElement *encrypted_element = NULL;
|
|
|
|
LassoSamlSubjectStatementAbstract *ss;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
|
|
|
|
|
|
|
profile = LASSO_PROFILE(login);
|
2004-12-14 20:20:20 +01:00
|
|
|
|
2005-01-08 14:53:42 +01:00
|
|
|
if (profile->identity == NULL)
|
|
|
|
return LASSO_PROFILE_ERROR_IDENTITY_NOT_FOUND;
|
|
|
|
|
2005-11-21 19:51:52 +01:00
|
|
|
IF_SAML2(profile) {
|
2005-11-20 16:38:19 +01:00
|
|
|
return lasso_saml20_login_build_assertion(login,
|
|
|
|
authenticationMethod, authenticationInstant,
|
2008-09-12 15:57:22 +02:00
|
|
|
notBefore, notOnOrAfter);
|
2005-11-20 16:38:19 +01:00
|
|
|
}
|
|
|
|
|
2004-12-14 20:20:20 +01:00
|
|
|
federation = g_hash_table_lookup(profile->identity->federations,
|
|
|
|
profile->remote_providerID);
|
2008-09-12 17:06:58 +02:00
|
|
|
|
2004-12-19 21:34:22 +01:00
|
|
|
assertion = LASSO_SAML_ASSERTION(lasso_lib_assertion_new_full(
|
2004-10-27 11:49:13 +02:00
|
|
|
LASSO_PROVIDER(profile->server)->ProviderID,
|
2005-11-20 16:38:19 +01:00
|
|
|
LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->RequestID,
|
2004-12-19 21:34:22 +01:00
|
|
|
profile->remote_providerID, notBefore, notOnOrAfter));
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2008-04-06 11:42:26 +02:00
|
|
|
if (strcmp(login->nameIDPolicy, LASSO_LIB_NAMEID_POLICY_TYPE_ONE_TIME) == 0 ||
|
|
|
|
federation == NULL) {
|
2004-10-27 11:49:13 +02:00
|
|
|
/* if NameIDPolicy is 'onetime', don't use a federation */
|
2004-10-27 17:41:28 +02:00
|
|
|
nameIdentifier = lasso_saml_name_identifier_new();
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_string(nameIdentifier->content, lasso_build_unique_id(32));
|
|
|
|
lasso_assign_string(nameIdentifier->NameQualifier,
|
2005-01-04 13:42:02 +01:00
|
|
|
LASSO_PROVIDER(profile->server)->ProviderID);
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_string(nameIdentifier->Format,
|
|
|
|
LASSO_LIB_NAME_IDENTIFIER_FORMAT_ONE_TIME);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
as = lasso_lib_authentication_statement_new_full(authenticationMethod,
|
|
|
|
authenticationInstant, reauthenticateOnOrAfter,
|
|
|
|
NULL, nameIdentifier);
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_gobject(profile->nameIdentifier, LASSO_NODE(nameIdentifier));
|
2004-10-27 11:49:13 +02:00
|
|
|
} else {
|
|
|
|
as = lasso_lib_authentication_statement_new_full(authenticationMethod,
|
|
|
|
authenticationInstant, reauthenticateOnOrAfter,
|
2005-11-20 16:38:19 +01:00
|
|
|
LASSO_SAML_NAME_IDENTIFIER(federation->remote_nameIdentifier),
|
|
|
|
LASSO_SAML_NAME_IDENTIFIER(federation->local_nameIdentifier));
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2007-12-05 11:48:49 +01:00
|
|
|
/* Encrypt NameID */
|
2009-10-30 15:47:23 +01:00
|
|
|
provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
|
2007-12-05 11:48:49 +01:00
|
|
|
ss = LASSO_SAML_SUBJECT_STATEMENT_ABSTRACT(as);
|
|
|
|
if (provider && provider->private_data->encryption_mode & LASSO_ENCRYPTION_MODE_NAMEID
|
|
|
|
&& provider->private_data->encryption_public_key != NULL) {
|
|
|
|
encrypted_element = LASSO_SAML2_ENCRYPTED_ELEMENT(lasso_node_encrypt(
|
|
|
|
LASSO_NODE(ss->Subject->NameIdentifier),
|
|
|
|
provider->private_data->encryption_public_key,
|
2010-01-12 16:39:57 +01:00
|
|
|
provider->private_data->encryption_sym_key_type, provider->ProviderID));
|
2007-12-05 11:48:49 +01:00
|
|
|
if (encrypted_element != NULL) {
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_gobject(ss->Subject->EncryptedNameIdentifier, encrypted_element);
|
|
|
|
lasso_release_gobject(ss->Subject->NameIdentifier);
|
2007-12-05 11:48:49 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-01-28 16:57:56 +01:00
|
|
|
assertion->AuthenticationStatement = LASSO_SAML_AUTHENTICATION_STATEMENT(as);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2008-09-16 18:31:05 +02:00
|
|
|
/* Save signing material in assertion private datas to be able to sign later */
|
2004-12-19 21:34:22 +01:00
|
|
|
if (profile->server->certificate) {
|
|
|
|
assertion->sign_type = LASSO_SIGNATURE_TYPE_WITHX509;
|
|
|
|
} else {
|
|
|
|
assertion->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
|
|
|
|
}
|
|
|
|
assertion->sign_method = profile->server->signature_method;
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_string(assertion->private_key_file, profile->server->private_key);
|
|
|
|
lasso_assign_string(assertion->certificate_file, profile->server->certificate);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2005-05-10 18:47:15 +02:00
|
|
|
if (login->protocolProfile == LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST || \
|
2005-05-12 14:55:19 +02:00
|
|
|
login->protocolProfile == LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_LECP) {
|
2004-10-27 11:49:13 +02:00
|
|
|
/* only add assertion if response is an AuthnResponse */
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_list_add_gobject(LASSO_SAMLP_RESPONSE(profile->response)->Assertion,
|
|
|
|
assertion);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
2005-01-28 00:41:05 +01:00
|
|
|
|
2008-09-12 15:57:22 +02:00
|
|
|
#ifdef LASSO_WSF_ENABLED
|
2008-09-16 18:31:05 +02:00
|
|
|
lasso_login_assertion_add_discovery(login, assertion);
|
2008-09-12 15:57:22 +02:00
|
|
|
#endif
|
2005-01-28 00:41:05 +01:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
/* store assertion in session object */
|
|
|
|
if (profile->session == NULL) {
|
|
|
|
profile->session = lasso_session_new();
|
|
|
|
}
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_gobject(login->assertion, LASSO_SAML_ASSERTION(assertion));
|
2008-02-18 14:11:33 +01:00
|
|
|
lasso_session_add_assertion(profile->session, profile->remote_providerID,
|
|
|
|
LASSO_NODE(assertion));
|
2005-01-28 16:57:56 +01:00
|
|
|
|
2008-09-12 17:06:58 +02:00
|
|
|
if (LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->MajorVersion == 1 &&
|
2005-11-20 16:38:19 +01:00
|
|
|
LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->MinorVersion < 2) {
|
2005-01-28 16:57:56 +01:00
|
|
|
/* pre-id-ff 1.2, saml 1.0 */
|
|
|
|
|
|
|
|
/* needs assertion artifact */
|
|
|
|
lasso_login_build_assertion_artifact(login);
|
|
|
|
|
|
|
|
assertion->MinorVersion = 0;
|
|
|
|
|
|
|
|
ss = LASSO_SAML_SUBJECT_STATEMENT_ABSTRACT(assertion->AuthenticationStatement);
|
|
|
|
ss->Subject = LASSO_SAML_SUBJECT(lasso_saml_subject_new());
|
|
|
|
ss->Subject->NameIdentifier = g_object_ref(profile->nameIdentifier);
|
|
|
|
ss->Subject->SubjectConfirmation = lasso_saml_subject_confirmation_new();
|
|
|
|
/* liberty-architecture-bindings-profiles-v1.1.pdf, page 24, line 729 */
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_list_add_string(ss->Subject->SubjectConfirmation->ConfirmationMethod,
|
|
|
|
LASSO_SAML_CONFIRMATION_METHOD_ARTIFACT01);
|
|
|
|
lasso_assign_string(ss->Subject->SubjectConfirmation->SubjectConfirmationData,
|
|
|
|
login->assertionArtifact);
|
2005-01-28 16:57:56 +01:00
|
|
|
|
|
|
|
if (nameIdentifier) {
|
|
|
|
/* draft-liberty-idff-protocols-schemas-1.2-errata-v2.0.pdf */
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_release_string(nameIdentifier->NameQualifier);
|
|
|
|
lasso_release_string(nameIdentifier->Format);
|
2005-01-28 16:57:56 +01:00
|
|
|
}
|
|
|
|
}
|
2008-09-12 17:06:58 +02:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
return 0;
|
2004-07-15 18:00:49 +02:00
|
|
|
}
|
|
|
|
|
2004-10-01 16:15:01 +02:00
|
|
|
/**
|
|
|
|
* lasso_login_must_ask_for_consent_private:
|
2004-12-22 13:48:05 +01:00
|
|
|
* @login: a #LassoLogin
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
|
|
|
* Evaluates if it is necessary to ask the consent of the Principal.
|
2004-10-01 16:15:01 +02:00
|
|
|
* This method doesn't take the isPassive value into account.
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2009-04-27 10:19:02 +02:00
|
|
|
* Return value: TRUE if consent should be asked, FALSE otherwise.
|
2004-10-01 16:15:01 +02:00
|
|
|
**/
|
|
|
|
static gboolean
|
|
|
|
lasso_login_must_ask_for_consent_private(LassoLogin *login)
|
|
|
|
{
|
2005-07-31 00:36:54 +02:00
|
|
|
char *nameIDPolicy, *consent;
|
2004-10-27 11:49:13 +02:00
|
|
|
LassoProfile *profile = LASSO_PROFILE(login);
|
|
|
|
LassoFederation *federation = NULL;
|
|
|
|
|
|
|
|
nameIDPolicy = LASSO_LIB_AUTHN_REQUEST(profile->request)->NameIDPolicy;
|
|
|
|
|
|
|
|
if (nameIDPolicy == NULL || strcmp(nameIDPolicy, LASSO_LIB_NAMEID_POLICY_TYPE_NONE) == 0)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (strcmp(nameIDPolicy, LASSO_LIB_NAMEID_POLICY_TYPE_ONE_TIME) == 0)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (strcmp(nameIDPolicy, LASSO_LIB_NAMEID_POLICY_TYPE_FEDERATED) != 0 &&
|
|
|
|
strcmp(nameIDPolicy, LASSO_LIB_NAMEID_POLICY_TYPE_ANY) != 0) {
|
2004-10-29 11:52:25 +02:00
|
|
|
message(G_LOG_LEVEL_CRITICAL, "Unknown NameIDPolicy: %s", nameIDPolicy);
|
2004-11-29 17:38:58 +01:00
|
|
|
/* NameIDPolicy is considered empty (None value) if its value is unknown/invalid */
|
2004-10-27 11:49:13 +02:00
|
|
|
return TRUE;
|
2004-10-01 16:15:01 +02:00
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
if (profile->identity != NULL) {
|
|
|
|
federation = g_hash_table_lookup(profile->identity->federations,
|
|
|
|
profile->remote_providerID);
|
|
|
|
if (federation)
|
|
|
|
return FALSE;
|
2004-10-01 16:15:01 +02:00
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
consent = LASSO_LIB_AUTHN_REQUEST(profile->request)->consent;
|
|
|
|
if (consent == NULL)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if (strcmp(consent, LASSO_LIB_CONSENT_OBTAINED) == 0)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (strcmp(consent, LASSO_LIB_CONSENT_OBTAINED_PRIOR) == 0)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (strcmp(consent, LASSO_LIB_CONSENT_OBTAINED_CURRENT_IMPLICIT) == 0)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (strcmp(consent, LASSO_LIB_CONSENT_OBTAINED_CURRENT_EXPLICIT) == 0)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (strcmp(consent, LASSO_LIB_CONSENT_UNAVAILABLE) == 0)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if (strcmp(consent, LASSO_LIB_CONSENT_INAPPLICABLE) == 0)
|
|
|
|
return TRUE;
|
|
|
|
|
2004-10-29 11:52:25 +02:00
|
|
|
message(G_LOG_LEVEL_CRITICAL, "Unknown consent value: %s", consent);
|
2004-10-27 11:49:13 +02:00
|
|
|
/* we consider consent as empty if its value is unknown/invalid */
|
|
|
|
return TRUE;
|
2004-10-01 16:15:01 +02:00
|
|
|
}
|
|
|
|
|
2004-09-30 19:12:23 +02:00
|
|
|
/**
|
|
|
|
* lasso_login_process_federation:
|
2004-12-31 11:51:17 +01:00
|
|
|
* @login: a #LassoLogin
|
|
|
|
* @is_consent_obtained: whether user consent has been obtained
|
|
|
|
*
|
|
|
|
* Return value: 0 on success; or a negative value otherwise.
|
2004-09-30 19:12:23 +02:00
|
|
|
**/
|
2004-07-14 14:53:11 +02:00
|
|
|
static gint
|
2004-10-27 11:49:13 +02:00
|
|
|
lasso_login_process_federation(LassoLogin *login, gboolean is_consent_obtained)
|
2004-07-06 19:20:48 +02:00
|
|
|
{
|
2004-10-27 11:49:13 +02:00
|
|
|
LassoFederation *federation = NULL;
|
2007-01-04 00:35:17 +01:00
|
|
|
LassoProfile *profile;
|
2004-10-29 12:07:52 +02:00
|
|
|
char *nameIDPolicy;
|
2004-10-27 11:49:13 +02:00
|
|
|
gint ret = 0;
|
|
|
|
|
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
|
|
|
|
2007-01-04 00:35:17 +01:00
|
|
|
profile = LASSO_PROFILE(login);
|
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
/* verify if identity already exists else create it */
|
|
|
|
if (profile->identity == NULL) {
|
|
|
|
profile->identity = lasso_identity_new();
|
|
|
|
}
|
2004-10-29 12:07:52 +02:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
/* get nameIDPolicy in lib:AuthnRequest */
|
|
|
|
nameIDPolicy = LASSO_LIB_AUTHN_REQUEST(profile->request)->NameIDPolicy;
|
2004-10-29 12:07:52 +02:00
|
|
|
if (nameIDPolicy == NULL)
|
|
|
|
nameIDPolicy = LASSO_LIB_NAMEID_POLICY_TYPE_NONE;
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_string(login->nameIDPolicy, nameIDPolicy);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
/* if nameIDPolicy is 'onetime' => nothing to do */
|
2004-10-29 12:07:52 +02:00
|
|
|
if (strcmp(nameIDPolicy, LASSO_LIB_NAMEID_POLICY_TYPE_ONE_TIME) == 0) {
|
|
|
|
return 0;
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* search a federation in the identity */
|
2007-01-04 00:35:17 +01:00
|
|
|
federation = g_hash_table_lookup(profile->identity->federations,
|
|
|
|
profile->remote_providerID);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2004-10-29 12:07:52 +02:00
|
|
|
if (strcmp(nameIDPolicy, LASSO_LIB_NAMEID_POLICY_TYPE_NONE) == 0) {
|
2004-10-27 11:49:13 +02:00
|
|
|
/* a federation MUST exist */
|
|
|
|
if (federation == NULL) {
|
2004-10-29 12:07:52 +02:00
|
|
|
/* if protocolProfile is LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST
|
|
|
|
* set StatusCode to FederationDoesNotExist in lib:AuthnResponse
|
2004-10-27 11:49:13 +02:00
|
|
|
*/
|
2004-12-29 12:00:20 +01:00
|
|
|
lasso_profile_set_response_status(LASSO_PROFILE(login),
|
|
|
|
LASSO_LIB_STATUS_CODE_FEDERATION_DOES_NOT_EXIST);
|
2004-10-29 12:07:52 +02:00
|
|
|
return LASSO_LOGIN_ERROR_FEDERATION_NOT_FOUND;
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
2004-10-29 12:07:52 +02:00
|
|
|
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_gobject(LASSO_PROFILE(login)->nameIdentifier,
|
2004-12-18 19:36:54 +01:00
|
|
|
LASSO_SAML_NAME_IDENTIFIER(federation->local_nameIdentifier));
|
2004-10-29 12:07:52 +02:00
|
|
|
return 0;
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2004-10-29 12:07:52 +02:00
|
|
|
if (strcmp(nameIDPolicy, LASSO_LIB_NAMEID_POLICY_TYPE_FEDERATED) != 0 &&
|
|
|
|
strcmp(nameIDPolicy, LASSO_LIB_NAMEID_POLICY_TYPE_ANY) != 0) {
|
2005-02-05 17:15:53 +01:00
|
|
|
return critical_error(LASSO_LOGIN_ERROR_INVALID_NAMEIDPOLICY);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
2004-10-29 12:07:52 +02:00
|
|
|
|
|
|
|
/* consent is necessary, it should be obtained via consent attribute
|
|
|
|
* in lib:AuthnRequest or IDP should ask the Principal
|
|
|
|
*/
|
|
|
|
if (lasso_login_must_ask_for_consent_private(login) && !is_consent_obtained) {
|
|
|
|
if (strcmp(nameIDPolicy, LASSO_LIB_NAMEID_POLICY_TYPE_ANY) == 0) {
|
|
|
|
/* if the NameIDPolicy element is 'any' and if the policy
|
|
|
|
* for the Principal forbids federation, then evaluation
|
|
|
|
* MAY proceed as if the value was 'onetime'.
|
|
|
|
*/
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_string(login->nameIDPolicy, LASSO_LIB_NAMEID_POLICY_TYPE_ONE_TIME);
|
2004-10-29 12:07:52 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2008-09-12 17:06:58 +02:00
|
|
|
|
2004-10-29 12:07:52 +02:00
|
|
|
/* if protocolProfile is LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST
|
|
|
|
* set StatusCode to FederationDoesNotExist in lib:AuthnResponse
|
|
|
|
*/
|
|
|
|
/* FIXME : is it the correct value for the StatusCode ? */
|
2004-12-29 12:00:20 +01:00
|
|
|
lasso_profile_set_response_status(LASSO_PROFILE(login),
|
|
|
|
LASSO_LIB_STATUS_CODE_FEDERATION_DOES_NOT_EXIST);
|
2004-10-29 12:07:52 +02:00
|
|
|
return LASSO_LOGIN_ERROR_CONSENT_NOT_OBTAINED;
|
2004-09-30 19:12:23 +02:00
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2004-10-29 12:07:52 +02:00
|
|
|
if (federation == NULL) {
|
|
|
|
federation = lasso_federation_new(LASSO_PROFILE(login)->remote_providerID);
|
2004-12-22 22:38:06 +01:00
|
|
|
lasso_federation_build_local_name_identifier(federation,
|
2004-10-29 12:07:52 +02:00
|
|
|
LASSO_PROVIDER(LASSO_PROFILE(login)->server)->ProviderID,
|
|
|
|
LASSO_LIB_NAME_IDENTIFIER_FORMAT_FEDERATED,
|
|
|
|
NULL);
|
|
|
|
lasso_identity_add_federation(LASSO_PROFILE(login)->identity, federation);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_gobject(LASSO_PROFILE(login)->nameIdentifier,
|
|
|
|
LASSO_SAML_NAME_IDENTIFIER(federation->local_nameIdentifier));
|
2004-10-29 12:07:52 +02:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
return ret;
|
2004-07-06 19:20:48 +02:00
|
|
|
}
|
|
|
|
|
2004-07-14 14:53:11 +02:00
|
|
|
static gint
|
2004-10-29 12:10:03 +02:00
|
|
|
lasso_login_process_response_status_and_assertion(LassoLogin *login)
|
|
|
|
{
|
|
|
|
LassoProvider *idp;
|
2004-10-27 11:49:13 +02:00
|
|
|
LassoSamlpResponse *response;
|
|
|
|
char *status_value;
|
2007-12-05 11:48:49 +01:00
|
|
|
LassoSamlSubjectStatementAbstract *sssa = NULL;
|
|
|
|
LassoSamlSubjectStatementAbstract *sas = NULL;
|
2009-01-24 10:34:00 +01:00
|
|
|
int rc = 0;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
|
|
|
|
|
|
|
response = LASSO_SAMLP_RESPONSE(LASSO_PROFILE(login)->response);
|
|
|
|
|
2008-09-12 17:06:58 +02:00
|
|
|
if (response->Status == NULL || ! LASSO_IS_SAMLP_STATUS(response->Status) ||
|
2004-12-31 14:23:08 +01:00
|
|
|
response->Status->StatusCode == NULL ||
|
|
|
|
response->Status->StatusCode->Value == NULL) {
|
2006-10-28 13:40:24 +02:00
|
|
|
return LASSO_PROFILE_ERROR_MISSING_STATUS_CODE;
|
2004-12-31 14:23:08 +01:00
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
status_value = response->Status->StatusCode->Value;
|
|
|
|
if (status_value && strcmp(status_value, LASSO_SAML_STATUS_CODE_SUCCESS) != 0) {
|
2004-12-28 14:59:39 +01:00
|
|
|
if (strcmp(status_value, LASSO_SAML_STATUS_CODE_REQUEST_DENIED) == 0)
|
|
|
|
return LASSO_LOGIN_ERROR_REQUEST_DENIED;
|
2005-03-07 16:59:27 +01:00
|
|
|
if (strcmp(status_value, LASSO_SAML_STATUS_CODE_RESPONDER) == 0) {
|
|
|
|
/* samlp:Responder */
|
|
|
|
if (response->Status->StatusCode->StatusCode &&
|
|
|
|
response->Status->StatusCode->StatusCode->Value) {
|
|
|
|
status_value = response->Status->StatusCode->StatusCode->Value;
|
|
|
|
if (strcmp(status_value,
|
|
|
|
LASSO_LIB_STATUS_CODE_FEDERATION_DOES_NOT_EXIST) == 0) {
|
|
|
|
return LASSO_LOGIN_ERROR_FEDERATION_NOT_FOUND;
|
|
|
|
}
|
2005-08-10 13:29:52 +02:00
|
|
|
if (strcmp(status_value,
|
|
|
|
LASSO_LIB_STATUS_CODE_UNKNOWN_PRINCIPAL) == 0) {
|
|
|
|
return LASSO_LOGIN_ERROR_UNKNOWN_PRINCIPAL;
|
|
|
|
}
|
2005-03-07 16:59:27 +01:00
|
|
|
}
|
|
|
|
}
|
2004-12-28 17:26:31 +01:00
|
|
|
return LASSO_LOGIN_ERROR_STATUS_NOT_SUCCESS;
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (response->Assertion) {
|
|
|
|
LassoProfile *profile = LASSO_PROFILE(login);
|
2005-01-08 18:22:09 +01:00
|
|
|
LassoSamlAssertion *assertion = response->Assertion->data;
|
2009-03-03 21:52:45 +01:00
|
|
|
LassoLibAssertion *lib_assertion = NULL;
|
|
|
|
|
|
|
|
if (LASSO_IS_LIB_ASSERTION(assertion)) {
|
|
|
|
lib_assertion = LASSO_LIB_ASSERTION(assertion);
|
|
|
|
}
|
|
|
|
|
2009-10-30 15:47:23 +01:00
|
|
|
idp = lasso_server_get_provider(profile->server, profile->remote_providerID);
|
2006-05-10 10:00:45 +02:00
|
|
|
if (idp == NULL) {
|
2006-12-28 00:55:07 +01:00
|
|
|
return LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND;
|
2006-05-10 10:00:45 +02:00
|
|
|
}
|
2009-03-03 21:52:45 +01:00
|
|
|
|
|
|
|
/* Validate AuthnRequest RequestID and InResponseTo */
|
|
|
|
{
|
|
|
|
char *previous_reqid = login->private_data->request_id;
|
|
|
|
if (previous_reqid) {
|
|
|
|
if (lib_assertion == NULL ||
|
|
|
|
lib_assertion->InResponseTo == NULL ||
|
|
|
|
strcmp(lib_assertion->InResponseTo, previous_reqid) != 0) {
|
|
|
|
return critical_error(LASSO_LOGIN_ERROR_ASSERTION_DOES_NOT_MATCH_REQUEST_ID);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-24 10:34:00 +01:00
|
|
|
/* If the status of the signature verification process is not 0, we try to verify on
|
|
|
|
* the assertion */
|
|
|
|
if (profile->signature_status != 0) {
|
|
|
|
xmlNode *assertion_xmlnode;
|
|
|
|
gchar *assertion_issuer;
|
|
|
|
|
|
|
|
assertion_xmlnode = lasso_node_get_original_xmlnode(LASSO_NODE(assertion));
|
|
|
|
assertion_issuer = (gchar*)xmlGetProp(assertion_xmlnode, (xmlChar*)"Issuer");
|
2009-04-23 01:49:29 +02:00
|
|
|
goto_cleanup_if_fail_with_rc(assertion_issuer, LASSO_PROFILE_ERROR_MISSING_ISSUER);
|
|
|
|
goto_cleanup_if_fail_with_rc(strcmp(assertion_issuer, profile->remote_providerID) == 0,
|
2009-01-24 10:34:00 +01:00
|
|
|
LASSO_PROFILE_ERROR_INVALID_ISSUER);
|
|
|
|
|
|
|
|
if (assertion_xmlnode) {
|
2009-03-27 16:04:58 +01:00
|
|
|
profile->signature_status = lasso_provider_verify_saml_signature(idp, assertion_xmlnode, NULL);
|
2009-04-23 01:49:29 +02:00
|
|
|
goto_cleanup_if_fail_with_rc(profile->signature_status == 0, profile->signature_status);
|
2009-01-24 10:34:00 +01:00
|
|
|
}
|
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2009-03-27 16:04:55 +01:00
|
|
|
lasso_release_gobject(profile->nameIdentifier);
|
|
|
|
|
|
|
|
/* Retrieve the name identifier from one of the statements */
|
2006-03-21 10:01:24 +01:00
|
|
|
if (assertion->AuthenticationStatement) {
|
|
|
|
sssa = LASSO_SAML_SUBJECT_STATEMENT_ABSTRACT(
|
|
|
|
assertion->AuthenticationStatement);
|
|
|
|
if (sssa->Subject && sssa->Subject->NameIdentifier) {
|
2009-03-27 16:04:55 +01:00
|
|
|
lasso_assign_gobject(profile->nameIdentifier,
|
|
|
|
LASSO_NODE(sssa->Subject->NameIdentifier));
|
2006-03-21 10:01:24 +01:00
|
|
|
}
|
2004-12-02 15:54:43 +01:00
|
|
|
}
|
|
|
|
|
2009-03-27 16:04:55 +01:00
|
|
|
if (profile->nameIdentifier == NULL && assertion->AttributeStatement) {
|
2006-05-10 10:00:45 +02:00
|
|
|
sas = LASSO_SAML_SUBJECT_STATEMENT_ABSTRACT(assertion->AttributeStatement);
|
|
|
|
if (sas->Subject && sas->Subject->NameIdentifier) {
|
2009-03-27 16:04:55 +01:00
|
|
|
lasso_assign_gobject(profile->nameIdentifier,
|
|
|
|
LASSO_NODE(sas->Subject->NameIdentifier));
|
2006-03-21 10:01:24 +01:00
|
|
|
}
|
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2006-05-10 10:00:45 +02:00
|
|
|
if (profile->nameIdentifier == NULL) {
|
2006-12-28 00:55:07 +01:00
|
|
|
return LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND;
|
2006-05-10 10:00:45 +02:00
|
|
|
}
|
2009-03-27 16:04:55 +01:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
2009-04-23 01:49:29 +02:00
|
|
|
cleanup:
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2009-01-24 10:34:00 +01:00
|
|
|
return rc;
|
2004-07-06 19:20:48 +02:00
|
|
|
}
|
|
|
|
|
2004-07-06 03:07:32 +02:00
|
|
|
/*****************************************************************************/
|
2004-10-27 11:49:13 +02:00
|
|
|
/* public methods */
|
2004-07-06 03:07:32 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
2004-08-19 14:51:25 +02:00
|
|
|
/**
|
|
|
|
* lasso_login_accept_sso:
|
2004-12-31 11:51:17 +01:00
|
|
|
* @login: a #LassoLogin
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2010-03-27 18:39:57 +01:00
|
|
|
* Gets the assertion of the response and adds it to the #LassoSession object.
|
2004-08-19 14:51:25 +02:00
|
|
|
* Builds a federation with the 2 name identifiers of the assertion
|
|
|
|
* and adds it into the identity.
|
|
|
|
* If the session or the identity are NULL, they are created.
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2009-04-27 10:19:04 +02:00
|
|
|
* Return value: 0 on success; or
|
2010-03-27 18:39:57 +01:00
|
|
|
* <itemizedlist>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if login is not a #LassoLogin object,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
2010-04-06 15:11:00 +02:00
|
|
|
* #LASSO_PROFILE_ERROR_MISSING_RESPONSE if no response is present in the login profile object;
|
|
|
|
* usually because no call to lasso_login_process_authn_response_msg was done;
|
2010-03-27 18:39:57 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_PROFILE_ERROR_MISSING_ASSERTION if the response does not contain an assertion,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND if the assertion does not contain a NameID element,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_PROFILE_ERROR_MISSING_NAME_IDENTIFIER same as
|
|
|
|
* #LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_LOGIN_ERROR_ASSERTION_REPLAY if the assertion has already been used.
|
|
|
|
* </para></listitem>
|
2010-04-19 13:30:35 +02:00
|
|
|
* </itemizedlist>
|
2004-08-19 14:51:25 +02:00
|
|
|
**/
|
2004-07-30 17:31:03 +02:00
|
|
|
gint
|
|
|
|
lasso_login_accept_sso(LassoLogin *login)
|
|
|
|
{
|
2004-10-27 11:49:13 +02:00
|
|
|
LassoProfile *profile;
|
2004-10-29 12:13:18 +02:00
|
|
|
LassoSamlAssertion *assertion;
|
2004-12-15 14:26:31 +01:00
|
|
|
LassoSamlNameIdentifier *ni, *idp_ni = NULL;
|
2004-10-29 12:13:18 +02:00
|
|
|
LassoFederation *federation;
|
|
|
|
LassoSamlSubjectStatementAbstract *authentication_statement;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
|
|
|
|
|
|
|
profile = LASSO_PROFILE(login);
|
|
|
|
|
|
|
|
if (profile->identity == NULL)
|
2008-09-12 17:06:58 +02:00
|
|
|
profile->identity = lasso_identity_new();
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
if (profile->session == NULL)
|
|
|
|
profile->session = lasso_session_new();
|
|
|
|
|
|
|
|
if (profile->response == NULL)
|
2006-12-28 00:55:07 +01:00
|
|
|
return LASSO_PROFILE_ERROR_MISSING_RESPONSE;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2005-11-21 19:51:52 +01:00
|
|
|
IF_SAML2(profile) {
|
2005-11-20 16:38:19 +01:00
|
|
|
return lasso_saml20_login_accept_sso(login);
|
|
|
|
}
|
|
|
|
|
2005-01-08 18:22:09 +01:00
|
|
|
if (LASSO_SAMLP_RESPONSE(profile->response)->Assertion == NULL)
|
2006-12-28 00:55:07 +01:00
|
|
|
return LASSO_PROFILE_ERROR_MISSING_ASSERTION;
|
2005-01-08 18:22:09 +01:00
|
|
|
|
|
|
|
assertion = LASSO_SAMLP_RESPONSE(profile->response)->Assertion->data;
|
2004-10-27 11:49:13 +02:00
|
|
|
if (assertion == NULL)
|
2006-12-28 00:55:07 +01:00
|
|
|
return LASSO_PROFILE_ERROR_MISSING_ASSERTION;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2008-02-18 14:11:33 +01:00
|
|
|
lasso_session_add_assertion(profile->session, profile->remote_providerID,
|
|
|
|
LASSO_NODE(assertion));
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
authentication_statement = LASSO_SAML_SUBJECT_STATEMENT_ABSTRACT(
|
2005-01-08 18:22:09 +01:00
|
|
|
assertion->AuthenticationStatement);
|
2007-01-04 00:35:17 +01:00
|
|
|
if (authentication_statement->Subject == NULL)
|
|
|
|
return LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND;
|
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
ni = authentication_statement->Subject->NameIdentifier;
|
|
|
|
|
|
|
|
if (ni == NULL)
|
2006-12-28 00:55:07 +01:00
|
|
|
return LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
if (LASSO_IS_LIB_SUBJECT(authentication_statement->Subject)) {
|
2004-10-29 12:13:18 +02:00
|
|
|
idp_ni = LASSO_LIB_SUBJECT(
|
|
|
|
authentication_statement->Subject)->IDPProvidedNameIdentifier;
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* create federation, only if nameidentifier format is Federated */
|
2008-06-05 17:46:42 +02:00
|
|
|
if (ni->Format && strcmp(ni->Format, LASSO_LIB_NAME_IDENTIFIER_FORMAT_FEDERATED) == 0) {
|
2004-10-27 11:49:13 +02:00
|
|
|
federation = lasso_federation_new(LASSO_PROFILE(login)->remote_providerID);
|
|
|
|
if (ni != NULL && idp_ni != NULL) {
|
2004-10-29 12:13:18 +02:00
|
|
|
federation->local_nameIdentifier = g_object_ref(ni);
|
|
|
|
federation->remote_nameIdentifier = g_object_ref(idp_ni);
|
2004-10-27 11:49:13 +02:00
|
|
|
} else {
|
2004-10-29 12:13:18 +02:00
|
|
|
federation->remote_nameIdentifier = g_object_ref(ni);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
/* add federation in identity */
|
|
|
|
lasso_identity_add_federation(LASSO_PROFILE(login)->identity, federation);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2004-07-30 17:31:03 +02:00
|
|
|
}
|
|
|
|
|
2005-01-28 16:57:56 +01:00
|
|
|
static void
|
|
|
|
lasso_login_build_assertion_artifact(LassoLogin *login)
|
|
|
|
{
|
|
|
|
xmlSecByte samlArt[42], *b64_samlArt;
|
2005-07-31 00:36:54 +02:00
|
|
|
char *identityProviderSuccinctID;
|
2005-01-28 16:57:56 +01:00
|
|
|
|
|
|
|
identityProviderSuccinctID = lasso_sha1(
|
|
|
|
LASSO_PROVIDER(LASSO_PROFILE(login)->server)->ProviderID);
|
|
|
|
|
|
|
|
/* Artifact Format is described in "Binding Profiles", 3.2.2.2. */
|
|
|
|
memcpy(samlArt, "\000\003", 2); /* type code */
|
|
|
|
memcpy(samlArt+2, identityProviderSuccinctID, 20);
|
2005-07-31 00:36:54 +02:00
|
|
|
lasso_build_random_sequence((char*)samlArt+22, 20);
|
2005-01-28 16:57:56 +01:00
|
|
|
|
|
|
|
xmlFree(identityProviderSuccinctID);
|
|
|
|
b64_samlArt = xmlSecBase64Encode(samlArt, 42, 0);
|
|
|
|
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_string(login->assertionArtifact, (char*)b64_samlArt);
|
|
|
|
lasso_release_xml_string(b64_samlArt);
|
2005-01-28 16:57:56 +01:00
|
|
|
}
|
|
|
|
|
2004-08-19 14:51:25 +02:00
|
|
|
/**
|
|
|
|
* lasso_login_build_artifact_msg:
|
2004-12-31 11:51:17 +01:00
|
|
|
* @login: a #LassoLogin
|
2004-08-21 03:20:13 +02:00
|
|
|
* @http_method: the HTTP method to send the artifact (REDIRECT or POST)
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2004-12-31 11:51:17 +01:00
|
|
|
* Builds a SAML artifact. Depending of the HTTP method, the data for the sending of
|
2005-01-21 11:51:24 +01:00
|
|
|
* the artifact are stored in @msg_url (REDIRECT) or @msg_url, @msg_body and
|
|
|
|
* @msg_relayState (POST).
|
2004-10-27 11:49:13 +02:00
|
|
|
*
|
2009-04-27 10:19:06 +02:00
|
|
|
* Return value: 0 on success; or
|
2010-03-27 18:40:00 +01:00
|
|
|
* <itemizedlist>
|
|
|
|
* <listitem><para>
|
2009-04-27 10:19:06 +02:00
|
|
|
* LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if login is not a #LassoLogin object,
|
2010-03-27 18:40:00 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
2009-04-27 10:19:06 +02:00
|
|
|
* LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID if no remote provider ID was setup in the login
|
2010-03-27 18:40:00 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
2009-04-27 10:19:06 +02:00
|
|
|
* profile object, it's usually done by lasso_login_process_authn_request_msg,
|
2010-03-27 18:40:00 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
2009-04-27 10:19:06 +02:00
|
|
|
* LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD if the HTTP method is neither LASSO_HTTP_METHOD_REDIRECT
|
2010-03-27 18:40:00 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
2009-04-27 10:19:06 +02:00
|
|
|
* or LASSO_HTTP_METHOD_POST (ID-FF 1.2 case) or neither LASSO_HTTP_METHOD_ARTIFACT_GET or
|
2010-03-27 18:40:00 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
2009-04-27 10:19:06 +02:00
|
|
|
* LASSO_HTTP_METHOD_ARTIFACT_POST (SAML 2.0 case) for SAML 2.0),
|
2010-03-27 18:40:00 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
2009-04-27 10:19:06 +02:00
|
|
|
* LASSO_PROFILE_ERROR_INVALID_PROTOCOLPROFILE if the current protocolProfile is not
|
2010-03-27 18:40:00 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
2009-04-27 10:19:06 +02:00
|
|
|
* LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART (only for ID-FF 1.2),
|
2010-03-27 18:40:00 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND if the remote provider is not known to our server object
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* which impeach us to find a service endpoint,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* LASSO_PROFILE_ERROR_MISSING_RESPONSE if the response object is missing,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* LASSO_PROFILE_ERROR_MISSING_STATUS_CODE if the response object is missing a status code,
|
|
|
|
* </para></listitem>
|
|
|
|
*</itemizedlist>
|
2009-04-27 10:19:06 +02:00
|
|
|
*
|
2004-08-19 14:51:25 +02:00
|
|
|
**/
|
2004-07-06 03:07:32 +02:00
|
|
|
gint
|
2004-12-31 19:33:23 +01:00
|
|
|
lasso_login_build_artifact_msg(LassoLogin *login, LassoHttpMethod http_method)
|
2004-07-06 03:07:32 +02:00
|
|
|
{
|
2004-10-27 11:49:13 +02:00
|
|
|
LassoProvider *remote_provider;
|
2004-12-24 11:04:37 +01:00
|
|
|
LassoProfile *profile;
|
2004-10-27 11:49:13 +02:00
|
|
|
gchar *url;
|
2005-07-31 00:36:54 +02:00
|
|
|
xmlChar *b64_samlArt;
|
|
|
|
char *relayState;
|
2004-10-27 11:49:13 +02:00
|
|
|
gint ret = 0;
|
|
|
|
|
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
|
|
|
|
2005-11-20 16:38:19 +01:00
|
|
|
profile = LASSO_PROFILE(login);
|
2007-01-05 14:40:07 +01:00
|
|
|
lasso_profile_clean_msg_info(profile);
|
2005-11-20 16:38:19 +01:00
|
|
|
|
2006-01-23 16:30:00 +01:00
|
|
|
if (profile->remote_providerID == NULL) {
|
2007-01-08 14:13:49 +01:00
|
|
|
/* this means lasso_login_init_request was not called before */
|
2006-01-23 16:30:00 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID);
|
|
|
|
}
|
|
|
|
|
2005-11-21 19:51:52 +01:00
|
|
|
IF_SAML2(profile) {
|
2005-11-20 16:38:19 +01:00
|
|
|
return lasso_saml20_login_build_artifact_msg(login, http_method);
|
|
|
|
}
|
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
if (http_method != LASSO_HTTP_METHOD_REDIRECT && http_method != LASSO_HTTP_METHOD_POST) {
|
2004-12-14 16:46:25 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ProtocolProfile must be BrwsArt */
|
|
|
|
if (login->protocolProfile != LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART) {
|
2004-12-14 16:46:25 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_INVALID_PROTOCOLPROFILE);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* build artifact infos */
|
2009-10-30 15:47:23 +01:00
|
|
|
remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
|
2005-01-21 23:02:56 +01:00
|
|
|
if (LASSO_IS_PROVIDER(remote_provider) == FALSE)
|
2005-02-05 17:15:53 +01:00
|
|
|
return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
|
2005-01-21 22:56:34 +01:00
|
|
|
|
2004-12-24 11:04:37 +01:00
|
|
|
url = lasso_provider_get_assertion_consumer_service_url(remote_provider,
|
|
|
|
LASSO_LIB_AUTHN_REQUEST(profile->request)->AssertionConsumerServiceID);
|
2004-12-14 22:41:57 +01:00
|
|
|
if (url == NULL) {
|
2005-03-24 15:18:53 +01:00
|
|
|
/* from draft-liberty-idff-protocols-schema-1.2-errata-v2.0.pdf
|
|
|
|
* paragraph starting line 768,
|
|
|
|
*
|
|
|
|
* If the <AssertionConsumerServiceID> element is provided,
|
|
|
|
* then the identity provider MUST search for the value among
|
|
|
|
* the id attributes in the <AssertionConsumerServiceURL>
|
|
|
|
* elements in the provider's metadata to determine the URL
|
|
|
|
* to use. If no match can be found, then the provider MUST
|
|
|
|
* return an error with a second-level <samlp:StatusCode> of
|
|
|
|
* lib:InvalidAssertionConsumerServiceIndex to the default URL
|
|
|
|
*/
|
|
|
|
lasso_profile_set_response_status(profile,
|
|
|
|
LASSO_LIB_STATUS_CODE_INVALID_ASSERTION_CONSUMER_SERVICE_INDEX);
|
|
|
|
url = lasso_provider_get_assertion_consumer_service_url(
|
|
|
|
remote_provider, NULL);
|
2004-12-14 22:41:57 +01:00
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2005-01-28 16:57:56 +01:00
|
|
|
/* it may have been created in lasso_login_build_assertion */
|
|
|
|
if (login->assertionArtifact == NULL)
|
|
|
|
lasso_login_build_assertion_artifact(login);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2005-04-25 16:25:03 +02:00
|
|
|
if (login->assertion) {
|
|
|
|
LassoSamlAssertion *assertion = login->assertion;
|
|
|
|
LassoSamlSubjectStatementAbstract *ss;
|
|
|
|
|
|
|
|
ss = LASSO_SAML_SUBJECT_STATEMENT_ABSTRACT(assertion->AuthenticationStatement);
|
2006-11-02 11:48:31 +01:00
|
|
|
/* Subject and SubjectConfirmation should never be NULL
|
|
|
|
* because they're built by Lasso
|
|
|
|
*/
|
|
|
|
if (ss->Subject != NULL && ss->Subject->SubjectConfirmation != NULL) {
|
|
|
|
if (assertion->MajorVersion == 1 && assertion->MinorVersion == 0) {
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_list_add_string(ss->Subject->SubjectConfirmation->ConfirmationMethod,
|
|
|
|
LASSO_SAML_CONFIRMATION_METHOD_ARTIFACT01);
|
2006-11-02 11:48:31 +01:00
|
|
|
} else {
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_list_add_string(ss->Subject->SubjectConfirmation->ConfirmationMethod,
|
|
|
|
LASSO_SAML_CONFIRMATION_METHOD_ARTIFACT);
|
2006-11-02 11:48:31 +01:00
|
|
|
}
|
2005-04-25 16:25:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-07-31 00:36:54 +02:00
|
|
|
b64_samlArt = xmlStrdup((xmlChar*)login->assertionArtifact);
|
|
|
|
relayState = (char*)xmlURIEscapeStr(
|
|
|
|
(xmlChar*)LASSO_LIB_AUTHN_REQUEST(profile->request)->RelayState, NULL);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2004-10-29 12:25:59 +02:00
|
|
|
if (http_method == LASSO_HTTP_METHOD_REDIRECT) {
|
2005-01-04 16:40:37 +01:00
|
|
|
xmlChar *escaped_artifact = xmlURIEscapeStr(b64_samlArt, NULL);
|
2006-11-07 13:44:32 +01:00
|
|
|
gchar *query;
|
|
|
|
|
2004-10-29 12:25:59 +02:00
|
|
|
if (relayState == NULL) {
|
2006-11-07 13:44:32 +01:00
|
|
|
query = g_strdup_printf("SAMLart=%s", escaped_artifact);
|
2004-10-29 12:25:59 +02:00
|
|
|
} else {
|
2008-09-12 17:06:58 +02:00
|
|
|
query = g_strdup_printf("SAMLart=%s&RelayState=%s",
|
2006-11-07 13:44:32 +01:00
|
|
|
escaped_artifact, relayState);
|
2004-10-29 12:25:59 +02:00
|
|
|
}
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_string(profile->msg_url, lasso_concat_url_query(url, query));
|
|
|
|
lasso_release_string(query);
|
2006-11-07 13:44:32 +01:00
|
|
|
|
2005-01-04 16:40:37 +01:00
|
|
|
xmlFree(escaped_artifact);
|
2004-10-29 12:25:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (http_method == LASSO_HTTP_METHOD_POST) {
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_string(profile->msg_url, url);
|
|
|
|
lasso_assign_string(profile->msg_body, (char*)b64_samlArt);
|
2004-10-29 12:25:59 +02:00
|
|
|
if (relayState != NULL) {
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_string(profile->msg_relayState, relayState);
|
2004-10-29 12:25:59 +02:00
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_release_string(url);
|
2004-10-27 11:49:13 +02:00
|
|
|
xmlFree(b64_samlArt);
|
2004-10-29 12:25:59 +02:00
|
|
|
xmlFree(relayState);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2005-03-22 18:12:32 +01:00
|
|
|
if (strcmp(LASSO_SAMLP_RESPONSE(profile->response)->Status->StatusCode->Value,
|
2007-01-04 00:35:17 +01:00
|
|
|
LASSO_SAML_STATUS_CODE_SUCCESS) != 0) {
|
2005-03-22 18:12:32 +01:00
|
|
|
if (profile->session == NULL)
|
|
|
|
profile->session = lasso_session_new();
|
2004-12-29 18:25:56 +01:00
|
|
|
|
|
|
|
lasso_session_add_status(profile->session, profile->remote_providerID,
|
|
|
|
g_object_ref(LASSO_SAMLP_RESPONSE(profile->response)->Status));
|
2005-05-17 21:38:47 +02:00
|
|
|
} else {
|
|
|
|
lasso_session_remove_status(profile->session, profile->remote_providerID);
|
2004-12-29 18:25:56 +01:00
|
|
|
}
|
2004-12-29 12:00:20 +01:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
return ret;
|
2004-07-06 19:20:48 +02:00
|
|
|
}
|
|
|
|
|
2004-08-19 14:51:25 +02:00
|
|
|
/**
|
|
|
|
* lasso_login_build_authn_request_msg:
|
2004-12-31 11:51:17 +01:00
|
|
|
* @login: a #LassoLogin
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2009-04-27 10:19:08 +02:00
|
|
|
* Converts profile authentication request (@request member) into a Liberty message, either an URL
|
|
|
|
* in HTTP-Redirect profile or an URL and a field value in Browser-POST (form) profile.
|
2004-12-31 11:51:17 +01:00
|
|
|
*
|
2009-04-27 10:19:08 +02:00
|
|
|
* The URL is set into the @msg_url member and the eventual field value (LAREQ) is set into the
|
|
|
|
* @msg_body member.
|
|
|
|
*
|
|
|
|
* Return value: 0 on success; or
|
2010-03-27 18:40:01 +01:00
|
|
|
* <itemizedlist>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if login is not a #LassoLogin object,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
2010-04-19 13:30:35 +02:00
|
|
|
* #LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID if not remote provider ID was setup&160;- it usually
|
2010-03-27 18:40:01 +01:00
|
|
|
* means that lasso_login_init_request() was not called before,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND if the remote provider ID is not registered in the server
|
2009-04-27 10:19:08 +02:00
|
|
|
* object,
|
2010-03-27 18:40:01 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE if the SSO profile is not supported by the targeted
|
2009-04-27 10:19:08 +02:00
|
|
|
* provider,
|
2010-03-27 18:40:01 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED if the building of the query part of the redirect URL
|
2010-04-19 13:30:35 +02:00
|
|
|
* or of the body of the POST content failed&160;- it only happens with the #LASSO_HTTP_METHOD_REDIRECT,
|
2010-03-27 18:40:01 +01:00
|
|
|
* #LASSO_HTTP_METHOD_POST, #LASSO_HTTP_METHOD_ARTIFACT_GET and
|
2010-04-19 13:30:35 +02:00
|
|
|
* #LASSO_HTTP_METHOD_ARTIFACT_POST bindings&160;-,
|
2010-03-27 18:40:01 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL if the metadata of the remote provider does not contain
|
|
|
|
* an url for the SSO profile,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_PROFILE_ERROR_INVALID_REQUEST if the request object is not of the needed type, is usually
|
|
|
|
* means that lasso_login_init_request() was not called before,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_PROFILE_MISSING_REQUEST if the request object is missing,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* #LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD if the current setted @http_method on the #LassoLogin
|
|
|
|
* object is invalid.
|
|
|
|
* </para></listitem>
|
|
|
|
* </itemizedlist>
|
2004-08-19 14:51:25 +02:00
|
|
|
**/
|
2004-07-08 03:33:39 +02:00
|
|
|
gint
|
2004-12-14 11:20:07 +01:00
|
|
|
lasso_login_build_authn_request_msg(LassoLogin *login)
|
2004-07-08 03:33:39 +02:00
|
|
|
{
|
2004-10-27 11:49:13 +02:00
|
|
|
LassoProvider *provider, *remote_provider;
|
2004-12-28 13:44:22 +01:00
|
|
|
LassoProfile *profile;
|
2004-10-29 13:16:38 +02:00
|
|
|
char *md_authnRequestsSigned, *url, *query, *lareq, *protocolProfile;
|
2006-05-16 10:10:56 +02:00
|
|
|
LassoProviderRole role, remote_role;
|
2004-10-27 11:49:13 +02:00
|
|
|
gboolean must_sign;
|
|
|
|
gint ret = 0;
|
|
|
|
|
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
2004-12-28 13:44:22 +01:00
|
|
|
profile = LASSO_PROFILE(login);
|
2007-01-05 14:40:07 +01:00
|
|
|
lasso_profile_clean_msg_info(profile);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2006-01-23 16:30:00 +01:00
|
|
|
if (profile->remote_providerID == NULL) {
|
2007-01-08 14:13:49 +01:00
|
|
|
/* this means lasso_login_init_request was not called before */
|
2006-01-23 16:30:00 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID);
|
|
|
|
}
|
|
|
|
|
2004-12-28 13:44:22 +01:00
|
|
|
provider = LASSO_PROVIDER(profile->server);
|
2009-10-30 15:47:23 +01:00
|
|
|
remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
|
2004-12-13 18:46:29 +01:00
|
|
|
if (LASSO_IS_PROVIDER(remote_provider) == FALSE) {
|
2005-02-05 17:15:53 +01:00
|
|
|
return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2005-11-21 19:51:52 +01:00
|
|
|
IF_SAML2(profile) {
|
2010-01-12 16:39:48 +01:00
|
|
|
return lasso_saml20_login_build_authn_request_msg(login);
|
2005-11-20 16:38:19 +01:00
|
|
|
}
|
|
|
|
|
2004-12-28 13:44:22 +01:00
|
|
|
protocolProfile = LASSO_LIB_AUTHN_REQUEST(profile->request)->ProtocolProfile;
|
2004-10-29 13:16:38 +02:00
|
|
|
if (protocolProfile == NULL)
|
|
|
|
protocolProfile = LASSO_LIB_PROTOCOL_PROFILE_BRWS_ART;
|
|
|
|
|
2004-12-08 23:07:34 +01:00
|
|
|
role = provider->role;
|
|
|
|
provider->role = LASSO_PROVIDER_ROLE_SP; /* we act as an SP for sure here */
|
2006-05-16 10:10:56 +02:00
|
|
|
remote_role = remote_provider->role;
|
|
|
|
remote_provider->role = LASSO_PROVIDER_ROLE_IDP; /* and remote is IdP */
|
2004-12-08 23:07:34 +01:00
|
|
|
|
2004-10-29 13:16:38 +02:00
|
|
|
if (lasso_provider_has_protocol_profile(remote_provider,
|
|
|
|
LASSO_MD_PROTOCOL_TYPE_SINGLE_SIGN_ON, protocolProfile) == FALSE) {
|
2004-12-08 23:07:34 +01:00
|
|
|
provider->role = role;
|
2006-05-16 10:10:56 +02:00
|
|
|
remote_provider->role = remote_role;
|
2004-10-29 13:16:38 +02:00
|
|
|
return LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE;
|
|
|
|
}
|
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
/* check if authnRequest must be signed */
|
|
|
|
md_authnRequestsSigned = lasso_provider_get_metadata_one(provider, "AuthnRequestsSigned");
|
|
|
|
must_sign = (md_authnRequestsSigned && strcmp(md_authnRequestsSigned, "true") == 0);
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_release_string(md_authnRequestsSigned);
|
2006-05-16 10:10:56 +02:00
|
|
|
|
|
|
|
/* restore original roles */
|
2004-12-08 23:07:34 +01:00
|
|
|
provider->role = role;
|
2006-05-16 10:10:56 +02:00
|
|
|
remote_provider->role = remote_role;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2005-10-14 15:06:50 +02:00
|
|
|
if (!must_sign)
|
|
|
|
LASSO_SAMLP_REQUEST_ABSTRACT(
|
|
|
|
profile->request)->sign_type = LASSO_SIGNATURE_TYPE_NONE;
|
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
if (login->http_method == LASSO_HTTP_METHOD_REDIRECT) {
|
|
|
|
/* REDIRECT -> query */
|
|
|
|
if (must_sign) {
|
2004-12-28 13:44:22 +01:00
|
|
|
query = lasso_node_export_to_query(LASSO_NODE(profile->request),
|
|
|
|
profile->server->signature_method,
|
|
|
|
profile->server->private_key);
|
2004-12-08 22:55:43 +01:00
|
|
|
} else {
|
2004-12-08 23:07:34 +01:00
|
|
|
query = lasso_node_export_to_query(
|
2004-12-28 13:44:22 +01:00
|
|
|
LASSO_NODE(profile->request), 0, NULL);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
2004-10-29 13:16:38 +02:00
|
|
|
if (query == NULL) {
|
2004-12-15 12:07:34 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED);
|
2004-10-29 13:16:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* get SingleSignOnServiceURL metadata */
|
|
|
|
url = lasso_provider_get_metadata_one(remote_provider, "SingleSignOnServiceURL");
|
|
|
|
if (url == NULL) {
|
2004-12-14 22:41:57 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
2004-10-29 13:16:38 +02:00
|
|
|
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_string(profile->msg_url, lasso_concat_url_query(url, query));
|
|
|
|
lasso_release_string(profile->msg_body);
|
|
|
|
lasso_release_string(query);
|
|
|
|
lasso_release_string(url);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
if (login->http_method == LASSO_HTTP_METHOD_POST) {
|
2004-12-10 17:13:34 +01:00
|
|
|
if (must_sign) {
|
2006-10-28 19:01:11 +02:00
|
|
|
/* XXX: private_key_file is not declared within request
|
|
|
|
* snippets so it is not freed on destroy, so it is
|
|
|
|
* normal to not strdup() it; nevertheless it would
|
|
|
|
* probably be more clean not to to it this way */
|
2008-09-12 17:06:58 +02:00
|
|
|
LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->private_key_file =
|
2005-11-20 16:38:19 +01:00
|
|
|
profile->server->private_key;
|
2008-09-12 17:06:58 +02:00
|
|
|
LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->certificate_file =
|
2005-11-20 16:38:19 +01:00
|
|
|
profile->server->certificate;
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
2005-11-20 16:38:19 +01:00
|
|
|
lareq = lasso_node_export_to_base64(profile->request);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2004-10-29 13:16:38 +02:00
|
|
|
if (lareq == NULL) {
|
2006-12-28 00:50:15 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_BUILDING_QUERY_FAILED);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_string(profile->msg_url, lasso_provider_get_metadata_one(
|
|
|
|
remote_provider, "SingleSignOnServiceURL"));
|
|
|
|
lasso_assign_new_string(profile->msg_body, lareq);
|
2004-10-29 13:16:38 +02:00
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
return ret;
|
2004-07-08 03:33:39 +02:00
|
|
|
}
|
|
|
|
|
2004-08-19 14:51:25 +02:00
|
|
|
/**
|
|
|
|
* lasso_login_build_authn_response_msg:
|
2004-12-31 11:51:17 +01:00
|
|
|
* @login: a #LassoLogin
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2004-12-31 11:51:17 +01:00
|
|
|
* Converts profile authentication response (@response member) into a Liberty
|
|
|
|
* message.
|
|
|
|
*
|
|
|
|
* The URL is set into the @msg_url member and the field value (LARES) is set
|
|
|
|
* into the @msg_body member.
|
2004-10-27 11:49:13 +02:00
|
|
|
*
|
2009-04-27 10:19:09 +02:00
|
|
|
* Return value: 0 on success; or
|
2010-03-27 18:40:03 +01:00
|
|
|
* <itemizedlist>
|
|
|
|
* <listitem><para>
|
2009-04-27 10:19:09 +02:00
|
|
|
* LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if login is not a #LassoLogin object,
|
2010-03-27 18:40:03 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
2009-04-27 10:19:09 +02:00
|
|
|
* LASSO_PROFILE_ERROR_INVALID_PROTOCOLPROFILE if the current protocol profile is not
|
2010-03-27 18:40:03 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
2009-04-27 10:19:09 +02:00
|
|
|
* LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST or LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_LECP,
|
2010-03-27 18:40:03 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
2009-04-27 10:19:09 +02:00
|
|
|
* LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND if the remote provider ID is not registered in the server
|
|
|
|
* object,
|
2010-03-27 18:40:03 +01:00
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
2009-04-27 10:19:09 +02:00
|
|
|
* LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL if the metadata of the remote provider does not contain
|
2010-03-27 18:40:03 +01:00
|
|
|
* an URL for the assertion consuming service,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* LASSO_PROFILE_ERROR_MISSING_SERVER the server object is needed to sign a message and it is
|
|
|
|
* missing,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED the private key for signing could not be found,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* LASSO_PROFILE_ERROR_MISSING_RESPONSE if the response object is missing,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE if the SSO profile is not supported by the targeted
|
|
|
|
* provider,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* LASSO_PROFILE_BUILDING_QUERY_FAILED if using #LASSO_HTTP_METHOD_REDIRECT building of the redirect
|
|
|
|
* URL failed,
|
|
|
|
* </para></listitem>
|
|
|
|
* <listitem><para>
|
|
|
|
* LASSO_PROFILE_BUILDING_MSG_FAILED if using #LASSO_HTTP_METHOD_POST, #LASSO_HTTP_METHOD_SOAP or
|
|
|
|
* #LASSO_HTTP_METHOD_PAOS and building the @msg_body failed.
|
|
|
|
* </para></listitem>
|
|
|
|
* </itemizedlist>
|
2009-04-27 10:19:09 +02:00
|
|
|
*
|
2004-08-19 14:51:25 +02:00
|
|
|
**/
|
2004-07-06 19:20:48 +02:00
|
|
|
gint
|
2004-12-14 20:20:20 +01:00
|
|
|
lasso_login_build_authn_response_msg(LassoLogin *login)
|
2004-07-06 19:20:48 +02:00
|
|
|
{
|
2004-10-27 11:49:13 +02:00
|
|
|
LassoProvider *remote_provider;
|
2004-12-14 20:20:20 +01:00
|
|
|
LassoProfile *profile;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
|
|
|
|
2004-10-29 14:18:25 +02:00
|
|
|
profile = LASSO_PROFILE(login);
|
2007-01-05 14:40:07 +01:00
|
|
|
lasso_profile_clean_msg_info(profile);
|
2004-10-29 14:18:25 +02:00
|
|
|
|
2006-10-28 19:01:11 +02:00
|
|
|
IF_SAML2(profile) {
|
|
|
|
return lasso_saml20_login_build_authn_response_msg(login);
|
|
|
|
}
|
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
/* ProtocolProfile must be BrwsPost */
|
2005-05-12 23:28:26 +02:00
|
|
|
if (login->protocolProfile != LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST &&
|
|
|
|
login->protocolProfile != LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_LECP) {
|
2004-12-14 16:46:25 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_INVALID_PROTOCOLPROFILE);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2005-04-25 16:25:03 +02:00
|
|
|
if (login->assertion) {
|
|
|
|
LassoSamlAssertion *assertion = login->assertion;
|
|
|
|
LassoSamlSubjectStatementAbstract *ss;
|
|
|
|
ss = LASSO_SAML_SUBJECT_STATEMENT_ABSTRACT(assertion->AuthenticationStatement);
|
2007-01-04 00:35:17 +01:00
|
|
|
if (ss->Subject && ss->Subject->SubjectConfirmation) {
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_list_add_string(ss->Subject->SubjectConfirmation->ConfirmationMethod,
|
|
|
|
LASSO_SAML_CONFIRMATION_METHOD_BEARER);
|
2007-01-04 00:35:17 +01:00
|
|
|
}
|
2005-04-25 16:25:03 +02:00
|
|
|
}
|
|
|
|
|
2004-12-19 21:34:22 +01:00
|
|
|
/* Countermeasure: The issuer should sign <lib:AuthnResponse> messages.
|
|
|
|
* (binding and profiles (1.2errata2, page 65) */
|
2006-12-28 11:56:13 +01:00
|
|
|
if (profile->server->certificate) {
|
2005-11-20 16:38:19 +01:00
|
|
|
LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->sign_type =
|
|
|
|
LASSO_SIGNATURE_TYPE_WITHX509;
|
2006-12-28 11:56:13 +01:00
|
|
|
} else {
|
2005-11-20 16:38:19 +01:00
|
|
|
LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->sign_type =
|
|
|
|
LASSO_SIGNATURE_TYPE_SIMPLE;
|
2006-12-28 11:56:13 +01:00
|
|
|
}
|
2005-11-20 16:38:19 +01:00
|
|
|
LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->sign_method =
|
|
|
|
LASSO_SIGNATURE_METHOD_RSA_SHA1;
|
2008-09-12 17:06:58 +02:00
|
|
|
LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->private_key_file =
|
2005-11-20 16:38:19 +01:00
|
|
|
profile->server->private_key;
|
2008-09-12 17:06:58 +02:00
|
|
|
LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->certificate_file =
|
2005-11-20 16:38:19 +01:00
|
|
|
profile->server->certificate;
|
2004-12-13 19:22:28 +01:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
/* build an lib:AuthnResponse base64 encoded */
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_string(profile->msg_body, lasso_node_export_to_base64(LASSO_NODE(profile->response)));
|
2004-12-14 20:20:20 +01:00
|
|
|
|
2009-10-30 15:47:23 +01:00
|
|
|
remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
|
2005-01-21 23:02:56 +01:00
|
|
|
if (LASSO_IS_PROVIDER(remote_provider) == FALSE)
|
2005-02-05 17:15:53 +01:00
|
|
|
return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_string(profile->msg_url, lasso_provider_get_assertion_consumer_service_url(remote_provider,
|
|
|
|
LASSO_LIB_AUTHN_REQUEST(profile->request)->AssertionConsumerServiceID));
|
2006-10-29 15:22:16 +01:00
|
|
|
if (profile->msg_url == NULL) {
|
|
|
|
return LASSO_PROFILE_ERROR_UNKNOWN_PROFILE_URL;
|
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2004-12-14 20:20:20 +01:00
|
|
|
return 0;
|
2004-07-06 03:07:32 +02:00
|
|
|
}
|
|
|
|
|
2004-10-01 19:43:14 +02:00
|
|
|
/**
|
|
|
|
* lasso_login_build_request_msg:
|
2004-12-31 11:51:17 +01:00
|
|
|
* @login: a #LassoLogin
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2009-04-27 10:19:11 +02:00
|
|
|
* Produce a SOAP Artifact Resolve message. It must follows a call to
|
|
|
|
* lasso_login_init_request() on the artifact message.
|
|
|
|
* Converts artifact request into a Liberty SOAP message.
|
2004-12-31 11:51:17 +01:00
|
|
|
*
|
|
|
|
* The URL is set into the @msg_url member and the SOAP message is set into the
|
2009-04-27 10:19:11 +02:00
|
|
|
* @msg_body member. You should POST the @msg_body to the @msg_url afterward.
|
|
|
|
*
|
|
|
|
* Return value: 0 on success; or
|
|
|
|
* LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if login is not a #LassoLogin object,
|
|
|
|
* LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID if not remote provider ID was setup -- it usually
|
|
|
|
* means that lasso_login_init_request was not called before,
|
|
|
|
* LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND if the remote provider ID is not registered in the server
|
|
|
|
* object.
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2004-10-01 19:43:14 +02:00
|
|
|
**/
|
2004-07-06 19:20:48 +02:00
|
|
|
gint
|
|
|
|
lasso_login_build_request_msg(LassoLogin *login)
|
|
|
|
{
|
2004-10-27 11:49:13 +02:00
|
|
|
LassoProvider *remote_provider;
|
2004-10-30 01:06:37 +02:00
|
|
|
LassoProfile *profile;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
|
|
|
|
2004-10-30 01:06:37 +02:00
|
|
|
profile = LASSO_PROFILE(login);
|
2007-01-05 14:40:07 +01:00
|
|
|
lasso_profile_clean_msg_info(profile);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2005-11-21 19:51:52 +01:00
|
|
|
IF_SAML2(profile) {
|
2005-11-20 16:38:19 +01:00
|
|
|
return lasso_saml20_login_build_request_msg(login);
|
|
|
|
}
|
|
|
|
|
2006-01-23 16:30:00 +01:00
|
|
|
if (profile->remote_providerID == NULL) {
|
2007-01-08 14:13:49 +01:00
|
|
|
/* this means lasso_login_init_request was not called before */
|
2006-01-23 16:30:00 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID);
|
|
|
|
}
|
|
|
|
|
2005-11-20 16:38:19 +01:00
|
|
|
LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->private_key_file =
|
|
|
|
profile->server->private_key;
|
2008-09-12 17:06:58 +02:00
|
|
|
LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->certificate_file =
|
2005-11-20 16:38:19 +01:00
|
|
|
profile->server->certificate;
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_string(profile->msg_body, lasso_node_export_to_soap(profile->request));
|
2004-10-30 01:06:37 +02:00
|
|
|
|
2009-10-30 15:47:23 +01:00
|
|
|
remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
|
2004-12-13 18:46:29 +01:00
|
|
|
if (LASSO_IS_PROVIDER(remote_provider) == FALSE) {
|
2005-02-05 17:15:53 +01:00
|
|
|
return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_string(profile->msg_url, lasso_provider_get_metadata_one(remote_provider, "SoapEndpoint"));
|
2004-10-27 11:49:13 +02:00
|
|
|
return 0;
|
2004-07-06 19:20:48 +02:00
|
|
|
}
|
|
|
|
|
2004-10-01 19:43:14 +02:00
|
|
|
/**
|
|
|
|
* lasso_login_build_response_msg:
|
2004-12-31 11:51:17 +01:00
|
|
|
* @login: a #LassoLogin
|
|
|
|
* @remote_providerID: service provider ID
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2004-12-31 11:51:17 +01:00
|
|
|
* Converts profile assertion response (@response member) into a Liberty SOAP
|
|
|
|
* messageresponse message.
|
|
|
|
*
|
|
|
|
* The URL is set into the @msg_url member and the SOAP message is set into the
|
|
|
|
* @msg_body member.
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2004-12-31 11:51:17 +01:00
|
|
|
* Return value: 0 on success; or a negative value otherwise.
|
2009-04-27 10:19:13 +02:00
|
|
|
* LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if login is not a #LassoLogin object,
|
|
|
|
* LASSO_PROFILE_ERROR_SESSION_NOT_FOUND if no session object was found in the login profile object
|
|
|
|
* -- it should be created by lasso_login_build_assertion() if you did not set it manually before
|
|
|
|
* calling lasso_login_build_assertion().
|
|
|
|
*
|
2004-10-02 03:17:03 +02:00
|
|
|
**/
|
|
|
|
gint
|
2004-10-27 11:49:13 +02:00
|
|
|
lasso_login_build_response_msg(LassoLogin *login, gchar *remote_providerID)
|
2004-09-03 18:12:51 +02:00
|
|
|
{
|
2004-10-27 11:49:13 +02:00
|
|
|
LassoProvider *remote_provider;
|
2004-12-14 14:59:22 +01:00
|
|
|
LassoProfile *profile;
|
2004-10-27 11:49:13 +02:00
|
|
|
gint ret = 0;
|
|
|
|
|
2006-12-28 00:50:15 +01:00
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
2004-12-14 14:59:22 +01:00
|
|
|
profile = LASSO_PROFILE(login);
|
2007-01-05 14:40:07 +01:00
|
|
|
lasso_profile_clean_msg_info(profile);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2005-11-21 19:51:52 +01:00
|
|
|
IF_SAML2(profile) {
|
2008-09-12 15:57:22 +02:00
|
|
|
return lasso_saml20_login_build_response_msg(login);
|
2005-11-20 16:38:19 +01:00
|
|
|
}
|
|
|
|
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_gobject(profile->response, lasso_samlp_response_new());
|
|
|
|
lasso_assign_string(LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->InResponseTo,
|
|
|
|
LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->RequestID);
|
2005-11-20 16:38:19 +01:00
|
|
|
if (LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->MajorVersion == 1 &&
|
|
|
|
LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->MinorVersion == 0) {
|
2005-03-18 21:58:34 +01:00
|
|
|
/* this is a SAML 1.0 request, must create SAML 1.0 response */
|
2005-11-20 16:38:19 +01:00
|
|
|
LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->MinorVersion = 0;
|
2005-01-28 16:57:56 +01:00
|
|
|
}
|
2004-12-31 15:21:44 +01:00
|
|
|
|
2005-03-07 15:16:16 +01:00
|
|
|
if (profile->server->certificate) {
|
2008-09-12 17:06:58 +02:00
|
|
|
LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->sign_type =
|
2005-03-07 15:16:16 +01:00
|
|
|
LASSO_SIGNATURE_TYPE_WITHX509;
|
|
|
|
} else {
|
2008-09-12 17:06:58 +02:00
|
|
|
LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->sign_type =
|
2005-03-07 15:16:16 +01:00
|
|
|
LASSO_SIGNATURE_TYPE_SIMPLE;
|
|
|
|
}
|
2008-09-12 17:06:58 +02:00
|
|
|
LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->sign_method =
|
2004-12-14 14:59:22 +01:00
|
|
|
LASSO_SIGNATURE_METHOD_RSA_SHA1;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
if (remote_providerID != NULL) {
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_string(profile->remote_providerID, remote_providerID);
|
2009-10-30 15:47:23 +01:00
|
|
|
remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
|
2004-12-14 14:50:46 +01:00
|
|
|
ret = lasso_provider_verify_signature(remote_provider,
|
|
|
|
login->private_data->soap_request_msg,
|
|
|
|
"RequestID", LASSO_MESSAGE_FORMAT_SOAP);
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_release_string(login->private_data->soap_request_msg);
|
2004-12-14 14:50:46 +01:00
|
|
|
|
2008-06-16 18:54:47 +02:00
|
|
|
/* lasso_profile_set_session_from_dump has not been called */
|
|
|
|
if (profile->session == NULL) {
|
|
|
|
ret = LASSO_PROFILE_ERROR_SESSION_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2005-03-29 10:16:58 +02:00
|
|
|
/* change status code into RequestDenied if signature is
|
|
|
|
* invalid or not found or if an error occurs during
|
|
|
|
* verification */
|
2004-10-27 11:49:13 +02:00
|
|
|
if (ret != 0) {
|
2004-12-14 14:59:22 +01:00
|
|
|
lasso_profile_set_response_status(profile,
|
2004-10-27 11:49:13 +02:00
|
|
|
LASSO_SAML_STATUS_CODE_REQUEST_DENIED);
|
|
|
|
}
|
|
|
|
|
2008-06-16 18:54:47 +02:00
|
|
|
if (ret == 0) {
|
2004-10-27 11:49:13 +02:00
|
|
|
/* get assertion in session and add it in response */
|
2005-03-29 10:27:03 +02:00
|
|
|
LassoSamlAssertion *assertion;
|
|
|
|
LassoSamlpStatus *status;
|
|
|
|
|
2006-11-06 21:26:31 +01:00
|
|
|
status = LASSO_SAMLP_STATUS(lasso_session_get_status(
|
|
|
|
profile->session, remote_providerID));
|
2005-11-20 16:38:19 +01:00
|
|
|
assertion = LASSO_SAML_ASSERTION(
|
|
|
|
lasso_session_get_assertion(profile->session,
|
|
|
|
profile->remote_providerID));
|
2005-03-29 10:38:00 +02:00
|
|
|
if (status) {
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_gobject(LASSO_SAMLP_RESPONSE(profile->response)->Status,
|
|
|
|
status);
|
2005-03-29 10:38:00 +02:00
|
|
|
lasso_session_remove_status(profile->session,
|
|
|
|
remote_providerID);
|
|
|
|
} else if (assertion) {
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_list_add_gobject(LASSO_SAMLP_RESPONSE(profile->response)->Assertion,
|
|
|
|
assertion);
|
2004-12-28 19:48:46 +01:00
|
|
|
lasso_profile_set_response_status(profile,
|
|
|
|
LASSO_SAML_STATUS_CODE_SUCCESS);
|
2004-12-29 18:25:56 +01:00
|
|
|
lasso_session_remove_status(profile->session, remote_providerID);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2004-12-14 14:59:22 +01:00
|
|
|
lasso_profile_set_response_status(profile, LASSO_SAML_STATUS_CODE_REQUEST_DENIED);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2008-09-12 17:06:58 +02:00
|
|
|
LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->private_key_file =
|
2005-11-20 16:38:19 +01:00
|
|
|
profile->server->private_key;
|
|
|
|
LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->certificate_file =
|
|
|
|
profile->server->certificate;
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_string(profile->msg_body, lasso_node_export_to_soap(profile->response));
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
return ret;
|
2004-09-03 18:12:51 +02:00
|
|
|
}
|
|
|
|
|
2004-10-02 03:17:03 +02:00
|
|
|
/**
|
|
|
|
* lasso_login_destroy:
|
2004-12-22 22:38:06 +01:00
|
|
|
* @login: a #LassoLogin
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2005-01-10 22:46:39 +01:00
|
|
|
* Destroys a #LassoLogin object.
|
2009-04-27 10:19:15 +02:00
|
|
|
*
|
|
|
|
* @Deprecated: Since #2.2.1, use g_object_unref() instead.
|
2004-10-02 03:17:03 +02:00
|
|
|
**/
|
2004-07-13 02:19:21 +02:00
|
|
|
void
|
|
|
|
lasso_login_destroy(LassoLogin *login)
|
|
|
|
{
|
2010-03-27 18:39:59 +01:00
|
|
|
lasso_release_gobject(login);
|
2004-07-13 02:19:21 +02:00
|
|
|
}
|
|
|
|
|
2004-12-30 13:57:26 +01:00
|
|
|
/**
|
|
|
|
* lasso_login_init_authn_request:
|
|
|
|
* @login: a #LassoLogin
|
2010-01-29 01:43:50 +01:00
|
|
|
* @remote_providerID:(allow-none): the providerID of the identity provider (may be NULL)
|
|
|
|
* @http_method:(default LASSO_HTTP_METHOD_REDIRECT): HTTP method to use for request transmission
|
2004-12-30 13:57:26 +01:00
|
|
|
*
|
2009-09-29 15:12:37 +02:00
|
|
|
* <para>Initializes a new AuthnRequest from current service provider to remote
|
2004-12-31 11:51:17 +01:00
|
|
|
* identity provider specified in @remote_providerID (if NULL the first known
|
2009-09-29 15:12:37 +02:00
|
|
|
* identity provider is used).</para>
|
2004-12-30 13:57:26 +01:00
|
|
|
*
|
2009-09-29 15:12:37 +02:00
|
|
|
* <para>For ID-FF 1.2 the default NameIDPolicy in an AuthnRequest is None, which imply that a
|
|
|
|
* federation must already exist on the IdP side.</para>
|
|
|
|
*
|
2009-09-29 15:20:33 +02:00
|
|
|
* <para>For SAML 2.0 the default NameIDPolicy is the first listed in the metadatas of the current
|
|
|
|
* provider, or if none is specified, Transient, which ask the IdP to give a one-time
|
|
|
|
* federation</para>
|
2009-09-29 15:12:37 +02:00
|
|
|
*
|
|
|
|
* Return value: 0 on success; or <itemizedlist>
|
|
|
|
* <listitem><para>LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if login is not a #LassoLogin object,</para></listitem>
|
|
|
|
* <listitem><para>LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID if @remote_providerID is NULL and no default remote
|
2009-04-27 10:19:18 +02:00
|
|
|
* provider could be found from the server object -- usually the first one in the order of adding to
|
2009-09-29 15:12:37 +02:00
|
|
|
* the server object --,</para></listitem>
|
|
|
|
* <listitem><para>LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND if the @remote_providerID is not known to our server object.</para></listitem>
|
|
|
|
* <listitem><para>LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD if the HTTP method is neither LASSO_HTTP_METHOD_REDIRECT
|
|
|
|
* or LASSO_HTTP_METHOD_POST,</para></listitem>
|
|
|
|
* <listitem><para>LASSO_PROFILE_ERROR_BUILDING_REQUEST_FAILED if creation of the request object failed.</para></listitem>
|
|
|
|
* </itemizedlist>
|
2009-04-27 10:19:18 +02:00
|
|
|
*
|
2004-12-30 13:57:26 +01:00
|
|
|
**/
|
2004-10-27 11:49:13 +02:00
|
|
|
gint
|
2004-12-14 11:20:07 +01:00
|
|
|
lasso_login_init_authn_request(LassoLogin *login, const gchar *remote_providerID,
|
2004-12-31 19:33:23 +01:00
|
|
|
LassoHttpMethod http_method)
|
2004-07-08 03:33:39 +02:00
|
|
|
{
|
2005-01-04 11:13:05 +01:00
|
|
|
LassoProfile *profile;
|
2005-01-21 23:02:56 +01:00
|
|
|
LassoProvider *remote_provider;
|
2005-11-20 16:38:19 +01:00
|
|
|
LassoSamlpRequestAbstract *request;
|
2004-08-13 02:33:51 +02:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
2004-07-08 03:33:39 +02:00
|
|
|
|
2005-01-04 11:13:05 +01:00
|
|
|
profile = LASSO_PROFILE(login);
|
|
|
|
|
2005-01-04 16:40:37 +01:00
|
|
|
/* clean state */
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_release_string (profile->remote_providerID);
|
|
|
|
lasso_release_gobject (profile->request);
|
2005-01-04 16:40:37 +01:00
|
|
|
|
2004-12-14 11:20:07 +01:00
|
|
|
if (remote_providerID != NULL) {
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_string(profile->remote_providerID, remote_providerID);
|
2004-12-14 11:20:07 +01:00
|
|
|
} else {
|
SAML 2.0: add support for attribute, authentication and authorization authorities metadata
* server.c,serverprivate.h: add new private method
lasso_server_get_firs_providerID_by_role(server, role)w
* defederation.c: use new private method
lasso_server_get_first_providerID_by_role for find providerID
when the argument remote_providerID is null in
lasso_defederation_init_notification.
* lasso/id-ff/login.c (lasso_login_init_authn_request): use new private
method lasso_server_get_first_providerID_by_role.
* provider.h: add thre new provider role (authn,pdp,attribute) and
four new services (authn,assertionid,attribute,authz) and also
a ROLE_ANY value (-1) for catchall purpose and a ROLE_LAST for
array sizing.
* provider.h: add a LAST member to LassoMdProtocolType enum.
* providerprivate.h,provider.c:
- removes separate hashtable for descriptors depending on provider role,
use only one table named Descriptors.
- use the LAST members of enumerations to dimention static string arrays.
* provider.h: add a LAST member to the e
2010-03-27 17:51:43 +01:00
|
|
|
lasso_assign_new_string(profile->remote_providerID, lasso_server_get_first_providerID_by_role(profile->server, LASSO_PROVIDER_ROLE_IDP));
|
2005-11-20 16:38:19 +01:00
|
|
|
if (profile->remote_providerID == NULL) {
|
2009-04-27 10:19:17 +02:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID);
|
2005-11-20 16:38:19 +01:00
|
|
|
}
|
2004-12-14 11:20:07 +01:00
|
|
|
}
|
2004-07-08 03:33:39 +02:00
|
|
|
|
2009-10-30 15:47:23 +01:00
|
|
|
remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
|
2005-01-21 23:02:56 +01:00
|
|
|
if (LASSO_IS_PROVIDER(remote_provider) == FALSE)
|
2005-02-05 17:15:53 +01:00
|
|
|
return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
|
2005-01-21 23:02:56 +01:00
|
|
|
|
2005-11-21 19:51:52 +01:00
|
|
|
IF_SAML2(profile) {
|
2008-09-12 15:57:22 +02:00
|
|
|
return lasso_saml20_login_init_authn_request(login, http_method);
|
2005-11-20 16:38:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (http_method != LASSO_HTTP_METHOD_REDIRECT && http_method != LASSO_HTTP_METHOD_POST) {
|
|
|
|
return critical_error(LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD);
|
|
|
|
}
|
|
|
|
|
2004-12-14 11:20:07 +01:00
|
|
|
login->http_method = http_method;
|
2004-07-08 03:33:39 +02:00
|
|
|
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_gobject(profile->request, LASSO_NODE(lasso_lib_authn_request_new()));
|
2005-01-04 11:13:05 +01:00
|
|
|
if (profile->request == NULL) {
|
|
|
|
return critical_error(LASSO_PROFILE_ERROR_BUILDING_REQUEST_FAILED);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
2004-07-08 03:33:39 +02:00
|
|
|
|
2005-11-20 16:38:19 +01:00
|
|
|
request = LASSO_SAMLP_REQUEST_ABSTRACT(profile->request);
|
|
|
|
request->RequestID = lasso_build_unique_id(32);
|
2009-02-17 18:02:01 +01:00
|
|
|
lasso_assign_string(login->private_data->request_id, request->RequestID);
|
2005-11-20 16:38:19 +01:00
|
|
|
request->MajorVersion = LASSO_LIB_MAJOR_VERSION_N;
|
|
|
|
request->MinorVersion = LASSO_LIB_MINOR_VERSION_N;
|
|
|
|
if (lasso_provider_get_protocol_conformance(remote_provider) < LASSO_PROTOCOL_LIBERTY_1_2) {
|
|
|
|
request->MajorVersion = 1;
|
|
|
|
request->MinorVersion = 0;
|
2005-01-28 14:29:14 +01:00
|
|
|
}
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_string(request->IssueInstant, lasso_get_current_time());
|
2009-03-27 16:06:17 +01:00
|
|
|
lasso_assign_string(LASSO_LIB_AUTHN_REQUEST(profile->request)->ProviderID,
|
2005-01-04 11:13:05 +01:00
|
|
|
LASSO_PROVIDER(profile->server)->ProviderID);
|
2009-03-27 16:06:17 +01:00
|
|
|
lasso_assign_string(LASSO_LIB_AUTHN_REQUEST(profile->request)->RelayState,
|
|
|
|
profile->msg_relayState);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2005-01-04 11:13:05 +01:00
|
|
|
if (http_method == LASSO_HTTP_METHOD_POST) {
|
2005-11-20 16:38:19 +01:00
|
|
|
request->sign_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
|
2005-03-07 15:16:16 +01:00
|
|
|
if (profile->server->certificate) {
|
2005-11-20 16:38:19 +01:00
|
|
|
request->sign_type = LASSO_SIGNATURE_TYPE_WITHX509;
|
2005-03-07 15:16:16 +01:00
|
|
|
} else {
|
2005-11-20 16:38:19 +01:00
|
|
|
request->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
|
2005-03-07 15:16:16 +01:00
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2004-07-06 03:07:32 +02:00
|
|
|
}
|
|
|
|
|
2004-12-31 11:51:17 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* lasso_login_init_request:
|
|
|
|
* @login: a #LassoLogin
|
|
|
|
* @response_msg: the authentication response received
|
|
|
|
* @response_http_method: the method used to receive the authentication
|
|
|
|
* response
|
|
|
|
*
|
2009-04-27 10:19:20 +02:00
|
|
|
* Initializes an artifact request. @response_msg is either the query string
|
2004-12-31 11:51:17 +01:00
|
|
|
* (in redirect mode) or the form LAREQ field (in browser-post mode).
|
2009-04-27 10:19:20 +02:00
|
|
|
* It should only be used if you received an artifact message, @response_msg must be content of the
|
|
|
|
* artifact field for the POST artifact binding of the query string for the REDIRECT artifact
|
|
|
|
* binding. You must set the @response_http_method argument according to the way you received the
|
|
|
|
* artifact message.
|
|
|
|
*
|
|
|
|
* Return value: 0 on success; or a
|
|
|
|
* LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if login is not a #LassoLogin object,
|
|
|
|
* LASSO_PARAM_ERROR_INVALID_VALUE if @response_msg is NULL,
|
|
|
|
* LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD if the HTTP method is neither LASSO_HTTP_METHOD_REDIRECT
|
|
|
|
* or LASSO_HTTP_METHOD_POST (in the ID-FF 1.2 case) or neither LASSO_HTTP_METHOD_ARTIFACT_GET or
|
|
|
|
* LASSO_HTTP_METHOD_ARTIFACT_POST (in the SAML 2.0 case),
|
|
|
|
* LASSO_PROFILE_ERROR_MISSING_ARTIFACT if no artifact field was found in the query string (only
|
|
|
|
* possible for the LASSO_HTTP_METHOD_REDIRECT case),
|
|
|
|
* LASSO_PROFILE_ERROR_INVALID_ARTIFACT if decoding of the artifact failed -- whether because
|
|
|
|
* the base64 encoding is invalid or because the type code is wrong --,
|
|
|
|
* LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID if no provider ID could be found corresponding to
|
|
|
|
* the hash contained in the artifact.
|
2004-12-31 11:51:17 +01:00
|
|
|
*
|
2008-09-12 17:06:58 +02:00
|
|
|
**/
|
2004-07-06 03:07:32 +02:00
|
|
|
gint
|
2004-10-27 11:49:13 +02:00
|
|
|
lasso_login_init_request(LassoLogin *login, gchar *response_msg,
|
2004-12-31 19:33:23 +01:00
|
|
|
LassoHttpMethod response_http_method)
|
2004-09-22 15:21:29 +02:00
|
|
|
{
|
2004-10-27 11:49:13 +02:00
|
|
|
char **query_fields;
|
|
|
|
gint ret = 0;
|
|
|
|
int i;
|
2004-12-31 19:21:32 +01:00
|
|
|
char *artifact_b64 = NULL, *provider_succinct_id_b64;
|
|
|
|
char provider_succinct_id[21];
|
2004-10-27 11:49:13 +02:00
|
|
|
char artifact[43];
|
|
|
|
LassoSamlpRequestAbstract *request;
|
2005-11-20 16:38:19 +01:00
|
|
|
LassoProfile *profile;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
|
|
|
g_return_val_if_fail(response_msg != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
|
2008-09-12 17:06:58 +02:00
|
|
|
|
2005-11-20 16:38:19 +01:00
|
|
|
profile = LASSO_PROFILE(login);
|
2005-11-21 19:51:52 +01:00
|
|
|
IF_SAML2(profile) {
|
2005-11-20 16:38:19 +01:00
|
|
|
return lasso_saml20_login_init_request(login, response_msg,
|
|
|
|
response_http_method);
|
|
|
|
}
|
2004-10-29 15:21:46 +02:00
|
|
|
if (response_http_method != LASSO_HTTP_METHOD_REDIRECT &&
|
|
|
|
response_http_method != LASSO_HTTP_METHOD_POST) {
|
2004-12-14 16:46:25 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD);
|
2004-10-29 15:21:46 +02:00
|
|
|
}
|
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
/* rebuild response (artifact) */
|
2004-10-29 15:21:46 +02:00
|
|
|
if (response_http_method == LASSO_HTTP_METHOD_REDIRECT) {
|
|
|
|
query_fields = urlencoded_to_strings(response_msg);
|
|
|
|
for (i=0; query_fields[i]; i++) {
|
2009-03-27 16:06:15 +01:00
|
|
|
if (strncmp(query_fields[i], "SAMLart=", 8) == 0) {
|
|
|
|
lasso_assign_string(artifact_b64, query_fields[i]+8);
|
|
|
|
}
|
|
|
|
if (strncmp(query_fields[i], "RelayState=", 11) == 0) {
|
|
|
|
lasso_assign_string(profile->msg_relayState, query_fields[i]+11);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
2005-02-08 19:44:51 +01:00
|
|
|
xmlFree(query_fields[i]);
|
2004-10-29 15:21:46 +02:00
|
|
|
}
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_release_string(query_fields);
|
2006-10-29 19:17:00 +01:00
|
|
|
if (artifact_b64 == NULL) {
|
|
|
|
return LASSO_PROFILE_ERROR_MISSING_ARTIFACT;
|
|
|
|
}
|
2004-10-29 15:21:46 +02:00
|
|
|
}
|
|
|
|
if (response_http_method == LASSO_HTTP_METHOD_POST) {
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_string(artifact_b64, response_msg);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2005-07-31 00:36:54 +02:00
|
|
|
i = xmlSecBase64Decode((xmlChar*)artifact_b64, (xmlChar*)artifact, 43);
|
2004-10-27 11:49:13 +02:00
|
|
|
if (i < 0 || i > 42) {
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_release_string(artifact_b64);
|
2009-04-27 10:19:22 +02:00
|
|
|
return LASSO_PROFILE_ERROR_INVALID_ARTIFACT;
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (artifact[0] != 0 || artifact[1] != 3) { /* wrong type code */
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_release_string(artifact_b64);
|
2009-04-27 10:19:22 +02:00
|
|
|
return LASSO_PROFILE_ERROR_INVALID_ARTIFACT;
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2004-12-31 19:21:32 +01:00
|
|
|
memcpy(provider_succinct_id, artifact+2, 20);
|
|
|
|
provider_succinct_id[20] = 0;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2005-07-31 00:36:54 +02:00
|
|
|
provider_succinct_id_b64 = (char*)xmlSecBase64Encode((xmlChar*)provider_succinct_id, 20, 0);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_string(profile->remote_providerID, lasso_server_get_providerID_from_hash(
|
|
|
|
profile->server, provider_succinct_id_b64));
|
2004-12-31 19:21:32 +01:00
|
|
|
xmlFree(provider_succinct_id_b64);
|
2005-11-20 16:38:19 +01:00
|
|
|
if (profile->remote_providerID == NULL) {
|
2005-02-11 15:35:43 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID);
|
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2004-12-19 12:07:22 +01:00
|
|
|
request = LASSO_SAMLP_REQUEST_ABSTRACT(lasso_samlp_request_new());
|
2004-10-27 11:49:13 +02:00
|
|
|
request->RequestID = lasso_build_unique_id(32);
|
2005-01-28 12:45:09 +01:00
|
|
|
request->MajorVersion = LASSO_SAML_MAJOR_VERSION_N;
|
|
|
|
request->MinorVersion = LASSO_SAML_MINOR_VERSION_N;
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_string(request->IssueInstant, lasso_get_current_time());
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
LASSO_SAMLP_REQUEST(request)->AssertionArtifact = artifact_b64;
|
2005-11-20 16:38:19 +01:00
|
|
|
if (profile->server->certificate) {
|
2005-03-07 15:16:16 +01:00
|
|
|
request->sign_type = LASSO_SIGNATURE_TYPE_WITHX509;
|
|
|
|
} else {
|
|
|
|
request->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
|
|
|
|
}
|
2004-10-30 01:06:37 +02:00
|
|
|
request->sign_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_gobject(profile->request, LASSO_NODE(request));
|
2008-09-12 17:06:58 +02:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
return ret;
|
2004-09-22 15:21:29 +02:00
|
|
|
}
|
|
|
|
|
2004-10-02 21:59:56 +02:00
|
|
|
/**
|
2004-10-27 11:49:13 +02:00
|
|
|
* lasso_login_init_idp_initiated_authn_request:
|
2004-12-31 11:51:17 +01:00
|
|
|
* @login: a #LassoLogin.
|
|
|
|
* @remote_providerID: the providerID of the remote service provider (may be
|
|
|
|
* NULL)
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2009-09-29 15:20:33 +02:00
|
|
|
* <para>Generates an authentication response without matching authentication
|
|
|
|
* request.</para>
|
2004-10-02 21:59:56 +02:00
|
|
|
*
|
2009-09-29 15:20:33 +02:00
|
|
|
* <para>The choice of NameIDFormat is the same as for lasso_login_init_authn_request() but with the
|
|
|
|
* target @remote_providerID as the current provider</para>
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2009-09-29 15:20:33 +02:00
|
|
|
* <para>If @remote_providerID is NULL, the first known provider is used.</para>
|
|
|
|
*
|
|
|
|
* Return value: 0 on success; or a negative value otherwise. Error codes are the same as
|
|
|
|
* lasso_login_init_authn_request().
|
2004-10-02 21:59:56 +02:00
|
|
|
**/
|
|
|
|
gint
|
2004-10-27 11:49:13 +02:00
|
|
|
lasso_login_init_idp_initiated_authn_request(LassoLogin *login,
|
|
|
|
const gchar *remote_providerID)
|
2004-10-02 21:59:56 +02:00
|
|
|
{
|
2010-04-30 11:23:01 +02:00
|
|
|
int rc = 0;
|
2005-01-04 11:13:05 +01:00
|
|
|
LassoProfile *profile;
|
2004-10-02 21:59:56 +02:00
|
|
|
|
2006-11-08 13:46:06 +01:00
|
|
|
profile = LASSO_PROFILE(login);
|
|
|
|
|
|
|
|
IF_SAML2(profile) {
|
|
|
|
return lasso_saml20_login_init_idp_initiated_authn_request(login,
|
|
|
|
remote_providerID);
|
|
|
|
}
|
|
|
|
|
2005-01-04 11:13:05 +01:00
|
|
|
rc = lasso_login_init_authn_request(login, remote_providerID, LASSO_HTTP_METHOD_POST);
|
|
|
|
if (rc)
|
|
|
|
return rc;
|
2004-10-02 21:59:56 +02:00
|
|
|
|
2004-10-29 15:21:46 +02:00
|
|
|
/* no RequestID attribute or it would be used in response assertion */
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_release_string(LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->RequestID);
|
|
|
|
lasso_assign_string(LASSO_LIB_AUTHN_REQUEST(profile->request)->NameIDPolicy,
|
2008-05-30 12:31:09 +02:00
|
|
|
LASSO_LIB_NAMEID_POLICY_TYPE_ANY);
|
2004-10-02 21:59:56 +02:00
|
|
|
|
2005-01-04 11:13:05 +01:00
|
|
|
return 0;
|
2004-10-02 21:59:56 +02:00
|
|
|
}
|
|
|
|
|
2004-10-01 16:15:01 +02:00
|
|
|
/**
|
2004-10-01 19:43:14 +02:00
|
|
|
* lasso_login_must_ask_for_consent:
|
2004-12-22 13:48:05 +01:00
|
|
|
* @login: a #LassoLogin
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2004-12-22 13:48:05 +01:00
|
|
|
* Evaluates if consent must be asked to the Principal to federate him.
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2004-12-31 11:51:17 +01:00
|
|
|
* Return value: %TRUE if consent must be asked
|
2004-10-01 16:15:01 +02:00
|
|
|
**/
|
2004-09-30 19:12:23 +02:00
|
|
|
gboolean
|
|
|
|
lasso_login_must_ask_for_consent(LassoLogin *login)
|
|
|
|
{
|
2005-11-20 16:38:19 +01:00
|
|
|
LassoProfile *profile = LASSO_PROFILE(login);
|
|
|
|
|
2005-11-21 19:51:52 +01:00
|
|
|
IF_SAML2(profile) {
|
2005-11-20 16:38:19 +01:00
|
|
|
return lasso_saml20_login_must_ask_for_consent(login);
|
|
|
|
}
|
|
|
|
|
2006-11-19 20:06:30 +01:00
|
|
|
if (LASSO_LIB_AUTHN_REQUEST(LASSO_PROFILE(login)->request)->IsPassive) {
|
|
|
|
return FALSE;
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
2006-11-19 20:06:30 +01:00
|
|
|
|
|
|
|
return lasso_login_must_ask_for_consent_private(login);
|
2004-09-30 19:12:23 +02:00
|
|
|
}
|
|
|
|
|
2004-12-31 11:51:17 +01:00
|
|
|
|
2004-10-01 19:43:14 +02:00
|
|
|
/**
|
|
|
|
* lasso_login_must_authenticate:
|
2004-12-22 13:48:05 +01:00
|
|
|
* @login: a #LassoLogin
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2004-12-31 11:51:17 +01:00
|
|
|
* Evaluates if user must be authenticated.
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2004-12-31 11:51:17 +01:00
|
|
|
* Return value: %TRUE if user must be authenticated
|
2004-10-01 19:43:14 +02:00
|
|
|
**/
|
2004-09-22 15:21:29 +02:00
|
|
|
gboolean
|
|
|
|
lasso_login_must_authenticate(LassoLogin *login)
|
|
|
|
{
|
2004-10-27 11:49:13 +02:00
|
|
|
LassoLibAuthnRequest *request;
|
2005-11-20 16:38:19 +01:00
|
|
|
LassoProfile *profile;
|
2006-11-08 23:43:39 +01:00
|
|
|
gboolean matched = TRUE;
|
|
|
|
GList *assertions = NULL;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
2005-11-20 16:38:19 +01:00
|
|
|
profile = LASSO_PROFILE(login);
|
2008-09-12 17:06:58 +02:00
|
|
|
|
2005-11-21 19:51:52 +01:00
|
|
|
IF_SAML2(profile) {
|
2005-11-20 16:38:19 +01:00
|
|
|
return lasso_saml20_login_must_authenticate(login);
|
|
|
|
}
|
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
request = LASSO_LIB_AUTHN_REQUEST(LASSO_PROFILE(login)->request);
|
2005-04-18 12:57:24 +02:00
|
|
|
if (request == NULL) {
|
|
|
|
return critical_error(LASSO_PROFILE_ERROR_MISSING_REQUEST);
|
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2006-11-08 23:43:39 +01:00
|
|
|
if (request->ForceAuthn == TRUE && request->IsPassive == FALSE)
|
2004-12-13 22:40:12 +01:00
|
|
|
return TRUE;
|
2006-11-08 23:43:39 +01:00
|
|
|
|
|
|
|
assertions = lasso_session_get_assertions(profile->session, NULL);
|
|
|
|
if (request->RequestAuthnContext) {
|
|
|
|
char *comparison = request->RequestAuthnContext->AuthnContextComparison;
|
|
|
|
char *class_ref;
|
|
|
|
GList *class_refs = request->RequestAuthnContext->AuthnContextClassRef;
|
|
|
|
GList *t1, *t2;
|
|
|
|
int compa;
|
|
|
|
|
|
|
|
if (comparison == NULL || strcmp(comparison, "exact") == 0) {
|
|
|
|
compa = 0;
|
|
|
|
} else if (strcmp(comparison, "minimum") == 0) {
|
|
|
|
message(G_LOG_LEVEL_CRITICAL, "'minimum' comparison is not implemented");
|
|
|
|
compa = 0;
|
|
|
|
} else if (strcmp(comparison, "better") == 0) {
|
|
|
|
message(G_LOG_LEVEL_CRITICAL, "'better' comparison is not implemented");
|
|
|
|
compa = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (class_refs) {
|
|
|
|
matched = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (t1 = class_refs; t1 && !matched; t1 = g_list_next(t1)) {
|
|
|
|
class_ref = t1->data;
|
|
|
|
for (t2 = assertions; t2 && !matched; t2 = g_list_next(t2)) {
|
2006-11-09 11:19:37 +01:00
|
|
|
LassoSamlAssertion *assertion;
|
2006-11-08 23:43:39 +01:00
|
|
|
LassoSamlAuthenticationStatement *as;
|
|
|
|
char *method;
|
|
|
|
|
2006-11-09 11:19:37 +01:00
|
|
|
if (LASSO_IS_SAML_ASSERTION(t2->data) == FALSE) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
assertion = t2->data;
|
|
|
|
|
2006-11-08 23:43:39 +01:00
|
|
|
as = LASSO_SAML_AUTHENTICATION_STATEMENT(
|
|
|
|
assertion->AuthenticationStatement);
|
|
|
|
method = as->AuthenticationMethod;
|
|
|
|
|
|
|
|
if (strcmp(method, LASSO_SAML_AUTHENTICATION_METHOD_PASSWORD) == 0)
|
|
|
|
{
|
|
|
|
/* mapping between SAML authentication
|
|
|
|
* methods and Liberty authentication
|
|
|
|
* context is not possible (excepted on
|
|
|
|
* that one)
|
|
|
|
*/
|
|
|
|
method = LASSO_LIB_AUTHN_CONTEXT_CLASS_REF_PASSWORD;
|
|
|
|
}
|
2008-09-12 17:06:58 +02:00
|
|
|
|
2006-11-08 23:43:39 +01:00
|
|
|
if (compa == 0) { /* exact */
|
|
|
|
if (strcmp(method, class_ref) == 0) {
|
|
|
|
matched = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (compa == 1) { /* minimum */
|
|
|
|
/* XXX: implement 'minimum' comparison */
|
|
|
|
} else if (compa == 2) { /* better */
|
|
|
|
/* XXX: implement 'better' comparison */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
/* if nothing specific was asked; don't look for any
|
2008-07-22 14:07:18 +02:00
|
|
|
* particular assertions, one is enough
|
2006-11-08 23:43:39 +01:00
|
|
|
*/
|
2008-07-22 14:07:18 +02:00
|
|
|
matched = (profile->session != NULL && \
|
2009-08-26 17:13:55 +02:00
|
|
|
lasso_session_count_assertions(profile->session) > 0);
|
2006-11-08 23:43:39 +01:00
|
|
|
}
|
2010-04-22 02:44:57 +02:00
|
|
|
lasso_release_list(assertions);
|
2006-11-08 23:43:39 +01:00
|
|
|
|
|
|
|
if (matched == FALSE && request->IsPassive == FALSE)
|
|
|
|
return TRUE;
|
|
|
|
|
2004-12-13 22:40:12 +01:00
|
|
|
if (LASSO_PROFILE(login)->identity == NULL && request->IsPassive &&
|
2004-10-27 11:49:13 +02:00
|
|
|
login->protocolProfile == LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST) {
|
|
|
|
lasso_profile_set_response_status(LASSO_PROFILE(login),
|
|
|
|
LASSO_LIB_STATUS_CODE_NO_PASSIVE);
|
2004-12-13 22:40:12 +01:00
|
|
|
return FALSE;
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2004-12-13 22:40:12 +01:00
|
|
|
return FALSE;
|
2004-09-22 15:21:29 +02:00
|
|
|
}
|
|
|
|
|
2004-12-31 11:51:17 +01:00
|
|
|
/**
|
|
|
|
* lasso_login_process_authn_request_msg:
|
|
|
|
* @login: a #LassoLogin
|
|
|
|
* @authn_request_msg: the authentication request received
|
|
|
|
*
|
|
|
|
* Processes received authentication request, checks it is signed correctly,
|
|
|
|
* checks if requested protocol profile is supported, etc.
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2004-12-31 11:51:17 +01:00
|
|
|
* Return value: 0 on success; or a negative value otherwise.
|
|
|
|
**/
|
2004-09-22 15:21:29 +02:00
|
|
|
gint
|
2004-11-01 19:23:20 +01:00
|
|
|
lasso_login_process_authn_request_msg(LassoLogin *login, const char *authn_request_msg)
|
2004-07-06 03:07:32 +02:00
|
|
|
{
|
2004-10-27 11:49:13 +02:00
|
|
|
LassoProvider *remote_provider;
|
|
|
|
gchar *protocolProfile;
|
2004-11-29 17:38:58 +01:00
|
|
|
gchar *authnRequestSigned;
|
2004-10-27 11:49:13 +02:00
|
|
|
gboolean must_verify_signature = FALSE;
|
|
|
|
gint ret = 0;
|
|
|
|
LassoLibAuthnRequest *request;
|
2004-11-22 14:13:16 +01:00
|
|
|
LassoMessageFormat format;
|
2005-01-28 16:57:56 +01:00
|
|
|
LassoProfile *profile;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
|
|
|
|
2005-01-28 16:57:56 +01:00
|
|
|
profile = LASSO_PROFILE(login);
|
|
|
|
|
2005-11-21 19:51:52 +01:00
|
|
|
IF_SAML2(profile) {
|
2005-11-20 16:38:19 +01:00
|
|
|
return lasso_saml20_login_process_authn_request_msg(login, authn_request_msg);
|
|
|
|
}
|
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
if (authn_request_msg == NULL) {
|
2004-12-15 14:26:31 +01:00
|
|
|
format = 0;
|
2005-01-28 16:57:56 +01:00
|
|
|
if (profile->request == NULL) {
|
2004-12-14 16:46:25 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_MISSING_REQUEST);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* LibAuthnRequest already set by lasso_login_init_idp_initiated_authn_request() */
|
2005-01-28 16:57:56 +01:00
|
|
|
request = LASSO_LIB_AUTHN_REQUEST(profile->request);
|
2008-09-12 17:06:58 +02:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
/* verify that NameIDPolicy is 'any' */
|
|
|
|
if (request->NameIDPolicy == NULL)
|
|
|
|
return LASSO_LOGIN_ERROR_INVALID_NAMEIDPOLICY;
|
2008-09-12 17:06:58 +02:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
if (strcmp(request->NameIDPolicy, LASSO_LIB_NAMEID_POLICY_TYPE_ANY) != 0)
|
|
|
|
return LASSO_LOGIN_ERROR_INVALID_NAMEIDPOLICY;
|
|
|
|
} else {
|
|
|
|
request = lasso_lib_authn_request_new();
|
2004-11-22 14:13:16 +01:00
|
|
|
format = lasso_node_init_from_message(LASSO_NODE(request), authn_request_msg);
|
|
|
|
if (format == LASSO_MESSAGE_FORMAT_UNKNOWN ||
|
|
|
|
format == LASSO_MESSAGE_FORMAT_ERROR) {
|
2004-12-14 16:46:25 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_INVALID_MSG);
|
2004-11-22 14:13:16 +01:00
|
|
|
}
|
2008-09-12 17:06:58 +02:00
|
|
|
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_gobject(profile->request, LASSO_NODE(request));
|
2005-01-22 09:44:13 +01:00
|
|
|
|
|
|
|
/* get remote ProviderID */
|
2009-03-27 16:06:15 +01:00
|
|
|
lasso_assign_string(profile->remote_providerID,
|
2005-01-28 16:57:56 +01:00
|
|
|
LASSO_LIB_AUTHN_REQUEST(profile->request)->ProviderID);
|
2005-01-22 09:44:13 +01:00
|
|
|
|
2009-03-27 16:06:15 +01:00
|
|
|
/* get RelayState */
|
|
|
|
lasso_assign_string(profile->msg_relayState, request->RelayState);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* get ProtocolProfile in lib:AuthnRequest */
|
2005-01-28 16:57:56 +01:00
|
|
|
protocolProfile = LASSO_LIB_AUTHN_REQUEST(profile->request)->ProtocolProfile;
|
2004-10-27 11:49:13 +02:00
|
|
|
if (protocolProfile == NULL ||
|
2004-11-29 11:45:46 +01:00
|
|
|
strcmp(protocolProfile, LASSO_LIB_PROTOCOL_PROFILE_BRWS_ART) == 0) {
|
2004-11-29 16:17:36 +01:00
|
|
|
protocolProfile = LASSO_LIB_PROTOCOL_PROFILE_BRWS_ART;
|
2004-10-27 11:49:13 +02:00
|
|
|
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART;
|
2004-11-29 16:17:36 +01:00
|
|
|
} else if (strcmp(protocolProfile, LASSO_LIB_PROTOCOL_PROFILE_BRWS_POST) == 0) {
|
|
|
|
protocolProfile = LASSO_LIB_PROTOCOL_PROFILE_BRWS_POST;
|
2004-10-27 11:49:13 +02:00
|
|
|
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST;
|
2005-05-10 18:47:15 +02:00
|
|
|
} else if (strcmp(protocolProfile, LASSO_LIB_PROTOCOL_PROFILE_BRWS_LECP) == 0) {
|
|
|
|
protocolProfile = LASSO_LIB_PROTOCOL_PROFILE_BRWS_LECP;
|
|
|
|
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_LECP;
|
2004-11-29 11:45:46 +01:00
|
|
|
} else {
|
2004-12-14 16:46:25 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_INVALID_PROTOCOLPROFILE);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2004-11-29 11:45:46 +01:00
|
|
|
/* check if requested single sign on protocol profile is supported */
|
2005-01-28 16:57:56 +01:00
|
|
|
LASSO_PROVIDER(profile->server)->role = LASSO_PROVIDER_ROLE_IDP;
|
2004-11-29 11:45:46 +01:00
|
|
|
if (lasso_provider_has_protocol_profile(
|
2005-01-28 16:57:56 +01:00
|
|
|
LASSO_PROVIDER(profile->server),
|
2004-11-29 11:45:46 +01:00
|
|
|
LASSO_MD_PROTOCOL_TYPE_SINGLE_SIGN_ON,
|
|
|
|
protocolProfile) == FALSE) {
|
2004-12-14 16:46:25 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE);
|
2004-11-29 11:45:46 +01:00
|
|
|
}
|
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
/* Check authnRequest signature. */
|
2004-11-29 11:45:46 +01:00
|
|
|
if (authn_request_msg != NULL) {
|
2009-10-30 15:47:23 +01:00
|
|
|
remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
|
2004-10-27 11:49:13 +02:00
|
|
|
if (remote_provider != NULL) {
|
|
|
|
/* Is authnRequest signed ? */
|
2004-11-29 17:38:58 +01:00
|
|
|
authnRequestSigned = lasso_provider_get_metadata_one(
|
2004-10-27 11:49:13 +02:00
|
|
|
remote_provider, "AuthnRequestsSigned");
|
2004-11-29 17:38:58 +01:00
|
|
|
if (authnRequestSigned != NULL) {
|
|
|
|
must_verify_signature = strcmp(authnRequestSigned, "true") == 0;
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_release_string(authnRequestSigned);
|
2004-10-27 11:49:13 +02:00
|
|
|
} else {
|
2004-12-31 14:40:38 +01:00
|
|
|
/* missing element in metadata; shouldn't
|
|
|
|
* happen, assume true */
|
|
|
|
must_verify_signature = TRUE;
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
} else {
|
2005-02-05 17:15:53 +01:00
|
|
|
return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* verify request signature */
|
|
|
|
if (must_verify_signature) {
|
|
|
|
ret = lasso_provider_verify_signature(remote_provider,
|
2004-12-10 01:30:01 +01:00
|
|
|
authn_request_msg, "RequestID", format);
|
2005-01-28 16:57:56 +01:00
|
|
|
profile->signature_status = ret;
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-01-28 15:19:40 +01:00
|
|
|
/* create LibAuthnResponse */
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_gobject(profile->response, lasso_lib_authn_response_new(
|
2005-01-28 16:57:56 +01:00
|
|
|
LASSO_PROVIDER(profile->server)->ProviderID,
|
2009-04-30 16:58:20 +02:00
|
|
|
LASSO_LIB_AUTHN_REQUEST(profile->request)));
|
2008-09-12 17:06:58 +02:00
|
|
|
if (LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->MajorVersion == 1 &&
|
2005-11-20 16:38:19 +01:00
|
|
|
LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->MinorVersion < 2) {
|
2005-01-28 16:57:56 +01:00
|
|
|
/* pre-id-ff 1.2, move accordingly */
|
2005-11-20 16:38:19 +01:00
|
|
|
LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->MajorVersion = 1;
|
|
|
|
LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->MinorVersion = 0;
|
2005-01-28 16:57:56 +01:00
|
|
|
}
|
2005-01-28 15:19:40 +01:00
|
|
|
|
|
|
|
|
2004-10-02 21:59:56 +02:00
|
|
|
return ret;
|
2004-07-06 03:07:32 +02:00
|
|
|
}
|
|
|
|
|
2004-12-31 11:51:17 +01:00
|
|
|
/**
|
|
|
|
* lasso_login_process_authn_response_msg:
|
|
|
|
* @login: a #LassoLogin
|
|
|
|
* @authn_response_msg: the authentication response received
|
|
|
|
*
|
|
|
|
* Processes received authentication response.
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2004-12-31 11:51:17 +01:00
|
|
|
* Return value: 0 on success; or a negative value otherwise.
|
|
|
|
**/
|
2004-07-06 03:07:32 +02:00
|
|
|
gint
|
2004-10-27 11:49:13 +02:00
|
|
|
lasso_login_process_authn_response_msg(LassoLogin *login, gchar *authn_response_msg)
|
2004-07-06 03:07:32 +02:00
|
|
|
{
|
2004-11-22 14:13:16 +01:00
|
|
|
LassoMessageFormat format;
|
2004-12-10 17:13:34 +01:00
|
|
|
LassoProvider *remote_provider;
|
2006-11-16 00:58:28 +01:00
|
|
|
LassoProfile *profile;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
|
|
|
g_return_val_if_fail(authn_response_msg != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
|
2006-11-16 00:58:28 +01:00
|
|
|
|
|
|
|
profile = LASSO_PROFILE(login);
|
|
|
|
|
|
|
|
IF_SAML2(profile) {
|
|
|
|
return lasso_saml20_login_process_authn_response_msg(login, authn_response_msg);
|
|
|
|
}
|
2008-09-12 17:06:58 +02:00
|
|
|
|
2005-01-04 16:40:37 +01:00
|
|
|
/* clean state */
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_release_string (profile->remote_providerID);
|
|
|
|
lasso_release_gobject(profile->response);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_gobject(profile->response, lasso_lib_authn_response_new(NULL, NULL));
|
2004-12-28 13:44:22 +01:00
|
|
|
format = lasso_node_init_from_message(
|
2006-11-16 00:58:28 +01:00
|
|
|
LASSO_NODE(profile->response), authn_response_msg);
|
2004-11-22 14:13:16 +01:00
|
|
|
if (format == LASSO_MESSAGE_FORMAT_UNKNOWN || format == LASSO_MESSAGE_FORMAT_ERROR) {
|
2004-12-14 16:46:25 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_INVALID_MSG);
|
2004-11-22 14:13:16 +01:00
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_string(profile->remote_providerID,
|
2006-11-16 00:58:28 +01:00
|
|
|
LASSO_LIB_AUTHN_RESPONSE(profile->response)->ProviderID);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2006-11-16 00:58:28 +01:00
|
|
|
if (profile->remote_providerID == NULL) {
|
2008-09-23 17:15:39 +02:00
|
|
|
return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2009-10-30 15:47:23 +01:00
|
|
|
remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
|
2005-01-21 23:02:56 +01:00
|
|
|
if (LASSO_IS_PROVIDER(remote_provider) == FALSE)
|
2005-02-05 17:15:53 +01:00
|
|
|
return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
|
2004-12-10 17:13:34 +01:00
|
|
|
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_string(profile->msg_relayState, LASSO_LIB_AUTHN_RESPONSE(
|
2006-11-16 00:58:28 +01:00
|
|
|
profile->response)->RelayState);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2006-11-16 00:58:28 +01:00
|
|
|
profile->signature_status = lasso_provider_verify_signature(
|
2004-12-13 19:39:49 +01:00
|
|
|
remote_provider, authn_response_msg, "ResponseID", format);
|
2008-09-23 17:15:39 +02:00
|
|
|
|
2009-01-24 10:33:57 +01:00
|
|
|
if (profile->signature_status) {
|
|
|
|
return profile->signature_status;
|
|
|
|
}
|
2008-09-23 17:15:39 +02:00
|
|
|
return lasso_login_process_response_status_and_assertion(login);
|
2004-07-06 03:07:32 +02:00
|
|
|
}
|
|
|
|
|
2004-12-31 11:51:17 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* lasso_login_process_request_msg:
|
|
|
|
* @login: a #LassoLogin
|
2004-12-31 12:03:45 +01:00
|
|
|
* @request_msg: the artifact request received
|
2004-12-31 11:51:17 +01:00
|
|
|
*
|
|
|
|
* Processes received artifact request.
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2004-12-31 11:51:17 +01:00
|
|
|
* Return value: 0 on success; or a negative value otherwise.
|
|
|
|
**/
|
2004-07-08 03:33:39 +02:00
|
|
|
gint
|
2004-10-27 11:49:13 +02:00
|
|
|
lasso_login_process_request_msg(LassoLogin *login, gchar *request_msg)
|
2004-07-08 03:33:39 +02:00
|
|
|
{
|
2004-10-27 11:49:13 +02:00
|
|
|
gint ret = 0;
|
|
|
|
LassoProfile *profile = LASSO_PROFILE(login);
|
|
|
|
|
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
|
|
|
g_return_val_if_fail(request_msg != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
|
|
|
|
|
2005-11-21 19:51:52 +01:00
|
|
|
IF_SAML2(profile) {
|
2005-11-20 16:38:19 +01:00
|
|
|
return lasso_saml20_login_process_request_msg(login, request_msg);
|
|
|
|
}
|
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
/* rebuild samlp:Request with request_msg */
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_gobject(profile->request, lasso_node_new_from_soap(request_msg));
|
2004-10-27 11:49:13 +02:00
|
|
|
if (profile->request == NULL) {
|
2004-12-15 11:07:09 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_INVALID_MSG);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
/* get AssertionArtifact */
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_string(login->assertionArtifact,
|
2004-10-27 17:41:28 +02:00
|
|
|
LASSO_SAMLP_REQUEST(profile->request)->AssertionArtifact);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2004-12-14 14:50:46 +01:00
|
|
|
/* Keep a copy of request msg so signature can be verified when we get
|
|
|
|
* the providerId in lasso_login_build_response_msg()
|
|
|
|
*/
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_string(login->private_data->soap_request_msg, request_msg);
|
2004-12-14 14:50:46 +01:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
return ret;
|
2004-07-08 03:33:39 +02:00
|
|
|
}
|
|
|
|
|
2004-12-31 11:51:17 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* lasso_login_process_response_msg:
|
|
|
|
* @login: a #LassoLogin
|
2004-12-31 12:03:45 +01:00
|
|
|
* @response_msg: the assertion response received
|
2004-12-31 11:51:17 +01:00
|
|
|
*
|
|
|
|
* Processes received assertion response.
|
2008-09-12 17:06:58 +02:00
|
|
|
*
|
2010-02-10 01:34:09 +01:00
|
|
|
* Return value: 0 on success; or
|
|
|
|
* <itemizedlist>
|
|
|
|
* <listitem><para>#LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if login is not a #LassoLogin object,</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_PARAM_ERROR_INVALID_VALUE if response_msg is NULL,</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_PROFILE_ERROR_INVALID_MSG if the message is not a #LassoSamlpResponse (ID-FF 1.2) or a #LassoSamlp2ResponseMsg (SAML 2.0),</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_PROFILE_ERROR_RESPONSE_DOES_NOT_MATCH_REQUEST if the response does not refer to the request or if the response refer to an unknown request and <link linkend="strict-checking"><literal>strict-checking</literal></link> is activated ,</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_LOGIN_ERROR_REQUEST_DENIED the identity provided
|
|
|
|
* returned a failure status of "RequestDenied"</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_LOGIN_ERROR_FEDERATION_NOT_FOUND if creation of a new
|
|
|
|
* federation was not allowed and none existed,</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_LOGIN_ERROR_UNKNOWN_PRINCIPAL if authentication failed
|
|
|
|
* or/and if the user cancelled the authentication,</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_LOGIN_ERROR_STATUS_NOT_SUCCESS, if the response status
|
|
|
|
* is a failure but we have no more precise error code to report it, you must
|
|
|
|
* look at the second level status in the response,</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND, if the issuing
|
|
|
|
* provider of the assertion is unknown,</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_PROFILE_ERROR_INVALID_ISSUER the issuer of the
|
|
|
|
* assertion received, is not the expected one</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND no statement was fournd, or none statement contains a subject with a name identifier,</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_PROFILE_ERROR_MISSING_STATUS_CODE if the reponse is
|
|
|
|
* missing a <literal>StatusCode</literal> element,</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_PROFILE_ERROR_MISSING_ASSERTION if the message does
|
|
|
|
* not contain any assertion.</para></listitem>
|
|
|
|
* </itemizedlist>
|
2004-12-31 11:51:17 +01:00
|
|
|
**/
|
2004-07-14 14:53:11 +02:00
|
|
|
gint
|
2004-10-27 11:49:13 +02:00
|
|
|
lasso_login_process_response_msg(LassoLogin *login, gchar *response_msg)
|
2004-07-06 03:07:32 +02:00
|
|
|
{
|
2005-11-20 16:38:19 +01:00
|
|
|
LassoProfile *profile;
|
2009-02-17 18:02:01 +01:00
|
|
|
LassoSamlpResponse *response;
|
2005-11-20 16:38:19 +01:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
|
|
|
g_return_val_if_fail(response_msg != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
|
|
|
|
|
2005-11-20 16:38:19 +01:00
|
|
|
profile = LASSO_PROFILE(login);
|
|
|
|
|
2005-11-21 19:51:52 +01:00
|
|
|
IF_SAML2(profile) {
|
2005-11-20 16:38:19 +01:00
|
|
|
return lasso_saml20_login_process_response_msg(login, response_msg);
|
|
|
|
}
|
|
|
|
|
2006-05-10 10:00:45 +02:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
/* rebuild samlp:Response with response_msg */
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_new_gobject(profile->response, lasso_node_new_from_soap(response_msg));
|
2005-11-20 16:38:19 +01:00
|
|
|
if (! LASSO_IS_SAMLP_RESPONSE(profile->response) ) {
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_release_gobject(profile->response);
|
2004-12-15 11:07:09 +01:00
|
|
|
return critical_error(LASSO_PROFILE_ERROR_INVALID_MSG);
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
2009-02-17 18:02:01 +01:00
|
|
|
response = LASSO_SAMLP_RESPONSE(profile->response);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2009-03-27 16:06:41 +01:00
|
|
|
/* Validate RequestID and InResponseTo */
|
|
|
|
if (profile->request || lasso_flag_strict_checking) {
|
|
|
|
char *request_id = NULL;
|
|
|
|
char *response_to = NULL;
|
|
|
|
|
|
|
|
if (LASSO_IS_SAMLP_REQUEST(profile->request)) {
|
|
|
|
request_id = LASSO_SAMLP_REQUEST_ABSTRACT(profile->request)->RequestID;
|
|
|
|
}
|
|
|
|
response_to = LASSO_SAMLP_RESPONSE_ABSTRACT(profile->response)->InResponseTo;
|
|
|
|
|
|
|
|
if ((! request_id && response_to) || /* response to an unknown request, only with
|
|
|
|
strict checking */
|
|
|
|
(profile->request && ! response_to) || /* not a response to our request, because
|
|
|
|
no ref */
|
|
|
|
/* not a response to our request because of mismatch */
|
|
|
|
(request_id && response_to && strcmp(request_id, response_to) != 0)) {
|
|
|
|
return critical_error(LASSO_PROFILE_ERROR_RESPONSE_DOES_NOT_MATCH_REQUEST);
|
|
|
|
} /* else no request and no inResponseTo, IDP initiated response, ok */
|
|
|
|
}
|
|
|
|
|
2009-01-24 10:34:03 +01:00
|
|
|
/* In the artifact profile we cannot verify the signature on the message, we must wait the
|
|
|
|
* verification on the assertion, so for the moment the signature verification failed. */
|
|
|
|
profile->signature_status = LASSO_DS_ERROR_SIGNATURE_VERIFICATION_FAILED;
|
|
|
|
|
|
|
|
xmlNode *signed_response;
|
|
|
|
signed_response = lasso_node_get_original_xmlnode(LASSO_NODE(profile->response));
|
|
|
|
if (signed_response && profile->remote_providerID) {
|
|
|
|
LassoProvider *idp;
|
|
|
|
|
2009-10-30 15:47:23 +01:00
|
|
|
idp = LASSO_PROVIDER(lasso_server_get_provider(profile->server,
|
2009-01-24 10:34:03 +01:00
|
|
|
profile->remote_providerID));
|
|
|
|
profile->signature_status = lasso_provider_verify_saml_signature(idp,
|
2009-03-27 16:04:55 +01:00
|
|
|
signed_response, NULL);
|
2009-01-24 10:34:03 +01:00
|
|
|
}
|
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
return lasso_login_process_response_status_and_assertion(login);
|
2004-07-06 03:07:32 +02:00
|
|
|
}
|
|
|
|
|
2005-01-28 11:25:19 +01:00
|
|
|
|
2005-01-28 00:41:05 +01:00
|
|
|
|
2004-07-13 02:19:21 +02:00
|
|
|
/*****************************************************************************/
|
2004-10-27 11:49:13 +02:00
|
|
|
/* private methods */
|
2004-07-13 02:19:21 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
2004-12-10 00:08:10 +01:00
|
|
|
static struct XmlSnippet schema_snippets[] = {
|
2009-01-24 10:33:40 +01:00
|
|
|
{ "AssertionArtifact", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoLogin, assertionArtifact), NULL, NULL, NULL},
|
|
|
|
{ "NameIDPolicy", SNIPPET_CONTENT, G_STRUCT_OFFSET(LassoLogin, nameIDPolicy), NULL, NULL, NULL},
|
|
|
|
{ "Assertion", SNIPPET_NODE_IN_CHILD, G_STRUCT_OFFSET(LassoLogin, assertion), NULL, NULL, NULL},
|
|
|
|
{NULL, 0, 0, NULL, NULL, NULL}
|
2004-12-10 00:08:10 +01:00
|
|
|
};
|
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
static LassoNodeClass *parent_class = NULL;
|
|
|
|
|
|
|
|
static xmlNode*
|
2004-12-19 21:34:22 +01:00
|
|
|
get_xmlNode(LassoNode *node, gboolean lasso_dump)
|
2004-07-26 14:09:07 +02:00
|
|
|
{
|
2004-10-27 11:49:13 +02:00
|
|
|
xmlNode *xmlnode;
|
|
|
|
LassoLogin *login = LASSO_LOGIN(node);
|
|
|
|
|
2004-12-19 21:34:22 +01:00
|
|
|
xmlnode = parent_class->get_xmlNode(node, lasso_dump);
|
2005-07-31 00:36:54 +02:00
|
|
|
xmlSetProp(xmlnode, (xmlChar*)"LoginDumpVersion", (xmlChar*)"2");
|
2009-03-03 21:52:45 +01:00
|
|
|
xmlSetProp(xmlnode, (xmlChar*)"RequestID", (xmlChar*)LASSO_LOGIN(node)->private_data->request_id);
|
2004-07-26 14:09:07 +02:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
if (login->protocolProfile == LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART)
|
2005-07-31 00:36:54 +02:00
|
|
|
xmlNewTextChild(xmlnode, NULL, (xmlChar*)"ProtocolProfile", (xmlChar*)"Artifact");
|
2007-12-03 19:36:43 +01:00
|
|
|
else if (login->protocolProfile == LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST)
|
2005-07-31 00:36:54 +02:00
|
|
|
xmlNewTextChild(xmlnode, NULL, (xmlChar*)"ProtocolProfile", (xmlChar*)"POST");
|
2007-12-03 19:36:43 +01:00
|
|
|
else if (login->protocolProfile == LASSO_LOGIN_PROTOCOL_PROFILE_REDIRECT)
|
|
|
|
xmlNewTextChild(xmlnode, NULL, (xmlChar*)"ProtocolProfile", (xmlChar*)"Redirect");
|
2004-07-26 14:09:07 +02:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
return xmlnode;
|
2004-07-26 14:09:07 +02:00
|
|
|
}
|
|
|
|
|
2004-11-09 10:08:47 +01:00
|
|
|
static int
|
2004-10-27 11:49:13 +02:00
|
|
|
init_from_xml(LassoNode *node, xmlNode *xmlnode)
|
|
|
|
{
|
|
|
|
LassoLogin *login = LASSO_LOGIN(node);
|
|
|
|
xmlNode *t;
|
2010-04-30 11:23:01 +02:00
|
|
|
int rc = 0;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2004-11-09 10:08:47 +01:00
|
|
|
rc = parent_class->init_from_xml(node, xmlnode);
|
|
|
|
if (rc) return rc;
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2009-03-03 21:52:45 +01:00
|
|
|
lasso_assign_new_string(LASSO_LOGIN(node)->private_data->request_id, (char*)xmlGetProp(xmlnode,
|
|
|
|
(xmlChar*)"RequestID"));
|
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
t = xmlnode->children;
|
|
|
|
while (t) {
|
|
|
|
if (t->type != XML_ELEMENT_NODE) {
|
|
|
|
t = t->next;
|
|
|
|
continue;
|
|
|
|
}
|
2005-07-31 00:36:54 +02:00
|
|
|
if (strcmp((char*)t->name, "ProtocolProfile") == 0) {
|
2004-10-27 11:49:13 +02:00
|
|
|
char *s;
|
2005-07-31 00:36:54 +02:00
|
|
|
s = (char*)xmlNodeGetContent(t);
|
2004-10-27 11:49:13 +02:00
|
|
|
if (strcmp(s, "Artifact") == 0)
|
|
|
|
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART;
|
2007-12-03 19:36:43 +01:00
|
|
|
else if (strcmp(s, "POST") == 0)
|
2004-10-27 11:49:13 +02:00
|
|
|
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_POST;
|
2007-12-03 19:36:43 +01:00
|
|
|
else if (strcmp(s, "Redirect") == 0)
|
|
|
|
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_REDIRECT;
|
2004-10-27 11:49:13 +02:00
|
|
|
xmlFree(s);
|
|
|
|
}
|
|
|
|
t = t->next;
|
|
|
|
}
|
2004-11-09 10:08:47 +01:00
|
|
|
return 0;
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
2004-07-13 02:19:21 +02:00
|
|
|
|
2004-12-14 14:50:46 +01:00
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/* overridden parent class methods */
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
static void
|
|
|
|
dispose(GObject *object)
|
|
|
|
{
|
|
|
|
LassoLogin *login = LASSO_LOGIN(object);
|
2008-05-20 20:34:09 +02:00
|
|
|
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_release_string(login->private_data->soap_request_msg);
|
|
|
|
lasso_release_gobject(login->private_data->saml2_assertion);
|
2008-05-20 20:34:09 +02:00
|
|
|
|
2006-01-25 12:18:52 +01:00
|
|
|
#ifdef LASSO_WSF_ENABLED
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_release_gobject(login->private_data->resourceId);
|
|
|
|
lasso_release_gobject(login->private_data->encryptedResourceId);
|
2006-01-25 12:18:52 +01:00
|
|
|
#endif
|
2009-02-17 18:02:01 +01:00
|
|
|
lasso_release_string(login->private_data->request_id);
|
2004-12-14 14:50:46 +01:00
|
|
|
G_OBJECT_CLASS(parent_class)->dispose(object);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
finalize(GObject *object)
|
2008-09-12 17:06:58 +02:00
|
|
|
{
|
2004-12-14 14:50:46 +01:00
|
|
|
LassoLogin *login = LASSO_LOGIN(object);
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_release(login->private_data);
|
2004-12-14 14:50:46 +01:00
|
|
|
G_OBJECT_CLASS(parent_class)->finalize(object);
|
|
|
|
}
|
|
|
|
|
2004-07-06 03:07:32 +02:00
|
|
|
/*****************************************************************************/
|
2004-10-27 11:49:13 +02:00
|
|
|
/* instance and class init functions */
|
2004-07-06 03:07:32 +02:00
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
|
|
static void
|
2004-10-27 11:49:13 +02:00
|
|
|
instance_init(LassoLogin *login)
|
2004-07-06 03:07:32 +02:00
|
|
|
{
|
2009-02-17 18:02:01 +01:00
|
|
|
login->private_data = g_new0(LassoLoginPrivate, 1);
|
2004-12-14 14:50:46 +01:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
login->protocolProfile = 0;
|
|
|
|
login->assertionArtifact = NULL;
|
2004-12-10 00:08:10 +01:00
|
|
|
login->nameIDPolicy = NULL;
|
|
|
|
login->http_method = 0;
|
2004-07-06 03:07:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-10-27 11:49:13 +02:00
|
|
|
class_init(LassoLoginClass *klass)
|
2004-07-06 03:07:32 +02:00
|
|
|
{
|
2004-12-10 00:08:10 +01:00
|
|
|
LassoNodeClass *nclass = LASSO_NODE_CLASS(klass);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2004-12-10 00:08:10 +01:00
|
|
|
parent_class = g_type_class_peek_parent(klass);
|
|
|
|
nclass->get_xmlNode = get_xmlNode;
|
|
|
|
nclass->init_from_xml = init_from_xml;
|
|
|
|
nclass->node_data = g_new0(LassoNodeClassData, 1);
|
|
|
|
lasso_node_class_set_nodename(nclass, "Login");
|
|
|
|
lasso_node_class_add_snippets(nclass, schema_snippets);
|
2004-12-14 14:50:46 +01:00
|
|
|
|
|
|
|
G_OBJECT_CLASS(klass)->dispose = dispose;
|
|
|
|
G_OBJECT_CLASS(klass)->finalize = finalize;
|
2004-07-06 03:07:32 +02:00
|
|
|
}
|
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
GType
|
|
|
|
lasso_login_get_type()
|
|
|
|
{
|
|
|
|
static GType this_type = 0;
|
|
|
|
|
|
|
|
if (!this_type) {
|
|
|
|
static const GTypeInfo this_info = {
|
|
|
|
sizeof(LassoLoginClass),
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
(GClassInitFunc) class_init,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
sizeof(LassoLogin),
|
|
|
|
0,
|
|
|
|
(GInstanceInitFunc) instance_init,
|
2009-01-24 10:33:40 +01:00
|
|
|
NULL
|
2004-10-27 11:49:13 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
this_type = g_type_register_static(LASSO_TYPE_PROFILE,
|
|
|
|
"LassoLogin", &this_info, 0);
|
|
|
|
}
|
|
|
|
return this_type;
|
2004-07-06 03:07:32 +02:00
|
|
|
}
|
|
|
|
|
2004-12-22 13:48:05 +01:00
|
|
|
/**
|
|
|
|
* lasso_login_new
|
2004-12-22 22:38:06 +01:00
|
|
|
* @server: the #LassoServer
|
2004-12-22 13:48:05 +01:00
|
|
|
*
|
|
|
|
* Creates a new #LassoLogin.
|
|
|
|
*
|
|
|
|
* Return value: a newly created #LassoLogin object; or NULL if an error
|
|
|
|
* occured
|
|
|
|
**/
|
2004-07-19 02:13:41 +02:00
|
|
|
LassoLogin*
|
2004-07-26 19:36:28 +02:00
|
|
|
lasso_login_new(LassoServer *server)
|
2004-07-06 03:07:32 +02:00
|
|
|
{
|
2004-10-27 11:49:13 +02:00
|
|
|
LassoLogin *login = NULL;
|
2004-07-06 03:07:32 +02:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
g_return_val_if_fail(LASSO_IS_SERVER(server), NULL);
|
2004-08-09 12:53:47 +02:00
|
|
|
|
2004-10-27 11:49:13 +02:00
|
|
|
login = g_object_new(LASSO_TYPE_LOGIN, NULL);
|
2009-04-30 16:58:20 +02:00
|
|
|
lasso_assign_gobject(LASSO_PROFILE(login)->server, server);
|
2004-10-27 11:49:13 +02:00
|
|
|
|
|
|
|
return login;
|
2004-07-06 03:07:32 +02:00
|
|
|
}
|
2004-07-09 19:13:24 +02:00
|
|
|
|
2004-12-22 13:48:05 +01:00
|
|
|
/**
|
|
|
|
* lasso_login_new_from_dump:
|
2004-12-22 22:38:06 +01:00
|
|
|
* @server: the #LassoServer
|
2004-12-22 13:48:05 +01:00
|
|
|
* @dump: XML login dump
|
|
|
|
*
|
|
|
|
* Restores the @dump to a new #LassoLogin.
|
|
|
|
*
|
2004-12-23 14:11:03 +01:00
|
|
|
* Return value: a newly created #LassoLogin; or NULL if an error occured.
|
2004-12-22 13:48:05 +01:00
|
|
|
**/
|
2004-07-19 02:13:41 +02:00
|
|
|
LassoLogin*
|
2004-10-27 11:49:13 +02:00
|
|
|
lasso_login_new_from_dump(LassoServer *server, const gchar *dump)
|
2004-07-09 19:13:24 +02:00
|
|
|
{
|
2004-10-27 11:49:13 +02:00
|
|
|
LassoLogin *login;
|
|
|
|
|
2010-02-04 01:02:12 +01:00
|
|
|
login = (LassoLogin*)lasso_node_new_from_dump(dump);
|
|
|
|
if (! LASSO_IS_LOGIN(login)) {
|
|
|
|
lasso_release_gobject(login);
|
|
|
|
} else {
|
|
|
|
lasso_assign_gobject(login->parent.server, server);
|
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
return login;
|
2004-07-09 19:13:24 +02:00
|
|
|
}
|
2004-10-27 11:49:13 +02:00
|
|
|
|
2004-12-22 13:48:05 +01:00
|
|
|
/**
|
|
|
|
* lasso_login_dump:
|
|
|
|
* @login: a #LassoLogin
|
|
|
|
*
|
|
|
|
* Dumps @login content to an XML string.
|
|
|
|
*
|
|
|
|
* Return value: the dump string. It must be freed by the caller.
|
|
|
|
**/
|
2004-10-27 11:49:13 +02:00
|
|
|
gchar*
|
|
|
|
lasso_login_dump(LassoLogin *login)
|
|
|
|
{
|
2005-01-01 19:53:30 +01:00
|
|
|
return lasso_node_dump(LASSO_NODE(login));
|
2004-10-27 11:49:13 +02:00
|
|
|
}
|
|
|
|
|
2004-12-14 20:20:20 +01:00
|
|
|
|
2004-12-31 12:07:45 +01:00
|
|
|
/**
|
|
|
|
* lasso_login_validate_request_msg:
|
2004-12-31 12:22:36 +01:00
|
|
|
* @login: a #LassoLogin
|
2004-12-31 12:07:45 +01:00
|
|
|
* @authentication_result: whether user has authenticated succesfully
|
|
|
|
* @is_consent_obtained: whether user consent has been obtained
|
|
|
|
*
|
|
|
|
* Initializes a response to the authentication request received.
|
|
|
|
*
|
2010-02-01 20:50:03 +01:00
|
|
|
* Return value: 0 on success; or <itemizedlist>
|
|
|
|
* <listitem><para>#LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if login is not a #LassoLogin object,</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_LOGIN_ERROR_REQUEST_DENIED</para> if @authentication_result if FALSE,</listitem>
|
|
|
|
* <listitem><para>#LASSO_LOGIN_ERROR_INVALID_SIGNATURE if signature validation of the request
|
|
|
|
* failed,</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_LOGIN_ERROR_UNSIGNED_AUTHN_REQUEST if no signature was present on the
|
|
|
|
* request,</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_LOGIN_ERROR_FEDERATION_NOT_FOUND if federation policy is
|
|
|
|
* #LASSO_LIB_NAMEID_POLICY_TYPE_NONE and no federation was found in the #LassoIdentity object
|
|
|
|
* (ID-FF 1.2 case)</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_LOGIN_ERROR_INVALID_NAMEIDPOLICY if request policy is not one of
|
|
|
|
* #LASSO_LIB_NAMEID_POLICY_TYPE_FEDERATED or #LASSO_LIB_NAMEID_POLICY_TYPE_ANY (ID-FF 1.2 case) or if no NameID policy was defined or the AllowCreate request flag is FALSE (SAML 2.0 case),</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_LOGIN_ERROR_CONSENT_NOT_OBTAINED if @is_consent_obtained is FALSE and
|
|
|
|
* conssent was necessary (for example if the request does not communicate that consent was already
|
|
|
|
* obtained from the user),</para></listitem>
|
|
|
|
* <listitem><para>#LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND if the requesting provider is unknown,</para></listitem>
|
|
|
|
* </itemizedlist>
|
2004-12-31 12:07:45 +01:00
|
|
|
**/
|
2004-12-14 20:20:20 +01:00
|
|
|
int
|
|
|
|
lasso_login_validate_request_msg(LassoLogin *login, gboolean authentication_result,
|
|
|
|
gboolean is_consent_obtained)
|
|
|
|
{
|
|
|
|
LassoProfile *profile;
|
|
|
|
gint ret = 0;
|
|
|
|
|
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
|
|
|
|
|
|
|
profile = LASSO_PROFILE(login);
|
|
|
|
|
2005-11-21 19:51:52 +01:00
|
|
|
IF_SAML2(profile) {
|
2005-11-20 16:38:19 +01:00
|
|
|
return lasso_saml20_login_validate_request_msg(login,
|
|
|
|
authentication_result, is_consent_obtained);
|
|
|
|
}
|
|
|
|
|
2004-12-14 20:20:20 +01:00
|
|
|
/* modify AuthnResponse StatusCode if user authentication is not OK */
|
|
|
|
if (authentication_result == FALSE) {
|
|
|
|
lasso_profile_set_response_status(profile,
|
2004-12-28 16:52:25 +01:00
|
|
|
LASSO_LIB_STATUS_CODE_UNKNOWN_PRINCIPAL);
|
2004-12-14 20:20:20 +01:00
|
|
|
return LASSO_LOGIN_ERROR_REQUEST_DENIED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if signature is not OK => modify AuthnResponse StatusCode */
|
|
|
|
if (profile->signature_status == LASSO_DS_ERROR_INVALID_SIGNATURE) {
|
|
|
|
lasso_profile_set_response_status(profile,
|
|
|
|
LASSO_LIB_STATUS_CODE_INVALID_SIGNATURE);
|
|
|
|
return LASSO_LOGIN_ERROR_INVALID_SIGNATURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (profile->signature_status == LASSO_DS_ERROR_SIGNATURE_NOT_FOUND) {
|
|
|
|
/* Unsigned AuthnRequest */
|
|
|
|
lasso_profile_set_response_status(profile,
|
|
|
|
LASSO_LIB_STATUS_CODE_UNSIGNED_AUTHN_REQUEST);
|
|
|
|
return LASSO_LOGIN_ERROR_UNSIGNED_AUTHN_REQUEST;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (profile->signature_status == 0 && authentication_result == TRUE) {
|
|
|
|
/* process federation */
|
|
|
|
ret = lasso_login_process_federation(login, is_consent_obtained);
|
2005-03-22 16:32:46 +01:00
|
|
|
if (ret != 0)
|
2004-12-14 20:20:20 +01:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
lasso_profile_set_response_status(profile, LASSO_SAML_STATUS_CODE_SUCCESS);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2006-12-05 18:16:54 +01:00
|
|
|
|
|
|
|
int
|
|
|
|
lasso_login_process_paos_response_msg(LassoLogin *login, gchar *msg)
|
|
|
|
{
|
|
|
|
LassoProfile *profile;
|
|
|
|
|
|
|
|
g_return_val_if_fail(LASSO_IS_LOGIN(login), LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
|
2007-01-06 23:51:13 +01:00
|
|
|
g_return_val_if_fail(msg != NULL, LASSO_PARAM_ERROR_INVALID_VALUE);
|
2006-12-05 18:16:54 +01:00
|
|
|
|
|
|
|
profile = LASSO_PROFILE(login);
|
|
|
|
|
|
|
|
IF_SAML2(profile) {
|
|
|
|
return lasso_saml20_login_process_paos_response_msg(login, msg);
|
|
|
|
}
|
|
|
|
|
2007-01-06 23:51:13 +01:00
|
|
|
return 0;
|
2006-12-05 18:16:54 +01:00
|
|
|
}
|
2010-01-04 10:14:20 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* lasso_login_get_assertion:
|
|
|
|
* @login: a #LassoLogin object
|
|
|
|
*
|
|
|
|
* Return the last build assertion.
|
|
|
|
*
|
|
|
|
* Return value: a #LassoNode representing the build assertion (generally a #LassoSamlAssertion when
|
|
|
|
* using ID-FF 1.2 or a #LassoSaml2Assertion when using SAML 2.0)
|
|
|
|
*/
|
|
|
|
LassoNode*
|
|
|
|
lasso_login_get_assertion(LassoLogin *login)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (LASSO_IS_LOGIN (login), NULL);
|
|
|
|
|
|
|
|
if (login->private_data && login->private_data->saml2_assertion)
|
|
|
|
return (LassoNode*)g_object_ref(login->private_data->saml2_assertion);
|
|
|
|
|
|
|
|
return (LassoNode*)g_object_ref(login->assertion);
|
|
|
|
}
|