Annotation of src/usr.bin/ssh/auth-krb5.c, Revision 1.1
1.1 ! dugsong 1: /*
! 2: * Kerberos v5 authentication and ticket-passing routines.
! 3: *
! 4: * $FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar Exp $
! 5: * $OpenBSD$
! 6: */
! 7:
! 8: #include "includes.h"
! 9: #include "ssh.h"
! 10: #include "ssh1.h"
! 11: #include "packet.h"
! 12: #include "xmalloc.h"
! 13: #include "log.h"
! 14: #include "servconf.h"
! 15: #include "uidswap.h"
! 16: #include "auth.h"
! 17:
! 18: #ifdef KRB5
! 19: #include <krb5.h>
! 20:
! 21: extern ServerOptions options;
! 22:
! 23: static int
! 24: krb5_init(void *context)
! 25: {
! 26: Authctxt *authctxt = (Authctxt *)context;
! 27: krb5_error_code problem;
! 28: static int cleanup_registered = 0;
! 29:
! 30: if (authctxt->krb5_ctx == NULL) {
! 31: problem = krb5_init_context(&authctxt->krb5_ctx);
! 32: if (problem)
! 33: return (problem);
! 34: krb5_init_ets(authctxt->krb5_ctx);
! 35: }
! 36: if (!cleanup_registered) {
! 37: fatal_add_cleanup(krb5_cleanup_proc, authctxt);
! 38: cleanup_registered = 1;
! 39: }
! 40: return (0);
! 41: }
! 42:
! 43: /*
! 44: * Try krb5 authentication. server_user is passed for logging purposes
! 45: * only, in auth is received ticket, in client is returned principal
! 46: * from the ticket
! 47: */
! 48: int
! 49: auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client)
! 50: {
! 51: krb5_error_code problem;
! 52: krb5_principal server;
! 53: krb5_data reply;
! 54: krb5_ticket *ticket;
! 55: int fd;
! 56:
! 57: server = NULL;
! 58: ticket = NULL;
! 59: reply.length = 0;
! 60:
! 61: problem = krb5_init(authctxt);
! 62: if (problem)
! 63: goto err;
! 64:
! 65: problem = krb5_auth_con_init(authctxt->krb5_ctx,
! 66: &authctxt->krb5_auth_ctx);
! 67: if (problem)
! 68: goto err;
! 69:
! 70: fd = packet_get_connection_in();
! 71: problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx,
! 72: authctxt->krb5_auth_ctx, &fd);
! 73: if (problem)
! 74: goto err;
! 75:
! 76: problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL ,
! 77: KRB5_NT_SRV_HST, &server);
! 78: if (problem)
! 79: goto err;
! 80:
! 81: problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx,
! 82: auth, server, NULL, NULL, &ticket);
! 83: if (problem)
! 84: goto err;
! 85:
! 86: problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client,
! 87: &authctxt->krb5_user);
! 88: if (problem)
! 89: goto err;
! 90:
! 91: /* if client wants mutual auth */
! 92: problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
! 93: &reply);
! 94: if (problem)
! 95: goto err;
! 96:
! 97: /* Check .k5login authorization now. */
! 98: if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
! 99: authctxt->pw->pw_name))
! 100: goto err;
! 101:
! 102: if (client)
! 103: krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
! 104: client);
! 105:
! 106: packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE);
! 107: packet_put_string((char *) reply.data, reply.length);
! 108: packet_send();
! 109: packet_write_wait();
! 110:
! 111: err:
! 112: if (server)
! 113: krb5_free_principal(authctxt->krb5_ctx, server);
! 114: if (ticket)
! 115: krb5_free_ticket(authctxt->krb5_ctx, ticket);
! 116: if (reply.length)
! 117: xfree(reply.data);
! 118:
! 119: if (problem) {
! 120: debug("Kerberos v5 authentication failed: %s",
! 121: krb5_get_err_text(authctxt->krb5_ctx, problem));
! 122: return (0);
! 123: }
! 124: return (1);
! 125: }
! 126:
! 127: int
! 128: auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt)
! 129: {
! 130: krb5_error_code problem;
! 131: krb5_ccache ccache = NULL;
! 132: char *pname;
! 133:
! 134: if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
! 135: return (0);
! 136:
! 137: temporarily_use_uid(authctxt->pw);
! 138:
! 139: problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
! 140: if (problem)
! 141: goto fail;
! 142:
! 143: problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
! 144: authctxt->krb5_user);
! 145: if (problem)
! 146: goto fail;
! 147:
! 148: problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
! 149: ccache, tgt);
! 150: if (problem)
! 151: goto fail;
! 152:
! 153: authctxt->krb5_fwd_ccache = ccache;
! 154: ccache = NULL;
! 155:
! 156: authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
! 157:
! 158: problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
! 159: &pname);
! 160: if (problem)
! 161: goto fail;
! 162:
! 163: debug("Kerberos v5 TGT accepted (%s)", pname);
! 164:
! 165: restore_uid();
! 166:
! 167: return (1);
! 168:
! 169: fail:
! 170: if (problem)
! 171: debug("Kerberos v5 TGT passing failed: %s",
! 172: krb5_get_err_text(authctxt->krb5_ctx, problem));
! 173: if (ccache)
! 174: krb5_cc_destroy(authctxt->krb5_ctx, ccache);
! 175:
! 176: restore_uid();
! 177:
! 178: return (0);
! 179: }
! 180:
! 181: int
! 182: auth_krb5_password(Authctxt *authctxt, const char *password)
! 183: {
! 184: krb5_error_code problem;
! 185:
! 186: if (authctxt->pw == NULL)
! 187: return (0);
! 188:
! 189: temporarily_use_uid(authctxt->pw);
! 190:
! 191: problem = krb5_init(authctxt);
! 192: if (problem)
! 193: goto out;
! 194:
! 195: problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
! 196: &authctxt->krb5_user);
! 197: if (problem)
! 198: goto out;
! 199:
! 200: problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
! 201: &authctxt->krb5_fwd_ccache);
! 202: if (problem)
! 203: goto out;
! 204:
! 205: problem = krb5_cc_initialize(authctxt->krb5_ctx,
! 206: authctxt->krb5_fwd_ccache, authctxt->krb5_user);
! 207: if (problem)
! 208: goto out;
! 209:
! 210: problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
! 211: authctxt->krb5_fwd_ccache, password, 1, NULL);
! 212: if (problem)
! 213: goto out;
! 214:
! 215: authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
! 216:
! 217: out:
! 218: restore_uid();
! 219:
! 220: if (problem) {
! 221: debug("Kerberos password authentication failed: %s",
! 222: krb5_get_err_text(authctxt->krb5_ctx, problem));
! 223:
! 224: krb5_cleanup_proc(authctxt);
! 225:
! 226: if (options.kerberos_or_local_passwd)
! 227: return (-1);
! 228: else
! 229: return (0);
! 230: }
! 231: return (1);
! 232: }
! 233:
! 234: void
! 235: krb5_cleanup_proc(void *context)
! 236: {
! 237: Authctxt *authctxt = (Authctxt *)context;
! 238:
! 239: debug("krb5_cleanup_proc called");
! 240: if (authctxt->krb5_fwd_ccache) {
! 241: krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
! 242: authctxt->krb5_fwd_ccache = NULL;
! 243: }
! 244: if (authctxt->krb5_user) {
! 245: krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
! 246: authctxt->krb5_user = NULL;
! 247: }
! 248: if (authctxt->krb5_auth_ctx) {
! 249: krb5_auth_con_free(authctxt->krb5_ctx,
! 250: authctxt->krb5_auth_ctx);
! 251: authctxt->krb5_auth_ctx = NULL;
! 252: }
! 253: if (authctxt->krb5_ctx) {
! 254: krb5_free_context(authctxt->krb5_ctx);
! 255: authctxt->krb5_ctx = NULL;
! 256: }
! 257: }
! 258:
! 259: #endif /* KRB5 */