version 1.1, 1999/09/26 20:53:33 |
version 1.2, 1999/09/29 18:16:19 |
|
|
#endif /* HAVE_SECURID */ |
#endif /* HAVE_SECURID */ |
|
|
#ifdef KRB4 |
#ifdef KRB4 |
#include <sys/param.h> |
|
#include <krb.h> |
|
extern char *ticket; |
extern char *ticket; |
#endif /* KRB4 */ |
#endif /* KRB4 */ |
|
|
|
|
if (!pw) |
if (!pw) |
return 0; |
return 0; |
|
|
|
#if defined(KRB4) |
|
/* Support for Kerberos v4 authentication - Dug Song <dugsong@UMICH.EDU> */ |
|
if (options.kerberos_authentication) |
|
{ |
|
AUTH_DAT adata; |
|
KTEXT_ST tkt; |
|
struct hostent *hp; |
|
unsigned long faddr; |
|
char localhost[MAXHOSTNAMELEN]; /* local host name */ |
|
char phost[INST_SZ]; /* host instance */ |
|
char realm[REALM_SZ]; /* local Kerberos realm */ |
|
int r; |
|
|
|
/* Try Kerberos password authentication only for non-root |
|
users and only if Kerberos is installed. */ |
|
if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) { |
|
|
|
/* Set up our ticket file. */ |
|
if (!ssh_tf_init(pw->pw_uid)) { |
|
log("Couldn't initialize Kerberos ticket file for %s!", |
|
server_user); |
|
goto kerberos_auth_failure; |
|
} |
|
/* Try to get TGT using our password. */ |
|
r = krb_get_pw_in_tkt((char *)server_user, "", realm, "krbtgt", realm, |
|
DEFAULT_TKT_LIFE, (char *)password); |
|
if (r != INTK_OK) { |
|
packet_send_debug("Kerberos V4 password authentication for %s " |
|
"failed: %s", server_user, krb_err_txt[r]); |
|
goto kerberos_auth_failure; |
|
} |
|
/* Successful authentication. */ |
|
chown(ticket, pw->pw_uid, pw->pw_gid); |
|
|
|
(void) gethostname(localhost, sizeof(localhost)); |
|
(void) strncpy(phost, (char *)krb_get_phost(localhost), INST_SZ); |
|
phost[INST_SZ-1] = 0; |
|
|
|
/* Now that we have a TGT, try to get a local "rcmd" ticket to |
|
ensure that we are not talking to a bogus Kerberos server. */ |
|
r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33); |
|
|
|
if (r == KSUCCESS) { |
|
if (!(hp = gethostbyname(localhost))) { |
|
log("Couldn't get local host address!"); |
|
goto kerberos_auth_failure; |
|
} |
|
memmove((void *)&faddr, (void *)hp->h_addr, sizeof(faddr)); |
|
|
|
/* Verify our "rcmd" ticket. */ |
|
r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost, faddr, &adata, ""); |
|
if (r == RD_AP_UNDEC) { |
|
/* Probably didn't have a srvtab on localhost. Allow login. */ |
|
log("Kerberos V4 TGT for %s unverifiable, no srvtab installed? " |
|
"krb_rd_req: %s", server_user, krb_err_txt[r]); |
|
} |
|
else if (r != KSUCCESS) { |
|
log("Kerberos V4 %s ticket unverifiable: %s", |
|
KRB4_SERVICE_NAME, krb_err_txt[r]); |
|
goto kerberos_auth_failure; |
|
} |
|
} |
|
else if (r == KDC_PR_UNKNOWN) { |
|
/* Allow login if no rcmd service exists, but log the error. */ |
|
log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s " |
|
"not registered, or srvtab is wrong?", server_user, |
|
krb_err_txt[r], KRB4_SERVICE_NAME, phost); |
|
} |
|
else { |
|
/* TGT is bad, forget it. Possibly spoofed! */ |
|
packet_send_debug("WARNING: Kerberos V4 TGT possibly spoofed for" |
|
"%s: %s", server_user, krb_err_txt[r]); |
|
goto kerberos_auth_failure; |
|
} |
|
|
|
/* Authentication succeeded. */ |
|
return 1; |
|
|
|
kerberos_auth_failure: |
|
(void) dest_tkt(); |
|
xfree(ticket); |
|
ticket = NULL; |
|
if (!options.kerberos_or_local_passwd ) return 0; |
|
} |
|
else { |
|
/* Logging in as root or no local Kerberos realm. */ |
|
packet_send_debug("Unable to authenticate to Kerberos."); |
|
} |
|
/* Fall back to ordinary passwd authentication. */ |
|
} |
|
#endif /* KRB4 */ |
|
|
#ifdef HAVE_SECURID |
#ifdef HAVE_SECURID |
/* Support for Security Dynamics SecurId card. |
/* Support for Security Dynamics SecurId card. |
Contributed by Donald McKillican <dmckilli@qc.bell.ca>. */ |
Contributed by Donald McKillican <dmckilli@qc.bell.ca>. */ |
#if defined(KRB4) |
|
if (options.kerberos_or_local_passwd) |
|
#endif /* KRB4 */ |
|
{ |
{ |
/* |
/* |
* the way we decide if this user is a securid user or not is |
* the way we decide if this user is a securid user or not is |
|
|
#endif /* HAVE_OSF1_C2_SECURITY */ |
#endif /* HAVE_OSF1_C2_SECURITY */ |
|
|
/* Check for users with no password. */ |
/* Check for users with no password. */ |
#if defined(KRB4) |
|
if (options.kerberos_or_local_passwd) |
|
#endif /* KRB4 */ |
|
if (strcmp(password, "") == 0 && strcmp(correct_passwd, "") == 0) |
if (strcmp(password, "") == 0 && strcmp(correct_passwd, "") == 0) |
{ |
{ |
packet_send_debug("Login permitted without a password because the account has no password."); |
packet_send_debug("Login permitted without a password because the account has no password."); |
|
|
#endif /* HAVE_OSF1_C2_SECURITY */ |
#endif /* HAVE_OSF1_C2_SECURITY */ |
|
|
/* Authentication is accepted if the encrypted passwords are identical. */ |
/* Authentication is accepted if the encrypted passwords are identical. */ |
#if defined(KRB4) |
return (strcmp(encrypted_password, correct_passwd) == 0); |
if (options.kerberos_or_local_passwd) |
|
#endif /* KRB4 */ |
|
if (strcmp(encrypted_password, correct_passwd) == 0) |
|
return 1; /* Success */ |
|
|
|
#if defined(KRB4) |
|
if (options.kerberos_authentication) |
|
{ |
|
AUTH_DAT adata; |
|
KTEXT_ST tkt; |
|
struct hostent *hp; |
|
unsigned long faddr; |
|
char localhost[MAXHOSTNAMELEN]; /* local host name */ |
|
char phost[INST_SZ]; /* host instance */ |
|
char realm[REALM_SZ]; /* local Kerberos realm */ |
|
int r; |
|
|
|
/* Try Kerberos password authentication only for non-root |
|
users and only if Kerberos is installed. */ |
|
if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) { |
|
|
|
/* Set up our ticket file. */ |
|
if (!ssh_tf_init(pw->pw_uid)) { |
|
log("Couldn't initialize Kerberos ticket file for %.100s!", |
|
server_user); |
|
goto kerberos_auth_failure; |
|
} |
|
/* Try to get TGT using our password. */ |
|
r = krb_get_pw_in_tkt(server_user, "", realm, "krbtgt", realm, |
|
DEFAULT_TKT_LIFE, password); |
|
if (r != INTK_OK) { |
|
packet_send_debug("Kerberos V4 password authentication for %.100s " |
|
"failed: %.100s", server_user, krb_err_txt[r]); |
|
goto kerberos_auth_failure; |
|
} |
|
/* Successful authentication. */ |
|
chown(ticket, pw->pw_uid, pw->pw_gid); |
|
|
|
(void) gethostname(localhost, sizeof(localhost)); |
|
(void) strncpy(phost, (char *)krb_get_phost(localhost), INST_SZ); |
|
phost[INST_SZ-1] = 0; |
|
|
|
/* Now that we have a TGT, try to get a local "rcmd" ticket to |
|
ensure that we are not talking to a bogus Kerberos server. */ |
|
r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33); |
|
|
|
if (r == KSUCCESS) { |
|
if (!(hp = gethostbyname(localhost))) { |
|
log("Couldn't get local host address!"); |
|
goto kerberos_auth_failure; |
|
} |
|
memmove((void *)&faddr, (void *)hp->h_addr, sizeof(faddr)); |
|
|
|
/* Verify our "rcmd" ticket. */ |
|
r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost, faddr, &adata, ""); |
|
if (r == RD_AP_UNDEC) { |
|
/* Probably didn't have a srvtab on localhost. Allow login. */ |
|
log("Kerberos V4 TGT for %.100s unverifiable, no srvtab? " |
|
"krb_rd_req: %.100s", server_user, krb_err_txt[r]); |
|
} |
|
else if (r != KSUCCESS) { |
|
log("Kerberos V4 %.100s ticket unverifiable: %.100s", |
|
KRB4_SERVICE_NAME, krb_err_txt[r]); |
|
goto kerberos_auth_failure; |
|
} |
|
} |
|
else if (r == KDC_PR_UNKNOWN) { |
|
/* Allow login if no rcmd service exists, but log the error. */ |
|
log("Kerberos V4 TGT for %.100s unverifiable: %.100s; %.100s.%.100s " |
|
"not registered, or srvtab is wrong?", server_user, |
|
krb_err_txt[r], KRB4_SERVICE_NAME, phost); |
|
} |
|
else { |
|
/* TGT is bad, forget it. Possibly spoofed. */ |
|
packet_send_debug("WARNING: Kerberos V4 TGT possibly spoofed for" |
|
"%.100s: %.100s", server_user, krb_err_txt[r]); |
|
goto kerberos_auth_failure; |
|
} |
|
|
|
/* Authentication succeeded. */ |
|
return 1; |
|
|
|
kerberos_auth_failure: |
|
(void) dest_tkt(); |
|
xfree(ticket); |
|
ticket = NULL; |
|
if (!options.kerberos_or_local_passwd ) return 0; |
|
} |
|
else /* Logging in as root or no local Kerberos realm. */ |
|
packet_send_debug("Unable to authenticate to Kerberos."); |
|
|
|
/* Fall back to ordinary passwd authentication. */ |
|
} |
|
#endif /* KRB4 */ |
|
|
|
return 0; /* Fail */ |
|
} |
} |