[BACK]Return to auth-krb4.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/auth-krb4.c, Revision 1.9

1.1       deraadt     1: /*
                      2:
                      3:    auth-kerberos.c
                      4:
1.2       dugsong     5:    Dug Song <dugsong@UMICH.EDU>
1.1       deraadt     6:
1.2       dugsong     7:    Kerberos v4 authentication and ticket-passing routines.
1.1       deraadt     8:
1.9     ! markus      9:    $Id: auth-krb4.c,v 1.8 1999/11/15 00:42:00 markus Exp $
1.1       deraadt    10: */
                     11:
                     12: #include "includes.h"
                     13: #include "packet.h"
                     14: #include "xmalloc.h"
                     15: #include "ssh.h"
                     16:
                     17: #ifdef KRB4
1.6       markus     18: char *ticket = NULL;
                     19:
                     20: void
                     21: krb4_cleanup_proc(void *ignore)
1.1       deraadt    22: {
1.9     ! markus     23:        debug("krb4_cleanup_proc called");
        !            24:        if (ticket) {
        !            25:                (void) dest_tkt();
        !            26:                xfree(ticket);
        !            27:                ticket = NULL;
        !            28:        }
1.6       markus     29: }
                     30:
1.9     ! markus     31: int
        !            32: krb4_init(uid_t uid)
1.6       markus     33: {
1.9     ! markus     34:        static int cleanup_registered = 0;
        !            35:        char *tkt_root = TKT_ROOT;
        !            36:        struct stat st;
        !            37:        int fd;
        !            38:
        !            39:        if (!ticket) {
        !            40:                /* Set unique ticket string manually since we're still root. */
        !            41:                ticket = xmalloc(MAXPATHLEN);
1.1       deraadt    42: #ifdef AFS
1.9     ! markus     43:                if (lstat("/ticket", &st) != -1)
        !            44:                        tkt_root = "/ticket/";
1.1       deraadt    45: #endif /* AFS */
1.9     ! markus     46:                snprintf(ticket, MAXPATHLEN, "%s%d_%d", tkt_root, uid, getpid());
        !            47:                (void) krb_set_tkt_string(ticket);
        !            48:        }
        !            49:        /* Register ticket cleanup in case of fatal error. */
        !            50:        if (!cleanup_registered) {
        !            51:                fatal_add_cleanup(krb4_cleanup_proc, NULL);
        !            52:                cleanup_registered = 1;
        !            53:        }
        !            54:        /* Try to create our ticket file. */
        !            55:        if ((fd = mkstemp(ticket)) != -1) {
        !            56:                close(fd);
        !            57:                return 1;
        !            58:        }
        !            59:        /* Ticket file exists - make sure user owns it (just passed ticket). */
        !            60:        if (lstat(ticket, &st) != -1) {
        !            61:                if (st.st_mode == (S_IFREG | S_IRUSR | S_IWUSR) &&
        !            62:                    st.st_uid == uid)
        !            63:                        return 1;
        !            64:        }
        !            65:        /* Failure - cancel cleanup function, leaving bad ticket for inspection. */
        !            66:        log("WARNING: bad ticket file %s", ticket);
        !            67:        fatal_remove_cleanup(krb4_cleanup_proc, NULL);
        !            68:        cleanup_registered = 0;
        !            69:        xfree(ticket);
        !            70:        ticket = NULL;
        !            71:
        !            72:        return 0;
1.1       deraadt    73: }
                     74:
1.9     ! markus     75: int
        !            76: auth_krb4(const char *server_user, KTEXT auth, char **client)
1.1       deraadt    77: {
1.9     ! markus     78:        AUTH_DAT adat = {0};
        !            79:        KTEXT_ST reply;
        !            80:        char instance[INST_SZ];
        !            81:        int r, s;
        !            82:        u_int cksum;
        !            83:        Key_schedule schedule;
        !            84:        struct sockaddr_in local, foreign;
        !            85:
        !            86:        s = packet_get_connection_in();
        !            87:
        !            88:        r = sizeof(local);
        !            89:        memset(&local, 0, sizeof(local));
        !            90:        if (getsockname(s, (struct sockaddr *) & local, &r) < 0)
        !            91:                debug("getsockname failed: %.100s", strerror(errno));
        !            92:        r = sizeof(foreign);
        !            93:        memset(&foreign, 0, sizeof(foreign));
        !            94:        if (getpeername(s, (struct sockaddr *) & foreign, &r) < 0) {
        !            95:                debug("getpeername failed: %.100s", strerror(errno));
        !            96:                fatal_cleanup();
        !            97:        }
        !            98:        instance[0] = '*';
        !            99:        instance[1] = 0;
        !           100:
        !           101:        /* Get the encrypted request, challenge, and session key. */
        !           102:        if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance, 0, &adat, ""))) {
        !           103:                packet_send_debug("Kerberos V4 krb_rd_req: %.100s", krb_err_txt[r]);
        !           104:                return 0;
        !           105:        }
        !           106:        des_key_sched((des_cblock *) adat.session, schedule);
        !           107:
        !           108:        *client = xmalloc(MAX_K_NAME_SZ);
        !           109:        (void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname,
        !           110:                        *adat.pinst ? "." : "", adat.pinst, adat.prealm);
        !           111:
        !           112:        /* Check ~/.klogin authorization now. */
        !           113:        if (kuserok(&adat, (char *) server_user) != KSUCCESS) {
        !           114:                packet_send_debug("Kerberos V4 .klogin authorization failed!");
        !           115:                log("Kerberos V4 .klogin authorization failed for %s to account %s",
        !           116:                    *client, server_user);
        !           117:                xfree(*client);
        !           118:                return 0;
        !           119:        }
        !           120:        /* Increment the checksum, and return it encrypted with the
        !           121:           session key. */
        !           122:        cksum = adat.checksum + 1;
        !           123:        cksum = htonl(cksum);
        !           124:
        !           125:        /* If we can't successfully encrypt the checksum, we send back an
        !           126:           empty message, admitting our failure. */
        !           127:        if ((r = krb_mk_priv((u_char *) & cksum, reply.dat, sizeof(cksum) + 1,
        !           128:                             schedule, &adat.session, &local, &foreign)) < 0) {
        !           129:                packet_send_debug("Kerberos V4 mk_priv: (%d) %s", r, krb_err_txt[r]);
        !           130:                reply.dat[0] = 0;
        !           131:                reply.length = 0;
        !           132:        } else
        !           133:                reply.length = r;
        !           134:
        !           135:        /* Clear session key. */
        !           136:        memset(&adat.session, 0, sizeof(&adat.session));
        !           137:
        !           138:        packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE);
        !           139:        packet_put_string((char *) reply.dat, reply.length);
        !           140:        packet_send();
        !           141:        packet_write_wait();
        !           142:        return 1;
1.1       deraadt   143: }
                    144: #endif /* KRB4 */
                    145:
                    146: #ifdef AFS
1.9     ! markus    147: int
        !           148: auth_kerberos_tgt(struct passwd *pw, const char *string)
1.1       deraadt   149: {
1.9     ! markus    150:        CREDENTIALS creds;
        !           151:
        !           152:        if (!radix_to_creds(string, &creds)) {
        !           153:                log("Protocol error decoding Kerberos V4 tgt");
        !           154:                packet_send_debug("Protocol error decoding Kerberos V4 tgt");
        !           155:                goto auth_kerberos_tgt_failure;
        !           156:        }
        !           157:        if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */
        !           158:                strlcpy(creds.service, "krbtgt", sizeof creds.service);
        !           159:
        !           160:        if (strcmp(creds.service, "krbtgt")) {
        !           161:                log("Kerberos V4 tgt (%s%s%s@%s) rejected for %s", creds.pname,
        !           162:                    creds.pinst[0] ? "." : "", creds.pinst, creds.realm, pw->pw_name);
        !           163:                packet_send_debug("Kerberos V4 tgt (%s%s%s@%s) rejected for %s",
        !           164:                     creds.pname, creds.pinst[0] ? "." : "", creds.pinst,
        !           165:                                  creds.realm, pw->pw_name);
        !           166:                goto auth_kerberos_tgt_failure;
        !           167:        }
        !           168:        if (!krb4_init(pw->pw_uid))
        !           169:                goto auth_kerberos_tgt_failure;
        !           170:
        !           171:        if (in_tkt(creds.pname, creds.pinst) != KSUCCESS)
        !           172:                goto auth_kerberos_tgt_failure;
        !           173:
        !           174:        if (save_credentials(creds.service, creds.instance, creds.realm,
        !           175:                             creds.session, creds.lifetime, creds.kvno,
        !           176:                             &creds.ticket_st, creds.issue_date) != KSUCCESS) {
        !           177:                packet_send_debug("Kerberos V4 tgt refused: couldn't save credentials");
        !           178:                goto auth_kerberos_tgt_failure;
        !           179:        }
        !           180:        /* Successful authentication, passed all checks. */
        !           181:        chown(tkt_string(), pw->pw_uid, pw->pw_gid);
        !           182:
        !           183:        packet_send_debug("Kerberos V4 tgt accepted (%s.%s@%s, %s%s%s@%s)",
        !           184:                          creds.service, creds.instance, creds.realm, creds.pname,
        !           185:                          creds.pinst[0] ? "." : "", creds.pinst, creds.realm);
        !           186:        memset(&creds, 0, sizeof(creds));
        !           187:        packet_start(SSH_SMSG_SUCCESS);
        !           188:        packet_send();
        !           189:        packet_write_wait();
        !           190:        return 1;
        !           191:
        !           192: auth_kerberos_tgt_failure:
        !           193:        krb4_cleanup_proc(NULL);
        !           194:        memset(&creds, 0, sizeof(creds));
        !           195:        packet_start(SSH_SMSG_FAILURE);
        !           196:        packet_send();
        !           197:        packet_write_wait();
        !           198:        return 0;
1.1       deraadt   199: }
                    200:
1.9     ! markus    201: int
        !           202: auth_afs_token(struct passwd *pw, const char *token_string)
1.1       deraadt   203: {
1.9     ! markus    204:        CREDENTIALS creds;
        !           205:        uid_t uid = pw->pw_uid;
1.1       deraadt   206:
1.9     ! markus    207:        if (!radix_to_creds(token_string, &creds)) {
        !           208:                log("Protocol error decoding AFS token");
        !           209:                packet_send_debug("Protocol error decoding AFS token");
        !           210:                packet_start(SSH_SMSG_FAILURE);
        !           211:                packet_send();
        !           212:                packet_write_wait();
        !           213:                return 0;
        !           214:        }
        !           215:        if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */
        !           216:                strlcpy(creds.service, "afs", sizeof creds.service);
        !           217:
        !           218:        if (strncmp(creds.pname, "AFS ID ", 7) == 0)
        !           219:                uid = atoi(creds.pname + 7);
        !           220:
        !           221:        if (kafs_settoken(creds.realm, uid, &creds)) {
        !           222:                log("AFS token (%s@%s) rejected for %s", creds.pname, creds.realm,
        !           223:                    pw->pw_name);
        !           224:                packet_send_debug("AFS token (%s@%s) rejected for %s", creds.pname,
        !           225:                                  creds.realm, pw->pw_name);
        !           226:                memset(&creds, 0, sizeof(creds));
        !           227:                packet_start(SSH_SMSG_FAILURE);
        !           228:                packet_send();
        !           229:                packet_write_wait();
        !           230:                return 0;
        !           231:        }
        !           232:        packet_send_debug("AFS token accepted (%s@%s, %s@%s)", creds.service,
        !           233:                          creds.realm, creds.pname, creds.realm);
        !           234:        memset(&creds, 0, sizeof(creds));
        !           235:        packet_start(SSH_SMSG_SUCCESS);
        !           236:        packet_send();
        !           237:        packet_write_wait();
        !           238:        return 1;
1.1       deraadt   239: }
                    240: #endif /* AFS */