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

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