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

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.3     ! deraadt     9:    $Id: auth-krb4.c,v 1.2 1999/09/29 18:16:18 dugsong 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
                     18: int ssh_tf_init(uid_t uid)
                     19: {
                     20:   extern char *ticket;
                     21:   char *tkt_root = TKT_ROOT;
                     22:   struct stat st;
                     23:   int fd;
1.2       dugsong    24:
1.1       deraadt    25:   /* Set unique ticket string manually since we're still root. */
                     26:   ticket = xmalloc(MAXPATHLEN);
                     27: #ifdef AFS
                     28:   if (lstat("/ticket", &st) != -1)
                     29:     tkt_root = "/ticket/";
                     30: #endif /* AFS */
1.2       dugsong    31:   snprintf(ticket, MAXPATHLEN, "%s%d_%d", tkt_root, uid, getpid());
1.1       deraadt    32:   (void) krb_set_tkt_string(ticket);
                     33:
                     34:   /* Make sure we own this ticket file, and we created it. */
1.2       dugsong    35:   if (lstat(ticket, &st) == -1 && errno == ENOENT) {
1.1       deraadt    36:     /* good, no ticket file exists. create it. */
                     37:     if ((fd = open(ticket, O_RDWR|O_CREAT|O_EXCL, 0600)) != -1) {
                     38:       close(fd);
                     39:       return 1;
                     40:     }
                     41:   }
                     42:   else {
                     43:     /* file exists. make sure server_user owns it (e.g. just passed ticket),
                     44:        and that it isn't a symlink, and that it is mode 600. */
                     45:     if (st.st_mode == (S_IFREG|S_IRUSR|S_IWUSR) && st.st_uid == uid)
                     46:       return 1;
                     47:   }
                     48:   /* Failure. */
1.2       dugsong    49:   log("WARNING: bad ticket file %s", ticket);
1.1       deraadt    50:   return 0;
                     51: }
                     52:
                     53: int auth_krb4(const char *server_user, KTEXT auth, char **client)
                     54: {
                     55:   AUTH_DAT adat   = { 0 };
                     56:   KTEXT_ST reply;
                     57:   char instance[INST_SZ];
                     58:   int r, s;
                     59:   u_long cksum;
                     60:   Key_schedule schedule;
                     61:   struct sockaddr_in local, foreign;
                     62:
                     63:   s = packet_get_connection_in();
                     64:
                     65:   r = sizeof(local);
                     66:   memset(&local, 0, sizeof(local));
                     67:   if (getsockname(s, (struct sockaddr *) &local, &r) < 0)
                     68:     debug("getsockname failed: %.100s", strerror(errno));
                     69:   r = sizeof(foreign);
                     70:   memset(&foreign, 0, sizeof(foreign));
                     71:   if (getpeername(s, (struct sockaddr *)&foreign, &r) < 0)
                     72:     debug("getpeername failed: %.100s", strerror(errno));
                     73:
                     74:   instance[0] = '*'; instance[1] = 0;
                     75:
                     76:   /* Get the encrypted request, challenge, and session key. */
1.2       dugsong    77:   if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance, 0, &adat, ""))) {
1.1       deraadt    78:     packet_send_debug("Kerberos V4 krb_rd_req: %.100s", krb_err_txt[r]);
                     79:     return 0;
                     80:   }
                     81:   des_key_sched((des_cblock *)adat.session, schedule);
                     82:
                     83:   *client = xmalloc(MAX_K_NAME_SZ);
1.2       dugsong    84:   (void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname,
                     85:                   *adat.pinst ? "." : "", adat.pinst, adat.prealm);
1.1       deraadt    86:
                     87:   /* Check ~/.klogin authorization now. */
                     88:   if (kuserok(&adat, (char *)server_user) != KSUCCESS) {
                     89:     packet_send_debug("Kerberos V4 .klogin authorization failed!");
1.2       dugsong    90:     log("Kerberos V4 .klogin authorization failed for %s to account %s",
1.1       deraadt    91:        *client, server_user);
                     92:     return 0;
                     93:   }
                     94:   /* Increment the checksum, and return it encrypted with the session key. */
                     95:   cksum = adat.checksum + 1;
                     96:   cksum = htonl(cksum);
                     97:
                     98:   /* If we can't successfully encrypt the checksum, we send back an empty
                     99:      message, admitting our failure. */
                    100:   if ((r = krb_mk_priv((u_char *)&cksum, reply.dat, sizeof(cksum)+1,
                    101:                       schedule, &adat.session, &local, &foreign)) < 0) {
1.2       dugsong   102:     packet_send_debug("Kerberos V4 mk_priv: (%d) %s", r, krb_err_txt[r]);
1.1       deraadt   103:     reply.dat[0] = 0;
                    104:     reply.length = 0;
                    105:   }
                    106:   else
                    107:     reply.length = r;
                    108:
                    109:   /* Clear session key. */
                    110:   memset(&adat.session, 0, sizeof(&adat.session));
                    111:
                    112:   packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE);
                    113:   packet_put_string((char *) reply.dat, reply.length);
                    114:   packet_send();
                    115:   packet_write_wait();
                    116:   return 1;
                    117: }
                    118: #endif /* KRB4 */
                    119:
                    120: #ifdef AFS
                    121: int auth_kerberos_tgt(struct passwd *pw, const char *string)
                    122: {
                    123:   CREDENTIALS creds;
                    124:   extern char *ticket;
                    125:   int r;
                    126:
                    127:   if (!radix_to_creds(string, &creds)) {
                    128:     log("Protocol error decoding Kerberos V4 tgt");
                    129:     packet_send_debug("Protocol error decoding Kerberos V4 tgt");
                    130:     goto auth_kerberos_tgt_failure;
                    131:   }
                    132:   if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */
1.3     ! deraadt   133:     strlcpy(creds.service, "krbtgt", sizeof creds.service);
1.1       deraadt   134:
                    135:   if (strcmp(creds.service, "krbtgt")) {
1.2       dugsong   136:     log("Kerberos V4 tgt (%s%s%s@%s) rejected for uid %d",
1.1       deraadt   137:        creds.pname, creds.pinst[0] ? "." : "", creds.pinst, creds.realm,
                    138:        pw->pw_uid);
1.2       dugsong   139:     packet_send_debug("Kerberos V4 tgt (%s%s%s@%s) rejected for uid %d",
1.1       deraadt   140:                      creds.pname, creds.pinst[0] ? "." : "", creds.pinst,
                    141:                      creds.realm, pw->pw_uid);
                    142:     goto auth_kerberos_tgt_failure;
                    143:   }
                    144:   if (!ssh_tf_init(pw->pw_uid) ||
                    145:       (r = in_tkt(creds.pname, creds.pinst)) ||
1.2       dugsong   146:       (r = save_credentials(creds.service, creds.instance, creds.realm,
                    147:                            creds.session, creds.lifetime, creds.kvno,
                    148:                            &creds.ticket_st, creds.issue_date))) {
1.1       deraadt   149:     xfree(ticket);
                    150:     ticket = NULL;
                    151:     packet_send_debug("Kerberos V4 tgt refused: couldn't save credentials");
                    152:     goto auth_kerberos_tgt_failure;
                    153:   }
                    154:   /* Successful authentication, passed all checks. */
                    155:   chown(ticket, pw->pw_uid, pw->pw_gid);
1.2       dugsong   156:   packet_send_debug("Kerberos V4 tgt accepted (%s.%s@%s, %s%s%s@%s)",
1.1       deraadt   157:                    creds.service, creds.instance, creds.realm,
                    158:                    creds.pname, creds.pinst[0] ? "." : "",
                    159:                    creds.pinst, creds.realm);
                    160:
                    161:   packet_start(SSH_SMSG_SUCCESS);
                    162:   packet_send();
                    163:   packet_write_wait();
                    164:   return 1;
                    165:
                    166: auth_kerberos_tgt_failure:
                    167:   memset(&creds, 0, sizeof(creds));
                    168:   packet_start(SSH_SMSG_FAILURE);
                    169:   packet_send();
                    170:   packet_write_wait();
                    171:   return 0;
                    172: }
                    173:
                    174: int auth_afs_token(char *server_user, uid_t uid, const char *string)
                    175: {
                    176:   CREDENTIALS creds;
                    177:
                    178:   if (!radix_to_creds(string, &creds)) {
                    179:     log("Protocol error decoding AFS token");
                    180:     packet_send_debug("Protocol error decoding AFS token");
                    181:     packet_start(SSH_SMSG_FAILURE);
                    182:     packet_send();
                    183:     packet_write_wait();
                    184:     return 0;
                    185:   }
                    186:   if (strncmp(creds.service, "", 1) == 0) /* backward compatibility */
1.3     ! deraadt   187:     strlcpy(creds.service, "afs", sizeof creds.service);
1.1       deraadt   188:
                    189:   if (strncmp(creds.pname, "AFS ID ", 7) == 0)
                    190:     uid = atoi(creds.pname + 7);
                    191:
                    192:   if (kafs_settoken(creds.realm, uid, &creds)) {
1.2       dugsong   193:     log("AFS token (%s@%s) rejected for uid %d", creds.pname,
                    194:        creds.realm, uid);
                    195:     packet_send_debug("AFS token (%s@%s) rejected for uid %d", creds.pname,
1.1       deraadt   196:                      creds.realm, uid);
                    197:     packet_start(SSH_SMSG_FAILURE);
                    198:     packet_send();
                    199:     packet_write_wait();
                    200:     return 0;
                    201:   }
1.2       dugsong   202:   packet_send_debug("AFS token accepted (%s@%s, %s@%s)", creds.service,
1.1       deraadt   203:                    creds.realm, creds.pname, creds.realm);
                    204:   packet_start(SSH_SMSG_SUCCESS);
                    205:   packet_send();
                    206:   packet_write_wait();
                    207:   return 1;
                    208: }
                    209: #endif /* AFS */