[BACK]Return to auth-krb5.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

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 */