summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--auth-rhosts.c27
-rw-r--r--auth.h7
-rw-r--r--auth2.c161
-rw-r--r--buffer.c11
-rw-r--r--canohost.c57
-rw-r--r--canohost.h4
-rw-r--r--compat.c6
-rw-r--r--compat.h3
-rw-r--r--hostfile.c4
-rw-r--r--pathnames.h5
-rw-r--r--readconf.c16
-rw-r--r--readconf.h3
-rw-r--r--servconf.c21
-rw-r--r--servconf.h4
-rw-r--r--ssh.c42
-rw-r--r--sshconnect.c8
-rw-r--r--sshconnect.h38
-rw-r--r--sshconnect1.c20
-rw-r--r--sshconnect2.c111
-rw-r--r--sshd_config4
21 files changed, 464 insertions, 99 deletions
diff --git a/ChangeLog b/ChangeLog
index 98dbed58c..708e59917 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,15 @@
4 [ssh.c] 4 [ssh.c]
5 show debug output during option processing, report from 5 show debug output during option processing, report from
6 pekkas@netcore.fi 6 pekkas@netcore.fi
7 - OpenBSD CVS Sync
8 - markus@cvs.openbsd.org 2001/04/12 19:15:26
9 [auth-rhosts.c auth.h auth2.c buffer.c canohost.c canohost.h
10 compat.c compat.h hostfile.c pathnames.h readconf.c readconf.h
11 servconf.c servconf.h ssh.c sshconnect.c sshconnect.h sshconnect1.c
12 sshconnect2.c sshd_config]
13 implement HostbasedAuthentication (= RhostRSAAuthentication for ssh v2)
14 similar to RhostRSAAuthentication unless you enable (the experimental)
15 HostbasedUsesNameFromPacketOnly option. please test. :)
7 - (bal) Added openbsd-compat/inet_ntop.[ch] since HP/UX (and others) 16 - (bal) Added openbsd-compat/inet_ntop.[ch] since HP/UX (and others)
8 lack it. 17 lack it.
9 18
@@ -5026,4 +5035,4 @@
5026 - Wrote replacements for strlcpy and mkdtemp 5035 - Wrote replacements for strlcpy and mkdtemp
5027 - Released 1.0pre1 5036 - Released 1.0pre1
5028 5037
5029$Id: ChangeLog,v 1.1102 2001/04/12 21:35:52 mouring Exp $ 5038$Id: ChangeLog,v 1.1103 2001/04/12 23:34:34 mouring Exp $
diff --git a/auth-rhosts.c b/auth-rhosts.c
index c71e9b55d..324a0f925 100644
--- a/auth-rhosts.c
+++ b/auth-rhosts.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$OpenBSD: auth-rhosts.c,v 1.22 2001/04/06 21:00:06 markus Exp $"); 17RCSID("$OpenBSD: auth-rhosts.c,v 1.23 2001/04/12 19:15:24 markus Exp $");
18 18
19#include "packet.h" 19#include "packet.h"
20#include "xmalloc.h" 20#include "xmalloc.h"
@@ -25,6 +25,9 @@ RCSID("$OpenBSD: auth-rhosts.c,v 1.22 2001/04/06 21:00:06 markus Exp $");
25#include "canohost.h" 25#include "canohost.h"
26#include "auth.h" 26#include "auth.h"
27 27
28/* import */
29extern ServerOptions options;
30
28/* 31/*
29 * This function processes an rhosts-style file (.rhosts, .shosts, or 32 * This function processes an rhosts-style file (.rhosts, .shosts, or
30 * /etc/hosts.equiv). This returns true if authentication can be granted 33 * /etc/hosts.equiv). This returns true if authentication can be granted
@@ -150,16 +153,31 @@ check_rhosts_file(const char *filename, const char *hostname,
150int 153int
151auth_rhosts(struct passwd *pw, const char *client_user) 154auth_rhosts(struct passwd *pw, const char *client_user)
152{ 155{
153 extern ServerOptions options;
154 char buf[1024];
155 const char *hostname, *ipaddr; 156 const char *hostname, *ipaddr;
157 int ret;
158
159 hostname = get_canonical_hostname(options.reverse_mapping_check);
160 ipaddr = get_remote_ipaddr();
161 ret = auth_rhosts2(pw, client_user, hostname, ipaddr);
162 return ret;
163}
164
165int
166auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
167 const char *ipaddr)
168{
169 char buf[1024];
156 struct stat st; 170 struct stat st;
157 static const char *rhosts_files[] = {".shosts", ".rhosts", NULL}; 171 static const char *rhosts_files[] = {".shosts", ".rhosts", NULL};
158 u_int rhosts_file_index; 172 u_int rhosts_file_index;
159 173
174 debug2("auth_rhosts2: clientuser %s hostname %s ipaddr %s",
175 client_user, hostname, ipaddr);
176
160 /* no user given */ 177 /* no user given */
161 if (pw == NULL) 178 if (pw == NULL)
162 return 0; 179 return 0;
180
163 /* Switch to the user's uid. */ 181 /* Switch to the user's uid. */
164 temporarily_use_uid(pw); 182 temporarily_use_uid(pw);
165 /* 183 /*
@@ -184,9 +202,6 @@ auth_rhosts(struct passwd *pw, const char *client_user)
184 stat(_PATH_SSH_HOSTS_EQUIV, &st) < 0) 202 stat(_PATH_SSH_HOSTS_EQUIV, &st) < 0)
185 return 0; 203 return 0;
186 204
187 hostname = get_canonical_hostname(options.reverse_mapping_check);
188 ipaddr = get_remote_ipaddr();
189
190 /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */ 205 /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */
191 if (pw->pw_uid != 0) { 206 if (pw->pw_uid != 0) {
192 if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr, client_user, 207 if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr, client_user,
diff --git a/auth.h b/auth.h
index 50375226a..1e02923c9 100644
--- a/auth.h
+++ b/auth.h
@@ -21,7 +21,7 @@
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 * 23 *
24 * $OpenBSD: auth.h,v 1.14 2001/03/28 22:43:31 markus Exp $ 24 * $OpenBSD: auth.h,v 1.15 2001/04/12 19:15:24 markus Exp $
25 */ 25 */
26#ifndef AUTH_H 26#ifndef AUTH_H
27#define AUTH_H 27#define AUTH_H
@@ -58,6 +58,11 @@ struct Authctxt {
58 */ 58 */
59int auth_rhosts(struct passwd * pw, const char *client_user); 59int auth_rhosts(struct passwd * pw, const char *client_user);
60 60
61/* extended interface similar to auth_rhosts() */
62int
63auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
64 const char *ipaddr);
65
61/* 66/*
62 * Tries to authenticate the user using the .rhosts file and the host using 67 * Tries to authenticate the user using the .rhosts file and the host using
63 * its host key. Returns true if authentication succeeds. 68 * its host key. Returns true if authentication succeeds.
diff --git a/auth2.c b/auth2.c
index d676270b7..cd6b27685 100644
--- a/auth2.c
+++ b/auth2.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: auth2.c,v 1.51 2001/04/06 21:00:08 markus Exp $"); 26RCSID("$OpenBSD: auth2.c,v 1.52 2001/04/12 19:15:24 markus Exp $");
27 27
28#include <openssl/evp.h> 28#include <openssl/evp.h>
29 29
@@ -48,6 +48,9 @@ RCSID("$OpenBSD: auth2.c,v 1.51 2001/04/06 21:00:08 markus Exp $");
48#include "uidswap.h" 48#include "uidswap.h"
49#include "auth-options.h" 49#include "auth-options.h"
50#include "misc.h" 50#include "misc.h"
51#include "hostfile.h"
52#include "canohost.h"
53#include "tildexpand.h"
51 54
52/* import */ 55/* import */
53extern ServerOptions options; 56extern ServerOptions options;
@@ -76,8 +79,11 @@ void protocol_error(int type, int plen, void *ctxt);
76 79
77/* helper */ 80/* helper */
78Authmethod *authmethod_lookup(const char *name); 81Authmethod *authmethod_lookup(const char *name);
79int user_key_allowed(struct passwd *pw, Key *key);
80char *authmethods_get(void); 82char *authmethods_get(void);
83int user_key_allowed(struct passwd *pw, Key *key);
84int
85hostbased_key_allowed(struct passwd *pw, const char *cuser, const char *chost,
86 Key *key);
81 87
82/* auth */ 88/* auth */
83void userauth_banner(void); 89void userauth_banner(void);
@@ -85,6 +91,7 @@ void userauth_reply(Authctxt *authctxt, int authenticated);
85int userauth_none(Authctxt *authctxt); 91int userauth_none(Authctxt *authctxt);
86int userauth_passwd(Authctxt *authctxt); 92int userauth_passwd(Authctxt *authctxt);
87int userauth_pubkey(Authctxt *authctxt); 93int userauth_pubkey(Authctxt *authctxt);
94int userauth_hostbased(Authctxt *authctxt);
88int userauth_kbdint(Authctxt *authctxt); 95int userauth_kbdint(Authctxt *authctxt);
89 96
90Authmethod authmethods[] = { 97Authmethod authmethods[] = {
@@ -100,6 +107,9 @@ Authmethod authmethods[] = {
100 {"keyboard-interactive", 107 {"keyboard-interactive",
101 userauth_kbdint, 108 userauth_kbdint,
102 &options.kbd_interactive_authentication}, 109 &options.kbd_interactive_authentication},
110 {"hostbased",
111 userauth_hostbased,
112 &options.hostbased_authentication},
103 {NULL, NULL, NULL} 113 {NULL, NULL, NULL}
104}; 114};
105 115
@@ -211,7 +221,7 @@ input_userauth_request(int type, int plen, void *ctxt)
211 } else if (authctxt->valid) { 221 } else if (authctxt->valid) {
212 if (strcmp(user, authctxt->user) != 0 || 222 if (strcmp(user, authctxt->user) != 0 ||
213 strcmp(service, authctxt->service) != 0) { 223 strcmp(service, authctxt->service) != 0) {
214 log("input_userauth_request: missmatch: (%s,%s)!=(%s,%s)", 224 log("input_userauth_request: mismatch: (%s,%s)!=(%s,%s)",
215 user, service, authctxt->user, authctxt->service); 225 user, service, authctxt->user, authctxt->service);
216 authctxt->valid = 0; 226 authctxt->valid = 0;
217 } 227 }
@@ -519,6 +529,89 @@ userauth_pubkey(Authctxt *authctxt)
519 return authenticated; 529 return authenticated;
520} 530}
521 531
532int
533userauth_hostbased(Authctxt *authctxt)
534{
535 Buffer b;
536 Key *key;
537 char *pkalg, *pkblob, *sig;
538 char *cuser, *chost;
539 u_int alen, blen, slen;
540 int pktype;
541 int authenticated = 0;
542
543 if (!authctxt->valid) {
544 debug2("userauth_hostbased: disabled because of invalid user");
545 return 0;
546 }
547 pkalg = packet_get_string(&alen);
548 pkblob = packet_get_string(&blen);
549 chost = packet_get_string(NULL);
550 cuser = packet_get_string(NULL);
551 sig = packet_get_string(&slen);
552
553 debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d",
554 cuser, chost, pkalg, slen);
555#ifdef DEBUG_PK
556 debug("signature:");
557 buffer_init(&b);
558 buffer_append(&b, sig, slen);
559 buffer_dump(&b);
560 buffer_free(&b);
561#endif
562 pktype = key_type_from_name(pkalg);
563 if (pktype == KEY_UNSPEC) {
564 /* this is perfectly legal */
565 log("userauth_hostbased: unsupported "
566 "public key algorithm: %s", pkalg);
567 goto done;
568 }
569 key = key_from_blob(pkblob, blen);
570 if (key == NULL) {
571 debug("userauth_hostbased: cannot decode key: %s", pkalg);
572 goto done;
573 }
574 buffer_init(&b);
575 if (datafellows & SSH_OLD_SESSIONID) {
576 buffer_append(&b, session_id2, session_id2_len);
577 } else {
578 buffer_put_string(&b, session_id2, session_id2_len);
579 }
580 if (datafellows & SSH_BUG_HBSERVICE)
581 debug("SSH_BUG_HBSERVICE");
582 /* reconstruct packet */
583 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
584 buffer_put_cstring(&b, authctxt->user);
585 buffer_put_cstring(&b,
586 datafellows & SSH_BUG_HBSERVICE ?
587 "ssh-userauth" :
588 authctxt->service);
589 buffer_put_cstring(&b, "hostbased");
590 buffer_put_string(&b, pkalg, alen);
591 buffer_put_string(&b, pkblob, blen);
592 buffer_put_cstring(&b, chost);
593 buffer_put_cstring(&b, cuser);
594#ifdef DEBUG_PK
595 buffer_dump(&b);
596#endif
597 /* test for allowed key and correct signature */
598 if (hostbased_key_allowed(authctxt->pw, cuser, chost, key) &&
599 key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1)
600 authenticated = 1;
601
602 buffer_clear(&b);
603 key_free(key);
604
605done:
606 debug2("userauth_hostbased: authenticated %d", authenticated);
607 xfree(pkalg);
608 xfree(pkblob);
609 xfree(cuser);
610 xfree(chost);
611 xfree(sig);
612 return authenticated;
613}
614
522/* get current user */ 615/* get current user */
523 616
524struct passwd* 617struct passwd*
@@ -696,3 +789,65 @@ user_key_allowed(struct passwd *pw, Key *key)
696 debug2("key not found"); 789 debug2("key not found");
697 return found_key; 790 return found_key;
698} 791}
792
793/* return 1 if given hostkey is allowed */
794int
795hostbased_key_allowed(struct passwd *pw, const char *cuser, const char *chost,
796 Key *key)
797{
798 Key *found;
799 const char *resolvedname, *ipaddr, *lookup;
800 struct stat st;
801 char *user_hostfile;
802 int host_status;
803
804 resolvedname = get_canonical_hostname(options.reverse_mapping_check);
805 ipaddr = get_remote_ipaddr();
806
807 debug2("userauth_hostbased: resolvedname %s ipaddr %s",
808 resolvedname, ipaddr);
809
810 if (options.hostbased_uses_name_from_packet_only) {
811 if (auth_rhosts2(pw, cuser, chost, chost) == 0)
812 return 0;
813 lookup = chost;
814 } else {
815 if (strcasecmp(resolvedname, chost) != 0)
816 log("userauth_hostbased mismatch: "
817 "client sends %s, but we resolve %s to %s",
818 chost, ipaddr, resolvedname);
819 if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0)
820 return 0;
821 lookup = resolvedname;
822 }
823 debug2("userauth_hostbased: access allowed by auth_rhosts2");
824
825 /* XXX this is copied from auth-rh-rsa.c and should be shared */
826 found = key_new(key->type);
827 host_status = check_host_in_hostfile(_PATH_SSH_SYSTEM_HOSTFILE2, lookup,
828 key, found, NULL);
829
830 if (host_status != HOST_OK && !options.ignore_user_known_hosts) {
831 user_hostfile = tilde_expand_filename(_PATH_SSH_USER_HOSTFILE2,
832 pw->pw_uid);
833 if (options.strict_modes &&
834 (stat(user_hostfile, &st) == 0) &&
835 ((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
836 (st.st_mode & 022) != 0)) {
837 log("Hostbased authentication refused for %.100s: "
838 "bad owner or modes for %.200s",
839 pw->pw_name, user_hostfile);
840 } else {
841 temporarily_use_uid(pw);
842 host_status = check_host_in_hostfile(user_hostfile,
843 lookup, key, found, NULL);
844 restore_uid();
845 }
846 xfree(user_hostfile);
847 }
848 key_free(found);
849
850 debug2("userauth_hostbased: key %s for %s", host_status == HOST_OK ?
851 "ok" : "not found", lookup);
852 return (host_status == HOST_OK);
853}
diff --git a/buffer.c b/buffer.c
index 377d0c09f..044caafb5 100644
--- a/buffer.c
+++ b/buffer.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: buffer.c,v 1.12 2001/04/07 08:55:15 markus Exp $"); 15RCSID("$OpenBSD: buffer.c,v 1.13 2001/04/12 19:15:24 markus Exp $");
16 16
17#include "xmalloc.h" 17#include "xmalloc.h"
18#include "buffer.h" 18#include "buffer.h"
@@ -154,7 +154,12 @@ buffer_dump(Buffer *buffer)
154 int i; 154 int i;
155 u_char *ucp = (u_char *) buffer->buf; 155 u_char *ucp = (u_char *) buffer->buf;
156 156
157 for (i = buffer->offset; i < buffer->end; i++) 157 for (i = buffer->offset; i < buffer->end; i++) {
158 fprintf(stderr, " %02x", ucp[i]); 158 fprintf(stderr, "%02x", ucp[i]);
159 if ((i-buffer->offset)%16==15)
160 fprintf(stderr, "\r\n");
161 else if ((i-buffer->offset)%2==1)
162 fprintf(stderr, " ");
163 }
159 fprintf(stderr, "\r\n"); 164 fprintf(stderr, "\r\n");
160} 165}
diff --git a/canohost.c b/canohost.c
index 927508f58..823545d4c 100644
--- a/canohost.c
+++ b/canohost.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: canohost.c,v 1.24 2001/04/05 15:48:19 stevesk Exp $"); 15RCSID("$OpenBSD: canohost.c,v 1.25 2001/04/12 19:15:24 markus Exp $");
16 16
17#include "packet.h" 17#include "packet.h"
18#include "xmalloc.h" 18#include "xmalloc.h"
@@ -202,30 +202,59 @@ get_canonical_hostname(int reverse_mapping_check)
202 * Returns the remote IP-address of socket as a string. The returned 202 * Returns the remote IP-address of socket as a string. The returned
203 * string must be freed. 203 * string must be freed.
204 */ 204 */
205
206char * 205char *
207get_peer_ipaddr(int socket) 206get_socket_address(int socket, int remote, int flags)
208{ 207{
209 struct sockaddr_storage from; 208 struct sockaddr_storage addr;
210 socklen_t fromlen; 209 socklen_t addrlen;
211 char ntop[NI_MAXHOST]; 210 char ntop[NI_MAXHOST];
212 211
213 /* Get IP address of client. */ 212 /* Get IP address of client. */
214 fromlen = sizeof(from); 213 addrlen = sizeof(addr);
215 memset(&from, 0, sizeof(from)); 214 memset(&addr, 0, sizeof(addr));
216 if (getpeername(socket, (struct sockaddr *) & from, &fromlen) < 0) { 215
217 debug("get_peer_ipaddr: getpeername failed: %.100s", strerror(errno)); 216 if (remote) {
218 return NULL; 217 if (getpeername(socket, (struct sockaddr *)&addr, &addrlen)
218 < 0) {
219 debug("get_socket_ipaddr: getpeername failed: %.100s",
220 strerror(errno));
221 return NULL;
222 }
223 } else {
224 if (getsockname(socket, (struct sockaddr *)&addr, &addrlen)
225 < 0) {
226 debug("get_socket_ipaddr: getsockname failed: %.100s",
227 strerror(errno));
228 return NULL;
229 }
219 } 230 }
220 /* Get the IP address in ascii. */ 231 /* Get the address in ascii. */
221 if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop), 232 if (getnameinfo((struct sockaddr *)&addr, addrlen, ntop, sizeof(ntop),
222 NULL, 0, NI_NUMERICHOST) != 0) { 233 NULL, 0, flags) != 0) {
223 error("get_peer_ipaddr: getnameinfo NI_NUMERICHOST failed"); 234 error("get_socket_ipaddr: getnameinfo %d failed", flags);
224 return NULL; 235 return NULL;
225 } 236 }
226 return xstrdup(ntop); 237 return xstrdup(ntop);
227} 238}
228 239
240char *
241get_peer_ipaddr(int socket)
242{
243 return get_socket_address(socket, 1, NI_NUMERICHOST);
244}
245
246char *
247get_local_ipaddr(int socket)
248{
249 return get_socket_address(socket, 0, NI_NUMERICHOST);
250}
251
252char *
253get_local_name(int socket)
254{
255 return get_socket_address(socket, 0, NI_NAMEREQD);
256}
257
229/* 258/*
230 * Returns the IP-address of the remote host as a string. The returned 259 * Returns the IP-address of the remote host as a string. The returned
231 * string must not be freed. 260 * string must not be freed.
diff --git a/canohost.h b/canohost.h
index 89bd5c3b4..36fb345a1 100644
--- a/canohost.h
+++ b/canohost.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: canohost.h,v 1.5 2001/04/05 15:48:19 stevesk Exp $ */ 1/* $OpenBSD: canohost.h,v 1.6 2001/04/12 19:15:24 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -30,6 +30,8 @@ const char *get_remote_name_or_ip(u_int utmp_len, int reverse_mapping_check);
30/* Returns the ipaddr/port number of the peer of the socket. */ 30/* Returns the ipaddr/port number of the peer of the socket. */
31char * get_peer_ipaddr(int socket); 31char * get_peer_ipaddr(int socket);
32int get_peer_port(int sock); 32int get_peer_port(int sock);
33char * get_local_ipaddr(int socket);
34char * get_local_name(int socket);
33 35
34/* Returns the port number of the remote/local host. */ 36/* Returns the port number of the remote/local host. */
35int get_remote_port(void); 37int get_remote_port(void);
diff --git a/compat.c b/compat.c
index f96a6c63c..4bdc6c6b3 100644
--- a/compat.c
+++ b/compat.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: compat.c,v 1.45 2001/04/05 11:09:16 markus Exp $"); 26RCSID("$OpenBSD: compat.c,v 1.46 2001/04/12 19:15:24 markus Exp $");
27 27
28#ifdef HAVE_LIBPCRE 28#ifdef HAVE_LIBPCRE
29# include <pcreposix.h> 29# include <pcreposix.h>
@@ -85,10 +85,10 @@ compat_datafellows(const char *version)
85 { "MindTerm", 0 }, 85 { "MindTerm", 0 },
86 { "^2\\.1\\.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| 86 { "^2\\.1\\.0", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
87 SSH_OLD_SESSIONID|SSH_BUG_DEBUG| 87 SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
88 SSH_BUG_RSASIGMD5 }, 88 SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE },
89 { "^2\\.1 ", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| 89 { "^2\\.1 ", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
90 SSH_OLD_SESSIONID|SSH_BUG_DEBUG| 90 SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
91 SSH_BUG_RSASIGMD5 }, 91 SSH_BUG_RSASIGMD5|SSH_BUG_HBSERVICE },
92 { "^2\\.0\\.1[3-9]", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| 92 { "^2\\.0\\.1[3-9]", SSH_BUG_SIGBLOB|SSH_BUG_HMAC|
93 SSH_OLD_SESSIONID|SSH_BUG_DEBUG| 93 SSH_OLD_SESSIONID|SSH_BUG_DEBUG|
94 SSH_BUG_PKSERVICE|SSH_BUG_X11FWD| 94 SSH_BUG_PKSERVICE|SSH_BUG_X11FWD|
diff --git a/compat.h b/compat.h
index 244cd1aa7..fc6f3344f 100644
--- a/compat.h
+++ b/compat.h
@@ -21,7 +21,7 @@
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */ 23 */
24/* RCSID("$OpenBSD: compat.h,v 1.22 2001/04/05 11:09:17 markus Exp $"); */ 24/* RCSID("$OpenBSD: compat.h,v 1.23 2001/04/12 19:15:24 markus Exp $"); */
25 25
26#ifndef COMPAT_H 26#ifndef COMPAT_H
27#define COMPAT_H 27#define COMPAT_H
@@ -47,6 +47,7 @@
47#define SSH_BUG_RSASIGMD5 0x2000 47#define SSH_BUG_RSASIGMD5 0x2000
48#define SSH_OLD_DHGEX 0x4000 48#define SSH_OLD_DHGEX 0x4000
49#define SSH_BUG_NOREKEY 0x8000 49#define SSH_BUG_NOREKEY 0x8000
50#define SSH_BUG_HBSERVICE 0x10000
50 51
51void enable_compat13(void); 52void enable_compat13(void);
52void enable_compat20(void); 53void enable_compat20(void);
diff --git a/hostfile.c b/hostfile.c
index 77aa8a899..d532bd6ad 100644
--- a/hostfile.c
+++ b/hostfile.c
@@ -36,7 +36,7 @@
36 */ 36 */
37 37
38#include "includes.h" 38#include "includes.h"
39RCSID("$OpenBSD: hostfile.c,v 1.25 2001/04/06 22:12:47 stevesk Exp $"); 39RCSID("$OpenBSD: hostfile.c,v 1.26 2001/04/12 19:15:24 markus Exp $");
40 40
41#include "packet.h" 41#include "packet.h"
42#include "match.h" 42#include "match.h"
@@ -115,6 +115,7 @@ check_host_in_hostfile(const char *filename, const char *host, Key *key,
115 char *cp, *cp2; 115 char *cp, *cp2;
116 HostStatus end_return; 116 HostStatus end_return;
117 117
118 debug3("check_host_in_hostfile: filename %s", filename);
118 if (key == NULL) 119 if (key == NULL)
119 fatal("no key to look up"); 120 fatal("no key to look up");
120 /* Open the file containing the list of known hosts. */ 121 /* Open the file containing the list of known hosts. */
@@ -166,6 +167,7 @@ check_host_in_hostfile(const char *filename, const char *host, Key *key,
166 /* Check if the current key is the same as the given key. */ 167 /* Check if the current key is the same as the given key. */
167 if (key_equal(key, found)) { 168 if (key_equal(key, found)) {
168 /* Ok, they match. */ 169 /* Ok, they match. */
170 debug3("check_host_in_hostfile: match line %d", linenum);
169 fclose(f); 171 fclose(f);
170 return HOST_OK; 172 return HOST_OK;
171 } 173 }
diff --git a/pathnames.h b/pathnames.h
index 75415f3a5..2f09820bd 100644
--- a/pathnames.h
+++ b/pathnames.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: pathnames.h,v 1.4 2001/02/08 22:28:07 stevesk Exp $ */ 1/* $OpenBSD: pathnames.h,v 1.5 2001/04/12 19:15:24 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -31,10 +31,11 @@
31 * Of these, ssh_host_key must be readable only by root, whereas ssh_config 31 * Of these, ssh_host_key must be readable only by root, whereas ssh_config
32 * should be world-readable. 32 * should be world-readable.
33 */ 33 */
34#define _PATH_HOST_KEY_FILE ETCDIR "/ssh_host_key"
35#define _PATH_SERVER_CONFIG_FILE ETCDIR "/sshd_config" 34#define _PATH_SERVER_CONFIG_FILE ETCDIR "/sshd_config"
36#define _PATH_HOST_CONFIG_FILE ETCDIR "/ssh_config" 35#define _PATH_HOST_CONFIG_FILE ETCDIR "/ssh_config"
36#define _PATH_HOST_KEY_FILE ETCDIR "/ssh_host_key"
37#define _PATH_HOST_DSA_KEY_FILE ETCDIR "/ssh_host_dsa_key" 37#define _PATH_HOST_DSA_KEY_FILE ETCDIR "/ssh_host_dsa_key"
38#define _PATH_HOST_RSA_KEY_FILE ETCDIR "/ssh_host_rsa_key"
38#define _PATH_DH_PRIMES ETCDIR "/primes" 39#define _PATH_DH_PRIMES ETCDIR "/primes"
39 40
40#ifndef _PATH_SSH_PROGRAM 41#ifndef _PATH_SSH_PROGRAM
diff --git a/readconf.c b/readconf.c
index 007056d4d..12b431d59 100644
--- a/readconf.c
+++ b/readconf.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: readconf.c,v 1.71 2001/04/07 08:55:17 markus Exp $"); 15RCSID("$OpenBSD: readconf.c,v 1.72 2001/04/12 19:15:25 markus Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "xmalloc.h" 18#include "xmalloc.h"
@@ -110,7 +110,7 @@ typedef enum {
110 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, 110 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
111 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication, 111 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
112 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, 112 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
113 oDynamicForward, oPreferredAuthentications 113 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication
114} OpCodes; 114} OpCodes;
115 115
116/* Textual representations of the tokens. */ 116/* Textual representations of the tokens. */
@@ -131,6 +131,8 @@ static struct {
131 { "rsaauthentication", oRSAAuthentication }, 131 { "rsaauthentication", oRSAAuthentication },
132 { "pubkeyauthentication", oPubkeyAuthentication }, 132 { "pubkeyauthentication", oPubkeyAuthentication },
133 { "dsaauthentication", oPubkeyAuthentication }, /* alias */ 133 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
134 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
135 { "hostbaedauthentication", oHostbasedAuthentication },
134 { "challengeresponseauthentication", oChallengeResponseAuthentication }, 136 { "challengeresponseauthentication", oChallengeResponseAuthentication },
135 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ 137 { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
136 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ 138 { "tisauthentication", oChallengeResponseAuthentication }, /* alias */
@@ -158,7 +160,6 @@ static struct {
158 { "user", oUser }, 160 { "user", oUser },
159 { "host", oHost }, 161 { "host", oHost },
160 { "escapechar", oEscapeChar }, 162 { "escapechar", oEscapeChar },
161 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
162 { "globalknownhostsfile", oGlobalKnownHostsFile }, 163 { "globalknownhostsfile", oGlobalKnownHostsFile },
163 { "userknownhostsfile", oUserKnownHostsFile }, 164 { "userknownhostsfile", oUserKnownHostsFile },
164 { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, 165 { "globalknownhostsfile2", oGlobalKnownHostsFile2 },
@@ -324,6 +325,10 @@ parse_flag:
324 intptr = &options->rhosts_rsa_authentication; 325 intptr = &options->rhosts_rsa_authentication;
325 goto parse_flag; 326 goto parse_flag;
326 327
328 case oHostbasedAuthentication:
329 intptr = &options->hostbased_authentication;
330 goto parse_flag;
331
327 case oChallengeResponseAuthentication: 332 case oChallengeResponseAuthentication:
328 intptr = &options->challenge_reponse_authentication; 333 intptr = &options->challenge_reponse_authentication;
329 goto parse_flag; 334 goto parse_flag;
@@ -594,7 +599,7 @@ parse_int:
594 filename, linenum); 599 filename, linenum);
595 fwd_port = atoi(arg); 600 fwd_port = atoi(arg);
596 add_local_forward(options, fwd_port, "socks4", 0); 601 add_local_forward(options, fwd_port, "socks4", 0);
597 break; 602 break;
598 603
599 case oHost: 604 case oHost:
600 *activep = 0; 605 *activep = 0;
@@ -712,6 +717,7 @@ initialize_options(Options * options)
712 options->kbd_interactive_authentication = -1; 717 options->kbd_interactive_authentication = -1;
713 options->kbd_interactive_devices = NULL; 718 options->kbd_interactive_devices = NULL;
714 options->rhosts_rsa_authentication = -1; 719 options->rhosts_rsa_authentication = -1;
720 options->hostbased_authentication = -1;
715 options->fallback_to_rsh = -1; 721 options->fallback_to_rsh = -1;
716 options->use_rsh = -1; 722 options->use_rsh = -1;
717 options->batch_mode = -1; 723 options->batch_mode = -1;
@@ -789,6 +795,8 @@ fill_default_options(Options * options)
789 options->kbd_interactive_authentication = 1; 795 options->kbd_interactive_authentication = 1;
790 if (options->rhosts_rsa_authentication == -1) 796 if (options->rhosts_rsa_authentication == -1)
791 options->rhosts_rsa_authentication = 1; 797 options->rhosts_rsa_authentication = 1;
798 if (options->hostbased_authentication == -1)
799 options->hostbased_authentication = 0;
792 if (options->fallback_to_rsh == -1) 800 if (options->fallback_to_rsh == -1)
793 options->fallback_to_rsh = 0; 801 options->fallback_to_rsh = 0;
794 if (options->use_rsh == -1) 802 if (options->use_rsh == -1)
diff --git a/readconf.h b/readconf.h
index 55babe80e..680068b09 100644
--- a/readconf.h
+++ b/readconf.h
@@ -11,7 +11,7 @@
11 * called by a name other than "ssh" or "Secure Shell". 11 * called by a name other than "ssh" or "Secure Shell".
12 */ 12 */
13 13
14/* RCSID("$OpenBSD: readconf.h,v 1.28 2001/03/10 17:51:04 markus Exp $"); */ 14/* RCSID("$OpenBSD: readconf.h,v 1.29 2001/04/12 19:15:25 markus Exp $"); */
15 15
16#ifndef READCONF_H 16#ifndef READCONF_H
17#define READCONF_H 17#define READCONF_H
@@ -38,6 +38,7 @@ typedef struct {
38 * authentication. */ 38 * authentication. */
39 int rsa_authentication; /* Try RSA authentication. */ 39 int rsa_authentication; /* Try RSA authentication. */
40 int pubkey_authentication; /* Try ssh2 pubkey authentication. */ 40 int pubkey_authentication; /* Try ssh2 pubkey authentication. */
41 int hostbased_authentication; /* ssh2's rhosts_rsa */
41 int challenge_reponse_authentication; 42 int challenge_reponse_authentication;
42 /* Try S/Key or TIS, authentication. */ 43 /* Try S/Key or TIS, authentication. */
43#ifdef KRB4 44#ifdef KRB4
diff --git a/servconf.c b/servconf.c
index 4d5eb53ae..8e876d1f1 100644
--- a/servconf.c
+++ b/servconf.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12#include "includes.h" 12#include "includes.h"
13RCSID("$OpenBSD: servconf.c,v 1.74 2001/04/06 22:25:25 stevesk Exp $"); 13RCSID("$OpenBSD: servconf.c,v 1.75 2001/04/12 19:15:25 markus Exp $");
14 14
15#ifdef KRB4 15#ifdef KRB4
16#include <krb.h> 16#include <krb.h>
@@ -67,6 +67,8 @@ initialize_server_options(ServerOptions *options)
67 options->log_level = (LogLevel) - 1; 67 options->log_level = (LogLevel) - 1;
68 options->rhosts_authentication = -1; 68 options->rhosts_authentication = -1;
69 options->rhosts_rsa_authentication = -1; 69 options->rhosts_rsa_authentication = -1;
70 options->hostbased_authentication = -1;
71 options->hostbased_uses_name_from_packet_only = -1;
70 options->rsa_authentication = -1; 72 options->rsa_authentication = -1;
71 options->pubkey_authentication = -1; 73 options->pubkey_authentication = -1;
72#ifdef KRB4 74#ifdef KRB4
@@ -156,6 +158,10 @@ fill_default_server_options(ServerOptions *options)
156 options->rhosts_authentication = 0; 158 options->rhosts_authentication = 0;
157 if (options->rhosts_rsa_authentication == -1) 159 if (options->rhosts_rsa_authentication == -1)
158 options->rhosts_rsa_authentication = 0; 160 options->rhosts_rsa_authentication = 0;
161 if (options->hostbased_authentication == -1)
162 options->hostbased_authentication = 0;
163 if (options->hostbased_uses_name_from_packet_only == -1)
164 options->hostbased_uses_name_from_packet_only = 0;
159 if (options->rsa_authentication == -1) 165 if (options->rsa_authentication == -1)
160 options->rsa_authentication = 1; 166 options->rsa_authentication = 1;
161 if (options->pubkey_authentication == -1) 167 if (options->pubkey_authentication == -1)
@@ -219,7 +225,8 @@ typedef enum {
219 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 225 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
220 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, 226 sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
221 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, 227 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
222 sBanner, sReverseMappingCheck 228 sBanner, sReverseMappingCheck, sHostbasedAuthentication,
229 sHostbasedUsesNameFromPacketOnly
223} ServerOpCodes; 230} ServerOpCodes;
224 231
225/* Textual representation of the tokens. */ 232/* Textual representation of the tokens. */
@@ -239,6 +246,8 @@ static struct {
239 { "loglevel", sLogLevel }, 246 { "loglevel", sLogLevel },
240 { "rhostsauthentication", sRhostsAuthentication }, 247 { "rhostsauthentication", sRhostsAuthentication },
241 { "rhostsrsaauthentication", sRhostsRSAAuthentication }, 248 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
249 { "hostbasedauthentication", sHostbasedAuthentication },
250 { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
242 { "rsaauthentication", sRSAAuthentication }, 251 { "rsaauthentication", sRSAAuthentication },
243 { "pubkeyauthentication", sPubkeyAuthentication }, 252 { "pubkeyauthentication", sPubkeyAuthentication },
244 { "dsaauthentication", sPubkeyAuthentication }, /* alias */ 253 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
@@ -537,6 +546,14 @@ parse_flag:
537 intptr = &options->rhosts_rsa_authentication; 546 intptr = &options->rhosts_rsa_authentication;
538 goto parse_flag; 547 goto parse_flag;
539 548
549 case sHostbasedAuthentication:
550 intptr = &options->hostbased_authentication;
551 goto parse_flag;
552
553 case sHostbasedUsesNameFromPacketOnly:
554 intptr = &options->hostbased_uses_name_from_packet_only;
555 goto parse_flag;
556
540 case sRSAAuthentication: 557 case sRSAAuthentication:
541 intptr = &options->rsa_authentication; 558 intptr = &options->rsa_authentication;
542 goto parse_flag; 559 goto parse_flag;
diff --git a/servconf.h b/servconf.h
index 57d4370f1..9b3a60f08 100644
--- a/servconf.h
+++ b/servconf.h
@@ -11,7 +11,7 @@
11 * called by a name other than "ssh" or "Secure Shell". 11 * called by a name other than "ssh" or "Secure Shell".
12 */ 12 */
13 13
14/* RCSID("$OpenBSD: servconf.h,v 1.39 2001/03/25 13:16:10 stevesk Exp $"); */ 14/* RCSID("$OpenBSD: servconf.h,v 1.40 2001/04/12 19:15:25 markus Exp $"); */
15 15
16#ifndef SERVCONF_H 16#ifndef SERVCONF_H
17#define SERVCONF_H 17#define SERVCONF_H
@@ -69,6 +69,8 @@ typedef struct {
69 * authentication. */ 69 * authentication. */
70 int rhosts_rsa_authentication; /* If true, permit rhosts RSA 70 int rhosts_rsa_authentication; /* If true, permit rhosts RSA
71 * authentication. */ 71 * authentication. */
72 int hostbased_authentication; /* If true, permit ssh2 hostbased auth */
73 int hostbased_uses_name_from_packet_only; /* experimental */
72 int rsa_authentication; /* If true, permit RSA authentication. */ 74 int rsa_authentication; /* If true, permit RSA authentication. */
73 int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */ 75 int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */
74#ifdef KRB4 76#ifdef KRB4
diff --git a/ssh.c b/ssh.c
index 5c08de820..f14fbac23 100644
--- a/ssh.c
+++ b/ssh.c
@@ -39,7 +39,7 @@
39 */ 39 */
40 40
41#include "includes.h" 41#include "includes.h"
42RCSID("$OpenBSD: ssh.c,v 1.111 2001/04/12 14:29:09 markus Exp $"); 42RCSID("$OpenBSD: ssh.c,v 1.112 2001/04/12 19:15:25 markus Exp $");
43 43
44#include <openssl/evp.h> 44#include <openssl/evp.h>
45#include <openssl/err.h> 45#include <openssl/err.h>
@@ -130,8 +130,11 @@ struct sockaddr_storage hostaddr;
130 */ 130 */
131volatile int received_window_change_signal = 0; 131volatile int received_window_change_signal = 0;
132 132
133/* Host private key. */ 133/* Private host keys. */
134Key *host_private_key = NULL; 134struct {
135 Key **keys;
136 int nkeys;
137} sensitive_data;
135 138
136/* Original real UID. */ 139/* Original real UID. */
137uid_t original_real_uid; 140uid_t original_real_uid;
@@ -646,9 +649,18 @@ main(int ac, char **av)
646 * authentication. This must be done before releasing extra 649 * authentication. This must be done before releasing extra
647 * privileges, because the file is only readable by root. 650 * privileges, because the file is only readable by root.
648 */ 651 */
649 if (ok && (options.protocol & SSH_PROTO_1)) { 652 sensitive_data.nkeys = 0;
650 host_private_key = key_load_private_type(KEY_RSA1, 653 sensitive_data.keys = NULL;
654 if (ok && (options.rhosts_rsa_authentication ||
655 options.hostbased_authentication)) {
656 sensitive_data.nkeys = 3;
657 sensitive_data.keys = xmalloc(sensitive_data.nkeys*sizeof(Key));
658 sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
651 _PATH_HOST_KEY_FILE, "", NULL); 659 _PATH_HOST_KEY_FILE, "", NULL);
660 sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
661 _PATH_HOST_DSA_KEY_FILE, "", NULL);
662 sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
663 _PATH_HOST_RSA_KEY_FILE, "", NULL);
652 } 664 }
653 /* 665 /*
654 * Get rid of any extra privileges that we may have. We will no 666 * Get rid of any extra privileges that we may have. We will no
@@ -707,11 +719,21 @@ main(int ac, char **av)
707 tilde_expand_filename(options.user_hostfile2, original_real_uid); 719 tilde_expand_filename(options.user_hostfile2, original_real_uid);
708 720
709 /* Log into the remote system. This never returns if the login fails. */ 721 /* Log into the remote system. This never returns if the login fails. */
710 ssh_login(host_private_key, host, (struct sockaddr *)&hostaddr, pw); 722 ssh_login(sensitive_data.keys, sensitive_data.nkeys,
711 723 host, (struct sockaddr *)&hostaddr, pw);
712 /* We no longer need the host private key. Clear it now. */ 724
713 if (host_private_key != NULL) 725 /* We no longer need the private host keys. Clear them now. */
714 key_free(host_private_key); /* Destroys contents safely */ 726 if (sensitive_data.nkeys != 0) {
727 for (i = 0; i < sensitive_data.nkeys; i++) {
728 if (sensitive_data.keys[i] != NULL) {
729 /* Destroys contents safely */
730 debug3("clear hostkey %d", i);
731 key_free(sensitive_data.keys[i]);
732 sensitive_data.keys[i] = NULL;
733 }
734 }
735 xfree(sensitive_data.keys);
736 }
715 737
716 exit_status = compat20 ? ssh_session2() : ssh_session(); 738 exit_status = compat20 ? ssh_session2() : ssh_session();
717 packet_close(); 739 packet_close();
diff --git a/sshconnect.c b/sshconnect.c
index 85427b44d..60b16a247 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -13,7 +13,7 @@
13 */ 13 */
14 14
15#include "includes.h" 15#include "includes.h"
16RCSID("$OpenBSD: sshconnect.c,v 1.103 2001/04/06 21:00:14 markus Exp $"); 16RCSID("$OpenBSD: sshconnect.c,v 1.104 2001/04/12 19:15:25 markus Exp $");
17 17
18#include <openssl/bn.h> 18#include <openssl/bn.h>
19 19
@@ -738,7 +738,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
738 * This function does not require super-user privileges. 738 * This function does not require super-user privileges.
739 */ 739 */
740void 740void
741ssh_login(Key *own_host_key, const char *orighost, 741ssh_login(Key **keys, int nkeys, const char *orighost,
742 struct sockaddr *hostaddr, struct passwd *pw) 742 struct sockaddr *hostaddr, struct passwd *pw)
743{ 743{
744 char *host, *cp; 744 char *host, *cp;
@@ -763,10 +763,10 @@ ssh_login(Key *own_host_key, const char *orighost,
763 /* authenticate user */ 763 /* authenticate user */
764 if (compat20) { 764 if (compat20) {
765 ssh_kex2(host, hostaddr); 765 ssh_kex2(host, hostaddr);
766 ssh_userauth2(server_user, host); 766 ssh_userauth2(local_user, server_user, host, keys, nkeys);
767 } else { 767 } else {
768 ssh_kex(host, hostaddr); 768 ssh_kex(host, hostaddr);
769 ssh_userauth(local_user, server_user, host, own_host_key); 769 ssh_userauth1(local_user, server_user, host, keys, nkeys);
770 } 770 }
771} 771}
772 772
diff --git a/sshconnect.h b/sshconnect.h
index 45caf7395..661040185 100644
--- a/sshconnect.h
+++ b/sshconnect.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.h,v 1.8 2001/04/06 21:00:15 markus Exp $ */ 1/* $OpenBSD: sshconnect.h,v 1.9 2001/04/12 19:15:25 markus Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -25,46 +25,30 @@
25 */ 25 */
26#ifndef SSHCONNECT_H 26#ifndef SSHCONNECT_H
27#define SSHCONNECT_H 27#define SSHCONNECT_H
28/* 28
29 * Opens a TCP/IP connection to the remote server on the given host. If port
30 * is 0, the default port will be used. If anonymous is zero, a privileged
31 * port will be allocated to make the connection. This requires super-user
32 * privileges if anonymous is false. Connection_attempts specifies the
33 * maximum number of tries, one per second. This returns true on success,
34 * and zero on failure. If the connection is successful, this calls
35 * packet_set_connection for the connection.
36 */
37int 29int
38ssh_connect(const char *host, struct sockaddr_storage * hostaddr, 30ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
39 u_short port, int connection_attempts, 31 u_short port, int connection_attempts,
40 int anonymous, struct passwd *pw, 32 int anonymous, struct passwd *pw,
41 const char *proxy_command); 33 const char *proxy_command);
42 34
43/*
44 * Starts a dialog with the server, and authenticates the current user on the
45 * server. This does not need any extra privileges. The basic connection to
46 * the server must already have been established before this is called. If
47 * login fails, this function prints an error and never returns. This
48 * initializes the random state, and leaves it initialized (it will also have
49 * references from the packet module).
50 */
51
52void 35void
53ssh_login(Key *host_key, const char *host, 36ssh_login(Key **keys, int nkeys, const char *orighost,
54 struct sockaddr * hostaddr, struct passwd *pw); 37 struct sockaddr *hostaddr, struct passwd *pw);
55
56 38
57void 39void
58check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, 40check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
59 const char *user_hostfile, const char *system_hostfile); 41 const char *user_hostfile, const char *system_hostfile);
60 42
61void ssh_kex(char *host, struct sockaddr *hostaddr); 43void ssh_kex(char *host, struct sockaddr *hostaddr);
62void
63ssh_userauth(const char * local_user, const char * server_user, char *host,
64 Key *own_host_key);
65
66void ssh_kex2(char *host, struct sockaddr *hostaddr); 44void ssh_kex2(char *host, struct sockaddr *hostaddr);
67void ssh_userauth2(const char *server_user, char *host); 45
46void
47ssh_userauth1(const char *local_user, const char *server_user, char *host,
48 Key **keys, int nkeys);
49void
50ssh_userauth2(const char *local_user, const char *server_user, char *host,
51 Key **keys, int nkeys);
68 52
69void ssh_put_password(char *password); 53void ssh_put_password(char *password);
70 54
diff --git a/sshconnect1.c b/sshconnect1.c
index 3ec5ecc51..865d04e85 100644
--- a/sshconnect1.c
+++ b/sshconnect1.c
@@ -13,7 +13,7 @@
13 */ 13 */
14 14
15#include "includes.h" 15#include "includes.h"
16RCSID("$OpenBSD: sshconnect1.c,v 1.29 2001/03/26 08:07:09 markus Exp $"); 16RCSID("$OpenBSD: sshconnect1.c,v 1.30 2001/04/12 19:15:25 markus Exp $");
17 17
18#include <openssl/bn.h> 18#include <openssl/bn.h>
19#include <openssl/evp.h> 19#include <openssl/evp.h>
@@ -911,17 +911,14 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
911 * Authenticate user 911 * Authenticate user
912 */ 912 */
913void 913void
914ssh_userauth( 914ssh_userauth1(const char *local_user, const char *server_user, char *host,
915 const char *local_user, 915 Key **keys, int nkeys)
916 const char *server_user,
917 char *host,
918 Key *own_host_key)
919{ 916{
920 int i, type; 917 int i, type;
921 int payload_len; 918 int payload_len;
922 919
923 if (supported_authentications == 0) 920 if (supported_authentications == 0)
924 fatal("ssh_userauth: server supports no auth methods"); 921 fatal("ssh_userauth1: server supports no auth methods");
925 922
926 /* Send the name of the user to log in as on the server. */ 923 /* Send the name of the user to log in as on the server. */
927 packet_start(SSH_CMSG_USER); 924 packet_start(SSH_CMSG_USER);
@@ -1000,9 +997,12 @@ ssh_userauth(
1000 * authentication. 997 * authentication.
1001 */ 998 */
1002 if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) && 999 if ((supported_authentications & (1 << SSH_AUTH_RHOSTS_RSA)) &&
1003 options.rhosts_rsa_authentication && own_host_key != NULL) { 1000 options.rhosts_rsa_authentication) {
1004 if (try_rhosts_rsa_authentication(local_user, own_host_key)) 1001 for (i = 0; i < nkeys; i++) {
1005 return; 1002 if (keys[i]->type == KEY_RSA1 &&
1003 try_rhosts_rsa_authentication(local_user, keys[i]))
1004 return;
1005 }
1006 } 1006 }
1007 /* Try RSA authentication if the server supports it. */ 1007 /* Try RSA authentication if the server supports it. */
1008 if ((supported_authentications & (1 << SSH_AUTH_RSA)) && 1008 if ((supported_authentications & (1 << SSH_AUTH_RSA)) &&
diff --git a/sshconnect2.c b/sshconnect2.c
index da5b71478..9a1d2576e 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: sshconnect2.c,v 1.67 2001/04/05 10:42:56 markus Exp $"); 26RCSID("$OpenBSD: sshconnect2.c,v 1.68 2001/04/12 19:15:25 markus Exp $");
27 27
28#include <openssl/bn.h> 28#include <openssl/bn.h>
29#include <openssl/md5.h> 29#include <openssl/md5.h>
@@ -53,6 +53,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.67 2001/04/05 10:42:56 markus Exp $");
53#include "readpass.h" 53#include "readpass.h"
54#include "match.h" 54#include "match.h"
55#include "dispatch.h" 55#include "dispatch.h"
56#include "canohost.h"
56 57
57/* import */ 58/* import */
58extern char *client_version_string; 59extern char *client_version_string;
@@ -147,15 +148,20 @@ typedef int sign_cb_fn(
147 148
148struct Authctxt { 149struct Authctxt {
149 const char *server_user; 150 const char *server_user;
151 const char *local_user;
150 const char *host; 152 const char *host;
151 const char *service; 153 const char *service;
152 AuthenticationConnection *agent;
153 Authmethod *method; 154 Authmethod *method;
154 int success; 155 int success;
155 char *authlist; 156 char *authlist;
157 /* pubkey */
156 Key *last_key; 158 Key *last_key;
157 sign_cb_fn *last_key_sign; 159 sign_cb_fn *last_key_sign;
158 int last_key_hint; 160 int last_key_hint;
161 AuthenticationConnection *agent;
162 /* hostbased */
163 Key **keys;
164 int nkeys;
159}; 165};
160struct Authmethod { 166struct Authmethod {
161 char *name; /* string to compare against server's list */ 167 char *name; /* string to compare against server's list */
@@ -175,6 +181,7 @@ int userauth_none(Authctxt *authctxt);
175int userauth_pubkey(Authctxt *authctxt); 181int userauth_pubkey(Authctxt *authctxt);
176int userauth_passwd(Authctxt *authctxt); 182int userauth_passwd(Authctxt *authctxt);
177int userauth_kbdint(Authctxt *authctxt); 183int userauth_kbdint(Authctxt *authctxt);
184int userauth_hostbased(Authctxt *authctxt);
178 185
179void userauth(Authctxt *authctxt, char *authlist); 186void userauth(Authctxt *authctxt, char *authlist);
180 187
@@ -200,6 +207,10 @@ Authmethod authmethods[] = {
200 userauth_kbdint, 207 userauth_kbdint,
201 &options.kbd_interactive_authentication, 208 &options.kbd_interactive_authentication,
202 &options.batch_mode}, 209 &options.batch_mode},
210 {"hostbased",
211 userauth_hostbased,
212 &options.hostbased_authentication,
213 NULL},
203 {"none", 214 {"none",
204 userauth_none, 215 userauth_none,
205 NULL, 216 NULL,
@@ -208,7 +219,8 @@ Authmethod authmethods[] = {
208}; 219};
209 220
210void 221void
211ssh_userauth2(const char *server_user, char *host) 222ssh_userauth2(const char *local_user, const char *server_user, char *host,
223 Key **keys, int nkeys)
212{ 224{
213 Authctxt authctxt; 225 Authctxt authctxt;
214 int type; 226 int type;
@@ -242,11 +254,14 @@ ssh_userauth2(const char *server_user, char *host)
242 /* setup authentication context */ 254 /* setup authentication context */
243 authctxt.agent = ssh_get_authentication_connection(); 255 authctxt.agent = ssh_get_authentication_connection();
244 authctxt.server_user = server_user; 256 authctxt.server_user = server_user;
257 authctxt.local_user = local_user;
245 authctxt.host = host; 258 authctxt.host = host;
246 authctxt.service = "ssh-connection"; /* service name */ 259 authctxt.service = "ssh-connection"; /* service name */
247 authctxt.success = 0; 260 authctxt.success = 0;
248 authctxt.method = authmethod_lookup("none"); 261 authctxt.method = authmethod_lookup("none");
249 authctxt.authlist = NULL; 262 authctxt.authlist = NULL;
263 authctxt.keys = keys;
264 authctxt.nkeys = nkeys;
250 if (authctxt.method == NULL) 265 if (authctxt.method == NULL)
251 fatal("ssh_userauth2: internal error: cannot send userauth none request"); 266 fatal("ssh_userauth2: internal error: cannot send userauth none request");
252 267
@@ -786,6 +801,96 @@ input_userauth_info_req(int type, int plen, void *ctxt)
786 packet_send(); 801 packet_send();
787} 802}
788 803
804/*
805 * this will be move to an external program (ssh-keysign) ASAP. ssh-keysign
806 * will be setuid-root and the sbit can be removed from /usr/bin/ssh.
807 */
808int
809userauth_hostbased(Authctxt *authctxt)
810{
811 Key *private = NULL;
812 Buffer b;
813 u_char *signature, *blob;
814 char *chost, *pkalg, *p;
815 u_int blen, slen;
816 int ok, i, found = 0;
817
818 p = get_local_name(packet_get_connection_in());
819 if (p == NULL) {
820 error("userauth_hostbased: cannot get local ipaddr/name");
821 return 0;
822 }
823 chost = xstrdup(p);
824 debug2("userauth_hostbased: chost %s", chost);
825 /* check for a useful key */
826 for (i = 0; i < authctxt->nkeys; i++) {
827 private = authctxt->keys[i];
828 if (private && private->type != KEY_RSA1) {
829 found = 1;
830 /* we take and free the key */
831 authctxt->keys[i] = NULL;
832 break;
833 }
834 }
835 if (!found) {
836 xfree(chost);
837 return 0;
838 }
839 if (key_to_blob(private, &blob, &blen) == 0) {
840 key_free(private);
841 xfree(chost);
842 return 0;
843 }
844 pkalg = xstrdup(key_ssh_name(private));
845 buffer_init(&b);
846 if (datafellows & SSH_OLD_SESSIONID) {
847 buffer_append(&b, session_id2, session_id2_len);
848 } else {
849 buffer_put_string(&b, session_id2, session_id2_len);
850 }
851 /* construct data */
852 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
853 buffer_put_cstring(&b, authctxt->server_user);
854 buffer_put_cstring(&b,
855 datafellows & SSH_BUG_HBSERVICE ?
856 "ssh-userauth" :
857 authctxt->service);
858 buffer_put_cstring(&b, authctxt->method->name);
859 buffer_put_cstring(&b, pkalg);
860 buffer_put_string(&b, blob, blen);
861 buffer_put_cstring(&b, chost);
862 buffer_put_cstring(&b, authctxt->local_user);
863#ifdef DEBUG_PK
864 buffer_dump(&b);
865#endif
866 debug2("xxx: chost %s", chost);
867 ok = key_sign(private, &signature, &slen, buffer_ptr(&b), buffer_len(&b));
868 key_free(private);
869 buffer_free(&b);
870 if (ok != 0) {
871 error("key_sign failed");
872 xfree(chost);
873 xfree(pkalg);
874 return 0;
875 }
876 packet_start(SSH2_MSG_USERAUTH_REQUEST);
877 packet_put_cstring(authctxt->server_user);
878 packet_put_cstring(authctxt->service);
879 packet_put_cstring(authctxt->method->name);
880 packet_put_cstring(pkalg);
881 packet_put_string(blob, blen);
882 packet_put_cstring(chost);
883 packet_put_cstring(authctxt->local_user);
884 packet_put_string(signature, slen);
885 memset(signature, 's', slen);
886 xfree(signature);
887 xfree(chost);
888 xfree(pkalg);
889
890 packet_send();
891 return 1;
892}
893
789/* find auth method */ 894/* find auth method */
790 895
791/* 896/*
diff --git a/sshd_config b/sshd_config
index 3ef9b929d..c131a5868 100644
--- a/sshd_config
+++ b/sshd_config
@@ -1,4 +1,4 @@
1# $OpenBSD: sshd_config,v 1.35 2001/03/25 13:16:11 stevesk Exp $ 1# $OpenBSD: sshd_config,v 1.36 2001/04/12 19:15:26 markus Exp $
2 2
3# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin 3# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
4 4
@@ -37,6 +37,8 @@ RhostsAuthentication no
37# 37#
38# For this to work you will also need host keys in /etc/ssh_known_hosts 38# For this to work you will also need host keys in /etc/ssh_known_hosts
39RhostsRSAAuthentication no 39RhostsRSAAuthentication no
40# similar for protocol version 2
41HostbasedAuthentication no
40# 42#
41RSAAuthentication yes 43RSAAuthentication yes
42 44