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

1.1       dugsong     1: /*
                      2:  *    Kerberos v5 authentication and ticket-passing routines.
1.1.6.3 ! miod        3:  *
1.1       dugsong     4:  * $FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar Exp $
                      5:  */
1.1.6.3 ! miod        6: /*
        !             7:  * Copyright (c) 2002 Daniel Kouril.  All rights reserved.
        !             8:  *
        !             9:  * Redistribution and use in source and binary forms, with or without
        !            10:  * modification, are permitted provided that the following conditions
        !            11:  * are met:
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer in the
        !            16:  *    documentation and/or other materials provided with the distribution.
        !            17:  *
        !            18:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            19:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            20:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            21:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            22:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            23:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            24:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            25:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            26:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            27:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            28:  */
1.1       dugsong    29:
                     30: #include "includes.h"
1.1.6.3 ! miod       31: RCSID("$OpenBSD: auth-krb5.c,v 1.8 2002/03/19 10:49:35 markus Exp $");
1.1.6.2   jason      32:
1.1       dugsong    33: #include "ssh.h"
                     34: #include "ssh1.h"
                     35: #include "packet.h"
                     36: #include "xmalloc.h"
                     37: #include "log.h"
                     38: #include "servconf.h"
                     39: #include "uidswap.h"
                     40: #include "auth.h"
                     41:
                     42: #ifdef KRB5
                     43: #include <krb5.h>
                     44:
                     45: extern ServerOptions    options;
                     46:
                     47: static int
                     48: krb5_init(void *context)
                     49: {
                     50:        Authctxt *authctxt = (Authctxt *)context;
                     51:        krb5_error_code problem;
                     52:        static int cleanup_registered = 0;
1.1.6.2   jason      53:
1.1       dugsong    54:        if (authctxt->krb5_ctx == NULL) {
                     55:                problem = krb5_init_context(&authctxt->krb5_ctx);
                     56:                if (problem)
                     57:                        return (problem);
                     58:                krb5_init_ets(authctxt->krb5_ctx);
                     59:        }
                     60:        if (!cleanup_registered) {
                     61:                fatal_add_cleanup(krb5_cleanup_proc, authctxt);
                     62:                cleanup_registered = 1;
                     63:        }
                     64:        return (0);
                     65: }
                     66:
                     67: /*
                     68:  * Try krb5 authentication. server_user is passed for logging purposes
                     69:  * only, in auth is received ticket, in client is returned principal
                     70:  * from the ticket
                     71:  */
1.1.6.2   jason      72: int
1.1       dugsong    73: auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client)
                     74: {
                     75:        krb5_error_code problem;
                     76:        krb5_principal server;
                     77:        krb5_data reply;
                     78:        krb5_ticket *ticket;
1.1.6.1   jason      79:        int fd, ret;
                     80:
                     81:        ret = 0;
1.1       dugsong    82:        server = NULL;
                     83:        ticket = NULL;
                     84:        reply.length = 0;
1.1.6.2   jason      85:
1.1       dugsong    86:        problem = krb5_init(authctxt);
1.1.6.2   jason      87:        if (problem)
1.1       dugsong    88:                goto err;
1.1.6.2   jason      89:
1.1       dugsong    90:        problem = krb5_auth_con_init(authctxt->krb5_ctx,
                     91:            &authctxt->krb5_auth_ctx);
                     92:        if (problem)
                     93:                goto err;
1.1.6.2   jason      94:
1.1       dugsong    95:        fd = packet_get_connection_in();
                     96:        problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx,
                     97:            authctxt->krb5_auth_ctx, &fd);
                     98:        if (problem)
                     99:                goto err;
1.1.6.2   jason     100:
1.1       dugsong   101:        problem = krb5_sname_to_principal(authctxt->krb5_ctx,  NULL, NULL ,
                    102:            KRB5_NT_SRV_HST, &server);
                    103:        if (problem)
                    104:                goto err;
1.1.6.2   jason     105:
1.1       dugsong   106:        problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx,
                    107:            auth, server, NULL, NULL, &ticket);
                    108:        if (problem)
                    109:                goto err;
1.1.6.2   jason     110:
1.1       dugsong   111:        problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client,
                    112:            &authctxt->krb5_user);
                    113:        if (problem)
                    114:                goto err;
1.1.6.2   jason     115:
1.1       dugsong   116:        /* if client wants mutual auth */
                    117:        problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
                    118:            &reply);
                    119:        if (problem)
                    120:                goto err;
1.1.6.2   jason     121:
1.1       dugsong   122:        /* Check .k5login authorization now. */
                    123:        if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
                    124:            authctxt->pw->pw_name))
                    125:                goto err;
1.1.6.2   jason     126:
1.1       dugsong   127:        if (client)
                    128:                krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
                    129:                    client);
1.1.6.2   jason     130:
1.1       dugsong   131:        packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE);
                    132:        packet_put_string((char *) reply.data, reply.length);
                    133:        packet_send();
                    134:        packet_write_wait();
1.1.6.1   jason     135:
                    136:        ret = 1;
1.1       dugsong   137:  err:
                    138:        if (server)
                    139:                krb5_free_principal(authctxt->krb5_ctx, server);
                    140:        if (ticket)
                    141:                krb5_free_ticket(authctxt->krb5_ctx, ticket);
                    142:        if (reply.length)
                    143:                xfree(reply.data);
1.1.6.2   jason     144:
                    145:        if (problem) {
                    146:                if (authctxt->krb5_ctx != NULL)
                    147:                        debug("Kerberos v5 authentication failed: %s",
                    148:                            krb5_get_err_text(authctxt->krb5_ctx, problem));
                    149:                else
                    150:                        debug("Kerberos v5 authentication failed: %d",
                    151:                            problem);
                    152:        }
1.1.6.1   jason     153:
                    154:        return (ret);
1.1       dugsong   155: }
                    156:
                    157: int
                    158: auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt)
                    159: {
                    160:        krb5_error_code problem;
                    161:        krb5_ccache ccache = NULL;
                    162:        char *pname;
1.1.6.2   jason     163:
1.1       dugsong   164:        if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
                    165:                return (0);
1.1.6.2   jason     166:
1.1       dugsong   167:        temporarily_use_uid(authctxt->pw);
1.1.6.2   jason     168:
1.1       dugsong   169:        problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
                    170:        if (problem)
                    171:                goto fail;
1.1.6.2   jason     172:
1.1       dugsong   173:        problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
                    174:            authctxt->krb5_user);
                    175:        if (problem)
                    176:                goto fail;
1.1.6.2   jason     177:
1.1       dugsong   178:        problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
                    179:            ccache, tgt);
                    180:        if (problem)
                    181:                goto fail;
1.1.6.2   jason     182:
1.1       dugsong   183:        authctxt->krb5_fwd_ccache = ccache;
                    184:        ccache = NULL;
1.1.6.2   jason     185:
1.1       dugsong   186:        authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
1.1.6.2   jason     187:
1.1       dugsong   188:        problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
                    189:            &pname);
                    190:        if (problem)
                    191:                goto fail;
1.1.6.2   jason     192:
1.1       dugsong   193:        debug("Kerberos v5 TGT accepted (%s)", pname);
1.1.6.2   jason     194:
1.1       dugsong   195:        restore_uid();
1.1.6.2   jason     196:
1.1       dugsong   197:        return (1);
1.1.6.2   jason     198:
1.1       dugsong   199:  fail:
                    200:        if (problem)
                    201:                debug("Kerberos v5 TGT passing failed: %s",
                    202:                    krb5_get_err_text(authctxt->krb5_ctx, problem));
                    203:        if (ccache)
                    204:                krb5_cc_destroy(authctxt->krb5_ctx, ccache);
1.1.6.2   jason     205:
1.1       dugsong   206:        restore_uid();
1.1.6.2   jason     207:
1.1       dugsong   208:        return (0);
                    209: }
                    210:
                    211: int
                    212: auth_krb5_password(Authctxt *authctxt, const char *password)
                    213: {
                    214:        krb5_error_code problem;
1.1.6.2   jason     215:
1.1       dugsong   216:        if (authctxt->pw == NULL)
                    217:                return (0);
1.1.6.2   jason     218:
1.1       dugsong   219:        temporarily_use_uid(authctxt->pw);
1.1.6.2   jason     220:
1.1       dugsong   221:        problem = krb5_init(authctxt);
                    222:        if (problem)
                    223:                goto out;
1.1.6.2   jason     224:
1.1       dugsong   225:        problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
                    226:                    &authctxt->krb5_user);
                    227:        if (problem)
                    228:                goto out;
1.1.6.2   jason     229:
1.1       dugsong   230:        problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
                    231:            &authctxt->krb5_fwd_ccache);
                    232:        if (problem)
                    233:                goto out;
1.1.6.2   jason     234:
1.1       dugsong   235:        problem = krb5_cc_initialize(authctxt->krb5_ctx,
                    236:            authctxt->krb5_fwd_ccache, authctxt->krb5_user);
                    237:        if (problem)
                    238:                goto out;
1.1.6.2   jason     239:
                    240:        restore_uid();
1.1       dugsong   241:        problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
                    242:            authctxt->krb5_fwd_ccache, password, 1, NULL);
1.1.6.2   jason     243:        temporarily_use_uid(authctxt->pw);
                    244:
1.1       dugsong   245:        if (problem)
                    246:                goto out;
1.1.6.2   jason     247:
1.1       dugsong   248:        authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
1.1.6.2   jason     249:
1.1       dugsong   250:  out:
                    251:        restore_uid();
1.1.6.2   jason     252:
1.1       dugsong   253:        if (problem) {
1.1.6.2   jason     254:                if (authctxt->krb5_ctx != NULL)
                    255:                        debug("Kerberos password authentication failed: %s",
                    256:                            krb5_get_err_text(authctxt->krb5_ctx, problem));
                    257:                else
                    258:                        debug("Kerberos password authentication failed: %d",
                    259:                            problem);
                    260:
1.1       dugsong   261:                krb5_cleanup_proc(authctxt);
1.1.6.2   jason     262:
1.1       dugsong   263:                if (options.kerberos_or_local_passwd)
                    264:                        return (-1);
                    265:                else
                    266:                        return (0);
                    267:        }
                    268:        return (1);
                    269: }
                    270:
                    271: void
                    272: krb5_cleanup_proc(void *context)
                    273: {
                    274:        Authctxt *authctxt = (Authctxt *)context;
1.1.6.2   jason     275:
1.1       dugsong   276:        debug("krb5_cleanup_proc called");
                    277:        if (authctxt->krb5_fwd_ccache) {
                    278:                krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
                    279:                authctxt->krb5_fwd_ccache = NULL;
                    280:        }
                    281:        if (authctxt->krb5_user) {
                    282:                krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
                    283:                authctxt->krb5_user = NULL;
                    284:        }
                    285:        if (authctxt->krb5_auth_ctx) {
                    286:                krb5_auth_con_free(authctxt->krb5_ctx,
                    287:                    authctxt->krb5_auth_ctx);
                    288:                authctxt->krb5_auth_ctx = NULL;
                    289:        }
                    290:        if (authctxt->krb5_ctx) {
                    291:                krb5_free_context(authctxt->krb5_ctx);
                    292:                authctxt->krb5_ctx = NULL;
                    293:        }
                    294: }
                    295:
                    296: #endif /* KRB5 */