From 8b36c0387032bdd63676c1c273c7122085d70e86 Mon Sep 17 00:00:00 2001 From: Sam Hartman Date: Tue, 19 Nov 2013 12:04:24 -0500 Subject: [PATCH] temporary: gsscon_passive_authenticate: acquire trustidentity creds. As discussin in LP: #1203159, the client always uses trustidentity as a name. We're running into problems because the server uses GSS_C_NO_CREDENTIAL. That means no service name is included in RADIUS and unless there's proxy magic, then channel bindings fails. For now, also acquire trustidentity credentials on the server. This still leaves the security issue discussed by that bug, but at least the code works. --- gsscon/gsscon_passive.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/gsscon/gsscon_passive.c b/gsscon/gsscon_passive.c index 87506fc..907153c 100755 --- a/gsscon/gsscon_passive.c +++ b/gsscon/gsscon_passive.c @@ -65,17 +65,38 @@ int gsscon_passive_authenticate (int inSocket, OM_uint32 majorStatus; OM_uint32 minorStatus = 0; gss_ctx_id_t gssContext = GSS_C_NO_CONTEXT; - gss_name_t clientName = GSS_C_NO_NAME; + gss_name_t clientName = GSS_C_NO_NAME, serviceName = GSS_C_NO_NAME; + gss_cred_id_t acceptorCredentials = NULL; gss_buffer_desc clientDisplayName = {0, NULL}; + gss_buffer_desc nameBuffer = {0, "trustidentity"}; char *inputTokenBuffer = NULL; size_t inputTokenBufferLength = 0; gss_buffer_desc inputToken; /* buffer received from the server */ + nameBuffer.length = strlen(nameBuffer.value); if (inSocket < 0 ) { err = EINVAL; } if (!outGSSContext) { err = EINVAL; } - + + if (!err) + majorStatus = gss_import_name (&minorStatus, &nameBuffer, (gss_OID) GSS_KRB5_NT_PRINCIPAL_NAME, &serviceName); + if (majorStatus != GSS_S_COMPLETE) { + gsscon_print_gss_errors ("gss_import_name(inServiceName)", majorStatus, minorStatus); + err = minorStatus ? minorStatus : majorStatus; + } + + if (!err) { + majorStatus = gss_acquire_cred ( &minorStatus, serviceName, + GSS_C_INDEFINITE, GSS_C_NO_OID_SET, + GSS_C_ACCEPT, &acceptorCredentials, + NULL /*mechs out*/, NULL /*time out*/); + if (majorStatus != GSS_S_COMPLETE) { + gsscon_print_gss_errors ("gss_acquire_cred", majorStatus, minorStatus); + err = minorStatus ? minorStatus : majorStatus; + } + } + /* * The main authentication loop: * @@ -111,13 +132,10 @@ int gsscon_passive_authenticate (int inSocket, /* * accept_sec_context does the actual work of taking the client's - * request and generating an appropriate reply. Note that we pass - * GSS_C_NO_CREDENTIAL for the service principal. - */ - // printf ("Calling gss_accept_sec_context...\n"); + * request and generating an appropriate reply. */ majorStatus = gss_accept_sec_context (&minorStatus, &gssContext, - GSS_C_NO_CREDENTIAL, + acceptorCredentials, &inputToken, GSS_C_NO_CHANNEL_BINDINGS, &clientName, @@ -166,6 +184,8 @@ if (clientName != GSS_C_NO_NAME) gss_release_name(&minorStatus, &clientName); if (clientDisplayName.value != NULL) gss_release_buffer(&minorStatus, &clientDisplayName); + gss_release_name( &minorStatus, &serviceName); + gss_release_cred( &minorStatus, &acceptorCredentials); return err; } -- 2.1.4