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

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.7     ! markus      9:    $Id: auth-krb4.c,v 1.6 1999/11/10 22:24:01 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);
1.7     ! markus    113:     xfree(*client);
1.1       deraadt   114:     return 0;
                    115:   }
                    116:   /* Increment the checksum, and return it encrypted with the session key. */
                    117:   cksum = adat.checksum + 1;
                    118:   cksum = htonl(cksum);
                    119:
                    120:   /* If we can't successfully encrypt the checksum, we send back an empty
                    121:      message, admitting our failure. */
                    122:   if ((r = krb_mk_priv((u_char *)&cksum, reply.dat, sizeof(cksum)+1,
                    123:                       schedule, &adat.session, &local, &foreign)) < 0) {
1.2       dugsong   124:     packet_send_debug("Kerberos V4 mk_priv: (%d) %s", r, krb_err_txt[r]);
1.1       deraadt   125:     reply.dat[0] = 0;
                    126:     reply.length = 0;
                    127:   }
1.6       markus    128:   else reply.length = r;
1.1       deraadt   129:
                    130:   /* Clear session key. */
                    131:   memset(&adat.session, 0, sizeof(&adat.session));
                    132:
                    133:   packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE);
                    134:   packet_put_string((char *) reply.dat, reply.length);
                    135:   packet_send();
                    136:   packet_write_wait();
                    137:   return 1;
                    138: }
                    139: #endif /* KRB4 */
                    140:
                    141: #ifdef AFS
                    142: int auth_kerberos_tgt(struct passwd *pw, const char *string)
                    143: {
                    144:   CREDENTIALS creds;
                    145:
                    146:   if (!radix_to_creds(string, &creds)) {
                    147:     log("Protocol error decoding Kerberos V4 tgt");
                    148:     packet_send_debug("Protocol error decoding Kerberos V4 tgt");
                    149:     goto auth_kerberos_tgt_failure;
                    150:   }
                    151:   if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */
1.3       deraadt   152:     strlcpy(creds.service, "krbtgt", sizeof creds.service);
1.1       deraadt   153:
                    154:   if (strcmp(creds.service, "krbtgt")) {
1.6       markus    155:     log("Kerberos V4 tgt (%s%s%s@%s) rejected for %s", creds.pname,
                    156:        creds.pinst[0] ? "." : "", creds.pinst, creds.realm, pw->pw_name);
                    157:     packet_send_debug("Kerberos V4 tgt (%s%s%s@%s) rejected for %s",
1.1       deraadt   158:                      creds.pname, creds.pinst[0] ? "." : "", creds.pinst,
1.6       markus    159:                      creds.realm, pw->pw_name);
1.1       deraadt   160:     goto auth_kerberos_tgt_failure;
                    161:   }
1.6       markus    162:   if (!krb4_init(pw->pw_uid))
                    163:     goto auth_kerberos_tgt_failure;
                    164:
                    165:   if (in_tkt(creds.pname, creds.pinst) != KSUCCESS)
                    166:     goto auth_kerberos_tgt_failure;
                    167:
                    168:   if (save_credentials(creds.service, creds.instance, creds.realm,
                    169:                       creds.session, creds.lifetime, creds.kvno,
                    170:                       &creds.ticket_st, creds.issue_date) != KSUCCESS) {
1.1       deraadt   171:     packet_send_debug("Kerberos V4 tgt refused: couldn't save credentials");
                    172:     goto auth_kerberos_tgt_failure;
                    173:   }
                    174:   /* Successful authentication, passed all checks. */
1.6       markus    175:   chown(tkt_string(), pw->pw_uid, pw->pw_gid);
                    176:
1.2       dugsong   177:   packet_send_debug("Kerberos V4 tgt accepted (%s.%s@%s, %s%s%s@%s)",
1.6       markus    178:                    creds.service, creds.instance, creds.realm, creds.pname,
                    179:                    creds.pinst[0] ? "." : "", creds.pinst, creds.realm);
                    180:   memset(&creds, 0, sizeof(creds));
1.1       deraadt   181:   packet_start(SSH_SMSG_SUCCESS);
                    182:   packet_send();
                    183:   packet_write_wait();
                    184:   return 1;
1.6       markus    185:
                    186:  auth_kerberos_tgt_failure:
                    187:   krb4_cleanup_proc(NULL);
1.1       deraadt   188:   memset(&creds, 0, sizeof(creds));
                    189:   packet_start(SSH_SMSG_FAILURE);
                    190:   packet_send();
                    191:   packet_write_wait();
                    192:   return 0;
                    193: }
                    194:
1.5       markus    195: int auth_afs_token(struct passwd *pw, const char *token_string)
1.1       deraadt   196: {
                    197:   CREDENTIALS creds;
1.5       markus    198:   uid_t uid = pw->pw_uid;
1.1       deraadt   199:
1.5       markus    200:   if (!radix_to_creds(token_string, &creds)) {
1.1       deraadt   201:     log("Protocol error decoding AFS token");
                    202:     packet_send_debug("Protocol error decoding AFS token");
                    203:     packet_start(SSH_SMSG_FAILURE);
                    204:     packet_send();
                    205:     packet_write_wait();
                    206:     return 0;
                    207:   }
                    208:   if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */
1.3       deraadt   209:     strlcpy(creds.service, "afs", sizeof creds.service);
1.1       deraadt   210:
                    211:   if (strncmp(creds.pname, "AFS ID ", 7) == 0)
                    212:     uid = atoi(creds.pname + 7);
                    213:
                    214:   if (kafs_settoken(creds.realm, uid, &creds)) {
1.6       markus    215:     log("AFS token (%s@%s) rejected for %s", creds.pname, creds.realm,
                    216:        pw->pw_name);
                    217:     packet_send_debug("AFS token (%s@%s) rejected for %s", creds.pname,
                    218:                      creds.realm, pw->pw_name);
                    219:     memset(&creds, 0, sizeof(creds));
1.1       deraadt   220:     packet_start(SSH_SMSG_FAILURE);
                    221:     packet_send();
                    222:     packet_write_wait();
                    223:     return 0;
                    224:   }
1.2       dugsong   225:   packet_send_debug("AFS token accepted (%s@%s, %s@%s)", creds.service,
1.1       deraadt   226:                    creds.realm, creds.pname, creds.realm);
1.6       markus    227:   memset(&creds, 0, sizeof(creds));
1.1       deraadt   228:   packet_start(SSH_SMSG_SUCCESS);
                    229:   packet_send();
                    230:   packet_write_wait();
                    231:   return 1;
                    232: }
                    233: #endif /* AFS */