summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authormarkm <markm@FreeBSD.org>2000-02-28 19:03:50 +0000
committermarkm <markm@FreeBSD.org>2000-02-28 19:03:50 +0000
commit37dce23afc624dfc2ebae4614ddd17d5e376a901 (patch)
tree08c26b6a05650dd5c73e020a82c50440e973043e /crypto
parent39a8b7149f0ab399cdd6a6d5f254c70ba2cf6fa6 (diff)
downloadFreeBSD-src-37dce23afc624dfc2ebae4614ddd17d5e376a901.zip
FreeBSD-src-37dce23afc624dfc2ebae4614ddd17d5e376a901.tar.gz
1) Add kerberos5 functionality.
by Daniel Kouril <kouril@informatics.muni.cz> 2) Add full LOGIN_CAP capability by Andrey Chernov
Diffstat (limited to 'crypto')
-rw-r--r--crypto/openssh/auth-krb4.c8
-rw-r--r--crypto/openssh/auth-krb5.c249
-rw-r--r--crypto/openssh/auth-passwd.c12
-rw-r--r--crypto/openssh/readconf.c55
-rw-r--r--crypto/openssh/readconf.h11
-rw-r--r--crypto/openssh/servconf.c89
-rw-r--r--crypto/openssh/servconf.h13
-rw-r--r--crypto/openssh/ssh.c3
-rw-r--r--crypto/openssh/ssh.h28
-rw-r--r--crypto/openssh/sshconnect.c298
-rw-r--r--crypto/openssh/sshd.816
-rw-r--r--crypto/openssh/sshd.c430
12 files changed, 1041 insertions, 171 deletions
diff --git a/crypto/openssh/auth-krb4.c b/crypto/openssh/auth-krb4.c
index fb0e20c..8c308bd 100644
--- a/crypto/openssh/auth-krb4.c
+++ b/crypto/openssh/auth-krb4.c
@@ -1,6 +1,8 @@
/*
* Dug Song <dugsong@UMICH.EDU>
* Kerberos v4 authentication and ticket-passing routines.
+ *
+ * $FreeBSD$
*/
#include "includes.h"
@@ -114,7 +116,7 @@ auth_krb4_password(struct passwd * pw, const char *password)
kerberos_auth_failure:
krb4_cleanup_proc(NULL);
- if (!options.kerberos_or_local_passwd)
+ if (!options.krb4_or_local_passwd)
return 0;
} else {
/* Logging in as root or no local Kerberos realm. */
@@ -242,7 +244,7 @@ auth_krb4(const char *server_user, KTEXT auth, char **client)
/* Clear session key. */
memset(&adat.session, 0, sizeof(&adat.session));
- packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE);
+ packet_start(SSH_SMSG_AUTH_KRB4_RESPONSE);
packet_put_string((char *) reply.dat, reply.length);
packet_send();
packet_write_wait();
@@ -252,7 +254,7 @@ auth_krb4(const char *server_user, KTEXT auth, char **client)
#ifdef AFS
int
-auth_kerberos_tgt(struct passwd *pw, const char *string)
+auth_krb4_tgt(struct passwd *pw, const char *string)
{
CREDENTIALS creds;
diff --git a/crypto/openssh/auth-krb5.c b/crypto/openssh/auth-krb5.c
new file mode 100644
index 0000000..6030d9a
--- /dev/null
+++ b/crypto/openssh/auth-krb5.c
@@ -0,0 +1,249 @@
+/*
+ * Kerberos v5 authentication and ticket-passing routines.
+ *
+ * $FreeBSD$
+ */
+
+#include "includes.h"
+#include "ssh.h"
+#include "packet.h"
+#include "xmalloc.h"
+
+#ifdef KRB5
+
+extern krb5_context ssh_context;
+krb5_auth_context auth_context;
+krb5_ccache mem_ccache = NULL; /* Credential cache for acquired ticket */
+
+/* Try krb5 authentication. server_user is passed for logging purposes only,
+ in auth is received ticket, in client is returned principal from the
+ ticket */
+int
+auth_krb5(const char* server_user, krb5_data *auth, krb5_principal *client)
+{
+ krb5_error_code problem;
+ krb5_principal server = NULL;
+ krb5_principal tkt_client = NULL;
+ krb5_data reply;
+ krb5_ticket *ticket = NULL;
+ int fd;
+ int ret;
+
+ reply.length = 0;
+
+ problem = krb5_init();
+ if (problem)
+ return 0;
+
+ problem = krb5_auth_con_init(ssh_context, &auth_context);
+ if (problem) {
+ log("Kerberos v5 authentication failed: %.100s",
+ krb5_get_err_text(ssh_context, problem));
+
+ return 0;
+ }
+
+ fd = packet_get_connection_in();
+ problem = krb5_auth_con_setaddrs_from_fd(ssh_context, auth_context, &fd);
+ if (problem) {
+ ret = 0;
+ goto err;
+ }
+
+ problem = krb5_sname_to_principal(ssh_context, NULL, NULL ,
+ KRB5_NT_SRV_HST, &server);
+ if (problem) {
+ ret = 0;
+ goto err;
+ }
+
+ problem = krb5_rd_req(ssh_context, &auth_context, auth, server, NULL,
+ NULL, &ticket);
+ if (problem) {
+ ret = 0;
+ goto err;
+ }
+
+ problem = krb5_copy_principal(ssh_context, ticket->client, &tkt_client);
+ if (problem) {
+ ret = 0;
+ goto err;
+ }
+
+ /* if client wants mutual auth */
+ problem = krb5_mk_rep(ssh_context, &auth_context, &reply);
+ if (problem) {
+ ret = 0;
+ goto err;
+ }
+
+ *client = tkt_client;
+
+ packet_start(SSH_SMSG_AUTH_KRB5_RESPONSE);
+ packet_put_string((char *) reply.data, reply.length);
+ packet_send();
+ packet_write_wait();
+ ret = 1;
+
+err:
+ if (server)
+ krb5_free_principal(ssh_context, server);
+ if (ticket)
+ krb5_free_ticket(ssh_context, ticket);
+ if (reply.length)
+ xfree(reply.data);
+ return ret;
+}
+
+int
+auth_krb5_tgt(char *server_user, krb5_data *tgt, krb5_principal tkt_client)
+{
+ krb5_error_code problem;
+ krb5_ccache ccache = NULL;
+
+ if (ssh_context == NULL) {
+ goto fail;
+ }
+
+ problem = krb5_cc_gen_new(ssh_context, &krb5_mcc_ops, &ccache);
+ if (problem) {
+ goto fail;
+ }
+
+ problem = krb5_cc_initialize(ssh_context, ccache, tkt_client);
+ if (problem) {
+ goto fail;
+ }
+
+ problem = krb5_rd_cred(ssh_context, auth_context, ccache, tgt);
+ if (problem) {
+ goto fail;
+ }
+
+ mem_ccache = ccache;
+ ccache = NULL;
+
+ /*
+ problem = krb5_cc_copy_cache(ssh_context, ccache, mem_ccache);
+ if (problem) {
+ mem_ccache = NULL;
+ goto fail;
+ }
+
+
+ problem = krb5_cc_destroy(ssh_context, ccache);
+ if (problem)
+ goto fail;
+ */
+
+#if 0
+ packet_start(SSH_SMSG_SUCCESS);
+ packet_send();
+ packet_write_wait();
+#endif
+ return 1;
+
+fail:
+ if (ccache)
+ krb5_cc_destroy(ssh_context, ccache);
+#if 0
+ packet_start(SSH_SMSG_FAILURE);
+ packet_send();
+ packet_write_wait();
+#endif
+ return 0;
+}
+
+int
+auth_krb5_password(struct passwd *pw, const char *password)
+{
+ krb5_error_code problem;
+ krb5_ccache ccache = NULL;
+ krb5_principal client = NULL;
+ int ret;
+
+ problem = krb5_init();
+ if (problem)
+ return 0;
+
+ problem = krb5_parse_name(ssh_context, pw->pw_name, &client);
+ if (problem) {
+ ret = 0;
+ goto out;
+ }
+
+ problem = krb5_cc_gen_new(ssh_context, &krb5_mcc_ops, &ccache);
+ if (problem) {
+ ret = 0;
+ goto out;
+ }
+
+ problem = krb5_cc_initialize(ssh_context, ccache, client);
+ if (problem) {
+ ret = 0;
+ goto out;
+ }
+
+ problem = krb5_verify_user(ssh_context, client, ccache, password, 1, NULL);
+ if (problem) {
+ ret = 0;
+ goto out;
+ }
+
+/*
+ problem = krb5_cc_copy_cache(ssh_context, ccache, mem_ccache);
+ if (problem) {
+ ret = 0;
+ mem_ccache = NULL;
+ goto out;
+ }
+ */
+ mem_ccache = ccache;
+ ccache = NULL;
+
+ ret = 1;
+out:
+ if (client != NULL)
+ krb5_free_principal(ssh_context, client);
+ if (ccache != NULL)
+ krb5_cc_destroy(ssh_context, ccache);
+ return ret;
+}
+
+void
+krb5_cleanup_proc(void *ignore)
+{
+ extern krb5_principal tkt_client;
+
+ debug("krb5_cleanup_proc() called");
+ if (mem_ccache)
+ krb5_cc_destroy(ssh_context, mem_ccache);
+ if (tkt_client)
+ krb5_free_principal(ssh_context, tkt_client);
+ if (auth_context)
+ krb5_auth_con_free(ssh_context, auth_context);
+ if (ssh_context)
+ krb5_free_context(ssh_context);
+}
+
+int
+krb5_init(void)
+{
+ krb5_error_code problem;
+ static cleanup_registered = 0;
+
+ if (ssh_context == NULL) {
+ problem = krb5_init_context(&ssh_context);
+ if (problem)
+ return problem;
+ krb5_init_ets(ssh_context);
+ }
+
+ if (!cleanup_registered) {
+ fatal_add_cleanup(krb4_cleanup_proc, NULL);
+ cleanup_registered = 1;
+ }
+ return 0;
+}
+
+#endif /* KRB5 */
diff --git a/crypto/openssh/auth-passwd.c b/crypto/openssh/auth-passwd.c
index de0f640..8622dbc 100644
--- a/crypto/openssh/auth-passwd.c
+++ b/crypto/openssh/auth-passwd.c
@@ -5,6 +5,8 @@
* Created: Sat Mar 18 05:11:38 1995 ylo
* Password authentication. This file contains the functions to check whether
* the password is valid for the user.
+ *
+ * $FreeBSD$
*/
#include "includes.h"
@@ -41,8 +43,16 @@ auth_password(struct passwd * pw, const char *password)
/* Fall back to ordinary passwd authentication. */
}
#endif
+#ifdef KRB5
+ if (options.krb5_authentication == 1) {
+ if (auth_krb5_password(pw, password))
+ return 1;
+ /* Fall back to ordinary passwd authentication. */
+ }
+
+#endif /* KRB5 */
#ifdef KRB4
- if (options.kerberos_authentication == 1) {
+ if (options.krb4_authentication == 1) {
int ret = auth_krb4_password(pw, password);
if (ret == 1 || ret == 0)
return ret;
diff --git a/crypto/openssh/readconf.c b/crypto/openssh/readconf.c
index b2da36f..f44ee55 100644
--- a/crypto/openssh/readconf.c
+++ b/crypto/openssh/readconf.c
@@ -93,10 +93,13 @@ typedef enum {
oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
oSkeyAuthentication,
#ifdef KRB4
- oKerberosAuthentication,
+ oKrb4Authentication,
#endif /* KRB4 */
+#ifdef KRB5
+ oKrb5Authentication, oKrb5TgtPassing,
+#endif /* KRB5 */
#ifdef AFS
- oKerberosTgtPassing, oAFSTokenPassing,
+ oKrb4TgtPassing, oAFSTokenPassing,
#endif
oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
@@ -121,10 +124,14 @@ static struct {
{ "rsaauthentication", oRSAAuthentication },
{ "skeyauthentication", oSkeyAuthentication },
#ifdef KRB4
- { "kerberosauthentication", oKerberosAuthentication },
+ { "kerberos4authentication", oKrb4Authentication },
#endif /* KRB4 */
+#ifdef KRB5
+ { "kerberos5authentication", oKrb5Authentication },
+ { "kerberos5tgtpassing", oKrb5TgtPassing },
+#endif /* KRB5 */
#ifdef AFS
- { "kerberostgtpassing", oKerberosTgtPassing },
+ { "kerberos4tgtpassing", oKrb4TgtPassing },
{ "afstokenpassing", oAFSTokenPassing },
#endif
{ "fallbacktorsh", oFallBackToRsh },
@@ -298,14 +305,24 @@ parse_flag:
goto parse_flag;
#ifdef KRB4
- case oKerberosAuthentication:
- intptr = &options->kerberos_authentication;
+ case oKrb4Authentication:
+ intptr = &options->krb4_authentication;
goto parse_flag;
#endif /* KRB4 */
+#ifdef KRB5
+ case oKrb5Authentication:
+ intptr = &options->krb5_authentication;
+ goto parse_flag;
+
+ case oKrb5TgtPassing:
+ intptr = &options->krb5_tgt_passing;
+ goto parse_flag;
+#endif /* KRB5 */
+
#ifdef AFS
- case oKerberosTgtPassing:
- intptr = &options->kerberos_tgt_passing;
+ case oKrb4TgtPassing:
+ intptr = &options->krb4_tgt_passing;
goto parse_flag;
case oAFSTokenPassing:
@@ -596,10 +613,14 @@ initialize_options(Options * options)
options->rsa_authentication = -1;
options->skey_authentication = -1;
#ifdef KRB4
- options->kerberos_authentication = -1;
+ options->krb4_authentication = -1;
#endif
+#ifdef KRB5
+ options->krb5_authentication = -1;
+ options->krb5_tgt_passing = -1;
+#endif /* KRB5 */
#ifdef AFS
- options->kerberos_tgt_passing = -1;
+ options->krb4_tgt_passing = -1;
options->afs_token_passing = -1;
#endif
options->password_authentication = -1;
@@ -651,12 +672,18 @@ fill_default_options(Options * options)
if (options->skey_authentication == -1)
options->skey_authentication = 0;
#ifdef KRB4
- if (options->kerberos_authentication == -1)
- options->kerberos_authentication = 1;
+ if (options->krb4_authentication == -1)
+ options->krb4_authentication = 1;
#endif /* KRB4 */
+#ifdef KRB5
+ if (options->krb5_authentication == -1)
+ options->krb5_authentication = 1;
+ if (options->krb5_tgt_passing == -1)
+ options->krb5_tgt_passing = 1;
+#endif /* KRB5 */
#ifdef AFS
- if (options->kerberos_tgt_passing == -1)
- options->kerberos_tgt_passing = 1;
+ if (options->krb4_tgt_passing == -1)
+ options->krb4_tgt_passing = 1;
if (options->afs_token_passing == -1)
options->afs_token_passing = 1;
#endif /* AFS */
diff --git a/crypto/openssh/readconf.h b/crypto/openssh/readconf.h
index 1d22002..5d511aa 100644
--- a/crypto/openssh/readconf.h
+++ b/crypto/openssh/readconf.h
@@ -11,6 +11,7 @@
*
* Functions for reading the configuration file.
*
+ * $FreeBSD$
*/
/* RCSID("$Id: readconf.h,v 1.13 1999/12/01 13:59:15 markus Exp $"); */
@@ -38,11 +39,17 @@ typedef struct {
int rsa_authentication; /* Try RSA authentication. */
int skey_authentication; /* Try S/Key or TIS authentication. */
#ifdef KRB4
- int kerberos_authentication; /* Try Kerberos
+ int krb4_authentication; /* Try Kerberos v4
* authentication. */
#endif
+
+#ifdef KRB5
+ int krb5_authentication;
+ int krb5_tgt_passing;
+#endif /* KRB5 */
+
#ifdef AFS
- int kerberos_tgt_passing; /* Try Kerberos tgt passing. */
+ int krb4_tgt_passing; /* Try Kerberos v4 tgt passing. */
int afs_token_passing; /* Try AFS token passing. */
#endif
int password_authentication; /* Try password
diff --git a/crypto/openssh/servconf.c b/crypto/openssh/servconf.c
index 6ae36e6..7852348 100644
--- a/crypto/openssh/servconf.c
+++ b/crypto/openssh/servconf.c
@@ -13,7 +13,7 @@
*/
#include "includes.h"
-RCSID("$Id: servconf.c,v 1.29 2000/01/04 00:07:59 markus Exp $");
+RCSID("$Id: servconf.c,v 1.30 2000/02/24 18:22:16 markus Exp $");
#include "ssh.h"
#include "servconf.h"
@@ -50,12 +50,16 @@ initialize_server_options(ServerOptions *options)
options->rhosts_rsa_authentication = -1;
options->rsa_authentication = -1;
#ifdef KRB4
- options->kerberos_authentication = -1;
- options->kerberos_or_local_passwd = -1;
- options->kerberos_ticket_cleanup = -1;
+ options->krb4_authentication = -1;
+ options->krb4_or_local_passwd = -1;
+ options->krb4_ticket_cleanup = -1;
#endif
+#ifdef KRB5
+ options->krb5_authentication = -1;
+ options->krb5_tgt_passing = -1;
+#endif /* KRB5 */
#ifdef AFS
- options->kerberos_tgt_passing = -1;
+ options->krb4_tgt_passing = -1;
options->afs_token_passing = -1;
#endif
options->password_authentication = -1;
@@ -90,7 +94,7 @@ fill_default_server_options(ServerOptions *options)
if (options->permit_root_login == -1)
options->permit_root_login = 1; /* yes */
if (options->ignore_rhosts == -1)
- options->ignore_rhosts = 0;
+ options->ignore_rhosts = 1;
if (options->ignore_user_known_hosts == -1)
options->ignore_user_known_hosts = 0;
if (options->check_mail == -1)
@@ -100,7 +104,7 @@ fill_default_server_options(ServerOptions *options)
if (options->x11_forwarding == -1)
options->x11_forwarding = 1;
if (options->x11_display_offset == -1)
- options->x11_display_offset = 1;
+ options->x11_display_offset = 10;
if (options->strict_modes == -1)
options->strict_modes = 1;
if (options->keepalives == -1)
@@ -112,20 +116,26 @@ fill_default_server_options(ServerOptions *options)
if (options->rhosts_authentication == -1)
options->rhosts_authentication = 0;
if (options->rhosts_rsa_authentication == -1)
- options->rhosts_rsa_authentication = 1;
+ options->rhosts_rsa_authentication = 0;
if (options->rsa_authentication == -1)
options->rsa_authentication = 1;
#ifdef KRB4
- if (options->kerberos_authentication == -1)
- options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
- if (options->kerberos_or_local_passwd == -1)
- options->kerberos_or_local_passwd = 1;
- if (options->kerberos_ticket_cleanup == -1)
- options->kerberos_ticket_cleanup = 1;
+ if (options->krb4_authentication == -1)
+ options->krb4_authentication = (access(KEYFILE, R_OK) == 0);
+ if (options->krb4_or_local_passwd == -1)
+ options->krb4_or_local_passwd = 1;
+ if (options->krb4_ticket_cleanup == -1)
+ options->krb4_ticket_cleanup = 1;
#endif /* KRB4 */
+#ifdef KRB5
+ if (options->krb5_authentication == -1)
+ options->krb5_authentication = 1;
+ if (options->krb5_tgt_passing == -1)
+ options->krb5_tgt_passing = 1;
+#endif /* KRB5 */
#ifdef AFS
- if (options->kerberos_tgt_passing == -1)
- options->kerberos_tgt_passing = 0;
+ if (options->krb4_tgt_passing == -1)
+ options->krb4_tgt_passing = 0;
if (options->afs_token_passing == -1)
options->afs_token_passing = k_hasafs();
#endif /* AFS */
@@ -136,7 +146,7 @@ fill_default_server_options(ServerOptions *options)
options->skey_authentication = 1;
#endif
if (options->permit_empty_passwd == -1)
- options->permit_empty_passwd = 1;
+ options->permit_empty_passwd = 0;
if (options->use_login == -1)
options->use_login = 0;
}
@@ -150,10 +160,13 @@ typedef enum {
sPermitRootLogin, sLogFacility, sLogLevel,
sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
#ifdef KRB4
- sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
+ sKrb4Authentication, sKrb4OrLocalPasswd, sKrb4TicketCleanup,
#endif
+#ifdef KRB5
+ sKrb5Authentication, sKrb5TgtPassing,
+#endif /* KRB5 */
#ifdef AFS
- sKerberosTgtPassing, sAFSTokenPassing,
+ sKrb4TgtPassing, sAFSTokenPassing,
#endif
#ifdef SKEY
sSkeyAuthentication,
@@ -182,12 +195,16 @@ static struct {
{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
{ "rsaauthentication", sRSAAuthentication },
#ifdef KRB4
- { "kerberosauthentication", sKerberosAuthentication },
- { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
- { "kerberosticketcleanup", sKerberosTicketCleanup },
+ { "kerberos4authentication", sKrb4Authentication },
+ { "kerberos4orlocalpasswd", sKrb4OrLocalPasswd },
+ { "kerberos4ticketcleanup", sKrb4TicketCleanup },
#endif
+#ifdef KRB5
+ { "kerberos5authentication", sKrb5Authentication },
+ { "kerberos5tgtpassing", sKrb5TgtPassing },
+#endif /* KRB5 */
#ifdef AFS
- { "kerberostgtpassing", sKerberosTgtPassing },
+ { "kerberos4tgtpassing", sKrb4TgtPassing },
{ "afstokenpassing", sAFSTokenPassing },
#endif
{ "passwordauthentication", sPasswordAuthentication },
@@ -425,22 +442,32 @@ parse_flag:
goto parse_flag;
#ifdef KRB4
- case sKerberosAuthentication:
- intptr = &options->kerberos_authentication;
+ case sKrb4Authentication:
+ intptr = &options->krb4_authentication;
goto parse_flag;
- case sKerberosOrLocalPasswd:
- intptr = &options->kerberos_or_local_passwd;
+ case sKrb4OrLocalPasswd:
+ intptr = &options->krb4_or_local_passwd;
goto parse_flag;
- case sKerberosTicketCleanup:
- intptr = &options->kerberos_ticket_cleanup;
+ case sKrb4TicketCleanup:
+ intptr = &options->krb4_ticket_cleanup;
goto parse_flag;
#endif
+#ifdef KRB5
+ case sKrb5Authentication:
+ intptr = &options->krb5_authentication;
+ goto parse_flag;
+
+ case sKrb5TgtPassing:
+ intptr = &options->krb5_tgt_passing;
+ goto parse_flag;
+#endif /* KRB5 */
+
#ifdef AFS
- case sKerberosTgtPassing:
- intptr = &options->kerberos_tgt_passing;
+ case sKrb4TgtPassing:
+ intptr = &options->krb4_tgt_passing;
goto parse_flag;
case sAFSTokenPassing:
diff --git a/crypto/openssh/servconf.h b/crypto/openssh/servconf.h
index e21e7ab..3e765b8 100644
--- a/crypto/openssh/servconf.h
+++ b/crypto/openssh/servconf.h
@@ -56,18 +56,23 @@ typedef struct {
* authentication. */
int rsa_authentication; /* If true, permit RSA authentication. */
#ifdef KRB4
- int kerberos_authentication; /* If true, permit Kerberos
+ int krb4_authentication; /* If true, permit Kerberos v4
* authentication. */
- int kerberos_or_local_passwd; /* If true, permit kerberos
+ int krb4_or_local_passwd; /* If true, permit kerberos v4
* and any other password
* authentication mechanism,
* such as SecurID or
* /etc/passwd */
- int kerberos_ticket_cleanup; /* If true, destroy ticket
+ int krb4_ticket_cleanup; /* If true, destroy ticket
* file on logout. */
#endif
+#ifdef KRB5
+ int krb5_authentication;
+ int krb5_tgt_passing;
+
+#endif /* KRB5 */
#ifdef AFS
- int kerberos_tgt_passing; /* If true, permit Kerberos tgt
+ int krb4_tgt_passing; /* If true, permit Kerberos v4 tgt
* passing. */
int afs_token_passing; /* If true, permit AFS token passing. */
#endif
diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c
index 81ce2ec..e240036 100644
--- a/crypto/openssh/ssh.c
+++ b/crypto/openssh/ssh.c
@@ -295,7 +295,8 @@ main(int ac, char **av)
break;
#ifdef AFS
case 'k':
- options.kerberos_tgt_passing = 0;
+ options.krb4_tgt_passing = 0;
+ options.krb5_tgt_passing = 0;
options.afs_token_passing = 0;
break;
#endif
diff --git a/crypto/openssh/ssh.h b/crypto/openssh/ssh.h
index 8576f2e..8d6267c 100644
--- a/crypto/openssh/ssh.h
+++ b/crypto/openssh/ssh.h
@@ -182,11 +182,14 @@
#define SSH_AUTH_PASSWORD 3
#define SSH_AUTH_RHOSTS_RSA 4
#define SSH_AUTH_TIS 5
-#define SSH_AUTH_KERBEROS 6
-#define SSH_PASS_KERBEROS_TGT 7
+#define SSH_AUTH_KRB4 6
+#define SSH_PASS_KRB4_TGT 7
/* 8 to 15 are reserved */
#define SSH_PASS_AFS_TOKEN 21
+#define SSH_AUTH_KRB5 29
+#define SSH_PASS_KRB5_TGT 30
+
/* Protocol flags. These are bit masks. */
#define SSH_PROTOFLAG_SCREEN_NUMBER 1 /* X11 forwarding includes screen */
#define SSH_PROTOFLAG_HOST_IN_FWD_OPEN 2 /* forwarding opens contain host */
@@ -240,11 +243,15 @@
#define SSH_CMSG_AUTH_TIS 39 /* we use this for s/key */
#define SSH_SMSG_AUTH_TIS_CHALLENGE 40 /* challenge (string) */
#define SSH_CMSG_AUTH_TIS_RESPONSE 41 /* response (string) */
-#define SSH_CMSG_AUTH_KERBEROS 42 /* (KTEXT) */
-#define SSH_SMSG_AUTH_KERBEROS_RESPONSE 43 /* (KTEXT) */
-#define SSH_CMSG_HAVE_KERBEROS_TGT 44 /* credentials (s) */
+#define SSH_CMSG_AUTH_KRB4 42 /* (KTEXT) */
+#define SSH_SMSG_AUTH_KRB4_RESPONSE 43 /* (KTEXT) */
+#define SSH_CMSG_HAVE_KRB4_TGT 44 /* credentials (s) */
#define SSH_CMSG_HAVE_AFS_TOKEN 65 /* token (s) */
+#define SSH_CMSG_AUTH_KRB5 110
+#define SSH_SMSG_AUTH_KRB5_RESPONSE 111
+#define SSH_CMSG_HAVE_KRB5_TGT 112
+
/*------------ definitions for login.c -------------*/
/*
@@ -690,6 +697,15 @@ struct envstring {
*/
ssize_t atomicio(ssize_t (*f)(), int fd, void *s, size_t n);
+#ifdef KRB5
+#include <krb5.h>
+int auth_krb5(); /* XXX Doplnit prototypy */
+int auth_krb5_tgt();
+int krb5_init();
+void krb5_cleanup_proc(void *ignore);
+int auth_krb5_password(struct passwd *pw, const char *password);
+#endif /* KRB5 */
+
#ifdef KRB4
#include <krb.h>
/*
@@ -706,7 +722,7 @@ int auth_krb4_password(struct passwd * pw, const char *password);
#include <kafs.h>
/* Accept passed Kerberos v4 ticket-granting ticket and AFS tokens. */
-int auth_kerberos_tgt(struct passwd * pw, const char *string);
+int auth_krb4_tgt(struct passwd * pw, const char *string);
int auth_afs_token(struct passwd * pw, const char *token_string);
int creds_to_radix(CREDENTIALS * creds, unsigned char *buf);
diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c
index 385f4d9..bcbd3af 100644
--- a/crypto/openssh/sshconnect.c
+++ b/crypto/openssh/sshconnect.c
@@ -626,7 +626,7 @@ try_rhosts_rsa_authentication(const char *local_user, RSA * host_key)
#ifdef KRB4
int
-try_kerberos_authentication()
+try_krb4_authentication()
{
KTEXT_ST auth; /* Kerberos data */
char *reply;
@@ -668,7 +668,7 @@ try_kerberos_authentication()
des_key_sched((des_cblock *) cred.session, schedule);
/* Send authentication info to server. */
- packet_start(SSH_CMSG_AUTH_KERBEROS);
+ packet_start(SSH_CMSG_AUTH_KRB4);
packet_put_string((char *) auth.dat, auth.length);
packet_send();
packet_write_wait();
@@ -693,13 +693,13 @@ try_kerberos_authentication()
type = packet_read(&plen);
switch (type) {
case SSH_SMSG_FAILURE:
- /* Should really be SSH_SMSG_AUTH_KERBEROS_FAILURE */
+ /* Should really be SSH_SMSG_AUTH_KRB4_FAILURE */
debug("Kerberos V4 authentication failed.");
return 0;
break;
- case SSH_SMSG_AUTH_KERBEROS_RESPONSE:
- /* SSH_SMSG_AUTH_KERBEROS_SUCCESS */
+ case SSH_SMSG_AUTH_KRB4_RESPONSE:
+ /* SSH_SMSG_AUTH_KRB4_SUCCESS */
debug("Kerberos V4 authentication accepted.");
/* Get server's response. */
@@ -742,7 +742,7 @@ try_kerberos_authentication()
#ifdef AFS
int
-send_kerberos_tgt()
+send_krb4_tgt()
{
CREDENTIALS *creds;
char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
@@ -771,7 +771,7 @@ send_kerberos_tgt()
creds_to_radix(creds, buffer);
xfree(creds);
- packet_start(SSH_CMSG_HAVE_KERBEROS_TGT);
+ packet_start(SSH_CMSG_HAVE_KRB4_TGT);
packet_put_string((char *) buffer, strlen(buffer));
packet_send();
packet_write_wait();
@@ -856,6 +856,247 @@ send_afs_tokens(void)
#endif /* AFS */
+#ifdef KRB5
+int
+try_krb5_authentication(krb5_context *context, krb5_auth_context *auth_context)
+{
+ krb5_error_code problem;
+ const char *tkfile;
+ struct stat buf;
+ krb5_ccache ccache = NULL;
+ krb5_creds req_creds;
+ krb5_creds *new_creds = NULL;
+ const char *remotehost;
+ krb5_data ap;
+ int type, payload_len;
+ krb5_ap_rep_enc_part *reply = NULL;
+ int ret;
+
+ memset(&ap, 0, sizeof(ap));
+
+ problem = krb5_init_context(context);
+ if (problem) {
+ ret = 0;
+ goto out;
+ }
+
+ tkfile = krb5_cc_default_name(*context);
+ if (strncmp(tkfile, "FILE:", 5) == 0)
+ tkfile += 5;
+
+ if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) {
+ debug("Kerberos V5: could not get default ccache (permission denied).");
+ ret = 0;
+ goto out;
+ }
+
+ problem = krb5_cc_default(*context, &ccache);
+ if (problem) {
+ ret = 0;
+ goto out;
+ }
+
+ memset(&req_creds, 0, sizeof(req_creds));
+
+ remotehost = get_canonical_hostname();
+
+ problem = krb5_sname_to_principal(*context, remotehost,
+ "host", KRB5_NT_SRV_HST,
+ &req_creds.server);
+ if (problem) {
+ ret = 0;
+ goto out;
+
+ }
+
+ problem = krb5_cc_get_principal(*context, ccache, &req_creds.client);
+ if (problem) {
+ ret = 0;
+ goto out;
+ }
+
+ /* creds.session.keytype=ETYPE_DES_CBC_CRC; */
+
+ problem = krb5_get_credentials(*context, 0, ccache, &req_creds, &new_creds);
+ if (problem) {
+ ret = 0;
+ goto out;
+ }
+
+ problem = krb5_auth_con_init(*context, auth_context);
+ if (problem) {
+ ret = 0;
+ goto out;
+ }
+
+ /* krb5_auth_con_setflags(ssh_context, auth_context,
+ KRB5_AUTH_CONTEXT_RET_TIME);
+ */
+ problem = krb5_mk_req_extended(*context, auth_context,
+ AP_OPTS_MUTUAL_REQUIRED /*| AP_OPTS_USE_SUBKEY*/ ,
+ NULL, new_creds, &ap);
+ if (problem) {
+ ret = 0;
+ goto out;
+ }
+
+ packet_start(SSH_CMSG_AUTH_KRB5);
+ packet_put_string((char *) ap.data, ap.length);
+ packet_send();
+ packet_write_wait();
+
+ xfree(ap.data);
+ ap.length = 0;
+
+ type = packet_read(&payload_len);
+ switch (type) {
+ case SSH_SMSG_FAILURE:
+ /* Should really be SSH_SMSG_AUTH_KRB5_FAILURE */
+ debug("Kerberos V5 authentication failed.");
+ ret = 0;
+ break;
+
+ case SSH_SMSG_AUTH_KRB5_RESPONSE:
+ /* SSH_SMSG_AUTH_KRB5_SUCCESS */
+ debug("Kerberos V5 authentication accepted.");
+
+ /* Get server's response. */
+ ap.data = packet_get_string((unsigned int *) &ap.length);
+
+ packet_integrity_check(payload_len, 4 + ap.length, type);
+ /* XXX je to dobre? */
+
+ problem = krb5_rd_rep(*context, *auth_context, &ap, &reply);
+ if (problem) {
+ ret = 0;
+ }
+ ret = 1;
+ break;
+
+ default:
+ packet_disconnect("Protocol error on Kerberos V5 response: %d", type);
+ ret = 0;
+ break;
+
+ }
+
+out:
+ if (req_creds.server != NULL)
+ krb5_free_principal(*context, req_creds.server);
+ if (req_creds.client != NULL)
+ krb5_free_principal(*context, req_creds.client);
+ if (new_creds != NULL)
+ krb5_free_creds(*context, new_creds);
+ if (ccache != NULL)
+ krb5_cc_close(*context, ccache);
+ if (reply != NULL)
+ krb5_free_ap_rep_enc_part(*context, reply);
+ if (ap.length > 0)
+ krb5_data_free(&ap);
+
+ return ret;
+
+}
+
+void
+send_krb5_tgt(krb5_context context, krb5_auth_context auth_context)
+{
+ int fd;
+ int type, payload_len;
+ krb5_error_code problem;
+ krb5_data outbuf;
+ krb5_ccache ccache = NULL;
+ krb5_creds creds;
+ krb5_kdc_flags flags;
+ const char* remotehost = get_canonical_hostname();
+
+ memset(&creds, 0, sizeof(creds));
+ memset(&outbuf, 0, sizeof(outbuf));
+
+ fd = packet_get_connection_in();
+ problem = krb5_auth_con_setaddrs_from_fd(context, auth_context, &fd);
+ if (problem) {
+ goto out;
+ }
+
+#if 0
+ tkfile = krb5_cc_default_name(context);
+ if (strncmp(tkfile, "FILE:", 5) == 0)
+ tkfile += 5;
+
+ if (stat(tkfile, &buf) == 0 && getuid() != buf.st_uid) {
+ debug("Kerberos V5: could not get default ccache (permission denied).");
+ goto out;
+ }
+#endif
+
+ problem = krb5_cc_default(context, &ccache);
+ if (problem) {
+ goto out;
+ }
+
+ problem = krb5_cc_get_principal(context, ccache, &creds.client);
+ if (problem) {
+ goto out;
+ }
+
+ problem = krb5_build_principal(context, &creds.server,
+ strlen(creds.client->realm),
+ creds.client->realm,
+ "krbtgt",
+ creds.client->realm,
+ NULL);
+ if (problem) {
+ goto out;
+ }
+
+ creds.times.endtime = 0;
+
+ flags.i = 0;
+ flags.b.forwarded = 1;
+ flags.b.forwardable = krb5_config_get_bool(context, NULL,
+ "libdefaults", "forwardable", NULL);
+
+ problem = krb5_get_forwarded_creds (context,
+ auth_context,
+ ccache,
+ flags.i,
+ remotehost,
+ &creds,
+ &outbuf);
+ if (problem) {
+ goto out;
+ }
+
+ packet_start(SSH_CMSG_HAVE_KRB5_TGT);
+ packet_put_string((char *)outbuf.data, outbuf.length);
+ packet_send();
+ packet_write_wait();
+
+ type = packet_read(&payload_len);
+ switch (type) {
+ case SSH_SMSG_SUCCESS:
+ break;
+ case SSH_SMSG_FAILURE:
+ break;
+ default:
+ break;
+ }
+
+out:
+ if (creds.client)
+ krb5_free_principal(context, creds.client);
+ if (creds.server)
+ krb5_free_principal(context, creds.server);
+ if (ccache)
+ krb5_cc_close(context, ccache);
+ if (outbuf.data)
+ xfree(outbuf.data);
+
+ return;
+}
+#endif /* KRB5 */
+
/*
* Tries to authenticate with any string-based challenge/response system.
* Note that the client code is not tied to s/key or TIS.
@@ -1087,11 +1328,9 @@ check_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key)
case AF_INET:
local = (ntohl(((struct sockaddr_in *)hostaddr)->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
break;
-#ifdef INET6
case AF_INET6:
local = IN6_IS_ADDR_LOOPBACK(&(((struct sockaddr_in6 *)hostaddr)->sin6_addr));
break;
-#endif
default:
local = 0;
break;
@@ -1512,11 +1751,11 @@ ssh_userauth(int host_key_valid, RSA *own_host_key,
#ifdef AFS
/* Try Kerberos tgt passing if the server supports it. */
- if ((supported_authentications & (1 << SSH_PASS_KERBEROS_TGT)) &&
- options.kerberos_tgt_passing) {
+ if ((supported_authentications & (1 << SSH_PASS_KRB4_TGT)) &&
+ options.krb4_tgt_passing) {
if (options.cipher == SSH_CIPHER_NONE)
log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
- (void) send_kerberos_tgt();
+ (void) send_krb4_tgt();
}
/* Try AFS token passing if the server supports it. */
if ((supported_authentications & (1 << SSH_PASS_AFS_TOKEN)) &&
@@ -1528,10 +1767,10 @@ ssh_userauth(int host_key_valid, RSA *own_host_key,
#endif /* AFS */
#ifdef KRB4
- if ((supported_authentications & (1 << SSH_AUTH_KERBEROS)) &&
- options.kerberos_authentication) {
+ if ((supported_authentications & (1 << SSH_AUTH_KRB4)) &&
+ options.krb4_authentication) {
debug("Trying Kerberos authentication.");
- if (try_kerberos_authentication()) {
+ if (try_krb4_authentication()) {
/* The server should respond with success or failure. */
type = packet_read(&payload_len);
if (type == SSH_SMSG_SUCCESS)
@@ -1542,6 +1781,35 @@ ssh_userauth(int host_key_valid, RSA *own_host_key,
}
#endif /* KRB4 */
+#ifdef KRB5
+ if ((supported_authentications & (1 << SSH_AUTH_KRB5)) &&
+ options.krb5_authentication){
+ krb5_context ssh_context = NULL;
+ krb5_auth_context auth_context = NULL;
+
+ debug("Trying Kerberos V5 authentication.");
+
+ if (try_krb5_authentication(&ssh_context, &auth_context)) {
+ type = packet_read(&payload_len);
+ if (type == SSH_SMSG_SUCCESS) {
+ if ((supported_authentications & (1 << SSH_PASS_KRB5_TGT)) &&
+ options.krb5_tgt_passing) {
+ if (options.cipher == SSH_CIPHER_NONE)
+ log("WARNING: Encryption is disabled! Ticket will be transmitted in the clear!");
+ send_krb5_tgt(ssh_context, auth_context);
+
+ }
+ krb5_auth_con_free(ssh_context, auth_context);
+ krb5_free_context(ssh_context);
+ return;
+ }
+ if (type != SSH_SMSG_FAILURE)
+ packet_disconnect("Protocol error: got %d in response to Kerberos5 auth", type);
+
+ }
+ }
+#endif /* KRB5 */
+
/*
* Use rhosts authentication if running in privileged socket and we
* do not wish to remain anonymous.
diff --git a/crypto/openssh/sshd.8 b/crypto/openssh/sshd.8
index 93ee16b..fc067bc 100644
--- a/crypto/openssh/sshd.8
+++ b/crypto/openssh/sshd.8
@@ -9,7 +9,7 @@
.\"
.\" Created: Sat Apr 22 21:55:14 1995 ylo
.\"
-.\" $Id: sshd.8,v 1.33 2000/02/21 14:19:09 deraadt Exp $
+.\" $Id: sshd.8,v 1.34 2000/02/24 18:22:16 markus Exp $
.\" $FreeBSD$
.\"
.Dd September 25, 1999
@@ -284,13 +284,16 @@ Note that
.Nm
does not start if this file is group/world-accessible.
.It Cm IgnoreRhosts
-Specifies that rhosts and shosts files will not be used in
-authentication.
+Specifies that
+.Pa .rhosts
+and
+.Pa .shosts
+files will not be used in authentication.
.Pa /etc/hosts.equiv
and
.Pa /etc/shosts.equiv
are still used. The default is
-.Dq no .
+.Dq yes .
.It Cm IgnoreUserKnownHosts
Specifies whether
.Nm
@@ -378,7 +381,7 @@ The default is
When password authentication is allowed, it specifies whether the
server allows login to accounts with empty password strings. The default
is
-.Dq yes .
+.Dq no .
.It Cm PermitRootLogin
Specifies whether the root can log in using
.Xr ssh 1 .
@@ -429,7 +432,7 @@ The default is
.It Cm RhostsRSAAuthentication
Specifies whether rhosts or /etc/hosts.equiv authentication together
with successful RSA host authentication is allowed. The default is
-.Dq yes .
+.Dq no .
.It Cm RSAAuthentication
Specifies whether pure RSA authentication is allowed. The default is
.Dq yes .
@@ -468,6 +471,7 @@ Specifies the first display number available for
X11 forwarding. This prevents
.Nm
from interfering with real X11 servers.
+The default is 10.
.It Cm X11Forwarding
Specifies whether X11 forwarding is permitted. The default is
.Dq yes .
diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c
index 1dfea88..8576bc2 100644
--- a/crypto/openssh/sshd.c
+++ b/crypto/openssh/sshd.c
@@ -37,9 +37,8 @@ int deny_severity = LOG_WARNING;
#endif /* LIBWRAP */
#ifdef __FreeBSD__
-#include <libutil.h>
-#include <syslog.h>
#define LOGIN_CAP
+#define _PATH_CHPASS "/usr/bin/passwd"
#endif /* __FreeBSD__ */
#ifdef LOGIN_CAP
@@ -50,6 +49,14 @@ int deny_severity = LOG_WARNING;
#define O_NOCTTY 0
#endif
+#ifdef KRB5
+#include <krb5.h>
+krb5_context ssh_context = NULL;
+krb5_principal tkt_client = NULL; /* Principal from the received ticket.
+Also is used as an indication of succesful krb5 authentization. */
+#endif /* KRB5 */
+
+
/* Local Xauthority file. */
static char *xauthfile = NULL;
@@ -149,7 +156,7 @@ struct magic_connection {
const size_t MAGIC_CONNECTIONS_SIZE = 1;
static __inline int
-magic_hash(struct sockaddr_storage *sa) {
+magic_hash(struct sockaddr *sa) {
return 0;
}
@@ -302,9 +309,13 @@ get_authname(int type)
case SSH_CMSG_AUTH_RHOSTS:
return "rhosts";
#ifdef KRB4
- case SSH_CMSG_AUTH_KERBEROS:
- return "kerberos";
+ case SSH_CMSG_AUTH_KRB4:
+ return "kerberosV4";
#endif
+#ifdef KRB5
+ case SSH_CMSG_AUTH_KRB5:
+ return "kerberosV5";
+#endif /* KRB5 */
#ifdef SKEY
case SSH_CMSG_AUTH_TIS_RESPONSE:
return "s/key";
@@ -723,7 +734,7 @@ main(int ac, char **av)
struct magic_connection *mc;
(void)gettimeofday(&connections_end, NULL);
- mc = &magic_connections[magic_hash(&from)];
+ mc = &magic_connections[magic_hash((struct sockaddr *)0)];
diff = timevaldiff(&mc->connections_begin, &connections_end);
if (diff.tv_sec >= options.connections_period) {
/*
@@ -948,9 +959,9 @@ main(int ac, char **av)
}
#ifdef KRB4
if (!packet_connection_is_ipv4() &&
- options.kerberos_authentication) {
+ options.krb4_authentication) {
debug("Kerberos Authentication disabled, only available for IPv4.");
- options.kerberos_authentication = 0;
+ options.krb4_authentication = 0;
}
#endif /* KRB4 */
@@ -964,7 +975,7 @@ main(int ac, char **av)
#ifdef KRB4
/* Cleanup user's ticket cache file. */
- if (options.kerberos_ticket_cleanup)
+ if (options.krb4_ticket_cleanup)
(void) dest_tkt();
#endif /* KRB4 */
@@ -1042,12 +1053,22 @@ do_ssh_kex()
if (options.rsa_authentication)
auth_mask |= 1 << SSH_AUTH_RSA;
#ifdef KRB4
- if (options.kerberos_authentication)
- auth_mask |= 1 << SSH_AUTH_KERBEROS;
+ if (options.krb4_authentication)
+ auth_mask |= 1 << SSH_AUTH_KRB4;
#endif
+#ifdef KRB5
+ if (options.krb5_authentication) {
+ auth_mask |= 1 << SSH_AUTH_KRB5;
+ /* compatibility with MetaCentre ssh */
+ auth_mask |= 1 << SSH_AUTH_KRB4;
+ }
+ if (options.krb5_tgt_passing)
+ auth_mask |= 1 << SSH_PASS_KRB5_TGT;
+#endif /* KRB5 */
+
#ifdef AFS
- if (options.kerberos_tgt_passing)
- auth_mask |= 1 << SSH_PASS_KERBEROS_TGT;
+ if (options.krb4_tgt_passing)
+ auth_mask |= 1 << SSH_PASS_KRB4_TGT;
if (options.afs_token_passing)
auth_mask |= 1 << SSH_PASS_AFS_TOKEN;
#endif
@@ -1246,6 +1267,7 @@ allowed_user(struct passwd * pw)
return 0;
}
}
+#ifndef __FreeBSD__ /* FreeBSD handle it later */
/* Fail if the account's expiration time has passed. */
if (pw->pw_expire != 0) {
struct timeval tv;
@@ -1254,6 +1276,7 @@ allowed_user(struct passwd * pw)
if (tv.tv_sec >= pw->pw_expire)
return 0;
}
+#endif /* !__FreeBSD__ */
/* We found no reason not to let this user try to log on... */
return 1;
}
@@ -1268,6 +1291,12 @@ do_authentication()
struct passwd *pw, pwcopy;
int plen, ulen;
char *user;
+#ifdef LOGIN_CAP
+ login_cap_t *lc;
+ char *hosts;
+ const char *from_host, *from_ip;
+ int denied;
+#endif /* LOGIN_CAP */
/* Get the name of the user that we wish to log in as. */
packet_read_expect(&plen, SSH_CMSG_USER);
@@ -1316,8 +1345,11 @@ do_authentication()
/* If the user has no password, accept authentication immediately. */
if (options.password_authentication &&
+#ifdef KRB5
+ !options.krb5_authentication &&
+#endif /* KRB5 */
#ifdef KRB4
- (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
+ (!options.krb4_authentication || options.krb4_or_local_passwd) &&
#endif /* KRB4 */
auth_password(pw, "")) {
/* Authentication with empty password succeeded. */
@@ -1338,6 +1370,38 @@ do_authentication()
packet_disconnect("ROOT LOGIN REFUSED FROM %.200s",
get_canonical_hostname());
}
+
+#ifdef LOGIN_CAP
+ lc = login_getpwclass(pw);
+ if (lc == NULL)
+ lc = login_getclassbyname(NULL, pw);
+ from_host = get_canonical_hostname();
+ from_ip = get_remote_ipaddr();
+
+ denied = 0;
+ if ((hosts = login_getcapstr(lc, "host.deny", NULL, NULL)) != NULL) {
+ denied = match_hostname(from_host, hosts, strlen(hosts));
+ if (!denied)
+ denied = match_hostname(from_ip, hosts, strlen(hosts));
+ }
+ if (!denied &&
+ (hosts = login_getcapstr(lc, "host.allow", NULL, NULL)) != NULL) {
+ denied = !match_hostname(from_host, hosts, strlen(hosts));
+ if (denied)
+ denied = !match_hostname(from_ip, hosts, strlen(hosts));
+ }
+ login_close(lc);
+ if (denied) {
+ log("Denied connection for %.200s from %.200s [%.200s].",
+ pw->pw_name, from_host, from_ip);
+ packet_disconnect("Sorry, you are not allowed to connect.");
+ }
+#endif /* LOGIN_CAP */
+
+ if (pw->pw_uid == 0)
+ log("ROOT LOGIN as '%.100s' from %.100s",
+ pw->pw_name, get_canonical_hostname());
+
/* The user has been authenticated and accepted. */
packet_start(SSH_SMSG_SUCCESS);
packet_send();
@@ -1367,6 +1431,22 @@ do_authloop(struct passwd * pw)
int plen, dlen, nlen, ulen, elen;
int type = 0;
void (*authlog) (const char *fmt,...) = verbose;
+#ifdef HAVE_LIBPAM
+ int pam_retval;
+#endif /* HAVE_LIBPAM */
+#if 0
+#ifdef KRB5
+ {
+ krb5_error_code ret;
+
+ ret = krb5_init_context(&ssh_context);
+ if (ret)
+ verbose("Error while initializing Kerberos V5.");
+ krb5_init_ets(ssh_context);
+
+ }
+#endif /* KRB5 */
+#endif
/* Indicate that authentication is needed. */
packet_start(SSH_SMSG_FAILURE);
@@ -1383,17 +1463,17 @@ do_authloop(struct passwd * pw)
/* Process the packet. */
switch (type) {
#ifdef AFS
- case SSH_CMSG_HAVE_KERBEROS_TGT:
- if (!options.kerberos_tgt_passing) {
+ case SSH_CMSG_HAVE_KRB4_TGT:
+ if (!options.krb4_tgt_passing) {
/* packet_get_all(); */
- verbose("Kerberos tgt passing disabled.");
+ verbose("Kerberos v4 tgt passing disabled.");
break;
} else {
- /* Accept Kerberos tgt. */
+ /* Accept Kerberos v4 tgt. */
char *tgt = packet_get_string(&dlen);
packet_integrity_check(plen, 4 + dlen, type);
- if (!auth_kerberos_tgt(pw, tgt))
- verbose("Kerberos tgt REFUSED for %s", pw->pw_name);
+ if (!auth_krb4_tgt(pw, tgt))
+ verbose("Kerberos v4 tgt REFUSED for %s", pw->pw_name);
xfree(tgt);
}
continue;
@@ -1414,10 +1494,10 @@ do_authloop(struct passwd * pw)
continue;
#endif /* AFS */
#ifdef KRB4
- case SSH_CMSG_AUTH_KERBEROS:
- if (!options.kerberos_authentication) {
+ case SSH_CMSG_AUTH_KRB4:
+ if (!options.krb4_authentication) {
/* packet_get_all(); */
- verbose("Kerberos authentication disabled.");
+ verbose("Kerberos v4 authentication disabled.");
break;
} else {
/* Try Kerberos v4 authentication. */
@@ -1439,6 +1519,36 @@ do_authloop(struct passwd * pw)
}
break;
#endif /* KRB4 */
+#ifdef KRB5
+ case SSH_CMSG_AUTH_KRB5:
+ if (!options.krb5_authentication) {
+ verbose("Kerberos v5 authentication disabled.");
+ break;
+ } else {
+ krb5_data k5data;
+#if 0
+ if (krb5_init_context(&ssh_context)) {
+ verbose("Error while initializing Kerberos V5.");
+ break;
+ }
+ krb5_init_ets(ssh_context);
+#endif
+
+ k5data.data = packet_get_string(&k5data.length);
+ packet_integrity_check(plen, 4 + k5data.length, type);
+ if (auth_krb5(pw->pw_name, &k5data, &tkt_client)) {
+ /* pw->name is passed just for logging purposes
+ * */
+ /* authorize client against .k5login */
+ if (krb5_kuserok(ssh_context,
+ tkt_client,
+ pw->pw_name))
+ authenticated = 1;
+ }
+ xfree(k5data.data);
+ }
+ break;
+#endif /* KRB5 */
case SSH_CMSG_AUTH_RHOSTS:
if (!options.rhosts_authentication) {
@@ -1908,6 +2018,32 @@ do_authenticated(struct passwd * pw)
do_exec_no_pty(command, pw, display, proto, data);
xfree(command);
return;
+#ifdef KRB5
+ case SSH_CMSG_HAVE_KRB5_TGT:
+ /* Passing krb5 ticket */
+ if (!options.krb5_tgt_passing
+ /*|| !options.krb5_authentication */) {
+
+ }
+
+ if (tkt_client == NULL) {
+ /* passing tgt without krb5 authentication */
+ }
+
+ {
+ krb5_data tgt;
+ tgt.data = packet_get_string(&tgt.length);
+
+ if (!auth_krb5_tgt(pw->pw_name, &tgt, tkt_client)) {
+ verbose ("Kerberos V5 TGT refused for %.100s", pw->pw_name);
+ xfree(tgt.data);
+ goto fail;
+ }
+ xfree(tgt.data);
+
+ break;
+ }
+#endif /* KRB5 */
default:
/*
@@ -2086,6 +2222,11 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd,
login_cap_t *lc;
char *fname;
#endif /* LOGIN_CAP */
+#ifdef __FreeBSD__
+#define DEFAULT_WARN (2L * 7L * 86400L) /* Two weeks */
+ struct timeval tv;
+ time_t warntime = DEFAULT_WARN;
+#endif /* __FreeBSD__ */
/* Get remote host name. */
hostname = get_canonical_hostname();
@@ -2157,6 +2298,50 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd,
quiet_login = login_getcapbool(lc, "hushlogin", quiet_login);
#endif /* LOGIN_CAP */
+#ifdef __FreeBSD__
+ if (pw->pw_change || pw->pw_expire)
+ (void)gettimeofday(&tv, NULL);
+#ifdef LOGIN_CAP
+ warntime = login_getcaptime(lc, "warnpassword",
+ DEFAULT_WARN, DEFAULT_WARN);
+#endif /* LOGIN_CAP */
+ /*
+ * If the password change time is set and has passed, give the
+ * user a password expiry notice and chance to change it.
+ */
+ if (pw->pw_change != 0) {
+ if (tv.tv_sec >= pw->pw_change) {
+ (void)printf(
+ "Sorry -- your password has expired.\n");
+ log("%s Password expired - forcing change",
+ pw->pw_name);
+ command = _PATH_CHPASS;
+ } else if (pw->pw_change - tv.tv_sec < warntime &&
+ !quiet_login)
+ (void)printf(
+ "Warning: your password expires on %s",
+ ctime(&pw->pw_change));
+ }
+#ifdef LOGIN_CAP
+ warntime = login_getcaptime(lc, "warnexpire",
+ DEFAULT_WARN, DEFAULT_WARN);
+#endif /* LOGIN_CAP */
+ if (pw->pw_expire) {
+ if (tv.tv_sec >= pw->pw_expire) {
+ (void)printf(
+ "Sorry -- your account has expired.\n");
+ log(
+ "LOGIN %.200s REFUSED (EXPIRED) FROM %.200s ON TTY %.200s",
+ pw->pw_name, hostname, ttyname);
+ exit(254);
+ } else if (pw->pw_expire - tv.tv_sec < warntime &&
+ !quiet_login)
+ (void)printf(
+ "Warning: your account expires on %s",
+ ctime(&pw->pw_expire));
+ }
+#endif /* __FreeBSD__ */
+
/*
* If the user has logged in before, display the time of last
* login. However, don't display anything extra if a command
@@ -2203,10 +2388,9 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd,
!options.use_login) {
#ifdef LOGIN_CAP
fname = login_getcapstr(lc, "welcome", NULL, NULL);
- login_close(lc);
if (fname == NULL || (f = fopen(fname, "r")) == NULL)
f = fopen("/etc/motd", "r");
-#else /* LOGIN_CAP */
+#else /* !LOGIN_CAP */
f = fopen("/etc/motd", "r");
#endif /* LOGIN_CAP */
/* Print /etc/motd if it exists. */
@@ -2216,6 +2400,9 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd,
fclose(f);
}
}
+#ifdef LOGIN_CAP
+ login_close(lc);
+#endif /* LOGIN_CAP */
/* Do common processing for the child, such as execing the command. */
do_child(command, pw, term, display, auth_proto, auth_data, ttyname);
@@ -2363,7 +2550,7 @@ do_child(const char *command, struct passwd * pw, const char *term,
char buf[256];
FILE *f;
unsigned int envsize, i;
- char **env;
+ char **env = NULL;
extern char **environ;
struct stat st;
char *argv[10];
@@ -2373,29 +2560,24 @@ do_child(const char *command, struct passwd * pw, const char *term,
lc = login_getpwclass(pw);
if (lc == NULL)
lc = login_getclassbyname(NULL, pw);
-#endif /* LOGIN_CAP */
-
+ if (pw->pw_uid != 0)
+ auth_checknologin(lc);
+#else /* !LOGIN_CAP */
f = fopen("/etc/nologin", "r");
-#ifdef __FreeBSD__
- if (f == NULL)
- f = fopen("/var/run/nologin", "r");
-#endif /* __FreeBSD__ */
if (f) {
/* /etc/nologin exists. Print its contents and exit. */
-#ifdef LOGIN_CAP
- /* On FreeBSD, etc., allow overriding nologin via login.conf. */
- if (!login_getcapbool(lc, "ignorenologin", 0)) {
-#else /* LOGIN_CAP */
- if (1) {
-#endif /* LOGIN_CAP */
- while (fgets(buf, sizeof(buf), f))
- fputs(buf, stderr);
- fclose(f);
- if (pw->pw_uid != 0)
- exit(254);
- }
+ while (fgets(buf, sizeof(buf), f))
+ fputs(buf, stderr);
+ fclose(f);
+ if (pw->pw_uid != 0)
+ exit(254);
}
+#endif /* LOGIN_CAP */
+
+#ifdef LOGIN_CAP
+ if (options.use_login)
+#endif /* LOGIN_CAP */
/* Set login name in the kernel. */
if (setlogin(pw->pw_name) < 0)
error("setlogin failed: %s", strerror(errno));
@@ -2405,12 +2587,42 @@ do_child(const char *command, struct passwd * pw, const char *term,
switch, so we let login(1) to this for us. */
if (!options.use_login) {
#ifdef LOGIN_CAP
- if (setclasscontext(pw->pw_class, LOGIN_SETPRIORITY |
- LOGIN_SETRESOURCES | LOGIN_SETUMASK) == -1) {
- perror("setclasscontext");
- exit(1);
- }
-#endif /* LOGIN_CAP */
+ char **tmpenv;
+
+ /* Initialize temp environment */
+ envsize = 64;
+ env = xmalloc(envsize * sizeof(char *));
+ env[0] = NULL;
+
+ child_set_env(&env, &envsize, "PATH",
+ (pw->pw_uid == 0) ?
+ _PATH_STDPATH : _PATH_DEFPATH);
+
+ snprintf(buf, sizeof buf, "%.200s/%.50s",
+ _PATH_MAILDIR, pw->pw_name);
+ child_set_env(&env, &envsize, "MAIL", buf);
+
+ if (getenv("TZ"))
+ child_set_env(&env, &envsize, "TZ", getenv("TZ"));
+
+ /* Save parent environment */
+ tmpenv = environ;
+ environ = env;
+
+ if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETALL) < 0)
+ fatal("setusercontext failed: %s", strerror(errno));
+
+ /* Restore parent environment */
+ env = environ;
+ environ = tmpenv;
+
+ for (envsize = 0; env[envsize] != NULL; ++envsize)
+ ;
+ envsize = (envsize < 100) ? 100 : envsize + 16;
+ env = xrealloc(env, envsize * sizeof(char *));
+
+#else /* !LOGIN_CAP */
+
if (getuid() == 0 || geteuid() == 0) {
if (setgid(pw->pw_gid) < 0) {
perror("setgid");
@@ -2428,18 +2640,15 @@ do_child(const char *command, struct passwd * pw, const char *term,
}
if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
fatal("Failed to set uids to %d.", (int) pw->pw_uid);
+#endif /* LOGIN_CAP */
}
/*
* Get the shell from the password data. An empty shell field is
* legal, and means /bin/sh.
*/
+ shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
#ifdef LOGIN_CAP
- shell = pw->pw_shell;
shell = login_getcapstr(lc, "shell", shell, shell);
- if (shell[0] == '\0')
- shell = _PATH_BSHELL;
-#else /* LOGIN_CAP */
- shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
#endif /* LOGIN_CAP */
#ifdef AFS
@@ -2455,29 +2664,31 @@ do_child(const char *command, struct passwd * pw, const char *term,
#endif /* AFS */
/* Initialize the environment. */
- envsize = 100;
- env = xmalloc(envsize * sizeof(char *));
- env[0] = NULL;
+ if (env == NULL) {
+ envsize = 100;
+ env = xmalloc(envsize * sizeof(char *));
+ env[0] = NULL;
+ }
if (!options.use_login) {
/* Set basic environment. */
child_set_env(&env, &envsize, "USER", pw->pw_name);
child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
child_set_env(&env, &envsize, "HOME", pw->pw_dir);
-#ifdef LOGIN_CAP
- child_set_env(&env, &envsize, "PATH",
- login_getpath(lc, "path", _PATH_STDPATH));
-#else /* LOGIN_CAP */
+#ifndef LOGIN_CAP
child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
-#endif /* LOGIN_CAP */
snprintf(buf, sizeof buf, "%.200s/%.50s",
_PATH_MAILDIR, pw->pw_name);
child_set_env(&env, &envsize, "MAIL", buf);
+#endif /* !LOGIN_CAP */
/* Normal systems set SHELL by default. */
child_set_env(&env, &envsize, "SHELL", shell);
}
+#ifdef LOGIN_CAP
+ if (options.use_login)
+#endif /* LOGIN_CAP */
if (getenv("TZ"))
child_set_env(&env, &envsize, "TZ", getenv("TZ"));
@@ -2516,6 +2727,32 @@ do_child(const char *command, struct passwd * pw, const char *term,
}
#endif /* KRB4 */
+#ifdef KRB5
+ {
+ extern krb5_ccache mem_ccache;
+
+ if (mem_ccache) {
+ krb5_error_code problem;
+ krb5_ccache ccache;
+#ifdef AFS
+ if (k_hasafs())
+ krb5_afslog(ssh_context, mem_ccache, NULL, NULL);
+#endif /* AFS */
+
+ problem = krb5_cc_default(ssh_context, &ccache);
+ if (problem) {}
+ else {
+ problem = krb5_cc_copy_cache(ssh_context, mem_ccache, ccache);
+ if (problem) {}
+ }
+
+ krb5_cc_close(ssh_context, ccache);
+ }
+
+ krb5_cleanup_proc(NULL);
+ }
+#endif /* KRB5 */
+
if (xauthfile)
child_set_env(&env, &envsize, "XAUTHORITY", xauthfile);
if (auth_get_socket_name() != NULL)
@@ -2559,10 +2796,6 @@ do_child(const char *command, struct passwd * pw, const char *term,
*/
endpwent();
-#ifdef LOGIN_CAP
- login_close(lc);
-#endif /* LOGIN_CAP */
-
/*
* Close any extra open file descriptors so that we don\'t have them
* hanging around in clients. Note that we want to do this after
@@ -2573,9 +2806,46 @@ do_child(const char *command, struct passwd * pw, const char *term,
close(i);
/* Change current directory to the user\'s home directory. */
- if (chdir(pw->pw_dir) < 0)
+ if (
+#ifdef __FreeBSD__
+ !*pw->pw_dir ||
+#endif /* __FreeBSD__ */
+ chdir(pw->pw_dir) < 0
+ ) {
+#ifdef __FreeBSD__
+ int quiet_login = 0;
+#endif /* __FreeBSD__ */
+#ifdef LOGIN_CAP
+ if (login_getcapbool(lc, "requirehome", 0)) {
+ (void)printf("Home directory not available\n");
+ log("LOGIN %.200s REFUSED (HOMEDIR) ON TTY %.200s",
+ pw->pw_name, ttyname);
+ exit(254);
+ }
+#endif /* LOGIN_CAP */
+#ifdef __FreeBSD__
+ if (chdir("/") < 0) {
+ (void)printf("Cannot find root directory\n");
+ log("LOGIN %.200s REFUSED (ROOTDIR) ON TTY %.200s",
+ pw->pw_name, ttyname);
+ exit(254);
+ }
+#ifdef LOGIN_CAP
+ quiet_login = login_getcapbool(lc, "hushlogin", 0);
+#endif /* LOGIN_CAP */
+ if (!quiet_login || *pw->pw_dir)
+ (void)printf(
+ "No home directory.\nLogging in with home = \"/\".\n");
+
+#else /* !__FreeBSD__ */
+
fprintf(stderr, "Could not chdir to home directory %s: %s\n",
pw->pw_dir, strerror(errno));
+#endif /* __FreeBSD__ */
+ }
+#ifdef LOGIN_CAP
+ login_close(lc);
+#endif /* LOGIN_CAP */
/*
* Must take new environment into use so that .ssh/rc, /etc/sshrc and
@@ -2588,26 +2858,6 @@ do_child(const char *command, struct passwd * pw, const char *term,
* in this order).
*/
if (!options.use_login) {
-#ifdef __FreeBSD__
- /*
- * If the password change time is set and has passed, give the
- * user a password expiry notice and chance to change it.
- */
- if (pw->pw_change != 0) {
- struct timeval tv;
-
- (void)gettimeofday(&tv, NULL);
- if (tv.tv_sec >= pw->pw_change) {
- (void)printf(
- "Sorry -- your password has expired.\n");
- syslog(LOG_INFO,
- "%s Password expired - forcing change",
- pw->pw_name);
- if (system("/usr/bin/passwd") != 0)
- perror("/usr/bin/passwd");
- }
- }
-#endif /* __FreeBSD__ */
if (stat(SSH_USER_RC, &st) >= 0) {
if (debug_flag)
fprintf(stderr, "Running /bin/sh %s\n", SSH_USER_RC);
@@ -2675,7 +2925,11 @@ do_child(const char *command, struct passwd * pw, const char *term,
mailbox = getenv("MAIL");
if (mailbox != NULL) {
if (stat(mailbox, &mailstat) != 0 || mailstat.st_size == 0)
+#ifdef __FreeBSD__
+ ;
+#else /* !__FreeBSD__ */
printf("No mail.\n");
+#endif /* __FreeBSD__ */
else if (mailstat.st_mtime < mailstat.st_atime)
printf("You have mail.\n");
else
OpenPOWER on IntegriCloud