summaryrefslogtreecommitdiffstats
path: root/lasso/id-ff
diff options
context:
space:
mode:
authorNicolas Clapies <nclapies@entrouvert.com>2004-08-17 14:18:40 +0000
committerNicolas Clapies <nclapies@entrouvert.com>2004-08-17 14:18:40 +0000
commit8608fd371cabd5f55bc234ca1748665607a94c02 (patch)
treebce3dd960c5fc6ca3bdb4333a022c171a8535812 /lasso/id-ff
parentaa0060069b1b09ced26d4d19278b704dd6e44cc0 (diff)
downloadlasso-8608fd371cabd5f55bc234ca1748665607a94c02.tar.gz
lasso-8608fd371cabd5f55bc234ca1748665607a94c02.tar.xz
lasso-8608fd371cabd5f55bc234ca1748665607a94c02.zip
updated doc in logout, fixed Feature Requests item #253, must be tested, added doc to federation termination notification
Diffstat (limited to 'lasso/id-ff')
-rw-r--r--lasso/id-ff/federation_termination.c89
-rw-r--r--lasso/id-ff/logout.c104
-rw-r--r--lasso/id-ff/logout.h5
3 files changed, 159 insertions, 39 deletions
diff --git a/lasso/id-ff/federation_termination.c b/lasso/id-ff/federation_termination.c
index e052b2dc..82f425ee 100644
--- a/lasso/id-ff/federation_termination.c
+++ b/lasso/id-ff/federation_termination.c
@@ -29,6 +29,24 @@
/* public methods */
/*****************************************************************************/
+/**
+ * lasso_federation_termination_build_notification_msg:
+ * @defederation: the federation termination object
+ *
+ * This method builds the federation termination notification message.
+ *
+ * It gets the federation termination notification protocol profile and :
+ * if it is a SOAP method, then it builds the federation termination notification SOAP message,
+ * set the msg_body attribute, get the federation termination service url
+ * and set the msg_url attribute of the federation termination object.
+ *
+ * if it is a HTTP-Redirect method, then it builds the federation termination notification QUERY message,
+ * builds the federation termination notification url with federation termination service url,
+ * set the msg_url attribute of the federation termination object,
+ * set the msg_body to NULL
+ *
+ * Return value: O of OK else < 0
+ **/
gint
lasso_federation_termination_build_notification_msg(LassoFederationTermination *defederation)
{
@@ -70,10 +88,9 @@ lasso_federation_termination_build_notification_msg(LassoFederationTermination *
if (xmlStrEqual(protocolProfile, lassoLibProtocolProfileSloSpSoap) || \
xmlStrEqual(protocolProfile, lassoLibProtocolProfileSloIdpSoap)) {
- profile->request_type = lassoHttpMethodSoap;
profile->msg_url = lasso_provider_get_federationTerminationServiceURL(provider,
- lassoProviderTypeIdp,
- NULL);
+ lassoProviderTypeIdp,
+ NULL);
if (profile->msg_url == NULL) {
message(G_LOG_LEVEL_CRITICAL, "Federation Termination Notification url not found\n");
ret = -1;
@@ -83,7 +100,6 @@ lasso_federation_termination_build_notification_msg(LassoFederationTermination *
}
else if (xmlStrEqual(protocolProfile,lassoLibProtocolProfileSloSpHttp) || \
xmlStrEqual(protocolProfile,lassoLibProtocolProfileSloIdpHttp)) {
- profile->request_type = lassoHttpMethodRedirect;
profile->msg_url = lasso_node_export_to_query(profile->request,
profile->server->signature_method,
profile->server->private_key);
@@ -106,12 +122,32 @@ lasso_federation_termination_build_notification_msg(LassoFederationTermination *
return(ret);
}
+/**
+ * lasso_federation_termination_destroy:
+ * @defederation: the federation termination object
+ *
+ * This method destroys the federation termination object
+ *
+ **/
void
lasso_federation_termination_destroy(LassoFederationTermination *defederation)
{
g_object_unref(G_OBJECT(defederation));
}
+/**
+ * lasso_federation_termination_init_notification:
+ * @defederation: the federation termination object
+ * @remote_providerID: the provider id of the federation termination notified provider.
+ * If it is set to NULL, then gets the default first remote provider id.
+ *
+ * It sets a new federation termination notification to the remote provider id
+ * with the provider id of the requester (from the server object )
+ * and the name identifier of the federated principal
+ *
+ *
+ * Return value: 0 if OK else < 0
+ **/
gint
lasso_federation_termination_init_notification(LassoFederationTermination *defederation,
gchar *remote_providerID)
@@ -127,16 +163,16 @@ lasso_federation_termination_init_notification(LassoFederationTermination *defed
profile = LASSO_PROFILE(defederation);
if (remote_providerID == NULL) {
- message(G_LOG_LEVEL_INFO, "No remote provider id, get the remote provider id of the first federation\n");
+ debug("No remote provider id, get the remote provider id of the first federation\n");
profile->remote_providerID = lasso_identity_get_next_federation_remote_providerID(profile->identity);
}
else {
- message(G_LOG_LEVEL_INFO, "A remote provider id for defederation notification : %s\n", remote_providerID);
+ debug("A remote provider id for defederation notification : %s\n", remote_providerID);
profile->remote_providerID = g_strdup(remote_providerID);
}
if (profile->remote_providerID == NULL) {
- message(G_LOG_LEVEL_CRITICAL, "No provider Id for init notification\n");
+ message(G_LOG_LEVEL_CRITICAL, "No remote provider id to build the federation termination notification\n");
ret = -1;
goto done;
}
@@ -203,6 +239,24 @@ lasso_federation_termination_init_notification(LassoFederationTermination *defed
return(ret);
}
+/**
+ * lasso_federation_termination_process_notification_msg:
+ * @defederation: the federation termination object
+ * @notification_msg: the federation termination notification message
+ * @notification_method: the federation termination notification method
+ *
+ * Process the federation termination notification.
+ * If it is a SOAP notification method then it builds the federation termination object
+ * from the SOAP message and optionaly verify the signature.
+ *
+ * if it is a HTTP-Redirect notification method the nit builds the federation termination notication
+ * object from the QUERY message and optionaly verify the signature
+ *
+ * Set the msg_nameIdentifier attribute with the NameIdentifier content of the notification object and
+ * optionaly set the msg_relayState attribute with the RelayState content of the notifcation object
+ *
+ * Return value: 0 if OK else < 0
+ **/
gint
lasso_federation_termination_process_notification_msg(LassoFederationTermination *defederation,
gchar *notification_msg,
@@ -233,7 +287,7 @@ lasso_federation_termination_process_notification_msg(LassoFederationTermination
return(-4);
}
- /* get the NameIdentifier to load identity dump */
+ /* get the NameIdentifier */
profile->nameIdentifier = lasso_node_get_child_content(profile->request,
"NameIdentifier", NULL, NULL);
if (profile->nameIdentifier==NULL) {
@@ -248,6 +302,18 @@ lasso_federation_termination_process_notification_msg(LassoFederationTermination
return(0);
}
+/**
+ * lasso_federation_termination_validate_notification:
+ * @defederation: the federation termination object
+ *
+ * Validate the federation termination notification :
+ * initialises the federation termination notification
+ * verifies the ProviderID
+ * verifies the federation
+ * verifies the authentication
+ *
+ * Return value: O if OK else < 0
+ **/
gint
lasso_federation_termination_validate_notification(LassoFederationTermination *defederation)
{
@@ -352,6 +418,13 @@ GType lasso_federation_termination_get_type() {
return this_type;
}
+/**
+ * lasso_federation_termination_new:
+ * @server: the server object of the provider
+ * @provider_type: the provider type (service provider or identity provider)
+ *
+ * Return value: a new instance of federation termination object or NULL
+ **/
LassoFederationTermination*
lasso_federation_termination_new(LassoServer *server,
gint provider_type)
diff --git a/lasso/id-ff/logout.c b/lasso/id-ff/logout.c
index 2d371cf3..4642e38e 100644
--- a/lasso/id-ff/logout.c
+++ b/lasso/id-ff/logout.c
@@ -113,16 +113,12 @@ lasso_logout_build_request_msg(LassoLogout *logout)
if (xmlStrEqual(protocolProfile, lassoLibProtocolProfileSloSpSoap) || \
xmlStrEqual(protocolProfile, lassoLibProtocolProfileSloIdpSoap)) {
- debug("Building a soap request message\n");
- profile->request_type = lassoHttpMethodSoap;
-
/* sign the request message */
lasso_samlp_request_abstract_set_signature(LASSO_SAMLP_REQUEST_ABSTRACT(profile->request),
profile->server->signature_method,
profile->server->private_key,
profile->server->certificate,
NULL);
-
profile->msg_url = lasso_provider_get_soapEndpoint(provider,
lassoProviderTypeIdp,
NULL);
@@ -130,14 +126,11 @@ lasso_logout_build_request_msg(LassoLogout *logout)
}
else if (xmlStrEqual(protocolProfile,lassoLibProtocolProfileSloSpHttp) || \
xmlStrEqual(protocolProfile,lassoLibProtocolProfileSloIdpHttp)) {
- profile->request_type = lassoHttpMethodRedirect;
- profile->msg_url = lasso_provider_get_singleLogoutServiceURL(provider,
- lassoProviderTypeIdp,
- NULL);
- profile->msg_url = lasso_node_export_to_query(profile->request,
- profile->server->signature_method,
- profile->server->private_key);
- profile->msg_body = NULL;
+ /* TODO - implement HTTP-Redirect */
+ gchar *query;
+ query = lasso_node_export_to_query(profile->request,
+ profile->server->signature_method,
+ profile->server->private_key);
}
return(0);
@@ -264,9 +257,10 @@ lasso_logout_get_next_providerID(LassoLogout *logout)
* lasso_logout_init_request:
* @logout: the logout object
* @remote_providerID: The provider id of the logout requested provider.
- * If it is set to NULL, get the default remote provider id.
+ * If it is set to NULL, then gets the default first remote provider id.
*
- * It initialises a new logout request with the remote provider id
+ * It sets a new logout request to the remote provider id
+ * with the provider id of the requester (from the server object )
* and name identifier of the federated principal
*
* Return value: 0 if OK else < 0
@@ -295,7 +289,7 @@ lasso_logout_init_request(LassoLogout *logout,
}
if (profile->remote_providerID == NULL) {
- message(G_LOG_LEVEL_CRITICAL, "No provider id for init request\n");
+ message(G_LOG_LEVEL_CRITICAL, "No remote provider id to send the logout request\n");
return(-1);
}
@@ -365,14 +359,13 @@ lasso_logout_init_request(LassoLogout *logout,
*
* Process a logout request.
* if it is a SOAP request method then it builds the logout request object
- * from the SOAP message and verify the signature of the logout request.
+ * from the SOAP message and optionaly verify the signature of the logout request.
*
* if it is a HTTP-Redirect request method then it builds the logout request object
* from the QUERY message and verify the signature
*
- * Set the HTTP request method
- * Set the msg_nameIdentifier attribute with the NameIdentifier of the logout request
- * Optionaly, set the msg_relayState attribute with the RelayState of the logout request
+ * Set the msg_nameIdentifier attribute with the NameIdentifier content of the logout object and
+ * optionaly set the msg_relayState attribute with the RelayState of the logout request
*
* Return value: 0 if OK else < 0
**/
@@ -440,6 +433,9 @@ gint lasso_logout_process_request_msg(LassoLogout *logout,
goto done;
}
+ /* set the http request method */
+ logout->http_request_method = request_method;
+
/* Set the NameIdentifier */
profile->nameIdentifier = lasso_node_get_child_content(profile->request,
"NameIdentifier",
@@ -463,11 +459,11 @@ gint lasso_logout_process_request_msg(LassoLogout *logout,
* @logout: the logout object
*
* Validate the logout request :
- * initialises the logout response
- * verify the ProviderID
- * verify the federation with the NameIdentifier
- * verify the authentication with the NameIdentifier
- * TODO - if SOAP method at identity provider, verify all the remote service providers support SOAP method.
+ * sets the logout response
+ * verifies the ProviderID
+ * verifies the federation with the NameIdentifier
+ * verifies the authentication with the NameIdentifier
+ * if SOAP method at identity provider, verify all the remote service providers support SOAP method.
*
* Return value: O if OK else < 0
**/
@@ -537,7 +533,7 @@ lasso_logout_validate_request(LassoLogout *logout)
if (assertion == NULL) {
message(G_LOG_LEVEL_WARNING, "%s has no assertion\n", remote_providerID);
statusCode_class->set_prop(statusCode, "Value", lassoSamlStatusCodeRequestDenied);
- return(-8);
+ return(-1);
}
lasso_node_destroy(assertion);
@@ -546,18 +542,66 @@ lasso_logout_validate_request(LassoLogout *logout)
if (federation == NULL) {
message(G_LOG_LEVEL_WARNING, "No federation for %s\n", remote_providerID);
statusCode_class->set_prop(statusCode, "Value", lassoLibStatusCodeFederationDoesNotExist);
- return(-9);
+ return(-1);
}
if (lasso_federation_verify_nameIdentifier(federation, nameIdentifier) == FALSE) {
message(G_LOG_LEVEL_WARNING, "No name identifier for %s\n", remote_providerID);
statusCode_class->set_prop(statusCode, "Value", lassoLibStatusCodeFederationDoesNotExist);
- return(-10);
+ return(-1);
}
- lasso_federation_destroy(federation);
- /* TODO - if SOAP request method at IDP then verify all the remote service providers supports SOAP protoco profile */
+ /* if SOAP request method at IDP then verify all the remote service providers support SOAP protocol profile.
+ If one remote authenticated principal service provider doesn't support SOAP
+ then return UnsupportedProfile to original service provider */
+ if (profile->provider_type==lassoProviderTypeIdp && logout->http_request_method==lassoHttpMethodSoap) {
+ gboolean all_http_soap;
+ LassoProvider *provider;
+ gchar *providerID, *protocolProfile;
+ int i;
+
+ all_http_soap = TRUE;
+
+ for (i = 0; i<profile->server->providers->len; i++) {
+ provider = g_ptr_array_index(profile->server->providers, i);
+ providerID = lasso_provider_get_providerID(provider);
+ /* if the original service provider then continue */
+ if (xmlStrEqual(remote_providerID, providerID)) {
+ continue;
+ }
+
+ /* if principal is not authenticated with this remote service provider, continue */
+ assertion = lasso_session_get_assertion(profile->session, providerID);
+ if (assertion == NULL) {
+ continue;
+ }
+
+ /* if protocolProfile is SOAP continue else break */
+ protocolProfile = lasso_provider_get_singleLogoutProtocolProfile(provider, lassoProviderTypeIdp, NULL);
+ if (protocolProfile == NULL || !xmlStrEqual(protocolProfile, lassoLibProtocolProfileSloSpSoap)) {
+ all_http_soap = FALSE;
+ break;
+ }
+
+ if (protocolProfile != NULL) {
+ xmlFree(protocolProfile);
+ }
+
+ if (providerID != NULL) {
+ xmlFree(providerID);
+ }
+ }
+
+ if (all_http_soap==FALSE) {
+ statusCode_class->set_prop(statusCode, "Value", lassoLibStatusCodeUnsupportedProfile);
+ return(-1);
+ }
+ }
+
+ lasso_federation_destroy(federation);
+
+ /* authentication is ok, federation is ok, propagation support is ok, remove federation */
/* verification is ok, save name identifier in logout object */
lasso_session_remove_assertion(profile->session, profile->remote_providerID);
if (profile->provider_type == lassoProviderTypeIdp) {
@@ -750,7 +794,7 @@ GType lasso_logout_get_type() {
*
* initialises a new logout object
*
- * Return value:
+ * Return value: a new instance of logout object or NULL
**/
LassoLogout*
lasso_logout_new(LassoServer *server,
diff --git a/lasso/id-ff/logout.h b/lasso/id-ff/logout.h
index 72fa09dd..f1c59cd6 100644
--- a/lasso/id-ff/logout.h
+++ b/lasso/id-ff/logout.h
@@ -49,11 +49,14 @@ struct _LassoLogout {
LassoProfile parent;
/*< public >*/
+
+ /*< private >*/
LassoNode *initial_request;
LassoNode *initial_response;
gchar *initial_remote_providerID;
- /*< private >*/
+ lassoHttpMethod http_request_method;
+
LassoLogoutPrivate *private;
};