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

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.4     ! markus      5:  * $OpenBSD: auth-krb5.c,v 1.3 2001/12/19 07:18:56 deraadt 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.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;
1.3       deraadt   134:
1.1       dugsong   135:        if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
                    136:                return (0);
1.3       deraadt   137:
1.1       dugsong   138:        temporarily_use_uid(authctxt->pw);
1.3       deraadt   139:
1.1       dugsong   140:        problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
                    141:        if (problem)
                    142:                goto fail;
1.3       deraadt   143:
1.1       dugsong   144:        problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
                    145:            authctxt->krb5_user);
                    146:        if (problem)
                    147:                goto fail;
1.3       deraadt   148:
1.1       dugsong   149:        problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
                    150:            ccache, tgt);
                    151:        if (problem)
                    152:                goto fail;
1.3       deraadt   153:
1.1       dugsong   154:        authctxt->krb5_fwd_ccache = ccache;
                    155:        ccache = NULL;
1.3       deraadt   156:
1.1       dugsong   157:        authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
1.3       deraadt   158:
1.1       dugsong   159:        problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
                    160:            &pname);
                    161:        if (problem)
                    162:                goto fail;
1.3       deraadt   163:
1.1       dugsong   164:        debug("Kerberos v5 TGT accepted (%s)", pname);
1.3       deraadt   165:
1.1       dugsong   166:        restore_uid();
1.3       deraadt   167:
1.1       dugsong   168:        return (1);
1.3       deraadt   169:
1.1       dugsong   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);
1.3       deraadt   176:
1.1       dugsong   177:        restore_uid();
1.3       deraadt   178:
1.1       dugsong   179:        return (0);
                    180: }
                    181:
                    182: int
                    183: auth_krb5_password(Authctxt *authctxt, const char *password)
                    184: {
                    185:        krb5_error_code problem;
1.3       deraadt   186:
1.1       dugsong   187:        if (authctxt->pw == NULL)
                    188:                return (0);
1.3       deraadt   189:
1.1       dugsong   190:        temporarily_use_uid(authctxt->pw);
1.3       deraadt   191:
1.1       dugsong   192:        problem = krb5_init(authctxt);
                    193:        if (problem)
                    194:                goto out;
1.3       deraadt   195:
1.1       dugsong   196:        problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
                    197:                    &authctxt->krb5_user);
                    198:        if (problem)
                    199:                goto out;
1.3       deraadt   200:
1.1       dugsong   201:        problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
                    202:            &authctxt->krb5_fwd_ccache);
                    203:        if (problem)
                    204:                goto out;
1.3       deraadt   205:
1.1       dugsong   206:        problem = krb5_cc_initialize(authctxt->krb5_ctx,
                    207:            authctxt->krb5_fwd_ccache, authctxt->krb5_user);
                    208:        if (problem)
                    209:                goto out;
1.3       deraadt   210:
1.4     ! markus    211:        restore_uid();
1.1       dugsong   212:        problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
                    213:            authctxt->krb5_fwd_ccache, password, 1, NULL);
1.4     ! markus    214:        temporarily_use_uid(authctxt->pw);
        !           215:
1.1       dugsong   216:        if (problem)
                    217:                goto out;
1.3       deraadt   218:
1.1       dugsong   219:        authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
1.3       deraadt   220:
1.1       dugsong   221:  out:
                    222:        restore_uid();
1.3       deraadt   223:
1.1       dugsong   224:        if (problem) {
                    225:                debug("Kerberos password authentication failed: %s",
                    226:                    krb5_get_err_text(authctxt->krb5_ctx, problem));
1.3       deraadt   227:
1.1       dugsong   228:                krb5_cleanup_proc(authctxt);
1.3       deraadt   229:
1.1       dugsong   230:                if (options.kerberos_or_local_passwd)
                    231:                        return (-1);
                    232:                else
                    233:                        return (0);
                    234:        }
                    235:        return (1);
                    236: }
                    237:
                    238: void
                    239: krb5_cleanup_proc(void *context)
                    240: {
                    241:        Authctxt *authctxt = (Authctxt *)context;
1.3       deraadt   242:
1.1       dugsong   243:        debug("krb5_cleanup_proc called");
                    244:        if (authctxt->krb5_fwd_ccache) {
                    245:                krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
                    246:                authctxt->krb5_fwd_ccache = NULL;
                    247:        }
                    248:        if (authctxt->krb5_user) {
                    249:                krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
                    250:                authctxt->krb5_user = NULL;
                    251:        }
                    252:        if (authctxt->krb5_auth_ctx) {
                    253:                krb5_auth_con_free(authctxt->krb5_ctx,
                    254:                    authctxt->krb5_auth_ctx);
                    255:                authctxt->krb5_auth_ctx = NULL;
                    256:        }
                    257:        if (authctxt->krb5_ctx) {
                    258:                krb5_free_context(authctxt->krb5_ctx);
                    259:                authctxt->krb5_ctx = NULL;
                    260:        }
                    261: }
                    262:
                    263: #endif /* KRB5 */