add delegation. From Daniel Kouril <kouril@ics.muni.cz> and Miroslav Ruda <ruda@ics.muni.cz>
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@8434 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -200,7 +200,9 @@ login (char *host)
|
|||||||
}
|
}
|
||||||
strlcpy(username, user, sizeof(username));
|
strlcpy(username, user, sizeof(username));
|
||||||
n = command("USER %s", user);
|
n = command("USER %s", user);
|
||||||
if (n == CONTINUE) {
|
if (n == COMPLETE)
|
||||||
|
n = command("PASS dummy"); /* DK: Compatibility with gssftp daemon */
|
||||||
|
else if(n == CONTINUE) {
|
||||||
if (pass == NULL) {
|
if (pass == NULL) {
|
||||||
char prompt[128];
|
char prompt[128];
|
||||||
if(myname &&
|
if(myname &&
|
||||||
|
@@ -101,6 +101,7 @@ extern int cpend; /* flag: if != 0, then pending server rep
|
|||||||
extern int mflag; /* flag: if != 0, then active multi command */
|
extern int mflag; /* flag: if != 0, then active multi command */
|
||||||
|
|
||||||
extern int options; /* used during socket creation */
|
extern int options; /* used during socket creation */
|
||||||
|
extern int use_kerberos; /* use Kerberos authentication */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Format of command table.
|
* Format of command table.
|
||||||
|
@@ -60,6 +60,7 @@ int cpend; /* flag: if != 0, then pending server reply */
|
|||||||
int mflag; /* flag: if != 0, then active multi command */
|
int mflag; /* flag: if != 0, then active multi command */
|
||||||
|
|
||||||
int options; /* used during socket creation */
|
int options; /* used during socket creation */
|
||||||
|
int use_kerberos; /* use Kerberos authentication */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Format of command table.
|
* Format of command table.
|
||||||
|
@@ -43,6 +43,7 @@ RCSID("$Id$");
|
|||||||
struct gss_data {
|
struct gss_data {
|
||||||
gss_ctx_id_t context_hdl;
|
gss_ctx_id_t context_hdl;
|
||||||
char *client_name;
|
char *client_name;
|
||||||
|
gss_cred_id_t delegated_cred_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -50,7 +51,17 @@ gss_init(void *app_data)
|
|||||||
{
|
{
|
||||||
struct gss_data *d = app_data;
|
struct gss_data *d = app_data;
|
||||||
d->context_hdl = GSS_C_NO_CONTEXT;
|
d->context_hdl = GSS_C_NO_CONTEXT;
|
||||||
|
d->delegated_cred_handle = NULL;
|
||||||
|
#if defined(FTP_SERVER)
|
||||||
return 0;
|
return 0;
|
||||||
|
#else
|
||||||
|
/* XXX Check the gss mechanism; with gss_indicate_mechs() ? */
|
||||||
|
#ifdef KRB5
|
||||||
|
return !use_kerberos;
|
||||||
|
#else
|
||||||
|
return 0
|
||||||
|
#endif /* KRB5 */
|
||||||
|
#endif /* FTP_SERVER */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -169,6 +180,15 @@ gss_adat(void *app_data, void *buf, size_t len)
|
|||||||
input_token.value = buf;
|
input_token.value = buf;
|
||||||
input_token.length = len;
|
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,
|
maj_stat = gss_accept_sec_context (&min_stat,
|
||||||
&d->context_hdl,
|
&d->context_hdl,
|
||||||
GSS_C_NO_CREDENTIAL,
|
GSS_C_NO_CREDENTIAL,
|
||||||
@@ -179,7 +199,7 @@ gss_adat(void *app_data, void *buf, size_t len)
|
|||||||
&output_token,
|
&output_token,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
&d->delegated_cred_handle);
|
||||||
|
|
||||||
if(output_token.length) {
|
if(output_token.length) {
|
||||||
if(base64_encode(output_token.value, output_token.length, &p) < 0) {
|
if(base64_encode(output_token.value, output_token.length, &p) < 0) {
|
||||||
@@ -304,7 +324,8 @@ gss_auth(void *app_data, char *host)
|
|||||||
&d->context_hdl,
|
&d->context_hdl,
|
||||||
target_name,
|
target_name,
|
||||||
GSS_C_NO_OID,
|
GSS_C_NO_OID,
|
||||||
GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG,
|
GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG
|
||||||
|
| GSS_C_DELEG_FLAG,
|
||||||
0,
|
0,
|
||||||
bindings,
|
bindings,
|
||||||
&input,
|
&input,
|
||||||
|
@@ -201,6 +201,12 @@ struct sec_server_mech krb4_server_mech = {
|
|||||||
|
|
||||||
#else /* FTP_SERVER */
|
#else /* FTP_SERVER */
|
||||||
|
|
||||||
|
static int
|
||||||
|
krb4_init(void *app_data)
|
||||||
|
{
|
||||||
|
return !use_kerberos;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mk_auth(struct krb4_data *d, KTEXT adat,
|
mk_auth(struct krb4_data *d, KTEXT adat,
|
||||||
char *service, char *host, int checksum)
|
char *service, char *host, int checksum)
|
||||||
@@ -322,7 +328,7 @@ krb4_auth(void *app_data, char *host)
|
|||||||
struct sec_client_mech krb4_client_mech = {
|
struct sec_client_mech krb4_client_mech = {
|
||||||
"KERBEROS_V4",
|
"KERBEROS_V4",
|
||||||
sizeof(struct krb4_data),
|
sizeof(struct krb4_data),
|
||||||
NULL, /* init */
|
krb4_init, /* init */
|
||||||
krb4_auth,
|
krb4_auth,
|
||||||
NULL, /* end */
|
NULL, /* end */
|
||||||
krb4_check_prot,
|
krb4_check_prot,
|
||||||
|
@@ -55,8 +55,9 @@ main(int argc, char **argv)
|
|||||||
interactive = 1;
|
interactive = 1;
|
||||||
autologin = 1;
|
autologin = 1;
|
||||||
passivemode = 0; /* passive mode not active */
|
passivemode = 0; /* passive mode not active */
|
||||||
|
use_kerberos = 1;
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "dginptv")) != -1) {
|
while ((ch = getopt(argc, argv, "dginptvK")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'd':
|
case 'd':
|
||||||
options |= SO_DEBUG;
|
options |= SO_DEBUG;
|
||||||
@@ -86,9 +87,14 @@ main(int argc, char **argv)
|
|||||||
verbose++;
|
verbose++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'K':
|
||||||
|
/* Disable Kerberos authentication */
|
||||||
|
use_kerberos = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage: ftp [-dginptv] [host [port]]\n");
|
"usage: ftp [-dginptvK] [host [port]]\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -148,6 +148,10 @@
|
|||||||
#include <kafs.h>
|
#include <kafs.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef KRB5
|
||||||
|
#include <krb5.h>
|
||||||
|
#endif /* KRB5 */
|
||||||
|
|
||||||
#ifdef OTP
|
#ifdef OTP
|
||||||
#include <otp.h>
|
#include <otp.h>
|
||||||
#endif
|
#endif
|
||||||
|
@@ -47,6 +47,7 @@ extern krb5_context gssapi_krb5_context;
|
|||||||
struct gss_data {
|
struct gss_data {
|
||||||
gss_ctx_id_t context_hdl;
|
gss_ctx_id_t context_hdl;
|
||||||
char *client_name;
|
char *client_name;
|
||||||
|
gss_cred_id_t delegated_cred_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
int gss_userok(void*, char*); /* to keep gcc happy */
|
int gss_userok(void*, char*); /* to keep gcc happy */
|
||||||
@@ -58,12 +59,58 @@ gss_userok(void *app_data, char *username)
|
|||||||
if(gssapi_krb5_context) {
|
if(gssapi_krb5_context) {
|
||||||
krb5_principal client;
|
krb5_principal client;
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
|
|
||||||
ret = krb5_parse_name(gssapi_krb5_context, data->client_name, &client);
|
ret = krb5_parse_name(gssapi_krb5_context, data->client_name, &client);
|
||||||
if(ret)
|
if(ret)
|
||||||
return 1;
|
return 1;
|
||||||
ret = krb5_kuserok(gssapi_krb5_context, client, username);
|
ret = krb5_kuserok(gssapi_krb5_context, client, username);
|
||||||
|
if (!ret) {
|
||||||
|
krb5_free_principal(gssapi_krb5_context, client);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
/* more of krb-depend stuff :-( */
|
||||||
|
/* gss_add_cred() ? */
|
||||||
|
if (data->delegated_cred_handle &&
|
||||||
|
data->delegated_cred_handle->ccache ) {
|
||||||
|
|
||||||
|
krb5_ccache ccache = NULL;
|
||||||
|
char* ticketfile;
|
||||||
|
struct passwd *pw;
|
||||||
|
|
||||||
|
pw = getpwnam(username);
|
||||||
|
|
||||||
|
asprintf (&ticketfile, "%s%u", KRB5_DEFAULT_CCROOT, pw->pw_uid);
|
||||||
|
|
||||||
|
ret = krb5_cc_resolve(gssapi_krb5_context, ticketfile, &ccache);
|
||||||
|
if (ret)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
ret = krb5_cc_copy_cache(gssapi_krb5_context,
|
||||||
|
data->delegated_cred_handle->ccache, ccache);
|
||||||
|
if (ret)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
chown (ticketfile+5, pw->pw_uid, pw->pw_gid);
|
||||||
|
|
||||||
|
if (k_hasafs()) {
|
||||||
|
krb5_afslog(gssapi_krb5_context, ccache, 0, 0);
|
||||||
|
}
|
||||||
|
setenv ("KRB5CCNAME", ticketfile, 1);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (ccache)
|
||||||
|
krb5_cc_close(gssapi_krb5_context, ccache);
|
||||||
|
krb5_cc_destroy(gssapi_krb5_context,
|
||||||
|
data->delegated_cred_handle->ccache);
|
||||||
|
data->delegated_cred_handle->ccache = NULL;
|
||||||
|
free(ticketfile);
|
||||||
|
}
|
||||||
|
|
||||||
krb5_free_principal(gssapi_krb5_context, client);
|
krb5_free_principal(gssapi_krb5_context, client);
|
||||||
return !ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user