summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-10-06 17:02:31 +0200
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-10-06 17:02:31 +0200
commitf5b88c854a2e24013b9536cfb8819817831269a6 (patch)
treea339a4f6745d52f300f5ee64f593d8b7ffc8d39a
parentece66aa4774c5e830e962d8e5d03a19f07a86df7 (diff)
parent21d61b5ba6a44e5de788afbe5fb910b68ccd0414 (diff)
downloadlasso-f5b88c854a2e24013b9536cfb8819817831269a6.tar.gz
lasso-f5b88c854a2e24013b9536cfb8819817831269a6.tar.xz
lasso-f5b88c854a2e24013b9536cfb8819817831269a6.zip
Merge branch 'hotfixes-2.3.4'
-rw-r--r--configure.ac4
-rw-r--r--docs/reference/lasso/lasso-docs.sgml2
-rw-r--r--lasso/id-ff/login.c168
-rw-r--r--lasso/id-ff/providerprivate.h2
-rw-r--r--lasso/saml-2.0/login.c2
-rw-r--r--lasso/saml-2.0/provider.c29
6 files changed, 166 insertions, 41 deletions
diff --git a/configure.ac b/configure.ac
index 59c0a1f9..1ccb4146 100644
--- a/configure.ac
+++ b/configure.ac
@@ -15,7 +15,7 @@ dnl - Second number is the number of supported API versions where API version >
dnl first number.
dnl - Third number is the current API version implementation version number.
dnl See libtool explanations about current, age and release, later in this file.
-AC_INIT([lasso], 2.3.3, lasso-devel@lists.labs.libre-entreprise.org)
+AC_INIT([lasso], 2.3.4, lasso-devel@lists.labs.libre-entreprise.org)
dnl Check if autoconf ver > 2.53
AC_PREREQ(2.53)
AC_CONFIG_MACRO_DIR([m4])
@@ -184,7 +184,7 @@ dnl - interfaces removed -> AGE = 0
# m = a
# r = r
current=`expr $VERSION_MAJOR + $VERSION_MINOR`
-LASSO_VERSION_INFO="12:1:9"
+LASSO_VERSION_INFO="12:2:9"
AC_SUBST(LASSO_VERSION_INFO)
dnl Compute the minimal supported ABI version for Win32 scripts and resources files.
diff --git a/docs/reference/lasso/lasso-docs.sgml b/docs/reference/lasso/lasso-docs.sgml
index 009813c6..e92d447e 100644
--- a/docs/reference/lasso/lasso-docs.sgml
+++ b/docs/reference/lasso/lasso-docs.sgml
@@ -21,7 +21,7 @@
</legalnotice>
<copyright>
- <year>2004, 2005, 2006, 2007, 2008, 2009</year>
+ <year>2004, 2005, 2006, 2007, 2008, 2009, 2010</year>
<holder>Entr'ouvert</holder>
</copyright>
diff --git a/lasso/id-ff/login.c b/lasso/id-ff/login.c
index 85deb368..b605aff5 100644
--- a/lasso/id-ff/login.c
+++ b/lasso/id-ff/login.c
@@ -307,8 +307,6 @@ static void lasso_login_build_assertion_artifact(LassoLogin *login);
* </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>
@@ -876,17 +874,11 @@ lasso_login_build_assertion_artifact(LassoLogin *login)
* </para></listitem>
* <listitem><para>
* LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID if no remote provider ID was setup in the login
- * </para></listitem>
- * <listitem><para>
* profile object, it's usually done by lasso_login_process_authn_request_msg,
* </para></listitem>
* <listitem><para>
* LASSO_PROFILE_ERROR_INVALID_HTTP_METHOD if the HTTP method is neither LASSO_HTTP_METHOD_REDIRECT
- * </para></listitem>
- * <listitem><para>
* or LASSO_HTTP_METHOD_POST (ID-FF 1.2 case) or neither LASSO_HTTP_METHOD_ARTIFACT_GET or
- * </para></listitem>
- * <listitem><para>
* LASSO_HTTP_METHOD_ARTIFACT_POST (SAML 2.0 case) for SAML 2.0),
* </para></listitem>
* <listitem><para>
@@ -897,8 +889,6 @@ lasso_login_build_assertion_artifact(LassoLogin *login)
* </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>
@@ -1602,18 +1592,44 @@ lasso_login_init_authn_request(LassoLogin *login, const gchar *remote_providerID
* 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
+ * 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_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),
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
* LASSO_PROFILE_ERROR_MISSING_ARTIFACT if no artifact field was found in the query string (only
* possible for the LASSO_HTTP_METHOD_REDIRECT case),
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
* 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 --,
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
* LASSO_PROFILE_ERROR_MISSING_REMOTE_PROVIDERID if no provider ID could be found corresponding to
* the hash contained in the artifact.
+ * </para>
+ * </listitem>
+ * </itemizedlist>
*
**/
gint
@@ -1896,7 +1912,87 @@ lasso_login_must_authenticate(LassoLogin *login)
* Processes received authentication request, checks it is signed correctly,
* checks if requested protocol profile is supported, etc.
*
- * Return value: 0 on success; or a negative value otherwise.
+ * Return value: 0 on success; or
+ * <itemizedlist>
+ * <listitem>
+ * <para>
+ * #LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ if login is no a #LassoLogin object,
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
+ * #LASSO_PROFILE_ERROR_MISSING_REQUEST if @authn_request_msg is #NULL and no request as actually
+ * been processed or initialized &#151; see lasso_login_init_idp_initiated_authn_request(),
+ *
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
+ * #LASSO_PROFILE_ERROR_INVALID_MSG if the content of @authn_request_msg cannot be parsed to as a
+ * valid lib:AuthnRequest messages for any support binding (mainly HTTP-Redirect, HTTP-Post and
+ * SOAP),
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
+ *
+ * #LASSO_PROFILE_ERROR_MISSING_ISSUER if the parsed samlp2:AuthnRequest does not have a proper Issuer element,
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
+ *
+ * #LASSO_PROFILE_ERROR_INVALID_REQUEST if the parsed message does not validate as a valid
+ * samlp2:AuthnRequest (SAMLv2) i.e. if there is no Issuer, or mutually exclusive attributes are
+ * used (ProtocolBinding and AssertionConsumerServiceIndex),
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
+ *
+ * #LASSO_PROFILE_ERROR_INVALID_PROTOCOLPROFILE if the protocolProfile (ID-FFv1.2) or the
+ * protocolBinding (SAMLv2) is unsupported by Lasso,
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
+ *
+ * #LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE if the protocolProfile (ID-FFv1.2) or the protocolBinding
+ * (SAMLv2) for the AssertionConsumer is unsupported by this provider implementation as indicated by
+ * its metadata file,
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
+ *
+ * #LASSO_PROFILE_ERROR_UNKNOWN_PROVIDER, or
+ * #LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND if the metadata for the issuer of the request are absent
+ * from the #LassoServer object of this profile,
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
+ *
+ * #LASSO_DS_ERROR_SIGNATURE_NOT_FOUND if no signature could be found and signature validation is
+ * forced &#151; by the service provider metadata with the AuthnRequestsSigned attribute
+ * (ID-FFv1.2&SAMLv2), the attribute WantAuthnRequestsSigned in the identity provider metadata file
+ * (SAMLv2) or as advised by the lasso_profile_set_signature_verify_hint() method),
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
+ *
+ * #LASSO_DS_ERROR_SIGNATURE_VERIFICATION_FAILED if the signature validation failed on a present
+ * signature,
+ * </para>
+ * </listitem>
+ * <listitem>
+ * <para>
+ * #LASSO_DS_ERROR_INVALID_SIGNATURE if the signature was malformed and a signature was present,
+ * </para>
+ * </listitem>
+ * </itemizedlist>
+ *
**/
gint
lasso_login_process_authn_request_msg(LassoLogin *login, const char *authn_request_msg)
@@ -1934,7 +2030,11 @@ lasso_login_process_authn_request_msg(LassoLogin *login, const char *authn_reque
return critical_error(LASSO_PROFILE_ERROR_INVALID_MSG);
}
- lasso_assign_new_gobject(profile->request, LASSO_NODE(request));
+ lasso_assign_new_gobject(profile->request, request);
+ if (! LASSO_IS_LIB_AUTHN_REQUEST(profile->request)) {
+ lasso_release_gobject(profile->request);
+ return LASSO_PROFILE_ERROR_INVALID_MSG;
+ }
/* get remote ProviderID */
lasso_assign_string(profile->remote_providerID,
@@ -1972,28 +2072,38 @@ lasso_login_process_authn_request_msg(LassoLogin *login, const char *authn_reque
/* Check authnRequest signature. */
if (authn_request_msg != NULL) {
+ LassoProfileSignatureVerifyHint sig_verify_hint;
+
+ sig_verify_hint = lasso_profile_get_signature_verify_hint(profile);
remote_provider = lasso_server_get_provider(profile->server, profile->remote_providerID);
- if (remote_provider != NULL) {
- /* Is authnRequest signed ? */
- authnRequestSigned = lasso_provider_get_metadata_one(
- remote_provider, "AuthnRequestsSigned");
- if (authnRequestSigned != NULL) {
- must_verify_signature = strcmp(authnRequestSigned, "true") == 0;
- lasso_release_string(authnRequestSigned);
- } else {
- /* missing element in metadata; shouldn't
- * happen, assume true */
- must_verify_signature = TRUE;
- }
- } else {
+ if (remote_provider == NULL) {
return critical_error(LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND);
}
-
- /* verify request signature */
+ /* Is authnRequest signed ? */
+ must_verify_signature = TRUE;
+ authnRequestSigned = lasso_provider_get_metadata_one(
+ remote_provider, "AuthnRequestsSigned");
+ if (authnRequestSigned != NULL) {
+ must_verify_signature = strcmp(authnRequestSigned, "true") == 0;
+ lasso_release_string(authnRequestSigned);
+ }
+ if (sig_verify_hint == LASSO_PROFILE_SIGNATURE_VERIFY_HINT_FORCE) {
+ must_verify_signature = TRUE;
+ }
+ if (sig_verify_hint == LASSO_PROFILE_SIGNATURE_VERIFY_HINT_IGNORE) {
+ must_verify_signature = FALSE;
+ }
+ /* reset the signature_status, and if signature validation was not really needed
+ * just choke on the presence of an invalid signature, if no signature just goes on
+ * */
+ profile->signature_status = 0;
if (must_verify_signature) {
ret = lasso_provider_verify_signature(remote_provider,
authn_request_msg, "RequestID", format);
- profile->signature_status = ret;
+ if (profile == LASSO_PROFILE_SIGNATURE_VERIFY_HINT_MAYBE && ret !=
+ LASSO_DS_ERROR_SIGNATURE_NOT_FOUND) {
+ profile->signature_status = ret;
+ }
}
}
diff --git a/lasso/id-ff/providerprivate.h b/lasso/id-ff/providerprivate.h
index 66b9ad08..1adce734 100644
--- a/lasso/id-ff/providerprivate.h
+++ b/lasso/id-ff/providerprivate.h
@@ -49,7 +49,7 @@ struct EndpointType_s {
char *url;
char *return_url;
int index;
- gboolean is_default;
+ int is_default;
};
typedef struct EndpointType_s EndpointType;
diff --git a/lasso/saml-2.0/login.c b/lasso/saml-2.0/login.c
index aa892315..a75e4cc0 100644
--- a/lasso/saml-2.0/login.c
+++ b/lasso/saml-2.0/login.c
@@ -288,7 +288,7 @@ lasso_saml20_login_process_authn_request_msg(LassoLogin *login, const char *auth
lasso_check_good_rc(lasso_saml20_profile_process_any_request(profile, request, authn_request_msg));
}
if (! LASSO_IS_SAMLP2_AUTHN_REQUEST(request)) {
- return critical_error(LASSO_PROFILE_ERROR_MISSING_REQUEST);
+ return critical_error(LASSO_PROFILE_ERROR_INVALID_MSG);
}
authn_request = LASSO_SAMLP2_AUTHN_REQUEST(request);
/* intialize the response */
diff --git a/lasso/saml-2.0/provider.c b/lasso/saml-2.0/provider.c
index bc9e70f1..15cf2a81 100644
--- a/lasso/saml-2.0/provider.c
+++ b/lasso/saml-2.0/provider.c
@@ -145,7 +145,7 @@ load_endpoint_type2(xmlNode *xmlnode, LassoProvider *provider, LassoProviderRole
xmlChar *isDefault = getSaml2MdProp(xmlnode, LASSO_SAML2_METADATA_ATTRIBUTE_ISDEFAULT);
gboolean indexed_endpoint = FALSE;
int idx = *counter++;
- gboolean is_default = FALSE;
+ int is_default = 0;
EndpointType *endpoint_type;
if (! binding || ! location) {
@@ -158,7 +158,18 @@ load_endpoint_type2(xmlNode *xmlnode, LassoProvider *provider, LassoProviderRole
warning("Invalid AssertionConsumerService, no index set");
goto cleanup;
}
- is_default = xsdIsTrue(isDefault);
+ /* isDefault is 0 if invalid or not present
+ * -1 if true (comes first)
+ * +1 if false (comes last)
+ */
+ if (isDefault) {
+ if (xsdIsTrue(isDefault)) {
+ is_default = -1;
+ }
+ if (xsdIsFalse(isDefault)) {
+ is_default = 1;
+ }
+ }
}
endpoint_type = g_new0(EndpointType, 1);
endpoint_type->kind = g_strdup((char*)xmlnode->name);
@@ -182,6 +193,13 @@ static gint
compare_endpoint_type(const EndpointType *a, const EndpointType *b) {
int c;
+ /* order the sequence of endpoints:
+ * - first by role,
+ * - then by profile,
+ * - then by isDefault attribute (truth first, then absent, then false)
+ * - then by index
+ * - then by binding
+ */
if (a->role < b->role)
return -1;
if (a->role > b->role)
@@ -189,12 +207,9 @@ compare_endpoint_type(const EndpointType *a, const EndpointType *b) {
c = g_strcmp0(a->kind,b->kind);
if (c != 0)
return c;
- c = g_strcmp0(a->binding,b->binding);
- if (c != 0)
- return c;
- if (a->is_default && ! b->is_default)
+ if (a->is_default < b->is_default)
return -1;
- if (! a->is_default && b->is_default)
+ if (a->is_default > b->is_default)
return +1;
if (a->index < b->index)
return -1;