Precedence: bulk Hi folks, It seemed to me that it would be useful to be able to control access to my server with the /etc/ssh_known_hosts file, using RSA authentication of the remote host. But the protocol only allows RSA host authentication in conjunction with rhosts, while I prefer RSA user authentication. I've made a patch to the server which adds a new configuration option: RSAHostOtherAuthentication. When this option is enabled RSA host authentication is turned on, but without the rhosts check. Also, RSA host authentication on its own is insufficient to authenticate the user. The server also requires one other authentication method to succeed. It doesn't matter which, and the order in which the methods are tried doesn't matter. With this modified server I can enable RSA authentication of both the remote host and the user. This only works if the client is willing to try different authentication methods if the first doesn't succeed. I'm happy with this, but does it make sense? Is there any obvious flaw? Ron diff -c openssh-2.1.1p4.orig/auth-rh-rsa.c openssh-2.1.1p4/auth-rh-rsa.c *** openssh-2.1.1p4.orig/auth-rh-rsa.c Thu Jun 22 12:32:31 2000 --- openssh-2.1.1p4/auth-rh-rsa.c Fri Aug 4 10:25:55 2000 *************** *** 47,53 **** return 0; /* Check if we would accept it using rhosts authentication. */ ! if (!auth_rhosts(pw, client_user)) return 0; canonical_hostname = get_canonical_hostname(); --- 47,54 ---- return 0; /* Check if we would accept it using rhosts authentication. */ ! /* But not if we're doing RSA host/other authentication. */ ! if (!options.rsa_host_other_authentication && !auth_rhosts(pw, client_user)) return 0; canonical_hostname = get_canonical_hostname(); diff -c openssh-2.1.1p4.orig/auth1.c openssh-2.1.1p4/auth1.c *** openssh-2.1.1p4.orig/auth1.c Sat Jul 8 01:44:14 2000 --- openssh-2.1.1p4/auth1.c Fri Aug 4 11:04:57 2000 *************** *** 31,36 **** --- 31,40 ---- extern char **saved_argv; #endif /* HAVE_OSF_SIA */ + #define AUTH_RSA_HOST 1 + #define AUTH_OTHER 2 + #define AUTH_BOTH (AUTH_RSA_HOST|AUTH_OTHER) + /* * convert ssh auth msg type into description */ *************** *** 150,155 **** --- 154,160 ---- unsigned int ulen; int type = 0; void (*authlog) (const char *fmt,...) = verbose; + int authenticated_so_far = 0; /* Indicate that authentication is needed. */ packet_start(SSH_SMSG_FAILURE); *************** *** 371,376 **** --- 376,404 ---- break; } + /* + * If we require both RSA host and some other authentication + * check that we've obtained two distinct authentications. + */ + if ( options.rsa_host_other_authentication && authenticated ) { + if ( type == SSH_CMSG_AUTH_RHOSTS_RSA ) { + authenticated_so_far |= AUTH_RSA_HOST ; + } + else { + authenticated_so_far |= AUTH_OTHER ; + } + + if ( authenticated_so_far == AUTH_BOTH ) { + verbose("Both RSA host and other authentication accepted."); + packet_send_debug("Both RSA host and other authentication accepted."); + } + else { + authenticated = 0 ; + verbose("Awaiting further authentication."); + packet_send_debug("Awaiting further authentication."); + } + } + /* * Check if the user is logging in as root and root logins * are disallowed. diff -c openssh-2.1.1p4.orig/servconf.c openssh-2.1.1p4/servconf.c *** openssh-2.1.1p4.orig/servconf.c Sat Jul 15 05:14:17 2000 --- openssh-2.1.1p4/servconf.c Fri Aug 4 10:49:16 2000 *************** *** 52,57 **** --- 52,58 ---- options->rhosts_authentication = -1; options->rhosts_rsa_authentication = -1; options->rsa_authentication = -1; + options->rsa_host_other_authentication = -1; options->dsa_authentication = -1; #ifdef KRB4 options->kerberos_authentication = -1; *************** *** 130,135 **** --- 131,138 ---- options->rhosts_rsa_authentication = 0; if (options->rsa_authentication == -1) options->rsa_authentication = 1; + if (options->rsa_host_other_authentication == -1) + options->rsa_host_other_authentication = 0; if (options->dsa_authentication == -1) options->dsa_authentication = 1; #ifdef KRB4 *************** *** 170,175 **** --- 173,179 ---- sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication, + sRSAHostOtherAuthentication, #ifdef KRB4 sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, #endif *************** *** 205,210 **** --- 209,215 ---- { "rhostsauthentication", sRhostsAuthentication }, { "rhostsrsaauthentication", sRhostsRSAAuthentication }, { "rsaauthentication", sRSAAuthentication }, + { "rsahostotherauthentication", sRSAHostOtherAuthentication }, { "dsaauthentication", sDSAAuthentication }, #ifdef KRB4 { "kerberosauthentication", sKerberosAuthentication }, *************** *** 457,462 **** --- 462,471 ---- intptr = &options->rhosts_rsa_authentication; goto parse_flag; + case sRSAHostOtherAuthentication: + intptr = &options->rsa_host_other_authentication; + goto parse_flag; + case sRSAAuthentication: intptr = &options->rsa_authentication; goto parse_flag; diff -c openssh-2.1.1p4.orig/servconf.h openssh-2.1.1p4/servconf.h *** openssh-2.1.1p4.orig/servconf.h Tue Jul 11 08:31:38 2000 --- openssh-2.1.1p4/servconf.h Fri Aug 4 10:26:09 2000 *************** *** 61,66 **** --- 61,68 ---- int rhosts_rsa_authentication; /* If true, permit rhosts RSA * authentication. */ int rsa_authentication; /* If true, permit RSA authentication. */ + int rsa_host_other_authentication; /* If true, require RSA host + * authentication and some other. */ int dsa_authentication; /* If true, permit DSA authentication. */ #ifdef KRB4 int kerberos_authentication; /* If true, permit Kerberos diff -c openssh-2.1.1p4.orig/sshd.8 openssh-2.1.1p4/sshd.8 *** openssh-2.1.1p4.orig/sshd.8 Tue Jul 11 08:31:39 2000 --- openssh-2.1.1p4/sshd.8 Fri Aug 4 11:09:06 2000 *************** *** 530,535 **** --- 530,541 ---- The default is .Dq yes . Note that this option applies to protocol version 1 only. + .It Cm RSAHostOtherAuthentication + Specifies whether a combination of RSA host and some other form of + authentication is required. + .Cm RhostsRSAAuthentication + will be enabled automatically if this option is enabled, but the rhost + authentication part will be ignored. .It Cm ServerKeyBits Defines the number of bits in the server key. The minimum value is 512, and the default is 768. diff -c openssh-2.1.1p4.orig/sshd.c openssh-2.1.1p4/sshd.c *** openssh-2.1.1p4.orig/sshd.c Wed Jul 12 00:45:27 2000 --- openssh-2.1.1p4/sshd.c Fri Aug 4 10:52:33 2000 *************** *** 977,982 **** --- 977,985 ---- * programs. Of course, if the intruder has root access on his local * machine, he can connect from any port. So do not use these * authentication methods from machines that you do not trust. + * + * If we're doing RSA host/other authentication we must have rhosts/RSA, + * but this is OK because we won't use rhosts authentication. */ if (remote_port >= IPPORT_RESERVED || remote_port < IPPORT_RESERVED / 2) { *************** *** 983,988 **** --- 986,994 ---- options.rhosts_authentication = 0; options.rhosts_rsa_authentication = 0; } + if ( options.rsa_host_other_authentication ) { + options.rhosts_rsa_authentication = 1; + } #ifdef KRB4 if (!packet_connection_is_ipv4() && options.kerberos_authentication) {