aboutsummaryrefslogtreecommitdiff
path: root/src/gssapi.c
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2013-11-15 18:07:49 -0500
committerSimo Sorce <simo@redhat.com>2013-11-15 23:32:20 -0500
commit66e7e7023b6f1568b65ccd8e04ca4dce24847058 (patch)
tree126b61bf75120351add326db842d295e977f8ae8 /src/gssapi.c
parentb4fc5d952439f672737e1e6bcf8a703a72aa9bcf (diff)
downloadlibssh-66e7e7023b6f1568b65ccd8e04ca4dce24847058.tar.gz
libssh-66e7e7023b6f1568b65ccd8e04ca4dce24847058.tar.xz
libssh-66e7e7023b6f1568b65ccd8e04ca4dce24847058.zip
gssapi: Fix support of delegated credentials
In a previous refactoring patch, the code underpinning the ssh_gssapi_set_creds() API was inadvertently removed. This patch fixes the problem. Also clarify what variable holds which credentials and insure that credentials created within the library are propelry freed. Signed-off-by: Simo Sorce <simo@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Diffstat (limited to 'src/gssapi.c')
-rw-r--r--src/gssapi.c60
1 files changed, 37 insertions, 23 deletions
diff --git a/src/gssapi.c b/src/gssapi.c
index e2bcce34..c0aaef54 100644
--- a/src/gssapi.c
+++ b/src/gssapi.c
@@ -49,7 +49,7 @@ struct ssh_gssapi_struct{
enum ssh_gssapi_state_e state; /* current state */
struct gss_OID_desc_struct mech; /* mechanism being elected for auth */
gss_cred_id_t server_creds; /* credentials of server */
- gss_cred_id_t client_creds; /* creds of the client */
+ gss_cred_id_t client_creds; /* creds delegated by the client */
gss_ctx_id_t ctx; /* the authentication context */
gss_name_t client_name; /* Identity of the client */
char *user; /* username of client */
@@ -59,6 +59,7 @@ struct ssh_gssapi_struct{
gss_name_t server_name; /* identity of server */
OM_uint32 flags; /* flags used for init context */
gss_OID oid; /* mech being used for authentication */
+ gss_cred_id_t creds; /* creds used to initialize context */
gss_cred_id_t client_deleg_creds; /* delegated creds (const, not freeable) */
} client;
};
@@ -90,12 +91,13 @@ static void ssh_gssapi_free(ssh_session session){
OM_uint32 min;
if (session->gssapi == NULL)
return;
- if (session->gssapi->mech.elements)
- SAFE_FREE(session->gssapi->mech.elements);
- if (session->gssapi->user)
- SAFE_FREE(session->gssapi->user);
- if (session->gssapi->server_creds)
- gss_release_cred(&min,&session->gssapi->server_creds);
+ SAFE_FREE(session->gssapi->user);
+ SAFE_FREE(session->gssapi->mech.elements);
+ gss_release_cred(&min,&session->gssapi->server_creds);
+ if (session->gssapi->client.creds !=
+ session->gssapi->client.client_deleg_creds) {
+ gss_release_cred(&min, &session->gssapi->client.creds);
+ }
SAFE_FREE(session->gssapi);
}
@@ -630,25 +632,37 @@ static int ssh_gssapi_match(ssh_session session, gss_OID_set *valid_oids)
char *ptr;
int ret;
- if (session->opts.gss_client_identity != NULL) {
- namebuf.value = (void *)session->opts.gss_client_identity;
- namebuf.length = strlen(session->opts.gss_client_identity);
+ if (session->gssapi->client.client_deleg_creds == NULL) {
+ if (session->opts.gss_client_identity != NULL) {
+ namebuf.value = (void *)session->opts.gss_client_identity;
+ namebuf.length = strlen(session->opts.gss_client_identity);
- maj_stat = gss_import_name(&min_stat, &namebuf,
- GSS_C_NT_USER_NAME, &client_id);
+ maj_stat = gss_import_name(&min_stat, &namebuf,
+ GSS_C_NT_USER_NAME, &client_id);
+ if (GSS_ERROR(maj_stat)) {
+ ret = SSH_ERROR;
+ goto end;
+ }
+ }
+
+ maj_stat = gss_acquire_cred(&min_stat, client_id, GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET, GSS_C_INITIATE,
+ &session->gssapi->client.creds,
+ &actual_mechs, NULL);
if (GSS_ERROR(maj_stat)) {
ret = SSH_ERROR;
goto end;
}
- }
+ } else {
+ session->gssapi->client.creds =
+ session->gssapi->client.client_deleg_creds;
- maj_stat = gss_acquire_cred(&min_stat, client_id, GSS_C_INDEFINITE,
- GSS_C_NO_OID_SET, GSS_C_INITIATE,
- &session->gssapi->client_creds,
- &actual_mechs, NULL);
- if (GSS_ERROR(maj_stat)) {
- ret = SSH_ERROR;
- goto end;
+ maj_stat = gss_inquire_cred(&min_stat, session->gssapi->client.creds,
+ &client_id, NULL, NULL, &actual_mechs);
+ if (GSS_ERROR(maj_stat)) {
+ ret = SSH_ERROR;
+ goto end;
+ }
}
gss_create_empty_oid_set(&min_stat, valid_oids);
@@ -659,7 +673,7 @@ static int ssh_gssapi_match(ssh_session session, gss_OID_set *valid_oids)
lifetime = 0;
oid = &actual_mechs->elements[i];
maj_stat = gss_inquire_cred_by_mech(&min_stat,
- session->gssapi->client_creds,
+ session->gssapi->client.creds,
oid, NULL, &lifetime, NULL, NULL);
if (maj_stat == GSS_S_COMPLETE && lifetime > 0) {
gss_add_oid_set_member(&min_stat, oid, valid_oids);
@@ -811,7 +825,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){
/* prepare the first TOKEN response */
maj_stat = gss_init_sec_context(&min_stat,
- session->gssapi->client_creds,
+ session->gssapi->client.creds,
&session->gssapi->ctx,
session->gssapi->client.server_name,
session->gssapi->client.oid,
@@ -910,7 +924,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){
input_token.length = ssh_string_len(token);
input_token.value = ssh_string_data(token);
maj_stat = gss_init_sec_context(&min_stat,
- session->gssapi->client_creds,
+ session->gssapi->client.creds,
&session->gssapi->ctx,
session->gssapi->client.server_name,
session->gssapi->client.oid,