diff options
author | cvs2svn <cvs2svn@FreeBSD.org> | 2000-12-05 02:55:13 +0000 |
---|---|---|
committer | cvs2svn <cvs2svn@FreeBSD.org> | 2000-12-05 02:55:13 +0000 |
commit | 5bcde1229c897d3a1ecba9ae48d888c773877ad9 (patch) | |
tree | 77a3cf9e728cff5023d829ebe45a5d6e6b2a0d75 /crypto/openssh/auth-krb5.c | |
parent | 2aecee364f2b1fa8b38c4d29600f05f33075cddf (diff) | |
download | FreeBSD-src-5bcde1229c897d3a1ecba9ae48d888c773877ad9.zip FreeBSD-src-5bcde1229c897d3a1ecba9ae48d888c773877ad9.tar.gz |
This commit was manufactured by cvs2svn to create branch
'VENDOR-crypto-openssh'.
Diffstat (limited to 'crypto/openssh/auth-krb5.c')
-rw-r--r-- | crypto/openssh/auth-krb5.c | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/crypto/openssh/auth-krb5.c b/crypto/openssh/auth-krb5.c new file mode 100644 index 0000000..6030d9a --- /dev/null +++ b/crypto/openssh/auth-krb5.c @@ -0,0 +1,249 @@ +/* + * Kerberos v5 authentication and ticket-passing routines. + * + * $FreeBSD$ + */ + +#include "includes.h" +#include "ssh.h" +#include "packet.h" +#include "xmalloc.h" + +#ifdef KRB5 + +extern krb5_context ssh_context; +krb5_auth_context auth_context; +krb5_ccache mem_ccache = NULL; /* Credential cache for acquired ticket */ + +/* Try krb5 authentication. server_user is passed for logging purposes only, + in auth is received ticket, in client is returned principal from the + ticket */ +int +auth_krb5(const char* server_user, krb5_data *auth, krb5_principal *client) +{ + krb5_error_code problem; + krb5_principal server = NULL; + krb5_principal tkt_client = NULL; + krb5_data reply; + krb5_ticket *ticket = NULL; + int fd; + int ret; + + reply.length = 0; + + problem = krb5_init(); + if (problem) + return 0; + + problem = krb5_auth_con_init(ssh_context, &auth_context); + if (problem) { + log("Kerberos v5 authentication failed: %.100s", + krb5_get_err_text(ssh_context, problem)); + + return 0; + } + + fd = packet_get_connection_in(); + problem = krb5_auth_con_setaddrs_from_fd(ssh_context, auth_context, &fd); + if (problem) { + ret = 0; + goto err; + } + + problem = krb5_sname_to_principal(ssh_context, NULL, NULL , + KRB5_NT_SRV_HST, &server); + if (problem) { + ret = 0; + goto err; + } + + problem = krb5_rd_req(ssh_context, &auth_context, auth, server, NULL, + NULL, &ticket); + if (problem) { + ret = 0; + goto err; + } + + problem = krb5_copy_principal(ssh_context, ticket->client, &tkt_client); + if (problem) { + ret = 0; + goto err; + } + + /* if client wants mutual auth */ + problem = krb5_mk_rep(ssh_context, &auth_context, &reply); + if (problem) { + ret = 0; + goto err; + } + + *client = tkt_client; + + packet_start(SSH_SMSG_AUTH_KRB5_RESPONSE); + packet_put_string((char *) reply.data, reply.length); + packet_send(); + packet_write_wait(); + ret = 1; + +err: + if (server) + krb5_free_principal(ssh_context, server); + if (ticket) + krb5_free_ticket(ssh_context, ticket); + if (reply.length) + xfree(reply.data); + return ret; +} + +int +auth_krb5_tgt(char *server_user, krb5_data *tgt, krb5_principal tkt_client) +{ + krb5_error_code problem; + krb5_ccache ccache = NULL; + + if (ssh_context == NULL) { + goto fail; + } + + problem = krb5_cc_gen_new(ssh_context, &krb5_mcc_ops, &ccache); + if (problem) { + goto fail; + } + + problem = krb5_cc_initialize(ssh_context, ccache, tkt_client); + if (problem) { + goto fail; + } + + problem = krb5_rd_cred(ssh_context, auth_context, ccache, tgt); + if (problem) { + goto fail; + } + + mem_ccache = ccache; + ccache = NULL; + + /* + problem = krb5_cc_copy_cache(ssh_context, ccache, mem_ccache); + if (problem) { + mem_ccache = NULL; + goto fail; + } + + + problem = krb5_cc_destroy(ssh_context, ccache); + if (problem) + goto fail; + */ + +#if 0 + packet_start(SSH_SMSG_SUCCESS); + packet_send(); + packet_write_wait(); +#endif + return 1; + +fail: + if (ccache) + krb5_cc_destroy(ssh_context, ccache); +#if 0 + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); +#endif + return 0; +} + +int +auth_krb5_password(struct passwd *pw, const char *password) +{ + krb5_error_code problem; + krb5_ccache ccache = NULL; + krb5_principal client = NULL; + int ret; + + problem = krb5_init(); + if (problem) + return 0; + + problem = krb5_parse_name(ssh_context, pw->pw_name, &client); + if (problem) { + ret = 0; + goto out; + } + + problem = krb5_cc_gen_new(ssh_context, &krb5_mcc_ops, &ccache); + if (problem) { + ret = 0; + goto out; + } + + problem = krb5_cc_initialize(ssh_context, ccache, client); + if (problem) { + ret = 0; + goto out; + } + + problem = krb5_verify_user(ssh_context, client, ccache, password, 1, NULL); + if (problem) { + ret = 0; + goto out; + } + +/* + problem = krb5_cc_copy_cache(ssh_context, ccache, mem_ccache); + if (problem) { + ret = 0; + mem_ccache = NULL; + goto out; + } + */ + mem_ccache = ccache; + ccache = NULL; + + ret = 1; +out: + if (client != NULL) + krb5_free_principal(ssh_context, client); + if (ccache != NULL) + krb5_cc_destroy(ssh_context, ccache); + return ret; +} + +void +krb5_cleanup_proc(void *ignore) +{ + extern krb5_principal tkt_client; + + debug("krb5_cleanup_proc() called"); + if (mem_ccache) + krb5_cc_destroy(ssh_context, mem_ccache); + if (tkt_client) + krb5_free_principal(ssh_context, tkt_client); + if (auth_context) + krb5_auth_con_free(ssh_context, auth_context); + if (ssh_context) + krb5_free_context(ssh_context); +} + +int +krb5_init(void) +{ + krb5_error_code problem; + static cleanup_registered = 0; + + if (ssh_context == NULL) { + problem = krb5_init_context(&ssh_context); + if (problem) + return problem; + krb5_init_ets(ssh_context); + } + + if (!cleanup_registered) { + fatal_add_cleanup(krb4_cleanup_proc, NULL); + cleanup_registered = 1; + } + return 0; +} + +#endif /* KRB5 */ |