From 84f5aebc101907f9952430fcbaebd60b830195fc Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Sun, 20 Mar 2011 20:50:19 +1100 Subject: [PATCH] use gss_userok --- appl/ftp/ftp/gssapi.c | 54 +++++------------ appl/ftp/ftpd/gss_userok.c | 118 +++++++------------------------------ 2 files changed, 37 insertions(+), 135 deletions(-) diff --git a/appl/ftp/ftp/gssapi.c b/appl/ftp/ftp/gssapi.c index 4d1669d8e..6b1378449 100644 --- a/appl/ftp/ftp/gssapi.c +++ b/appl/ftp/ftp/gssapi.c @@ -45,9 +45,9 @@ RCSID("$Id$"); int ftp_do_gss_bindings = 0; int ftp_do_gss_delegate = 1; -struct gss_data { +struct gssapi_data { gss_ctx_id_t context_hdl; - char *client_name; + gss_name_t client_name; gss_cred_id_t delegated_cred_handle; void *mech_data; }; @@ -55,7 +55,7 @@ struct gss_data { static int gss_init(void *app_data) { - struct gss_data *d = app_data; + struct gssapi_data *d = app_data; d->context_hdl = GSS_C_NO_CONTEXT; d->delegated_cred_handle = GSS_C_NO_CREDENTIAL; #if defined(FTP_SERVER) @@ -85,7 +85,7 @@ gss_decode(void *app_data, void *buf, int len, int level) gss_buffer_desc input, output; gss_qop_t qop_state; int conf_state; - struct gss_data *d = app_data; + struct gssapi_data *d = app_data; size_t ret_len; input.length = len; @@ -117,7 +117,7 @@ gss_encode(void *app_data, void *from, int length, int level, void **to) OM_uint32 maj_stat, min_stat; gss_buffer_desc input, output; int conf_state; - struct gss_data *d = app_data; + struct gssapi_data *d = app_data; input.length = length; input.value = from; @@ -173,7 +173,7 @@ gss_adat(void *app_data, void *buf, size_t len) gss_buffer_desc input_token, output_token; OM_uint32 maj_stat, min_stat; gss_name_t client_name; - struct gss_data *d = app_data; + struct gssapi_data *d = app_data; gss_channel_bindings_t bindings; if (ftp_do_gss_bindings) { @@ -219,32 +219,8 @@ gss_adat(void *app_data, void *buf, size_t len) gss_release_buffer(&min_stat, &output_token); } if(maj_stat == GSS_S_COMPLETE){ - char *name; - gss_buffer_desc export_name; - gss_OID oid; - - maj_stat = gss_display_name(&min_stat, client_name, - &export_name, &oid); - if(maj_stat != 0) { - reply(500, "Error displaying name"); - goto out; - } - /* XXX kerberos */ - if(oid != GSS_KRB5_NT_PRINCIPAL_NAME) { - reply(500, "OID not kerberos principal name"); - gss_release_buffer(&min_stat, &export_name); - goto out; - } - name = malloc(export_name.length + 1); - if(name == NULL) { - reply(500, "Out of memory"); - gss_release_buffer(&min_stat, &export_name); - goto out; - } - memcpy(name, export_name.value, export_name.length); - name[export_name.length] = '\0'; - gss_release_buffer(&min_stat, &export_name); - d->client_name = name; + d->client_name = client_name; + client_name = GSS_C_NO_NAME; if(p) reply(235, "ADAT=%s", p); else @@ -279,12 +255,12 @@ gss_adat(void *app_data, void *buf, size_t len) return 0; } -int gss_userok(void*, char*); -int gss_session(void*, char*); +int gssapi_userok(void*, char*); +int gssapi_session(void*, char*); struct sec_server_mech gss_server_mech = { "GSSAPI", - sizeof(struct gss_data), + sizeof(struct gssapi_data), gss_init, /* init */ NULL, /* end */ gss_check_prot, @@ -296,8 +272,8 @@ struct sec_server_mech gss_server_mech = { gss_adat, NULL, /* pbsz */ NULL, /* ccc */ - gss_userok, - gss_session + gssapi_userok, + gssapi_session }; #else /* FTP_SERVER */ @@ -357,7 +333,7 @@ gss_auth(void *app_data, char *host) char *p; int n; gss_channel_bindings_t bindings; - struct gss_data *d = app_data; + struct gssapi_data *d = app_data; OM_uint32 mech_flags = GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG; const char *knames[] = { "ftp", "host", NULL }, **kname = knames; @@ -522,7 +498,7 @@ gss_auth(void *app_data, char *host) struct sec_client_mech gss_client_mech = { "GSSAPI", - sizeof(struct gss_data), + sizeof(struct gssapi_data), gss_init, gss_auth, NULL, /* end */ diff --git a/appl/ftp/ftpd/gss_userok.c b/appl/ftp/ftpd/gss_userok.c index d65c581a9..6d6267d75 100644 --- a/appl/ftp/ftpd/gss_userok.c +++ b/appl/ftp/ftpd/gss_userok.c @@ -33,122 +33,48 @@ #include "ftpd_locl.h" #include -#include -#include - -/* XXX a bit too much of krb5 dependency here... - What is the correct way to do this? - */ - -struct gss_krb5_data { - krb5_context context; -}; /* XXX sync with gssapi.c */ -struct gss_data { +struct gssapi_data { gss_ctx_id_t context_hdl; - char *client_name; + gss_name_t client_name; gss_cred_id_t delegated_cred_handle; void *mech_data; }; -int gss_userok(void*, char*); /* to keep gcc happy */ -int gss_session(void*, char*); /* to keep gcc happy */ +int gssapi_userok(void*, char*); /* to keep gcc happy */ +int gssapi_session(void*, char*); /* to keep gcc happy */ int -gss_userok(void *app_data, char *username) +gssapi_userok(void *app_data, char *username) { - struct gss_data *data = app_data; - krb5_error_code ret; - krb5_principal client; - struct gss_krb5_data *kdata; + struct gssapi_data *data = app_data; + OM_uint32 major, minor; + int userok; - kdata = calloc(1, sizeof(struct gss_krb5_data)); - if (kdata == NULL) - return 1; - data->mech_data = kdata; + major = gss_userok(&minor, data->client_name, username, &userok); + if (GSS_ERROR(major) || !userok) + return 1; - ret = krb5_init_context(&(kdata->context)); - if (ret) { - free(kdata); - return 1; - } - - ret = krb5_parse_name(kdata->context, data->client_name, &client); - if(ret) { - krb5_free_context(kdata->context); - free(kdata); - return 1; - } - ret = krb5_kuserok(kdata->context, client, username); - if (!ret) { - krb5_free_principal(kdata->context, client); - krb5_free_context(kdata->context); - free(kdata); - return 1; - } - - ret = 0; - krb5_free_principal(kdata->context, client); - return ret; + return 0; } int -gss_session(void *app_data, char *username) +gssapi_session(void *app_data, char *username) { - struct gss_data *data = app_data; - krb5_error_code ret; - OM_uint32 minor_status; - struct gss_krb5_data *kdata; + struct gssapi_data *data = app_data; + OM_uint32 major, minor; + int ret = 0; - ret = 0; - - kdata = (struct gss_krb5_data *)(data->mech_data); - - /* more of krb-depend stuff :-( */ - /* gss_add_cred() ? */ if (data->delegated_cred_handle != GSS_C_NO_CREDENTIAL) { - krb5_ccache ccache = NULL; - const char* ticketfile; - struct passwd *kpw; - - ret = krb5_cc_new_unique(kdata->context, NULL, NULL, &ccache); - if (ret) - goto fail; - - ticketfile = krb5_cc_get_name(kdata->context, ccache); - - ret = gss_krb5_copy_ccache(&minor_status, - data->delegated_cred_handle, - ccache); - if (ret) { - ret = 0; - goto fail; - } - - do_destroy_tickets = 1; - - kpw = getpwnam(username); - - if (kpw == NULL) { - unlink(ticketfile); - ret = 1; - goto fail; - } - - chown (ticketfile, kpw->pw_uid, kpw->pw_gid); - - if (asprintf(&k5ccname, "FILE:%s", ticketfile) != -1) { - esetenv ("KRB5CCNAME", k5ccname, 1); - } + major = gss_store_cred(&minor, data->delegated_cred_handle, + GSS_C_INITIATE, GSS_C_NO_OID, + 1, 1, NULL, NULL); + if (GSS_ERROR(major)) + ret = 1; afslog(NULL, 1); - fail: - if (ccache) - krb5_cc_close(kdata->context, ccache); } - gss_release_cred(&minor_status, &data->delegated_cred_handle); - krb5_free_context(kdata->context); - free(kdata); + gss_release_cred(&minor, &data->delegated_cred_handle); return ret; }