Merge branch 'hotfixes-2.3.1'

This commit is contained in:
Benjamin Dauvergne 2010-09-07 17:02:12 +02:00
commit 3e8c2b24b7
28 changed files with 1918 additions and 374 deletions

259
ChangeLog
View File

@ -1,3 +1,262 @@
2010-09-07 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* configure.ac, lasso/saml-2.0/profile.c:
[SAMLv2] when no artifact message is present, still return a success
status
It is mandated by the specification.
2010-09-06 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* tests/integration/saml2/__init__.py:
[Tests integration] fix configuration variable name
2010-09-03 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/id-ff/provider.c:
[Core] fix memory leak in lasso_endpoint_free
2010-09-03 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/id-ff/provider.c, lasso/saml-2.0/provider.c:
[ID-FFv1.2&SAMLv2] add more warning for failure to load metadata file
Report detailf of the failure through warning log.
2010-09-03 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/saml-2.0/profile.c, lasso/xml/strings.h:
[SAMLv2] when failing to recreate the content for the ArtefactResponse set a lasso specific status code
2010-09-01 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/saml-2.0/profile.c:
[SAMLv2] change the way content is stored and loaded for the
HTTP-Artifact binding
Previously content was stored as the result of lasso_node_dump method
then reloaded, and then serialized again as part of the
ArtifactResponse message. lasso_node_dump was ignoring all hint to
sign node, but keeping the needed parameters around. That's not what
must be done, the signature should happen at the generation of the
artifact and the result must manipulated as is (i.e. XML content) and
never moved back to the land of LassoNode objects.
Now the content is:
- first removed of any signature at the message level, because the
ArtifactResponse will take care of this, (any signature under this
level (like at the assertion) is kept),
- serialized using lasso_node_export_to_xml,
- reloaded using lasso_xml_parse_memory,
- and put into the ArtifactResponse using a
lasso_misc_text_node_new_with_xml_node.
2010-09-01 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/saml-2.0/profile.c, lasso/saml-2.0/profileprivate.h:
[SAMLv2] make lasso_saml20_profile_generate_artifact a static function
It is only used in lasso/saml-2.0/profile.c anyway.
2010-09-01 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/xml/xml.c:
[Core] load signature parameters
Generic signature parameters (attached as qdata to nodes) is now
reloaded when initializing a node from XML for a node type with a
signature snippet in its metadatas.
It fixes the problematic usage of ciphered private keys with the
HTTP-Artifact binding (which needs to keep a copy of the AuthnResponse
around and to sign it later).
2010-09-01 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/xml/xml.c:
[Core] add private function to read an integer attribute
This function does integer parsing and range checks, it returns TRUE if
all goes well.
2010-09-01 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/xml/tools.c, lasso/xml/xml.h:
[Core] add LAST enum values to LassoSignatureMethod and
LassoSignatureType enumerations
It helps making range checks.
2010-09-01 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* bindings/java/lang.py, bindings/perl/lang.py,
bindings/php5/wrapper_source.py, bindings/python/lang.py,
lasso/xml/strings.h:
[Strings] add string constant for the internal XML attributes used in
dumps
Add string constants for signature method, signature type, private key
(file path or content), private key password and certificate (file
path or content).
Add cast for xmlChar constant strings definition in python bindings,
it assumed all constant strings were char*.
2010-08-31 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso.doap:
[DOAP] fix typos
Tags were badly formatted.
2010-08-25 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/saml-2.0/login.c:
[SAMLv2] mark Redirect binding as an invalid binding for return AuthnResponse
This is really not supported by the SAMLv2 protocol.
2010-08-25 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/saml-2.0/login.c:
[SAMLv2] fix string in comment
2010-08-25 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/saml-2.0/login.c:
[SAMLv2] replace use of lasso_provider_get_default_name_id_format with direct use of lasso_provider_get_metadata_one_for_role
The first is trying to use provider->role to know which kind of role
descriptor to lookup, but for the server object this field is 0 and
when building authn request we know that we want our default
NameIDFormat for the SP sso descriptor.
2010-08-25 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/saml-2.0/provider.c:
[SAMLv2] rebuild specialized LassoProvider methods upon new endpoints storage
The new way of storing endpoints allows to keep ordering between
endpoints with respect to the order of the index and isDefault field
for indexed endpoint type, and to the XML node orders for other
endpoints.
It also simplifies the code.
2010-08-25 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/id-ff/provider.c:
[Core] add destroy code for new private field endpoints
The contained string must be disallocated if the object is destroyed.
2010-08-25 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/id-ff/providerprivate.h:
[Core] add structure to store endpoints type for metadata files
This new C structure will allow to filter ID-FFv1.2 and SAMLv2
endpoints more easily.
2010-08-25 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/xml/xml.c:
[XML] use strtol instead of atoi to parse XSchema integers
This commit also reject negative integers from being parsed (all
integers in SAMLv2 and ID-FFv1.2 schemas are positive integers).
2010-08-25 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/saml-2.0/login.c:
[SAMLv2] when AuthnRequest contains invalid attributes returns
INVALID_REQUEST not NO_DEFAULT_ENDPOINT
This is the right status to return.
2010-08-05 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* lasso/id-ff/provider.h:
[Core] fix change of enumeration value
This change broke the API, revert it.
2010-07-27 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* website/web/index.xml:
[Website] update download link on front page
2010-07-27 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* website/templates/base.ezt:
[Website] fix typos
2010-07-27 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* website/templates/base.ezt, website/web/download/index.xml:
[Website] fix source and download links
The source repository is now the git repository on dev.entrouvert.org.
Latest source release is 2.3.0. And git browser is included in our
redmine.
2010-07-27 Benjamin Dauvergne <bdauvergne@lupin.entrouvert.com>
* website/templates/base.ezt:
[Website] change position of Download block in right bar
2010-07-27 Benjamin Dauvergne <bdauvergne@lupin.entrouvert.com>
* website/convert-to-static.py:
[Website] in convert-to-static.py, work around errors in build logs
If Build() constructor fails, keep going.
2010-07-27 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* website/web/news/15-release-2.3.0.xml:
[Website] fix wrong structure for the news file about release 2.3.0
2010-07-27 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* website/convert-to-static.py:
[Website] import convert-to-static.py modification from lupin
2010-07-27 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* website/web/news/15-release-2.3.0.xml:
[Website] add news file aboute release 2.3.0
2010-07-22 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* website/web/download/index.xml:
[Website] fix non escaped ampersand
2010-07-21 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* configure.ac:
[Release] update libtool version
2010-07-21 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* website/web/download/index.xml:
[Website] update download links
2010-07-21 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* NEWS, configure.ac, lasso.doap, website/web/doap.rdf:
[Release] Update version number from 2.3 to 2.3.0
2010-07-21 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* NEWS:
[Release] update release date in NEWS file
2010-07-21 Benjamin Dauvergne <bdauvergne@entrouvert.com>
* ChangeLog:
[Release] update ChangeLog
2010-07-21 17:55 bdauvergne
* NEWS, abi/abi-2.3, configure.ac, lasso.doap, website/templates/base.ezt,

21
NEWS
View File

@ -1,8 +1,27 @@
NEWS
====
2.3.1 - September 9th 2010
--------------------------
31 commits, 23 files changed, 523 insertions, 356 deletions
* An ABI breakage was introduced in 2.3.0 with change of value for enumeration
values LASSO_PROVIDER_ROLE_SP and LASSO_PROVIDER_ROLE_IDP, it breaked code
compiled with previous version and dumps of server objects. This release fix
it.
* SAMLv2 handling of the artifact binding for the WebSSO profile is now
simpler, no more dumping of the response nodes and signing at the artifact
building time, the final response is signed when the artifact is generated
and when unserialized later it is only manipulated as XML for not breaking
the signature. It fixes usage of ciphered private keys with the
HTTP-Artifact binding.
* SAMLv2 internal storage of endpoints was modified to better keep the
ordering between endpoints, which is espacially important for
AssertionConsumerService endpoints and difficult to implement well.
2.3.0 - July 21th 2010
--------------------
----------------------
391 commits, 332 files changed, 13919 insertions, 7137 deletions

1091
abi/abi-2.3.1 Normal file

File diff suppressed because it is too large Load Diff

View File

@ -364,7 +364,7 @@ protected static native void destroy(long cptr);
elif c[0] == 's':
print >>fd, wrapper_decl(s,'jstring')
print >>fd, ') {'
print >>fd, ' return (*env)->NewStringUTF(env, %s);' % c[1]
print >>fd, ' return (*env)->NewStringUTF(env, (char*) %s);' % c[1]
print >>fd, '}'
elif c[0] == 'b':
print >>fd, wrapper_decl(s,'jboolean')

View File

@ -223,7 +223,7 @@ INCLUDE: LassoNode.xs
if type == 'i':
self.xs.pn('ct = newSViv(%s);' % name)
elif type == 's':
self.xs.pn('ct = newSVpv(%s, 0);' % name)
self.xs.pn('ct = newSVpv((char*)%s, 0);' % name)
elif type == 'b': # only one case LASSO_WSF_ENABLED
self.xs.unindent()
self.xs.pn('''#ifdef %s

View File

@ -76,7 +76,7 @@ PHP_MINIT_FUNCTION(lasso)
if c[0] == 'i':
print >> self.fd, ' REGISTER_LONG_CONSTANT("%s", %s, CONST_CS|CONST_PERSISTENT);' % (c[1], c[1])
elif c[0] == 's':
print >> self.fd, ' REGISTER_STRING_CONSTANT("%s", %s, CONST_CS|CONST_PERSISTENT);' % (c[1], c[1])
print >> self.fd, ' REGISTER_STRING_CONSTANT("%s", (char*) %s, CONST_CS|CONST_PERSISTENT);' % (c[1], c[1])
elif c[0] == 'b':
print >> self.fd, '''\
#ifdef %s

View File

@ -692,7 +692,7 @@ register_constants(PyObject *d)
if c[0] == 'i':
print >> fd, ' obj = PyInt_FromLong(%s);' % c[1]
elif c[0] == 's':
print >> fd, ' obj = PyString_FromString(%s);' % c[1]
print >> fd, ' obj = PyString_FromString((char*)%s);' % c[1]
elif c[0] == 'b':
print >> fd, '''\
#ifdef %s

View File

@ -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.0, lasso-devel@lists.labs.libre-entreprise.org)
AC_INIT([lasso], 2.3.1, 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="11:0:8"
LASSO_VERSION_INFO="12:0:8"
AC_SUBST(LASSO_VERSION_INFO)
dnl Compute the minimal supported ABI version for Win32 scripts and resources files.

View File

@ -1,4 +1,4 @@
<Project
<Project
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns="http://usefulinc.com/ns/doap#"
@ -29,12 +29,12 @@
<implements>
<Specification rdf:about="http://www.projectliberty.org/liberty/content/download/1266/8160/file/liberty-idff-1.2-20050520.zip">
<rdfs:label>Liberty Alliance ID-FF 1.2</rdfs:label>
</Specification
</Specification>
</implements>
<implements>
<Specification rdf:about="http://docs.oasis-open.org/security/saml/v2.0/saml-2.0-os.zip">
<rdfs:label>OASIS SAML 2.0</rdfs:label>
</Specification
</Specification>
</implements>
<maintainer>
<foaf:Person>
@ -61,6 +61,10 @@
</SVNRepository>
</repository>
<release>
<Version>
<created>2010-09-07</created>
<revision>2.3.1</revision>
</Version>
<Version>
<created>2010-07-21</created>
<revision>2.3.0</revision>

View File

@ -859,6 +859,14 @@ finalize(GObject *object)
/* instance and class init functions */
/*****************************************************************************/
void
lasso_endpoint_free(EndpointType *endpoint_type) {
g_free(endpoint_type->binding);
g_free(endpoint_type->url);
g_free(endpoint_type->kind);
g_free(endpoint_type->return_url);
g_free(endpoint_type);
}
static void
instance_init(LassoProvider *provider)
@ -881,6 +889,7 @@ instance_init(LassoProvider *provider)
provider->private_data->encryption_public_key = NULL;
provider->private_data->encryption_mode = LASSO_ENCRYPTION_MODE_NONE;
provider->private_data->encryption_sym_key_type = LASSO_ENCRYPTION_SYM_KEY_TYPE_AES_128;
lasso_release_list_of_full(provider->private_data->endpoints, lasso_endpoint_free);
/* no value_destroy_func since it shouldn't destroy the GList on insert */
provider->private_data->Descriptors = g_hash_table_new_full(
@ -1019,6 +1028,7 @@ _lasso_provider_load_metadata_from_doc(LassoProvider *provider, xmlDoc *doc)
g_return_val_if_fail(LASSO_IS_PROVIDER(provider), FALSE);
if (doc == NULL) {
warning("Metadata is not an XML document");
return FALSE;
}

View File

@ -128,8 +128,8 @@ typedef enum {
typedef enum {
LASSO_PROVIDER_ROLE_ANY = -1,
LASSO_PROVIDER_ROLE_NONE = 0,
LASSO_PROVIDER_ROLE_IDP = 1,
LASSO_PROVIDER_ROLE_SP = 2,
LASSO_PROVIDER_ROLE_SP = 1,
LASSO_PROVIDER_ROLE_IDP = 2,
LASSO_PROVIDER_ROLE_BOTH = 3,
LASSO_PROVIDER_ROLE_AUTHN_AUTHORITY = 4,
LASSO_PROVIDER_ROLE_AUTHZ_AUTHORITY = 8,

View File

@ -41,6 +41,18 @@ typedef enum {
LASSO_PUBLIC_KEY_ENCRYPTION
} LassoPublicKeyType;
/* This structure should allow to map ID-FFv1.2 and SAMLv2 endpoints */
struct EndpointType_s {
LassoProviderRole role;
char *kind;
char *binding;
char *url;
char *return_url;
int index;
gboolean is_default;
};
typedef struct EndpointType_s EndpointType;
struct _LassoProviderPrivate
{
@ -65,9 +77,9 @@ struct _LassoProviderPrivate
LassoEncryptionSymKeyType encryption_sym_key_type;
char *valid_until;
char *cache_duration;
GList *endpoints; /* of EndpointType_s */
};
gboolean lasso_provider_load_metadata(LassoProvider *provider, const gchar *metadata);
gboolean lasso_provider_load_metadata_from_buffer(LassoProvider *provider, const gchar *metadata);
int lasso_provider_verify_signature(LassoProvider *provider,

View File

@ -91,7 +91,8 @@ lasso_saml20_login_init_authn_request(LassoLogin *login, LassoHttpMethod http_me
lasso_samlp2_name_id_policy_new());
/* set name id policy format */
/* no need to check server, done in init_request */
default_name_id_format = lasso_provider_get_default_name_id_format(&profile->server->parent);
default_name_id_format = lasso_provider_get_metadata_one_for_role(&profile->server->parent,
LASSO_PROVIDER_ROLE_SP, "NameIDFormat");
if (default_name_id_format) {
/* steal the string */
lasso_assign_new_string(LASSO_SAMLP2_AUTHN_REQUEST(request)->NameIDPolicy->Format,
@ -310,7 +311,7 @@ lasso_saml20_login_process_authn_request_msg(LassoLogin *login, const char *auth
(authn_request->AssertionConsumerServiceURL != NULL)) &&
(authn_request->AssertionConsumerServiceIndex != -1))
{
rc = LASSO_LOGIN_ERROR_NO_DEFAULT_ENDPOINT;
rc = LASSO_PROFILE_ERROR_INVALID_REQUEST;
goto cleanup;
}
@ -318,7 +319,7 @@ lasso_saml20_login_process_authn_request_msg(LassoLogin *login, const char *auth
protocol_binding = authn_request->ProtocolBinding;
if (protocol_binding == NULL && authn_request->AssertionConsumerServiceIndex) {
/* protocol binding not set; so it will look into
* AssertionConsumingServiceIndex
* AssertionConsumerServiceIndex
* Also, if AssertionConsumerServiceIndex is not set in request,
* its value will be -1, which is just the right value to get
* default assertion consumer... (convenient)
@ -360,6 +361,7 @@ lasso_saml20_login_process_authn_request_msg(LassoLogin *login, const char *auth
} else if (g_strcmp0(protocol_binding,
LASSO_SAML2_METADATA_BINDING_REDIRECT) == 0) {
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_REDIRECT;
goto_cleanup_with_rc(LASSO_PROFILE_ERROR_INVALID_PROTOCOLPROFILE);
} else if (g_strcmp0(protocol_binding, LASSO_SAML2_METADATA_BINDING_PAOS) == 0) {
login->protocolProfile = LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_LECP;
} else {

View File

@ -46,6 +46,7 @@
#include "../xml/saml-2.0/samlp2_status_response.h"
#include "../xml/saml-2.0/samlp2_response.h"
#include "../xml/saml-2.0/saml2_assertion.h"
#include "../xml/misc_text_node.h"
#include "../utils.h"
#include "../debug.h"
@ -62,6 +63,7 @@ static gint lasso_profile_saml20_build_artifact_post_response_msg(LassoProfile *
const char *service);
static gboolean has_signature(LassoNode *node, LassoSignatureMethod *signature_method,
char **private_key_file, char **private_key_password);
static char* lasso_saml20_profile_generate_artifact(LassoProfile *profile, int part);
#define check_msg_body \
if (! profile->msg_body) { \
@ -152,20 +154,24 @@ http_method_to_binding(LassoHttpMethod method) {
*
* Return value: the generated artifact (internally allocated, don't free)
**/
char*
static char*
lasso_saml20_profile_generate_artifact(LassoProfile *profile, int part)
{
LassoNode *what = NULL;
lasso_assign_new_string(profile->private_data->artifact,
lasso_saml20_profile_build_artifact(&profile->server->parent));
if (part == 0) {
lasso_assign_new_string(profile->private_data->artifact_message,
lasso_node_dump(profile->request));
what = profile->request;
} else if (part == 1) {
lasso_assign_new_string(profile->private_data->artifact_message,
lasso_node_dump(profile->response));
what = profile->response;
} else {
/* XXX: RequestDenied here? */
}
/* Remove signature at the response level, if needed if will be on the ArtifactResponse */
lasso_node_remove_signature(what);
/* Keep an XML copy of the response for later retrieval */
lasso_assign_new_string(profile->private_data->artifact_message,
lasso_node_export_to_xml(what));
return profile->private_data->artifact;
}
@ -378,34 +384,47 @@ int
lasso_saml20_profile_build_artifact_response(LassoProfile *profile)
{
LassoSamlp2StatusResponse *response = NULL;
LassoNode *resp = NULL;
int rc = 0;
if ( ! LASSO_IS_SAMLP2_REQUEST_ABSTRACT(profile->request)) {
return LASSO_PROFILE_ERROR_MISSING_REQUEST;
}
/* Setup the response */
response = LASSO_SAMLP2_STATUS_RESPONSE(lasso_samlp2_artifact_response_new());
if (profile->private_data->artifact_message) {
resp = lasso_node_new_from_dump(profile->private_data->artifact_message);
lasso_assign_new_gobject(LASSO_SAMLP2_ARTIFACT_RESPONSE(response)->any, resp);
}
lasso_assign_new_gobject(profile->response, response);
response->ID = lasso_build_unique_id(32);
lasso_assign_string(response->Version, "2.0");
response->Issuer = LASSO_SAML2_NAME_ID(lasso_saml2_name_id_new_with_string(
LASSO_PROVIDER(profile->server)->ProviderID));
response->IssueInstant = lasso_get_current_time();
lasso_assign_string(response->InResponseTo, LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->ID);
lasso_check_good_rc(lasso_profile_saml20_setup_message_signature(profile,
(LassoNode*)response));
lasso_assign_new_gobject(profile->response, LASSO_NODE(response));
if (resp == NULL) {
lasso_saml20_profile_set_response_status(profile,
LASSO_SAML2_STATUS_CODE_REQUESTER, NULL);
/* Add content */
if (profile->private_data->artifact_message) {
xmlDoc *doc;
xmlNode *node;
char *content = profile->private_data->artifact_message;
doc = lasso_xml_parse_memory(content, strlen(content));
if (doc) {
node = xmlDocGetRootElement(doc);
lasso_assign_new_gobject(LASSO_SAMLP2_ARTIFACT_RESPONSE(response)->any,
lasso_misc_text_node_new_with_xml_node(node));
lasso_release_doc(doc);
lasso_saml20_profile_set_response_status(profile,
LASSO_SAML2_STATUS_CODE_SUCCESS, NULL);
} else {
lasso_saml20_profile_set_response_status(profile,
LASSO_SAML2_STATUS_CODE_RESPONDER,
LASSO_PRIVATE_STATUS_CODE_FAILED_TO_RESTORE_ARTIFACT);
}
} else {
/* if no artifact is present, it is a success anyway */
lasso_saml20_profile_set_response_status(profile,
LASSO_SAML2_STATUS_CODE_SUCCESS, NULL);
}
/* Setup the signature */
lasso_check_good_rc(lasso_profile_saml20_setup_message_signature(profile,
(LassoNode*)response));
/* Serialize the message */
lasso_assign_new_string(profile->msg_body, lasso_node_export_to_soap(profile->response));
cleanup:
return rc;

View File

@ -40,7 +40,6 @@ extern "C" {
int lasso_saml20_profile_init_request(LassoProfile *profile, const char *remote_provider_id,
gboolean first_in_session, LassoSamlp2RequestAbstract *request_abstract,
LassoHttpMethod http_method, LassoMdProtocolType protocol_type);
char* lasso_saml20_profile_generate_artifact(LassoProfile *profile, int part);
#define lasso_saml20_profile_set_response_status_success(profile, code2) \
lasso_saml20_profile_set_response_status(profile, LASSO_SAML2_STATUS_CODE_SUCCESS, code2)
#define lasso_saml20_profile_set_response_status_responder(profile, code2) \

View File

@ -53,8 +53,6 @@ const char *profile_names[LASSO_MD_PROTOCOL_TYPE_LAST] = {
"AttributeService" /*AttributeAuthorityDescriptor*/
};
static void add_assertion_consumer_url_to_list(gchar *key, G_GNUC_UNUSED gpointer value, GList **list);
static const char*
binding_uri_to_identifier(const char *uri)
{
@ -74,23 +72,21 @@ binding_uri_to_identifier(const char *uri)
return NULL;
}
static const char*
identifier_to_binding_uri(const char *identifier)
static LassoHttpMethod
binding_uri_to_http_method(const char *uri)
{
if (strcmp(identifier, "SOAP") == 0) {
return LASSO_SAML2_METADATA_BINDING_SOAP;
} else if (strcmp(identifier, "HTTP-Redirect") == 0) {
return LASSO_SAML2_METADATA_BINDING_REDIRECT;
} else if (strcmp(identifier, "HTTP-POST") == 0) {
return LASSO_SAML2_METADATA_BINDING_POST;
} else if (strcmp(identifier, "HTTP-Artifact") == 0) {
return LASSO_SAML2_METADATA_BINDING_ARTIFACT;
} else if (strcmp(identifier, "PAOS") == 0) {
return LASSO_SAML2_METADATA_BINDING_PAOS;
} else if (strcmp(identifier, "URI") == 0) {
return LASSO_SAML2_METADATA_BINDING_URI;
if (strcmp(uri, LASSO_SAML2_METADATA_BINDING_SOAP) == 0) {
return LASSO_HTTP_METHOD_SOAP;
} else if (strcmp(uri, LASSO_SAML2_METADATA_BINDING_REDIRECT) == 0) {
return LASSO_HTTP_METHOD_REDIRECT;
} else if (strcmp(uri, LASSO_SAML2_METADATA_BINDING_POST) == 0) {
return LASSO_HTTP_METHOD_NONE;
} else if (strcmp(uri, LASSO_SAML2_METADATA_BINDING_ARTIFACT) == 0) {
return LASSO_HTTP_METHOD_ARTIFACT_GET;
} else if (strcmp(uri, LASSO_SAML2_METADATA_BINDING_PAOS) == 0) {
return LASSO_HTTP_METHOD_PAOS;
}
return NULL;
return LASSO_HTTP_METHOD_NONE;
}
static gboolean
@ -127,6 +123,87 @@ xsdIsFalse(xmlChar *value)
return FALSE;
}
static gboolean
xsdUnsignedShortParse(xmlChar *value, int *out) {
int l = strtol((char*)value, NULL, 10);
if (((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) ||
errno == EINVAL || l < 0 || l >= 65535) {
return FALSE;
}
*out = l;
return TRUE;
}
static void
load_endpoint_type2(xmlNode *xmlnode, LassoProvider *provider, LassoProviderRole role, int *counter)
{
xmlChar *binding = getSaml2MdProp(xmlnode, LASSO_SAML2_METADATA_ATTRIBUTE_BINDING);
xmlChar *location = getSaml2MdProp(xmlnode, LASSO_SAML2_METADATA_ATTRIBUTE_LOCATION);
xmlChar *response_location = getSaml2MdProp(xmlnode, LASSO_SAML2_METADATA_ATTRIBUTE_RESPONSE_LOCATION);
xmlChar *index = getSaml2MdProp(xmlnode, LASSO_SAML2_METADATA_ATTRIBUTE_INDEX);
xmlChar *isDefault = getSaml2MdProp(xmlnode, LASSO_SAML2_METADATA_ATTRIBUTE_ISDEFAULT);
gboolean indexed_endpoint = FALSE;
int idx = *counter++;
gboolean is_default = FALSE;
EndpointType *endpoint_type;
if (! binding || ! location) {
warning("Invalid endpoint node %s", (char*) xmlnode->name);
goto cleanup;
}
indexed_endpoint = checkSaml2MdNode(xmlnode, LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE);
if (indexed_endpoint) {
if (! xsdUnsignedShortParse(index, &idx)) {
warning("Invalid AssertionConsumerService, no index set");
goto cleanup;
}
is_default = xsdIsTrue(isDefault);
}
endpoint_type = g_new0(EndpointType, 1);
endpoint_type->kind = g_strdup((char*)xmlnode->name);
endpoint_type->binding = g_strdup((char*)binding);
endpoint_type->url = g_strdup((char*)location);
endpoint_type->return_url = g_strdup((char*)response_location);
endpoint_type->role = role;
endpoint_type->index = idx;
endpoint_type->is_default = is_default;
lasso_list_add(provider->private_data->endpoints, (void*)endpoint_type);
cleanup:
lasso_release_xml_string(binding);
lasso_release_xml_string(location);
lasso_release_xml_string(response_location);
lasso_release_xml_string(isDefault);
lasso_release_xml_string(index);
}
static gint
compare_endpoint_type(const EndpointType *a, const EndpointType *b) {
int c;
if (a->role < b->role)
return -1;
if (a->role > b->role)
return +1;
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)
return -1;
if (! a->is_default && b->is_default)
return +1;
if (a->index < b->index)
return -1;
if (a->index > b->index)
return +1;
return 0;
}
static void
load_endpoint_type(xmlNode *xmlnode, LassoProvider *provider, LassoProviderRole role)
{
@ -141,7 +218,7 @@ load_endpoint_type(xmlNode *xmlnode, LassoProvider *provider, LassoProviderRole
binding_s = binding_uri_to_identifier((char*)binding);
if (! binding_s) {
message(G_LOG_LEVEL_CRITICAL, "XXX: unknown binding: %s", binding);
critical("XXX: unknown binding: %s", binding);
goto cleanup;
}
@ -259,6 +336,7 @@ load_descriptor(xmlNode *xmlnode, LassoProvider *provider, LassoProviderRole rol
xmlChar *value;
LassoProviderPrivate *pdata = provider->private_data;
char *token, *saveptr;
int counter = 0;
/* check protocol support enumeration */
value = getSaml2MdProp(xmlnode,
@ -290,6 +368,7 @@ load_descriptor(xmlNode *xmlnode, LassoProvider *provider, LassoProviderRole rol
attribute);
} else if (hasSaml2MdProp(t, LASSO_SAML2_METADATA_ATTRIBUTE_BINDING)) {
load_endpoint_type(t, provider, role);
load_endpoint_type2(t, provider, role, &counter);
} else {
value = xmlNodeGetContent(t);
_lasso_provider_add_metadata_value_for_role(provider, role, (char*)t->name,
@ -298,6 +377,8 @@ load_descriptor(xmlNode *xmlnode, LassoProvider *provider, LassoProviderRole rol
}
t = xmlSecGetNextElementNode(t->next);
}
provider->private_data->endpoints = g_list_sort(provider->private_data->endpoints,
(GCompareFunc) compare_endpoint_type);
for (i = 0; descriptor_attrs[i]; i++) {
value = getSaml2MdProp(xmlnode, descriptor_attrs[i]);
if (value == NULL) {
@ -396,6 +477,12 @@ lasso_saml20_provider_load_metadata(LassoProvider *provider, xmlNode *root_node)
(! loaded_one_or_more_descriptor || (pdata->roles & provider->role) == 0)) {
/* We must at least load one descriptor, and we must load a descriptor for our
* assigned role or we fail. */
if (! loaded_one_or_more_descriptor) {
warning("No descriptor was loaded, failing");
}
if ((pdata->roles & provider->role) == 0) {
warning("Loaded roles and prescribed role does not intersect");
}
return FALSE;
}
@ -403,226 +490,141 @@ lasso_saml20_provider_load_metadata(LassoProvider *provider, xmlNode *root_node)
}
LassoHttpMethod
lasso_saml20_provider_get_first_http_method(LassoProvider *provider,
lasso_saml20_provider_get_first_http_method(G_GNUC_UNUSED LassoProvider *provider,
LassoProvider *remote_provider, LassoMdProtocolType protocol_type)
{
LassoHttpMethod method = LASSO_HTTP_METHOD_NONE;
LassoProviderRole our_role = LASSO_PROVIDER_ROLE_SP;
int i;
const char *possible_bindings[] = {
"HTTP-POST",
"HTTP-Redirect",
"HTTP-Artifact",
"SOAP",
"PAOS",
NULL
};
LassoHttpMethod method_bindings[] = {
LASSO_HTTP_METHOD_POST,
LASSO_HTTP_METHOD_REDIRECT,
LASSO_HTTP_METHOD_ARTIFACT_GET,
LASSO_HTTP_METHOD_SOAP,
LASSO_HTTP_METHOD_PAOS
};
switch (remote_provider->role) {
case LASSO_PROVIDER_ROLE_IDP:
our_role = LASSO_PROVIDER_ROLE_SP;
break;
case LASSO_PROVIDER_ROLE_SP:
our_role = LASSO_PROVIDER_ROLE_IDP;
break;
default:
return LASSO_HTTP_METHOD_NONE;
GList *t = NULL;
const char *kind = NULL;
LassoHttpMethod result = LASSO_HTTP_METHOD_NONE;
if (protocol_type < LASSO_MD_PROTOCOL_TYPE_LAST) {
kind = profile_names[protocol_type];
}
if (! kind) {
warning("Could not find a first http method for protocol type %u", protocol_type);
return LASSO_HTTP_METHOD_NONE;
}
for (i=0; possible_bindings[i] && method == LASSO_HTTP_METHOD_NONE; i++) {
char *s;
const GList *l1, *l2;
s = g_strdup_printf("%s %s",
profile_names[protocol_type],
possible_bindings[i]);
l1 = lasso_provider_get_metadata_list_for_role(provider, our_role, s);
l2 = lasso_provider_get_metadata_list(remote_provider, s);
if (l1 && l2) {
method = method_bindings[i];
lasso_foreach(t, remote_provider->private_data->endpoints) {
EndpointType *endpoint_type = (EndpointType*)t->data;
if (endpoint_type && g_strcmp0(endpoint_type->kind, kind) == 0) {
result = binding_uri_to_http_method(endpoint_type->binding);
if (result) break;
}
}
return method;
return result;
}
gboolean
lasso_saml20_provider_accept_http_method(G_GNUC_UNUSED LassoProvider *provider, LassoProvider *remote_provider,
LassoMdProtocolType protocol_type, LassoHttpMethod http_method,
G_GNUC_UNUSED gboolean initiate_profile)
{
GList *t = NULL;
const char *kind = NULL;
if (protocol_type < LASSO_MD_PROTOCOL_TYPE_LAST) {
kind = profile_names[protocol_type];
}
if (! kind) {
warning("Could not find a first http method for protocol type %u", protocol_type);
return LASSO_HTTP_METHOD_NONE;
}
lasso_foreach(t, remote_provider->private_data->endpoints) {
EndpointType *endpoint_type = (EndpointType*)t->data;
if (endpoint_type && endpoint_type->role == remote_provider->role &&
g_strcmp0(endpoint_type->kind, kind) == 0) {
if (binding_uri_to_http_method(endpoint_type->binding) == http_method) {
return TRUE;
}
}
}
return FALSE;
}
gboolean
lasso_saml20_provider_check_assertion_consumer_service_url(LassoProvider *provider, const gchar *url, const gchar *binding)
{
GHashTable *descriptor;
GList *l = NULL, *r = NULL, *candidate = NULL;
char *name;
const char *binding_s = NULL;
int lname;
GList *t = NULL;
descriptor = provider->private_data->Descriptors;
if (descriptor == NULL || url == NULL || binding == NULL)
return FALSE;
binding_s = binding_uri_to_identifier(binding);
if (binding_s == NULL) {
return FALSE;
}
g_hash_table_foreach(descriptor,
(GHFunc)add_assertion_consumer_url_to_list,
&r);
name = g_strdup_printf(LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE
" %s ", binding_s);
lname = strlen(name);
for (l = r; l; l = g_list_next(l)) {
char *b = l->data;
if (strncmp(name, b, lname) == 0) {
candidate = lasso_provider_get_metadata_list_for_role(provider, LASSO_PROVIDER_ROLE_SP, b);
if (candidate && candidate->data && strcmp(candidate->data, url) == 0)
break;
else
candidate = NULL;
lasso_foreach (provider->private_data->endpoints, t) {
EndpointType *endpoint_type = (EndpointType*) t->data;
if (endpoint_type && endpoint_type->role == LASSO_PROVIDER_ROLE_SP
&& g_strcmp0(endpoint_type->url, url) == 0
&& g_strcmp0(endpoint_type->binding, binding) == 0)
{
return TRUE;
}
}
lasso_release(name);
lasso_release_list(r);
if (candidate)
return TRUE;
else
return FALSE;
return FALSE;
}
static const char *supported_assertion_consumer_bindings[] = { LASSO_SAML2_METADATA_BINDING_POST,
LASSO_SAML2_METADATA_BINDING_ARTIFACT, NULL };
static gboolean match_any(const char *key, const char *array[]) {
const char **t = array;
while (*t) {
if (g_strcmp0(key, *t) == 0) {
return TRUE;
}
t++;
}
return FALSE;
}
static EndpointType *
lasso_saml20_provider_get_assertion_consumer_service(LassoProvider *provider, int service_id)
{
const char *kind = LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE;
GList *t = NULL;
EndpointType *result = NULL;
if (service_id != -1) {
lasso_foreach(t, provider->private_data->endpoints) {
EndpointType *endpoint_type = (EndpointType*) t->data;
if (! endpoint_type)
continue;
if (endpoint_type->role == LASSO_PROVIDER_ROLE_SP &&
g_strcmp0(endpoint_type->kind, kind) == 0 &&
endpoint_type->index == service_id)
{
result = endpoint_type;
break;
}
}
} else { /* lookup a default supported endpoint type */
lasso_foreach(t, provider->private_data->endpoints) {
EndpointType *endpoint_type = (EndpointType*) t->data;
if (! endpoint_type)
continue;
if (endpoint_type->role == LASSO_PROVIDER_ROLE_SP &&
g_strcmp0(endpoint_type->kind, kind) == 0 &&
match_any(endpoint_type->binding,
supported_assertion_consumer_bindings))
{
result = endpoint_type;
break;
}
}
}
return result;
}
gchar*
lasso_saml20_provider_get_assertion_consumer_service_url(LassoProvider *provider,
int service_id)
{
GList *l = NULL;
char *sid;
char *name;
const char *possible_bindings[] = {
"HTTP-Artifact",
"HTTP-POST",
NULL
};
int i;
if (service_id == -1) {
sid = g_strdup(provider->private_data->default_assertion_consumer);
} else {
sid = g_strdup_printf("%d", service_id);
EndpointType *endpoint_type = lasso_saml20_provider_get_assertion_consumer_service(provider, service_id);
if (endpoint_type)
{
return g_strdup(endpoint_type->url);
}
for (i=0; possible_bindings[i]; i++) {
name = g_strdup_printf(LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE
" %s %s",
possible_bindings[i], sid);
l = lasso_provider_get_metadata_list_for_role(provider,
LASSO_PROVIDER_ROLE_SP,
name);
lasso_release_string(name);
if (l != NULL)
break;
}
lasso_release_string(sid);
if (l)
return g_strdup(l->data);
return NULL;
}
#define ACS_KEY "sp " LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE
static void
add_assertion_consumer_url_to_list(gchar *key, G_GNUC_UNUSED gpointer value, GList **list)
{
if (strncmp(key, ACS_KEY, sizeof(ACS_KEY)-1) == 0) {
lasso_list_add_new_string(*list, key);
}
}
struct HelperBindingByUrl {
const char *binding;
const char *url;
};
void
helper_binding_by_url(char *key, GList *value, struct HelperBindingByUrl *data)
{
if (strncmp(key, ACS_KEY, sizeof(ACS_KEY)-1) != 0) {
return;
}
if (data->binding == NULL && g_list_find_custom(value, data->url, (GCompareFunc)g_strcmp0) != NULL) {
char *end;
// URL was found for the first time
key += sizeof(ACS_KEY);
end = strchr(key, ' ');
if (end) {
key = g_strndup(key, (ptrdiff_t)(end-key));
data->binding = identifier_to_binding_uri(key);
lasso_release(key);
} else {
data->binding = identifier_to_binding_uri(key);
}
}
}
const gchar*
lasso_saml20_provider_get_assertion_consumer_service_binding_by_url(LassoProvider *provider, const char *url)
{
struct HelperBindingByUrl _helper_binding_by_url = { .binding = NULL, .url = url };
g_hash_table_foreach(provider->private_data->Descriptors, (GHFunc)helper_binding_by_url,
&_helper_binding_by_url);
return _helper_binding_by_url.binding;
}
gchar*
lasso_saml20_provider_get_assertion_consumer_service_url_by_binding(LassoProvider *provider,
const gchar *binding)
{
GHashTable *descriptor;
GList *l = NULL, *r = NULL;
char *name;
const char *binding_s = NULL;
int lname;
descriptor = provider->private_data->Descriptors;
if (descriptor == NULL)
return NULL;
binding_s = binding_uri_to_identifier(binding);
if (binding_s == NULL) {
return NULL;
}
g_hash_table_foreach(descriptor,
(GHFunc)add_assertion_consumer_url_to_list,
&r);
name = g_strdup_printf("sp "
LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE
" %s ", binding_s);
lname = strlen(name);
for (l = r; l; l = g_list_next(l)) {
char *b = l->data;
if (strncmp(name, b, lname) == 0) {
l = g_hash_table_lookup(descriptor, b);
break;
}
}
lasso_release_string(name);
lasso_release_list(r);
if (l) {
return g_strdup(l->data);
}
return NULL;
}
@ -630,88 +632,53 @@ gchar*
lasso_saml20_provider_get_assertion_consumer_service_binding(LassoProvider *provider,
int service_id)
{
GHashTable *descriptor;
GList *l = NULL;
char *sid;
char *name;
char *binding = NULL;
const char *possible_bindings[] = {
"HTTP-POST",
"HTTP-Redirect",
"HTTP-Artifact",
"SOAP",
NULL
};
int i;
if (service_id == -1) {
sid = g_strdup(provider->private_data->default_assertion_consumer);
} else {
sid = g_strdup_printf("%d", service_id);
EndpointType *endpoint_type = lasso_saml20_provider_get_assertion_consumer_service(provider, service_id);
if (endpoint_type)
{
return g_strdup(binding_uri_to_identifier(endpoint_type->binding));
}
descriptor = provider->private_data->Descriptors;
if (descriptor == NULL)
return NULL;
for (i=0; possible_bindings[i]; i++) {
name = g_strdup_printf(LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE
" %s %s",
possible_bindings[i], sid);
l = lasso_provider_get_metadata_list_for_role(provider, LASSO_PROVIDER_ROLE_SP, name);
lasso_release_string(name);
if (l != NULL) {
binding = g_strdup(possible_bindings[i]);
break;
}
}
lasso_release_string(sid);
return binding;
return NULL;
}
gboolean
lasso_saml20_provider_accept_http_method(LassoProvider *provider, LassoProvider *remote_provider,
LassoMdProtocolType protocol_type, LassoHttpMethod http_method,
gboolean initiate_profile)
const gchar*
lasso_saml20_provider_get_assertion_consumer_service_binding_by_url(LassoProvider *provider, const char *url)
{
char *protocol_profile;
static const char *http_methods[] = {
NULL,
NULL,
NULL,
NULL,
"HTTP-POST",
"HTTP-Redirect",
"SOAP",
"HTTP-Artifact",
"HTTP-Artifact",
NULL
};
gboolean rc = FALSE;
LassoProviderRole initiating_role;
const char *kind = LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE;
GList *t = NULL;
initiating_role = remote_provider->role;
if (remote_provider->role == LASSO_PROVIDER_ROLE_SP) {
provider->role = LASSO_PROVIDER_ROLE_IDP;
lasso_foreach(t, provider->private_data->endpoints) {
EndpointType *endpoint_type = (EndpointType*) t->data;
if (! endpoint_type)
continue;
if (endpoint_type->role == LASSO_PROVIDER_ROLE_SP &&
g_strcmp0(endpoint_type->kind, kind) == 0 &&
g_strcmp0(endpoint_type->url, url) == 0)
{
return endpoint_type->binding;
}
}
if (remote_provider->role == LASSO_PROVIDER_ROLE_IDP) {
provider->role = LASSO_PROVIDER_ROLE_SP;
return NULL;
}
gchar*
lasso_saml20_provider_get_assertion_consumer_service_url_by_binding(LassoProvider *provider,
const gchar *binding)
{
const char *kind = LASSO_SAML2_METADATA_ELEMENT_ASSERTION_CONSUMER_SERVICE;
GList *t = NULL;
lasso_foreach(t, provider->private_data->endpoints) {
EndpointType *endpoint_type = (EndpointType*) t->data;
if (! endpoint_type)
continue;
if (endpoint_type->role == LASSO_PROVIDER_ROLE_SP &&
g_strcmp0(endpoint_type->kind, kind) == 0 &&
g_strcmp0(endpoint_type->binding, binding) == 0)
{
return endpoint_type->url;
}
}
if (initiate_profile)
initiating_role = provider->role;
/* exclude bad input */
if (http_method > (int)G_N_ELEMENTS(http_methods) || http_method < 0 || http_methods[http_method+1] == NULL) {
return FALSE;
}
protocol_profile = g_strdup_printf("%s %s", profile_names[protocol_type],
http_methods[http_method+1]);
/* just check if remote provider can receive the request, remote provider will have to check
* how to return the response itself */
rc = (lasso_provider_get_metadata_list(remote_provider, protocol_profile) != NULL);
lasso_release_string(protocol_profile);
return rc;
return NULL;
}
/**

View File

@ -107,6 +107,13 @@
*/
#define LASSO_SOAP_FAULT_CODE_VERSION_MISMATCH "s:VersionMismatch"
/**
* LASSO_PRIVATE_STATUS_CODE_FAILED_TO_RESTORE_ARTIFACT:
*
* An artifact content is present but Lasso failed to rebuild the corresponding XML content.
*/
#define LASSO_PRIVATE_STATUS_CODE_FAILED_TO_RESTORE_ARTIFACT "FailedToRestoreArtifact"
/*****************************************************************************/
/* Lasso */
/*****************************************************************************/
@ -131,6 +138,41 @@
*/
#define LASSO_PYTHON_HREF "http://www.entrouvert.org/namespaces/python/0.0"
/**
* LASSO_SIGNATURE_TYPE_ATTRIBUTE:
*
* Attribute name for the Lasso signature type attribute.
*/
#define LASSO_SIGNATURE_TYPE_ATTRIBUTE BAD_CAST "SignatureType"
/**
* LASSO_SIGNATURE_METHOD_ATTRIBUTE:
*
* Attribute name for the Lasso signature type attribute.
*/
#define LASSO_SIGNATURE_METHOD_ATTRIBUTE BAD_CAST "SignatureMethod"
/**
* LASSO_PRIVATE_KEY_ATTRIBUTE:
*
* Attribute name for the Lasso private key attribute.
*/
#define LASSO_PRIVATE_KEY_ATTRIBUTE BAD_CAST "PrivateKey"
/**
* LASSO_PRIVATE_KEY_PASSWORD_ATTRIBUTE:
*
* Attribute name for the Lasso private key attribute.
*/
#define LASSO_PRIVATE_KEY_PASSWORD_ATTRIBUTE BAD_CAST "PrivateKeyPassword"
/**
* LASSO_CERTIFICATE_ATTRIBUTE:
*
* Attribute name for the Lasso private key attribute.
*/
#define LASSO_CERTIFICATE_ATTRIBUTE BAD_CAST "Certificate"
/*****************************************************************************/
/* Liberty Alliance ID-FF */
/*****************************************************************************/

View File

@ -518,6 +518,8 @@ lasso_query_sign(char *query, LassoSignatureMethod sign_method, const char *priv
new_query = g_strdup_printf("%s&SigAlg=%s", query, t);
xmlFree(t);
break;
case LASSO_SIGNATURE_METHOD_LAST:
g_assert_not_reached();
}
/* build buffer digest */
@ -568,6 +570,8 @@ lasso_query_sign(char *query, LassoSignatureMethod sign_method, const char *priv
case LASSO_SIGNATURE_METHOD_DSA_SHA1:
s_new_query = g_strdup_printf("%s&Signature=%s", new_query, e_b64_sigret);
break;
case LASSO_SIGNATURE_METHOD_LAST:
g_assert_not_reached();
}
done:

View File

@ -1129,6 +1129,27 @@ _lasso_node_collect_namespaces(GHashTable **namespaces, xmlNode *node)
}
}
gboolean
lasso_get_integer_attribute(xmlNode *node, xmlChar *attribute_name, xmlChar *ns_href, int *integer, long int low, long int high) {
xmlChar *content = NULL;
gboolean rc = FALSE;
long int what;
g_assert (integer);
content = xmlGetNsProp(node, attribute_name, ns_href);
if (! content)
goto cleanup;
if (! lasso_string_to_xsd_integer((char*)content, &what))
goto cleanup;
if (*integer < low || *integer >= high)
goto cleanup;
*integer = what;
rc = TRUE;
cleanup:
lasso_release_xml_string(content);
return rc;
}
/** FIXME: return a real error code */
static int
lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
@ -1141,6 +1162,7 @@ lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
struct XmlSnippet *snippet_any = NULL;
struct XmlSnippet *snippet_any_attribute = NULL;
struct XmlSnippet *snippet_collect_namespaces = NULL;
struct XmlSnippet *snippet_signature = NULL;
GSList *unknown_nodes = NULL;
GSList *known_attributes = NULL;
gboolean keep_xmlnode = FALSE;
@ -1295,7 +1317,15 @@ lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
*(void**)value = tmp;
tmp = NULL;
} else if (snippet->type & SNIPPET_INTEGER) {
int val = atoi(tmp);
int val = strtol(tmp, NULL, 10);
if (((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE)
|| errno == EINVAL || val < 0) {
if (snippet->type & SNIPPET_OPTIONAL_NEG) {
val = -1;
} else {
val = 0;
}
}
(*(int*)value) = val;
trace_snippet(" setting integer %i for ", val);
xmlFree(tmp);
@ -1342,6 +1372,10 @@ lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
snippet_collect_namespaces = snippet;
}
if (type == SNIPPET_SIGNATURE) {
snippet_signature = snippet;
}
if (type == SNIPPET_ATTRIBUTE) {
if (snippet->type & SNIPPET_ANY) {
snippet_any_attribute = snippet;
@ -1356,7 +1390,15 @@ lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
continue;
if (snippet->type & SNIPPET_INTEGER) {
int val = atoi(tmp);
int val = strtol(tmp, NULL, 10);
if (((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE)
|| errno == EINVAL || val < 0) {
if (snippet->type & SNIPPET_OPTIONAL_NEG) {
val = -1;
} else {
val = 0;
}
}
(*(int*)value) = val;
} else if (snippet->type & SNIPPET_BOOLEAN) {
int val = 0;
@ -1390,6 +1432,44 @@ lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
_lasso_node_collect_namespaces(value, xmlnode);
}
/* Collect signature parameters */
{
LassoSignatureMethod method;
LassoSignatureType type;
xmlChar *private_key = NULL;
xmlChar *private_key_password = NULL;
xmlChar *certificate = NULL;
while (snippet_signature) {
int what;
if (! lasso_get_integer_attribute(xmlnode, LASSO_SIGNATURE_METHOD_ATTRIBUTE,
BAD_CAST LASSO_LIB_HREF, &what,
LASSO_SIGNATURE_METHOD_RSA_SHA1,
LASSO_SIGNATURE_METHOD_LAST))
break;
method = what;
if (! lasso_get_integer_attribute(xmlnode, LASSO_SIGNATURE_METHOD_ATTRIBUTE,
BAD_CAST LASSO_LIB_HREF, &what, LASSO_SIGNATURE_TYPE_NONE+1,
LASSO_SIGNATURE_TYPE_LAST))
break;
type = what;
private_key = xmlGetNsProp(xmlnode, LASSO_PRIVATE_KEY_PASSWORD_ATTRIBUTE,
BAD_CAST LASSO_LIB_HREF);
if (! private_key)
break;
private_key = xmlGetNsProp(xmlnode, LASSO_PRIVATE_KEY_ATTRIBUTE, BAD_CAST
LASSO_LIB_HREF);
certificate = xmlGetNsProp(xmlnode, LASSO_CERTIFICATE_ATTRIBUTE, BAD_CAST
LASSO_LIB_HREF);
lasso_node_set_signature(node, type,
method, (char*) private_key, (char*) private_key_password, (char*) certificate);
}
lasso_release_xml_string(private_key);
lasso_release_xml_string(private_key_password);
lasso_release_xml_string(certificate);
}
/* Collect other children */
if (unknown_nodes && snippet_any) {
xmlNode *t = unknown_nodes->data;
void *tmp;
@ -1398,6 +1478,7 @@ lasso_node_impl_init_from_xml(LassoNode *node, xmlNode *xmlnode)
(*(char**)value) = tmp;
}
/* Collect other attributes */
if (snippet_any_attribute) {
GHashTable **any_attribute;
GSList *tmp_attr;
@ -1617,15 +1698,15 @@ lasso_node_impl_get_xmlNode(LassoNode *node, gboolean lasso_dump)
if (private_key) {
ns = get_or_define_ns(xmlnode, BAD_CAST LASSO_LASSO_HREF);
sprintf(buffer, "%u", type);
xmlSetNsProp(xmlnode, ns, BAD_CAST "SignatureType", BAD_CAST buffer);
xmlSetNsProp(xmlnode, ns, LASSO_SIGNATURE_TYPE_ATTRIBUTE, BAD_CAST buffer);
sprintf(buffer, "%u", method);
xmlSetNsProp(xmlnode, ns, BAD_CAST "SignatureMethod", BAD_CAST buffer);
xmlSetNsProp(xmlnode, ns, BAD_CAST "PrivateKey", BAD_CAST private_key);
xmlSetNsProp(xmlnode, ns, LASSO_SIGNATURE_METHOD_ATTRIBUTE, BAD_CAST buffer);
xmlSetNsProp(xmlnode, ns, LASSO_PRIVATE_KEY_ATTRIBUTE, BAD_CAST private_key);
if (private_key_password) {
xmlSetNsProp(xmlnode, ns, BAD_CAST "PrivateKeyPassword", BAD_CAST private_key_password);
xmlSetNsProp(xmlnode, ns, LASSO_PRIVATE_KEY_PASSWORD_ATTRIBUTE, BAD_CAST private_key_password);
}
if (certificate) {
xmlSetNsProp(xmlnode, ns, BAD_CAST "Certificate", BAD_CAST certificate);
xmlSetNsProp(xmlnode, ns, LASSO_CERTIFICATE_ATTRIBUTE, BAD_CAST certificate);
}
}
}

View File

@ -84,7 +84,8 @@ typedef enum {
typedef enum {
LASSO_SIGNATURE_TYPE_NONE = 0,
LASSO_SIGNATURE_TYPE_SIMPLE,
LASSO_SIGNATURE_TYPE_WITHX509
LASSO_SIGNATURE_TYPE_WITHX509,
LASSO_SIGNATURE_TYPE_LAST
} LassoSignatureType;
@ -97,7 +98,8 @@ typedef enum {
**/
typedef enum {
LASSO_SIGNATURE_METHOD_RSA_SHA1 = 1,
LASSO_SIGNATURE_METHOD_DSA_SHA1
LASSO_SIGNATURE_METHOD_DSA_SHA1,
LASSO_SIGNATURE_METHOD_LAST
} LassoSignatureMethod;

View File

@ -25,7 +25,7 @@ if os.path.exists(CONFIG_FILE):
# Combine default and configuration file
AUTHENTIC_SRCDIR = CONFIG.get('AUTHENTIC_SRCDIR') or '/usr/local/src/authentic'
AUTHENTICCTL = CONFIG.get('AUTHENTICCTL') or '/usr/sbin/authenticctl.py'
AUTHENTIC_DATA_DIR = CONFIG.get('AUTHENTIC_DATA_DIR') or '/usr/share/authentic/'
AUTHENTIC_DATADIR = CONFIG.get('AUTHENTIC_DATADIR') or '/usr/share/authentic/'
LCSCTL = CONFIG.get('LCSCTL') or '/usr/sbin/lcsctl.py'
LCS_DATADIR = CONFIG.get('LCS_DATADIR') or '/usr/share/lcs/'
LASSO_BUILDDIR = os.environ.get('LASSO_BUILDDIR') or \

View File

@ -113,11 +113,16 @@ class Build:
if self.changelog:
self.changelog = self.changelog.replace('.xml', '')
dom_cl = xml.dom.minidom.parse(file('web' + self.changelog + '.xml'))
self.last_commit_author = getText(dom_cl.getElementsByTagName('author')[-1].childNodes)
self.nb_commits = len(dom_cl.getElementsByTagName('entry'))
if not self.nb_commits:
self.nb_commits = len(dom_cl.getElementsByTagName('logentry'))
try:
dom_cl = xml.dom.minidom.parse(file('web' + self.changelog + '.xml'))
except:
self.nb_commits = '?'
self.last_commit_author = '?'
else:
self.last_commit_author = getText(dom_cl.getElementsByTagName('author')[-1].childNodes)
self.nb_commits = len(dom_cl.getElementsByTagName('entry'))
if not self.nb_commits:
self.nb_commits = len(dom_cl.getElementsByTagName('logentry'))
@ -129,7 +134,6 @@ re_summary = re.compile('[a-z]+\.[0-9]{4}.xml')
if not os.path.exists('web-static'):
os.mkdir('web-static')
for BUILDLOGS_DIR in ('build-logs', 'build-logs-wsf'):
if not os.path.exists('web/%s' % BUILDLOGS_DIR):
continue
@ -137,7 +141,7 @@ for BUILDLOGS_DIR in ('build-logs', 'build-logs-wsf'):
os.mkdir('web-static/%s' % BUILDLOGS_DIR)
for base, dirs, files in os.walk('web/%s' % BUILDLOGS_DIR):
if base.endswith('/CVS') or base.endswith('/.svn'):
if base.endswith('/CVS') or base.endswith('/.svn') or base.endswith('/.git'):
continue
for dirname in dirs:
src_file = os.path.join(base, dirname)
@ -205,7 +209,7 @@ for BUILDLOGS_DIR in ('build-logs', 'build-logs-wsf'):
day_dirs = os.listdir('web/%s/' % BUILDLOGS_DIR)
day_dirs.sort()
day_dirs.reverse()
day_dirs = day_dirs[:20]
day_dirs = day_dirs[:60]
main_page = []
@ -217,12 +221,15 @@ for BUILDLOGS_DIR in ('build-logs', 'build-logs-wsf'):
main_page.sort()
main_page.reverse()
main_page = main_page[:20]
main_page = main_page[:50]
builds = []
for filename in main_page:
builds.append( Build(xml.dom.minidom.parse(filename)) )
if len(builds) > 1 and builds[-2].date[:8] == builds[-1].date[:8]:
builds[-1].display_date = ''
try:
builds.append( Build(xml.dom.minidom.parse(filename)) )
if len(builds) > 1 and builds[-2].date[:8] == builds[-1].date[:8]:
builds[-1].display_date = ''
except:
pass
fd = StringIO()
buildlog_template.generate(fd, {'build': builds})
@ -255,6 +262,8 @@ for base, dirs, files in os.walk('web'):
src_file = os.path.join(base, filename)
dst_file = 'web-static/' + src_file[4:]
if os.path.isdir(src_file): continue
if os.path.exists(dst_file) and \
os.stat(dst_file)[stat.ST_MTIME] >= os.stat(src_file)[stat.ST_MTIME]:
continue

View File

@ -32,25 +32,6 @@
</div>
<div id="quicklinks">
[is section "download"]
[else]
<div id="download">
<h2>Download</h2>
<p>
The most recent version of Lasso is <strong>2.3</strong> and was
release on July 19th 2010.
</p>
<h3>Binary packages</h3>
<p>
There are some Debian and Ubuntu packages (for <i>lenny</i> and <i>karmic</i>)
available at <a href="http://deb.entrouvert.org">deb.entrouvert.org</a>.
</p>
<h3>Source</h3>
<p>
<li>Wait for 2.3 updates of download links...</li>
</p>
</div>
[end]
<div id="morelinks">
<h2>Resources</h2>
<ul>
@ -71,6 +52,27 @@
[news]
</div>
[end]
[is section "download"]
[else]
<div id="download">
<h2>Download</h2>
<p>
The most recent version of Lasso is <strong>2.3.1</strong> and was
release on Septembre 9th 2010.
</p>
<h3>Binary packages</h3>
<p>
There are some Debian and Ubuntu packages (for <i>lenny</i> and <i>karmic</i>)
available at <a href="http://deb.entrouvert.org">deb.entrouvert.org</a>.
</p>
<h3>Source</h3>
<p>
<li><a href="https://dev.entrouvert.org/attachments/download/12/lasso-2.3.1.tar.gz">.tar.gz</a></li>
<li><a href="http://dev.entrouvert.org/git/lasso.git">Git repository : http://dev.entrouvert.org/git/lasso.git</a></li>
<li><a href="https://dev.entrouvert.org/projects/lasso/repository">Browse git repository</a></li>
</p>
</div>
[end]
</div>
<div id="content">

View File

@ -1,4 +1,4 @@
<Project
<Project
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns="http://usefulinc.com/ns/doap#"
@ -29,12 +29,12 @@
<implements>
<Specification rdf:about="http://www.projectliberty.org/liberty/content/download/1266/8160/file/liberty-idff-1.2-20050520.zip">
<rdfs:label>Liberty Alliance ID-FF 1.2</rdfs:label>
</Specification
</Specification>
</implements>
<implements>
<Specification rdf:about="http://docs.oasis-open.org/security/saml/v2.0/saml-2.0-os.zip">
<rdfs:label>OASIS SAML 2.0</rdfs:label>
</Specification
</Specification>
</implements>
<maintainer>
<foaf:Person>
@ -61,6 +61,10 @@
</SVNRepository>
</repository>
<release>
<Version>
<created>2010-09-07</created>
<revision>2.3.1</revision>
</Version>
<Version>
<created>2010-07-21</created>
<revision>2.3.0</revision>

View File

@ -10,7 +10,7 @@
<p>
Lasso is licensed under the GNU GPL and the latest release
is available here as a gzipped tarball:
<a href="http://labs.libre-entreprise.org/frs/download.php/806/lasso-2.3.0.tar.gz">lasso-2.3.0.tar.gz</a>
<a href="http://labs.libre-entreprise.org/frs/download.php/807/lasso-2.3.0.tar.gz">lasso-2.3.0.tar.gz</a>
</p>
<h2>Binary Downloads</h2>
@ -41,7 +41,7 @@ deb http://deb.entrouvert.org karmic main
<ul>
<li>liblasso3: runtime library</li>
<li>liblasso3-dev: C development kit</li>
<li>python-lasso: Python 2.5 & 2.6 bindings</li>
<li>python-lasso: Python 2.5 &amp; 2.6 bindings</li>
<li>php5-lasso: PHP bindings</li>
<li>liblasso-java: JAVA bindings</li>
<li>liblasso3-perl: Perl bindings</li>

View File

@ -46,10 +46,10 @@
</p>
<p>
The most recent version of Lasso is <strong>2.1.1</strong>. You can
The most recent version of Lasso is <strong>2.3.0</strong>. You can
<a
href="https://labs.libre-entreprise.org/frs/download.php/594/lasso-2.1.1.tar.gz">download
the 2.1.1 tarball here</a> or get more options on the general <a
href="https://labs.libre-entreprise.org/frs/download.php/807/lasso-2.3.0.tar.gz">download
the 2.3.0 tarball here</a> or get more options on the general <a
href="/download/">download</a> page.
</p>

View File

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<div xmlns="http://www.w3.org/1999/xhtml">
<h3>2010-07-21: Released 2.3.0</h3>
<p>
Lasso 2.3.0 has been released.
<a href="/download/">Download it now</a>
</p>
<p class="changes">
<strong>What changed ?</strong>
This release contains many bugfixes, better support for profiles outside
of WebSSO (especially Attribute requests), better control over
signatures creation and validation, support for encrypted private
keys, and improved Python, PHP5, Java, and Perl bindings.
</p>
</div>