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

1.1       dugsong     1: /*
                      2:  *    Kerberos v5 authentication and ticket-passing routines.
1.8       markus      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.7       stevesk     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.8.2.1 ! miod       31: RCSID("$OpenBSD: auth-krb5.c,v 1.9 2002/09/09 06:48:06 itojun Exp $");
1.6       stevesk    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.3       deraadt    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.3       deraadt    72: int
1.8.2.1 ! miod       73: auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *reply)
1.1       dugsong    74: {
                     75:        krb5_error_code problem;
                     76:        krb5_principal server;
                     77:        krb5_ticket *ticket;
1.2       dugsong    78:        int fd, ret;
                     79:
                     80:        ret = 0;
1.1       dugsong    81:        server = NULL;
                     82:        ticket = NULL;
1.8.2.1 ! miod       83:        reply->length = 0;
1.3       deraadt    84:
1.1       dugsong    85:        problem = krb5_init(authctxt);
1.3       deraadt    86:        if (problem)
1.1       dugsong    87:                goto err;
1.3       deraadt    88:
1.1       dugsong    89:        problem = krb5_auth_con_init(authctxt->krb5_ctx,
                     90:            &authctxt->krb5_auth_ctx);
                     91:        if (problem)
                     92:                goto err;
1.3       deraadt    93:
1.1       dugsong    94:        fd = packet_get_connection_in();
                     95:        problem = krb5_auth_con_setaddrs_from_fd(authctxt->krb5_ctx,
                     96:            authctxt->krb5_auth_ctx, &fd);
                     97:        if (problem)
                     98:                goto err;
1.3       deraadt    99:
1.1       dugsong   100:        problem = krb5_sname_to_principal(authctxt->krb5_ctx,  NULL, NULL ,
                    101:            KRB5_NT_SRV_HST, &server);
                    102:        if (problem)
                    103:                goto err;
1.3       deraadt   104:
1.1       dugsong   105:        problem = krb5_rd_req(authctxt->krb5_ctx, &authctxt->krb5_auth_ctx,
                    106:            auth, server, NULL, NULL, &ticket);
                    107:        if (problem)
                    108:                goto err;
1.3       deraadt   109:
1.1       dugsong   110:        problem = krb5_copy_principal(authctxt->krb5_ctx, ticket->client,
                    111:            &authctxt->krb5_user);
                    112:        if (problem)
                    113:                goto err;
1.3       deraadt   114:
1.1       dugsong   115:        /* if client wants mutual auth */
                    116:        problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
1.8.2.1 ! miod      117:            reply);
1.1       dugsong   118:        if (problem)
                    119:                goto err;
1.3       deraadt   120:
1.1       dugsong   121:        /* Check .k5login authorization now. */
                    122:        if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
                    123:            authctxt->pw->pw_name))
                    124:                goto err;
1.3       deraadt   125:
1.1       dugsong   126:        if (client)
                    127:                krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
                    128:                    client);
1.3       deraadt   129:
1.2       dugsong   130:        ret = 1;
1.1       dugsong   131:  err:
                    132:        if (server)
                    133:                krb5_free_principal(authctxt->krb5_ctx, server);
                    134:        if (ticket)
                    135:                krb5_free_ticket(authctxt->krb5_ctx, ticket);
1.8.2.1 ! miod      136:        if (!ret && reply->length) {
        !           137:                xfree(reply->data);
        !           138:                memset(reply, 0, sizeof(*reply));
        !           139:        }
1.3       deraadt   140:
1.5       markus    141:        if (problem) {
                    142:                if (authctxt->krb5_ctx != NULL)
                    143:                        debug("Kerberos v5 authentication failed: %s",
                    144:                            krb5_get_err_text(authctxt->krb5_ctx, problem));
                    145:                else
                    146:                        debug("Kerberos v5 authentication failed: %d",
                    147:                            problem);
                    148:        }
1.2       dugsong   149:
                    150:        return (ret);
1.1       dugsong   151: }
                    152:
                    153: int
                    154: auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt)
                    155: {
                    156:        krb5_error_code problem;
                    157:        krb5_ccache ccache = NULL;
                    158:        char *pname;
1.3       deraadt   159:
1.1       dugsong   160:        if (authctxt->pw == NULL || authctxt->krb5_user == NULL)
                    161:                return (0);
1.3       deraadt   162:
1.1       dugsong   163:        temporarily_use_uid(authctxt->pw);
1.3       deraadt   164:
1.1       dugsong   165:        problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &ccache);
                    166:        if (problem)
                    167:                goto fail;
1.3       deraadt   168:
1.1       dugsong   169:        problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache,
                    170:            authctxt->krb5_user);
                    171:        if (problem)
                    172:                goto fail;
1.3       deraadt   173:
1.1       dugsong   174:        problem = krb5_rd_cred2(authctxt->krb5_ctx, authctxt->krb5_auth_ctx,
                    175:            ccache, tgt);
                    176:        if (problem)
                    177:                goto fail;
1.3       deraadt   178:
1.1       dugsong   179:        authctxt->krb5_fwd_ccache = ccache;
                    180:        ccache = NULL;
1.3       deraadt   181:
1.1       dugsong   182:        authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
1.3       deraadt   183:
1.1       dugsong   184:        problem = krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user,
                    185:            &pname);
                    186:        if (problem)
                    187:                goto fail;
1.3       deraadt   188:
1.1       dugsong   189:        debug("Kerberos v5 TGT accepted (%s)", pname);
1.3       deraadt   190:
1.1       dugsong   191:        restore_uid();
1.3       deraadt   192:
1.1       dugsong   193:        return (1);
1.3       deraadt   194:
1.1       dugsong   195:  fail:
                    196:        if (problem)
                    197:                debug("Kerberos v5 TGT passing failed: %s",
                    198:                    krb5_get_err_text(authctxt->krb5_ctx, problem));
                    199:        if (ccache)
                    200:                krb5_cc_destroy(authctxt->krb5_ctx, ccache);
1.3       deraadt   201:
1.1       dugsong   202:        restore_uid();
1.3       deraadt   203:
1.1       dugsong   204:        return (0);
                    205: }
                    206:
                    207: int
                    208: auth_krb5_password(Authctxt *authctxt, const char *password)
                    209: {
                    210:        krb5_error_code problem;
1.3       deraadt   211:
1.1       dugsong   212:        if (authctxt->pw == NULL)
                    213:                return (0);
1.3       deraadt   214:
1.1       dugsong   215:        temporarily_use_uid(authctxt->pw);
1.3       deraadt   216:
1.1       dugsong   217:        problem = krb5_init(authctxt);
                    218:        if (problem)
                    219:                goto out;
1.3       deraadt   220:
1.1       dugsong   221:        problem = krb5_parse_name(authctxt->krb5_ctx, authctxt->pw->pw_name,
                    222:                    &authctxt->krb5_user);
                    223:        if (problem)
                    224:                goto out;
1.3       deraadt   225:
1.1       dugsong   226:        problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops,
                    227:            &authctxt->krb5_fwd_ccache);
                    228:        if (problem)
                    229:                goto out;
1.3       deraadt   230:
1.1       dugsong   231:        problem = krb5_cc_initialize(authctxt->krb5_ctx,
                    232:            authctxt->krb5_fwd_ccache, authctxt->krb5_user);
                    233:        if (problem)
                    234:                goto out;
1.3       deraadt   235:
1.4       markus    236:        restore_uid();
1.1       dugsong   237:        problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
                    238:            authctxt->krb5_fwd_ccache, password, 1, NULL);
1.4       markus    239:        temporarily_use_uid(authctxt->pw);
                    240:
1.1       dugsong   241:        if (problem)
                    242:                goto out;
1.3       deraadt   243:
1.1       dugsong   244:        authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
1.3       deraadt   245:
1.1       dugsong   246:  out:
                    247:        restore_uid();
1.3       deraadt   248:
1.1       dugsong   249:        if (problem) {
1.5       markus    250:                if (authctxt->krb5_ctx != NULL)
                    251:                        debug("Kerberos password authentication failed: %s",
                    252:                            krb5_get_err_text(authctxt->krb5_ctx, problem));
                    253:                else
                    254:                        debug("Kerberos password authentication failed: %d",
                    255:                            problem);
1.3       deraadt   256:
1.1       dugsong   257:                krb5_cleanup_proc(authctxt);
1.3       deraadt   258:
1.1       dugsong   259:                if (options.kerberos_or_local_passwd)
                    260:                        return (-1);
                    261:                else
                    262:                        return (0);
                    263:        }
                    264:        return (1);
                    265: }
                    266:
                    267: void
                    268: krb5_cleanup_proc(void *context)
                    269: {
                    270:        Authctxt *authctxt = (Authctxt *)context;
1.3       deraadt   271:
1.1       dugsong   272:        debug("krb5_cleanup_proc called");
                    273:        if (authctxt->krb5_fwd_ccache) {
                    274:                krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
                    275:                authctxt->krb5_fwd_ccache = NULL;
                    276:        }
                    277:        if (authctxt->krb5_user) {
                    278:                krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user);
                    279:                authctxt->krb5_user = NULL;
                    280:        }
                    281:        if (authctxt->krb5_auth_ctx) {
                    282:                krb5_auth_con_free(authctxt->krb5_ctx,
                    283:                    authctxt->krb5_auth_ctx);
                    284:                authctxt->krb5_auth_ctx = NULL;
                    285:        }
                    286:        if (authctxt->krb5_ctx) {
                    287:                krb5_free_context(authctxt->krb5_ctx);
                    288:                authctxt->krb5_ctx = NULL;
                    289:        }
                    290: }
                    291:
                    292: #endif /* KRB5 */