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

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