diff options
| -rw-r--r-- | lasso/Attic/protocols/logout_response.c | 12 | ||||
| -rw-r--r-- | lasso/id-ff/logout.c | 100 | ||||
| -rw-r--r-- | lasso/id-ff/logout.h | 7 | ||||
| -rw-r--r-- | python/environs/py_logout.c | 19 | ||||
| -rw-r--r-- | python/environs/py_logout.h | 1 | ||||
| -rw-r--r-- | python/examples/logout-from-idp.py | 4 | ||||
| -rw-r--r-- | python/examples/logout.py | 81 | ||||
| -rw-r--r-- | python/lasso.py | 5 | ||||
| -rw-r--r-- | python/lassomod.c | 1 |
9 files changed, 182 insertions, 48 deletions
diff --git a/lasso/Attic/protocols/logout_response.c b/lasso/Attic/protocols/logout_response.c index 3eaac369..6f2a2fc2 100644 --- a/lasso/Attic/protocols/logout_response.c +++ b/lasso/Attic/protocols/logout_response.c @@ -256,8 +256,16 @@ lasso_logout_response_new_from_soap(gchar *buffer) response = LASSO_NODE(g_object_new(LASSO_TYPE_LOGOUT_RESPONSE, NULL)); envelope = lasso_node_new_from_dump(buffer); - lassoNode_response = lasso_node_get_child(envelope, "LogoutResponse", lassoLibHRef); - + if(envelope==NULL){ + debug(ERROR, "Error while parsing the soap msg\n"); + return(NULL); + } + + lassoNode_response = lasso_node_get_child(envelope, "LogoutResponse", NULL); + if(lassoNode_response==NULL){ + debug(ERROR, "LogoutResponse node not found\n"); + return(NULL); + } class = LASSO_NODE_GET_CLASS(lassoNode_response); xmlNode_response = xmlCopyNode(class->get_xmlNode(LASSO_NODE(lassoNode_response)), 1); lasso_node_destroy(lassoNode_response); diff --git a/lasso/id-ff/logout.c b/lasso/id-ff/logout.c index 34231913..c187943f 100644 --- a/lasso/id-ff/logout.c +++ b/lasso/id-ff/logout.c @@ -34,8 +34,7 @@ static GObjectClass *parent_class = NULL; gchar * lasso_logout_dump(LassoLogout *logout) { - LassoProfileContext *profileContext; - gchar *dump; + gchar *dump = NULL; g_return_val_if_fail(LASSO_IS_LOGOUT(logout), NULL); @@ -47,7 +46,7 @@ lasso_logout_build_request_msg(LassoLogout *logout) { LassoProfileContext *profileContext; LassoProvider *provider; - xmlChar *protocolProfile, *singleLogoutServiceURL; + xmlChar *protocolProfile; g_return_val_if_fail(LASSO_IS_LOGOUT(logout), -1); @@ -99,7 +98,6 @@ lasso_logout_build_response_msg(LassoLogout *logout) LassoProfileContext *profileContext; LassoProvider *provider; xmlChar *protocolProfile; - int codeError = 0; if(!LASSO_IS_LOGOUT(logout)){ debug(ERROR, "Not a Logout object\n"); @@ -143,6 +141,34 @@ lasso_logout_destroy(LassoLogout *logout) g_object_unref(G_OBJECT(logout)); } +gchar* +lasso_logout_get_next_providerID(LassoLogout *logout) +{ + LassoProfileContext *profileContext; + gchar *current_provider_id; + int i; + + + g_return_val_if_fail(LASSO_IS_LOGOUT(logout), NULL); + + profileContext = LASSO_PROFILE_CONTEXT(logout); + + /* if a ProviderID from a SP request, pass it and return the next provider id found */ + for(i = 0; i<profileContext->user->assertion_providerIDs->len; i++){ + current_provider_id = g_strdup(g_ptr_array_index(profileContext->user->assertion_providerIDs, i)); + if(logout->first_remote_providerID!=NULL){ + if(xmlStrEqual(current_provider_id, logout->first_remote_providerID)){ + /* debug(INFO, "It's the ProviderID of the SP requester (%s) : %s, pass it\n", logout->first_remote_providerID, current_provider_id); */ + xmlFree(current_provider_id); + continue; + } + } + return(current_provider_id); + } + + return(NULL); +} + gint lasso_logout_init_request(LassoLogout *logout, gchar *remote_providerID) @@ -150,7 +176,6 @@ lasso_logout_init_request(LassoLogout *logout, LassoProfileContext *profileContext; LassoNode *nameIdentifier; LassoIdentity *identity; - LassoLogoutRequest *request; xmlChar *content, *nameQualifier, *format; @@ -159,11 +184,11 @@ lasso_logout_init_request(LassoLogout *logout, profileContext = LASSO_PROFILE_CONTEXT(logout); if(remote_providerID==NULL){ - debug(INFO, "No remote provider id, get the next assertion peer provider id\n"); + /* debug(INFO, "No remote provider id, get the next assertion peer provider id\n"); */ profileContext->remote_providerID = lasso_user_get_next_assertion_remote_providerID(profileContext->user); } else{ - debug(INFO, "A remote provider id for logout request : %s\n", remote_providerID); + /* debug(INFO, "A remote provider id for logout request : %s\n", remote_providerID); */ profileContext->remote_providerID = g_strdup(remote_providerID); } @@ -286,7 +311,7 @@ lasso_logout_process_request_msg(LassoLogout *logout, return(-7); } - /* verify authentication (if ok, delete assertion) */ + /* verify authentication */ if(profileContext->user==NULL){ debug(WARNING, "User environ not found\n"); statusCode_class->set_prop(statusCode, "Value", lassoSamlStatusCodeRequestDenied); @@ -313,6 +338,27 @@ lasso_logout_process_request_msg(LassoLogout *logout, return(-10); } + switch(profileContext->provider_type){ + case lassoProviderTypeSp: + /* at sp, everything is ok, delete the assertion */ + lasso_user_remove_assertion(profileContext->user, profileContext->remote_providerID); + break; + case lassoProviderTypeIdp: + /* at idp, backup original infos of the sp requester */ + logout->first_request = profileContext->request; + profileContext->request = NULL; + + logout->first_response = profileContext->response; + profileContext->response = NULL; + + logout->first_remote_providerID = profileContext->remote_providerID; + profileContext->remote_providerID = NULL; + + break; + default: + debug(ERROR, "Uknown provider type\n"); + } + return(0); } @@ -342,11 +388,45 @@ lasso_logout_process_response_msg(LassoLogout *logout, debug(ERROR, "Unknown response method\n"); return(-3); } - + + if(profileContext->response==NULL){ + debug(ERROR, "LogoutResponse is NULL\n"); + return(-1); + } statusCode = lasso_node_get_child(profileContext->response, "StatusCode", NULL); + + if(statusCode==NULL){ + debug(ERROR, "StatusCode node not found\n"); + return(-1); + } + statusCodeValue = lasso_node_get_attr_value(statusCode, "Value", NULL); + if(!xmlStrEqual(statusCodeValue, lassoSamlStatusCodeSuccess)){ - return(-4); + return(-1); + } + + profileContext->remote_providerID = lasso_node_get_child_content(profileContext->response, "ProviderID", NULL); + /* response is ok, so delete the assertion */ + switch(profileContext->provider_type){ + case lassoProviderTypeSp: + break; + case lassoProviderTypeIdp: + /* response os ok, delete the assertion */ + lasso_user_remove_assertion(profileContext->user, profileContext->remote_providerID); + debug(INFO, "Remove assertion for %s\n", profileContext->remote_providerID); + + /* if no more assertion for other providers, remove assertion of the original provider */ + if(profileContext->user->assertion_providerIDs->len == 1){ + debug(WARNING, "remove assertion of the original provider\n"); + lasso_user_remove_assertion(profileContext->user, logout->first_remote_providerID); + + printf("%s\n", lasso_user_dump(profileContext->user)); + } + + break; + default: + debug(ERROR, "Unkown provider type\n"); } return(0); diff --git a/lasso/id-ff/logout.h b/lasso/id-ff/logout.h index b3cc028b..bf86fd26 100644 --- a/lasso/id-ff/logout.h +++ b/lasso/id-ff/logout.h @@ -47,6 +47,11 @@ typedef struct _LassoLogoutClass LassoLogoutClass; struct _LassoLogout { LassoProfileContext parent; + + LassoNode *first_request; + LassoNode *first_response; + gchar *first_remote_providerID; + /*< public >*/ /*< private >*/ }; @@ -68,6 +73,8 @@ LASSO_EXPORT gint lasso_logout_build_response_msg (LassoLogout *log LASSO_EXPORT void lasso_logout_destroy (LassoLogout *logout); +LASSO_EXPORT gchar* lasso_logout_get_next_providerID (LassoLogout *logout); + LASSO_EXPORT gint lasso_logout_init_request (LassoLogout *logout, gchar *remote_providerID); diff --git a/python/environs/py_logout.c b/python/environs/py_logout.c index 7e444a07..35fa483e 100644 --- a/python/environs/py_logout.c +++ b/python/environs/py_logout.c @@ -138,6 +138,25 @@ PyObject *logout_destroy(PyObject *self, PyObject *args){ return(Py_None); } +PyObject *logout_get_next_providerID(PyObject *self, PyObject *args) { + PyObject *logout_obj; + gchar *remote_providerID; + + if (CheckArgs(args, "O:logout_get_next_providerID")) { + if(!PyArg_ParseTuple(args, (char *) "O:logout_get_next_providerID", &logout_obj)) + return NULL; + } + else return NULL; + + remote_providerID = lasso_logout_get_next_providerID(LassoLogout_get(logout_obj)); + if(remote_providerID==NULL){ + Py_INCREF(Py_None); + return (Py_None); + } + + return (charPtr_wrap(remote_providerID)); +} + PyObject *logout_init_request(PyObject *self, PyObject *args) { PyObject *logout_obj; gchar *remote_providerID; diff --git a/python/environs/py_logout.h b/python/environs/py_logout.h index 479f0764..773ec548 100644 --- a/python/environs/py_logout.h +++ b/python/environs/py_logout.h @@ -44,6 +44,7 @@ PyObject *logout_getattr(PyObject *self, PyObject *args); PyObject *logout_build_request_msg(PyObject *self, PyObject *args); PyObject *logout_build_response_msg(PyObject *self, PyObject *args); PyObject *logout_destroy(PyObject *self, PyObject *args); +PyObject *logout_get_next_providerID(PyObject *self, PyObject *args); PyObject *logout_init_request(PyObject *self, PyObject *args); PyObject *logout_new(PyObject *self, PyObject *args); PyObject *logout_process_request_msg(PyObject *self, PyObject *args); diff --git a/python/examples/logout-from-idp.py b/python/examples/logout-from-idp.py index 398b9695..f1e21b05 100644 --- a/python/examples/logout-from-idp.py +++ b/python/examples/logout-from-idp.py @@ -43,7 +43,9 @@ while(next_provider_id): print 'url : ', logout.msg_url print 'body : ', logout.msg_body - user.remove_assertion(next_provider_id) + # use the fake response : + lasso_logout_process_response_msg() + next_provider_id = user.get_next_assertion_remote_providerID() print "End of logout ..." diff --git a/python/examples/logout.py b/python/examples/logout.py index efdbcb96..c4f13254 100644 --- a/python/examples/logout.py +++ b/python/examples/logout.py @@ -6,55 +6,68 @@ import lasso lasso.init() -spserver = lasso.Server.new("../../examples/sp.xml", +# SP1 server and user : +sp1server = lasso.Server.new("../../examples/sp1.xml", "../../examples/rsapub.pem", "../../examples/rsakey.pem", "../../examples/rsacert.pem", lasso.signatureMethodRsaSha1) +sp1server.add_provider("../../examples/idp.xml", None, None) -spserver.add_provider("../../examples/idp.xml", None, None) -spserver.add_provider("../../examples/idp2.xml", None, None) +sp1user_dump = "<LassoUser><LassoAssertions><LassoAssertion RemoteProviderID=\"https://identity-provider:2003/liberty-alliance/metadata\"><Assertion AssertionID=\"C9DS8CD7CSD6CDSCKDKCS\"></Assertion></LassoAssertion></LassoAssertions><LassoIdentities><LassoIdentity RemoteProviderID=\"https://identity-provider:2003/liberty-alliance/metadata\"><LassoRemoteNameIdentifier><NameIdentifier NameQualifier=\"qualifier.com\" Format=\"federated\">11111111111111111111111111</NameIdentifier></LassoRemoteNameIdentifier></LassoIdentity></LassoIdentities></LassoUser>" -spuser_dump = "<LassoUser><LassoAssertions><LassoAssertion RemoteProviderID=\"https://identity-provider:2003/liberty-alliance/metadata\"><Assertion AssertionID=\"CD8SCD7SC6SDCD5CDSDCD88SDCDSD\"></Assertion></LassoAssertion></LassoAssertions><LassoIdentities><LassoIdentity RemoteProviderID=\"https://identity-provider:2003/liberty-alliance/metadata\"><LassoLocalNameIdentifier><NameIdentifier NameQualifier=\"qualifier.com\" Format=\"federated\">11111111111111111111111111</NameIdentifier></LassoLocalNameIdentifier></LassoIdentity><LassoIdentity RemoteProviderID=\"https://identity-provider2:2003/liberty-alliance/metadata\"><LassoLocalNameIdentifier><NameIdentifier NameQualifier=\"qualifier.com\" Format=\"federated\">22222222222222222222222222</NameIdentifier></LassoLocalNameIdentifier></LassoIdentity></LassoIdentities></LassoUser>" +# SP2 server and user : +sp2server = lasso.Server.new("../../examples/sp2.xml", + "../../examples/rsapub.pem", "../../examples/rsakey.pem", "../../examples/rsacert.pem", + lasso.signatureMethodRsaSha1) +sp2server.add_provider("../../examples/idp.xml", None, None) -spuser = lasso.User.new_from_dump(spuser_dump) +sp2user_dump = "<LassoUser><LassoAssertions><LassoAssertion RemoteProviderID=\"https://identity-provider:2003/liberty-alliance/metadata\"><Assertion AssertionID=\"4IK43JCJSDCSDKCSCSDL\"></Assertion></LassoAssertion></LassoAssertions><LassoIdentities><LassoIdentity RemoteProviderID=\"https://identity-provider:2003/liberty-alliance/metadata\"><LassoRemoteNameIdentifier><NameIdentifier NameQualifier=\"qualifier.com\" Format=\"federated\">222222222222222222222222</NameIdentifier></LassoRemoteNameIdentifier></LassoIdentity></LassoIdentities></LassoUser>" -# LogoutRequest : -splogout = lasso.Logout.new(spserver, spuser, lasso.providerTypeSp) -splogout.init_request() -splogout.build_request_msg() +# IDP server and user : +idpserver = lasso.Server.new("../../examples/idp.xml", + "../../examples/rsapub.pem", "../../examples/rsakey.pem", "../../examples/rsacert.pem", + lasso.signatureMethodRsaSha1) +idpserver.add_provider("../../examples/sp1.xml", None, None) +idpserver.add_provider("../../examples/sp2.xml", None, None) +idpserver.add_provider("../../examples/sp3.xml", None, None) -request_msg = splogout.msg_body -msg_url = splogout.msg_url -msg_body = splogout.msg_body +idpuser_dump = "<LassoUser><LassoAssertions><LassoAssertion RemoteProviderID=\"https://service-provider1:2003/liberty-alliance/metadata\"><Assertion AssertionID=\"C9DS8CD7CSD6CDSCKDKCS\"></Assertion></LassoAssertion><LassoAssertion RemoteProviderID=\"https://service-provider2:2003/liberty-alliance/metadata\"><Assertion AssertionID=\"4IK43JCJSDCSDKCSCSDL\"></Assertion></LassoAssertion></LassoAssertions><LassoIdentities><LassoIdentity RemoteProviderID=\"https://service-provider1:2003/liberty-alliance/metadata\"><LassoLocalNameIdentifier><NameIdentifier NameQualifier=\"qualifier.com\" Format=\"federated\">11111111111111111111111111</NameIdentifier></LassoLocalNameIdentifier></LassoIdentity><LassoIdentity RemoteProviderID=\"https://service-provider2:2003/liberty-alliance/metadata\"><LassoLocalNameIdentifier><NameIdentifier NameQualifier=\"qualifier.com\" Format=\"federated\">222222222222222222222222</NameIdentifier></LassoLocalNameIdentifier></LassoIdentity></LassoIdentities></LassoUser>" -splogout.destroy() -print 'request url : ', msg_url -print 'request body : ', msg_body -request_type = lasso.get_request_type_from_soap_msg(msg_body) -if request_type == lasso.requestTypeLogout: - print "it's a LogoutRequest !" +# SP1 build a request : +sp1user = lasso.User.new_from_dump(sp1user_dump) +sp1logout = lasso.Logout.new(sp1server, sp1user, lasso.providerTypeSp) +sp1logout.init_request() +sp1logout.build_request_msg() -# LogoutResponse : -idpserver = lasso.Server.new("../../examples/idp.xml", - "../../examples/rsapub.pem", "../../examples/rsakey.pem", "../../examples/rsacert.pem", - lasso.signatureMethodRsaSha1) -idpserver.add_provider("../../examples/sp.xml", None, None) +msg_url = sp1logout.msg_url +msg_body = sp1logout.msg_body -idpuser_dump = "<LassoUser><LassoAssertions></LassoAssertions><LassoIdentities></LassoIdentities></LassoUser>" -idpuser = lasso.User.new_from_dump(idpuser_dump) +sp1logout.destroy() +# IDP process request and return a response : +idpuser = lasso.User.new_from_dump(idpuser_dump) idplogout = lasso.Logout.new(idpserver, idpuser, lasso.providerTypeIdp) -idplogout.process_request_msg(request_msg, lasso.httpMethodSoap) -idplogout.build_response_msg() -msg_url = idplogout.msg_url -msg_body = idplogout.msg_body -print 'body : ', idplogout.msg_body -# process the response : -splogout = lasso.Logout.new(spserver, spuser, lasso.providerTypeSp) -splogout.process_response_msg(msg_body, lasso.httpMethodSoap) +if lasso.get_request_type_from_soap_msg(msg_body)==lasso.requestTypeLogout: + print "it's a logout request !" + +#fake response, only for test ! +response_msg_body = "<Envelope><LogoutResponse><ProviderID>https://service-provider2:2003/liberty-alliance/metadata</ProviderID><Status><StatusCode Value=\"Samlp:Success\"></StatusCode></Status></LogoutResponse></Envelope>" + +idplogout.process_request_msg(msg_body, lasso.httpMethodSoap) +next_provider_id = idplogout.get_next_providerID() +while next_provider_id: + idplogout.init_request(next_provider_id) + idplogout.build_request_msg() + + print "send soap msg to url", idplogout.msg_url + # remote SP send back a LogoutResponse, process it. + idplogout.process_response_msg(response_msg_body, lasso.httpMethodSoap) + + next_provider_id = idplogout.get_next_providerID() + -lasso.shutdown() +print "End of logout" diff --git a/python/lasso.py b/python/lasso.py index 000709c3..855ba163 100644 --- a/python/lasso.py +++ b/python/lasso.py @@ -1017,7 +1017,10 @@ class Logout: return lassomod.logout_build_response_msg(self) def destroy(self): - pass + lassomod.logout_destroy(self); + + def get_next_providerID(self): + return lassomod.logout_get_next_providerID(self); def init_request(self, remote_providerID = None): return lassomod.logout_init_request(self, remote_providerID); diff --git a/python/lassomod.c b/python/lassomod.c index 47e66c69..171abf92 100644 --- a/python/lassomod.c +++ b/python/lassomod.c @@ -237,6 +237,7 @@ static PyMethodDef lasso_methods[] = { {"logout_build_request_msg", logout_build_request_msg, METH_VARARGS}, {"logout_build_response_msg", logout_build_response_msg, METH_VARARGS}, {"logout_destroy", logout_destroy, METH_VARARGS}, + {"logout_get_next_providerID", logout_get_next_providerID, METH_VARARGS}, {"logout_init_request", logout_init_request, METH_VARARGS}, {"logout_process_request_msg", logout_process_request_msg, METH_VARARGS}, {"logout_process_response_msg", logout_process_response_msg, METH_VARARGS}, |
