From 32e004f92a3d25dcf1be584a5db19b73430b1d22 Mon Sep 17 00:00:00 2001 From: itojun Date: Mon, 9 Sep 2002 06:45:17 +0000 Subject: [PATCH] kerberos support w/ privsep. confirmed to work by lha@stacken.kth.se --- crypto/dist/ssh/auth-krb5.c | 20 ++++++--------- crypto/dist/ssh/auth.h | 4 +-- crypto/dist/ssh/auth1.c | 18 +++++++++++--- crypto/dist/ssh/monitor.c | 45 +++++++++++++++++++++++++++++++++- crypto/dist/ssh/monitor.h | 3 ++- crypto/dist/ssh/monitor_wrap.c | 37 +++++++++++++++++++++++++++- crypto/dist/ssh/monitor_wrap.h | 9 ++++++- 7 files changed, 115 insertions(+), 21 deletions(-) diff --git a/crypto/dist/ssh/auth-krb5.c b/crypto/dist/ssh/auth-krb5.c index 56e8cc6c97ae..b316c6fd1a19 100644 --- a/crypto/dist/ssh/auth-krb5.c +++ b/crypto/dist/ssh/auth-krb5.c @@ -1,4 +1,4 @@ -/* $NetBSD: auth-krb5.c,v 1.9 2002/04/22 07:59:36 itojun Exp $ */ +/* $NetBSD: auth-krb5.c,v 1.10 2002/09/09 06:45:17 itojun Exp $ */ /* * Kerberos v5 authentication and ticket-passing routines. * @@ -71,18 +71,17 @@ krb5_init(void *context) * from the ticket */ int -auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client) +auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *reply) { krb5_error_code problem; krb5_principal server; - krb5_data reply; krb5_ticket *ticket; int fd, ret; ret = 0; server = NULL; ticket = NULL; - reply.length = 0; + reply->length = 0; problem = krb5_init(authctxt); if (problem) @@ -116,7 +115,7 @@ auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client) /* if client wants mutual auth */ problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx, - &reply); + reply); if (problem) goto err; @@ -129,19 +128,16 @@ auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client) krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user, client); - packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE); - packet_put_string((char *) reply.data, reply.length); - packet_send(); - packet_write_wait(); - ret = 1; err: if (server) krb5_free_principal(authctxt->krb5_ctx, server); if (ticket) krb5_free_ticket(authctxt->krb5_ctx, ticket); - if (reply.length) - xfree(reply.data); + if (!ret && reply->length) { + xfree(reply->data); + memset(reply, 0, sizeof(*reply)); + } if (problem) { if (authctxt->krb5_ctx != NULL) diff --git a/crypto/dist/ssh/auth.h b/crypto/dist/ssh/auth.h index c4c9a2377627..f15caff6077c 100644 --- a/crypto/dist/ssh/auth.h +++ b/crypto/dist/ssh/auth.h @@ -1,4 +1,4 @@ -/* $NetBSD: auth.h,v 1.12 2002/06/24 05:48:27 itojun Exp $ */ +/* $NetBSD: auth.h,v 1.13 2002/09/09 06:45:17 itojun Exp $ */ /* $OpenBSD: auth.h,v 1.39 2002/05/31 11:35:15 markus Exp $ */ /* @@ -127,7 +127,7 @@ int auth_afs_token(Authctxt *, const char *); #endif /* KRB4 */ #ifdef KRB5 -int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client); +int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt); int auth_krb5_password(Authctxt *authctxt, const char *password); void krb5_cleanup_proc(void *authctxt); diff --git a/crypto/dist/ssh/auth1.c b/crypto/dist/ssh/auth1.c index e18b2fa0e9df..c5af1c7274d1 100644 --- a/crypto/dist/ssh/auth1.c +++ b/crypto/dist/ssh/auth1.c @@ -1,4 +1,4 @@ -/* $NetBSD: auth1.c,v 1.18 2002/06/24 05:48:27 itojun Exp $ */ +/* $NetBSD: auth1.c,v 1.19 2002/09/09 06:45:18 itojun Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -133,15 +133,27 @@ do_authloop(Authctxt *authctxt) #endif /* KRB4 */ } else { #ifdef KRB5 - krb5_data tkt; + krb5_data tkt, reply; tkt.length = dlen; tkt.data = kdata; - if (auth_krb5(authctxt, &tkt, &client_user)) { + if (PRIVSEP(auth_krb5(authctxt, &tkt, + &client_user, &reply))) { authenticated = 1; snprintf(info, sizeof(info), " tktuser %.100s", client_user); + + /* Send response to client */ + packet_start( + SSH_SMSG_AUTH_KERBEROS_RESPONSE); + packet_put_string((char *) + reply.data, reply.length); + packet_send(); + packet_write_wait(); + + if (reply.length) + xfree(reply.data); xfree(client_user); } #endif /* KRB5 */ diff --git a/crypto/dist/ssh/monitor.c b/crypto/dist/ssh/monitor.c index 0c3b9e849d10..f55df6f53af2 100644 --- a/crypto/dist/ssh/monitor.c +++ b/crypto/dist/ssh/monitor.c @@ -1,4 +1,4 @@ -/* $NetBSD: monitor.c,v 1.7 2002/07/01 06:17:12 itojun Exp $ */ +/* $NetBSD: monitor.c,v 1.8 2002/09/09 06:45:18 itojun Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -117,6 +117,10 @@ int mm_answer_rsa_response(int, Buffer *); int mm_answer_sesskey(int, Buffer *); int mm_answer_sessid(int, Buffer *); +#ifdef KRB5 +int mm_answer_krb5(int, Buffer *); +#endif + static Authctxt *authctxt; static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ @@ -189,6 +193,9 @@ struct mon_table mon_dispatch_proto15[] = { #ifdef SKEY {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, +#endif +#ifdef KRB5 + {MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5}, #endif {0, 0, NULL} }; @@ -1242,6 +1249,42 @@ mm_answer_rsa_response(int socket, Buffer *m) return (success); } + +#ifdef KRB5 +int +mm_answer_krb5(int socket, Buffer *m) +{ + krb5_data tkt, reply; + char *client_user; + u_int len; + int success; + + /* use temporary var to avoid size issues on 64bit arch */ + tkt.data = buffer_get_string(m, &len); + tkt.length = len; + + success = auth_krb5(authctxt, &tkt, &client_user, &reply); + + if (tkt.length) + xfree(tkt.data); + + buffer_clear(m); + buffer_put_int(m, success); + + if (success) { + buffer_put_cstring(m, client_user); + buffer_put_string(m, reply.data, reply.length); + if (client_user) + xfree(client_user); + if (reply.length) + xfree(reply.data); + } + mm_request_send(socket, MONITOR_ANS_KRB5, m); + + return success; +} +#endif + int mm_answer_term(int socket, Buffer *req) { diff --git a/crypto/dist/ssh/monitor.h b/crypto/dist/ssh/monitor.h index 32c5b0704744..eeeafefe1cb1 100644 --- a/crypto/dist/ssh/monitor.h +++ b/crypto/dist/ssh/monitor.h @@ -1,4 +1,4 @@ -/* $NetBSD: monitor.h,v 1.1.1.3 2002/06/24 05:26:11 itojun Exp $ */ +/* $NetBSD: monitor.h,v 1.2 2002/09/09 06:45:18 itojun Exp $ */ /* $OpenBSD: monitor.h,v 1.6 2002/06/11 05:46:20 mpech Exp $ */ /* @@ -50,6 +50,7 @@ enum monitor_reqtype { MONITOR_REQ_RSAKEYALLOWED, MONITOR_ANS_RSAKEYALLOWED, MONITOR_REQ_RSACHALLENGE, MONITOR_ANS_RSACHALLENGE, MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE, + MONITOR_REQ_KRB5, MONITOR_ANS_KRB5, MONITOR_REQ_TERM }; diff --git a/crypto/dist/ssh/monitor_wrap.c b/crypto/dist/ssh/monitor_wrap.c index d3e1f2aad88c..4c25f6d94bbc 100644 --- a/crypto/dist/ssh/monitor_wrap.c +++ b/crypto/dist/ssh/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $NetBSD: monitor_wrap.c,v 1.5 2002/07/01 06:17:12 itojun Exp $ */ +/* $NetBSD: monitor_wrap.c,v 1.6 2002/09/09 06:45:18 itojun Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -919,3 +919,38 @@ mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) return (success); } + +#ifdef KRB5 +int +mm_auth_krb5(void *ctx, void *argp, char **userp, void *resp) +{ + krb5_data *tkt, *reply; + Buffer m; + int success; + + debug3("%s entering", __func__); + tkt = (krb5_data *) argp; + reply = (krb5_data *) resp; + + buffer_init(&m); + buffer_put_string(&m, tkt->data, tkt->length); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB5, &m); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB5, &m); + + success = buffer_get_int(&m); + if (success) { + u_int len; + + *userp = buffer_get_string(&m, NULL); + reply->data = buffer_get_string(&m, &len); + reply->length = len; + } else { + memset(reply, 0, sizeof(*reply)); + *userp = NULL; + } + + buffer_free(&m); + return (success); +} +#endif diff --git a/crypto/dist/ssh/monitor_wrap.h b/crypto/dist/ssh/monitor_wrap.h index 80b9a2d8cedc..1754afee77f4 100644 --- a/crypto/dist/ssh/monitor_wrap.h +++ b/crypto/dist/ssh/monitor_wrap.h @@ -1,4 +1,4 @@ -/* $NetBSD: monitor_wrap.h,v 1.1.1.2 2002/05/13 02:28:42 itojun Exp $ */ +/* $NetBSD: monitor_wrap.h,v 1.2 2002/09/09 06:45:19 itojun Exp $ */ /* $OpenBSD: monitor_wrap.h,v 1.5 2002/05/12 23:53:45 djm Exp $ */ /* @@ -80,6 +80,13 @@ int mm_bsdauth_respond(void *, u_int, char **); int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_skey_respond(void *, u_int, char **); +/* auth_krb5 */ +#ifdef KRB5 +/* auth and reply are really krb5_data objects, but we don't want to + * include all of the krb5 headers here */ +int mm_auth_krb5(void *authctxt, void *auth, char **client, void *reply); +#endif + /* zlib allocation hooks */ void *mm_zalloc(struct mm_master *, u_int, u_int);