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

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