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

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.5     ! markus      5:  * $OpenBSD: auth-krb5.c,v 1.4 2002/01/27 15:12:09 markus 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;
1.3       deraadt    29:
1.1       dugsong    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:  */
1.3       deraadt    48: int
1.1       dugsong    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;
1.3       deraadt    61:
1.1       dugsong    62:        problem = krb5_init(authctxt);
1.3       deraadt    63:        if (problem)
1.1       dugsong    64:                goto err;
1.3       deraadt    65:
1.1       dugsong    66:        problem = krb5_auth_con_init(authctxt->krb5_ctx,
                     67:            &authctxt->krb5_auth_ctx);
                     68:        if (problem)
                     69:                goto err;
1.3       deraadt    70:
1.1       dugsong    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;
1.3       deraadt    76:
1.1       dugsong    77:        problem = krb5_sname_to_principal(authctxt->krb5_ctx,  NULL, NULL ,
                     78:            KRB5_NT_SRV_HST, &server);
                     79:        if (problem)
                     80:                goto err;
1.3       deraadt    81:
1.1       dugsong    82:        problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx,
                     83:            auth, server, NULL, NULL, &ticket);
                     84:        if (problem)
                     85:                goto err;
1.3       deraadt    86:
1.1       dugsong    87:        problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client,
                     88:            &authctxt->krb5_user);
                     89:        if (problem)
                     90:                goto err;
1.3       deraadt    91:
1.1       dugsong    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;
1.3       deraadt    97:
1.1       dugsong    98:        /* Check .k5login authorization now. */
                     99:        if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
                    100:            authctxt->pw->pw_name))
                    101:                goto err;
1.3       deraadt   102:
1.1       dugsong   103:        if (client)
                    104:                krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
                    105:                    client);
1.3       deraadt   106:
1.1       dugsong   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);
1.3       deraadt   120:
1.5     ! markus    121:        if (problem) {
        !           122:                if (authctxt->krb5_ctx != NULL)
        !           123:                        debug("Kerberos v5 authentication failed: %s",
        !           124:                            krb5_get_err_text(authctxt->krb5_ctx, problem));
        !           125:                else
        !           126:                        debug("Kerberos v5 authentication failed: %d",
        !           127:                            problem);
        !           128:        }
1.2       dugsong   129:
                    130:        return (ret);
1.1       dugsong   131: }
                    132:
                    133: int
                    134: auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt)
                    135: {
                    136:        krb5_error_code problem;
                    137:        krb5_ccache ccache = NULL;
                    138:        char *pname;
1.3       deraadt   139:
1.1       dugsong   140:        if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
                    141:                return (0);
1.3       deraadt   142:
1.1       dugsong   143:        temporarily_use_uid(authctxt->pw);
1.3       deraadt   144:
1.1       dugsong   145:        problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
                    146:        if (problem)
                    147:                goto fail;
1.3       deraadt   148:
1.1       dugsong   149:        problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
                    150:            authctxt->krb5_user);
                    151:        if (problem)
                    152:                goto fail;
1.3       deraadt   153:
1.1       dugsong   154:        problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
                    155:            ccache, tgt);
                    156:        if (problem)
                    157:                goto fail;
1.3       deraadt   158:
1.1       dugsong   159:        authctxt->krb5_fwd_ccache = ccache;
                    160:        ccache = NULL;
1.3       deraadt   161:
1.1       dugsong   162:        authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
1.3       deraadt   163:
1.1       dugsong   164:        problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
                    165:            &pname);
                    166:        if (problem)
                    167:                goto fail;
1.3       deraadt   168:
1.1       dugsong   169:        debug("Kerberos v5 TGT accepted (%s)", pname);
1.3       deraadt   170:
1.1       dugsong   171:        restore_uid();
1.3       deraadt   172:
1.1       dugsong   173:        return (1);
1.3       deraadt   174:
1.1       dugsong   175:  fail:
                    176:        if (problem)
                    177:                debug("Kerberos v5 TGT passing failed: %s",
                    178:                    krb5_get_err_text(authctxt->krb5_ctx, problem));
                    179:        if (ccache)
                    180:                krb5_cc_destroy(authctxt->krb5_ctx, ccache);
1.3       deraadt   181:
1.1       dugsong   182:        restore_uid();
1.3       deraadt   183:
1.1       dugsong   184:        return (0);
                    185: }
                    186:
                    187: int
                    188: auth_krb5_password(Authctxt *authctxt, const char *password)
                    189: {
                    190:        krb5_error_code problem;
1.3       deraadt   191:
1.1       dugsong   192:        if (authctxt->pw == NULL)
                    193:                return (0);
1.3       deraadt   194:
1.1       dugsong   195:        temporarily_use_uid(authctxt->pw);
1.3       deraadt   196:
1.1       dugsong   197:        problem = krb5_init(authctxt);
                    198:        if (problem)
                    199:                goto out;
1.3       deraadt   200:
1.1       dugsong   201:        problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
                    202:                    &authctxt->krb5_user);
                    203:        if (problem)
                    204:                goto out;
1.3       deraadt   205:
1.1       dugsong   206:        problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
                    207:            &authctxt->krb5_fwd_ccache);
                    208:        if (problem)
                    209:                goto out;
1.3       deraadt   210:
1.1       dugsong   211:        problem = krb5_cc_initialize(authctxt->krb5_ctx,
                    212:            authctxt->krb5_fwd_ccache, authctxt->krb5_user);
                    213:        if (problem)
                    214:                goto out;
1.3       deraadt   215:
1.4       markus    216:        restore_uid();
1.1       dugsong   217:        problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
                    218:            authctxt->krb5_fwd_ccache, password, 1, NULL);
1.4       markus    219:        temporarily_use_uid(authctxt->pw);
                    220:
1.1       dugsong   221:        if (problem)
                    222:                goto out;
1.3       deraadt   223:
1.1       dugsong   224:        authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
1.3       deraadt   225:
1.1       dugsong   226:  out:
                    227:        restore_uid();
1.3       deraadt   228:
1.1       dugsong   229:        if (problem) {
1.5     ! markus    230:                if (authctxt->krb5_ctx != NULL)
        !           231:                        debug("Kerberos password authentication failed: %s",
        !           232:                            krb5_get_err_text(authctxt->krb5_ctx, problem));
        !           233:                else
        !           234:                        debug("Kerberos password authentication failed: %d",
        !           235:                            problem);
1.3       deraadt   236:
1.1       dugsong   237:                krb5_cleanup_proc(authctxt);
1.3       deraadt   238:
1.1       dugsong   239:                if (options.kerberos_or_local_passwd)
                    240:                        return (-1);
                    241:                else
                    242:                        return (0);
                    243:        }
                    244:        return (1);
                    245: }
                    246:
                    247: void
                    248: krb5_cleanup_proc(void *context)
                    249: {
                    250:        Authctxt *authctxt = (Authctxt *)context;
1.3       deraadt   251:
1.1       dugsong   252:        debug("krb5_cleanup_proc called");
                    253:        if (authctxt->krb5_fwd_ccache) {
                    254:                krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
                    255:                authctxt->krb5_fwd_ccache = NULL;
                    256:        }
                    257:        if (authctxt->krb5_user) {
                    258:                krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
                    259:                authctxt->krb5_user = NULL;
                    260:        }
                    261:        if (authctxt->krb5_auth_ctx) {
                    262:                krb5_auth_con_free(authctxt->krb5_ctx,
                    263:                    authctxt->krb5_auth_ctx);
                    264:                authctxt->krb5_auth_ctx = NULL;
                    265:        }
                    266:        if (authctxt->krb5_ctx) {
                    267:                krb5_free_context(authctxt->krb5_ctx);
                    268:                authctxt->krb5_ctx = NULL;
                    269:        }
                    270: }
                    271:
                    272: #endif /* KRB5 */