version 1.1, 1999/09/26 20:53:33 |
version 1.2, 1999/09/29 18:16:18 |
|
|
|
|
auth-kerberos.c |
auth-kerberos.c |
|
|
Hacked together by Dug Song <dugsong@umich.edu>. |
Dug Song <dugsong@UMICH.EDU> |
|
|
Kerberos authentication and ticket-passing routines. |
Kerberos v4 authentication and ticket-passing routines. |
|
|
|
$Id$ |
*/ |
*/ |
|
|
#include "includes.h" |
#include "includes.h" |
|
|
#include "ssh.h" |
#include "ssh.h" |
|
|
#ifdef KRB4 |
#ifdef KRB4 |
#include <sys/param.h> |
|
#include <krb.h> |
|
|
|
int ssh_tf_init(uid_t uid) |
int ssh_tf_init(uid_t uid) |
{ |
{ |
extern char *ticket; |
extern char *ticket; |
char *tkt_root = TKT_ROOT; |
char *tkt_root = TKT_ROOT; |
struct stat st; |
struct stat st; |
int fd; |
int fd; |
|
|
/* Set unique ticket string manually since we're still root. */ |
/* Set unique ticket string manually since we're still root. */ |
ticket = xmalloc(MAXPATHLEN); |
ticket = xmalloc(MAXPATHLEN); |
#ifdef AFS |
#ifdef AFS |
if (lstat("/ticket", &st) != -1) |
if (lstat("/ticket", &st) != -1) |
tkt_root = "/ticket/"; |
tkt_root = "/ticket/"; |
#endif /* AFS */ |
#endif /* AFS */ |
sprintf(ticket, "%.100s%d_%d", tkt_root, uid, getpid()); |
snprintf(ticket, MAXPATHLEN, "%s%d_%d", tkt_root, uid, getpid()); |
(void) krb_set_tkt_string(ticket); |
(void) krb_set_tkt_string(ticket); |
|
|
/* Make sure we own this ticket file, and we created it. */ |
/* Make sure we own this ticket file, and we created it. */ |
if (lstat(ticket, &st) < 0 && errno == ENOENT) { |
if (lstat(ticket, &st) == -1 && errno == ENOENT) { |
/* good, no ticket file exists. create it. */ |
/* good, no ticket file exists. create it. */ |
if ((fd = open(ticket, O_RDWR|O_CREAT|O_EXCL, 0600)) != -1) { |
if ((fd = open(ticket, O_RDWR|O_CREAT|O_EXCL, 0600)) != -1) { |
close(fd); |
close(fd); |
|
|
return 1; |
return 1; |
} |
} |
/* Failure. */ |
/* Failure. */ |
log("WARNING: bad ticket file %.100s", ticket); |
log("WARNING: bad ticket file %s", ticket); |
return 0; |
return 0; |
} |
} |
|
|
|
|
instance[0] = '*'; instance[1] = 0; |
instance[0] = '*'; instance[1] = 0; |
|
|
/* Get the encrypted request, challenge, and session key. */ |
/* Get the encrypted request, challenge, and session key. */ |
r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance, 0, &adat, ""); |
if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance, 0, &adat, ""))) { |
if (r != KSUCCESS) { |
|
packet_send_debug("Kerberos V4 krb_rd_req: %.100s", krb_err_txt[r]); |
packet_send_debug("Kerberos V4 krb_rd_req: %.100s", krb_err_txt[r]); |
return 0; |
return 0; |
} |
} |
des_key_sched((des_cblock *)adat.session, schedule); |
des_key_sched((des_cblock *)adat.session, schedule); |
|
|
*client = xmalloc(MAX_K_NAME_SZ); |
*client = xmalloc(MAX_K_NAME_SZ); |
sprintf(*client, "%.100s%.100s%.100s@%.100s", adat.pname, *adat.pinst ? "." : "", |
(void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname, |
adat.pinst, adat.prealm); |
*adat.pinst ? "." : "", adat.pinst, adat.prealm); |
|
|
/* Check ~/.klogin authorization now. */ |
/* Check ~/.klogin authorization now. */ |
if (kuserok(&adat, (char *)server_user) != KSUCCESS) { |
if (kuserok(&adat, (char *)server_user) != KSUCCESS) { |
packet_send_debug("Kerberos V4 .klogin authorization failed!"); |
packet_send_debug("Kerberos V4 .klogin authorization failed!"); |
log("Kerberos V4 .klogin authorization failed for %.100s to account %.100s", |
log("Kerberos V4 .klogin authorization failed for %s to account %s", |
*client, server_user); |
*client, server_user); |
return 0; |
return 0; |
} |
} |
|
|
message, admitting our failure. */ |
message, admitting our failure. */ |
if ((r = krb_mk_priv((u_char *)&cksum, reply.dat, sizeof(cksum)+1, |
if ((r = krb_mk_priv((u_char *)&cksum, reply.dat, sizeof(cksum)+1, |
schedule, &adat.session, &local, &foreign)) < 0) { |
schedule, &adat.session, &local, &foreign)) < 0) { |
packet_send_debug("Kerberos V4 mk_priv: (%d) %.100s", r, krb_err_txt[r]); |
packet_send_debug("Kerberos V4 mk_priv: (%d) %s", r, krb_err_txt[r]); |
reply.dat[0] = 0; |
reply.dat[0] = 0; |
reply.length = 0; |
reply.length = 0; |
} |
} |
|
|
#endif /* KRB4 */ |
#endif /* KRB4 */ |
|
|
#ifdef AFS |
#ifdef AFS |
#include <kafs.h> |
|
|
|
|
|
#ifdef KERBEROS_TGT_PASSING |
|
|
|
int auth_kerberos_tgt(struct passwd *pw, const char *string) |
int auth_kerberos_tgt(struct passwd *pw, const char *string) |
{ |
{ |
CREDENTIALS creds; |
CREDENTIALS creds; |
|
|
strcpy(creds.service, "krbtgt"); |
strcpy(creds.service, "krbtgt"); |
|
|
if (strcmp(creds.service, "krbtgt")) { |
if (strcmp(creds.service, "krbtgt")) { |
log("Kerberos V4 tgt (%.100s%.100s%.100s@%.100s) rejected for uid %d", |
log("Kerberos V4 tgt (%s%s%s@%s) rejected for uid %d", |
creds.pname, creds.pinst[0] ? "." : "", creds.pinst, creds.realm, |
creds.pname, creds.pinst[0] ? "." : "", creds.pinst, creds.realm, |
pw->pw_uid); |
pw->pw_uid); |
packet_send_debug("Kerberos V4 tgt (%.100s%.100s%.100s@%.100s) rejected for uid %d", |
packet_send_debug("Kerberos V4 tgt (%s%s%s@%s) rejected for uid %d", |
creds.pname, creds.pinst[0] ? "." : "", creds.pinst, |
creds.pname, creds.pinst[0] ? "." : "", creds.pinst, |
creds.realm, pw->pw_uid); |
creds.realm, pw->pw_uid); |
goto auth_kerberos_tgt_failure; |
goto auth_kerberos_tgt_failure; |
} |
} |
if (!ssh_tf_init(pw->pw_uid) || |
if (!ssh_tf_init(pw->pw_uid) || |
(r = in_tkt(creds.pname, creds.pinst)) || |
(r = in_tkt(creds.pname, creds.pinst)) || |
(r = save_credentials(creds.service,creds.instance,creds.realm, |
(r = save_credentials(creds.service, creds.instance, creds.realm, |
creds.session,creds.lifetime,creds.kvno, |
creds.session, creds.lifetime, creds.kvno, |
&creds.ticket_st,creds.issue_date))) { |
&creds.ticket_st, creds.issue_date))) { |
xfree(ticket); |
xfree(ticket); |
ticket = NULL; |
ticket = NULL; |
packet_send_debug("Kerberos V4 tgt refused: couldn't save credentials"); |
packet_send_debug("Kerberos V4 tgt refused: couldn't save credentials"); |
|
|
} |
} |
/* Successful authentication, passed all checks. */ |
/* Successful authentication, passed all checks. */ |
chown(ticket, pw->pw_uid, pw->pw_gid); |
chown(ticket, pw->pw_uid, pw->pw_gid); |
packet_send_debug("Kerberos V4 ticket accepted (%.100s.%.100s@%.100s, %.100s%.100s%.100s@%.100s)", |
packet_send_debug("Kerberos V4 tgt accepted (%s.%s@%s, %s%s%s@%s)", |
creds.service, creds.instance, creds.realm, |
creds.service, creds.instance, creds.realm, |
creds.pname, creds.pinst[0] ? "." : "", |
creds.pname, creds.pinst[0] ? "." : "", |
creds.pinst, creds.realm); |
creds.pinst, creds.realm); |
|
|
packet_write_wait(); |
packet_write_wait(); |
return 0; |
return 0; |
} |
} |
#endif /* KERBEROS_TGT_PASSING */ |
|
|
|
int auth_afs_token(char *server_user, uid_t uid, const char *string) |
int auth_afs_token(char *server_user, uid_t uid, const char *string) |
{ |
{ |
|
|
uid = atoi(creds.pname + 7); |
uid = atoi(creds.pname + 7); |
|
|
if (kafs_settoken(creds.realm, uid, &creds)) { |
if (kafs_settoken(creds.realm, uid, &creds)) { |
log("AFS token (%.100s@%.100s) rejected for uid %d", |
log("AFS token (%s@%s) rejected for uid %d", creds.pname, |
creds.pname, creds.realm, uid); |
creds.realm, uid); |
packet_send_debug("AFS token (%.100s@%.100s) rejected for uid %d", creds.pname, |
packet_send_debug("AFS token (%s@%s) rejected for uid %d", creds.pname, |
creds.realm, uid); |
creds.realm, uid); |
packet_start(SSH_SMSG_FAILURE); |
packet_start(SSH_SMSG_FAILURE); |
packet_send(); |
packet_send(); |
packet_write_wait(); |
packet_write_wait(); |
return 0; |
return 0; |
} |
} |
packet_send_debug("AFS token accepted (%.100s@%.100s, %.100s@%.100s)", creds.service, |
packet_send_debug("AFS token accepted (%s@%s, %s@%s)", creds.service, |
creds.realm, creds.pname, creds.realm); |
creds.realm, creds.pname, creds.realm); |
packet_start(SSH_SMSG_SUCCESS); |
packet_start(SSH_SMSG_SUCCESS); |
packet_send(); |
packet_send(); |