[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.2.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 $
1.1.2.1 ! miod        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;
                     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 */