SAML2: change lasso_saml20_profile_set_response_status signature

* lasso/saml-2.0/profile.c:
 * lasso/saml-2.0/profileprivate.h:
   make lasso_saml20_profile_set_response_status2 the new implementation
   of lasso_saml20_profile_set_response_status.
   add helper macros to set success, responder and requester first level
   status code.
 * saml-2.0/assertion_query.c:
 * saml-2.0/login.c:
 * saml-2.0/logout.c:
 * saml-2.0/name_id_management.c:
   adapt consumers to the new signature.
This commit is contained in:
Benjamin Dauvergne 2009-10-30 14:47:30 +00:00
parent a8e89261dd
commit 2b24cd50e2
6 changed files with 82 additions and 118 deletions

View File

@ -280,7 +280,7 @@ lasso_assertion_query_validate_request(LassoAssertionQuery *assertion_query)
LASSO_PROVIDER(profile->server)->ProviderID));
response->IssueInstant = lasso_get_current_time();
response->InResponseTo = g_strdup(LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->ID);
lasso_saml20_profile_set_response_status(profile, LASSO_SAML2_STATUS_CODE_SUCCESS);
lasso_saml20_profile_set_response_status(profile, LASSO_SAML2_STATUS_CODE_SUCCESS, NULL);
response->sign_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
if (profile->server->certificate) {
@ -293,8 +293,7 @@ lasso_assertion_query_validate_request(LassoAssertionQuery *assertion_query)
/* verify signature status */
if (profile->signature_status != 0) {
/* XXX: which SAML2 Status Code ? */
lasso_saml20_profile_set_response_status(profile,
lasso_saml20_profile_set_response_status_requester(profile,
LASSO_LIB_STATUS_CODE_INVALID_SIGNATURE);
return profile->signature_status;
}
@ -333,7 +332,7 @@ lasso_assertion_query_build_response_msg(LassoAssertionQuery *assertion_query)
response->IssueInstant = lasso_get_current_time();
response->InResponseTo = g_strdup(
LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->ID);
lasso_saml20_profile_set_response_status(profile,
lasso_saml20_profile_set_response_status_responder(profile,
LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
response->sign_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;

View File

@ -400,7 +400,7 @@ lasso_saml20_login_must_authenticate(LassoLogin *login)
return TRUE;
if (profile->identity == NULL && request->IsPassive) {
lasso_saml20_profile_set_response_status(LASSO_PROFILE(login),
lasso_saml20_profile_set_response_status_responder(LASSO_PROFILE(login),
LASSO_SAML2_STATUS_CODE_NO_PASSIVE);
return FALSE;
}
@ -493,19 +493,19 @@ lasso_saml20_login_validate_request_msg(LassoLogin *login, gboolean authenticati
profile = LASSO_PROFILE(login);
if (authentication_result == FALSE) {
lasso_saml20_profile_set_response_status(profile,
lasso_saml20_profile_set_response_status_responder(profile,
LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
return LASSO_LOGIN_ERROR_REQUEST_DENIED;
}
if (profile->signature_status == LASSO_DS_ERROR_INVALID_SIGNATURE) {
lasso_saml20_profile_set_response_status(profile,
lasso_saml20_profile_set_response_status_responder(profile,
LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
return LASSO_LOGIN_ERROR_INVALID_SIGNATURE;
}
if (profile->signature_status == LASSO_DS_ERROR_SIGNATURE_NOT_FOUND) {
lasso_saml20_profile_set_response_status(profile,
lasso_saml20_profile_set_response_status_responder(profile,
LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
return LASSO_LOGIN_ERROR_UNSIGNED_AUTHN_REQUEST;
}
@ -513,19 +513,19 @@ lasso_saml20_login_validate_request_msg(LassoLogin *login, gboolean authenticati
if (profile->signature_status == 0 && authentication_result == TRUE) {
ret = lasso_saml20_login_process_federation(login, is_consent_obtained);
if (ret == LASSO_LOGIN_ERROR_FEDERATION_NOT_FOUND) {
lasso_saml20_profile_set_response_status(profile,
lasso_saml20_profile_set_response_status_requester(profile,
LASSO_LIB_STATUS_CODE_FEDERATION_DOES_NOT_EXIST);
return ret;
}
/* Only possibility, consent not obtained. */
if (ret) {
lasso_saml20_profile_set_response_status(profile,
lasso_saml20_profile_set_response_status_responder(profile,
LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
return ret;
}
}
lasso_saml20_profile_set_response_status(profile, LASSO_SAML2_STATUS_CODE_SUCCESS);
lasso_saml20_profile_set_response_status_success(profile, NULL);
return ret;
}

View File

@ -31,7 +31,6 @@
#include "../id-ff/providerprivate.h"
#include "../id-ff/logout.h"
#include "../id-ff/logoutprivate.h"
#include "../id-ff/identityprivate.h"
#include "../id-ff/sessionprivate.h"
#include "../id-ff/profileprivate.h"
#include "../id-ff/serverprivate.h"
@ -41,6 +40,7 @@
#include "../xml/saml-2.0/samlp2_logout_request.h"
#include "../xml/saml-2.0/samlp2_logout_response.h"
#include "../xml/saml-2.0/saml2_assertion.h"
#include "../xml/saml-2.0/saml2_authn_statement.h"
#include "../utils.h"
static void check_soap_support(gchar *key, LassoProvider *provider, LassoProfile *profile);
@ -50,10 +50,9 @@ lasso_saml20_logout_init_request(LassoLogout *logout, LassoProvider *remote_prov
LassoHttpMethod http_method)
{
LassoProfile *profile = LASSO_PROFILE(logout);
LassoNode *assertion_n, *name_id_n;
LassoNode *assertion_n;
LassoSaml2Assertion *assertion;
LassoSaml2NameID *name_id;
LassoFederation *federation;
LassoSession *session;
LassoSamlp2RequestAbstract *request;
LassoSaml2EncryptedElement *encrypted_element = NULL;
@ -77,39 +76,8 @@ lasso_saml20_logout_init_request(LassoLogout *logout, LassoProvider *remote_prov
}
name_id = assertion->Subject->NameID;
if (name_id->Format && strcmp(name_id->Format,
LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT) == 0) {
char *name_id_sp_name_qualifier = NULL;
if (LASSO_IS_IDENTITY(profile->identity) == FALSE) {
return critical_error(LASSO_PROFILE_ERROR_IDENTITY_NOT_FOUND);
}
if (remote_provider->private_data->affiliation_id) {
name_id_sp_name_qualifier = remote_provider->private_data->affiliation_id;
} else {
name_id_sp_name_qualifier = profile->remote_providerID;
}
federation = g_hash_table_lookup(profile->identity->federations,
name_id_sp_name_qualifier);
if (federation == NULL) {
return critical_error(LASSO_PROFILE_ERROR_FEDERATION_NOT_FOUND);
}
name_id_n = lasso_profile_get_nameIdentifier(profile);
if (name_id_n == NULL) {
return critical_error(LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND);
}
if (federation->local_nameIdentifier) {
lasso_assign_gobject(profile->nameIdentifier, federation->local_nameIdentifier);
} else {
lasso_assign_gobject(profile->nameIdentifier, name_id_n);
}
} else {
lasso_assign_gobject(profile->nameIdentifier, name_id);
}
/* Just send back the NameID from the assertion. */
lasso_assign_gobject(profile->nameIdentifier, name_id);
if (http_method == LASSO_HTTP_METHOD_ANY) {
http_method = lasso_provider_get_first_http_method(
@ -259,11 +227,14 @@ lasso_saml20_logout_validate_request(LassoLogout *logout)
LassoSaml2NameID *name_id;
LassoNode *assertion_n;
LassoSaml2Assertion *assertion;
LassoFederation *federation;
LassoSamlp2LogoutRequest *logout_request;
char *assertion_SessionIndex = NULL;
if (LASSO_IS_SAMLP2_LOGOUT_REQUEST(profile->request) == FALSE)
return LASSO_PROFILE_ERROR_MISSING_REQUEST;
logout_request = (LassoSamlp2LogoutRequest*)profile->request;
lasso_assign_string(profile->remote_providerID,
LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->Issuer->content);
@ -283,7 +254,7 @@ lasso_saml20_logout_validate_request(LassoLogout *logout)
lasso_assign_new_string(response->IssueInstant, lasso_get_current_time());
lasso_assign_string(response->InResponseTo,
LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->ID);
lasso_saml20_profile_set_response_status(profile, LASSO_SAML2_STATUS_CODE_SUCCESS);
lasso_saml20_profile_set_response_status_success(profile, NULL);
response->sign_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
if (profile->server->certificate) {
@ -296,8 +267,7 @@ lasso_saml20_logout_validate_request(LassoLogout *logout)
/* verify signature status */
if (profile->signature_status != 0) {
/* XXX: which SAML2 Status Code ? */
lasso_saml20_profile_set_response_status(profile,
lasso_saml20_profile_set_response_status_requester(profile,
LASSO_LIB_STATUS_CODE_INVALID_SIGNATURE);
return profile->signature_status;
}
@ -305,15 +275,13 @@ lasso_saml20_logout_validate_request(LassoLogout *logout)
/* Get the name identifier */
name_id = LASSO_SAMLP2_LOGOUT_REQUEST(profile->request)->NameID;
if (name_id == NULL) {
message(G_LOG_LEVEL_CRITICAL, "Name identifier not found in logout request");
/* XXX: which status code in SAML 2.0 ? */
lasso_saml20_profile_set_response_status(
lasso_saml20_profile_set_response_status_responder(
profile, LASSO_LIB_STATUS_CODE_FEDERATION_DOES_NOT_EXIST);
return LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND;
}
if (profile->session == NULL) {
lasso_saml20_profile_set_response_status(profile,
lasso_saml20_profile_set_response_status_responder(profile,
LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
return critical_error(LASSO_PROFILE_ERROR_SESSION_NOT_FOUND);
}
@ -321,53 +289,45 @@ lasso_saml20_logout_validate_request(LassoLogout *logout)
/* verify authentication */
assertion_n = lasso_session_get_assertion(profile->session, profile->remote_providerID);
if (LASSO_IS_SAML2_ASSERTION(assertion_n) == FALSE) {
message(G_LOG_LEVEL_WARNING, "%s has no assertion", profile->remote_providerID);
lasso_saml20_profile_set_response_status(profile,
lasso_saml20_profile_set_response_status_responder(profile,
LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
return LASSO_PROFILE_ERROR_MISSING_ASSERTION;
}
assertion = LASSO_SAML2_ASSERTION(assertion_n);
/* If name identifier is federated, then verify federation */
if (strcmp(name_id->Format, LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT) == 0) {
char *name_id_sp_name_qualifier = NULL;
if (LASSO_IS_IDENTITY(profile->identity) == FALSE) {
/* XXX: which SAML 2 status code ? */
lasso_saml20_profile_set_response_status(profile,
LASSO_LIB_STATUS_CODE_FEDERATION_DOES_NOT_EXIST);
return critical_error(LASSO_PROFILE_ERROR_IDENTITY_NOT_FOUND);
}
/* Verify name identifier and session matching */
if (assertion->Subject == NULL) {
lasso_saml20_profile_set_response_status(profile,
LASSO_SAML2_STATUS_CODE_RESPONDER, "http://lasso.entrouvert.org/error/MalformedAssertion");
return LASSO_PROFILE_ERROR_MISSING_SUBJECT;
}
if (remote_provider->private_data->affiliation_id) {
name_id_sp_name_qualifier = remote_provider->private_data->affiliation_id;
} else {
name_id_sp_name_qualifier = profile->remote_providerID;
}
if (lasso_saml2_name_id_equals(name_id, assertion->Subject->NameID) != TRUE) {
lasso_saml20_profile_set_response_status_responder(profile,
LASSO_SAML2_STATUS_CODE_UNKNOWN_PRINCIPAL);
return LASSO_LOGOUT_ERROR_UNKNOWN_PRINCIPAL;
}
federation = g_hash_table_lookup(profile->identity->federations,
name_id_sp_name_qualifier);
if (LASSO_IS_FEDERATION(federation) == FALSE) {
/* XXX: which status code in SAML 2 ? */
lasso_saml20_profile_set_response_status(profile,
LASSO_LIB_STATUS_CODE_FEDERATION_DOES_NOT_EXIST);
return critical_error(LASSO_PROFILE_ERROR_FEDERATION_NOT_FOUND);
}
/* verify session index */
if (assertion->AuthnStatement) {
if (! LASSO_IS_SAML2_AUTHN_STATEMENT(assertion->AuthnStatement->data)) {
if (lasso_federation_verify_name_identifier(federation,
LASSO_NODE(name_id)) == FALSE) {
message(G_LOG_LEVEL_WARNING, "No name identifier for %s",
profile->remote_providerID);
lasso_saml20_profile_set_response_status(profile,
LASSO_LIB_STATUS_CODE_FEDERATION_DOES_NOT_EXIST);
return LASSO_LOGOUT_ERROR_FEDERATION_NOT_FOUND;
LASSO_SAML2_STATUS_CODE_RESPONDER, "http://lasso.entrouvert.org/error/MalformedAssertion");
return LASSO_PROFILE_ERROR_BAD_SESSION_DUMP;
}
assertion_SessionIndex =
((LassoSaml2AuthnStatement*)assertion->AuthnStatement->data)->SessionIndex;
if (g_strcmp0(logout_request->SessionIndex, assertion_SessionIndex) != 0) {
lasso_saml20_profile_set_response_status_responder(profile,
LASSO_SAML2_STATUS_CODE_UNKNOWN_PRINCIPAL);
return LASSO_LOGOUT_ERROR_UNKNOWN_PRINCIPAL;
}
}
/* 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 */
SOAP protocol profile. If one remote authenticated principal service provider doesn't
support SOAP then return UnsupportedProfile to original service provider */
if (remote_provider->role == LASSO_PROVIDER_ROLE_SP &&
profile->http_request_method == LASSO_HTTP_METHOD_SOAP) {
@ -376,7 +336,7 @@ lasso_saml20_logout_validate_request(LassoLogout *logout)
(GHFunc)check_soap_support, profile);
if (logout->private_data->all_soap == FALSE) {
lasso_saml20_profile_set_response_status(profile,
lasso_saml20_profile_set_response_status_responder(profile,
LASSO_LIB_STATUS_CODE_UNSUPPORTED_PROFILE);
return LASSO_LOGOUT_ERROR_UNSUPPORTED_PROFILE;
}
@ -446,7 +406,7 @@ lasso_saml20_logout_build_response_msg(LassoLogout *logout)
lasso_assign_string(response->InResponseTo,
LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->ID);
}
lasso_saml20_profile_set_response_status(profile,
lasso_saml20_profile_set_response_status_responder(profile,
LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
response->sign_method = LASSO_SIGNATURE_METHOD_RSA_SHA1;
@ -523,6 +483,7 @@ lasso_saml20_logout_process_response_msg(LassoLogout *logout, const char *respon
/* If at SP, if the request method was a SOAP type, then
* rebuild the request message with HTTP method */
/* XXX is this still what to do for SAML 2.0? */
logout->private_data->partial_logout = TRUE;
if (strcmp(status_code_value, LASSO_SAML2_STATUS_CODE_RESPONDER) == 0) {
/* Responder -> look inside */
@ -543,7 +504,6 @@ lasso_saml20_logout_process_response_msg(LassoLogout *logout, const char *respon
if (strcmp(status_code_value, LASSO_SAML2_STATUS_CODE_UNKNOWN_PRINCIPAL) == 0) {
rc = LASSO_LOGOUT_ERROR_UNKNOWN_PRINCIPAL;
}
message(G_LOG_LEVEL_CRITICAL, "Status code is not success: %s", status_code_value);
rc = LASSO_PROFILE_ERROR_STATUS_NOT_SUCCESS;
}
@ -573,6 +533,14 @@ lasso_saml20_logout_process_response_msg(LassoLogout *logout, const char *respon
logout->initial_remote_providerID);
lasso_transfer_gobject(profile->request, logout->initial_request);
lasso_transfer_gobject(profile->response, logout->initial_response);
/* if some of the logout failed, set a partial logout status code */
if (logout->private_data->partial_logout) {
/* reset the partial logout status */
logout->private_data->partial_logout = FALSE;
lasso_saml20_profile_set_response_status(profile,
LASSO_SAML2_STATUS_CODE_SUCCESS,
LASSO_SAML2_STATUS_CODE_PARTIAL_LOGOUT);
}
}
}

View File

@ -199,7 +199,7 @@ lasso_name_id_management_validate_request(LassoNameIdManagement *name_id_managem
if (! LASSO_IS_SAML2_NAME_ID(name_id)) {
message(G_LOG_LEVEL_CRITICAL,
"Name identifier not found in name id management request");
lasso_saml20_profile_set_response_status(
lasso_saml20_profile_set_response_status_responder(
profile,
LASSO_SAML2_STATUS_CODE_UNKNOWN_PRINCIPAL);
rc = LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND;
@ -275,7 +275,8 @@ lasso_name_id_management_build_response_msg(LassoNameIdManagement *name_id_manag
/* no response set here means request denied */
if (! profile->response) {
profile->response = lasso_samlp2_manage_name_id_response_new();
lasso_saml20_profile_init_response(profile, LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
lasso_saml20_profile_init_response(profile, LASSO_SAML2_STATUS_CODE_RESPONDER,
LASSO_SAML2_STATUS_CODE_REQUEST_DENIED);
}
rc = lasso_saml20_profile_build_response(profile, "ManageNameIDService", FALSE, profile->http_request_method);

View File

@ -155,8 +155,8 @@ lasso_saml20_profile_build_artifact(LassoProvider *provider)
return ret;
}
static int
lasso_saml20_profile_set_response_status2(LassoProfile *profile,
int
lasso_saml20_profile_set_response_status(LassoProfile *profile,
const char *code1, const char *code2)
{
LassoSamlp2StatusResponse *status_response = NULL;
@ -195,19 +195,6 @@ cleanup:
return rc;
}
void
lasso_saml20_profile_set_response_status(LassoProfile *profile, const char *status_code_value)
{
if (strcmp(status_code_value, LASSO_SAML2_STATUS_CODE_SUCCESS) != 0 &&
strcmp(status_code_value, LASSO_SAML2_STATUS_CODE_VERSION_MISMATCH) != 0 &&
strcmp(status_code_value, LASSO_SAML2_STATUS_CODE_REQUESTER) != 0) {
lasso_saml20_profile_set_response_status2(profile,
LASSO_SAML2_STATUS_CODE_RESPONDER, status_code_value);
} else {
lasso_saml20_profile_set_response_status2(profile, status_code_value, NULL);
}
}
int
lasso_saml20_profile_init_artifact_resolve(LassoProfile *profile,
const char *msg, LassoHttpMethod method)
@ -339,10 +326,10 @@ lasso_saml20_profile_build_artifact_response(LassoProfile *profile)
if (resp == NULL) {
lasso_saml20_profile_set_response_status(profile,
LASSO_SAML2_STATUS_CODE_REQUESTER);
LASSO_SAML2_STATUS_CODE_REQUESTER, NULL);
} else {
lasso_saml20_profile_set_response_status(profile,
LASSO_SAML2_STATUS_CODE_SUCCESS);
LASSO_SAML2_STATUS_CODE_SUCCESS, NULL);
}
lasso_assign_new_string(profile->msg_body, lasso_node_export_to_soap(profile->response));
return 0;
@ -847,7 +834,7 @@ cleanup:
}
int
lasso_saml20_profile_init_response(LassoProfile *profile, const char *status_code)
lasso_saml20_profile_init_response(LassoProfile *profile, const char *status_code1, const char *status_code2)
{
LassoSamlp2StatusResponse *status_response = NULL;
LassoSamlp2RequestAbstract *request_abstract = NULL;
@ -869,9 +856,9 @@ lasso_saml20_profile_init_response(LassoProfile *profile, const char *status_cod
server->parent.ProviderID)));
lasso_assign_new_string(status_response->IssueInstant, lasso_get_current_time());
lasso_assign_string(status_response->InResponseTo, request_abstract->ID);
if (status_code)
if (status_code1)
lasso_saml20_profile_set_response_status(profile,
status_code);
status_code1, status_code2);
cleanup:
return rc;
@ -908,11 +895,11 @@ lasso_saml20_profile_validate_request(LassoProfile *profile, gboolean needs_iden
/* init the response */
lasso_assign_gobject(profile->response, &status_response->parent);
lasso_saml20_profile_init_response(profile, LASSO_SAML2_STATUS_CODE_SUCCESS);
lasso_saml20_profile_init_response(profile, LASSO_SAML2_STATUS_CODE_SUCCESS, NULL);
if (profile->signature_status) {
message(G_LOG_LEVEL_WARNING, "Request signature is invalid");
lasso_saml20_profile_set_response_status2(profile,
lasso_saml20_profile_set_response_status(profile,
LASSO_SAML2_STATUS_CODE_REQUESTER,
LASSO_LIB_STATUS_CODE_INVALID_SIGNATURE);
return profile->signature_status;

View File

@ -40,7 +40,15 @@ int lasso_saml20_init_request(LassoProfile *profile, 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);
void lasso_saml20_profile_set_response_status(LassoProfile *profile, const char *status_code_value);
#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) \
lasso_saml20_profile_set_response_status(profile, LASSO_SAML2_STATUS_CODE_RESPONDER, code2)
#define lasso_saml20_profile_set_response_status_requester(profile, code2) \
lasso_saml20_profile_set_response_status(profile, LASSO_SAML2_STATUS_CODE_REQUESTER, code2)
int lasso_saml20_profile_set_response_status(LassoProfile *profile, const char *code1, const char
*code2);
int lasso_saml20_profile_init_artifact_resolve(LassoProfile *profile,
const char *msg, LassoHttpMethod method);
int lasso_saml20_profile_process_artifact_resolve(LassoProfile *profile, const char *msg);
@ -57,7 +65,8 @@ int lasso_saml20_profile_process_any_response(LassoProfile *profile, LassoSamlp2
int lasso_saml20_profile_setup_request_signing(LassoProfile *profile);
int lasso_saml20_profile_build_request_msg(LassoProfile *profile, char *service, gboolean no_signature);
int lasso_saml20_profile_build_response(LassoProfile *profile, char *service, gboolean no_signature, LassoHttpMethod method);
int lasso_saml20_profile_init_response(LassoProfile *profile, const char *status_code);
int lasso_saml20_profile_init_response(LassoProfile *profile, const char *status_code1,
const char *status_code2);
int lasso_saml20_profile_validate_request(LassoProfile *profile, gboolean needs_identity, LassoSamlp2StatusResponse *status_response, LassoProvider **provider_out);
gint lasso_saml20_build_http_redirect_query_simple(LassoProfile *profile, LassoNode *msg,
gboolean must_sign, const char *profile_name, gboolean is_response);