diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 1999-10-07 21:45:04 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 1999-10-07 21:45:04 +0000 |
commit | 6e7e05417a32dd36ddfb2755a30aaef99f727d97 (patch) | |
tree | 1627a5eea59bd10356b842f5b7ed0346717a98a4 /usr.bin/ssh | |
parent | 3420dc17a77c97696c3c678a6b8725d22c9d6a73 (diff) |
add skey to sshd:
1) pass *pw to auth_password() not user_name, do_authentication already
keeps private copy of struct passwd for current user.
2) limit authentication attemps to 5, otherwise
ssh -o 'NumberOfPasswordPrompts 100000' host
lets you enter 100000 passwds
3) make s/key a run-time option in /etc/sshd_config
4) generate fake skeys,
for s/key for nonexisting users, too
limit auth-tries for nonexisting users, too.
Note that
% ssh -l nonexisting-user -o 'NumberOfPasswordPrompts 100000' host
has NO limits in ssh-1.2.27
Diffstat (limited to 'usr.bin/ssh')
-rw-r--r-- | usr.bin/ssh/Makefile.inc | 2 | ||||
-rw-r--r-- | usr.bin/ssh/auth-passwd.c | 66 | ||||
-rw-r--r-- | usr.bin/ssh/auth-skey.c | 148 | ||||
-rw-r--r-- | usr.bin/ssh/servconf.c | 23 | ||||
-rw-r--r-- | usr.bin/ssh/servconf.h | 5 | ||||
-rw-r--r-- | usr.bin/ssh/ssh.h | 9 | ||||
-rw-r--r-- | usr.bin/ssh/sshd.8 | 57 | ||||
-rw-r--r-- | usr.bin/ssh/sshd.c | 35 | ||||
-rw-r--r-- | usr.bin/ssh/sshd/Makefile | 10 | ||||
-rw-r--r-- | usr.bin/ssh/sshd_config | 2 |
10 files changed, 300 insertions, 57 deletions
diff --git a/usr.bin/ssh/Makefile.inc b/usr.bin/ssh/Makefile.inc index 0be2a7ac5d7..b6d0347f032 100644 --- a/usr.bin/ssh/Makefile.inc +++ b/usr.bin/ssh/Makefile.inc @@ -1 +1 @@ -CFLAGS+= -I${.OBJDIR} -I${.CURDIR}/.. +CFLAGS+= -I${.CURDIR}/.. diff --git a/usr.bin/ssh/auth-passwd.c b/usr.bin/ssh/auth-passwd.c index b4873f7f085..1143c85a0c7 100644 --- a/usr.bin/ssh/auth-passwd.c +++ b/usr.bin/ssh/auth-passwd.c @@ -15,7 +15,7 @@ the password is valid for the user. */ #include "includes.h" -RCSID("$Id: auth-passwd.c,v 1.5 1999/09/30 04:30:03 deraadt Exp $"); +RCSID("$Id: auth-passwd.c,v 1.6 1999/10/07 21:45:02 markus Exp $"); #include "packet.h" #include "ssh.h" @@ -29,14 +29,10 @@ extern char *ticket; /* Tries to authenticate the user using password. Returns true if authentication succeeds. */ -int auth_password(const char *server_user, const char *password) +int auth_password(struct passwd *pw, const char *password) { extern ServerOptions options; - extern char *crypt(const char *key, const char *salt); - struct passwd *pw; char *encrypted_password; - char correct_passwd[200]; - char *saved_pw_name, *saved_pw_passwd; if (*password == '\0' && options.permit_empty_passwd == 0) { @@ -44,14 +40,32 @@ int auth_password(const char *server_user, const char *password) return 0; } - /* Get the encrypted password for the user. */ - pw = getpwnam(server_user); - if (!pw) + /* deny if no user. */ + if (pw == NULL) return 0; - saved_pw_name = xstrdup(pw->pw_name); - saved_pw_passwd = xstrdup(pw->pw_passwd); - +#ifdef SKEY + if (options.skey_authentication == 1) { + if (strncasecmp(password, "s/key", 5) == 0) { + char *skeyinfo = skey_keyinfo(pw->pw_name); + if(skeyinfo == NULL){ + debug("generating fake skeyinfo for %.100s.", pw->pw_name); + skeyinfo = skey_fake_keyinfo(pw->pw_name); + } + if(skeyinfo != NULL) + packet_send_debug(skeyinfo); + /* Try again. */ + return 0; + } + else if (skey_haskey(pw->pw_name) == 0 && + skey_passcheck(pw->pw_name, (char *)password) != -1) { + /* Authentication succeeded. */ + return 1; + } + /* Fall back to ordinary passwd authentication. */ + } +#endif + #if defined(KRB4) /* Support for Kerberos v4 authentication - Dug Song <dugsong@UMICH.EDU> */ if (options.kerberos_authentication) @@ -72,15 +86,15 @@ int auth_password(const char *server_user, const char *password) /* Set up our ticket file. */ if (!ssh_tf_init(pw->pw_uid)) { log("Couldn't initialize Kerberos ticket file for %s!", - server_user); + pw->pw_name); goto kerberos_auth_failure; } /* Try to get TGT using our password. */ - r = krb_get_pw_in_tkt((char *)server_user, "", realm, "krbtgt", realm, + r = krb_get_pw_in_tkt((char *)pw->pw_name, "", 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]); + "failed: %s", pw->pw_name, krb_err_txt[r]); goto kerberos_auth_failure; } /* Successful authentication. */ @@ -105,7 +119,7 @@ int auth_password(const char *server_user, const char *password) 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]); + "krb_rd_req: %s", pw->pw_name, krb_err_txt[r]); } else if (r != KSUCCESS) { log("Kerberos V4 %s ticket unverifiable: %s", @@ -116,13 +130,13 @@ int auth_password(const char *server_user, const char *password) 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, + "not registered, or srvtab is wrong?", pw->pw_name, 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]); + "%s: %s", pw->pw_name, krb_err_txt[r]); goto kerberos_auth_failure; } @@ -142,25 +156,19 @@ int auth_password(const char *server_user, const char *password) /* Fall back to ordinary passwd authentication. */ } #endif /* KRB4 */ - - /* Save the encrypted password. */ - strlcpy(correct_passwd, saved_pw_passwd, sizeof(correct_passwd)); - + /* Check for users with no password. */ - if (strcmp(password, "") == 0 && strcmp(correct_passwd, "") == 0) + if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0) { packet_send_debug("Login permitted without a password because the account has no password."); return 1; /* The user has no password and an empty password was tried. */ } - xfree(saved_pw_name); - xfree(saved_pw_passwd); - /* Encrypt the candidate password using the proper salt. */ encrypted_password = crypt(password, - (correct_passwd[0] && correct_passwd[1]) ? - correct_passwd : "xx"); + (pw->pw_passwd[0] && pw->pw_passwd[1]) ? + pw->pw_passwd : "xx"); /* Authentication is accepted if the encrypted passwords are identical. */ - return (strcmp(encrypted_password, correct_passwd) == 0); + return (strcmp(encrypted_password, pw->pw_passwd) == 0); } diff --git a/usr.bin/ssh/auth-skey.c b/usr.bin/ssh/auth-skey.c new file mode 100644 index 00000000000..fe3103bd352 --- /dev/null +++ b/usr.bin/ssh/auth-skey.c @@ -0,0 +1,148 @@ +#include "includes.h" +RCSID("$Id: auth-skey.c,v 1.1 1999/10/07 21:45:02 markus Exp $"); + +#include "ssh.h" +#include <sha1.h> + +/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */ + + +#define ROUND(x) (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \ + ((x)[3])) + +/* + * hash_collapse() + */ +static u_int32_t +hash_collapse(s) + u_char *s; +{ + int len, target; + u_int32_t i; + + if ((strlen(s) % sizeof(u_int32_t)) == 0) + target = strlen(s); /* Multiple of 4 */ + else + target = strlen(s) - (strlen(s) % sizeof(u_int32_t)); + + for (i = 0, len = 0; len < target; len += 4) + i ^= ROUND(s + len); + + return i; +} +char * +skey_fake_keyinfo(char *username) +{ + int i; + u_int ptr; + u_char hseed[SKEY_MAX_SEED_LEN], flg = 1, *up; + char pbuf[SKEY_MAX_PW_LEN+1]; + static char skeyprompt[SKEY_MAX_CHALLENGE+1]; + char *secret = NULL; + size_t secretlen = 0; + SHA1_CTX ctx; + char *p, *u; + + /* + * Base first 4 chars of seed on hostname. + * Add some filler for short hostnames if necessary. + */ + if (gethostname(pbuf, sizeof(pbuf)) == -1) + *(p = pbuf) = '.'; + else + for (p = pbuf; *p && isalnum(*p); p++) + if (isalpha(*p) && isupper(*p)) + *p = tolower(*p); + if (*p && pbuf - p < 4) + (void)strncpy(p, "asjd", 4 - (pbuf - p)); + pbuf[4] = '\0'; + + /* Hash the username if possible */ + if ((up = SHA1Data(username, strlen(username), NULL)) != NULL) { + struct stat sb; + time_t t; + int fd; + + /* Collapse the hash */ + ptr = hash_collapse(up); + memset(up, 0, strlen(up)); + + /* See if the random file's there, else use ctime */ + if ((fd = open(_SKEY_RAND_FILE_PATH_, O_RDONLY)) != -1 + && fstat(fd, &sb) == 0 && + sb.st_size > (off_t)SKEY_MAX_SEED_LEN && + lseek(fd, ptr % (sb.st_size - SKEY_MAX_SEED_LEN), + SEEK_SET) != -1 && read(fd, hseed, + SKEY_MAX_SEED_LEN) == SKEY_MAX_SEED_LEN) { + close(fd); + secret = hseed; + secretlen = SKEY_MAX_SEED_LEN; + flg = 0; + } else if (!stat(_PATH_MEM, &sb) || !stat("/", &sb)) { + t = sb.st_ctime; + secret = ctime(&t); + secretlen = strlen(secret); + flg = 0; + } + } + + /* Put that in your pipe and smoke it */ + if (flg == 0) { + /* Hash secret value with username */ + SHA1Init(&ctx); + SHA1Update(&ctx, secret, secretlen); + SHA1Update(&ctx, username, strlen(username)); + SHA1End(&ctx, up); + + /* Zero out */ + memset(secret, 0, secretlen); + + /* Now hash the hash */ + SHA1Init(&ctx); + SHA1Update(&ctx, up, strlen(up)); + SHA1End(&ctx, up); + + ptr = hash_collapse(up + 4); + + for (i = 4; i < 9; i++) { + pbuf[i] = (ptr % 10) + '0'; + ptr /= 10; + } + pbuf[i] = '\0'; + + /* Sequence number */ + ptr = ((up[2] + up[3]) % 99) + 1; + + memset(up, 0, 20); /* SHA1 specific */ + free(up); + + (void)sprintf(skeyprompt, + "otp-%.*s %d %.*s", + SKEY_MAX_HASHNAME_LEN, + skey_get_algorithm(), + ptr, SKEY_MAX_SEED_LEN, + pbuf); + } else { + /* Base last 8 chars of seed on username */ + u = username; + i = 8; + p = &pbuf[4]; + do { + if (*u == 0) { + /* Pad remainder with zeros */ + while (--i >= 0) + *p++ = '0'; + break; + } + + *p++ = (*u++ % 10) + '0'; + } while (--i != 0); + pbuf[12] = '\0'; + + (void)sprintf(skeyprompt, "otp-%.*s %d %.*s", + SKEY_MAX_HASHNAME_LEN, + skey_get_algorithm(), + 99, SKEY_MAX_SEED_LEN, pbuf); + } + return skeyprompt; +} diff --git a/usr.bin/ssh/servconf.c b/usr.bin/ssh/servconf.c index f68ecb10ab3..ab8cac6d2ea 100644 --- a/usr.bin/ssh/servconf.c +++ b/usr.bin/ssh/servconf.c @@ -12,7 +12,7 @@ Created: Mon Aug 21 15:48:58 1995 ylo */ #include "includes.h" -RCSID("$Id: servconf.c,v 1.9 1999/10/02 19:18:22 deraadt Exp $"); +RCSID("$Id: servconf.c,v 1.10 1999/10/07 21:45:02 markus Exp $"); #include "ssh.h" #include "servconf.h" @@ -52,6 +52,9 @@ void initialize_server_options(ServerOptions *options) options->afs_token_passing = -1; #endif options->password_authentication = -1; +#ifdef SKEY + options->skey_authentication = -1; +#endif options->permit_empty_passwd = -1; options->num_allow_hosts = 0; options->num_deny_hosts = 0; @@ -120,8 +123,12 @@ void fill_default_server_options(ServerOptions *options) #endif /* AFS */ if (options->password_authentication == -1) options->password_authentication = 1; +#ifdef SKEY + if (options->skey_authentication == -1) + options->skey_authentication = 1; +#endif if (options->permit_empty_passwd == -1) - options->permit_empty_passwd = 1; + options->permit_empty_passwd = 1; } #define WHITESPACE " \t\r\n" @@ -138,6 +145,9 @@ typedef enum #ifdef AFS sKerberosTgtPassing, sAFSTokenPassing, #endif +#ifdef SKEY + sSkeyAuthentication, +#endif sPasswordAuthentication, sAllowHosts, sDenyHosts, sListenAddress, sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives @@ -172,6 +182,9 @@ static struct { "afstokenpassing", sAFSTokenPassing }, #endif { "passwordauthentication", sPasswordAuthentication }, +#ifdef SKEY + { "skeyauthentication", sSkeyAuthentication }, +#endif { "allowhosts", sAllowHosts }, { "denyhosts", sDenyHosts }, { "listenaddress", sListenAddress }, @@ -392,6 +405,12 @@ void read_server_config(ServerOptions *options, const char *filename) intptr = &options->password_authentication; goto parse_flag; +#ifdef SKEY + case sSkeyAuthentication: + intptr = &options->skey_authentication; + goto parse_flag; +#endif + case sPrintMotd: intptr = &options->print_motd; goto parse_flag; diff --git a/usr.bin/ssh/servconf.h b/usr.bin/ssh/servconf.h index d87b83c965d..8a838011594 100644 --- a/usr.bin/ssh/servconf.h +++ b/usr.bin/ssh/servconf.h @@ -13,7 +13,7 @@ Definitions for server configuration data and for the functions reading it. */ -/* RCSID("$Id: servconf.h,v 1.4 1999/10/01 02:38:09 provos Exp $"); */ +/* RCSID("$Id: servconf.h,v 1.5 1999/10/07 21:45:02 markus Exp $"); */ #ifndef SERVCONF_H #define SERVCONF_H @@ -54,6 +54,9 @@ typedef struct int afs_token_passing; /* If true, permit AFS token passing. */ #endif int password_authentication; /* If true, permit password authentication. */ +#ifdef SKEY + int skey_authentication; /* If true, permit s/key authentication. */ +#endif int permit_empty_passwd; /* If false, do not permit empty passwords. */ unsigned int num_allow_hosts; char *allow_hosts[MAX_ALLOW_HOSTS]; diff --git a/usr.bin/ssh/ssh.h b/usr.bin/ssh/ssh.h index 1586ace8b22..756a795b8bc 100644 --- a/usr.bin/ssh/ssh.h +++ b/usr.bin/ssh/ssh.h @@ -13,7 +13,7 @@ Generic header file for ssh. */ -/* RCSID("$Id: ssh.h,v 1.8 1999/10/05 22:18:52 markus Exp $"); */ +/* RCSID("$Id: ssh.h,v 1.9 1999/10/07 21:45:02 markus Exp $"); */ #ifndef SSH_H #define SSH_H @@ -260,7 +260,7 @@ int auth_rhosts_rsa(struct passwd *pw, const char *client_user, /* Tries to authenticate the user using password. Returns true if authentication succeeds. */ -int auth_password(const char *server_user, const char *password); +int auth_password(struct passwd *pw, const char *password); /* Performs the RSA authentication dialog with the client. This returns 0 if the client could not be authenticated, and 1 if authentication was @@ -583,4 +583,9 @@ int radix_to_creds(const char *buf, CREDENTIALS *creds); #endif /* KRB4 */ +#ifdef SKEY +#include <skey.h> +char *skey_fake_keyinfo(char *username); +#endif /* SKEY */ + #endif /* SSH_H */ diff --git a/usr.bin/ssh/sshd.8 b/usr.bin/ssh/sshd.8 index e32a9ae89ee..d088b62105f 100644 --- a/usr.bin/ssh/sshd.8 +++ b/usr.bin/ssh/sshd.8 @@ -9,7 +9,7 @@ .\" .\" Created: Sat Apr 22 21:55:14 1995 ylo .\" -.\" $Id: sshd.8,v 1.6 1999/10/03 18:46:12 aaron Exp $ +.\" $Id: sshd.8,v 1.7 1999/10/07 21:45:02 markus Exp $ .\" .Dd September 25, 1999 .Dt SSHD 8 @@ -126,14 +126,22 @@ indicates no limit. .It Fl h Ar host_key_file Specifies the file from which the host key is read (default .Pa /etc/ssh_host_key ) . -This option must be given if sshd is not run as root (as the normal +This option must be given if +.Nm +is not run as root (as the normal host file is normally not readable by anyone but root). .It Fl i -Specifies that sshd is being run from inetd. Sshd is normally not run +Specifies that +.Nm +is being run from inetd. +.Nm +is normally not run from inetd because it needs to generate the server key before it can respond to the client, and this may take tens of seconds. Clients would have to wait too long if the key was regenerated every time. -However, with small key sizes (e.g. 512) using sshd from inetd may +However, with small key sizes (e.g. 512) using +.Nm +from inetd may be feasible. .It Fl k Ar key_gen_time Specifies how often the server key is regenerated (default 3600 @@ -182,7 +190,7 @@ are allowed to connect. Note that .Nm can also be configured to use tcp_wrappers using the -.Fl LIBWARP +.Sy LIBWARP compile-time option. .It Cm DenyHosts This keyword can be followed by any number of host name patterns, @@ -228,7 +236,8 @@ To disable keepalives, the value should be set to in both the server and the client configuration files. .It Cm KerberosAuthentication Specifies whether Kerberos authentication is allowed. This can -be in the form of a Kerberos ticket, or if PasswordAuthentication +be in the form of a Kerberos ticket, or if +.Cm PasswordAuthentication is yes, the password provided by the user will be validated through the Kerberos KDC. Default is .Dq yes . @@ -245,8 +254,8 @@ Default is .Dq no , as this only works when the Kerberos KDC is actually an AFS kaserver. .It Cm KerberosTicketCleanup -Specifies whether to automatically destroy the user's -ticket cache file on logout. Default is +Specifies whether to automatically destroy the user's ticket cache +file on logout. Default is .Dq yes . .It Cm KeyRegenerationInterval The server key is automatically regenerated after this many seconds @@ -255,6 +264,11 @@ decrypting captured sessions by later breaking into the machine and stealing the keys. The key is never stored anywhere. If the value is 0, the key is never regenerated. The default is 3600 (seconds). +.It Cm ListenAddress +Specifies what local address +.Nm +should listen on. +The default is to listen to all local addresses. .It Cm LoginGraceTime The server disconnects after this time if the user has not successfully logged in. If the value is 0, there is no time limit. @@ -304,7 +318,9 @@ Obsolete. Random number generation uses other techniques. .It Cm RhostsAuthentication Specifies whether authentication using rhosts or /etc/hosts.equiv files is sufficient. Normally, this method should not be permitted -because it is insecure. RhostsRSAAuthentication should be used +because it is insecure. +.Cm RhostsRSAAuthentication +should be used instead, because it performs RSA-based host authentication in addition to normal rhosts or /etc/hosts.equiv authentication. The default is @@ -319,11 +335,20 @@ Specifies whether pure RSA authentication is allowed. The default is .It Cm ServerKeyBits Defines the number of bits in the server key. The minimum value is 512, and the default is 768. +.It Cm SkeyAuthentication +Specifies whether +.Xr skey 1 +authentication is allowed. The default is +.Dq yes . +Note that s/key authentication is enabled only if +.Cm PasswordAuthentication +is allowed, too. .It Cm StrictModes Specifies whether SSH should check file modes and ownership of the user's home directory and rhosts files before accepting login. This is normally desirable because novices sometimes accidentally leave their -directory or files world-writable. The default is "yes". +directory or files world-writable. The default is +.Dq yes . .It Cm SyslogFacility Gives the facility code that is used when logging messages from .Nm sshd . @@ -516,19 +541,17 @@ Contains configuration data for This file should be writable by root only, but it is recommended (though not necessary) that it be world-readable. .It Pa /etc/ssh_host_key -Contains the private part of the host key. This file is normally -created automatically by "make install", but can also be created -manually using -.Xr ssh-keygen 1 . +Contains the private part of the host key. This file should only be owned by root, readable only by root, and not accessible to others. .It Pa /etc/ssh_host_key.pub -Contains the public part of the host key. This file is normally -created automatically by "make install", but can also be created -manually. This file should be world-readable but writable only by +Contains the public part of the host key. +This file should be world-readable but writable only by root. Its contents should match the private part. This file is not really used for anything; it is only provided for the convenience of the user so its contents can be copied to known hosts files. +These two files are created using +.Xr ssh-keygen 1 . .It Pa /var/run/sshd.pid Contains the process ID of the .Nm diff --git a/usr.bin/ssh/sshd.c b/usr.bin/ssh/sshd.c index 166c9256a9e..5c5317eec34 100644 --- a/usr.bin/ssh/sshd.c +++ b/usr.bin/ssh/sshd.c @@ -18,7 +18,7 @@ agent connections. */ #include "includes.h" -RCSID("$Id: sshd.c,v 1.23 1999/10/07 04:40:03 deraadt Exp $"); +RCSID("$Id: sshd.c,v 1.24 1999/10/07 21:45:02 markus Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -938,11 +938,14 @@ void do_connection(int privileged_port) in as (received from the clinet). Privileged_port is true if the connection comes from a privileged port (used for .rhosts authentication).*/ +#define MAX_AUTH_FAILURES 5 + void do_authentication(char *user, int privileged_port) { int type; int authenticated = 0; + int authentication_failures = 0; char *password; struct passwd *pw, pwcopy; char *client_user; @@ -972,13 +975,30 @@ do_authentication(char *user, int privileged_port) { /* Read a packet. This will not return if the client disconnects. */ int plen; - (void) packet_read(&plen); - + int type = packet_read(&plen); +#ifdef SKEY + int passw_len; + char *password, *skeyinfo; + if (options.password_authentication && + options.skey_authentication == 1 && + type == SSH_CMSG_AUTH_PASSWORD && + (password = packet_get_string(&passw_len)) != NULL && + passw_len == 5 && + strncasecmp(password, "s/key", 5) == 0 && + (skeyinfo = skey_fake_keyinfo(user)) != NULL ){ + /* Send a fake s/key challenge. */ + packet_send_debug(skeyinfo); + } +#endif /* Send failure. This should be indistinguishable from a failed authentication. */ packet_start(SSH_SMSG_FAILURE); packet_send(); packet_write_wait(); + if (++authentication_failures >= MAX_AUTH_FAILURES) { + packet_disconnect("To many authentication failures for %.100s from %.200s", + user, get_canonical_hostname()); + } } /*NOTREACHED*/ abort(); @@ -1006,7 +1026,7 @@ do_authentication(char *user, int privileged_port) #ifdef KRB4 options.kerberos_or_local_passwd && #endif /* KRB4 */ - auth_password(user, "")) + auth_password(pw, "")) { /* Authentication with empty password succeeded. */ debug("Login for user %.100s accepted without authentication.", user); @@ -1243,7 +1263,7 @@ do_authentication(char *user, int privileged_port) } /* Try authentication with the password. */ - if (auth_password(user, password)) + if (auth_password(pw, password)) { /* Successful authentication. */ /* Clear the password from memory. */ @@ -1272,6 +1292,11 @@ do_authentication(char *user, int privileged_port) packet_start(SSH_SMSG_FAILURE); packet_send(); packet_write_wait(); + + if (++authentication_failures >= MAX_AUTH_FAILURES) { + packet_disconnect("To many authentication failures for %.100s from %.200s", + pw->pw_name, get_canonical_hostname()); + } } /* Check if the user is logging in as root and root logins are disallowed. */ diff --git a/usr.bin/ssh/sshd/Makefile b/usr.bin/ssh/sshd/Makefile index db22b53ed29..f2d01164527 100644 --- a/usr.bin/ssh/sshd/Makefile +++ b/usr.bin/ssh/sshd/Makefile @@ -27,6 +27,10 @@ DPADD+= ${LIBKRBAFS} .endif # AFS .endif # KERBEROS +.if (${SKEY} == "yes") +SRCS+= auth-skey.c +.endif + .include <bsd.prog.mk> LDADD+= -lcrypto -lutil -lz @@ -37,3 +41,9 @@ CFLAGS+= -DLIBWRAP LDADD+= -lwrap DPADD+= ${LIBWRAP} .endif + +.if (${SKEY} == "yes") +CFLAGS+= -DSKEY +LDADD+= -lskey +DPADD+= ${SKEY} +.endif diff --git a/usr.bin/ssh/sshd_config b/usr.bin/ssh/sshd_config index 3c5e41879fa..5f30462b301 100644 --- a/usr.bin/ssh/sshd_config +++ b/usr.bin/ssh/sshd_config @@ -29,6 +29,8 @@ RSAAuthentication yes # To disable tunneled clear text passwords, change to no here! PasswordAuthentication yes PermitEmptyPasswords no +# Uncomment to disable s/key passwords +#SkeyAuthentication no # To change Kerberos options #KerberosAuthentication no |