[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.2

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 $
1.2     ! dugsong     5:  * $OpenBSD: auth-krb5.c,v 1.1 2001/06/26 16:15:23 dugsong Exp $
1.1       dugsong     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;
1.2     ! dugsong    55:        int fd, ret;
        !            56:
        !            57:        ret = 0;
1.1       dugsong    58:        server = NULL;
                     59:        ticket = NULL;
                     60:        reply.length = 0;
                     61:
                     62:        problem = krb5_init(authctxt);
                     63:        if (problem)
                     64:                goto err;
                     65:
                     66:        problem = krb5_auth_con_init(authctxt->krb5_ctx,
                     67:            &authctxt->krb5_auth_ctx);
                     68:        if (problem)
                     69:                goto err;
                     70:
                     71:        fd = packet_get_connection_in();
                     72:        problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx,
                     73:            authctxt->krb5_auth_ctx, &fd);
                     74:        if (problem)
                     75:                goto err;
                     76:
                     77:        problem = krb5_sname_to_principal(authctxt->krb5_ctx,  NULL, NULL ,
                     78:            KRB5_NT_SRV_HST, &server);
                     79:        if (problem)
                     80:                goto err;
                     81:
                     82:        problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx,
                     83:            auth, server, NULL, NULL, &ticket);
                     84:        if (problem)
                     85:                goto err;
                     86:
                     87:        problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client,
                     88:            &authctxt->krb5_user);
                     89:        if (problem)
                     90:                goto err;
                     91:
                     92:        /* if client wants mutual auth */
                     93:        problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
                     94:            &reply);
                     95:        if (problem)
                     96:                goto err;
                     97:
                     98:        /* Check .k5login authorization now. */
                     99:        if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
                    100:            authctxt->pw->pw_name))
                    101:                goto err;
                    102:
                    103:        if (client)
                    104:                krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
                    105:                    client);
                    106:
                    107:        packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE);
                    108:        packet_put_string((char *) reply.data, reply.length);
                    109:        packet_send();
                    110:        packet_write_wait();
1.2     ! dugsong   111:
        !           112:        ret = 1;
1.1       dugsong   113:  err:
                    114:        if (server)
                    115:                krb5_free_principal(authctxt->krb5_ctx, server);
                    116:        if (ticket)
                    117:                krb5_free_ticket(authctxt->krb5_ctx, ticket);
                    118:        if (reply.length)
                    119:                xfree(reply.data);
                    120:
1.2     ! dugsong   121:        if (problem)
1.1       dugsong   122:                debug("Kerberos v5 authentication failed: %s",
                    123:                    krb5_get_err_text(authctxt->krb5_ctx, problem));
1.2     ! dugsong   124:
        !           125:        return (ret);
1.1       dugsong   126: }
                    127:
                    128: int
                    129: auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt)
                    130: {
                    131:        krb5_error_code problem;
                    132:        krb5_ccache ccache = NULL;
                    133:        char *pname;
                    134:
                    135:        if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
                    136:                return (0);
                    137:
                    138:        temporarily_use_uid(authctxt->pw);
                    139:
                    140:        problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
                    141:        if (problem)
                    142:                goto fail;
                    143:
                    144:        problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
                    145:            authctxt->krb5_user);
                    146:        if (problem)
                    147:                goto fail;
                    148:
                    149:        problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
                    150:            ccache, tgt);
                    151:        if (problem)
                    152:                goto fail;
                    153:
                    154:        authctxt->krb5_fwd_ccache = ccache;
                    155:        ccache = NULL;
                    156:
                    157:        authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
                    158:
                    159:        problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
                    160:            &pname);
                    161:        if (problem)
                    162:                goto fail;
                    163:
                    164:        debug("Kerberos v5 TGT accepted (%s)", pname);
                    165:
                    166:        restore_uid();
                    167:
                    168:        return (1);
                    169:
                    170:  fail:
                    171:        if (problem)
                    172:                debug("Kerberos v5 TGT passing failed: %s",
                    173:                    krb5_get_err_text(authctxt->krb5_ctx, problem));
                    174:        if (ccache)
                    175:                krb5_cc_destroy(authctxt->krb5_ctx, ccache);
                    176:
                    177:        restore_uid();
                    178:
                    179:        return (0);
                    180: }
                    181:
                    182: int
                    183: auth_krb5_password(Authctxt *authctxt, const char *password)
                    184: {
                    185:        krb5_error_code problem;
                    186:
                    187:        if (authctxt->pw == NULL)
                    188:                return (0);
                    189:
                    190:        temporarily_use_uid(authctxt->pw);
                    191:
                    192:        problem = krb5_init(authctxt);
                    193:        if (problem)
                    194:                goto out;
                    195:
                    196:        problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
                    197:                    &authctxt->krb5_user);
                    198:        if (problem)
                    199:                goto out;
                    200:
                    201:        problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
                    202:            &authctxt->krb5_fwd_ccache);
                    203:        if (problem)
                    204:                goto out;
                    205:
                    206:        problem = krb5_cc_initialize(authctxt->krb5_ctx,
                    207:            authctxt->krb5_fwd_ccache, authctxt->krb5_user);
                    208:        if (problem)
                    209:                goto out;
                    210:
                    211:        problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
                    212:            authctxt->krb5_fwd_ccache, password, 1, NULL);
                    213:        if (problem)
                    214:                goto out;
                    215:
                    216:        authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
                    217:
                    218:  out:
                    219:        restore_uid();
                    220:
                    221:        if (problem) {
                    222:                debug("Kerberos password authentication failed: %s",
                    223:                    krb5_get_err_text(authctxt->krb5_ctx, problem));
                    224:
                    225:                krb5_cleanup_proc(authctxt);
                    226:
                    227:                if (options.kerberos_or_local_passwd)
                    228:                        return (-1);
                    229:                else
                    230:                        return (0);
                    231:        }
                    232:        return (1);
                    233: }
                    234:
                    235: void
                    236: krb5_cleanup_proc(void *context)
                    237: {
                    238:        Authctxt *authctxt = (Authctxt *)context;
                    239:
                    240:        debug("krb5_cleanup_proc called");
                    241:        if (authctxt->krb5_fwd_ccache) {
                    242:                krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
                    243:                authctxt->krb5_fwd_ccache = NULL;
                    244:        }
                    245:        if (authctxt->krb5_user) {
                    246:                krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
                    247:                authctxt->krb5_user = NULL;
                    248:        }
                    249:        if (authctxt->krb5_auth_ctx) {
                    250:                krb5_auth_con_free(authctxt->krb5_ctx,
                    251:                    authctxt->krb5_auth_ctx);
                    252:                authctxt->krb5_auth_ctx = NULL;
                    253:        }
                    254:        if (authctxt->krb5_ctx) {
                    255:                krb5_free_context(authctxt->krb5_ctx);
                    256:                authctxt->krb5_ctx = NULL;
                    257:        }
                    258: }
                    259:
                    260: #endif /* KRB5 */