diff options
Diffstat (limited to 'crypto/heimdal/appl/ftp/ftp/gssapi.c')
-rw-r--r-- | crypto/heimdal/appl/ftp/ftp/gssapi.c | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/crypto/heimdal/appl/ftp/ftp/gssapi.c b/crypto/heimdal/appl/ftp/ftp/gssapi.c index 65742e84d543..9432feb8290e 100644 --- a/crypto/heimdal/appl/ftp/ftp/gssapi.c +++ b/crypto/heimdal/appl/ftp/ftp/gssapi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998 - 2003 Kungliga Tekniska Högskolan + * Copyright (c) 1998 - 2005 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,14 +39,16 @@ #include <gssapi.h> #include <krb5_err.h> -RCSID("$Id: gssapi.c,v 1.22.2.2 2003/08/20 16:41:24 lha Exp $"); +RCSID("$Id: gssapi.c 21513 2007-07-12 12:45:25Z lha $"); int ftp_do_gss_bindings = 0; +int ftp_do_gss_delegate = 1; struct gss_data { gss_ctx_id_t context_hdl; char *client_name; gss_cred_id_t delegated_cred_handle; + void *mech_data; }; static int @@ -54,7 +56,7 @@ gss_init(void *app_data) { struct gss_data *d = app_data; d->context_hdl = GSS_C_NO_CONTEXT; - d->delegated_cred_handle = NULL; + d->delegated_cred_handle = GSS_C_NO_CREDENTIAL; #if defined(FTP_SERVER) return 0; #else @@ -62,7 +64,7 @@ gss_init(void *app_data) #ifdef KRB5 return !use_kerberos; #else - return 0 + return 0; #endif /* KRB5 */ #endif /* FTP_SERVER */ } @@ -130,7 +132,7 @@ gss_encode(void *app_data, void *from, int length, int level, void **to) } static void -sockaddr_to_gss_address (const struct sockaddr *sa, +sockaddr_to_gss_address (struct sockaddr *sa, OM_uint32 *addr_type, gss_buffer_desc *gss_addr) { @@ -146,10 +148,10 @@ sockaddr_to_gss_address (const struct sockaddr *sa, } #endif case AF_INET : { - struct sockaddr_in *sin = (struct sockaddr_in *)sa; + struct sockaddr_in *sin4 = (struct sockaddr_in *)sa; gss_addr->length = 4; - gss_addr->value = &sin->sin_addr; + gss_addr->value = &sin4->sin_addr; *addr_type = GSS_C_AF_INET; break; } @@ -193,15 +195,6 @@ gss_adat(void *app_data, void *buf, size_t len) input_token.value = buf; input_token.length = len; - d->delegated_cred_handle = malloc(sizeof(*d->delegated_cred_handle)); - if (d->delegated_cred_handle == NULL) { - reply(500, "Out of memory"); - goto out; - } - - memset ((char*)d->delegated_cred_handle, 0, - sizeof(*d->delegated_cred_handle)); - maj_stat = gss_accept_sec_context (&min_stat, &d->context_hdl, GSS_C_NO_CREDENTIAL, @@ -222,6 +215,7 @@ gss_adat(void *app_data, void *buf, size_t len) reply(535, "Out of memory base64-encoding."); return -1; } + gss_release_buffer(&min_stat, &output_token); } if(maj_stat == GSS_S_COMPLETE){ char *name; @@ -277,11 +271,14 @@ gss_adat(void *app_data, void *buf, size_t len) reply(431, "Security resource unavailable"); } out: + if (client_name) + gss_release_name(&min_stat, &client_name); free(p); return 0; } int gss_userok(void*, char*); +int gss_session(void*, char*); struct sec_server_mech gss_server_mech = { "GSSAPI", @@ -297,7 +294,8 @@ struct sec_server_mech gss_server_mech = { gss_adat, NULL, /* pbsz */ NULL, /* ccc */ - gss_userok + gss_userok, + gss_session }; #else /* FTP_SERVER */ @@ -309,12 +307,14 @@ import_name(const char *kname, const char *host, gss_name_t *target_name) { OM_uint32 maj_stat, min_stat; gss_buffer_desc name; + char *str; - name.length = asprintf((char**)&name.value, "%s@%s", kname, host); - if (name.value == NULL) { + name.length = asprintf(&str, "%s@%s", kname, host); + if (str == NULL) { printf("Out of memory\n"); return AUTH_ERROR; } + name.value = str; maj_stat = gss_import_name(&min_stat, &name, @@ -334,6 +334,7 @@ import_name(const char *kname, const char *host, gss_name_t *target_name) printf("Error importing name %s: %s\n", (char *)name.value, (char *)status_string.value); + free(name.value); gss_release_buffer(&new_stat, &status_string); return AUTH_ERROR; } @@ -353,6 +354,7 @@ gss_auth(void *app_data, char *host) int n; gss_channel_bindings_t bindings; struct gss_data *d = app_data; + OM_uint32 mech_flags = GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG; const char *knames[] = { "ftp", "host", NULL }, **kname = knames; @@ -380,14 +382,16 @@ gss_auth(void *app_data, char *host) } else bindings = GSS_C_NO_CHANNEL_BINDINGS; + if (ftp_do_gss_delegate) + mech_flags |= GSS_C_DELEG_FLAG; + while(!context_established) { maj_stat = gss_init_sec_context(&min_stat, GSS_C_NO_CREDENTIAL, &d->context_hdl, target_name, GSS_C_NO_OID, - GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG - | GSS_C_DELEG_FLAG, + mech_flags, 0, bindings, &input, @@ -400,7 +404,12 @@ gss_auth(void *app_data, char *host) OM_uint32 msg_ctx = 0; gss_buffer_desc status_string; - if(min_stat == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN && *kname != NULL) { + d->context_hdl = GSS_C_NO_CONTEXT; + + gss_release_name(&min_stat, &target_name); + + if(*kname != NULL) { + if(import_name(*kname++, host, &target_name)) { if (bindings != GSS_C_NO_CHANNEL_BINDINGS) free(bindings); @@ -466,6 +475,8 @@ gss_auth(void *app_data, char *host) } } + gss_release_name(&min_stat, &target_name); + if (bindings != GSS_C_NO_CHANNEL_BINDINGS) free(bindings); if (input.value) |