summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2000-11-13 22:57:25 +1100
committerDamien Miller <djm@mindrot.org>2000-11-13 22:57:25 +1100
commit0bc1bd814e3c2b5e92d6f595930051960d17f47f (patch)
tree176c7dc2844ecc2c1de0f72d221449556ffa5209
parent559d383037b0872fcde4e6c40188b649c574be74 (diff)
- (djm) Merge OpenBSD changes:
- markus@cvs.openbsd.org 2000/11/06 16:04:56 [channels.c channels.h clientloop.c nchan.c serverloop.c] [session.c ssh.c] agent forwarding and -R for ssh2, based on work from jhuuskon@messi.uku.fi - markus@cvs.openbsd.org 2000/11/06 16:13:27 [ssh.c sshconnect.c sshd.c] do not disabled rhosts(rsa) if server port > 1024; from pekkas@netcore.fi - markus@cvs.openbsd.org 2000/11/06 16:16:35 [sshconnect.c] downgrade client to 1.3 if server is 1.4; help from mdb@juniper.net - markus@cvs.openbsd.org 2000/11/09 18:04:40 [auth1.c] typo; from mouring@pconline.com - markus@cvs.openbsd.org 2000/11/12 12:03:28 [ssh-agent.c] off-by-one when removing a key from the agent - markus@cvs.openbsd.org 2000/11/12 12:50:39 [auth-rh-rsa.c auth2.c authfd.c authfd.h] [authfile.c hostfile.c kex.c kex.h key.c key.h myproposal.h] [readconf.c readconf.h rsa.c rsa.h servconf.c servconf.h ssh-add.c] [ssh-agent.c ssh-keygen.1 ssh-keygen.c ssh.1 ssh.c ssh_config] [sshconnect1.c sshconnect2.c sshd.8 sshd.c sshd_config ssh-dss.c] [ssh-dss.h ssh-rsa.c ssh-rsa.h dsa.c dsa.h] add support for RSA to SSH2. please test. there are now 3 types of keys: RSA1 is used by ssh-1 only, RSA and DSA are used by SSH2. you can use 'ssh-keygen -t rsa -f ssh2_rsa_file' to generate RSA keys for SSH2 and use the RSA keys for hostkeys or for user keys. SSH2 RSA or DSA keys are added to .ssh/authorised_keys2 as before. - (djm) Fix up Makefile and Redhat init script to create RSA host keys - (djm) Change to interim version
-rw-r--r--ChangeLog33
-rw-r--r--Makefile.in16
-rw-r--r--auth-rh-rsa.c6
-rw-r--r--auth1.c2
-rw-r--r--auth2.c38
-rw-r--r--authfd.c76
-rw-r--r--authfd.h7
-rw-r--r--authfile.c136
-rw-r--r--channels.c159
-rw-r--r--channels.h18
-rw-r--r--clientloop.c122
-rwxr-xr-xcontrib/redhat/sshd.init27
-rw-r--r--hostfile.c12
-rw-r--r--kex.c12
-rw-r--r--kex.h2
-rw-r--r--key.c388
-rw-r--r--key.h28
-rw-r--r--myproposal.h2
-rw-r--r--nchan.c6
-rw-r--r--readconf.c55
-rw-r--r--readconf.h9
-rw-r--r--rsa.c79
-rw-r--r--rsa.h13
-rw-r--r--servconf.c57
-rw-r--r--servconf.h9
-rw-r--r--serverloop.c128
-rw-r--r--session.c17
-rw-r--r--sftp-server.84
-rw-r--r--ssh-add.12
-rw-r--r--ssh-add.c26
-rw-r--r--ssh-agent.14
-rw-r--r--ssh-agent.c143
-rw-r--r--ssh-dss.c (renamed from dsa.c)118
-rw-r--r--ssh-dss.h (renamed from dsa.h)10
-rw-r--r--ssh-keygen.124
-rw-r--r--ssh-keygen.c115
-rw-r--r--ssh-rsa.c163
-rw-r--r--ssh-rsa.h39
-rw-r--r--ssh.153
-rw-r--r--ssh.c193
-rw-r--r--ssh_config13
-rw-r--r--sshconnect.c12
-rw-r--r--sshconnect1.c13
-rw-r--r--sshconnect2.c77
-rw-r--r--sshd.830
-rw-r--r--sshd.c316
-rw-r--r--sshd_config2
47 files changed, 1817 insertions, 997 deletions
diff --git a/ChangeLog b/ChangeLog
index ff3924a4c..38f81b2f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,39 @@
120001113 120001113
2 - (djm) Add pointer to http://www.imasy.or.jp/~gotoh/connect.c to 2 - (djm) Add pointer to http://www.imasy.or.jp/~gotoh/connect.c to
3 contrib/README 3 contrib/README
4 - (djm) Merge OpenBSD changes:
5 - markus@cvs.openbsd.org 2000/11/06 16:04:56
6 [channels.c channels.h clientloop.c nchan.c serverloop.c]
7 [session.c ssh.c]
8 agent forwarding and -R for ssh2, based on work from
9 jhuuskon@messi.uku.fi
10 - markus@cvs.openbsd.org 2000/11/06 16:13:27
11 [ssh.c sshconnect.c sshd.c]
12 do not disabled rhosts(rsa) if server port > 1024; from
13 pekkas@netcore.fi
14 - markus@cvs.openbsd.org 2000/11/06 16:16:35
15 [sshconnect.c]
16 downgrade client to 1.3 if server is 1.4; help from mdb@juniper.net
17 - markus@cvs.openbsd.org 2000/11/09 18:04:40
18 [auth1.c]
19 typo; from mouring@pconline.com
20 - markus@cvs.openbsd.org 2000/11/12 12:03:28
21 [ssh-agent.c]
22 off-by-one when removing a key from the agent
23 - markus@cvs.openbsd.org 2000/11/12 12:50:39
24 [auth-rh-rsa.c auth2.c authfd.c authfd.h]
25 [authfile.c hostfile.c kex.c kex.h key.c key.h myproposal.h]
26 [readconf.c readconf.h rsa.c rsa.h servconf.c servconf.h ssh-add.c]
27 [ssh-agent.c ssh-keygen.1 ssh-keygen.c ssh.1 ssh.c ssh_config]
28 [sshconnect1.c sshconnect2.c sshd.8 sshd.c sshd_config ssh-dss.c]
29 [ssh-dss.h ssh-rsa.c ssh-rsa.h dsa.c dsa.h]
30 add support for RSA to SSH2. please test.
31 there are now 3 types of keys: RSA1 is used by ssh-1 only,
32 RSA and DSA are used by SSH2.
33 you can use 'ssh-keygen -t rsa -f ssh2_rsa_file' to generate RSA
34 keys for SSH2 and use the RSA keys for hostkeys or for user keys.
35 SSH2 RSA or DSA keys are added to .ssh/authorised_keys2 as before.
36 - (djm) Fix up Makefile and Redhat init script to create RSA host keys
4 37
520001112 3820001112
6 - (bal) SCO Patch to add needed libraries for configure.in. Patch by 39 - (bal) SCO Patch to add needed libraries for configure.in. Patch by
diff --git a/Makefile.in b/Makefile.in
index cc49517b4..c93e7eab2 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -35,7 +35,7 @@ INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@
35 35
36TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) $(EXTRA_TARGETS) 36TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) $(EXTRA_TARGETS)
37 37
38LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o cli.o compat.o compress.o crc32.o cygwin_util.o deattack.o dispatch.o dsa.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o rijndael.o entropy.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o util.o uuencode.o xmalloc.o 38LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o cli.o compat.o compress.o crc32.o cygwin_util.o deattack.o dispatch.o hmac.o hostfile.o key.o kex.o log.o match.o mpaux.o nchan.o packet.o radix.o rijndael.o entropy.o readpass.o rsa.o ssh-dss.o ssh-rsa.o tildexpand.o ttymodes.o uidswap.o util.o uuencode.o xmalloc.o
39 39
40LIBOPENBSD_COMPAT_OBJS=bsd-arc4random.o bsd-base64.o bsd-bindresvport.o bsd-daemon.o bsd-getcwd.o bsd-inet_aton.o bsd-inet_ntoa.o bsd-misc.o bsd-mktemp.o bsd-realpath.o bsd-rresvport.o bsd-setenv.o bsd-sigaction.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bsd-strsep.o bsd-strtok.o bsd-vis.o bsd-setproctitle.o bsd-waitpid.o fake-getaddrinfo.o fake-getnameinfo.o next-posix.o 40LIBOPENBSD_COMPAT_OBJS=bsd-arc4random.o bsd-base64.o bsd-bindresvport.o bsd-daemon.o bsd-getcwd.o bsd-inet_aton.o bsd-inet_ntoa.o bsd-misc.o bsd-mktemp.o bsd-realpath.o bsd-rresvport.o bsd-setenv.o bsd-sigaction.o bsd-snprintf.o bsd-strlcat.o bsd-strlcpy.o bsd-strsep.o bsd-strtok.o bsd-vis.o bsd-setproctitle.o bsd-waitpid.o fake-getaddrinfo.o fake-getnameinfo.o next-posix.o
41 41
@@ -179,18 +179,24 @@ host-key: ssh-keygen$(EXEEXT)
179 if [ -f "$(DESTDIR)$(sysconfdir)/ssh_host_key" ] ; then \ 179 if [ -f "$(DESTDIR)$(sysconfdir)/ssh_host_key" ] ; then \
180 echo "$(DESTDIR)$(sysconfdir)/ssh_host_key already exists, skipping." ; \ 180 echo "$(DESTDIR)$(sysconfdir)/ssh_host_key already exists, skipping." ; \
181 else \ 181 else \
182 $(srcdir)/ssh-keygen -b 1024 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" ; \ 182 $(srcdir)/ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" ; \
183 fi ; \ 183 fi ; \
184 if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key ] ; then \ 184 if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key ] ; then \
185 echo "$(DESTDIR)$(sysconfdir)/ssh_host_dsa_key already exists, skipping." ; \ 185 echo "$(DESTDIR)$(sysconfdir)/ssh_host_dsa_key already exists, skipping." ; \
186 else \ 186 else \
187 $(srcdir)/ssh-keygen -d -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ; \ 187 $(srcdir)/ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ; \
188 fi ; \
189 if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key ] ; then \
190 echo "$(DESTDIR)$(sysconfdir)/ssh_host_rsa_key already exists, skipping." ; \
191 else \
192 $(srcdir)/ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N "" ; \
188 fi ; \ 193 fi ; \
189 fi ; 194 fi ;
190 195
191host-key-force: ssh-keygen$(EXEEXT) 196host-key-force: ssh-keygen$(EXEEXT)
192 $(srcdir)/ssh-keygen -b 1024 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" 197 $(srcdir)/ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N ""
193 $(srcdir)/ssh-keygen -d -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" 198 $(srcdir)/ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N ""
199 $(srcdir)/ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N ""
194 200
195uninstallall: uninstall 201uninstallall: uninstall
196 -rm -f $(DESTDIR)$(sysconfdir)/ssh_config 202 -rm -f $(DESTDIR)$(sysconfdir)/ssh_config
diff --git a/auth-rh-rsa.c b/auth-rh-rsa.c
index 3070c9d41..a9f17ef83 100644
--- a/auth-rh-rsa.c
+++ b/auth-rh-rsa.c
@@ -13,7 +13,7 @@
13 */ 13 */
14 14
15#include "includes.h" 15#include "includes.h"
16RCSID("$OpenBSD: auth-rh-rsa.c,v 1.17 2000/10/03 18:03:03 markus Exp $"); 16RCSID("$OpenBSD: auth-rh-rsa.c,v 1.18 2000/11/12 19:50:37 markus Exp $");
17 17
18#include "packet.h" 18#include "packet.h"
19#include "ssh.h" 19#include "ssh.h"
@@ -53,10 +53,10 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user, RSA *client_host_key
53 debug("Rhosts RSA authentication: canonical host %.900s", canonical_hostname); 53 debug("Rhosts RSA authentication: canonical host %.900s", canonical_hostname);
54 54
55 /* wrap the RSA key into a 'generic' key */ 55 /* wrap the RSA key into a 'generic' key */
56 client_key = key_new(KEY_RSA); 56 client_key = key_new(KEY_RSA1);
57 BN_copy(client_key->rsa->e, client_host_key->e); 57 BN_copy(client_key->rsa->e, client_host_key->e);
58 BN_copy(client_key->rsa->n, client_host_key->n); 58 BN_copy(client_key->rsa->n, client_host_key->n);
59 found = key_new(KEY_RSA); 59 found = key_new(KEY_RSA1);
60 60
61 /* Check if we know the host and its host key. */ 61 /* Check if we know the host and its host key. */
62 host_status = check_host_in_hostfile(SSH_SYSTEM_HOSTFILE, canonical_hostname, 62 host_status = check_host_in_hostfile(SSH_SYSTEM_HOSTFILE, canonical_hostname,
diff --git a/auth1.c b/auth1.c
index ca0495d32..fec73e3a2 100644
--- a/auth1.c
+++ b/auth1.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12#include "includes.h" 12#include "includes.h"
13RCSID("$OpenBSD: auth1.c,v 1.6 2000/10/11 20:27:23 markus Exp $"); 13RCSID("$OpenBSD: auth1.c,v 1.7 2000/11/10 01:04:40 markus Exp $");
14 14
15#ifdef HAVE_OSF_SIA 15#ifdef HAVE_OSF_SIA
16# include <sia.h> 16# include <sia.h>
diff --git a/auth2.c b/auth2.c
index d51a1a765..46bf07c80 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.20 2000/10/14 12:16:56 markus Exp $"); 26RCSID("$OpenBSD: auth2.c,v 1.21 2000/11/12 19:50:37 markus Exp $");
27 27
28#ifdef HAVE_OSF_SIA 28#ifdef HAVE_OSF_SIA
29# include <sia.h> 29# include <sia.h>
@@ -52,7 +52,6 @@ RCSID("$OpenBSD: auth2.c,v 1.20 2000/10/14 12:16:56 markus Exp $");
52#include "key.h" 52#include "key.h"
53#include "kex.h" 53#include "kex.h"
54 54
55#include "dsa.h"
56#include "uidswap.h" 55#include "uidswap.h"
57#include "auth-options.h" 56#include "auth-options.h"
58 57
@@ -89,7 +88,7 @@ void protocol_error(int type, int plen, void *ctxt);
89/* helper */ 88/* helper */
90Authmethod *authmethod_lookup(const char *name); 89Authmethod *authmethod_lookup(const char *name);
91struct passwd *pwcopy(struct passwd *pw); 90struct passwd *pwcopy(struct passwd *pw);
92int user_dsa_key_allowed(struct passwd *pw, Key *key); 91int user_key_allowed(struct passwd *pw, Key *key);
93char *authmethods_get(void); 92char *authmethods_get(void);
94 93
95/* auth */ 94/* auth */
@@ -104,7 +103,7 @@ Authmethod authmethods[] = {
104 &one}, 103 &one},
105 {"publickey", 104 {"publickey",
106 userauth_pubkey, 105 userauth_pubkey,
107 &options.dsa_authentication}, 106 &options.pubkey_authentication},
108 {"keyboard-interactive", 107 {"keyboard-interactive",
109 userauth_kbdint, 108 userauth_kbdint,
110 &options.kbd_interactive_authentication}, 109 &options.kbd_interactive_authentication},
@@ -422,7 +421,7 @@ userauth_pubkey(Authctxt *authctxt)
422 Key *key; 421 Key *key;
423 char *pkalg, *pkblob, *sig; 422 char *pkalg, *pkblob, *sig;
424 unsigned int alen, blen, slen; 423 unsigned int alen, blen, slen;
425 int have_sig; 424 int have_sig, pktype;
426 int authenticated = 0; 425 int authenticated = 0;
427 426
428 if (!authctxt->valid) { 427 if (!authctxt->valid) {
@@ -431,13 +430,14 @@ userauth_pubkey(Authctxt *authctxt)
431 } 430 }
432 have_sig = packet_get_char(); 431 have_sig = packet_get_char();
433 pkalg = packet_get_string(&alen); 432 pkalg = packet_get_string(&alen);
434 if (strcmp(pkalg, KEX_DSS) != 0) { 433 pktype = key_type_from_name(pkalg);
435 log("bad pkalg %s", pkalg); /*XXX*/ 434 if (pktype == KEY_UNSPEC) {
435 log("bad pkalg %s", pkalg);
436 xfree(pkalg); 436 xfree(pkalg);
437 return 0; 437 return 0;
438 } 438 }
439 pkblob = packet_get_string(&blen); 439 pkblob = packet_get_string(&blen);
440 key = dsa_key_from_blob(pkblob, blen); 440 key = key_from_blob(pkblob, blen);
441 if (key != NULL) { 441 if (key != NULL) {
442 if (have_sig) { 442 if (have_sig) {
443 sig = packet_get_string(&slen); 443 sig = packet_get_string(&slen);
@@ -457,14 +457,14 @@ userauth_pubkey(Authctxt *authctxt)
457 authctxt->service); 457 authctxt->service);
458 buffer_put_cstring(&b, "publickey"); 458 buffer_put_cstring(&b, "publickey");
459 buffer_put_char(&b, have_sig); 459 buffer_put_char(&b, have_sig);
460 buffer_put_cstring(&b, KEX_DSS); 460 buffer_put_cstring(&b, key_ssh_name(key));
461 buffer_put_string(&b, pkblob, blen); 461 buffer_put_string(&b, pkblob, blen);
462#ifdef DEBUG_DSS 462#ifdef DEBUG_PK
463 buffer_dump(&b); 463 buffer_dump(&b);
464#endif 464#endif
465 /* test for correct signature */ 465 /* test for correct signature */
466 if (user_dsa_key_allowed(authctxt->pw, key) && 466 if (user_key_allowed(authctxt->pw, key) &&
467 dsa_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1) 467 key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1)
468 authenticated = 1; 468 authenticated = 1;
469 buffer_clear(&b); 469 buffer_clear(&b);
470 xfree(sig); 470 xfree(sig);
@@ -480,7 +480,7 @@ userauth_pubkey(Authctxt *authctxt)
480 * if a user is not allowed to login. is this an 480 * if a user is not allowed to login. is this an
481 * issue? -markus 481 * issue? -markus
482 */ 482 */
483 if (user_dsa_key_allowed(authctxt->pw, key)) { 483 if (user_key_allowed(authctxt->pw, key)) {
484 packet_start(SSH2_MSG_USERAUTH_PK_OK); 484 packet_start(SSH2_MSG_USERAUTH_PK_OK);
485 packet_put_string(pkalg, alen); 485 packet_put_string(pkalg, alen);
486 packet_put_string(pkblob, blen); 486 packet_put_string(pkblob, blen);
@@ -493,6 +493,7 @@ userauth_pubkey(Authctxt *authctxt)
493 auth_clear_options(); 493 auth_clear_options();
494 key_free(key); 494 key_free(key);
495 } 495 }
496 debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg);
496 xfree(pkalg); 497 xfree(pkalg);
497 xfree(pkblob); 498 xfree(pkblob);
498#ifdef HAVE_CYGWIN 499#ifdef HAVE_CYGWIN
@@ -560,11 +561,10 @@ authmethod_lookup(const char *name)
560 561
561/* return 1 if user allows given key */ 562/* return 1 if user allows given key */
562int 563int
563user_dsa_key_allowed(struct passwd *pw, Key *key) 564user_key_allowed(struct passwd *pw, Key *key)
564{ 565{
565 char line[8192], file[1024]; 566 char line[8192], file[1024];
566 int found_key = 0; 567 int found_key = 0;
567 unsigned int bits = -1;
568 FILE *f; 568 FILE *f;
569 unsigned long linenum = 0; 569 unsigned long linenum = 0;
570 struct stat st; 570 struct stat st;
@@ -645,10 +645,10 @@ user_dsa_key_allowed(struct passwd *pw, Key *key)
645 if (!*cp || *cp == '\n' || *cp == '#') 645 if (!*cp || *cp == '\n' || *cp == '#')
646 continue; 646 continue;
647 647
648 bits = key_read(found, &cp); 648 if (key_read(found, &cp) == -1) {
649 if (bits == 0) {
650 /* no key? check if there are options for this key */ 649 /* no key? check if there are options for this key */
651 int quoted = 0; 650 int quoted = 0;
651 debug2("user_key_allowed: check options: '%s'", cp);
652 options = cp; 652 options = cp;
653 for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { 653 for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
654 if (*cp == '\\' && cp[1] == '"') 654 if (*cp == '\\' && cp[1] == '"')
@@ -659,8 +659,8 @@ user_dsa_key_allowed(struct passwd *pw, Key *key)
659 /* Skip remaining whitespace. */ 659 /* Skip remaining whitespace. */
660 for (; *cp == ' ' || *cp == '\t'; cp++) 660 for (; *cp == ' ' || *cp == '\t'; cp++)
661 ; 661 ;
662 bits = key_read(found, &cp); 662 if (key_read(found, &cp) == -1) {
663 if (bits == 0) { 663 debug2("user_key_allowed: advance: '%s'", cp);
664 /* still no key? advance to next line*/ 664 /* still no key? advance to next line*/
665 continue; 665 continue;
666 } 666 }
diff --git a/authfd.c b/authfd.c
index d06cc536c..9036a8d89 100644
--- a/authfd.c
+++ b/authfd.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$OpenBSD: authfd.c,v 1.29 2000/10/09 21:51:00 markus Exp $"); 38RCSID("$OpenBSD: authfd.c,v 1.30 2000/11/12 19:50:37 markus Exp $");
39 39
40#include "ssh.h" 40#include "ssh.h"
41#include "rsa.h" 41#include "rsa.h"
@@ -50,7 +50,6 @@ RCSID("$OpenBSD: authfd.c,v 1.29 2000/10/09 21:51:00 markus Exp $");
50#include "key.h" 50#include "key.h"
51#include "authfd.h" 51#include "authfd.h"
52#include "kex.h" 52#include "kex.h"
53#include "dsa.h"
54#include "compat.h" 53#include "compat.h"
55 54
56/* helper */ 55/* helper */
@@ -211,8 +210,8 @@ ssh_close_authentication_connection(AuthenticationConnection *auth)
211 * Returns the first authentication identity held by the agent. 210 * Returns the first authentication identity held by the agent.
212 */ 211 */
213 212
214Key * 213int
215ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version) 214ssh_get_num_identities(AuthenticationConnection *auth, int version)
216{ 215{
217 int type, code1 = 0, code2 = 0; 216 int type, code1 = 0, code2 = 0;
218 Buffer request; 217 Buffer request;
@@ -227,7 +226,7 @@ ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int versi
227 code2 = SSH2_AGENT_IDENTITIES_ANSWER; 226 code2 = SSH2_AGENT_IDENTITIES_ANSWER;
228 break; 227 break;
229 default: 228 default:
230 return NULL; 229 return 0;
231 } 230 }
232 231
233 /* 232 /*
@@ -240,14 +239,14 @@ ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int versi
240 buffer_clear(&auth->identities); 239 buffer_clear(&auth->identities);
241 if (ssh_request_reply(auth, &request, &auth->identities) == 0) { 240 if (ssh_request_reply(auth, &request, &auth->identities) == 0) {
242 buffer_free(&request); 241 buffer_free(&request);
243 return NULL; 242 return 0;
244 } 243 }
245 buffer_free(&request); 244 buffer_free(&request);
246 245
247 /* Get message type, and verify that we got a proper answer. */ 246 /* Get message type, and verify that we got a proper answer. */
248 type = buffer_get_char(&auth->identities); 247 type = buffer_get_char(&auth->identities);
249 if (agent_failed(type)) { 248 if (agent_failed(type)) {
250 return NULL; 249 return 0;
251 } else if (type != code2) { 250 } else if (type != code2) {
252 fatal("Bad authentication reply message type: %d", type); 251 fatal("Bad authentication reply message type: %d", type);
253 } 252 }
@@ -258,8 +257,16 @@ ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int versi
258 fatal("Too many identities in authentication reply: %d\n", 257 fatal("Too many identities in authentication reply: %d\n",
259 auth->howmany); 258 auth->howmany);
260 259
261 /* Return the first entry (if any). */ 260 return auth->howmany;
262 return ssh_get_next_identity(auth, comment, version); 261}
262
263Key *
264ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version)
265{
266 /* get number of identities and return the first entry (if any). */
267 if (ssh_get_num_identities(auth, version) > 0)
268 return ssh_get_next_identity(auth, comment, version);
269 return NULL;
263} 270}
264 271
265Key * 272Key *
@@ -280,7 +287,7 @@ ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int versio
280 */ 287 */
281 switch(version){ 288 switch(version){
282 case 1: 289 case 1:
283 key = key_new(KEY_RSA); 290 key = key_new(KEY_RSA1);
284 bits = buffer_get_int(&auth->identities); 291 bits = buffer_get_int(&auth->identities);
285 buffer_get_bignum(&auth->identities, key->rsa->e); 292 buffer_get_bignum(&auth->identities, key->rsa->e);
286 buffer_get_bignum(&auth->identities, key->rsa->n); 293 buffer_get_bignum(&auth->identities, key->rsa->n);
@@ -292,7 +299,7 @@ ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int versio
292 case 2: 299 case 2:
293 blob = buffer_get_string(&auth->identities, &blen); 300 blob = buffer_get_string(&auth->identities, &blen);
294 *comment = buffer_get_string(&auth->identities, NULL); 301 *comment = buffer_get_string(&auth->identities, NULL);
295 key = dsa_key_from_blob(blob, blen); 302 key = key_from_blob(blob, blen);
296 xfree(blob); 303 xfree(blob);
297 break; 304 break;
298 default: 305 default:
@@ -324,7 +331,7 @@ ssh_decrypt_challenge(AuthenticationConnection *auth,
324 int i; 331 int i;
325 int type; 332 int type;
326 333
327 if (key->type != KEY_RSA) 334 if (key->type != KEY_RSA1)
328 return 0; 335 return 0;
329 if (response_type == 0) { 336 if (response_type == 0) {
330 log("Compatibility with ssh protocol version 1.0 no longer supported."); 337 log("Compatibility with ssh protocol version 1.0 no longer supported.");
@@ -376,7 +383,7 @@ ssh_agent_sign(AuthenticationConnection *auth,
376 int type, flags = 0; 383 int type, flags = 0;
377 int ret = -1; 384 int ret = -1;
378 385
379 if (dsa_make_key_blob(key, &blob, &blen) == 0) 386 if (key_to_blob(key, &blob, &blen) == 0)
380 return -1; 387 return -1;
381 388
382 if (datafellows & SSH_BUG_SIGBLOB) 389 if (datafellows & SSH_BUG_SIGBLOB)
@@ -409,7 +416,7 @@ ssh_agent_sign(AuthenticationConnection *auth,
409/* Encode key for a message to the agent. */ 416/* Encode key for a message to the agent. */
410 417
411void 418void
412ssh_encode_identity_rsa(Buffer *b, RSA *key, const char *comment) 419ssh_encode_identity_rsa1(Buffer *b, RSA *key, const char *comment)
413{ 420{
414 buffer_clear(b); 421 buffer_clear(b);
415 buffer_put_char(b, SSH_AGENTC_ADD_RSA_IDENTITY); 422 buffer_put_char(b, SSH_AGENTC_ADD_RSA_IDENTITY);
@@ -425,17 +432,29 @@ ssh_encode_identity_rsa(Buffer *b, RSA *key, const char *comment)
425} 432}
426 433
427void 434void
428ssh_encode_identity_dsa(Buffer *b, DSA *key, const char *comment) 435ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
429{ 436{
430 buffer_clear(b); 437 buffer_clear(b);
431 buffer_put_char(b, SSH2_AGENTC_ADD_IDENTITY); 438 buffer_put_char(b, SSH2_AGENTC_ADD_IDENTITY);
432 buffer_put_cstring(b, KEX_DSS); 439 buffer_put_cstring(b, key_ssh_name(key));
433 buffer_put_bignum2(b, key->p); 440 switch(key->type){
434 buffer_put_bignum2(b, key->q); 441 case KEY_RSA:
435 buffer_put_bignum2(b, key->g); 442 buffer_put_bignum2(b, key->rsa->n);
436 buffer_put_bignum2(b, key->pub_key); 443 buffer_put_bignum2(b, key->rsa->e);
437 buffer_put_bignum2(b, key->priv_key); 444 buffer_put_bignum2(b, key->rsa->d);
438 buffer_put_string(b, comment, strlen(comment)); 445 buffer_put_bignum2(b, key->rsa->iqmp);
446 buffer_put_bignum2(b, key->rsa->p);
447 buffer_put_bignum2(b, key->rsa->q);
448 break;
449 case KEY_DSA:
450 buffer_put_bignum2(b, key->dsa->p);
451 buffer_put_bignum2(b, key->dsa->q);
452 buffer_put_bignum2(b, key->dsa->g);
453 buffer_put_bignum2(b, key->dsa->pub_key);
454 buffer_put_bignum2(b, key->dsa->priv_key);
455 break;
456 }
457 buffer_put_cstring(b, comment);
439} 458}
440 459
441/* 460/*
@@ -452,11 +471,12 @@ ssh_add_identity(AuthenticationConnection *auth, Key *key, const char *comment)
452 buffer_init(&msg); 471 buffer_init(&msg);
453 472
454 switch (key->type) { 473 switch (key->type) {
455 case KEY_RSA: 474 case KEY_RSA1:
456 ssh_encode_identity_rsa(&msg, key->rsa, comment); 475 ssh_encode_identity_rsa1(&msg, key->rsa, comment);
457 break; 476 break;
477 case KEY_RSA:
458 case KEY_DSA: 478 case KEY_DSA:
459 ssh_encode_identity_dsa(&msg, key->dsa, comment); 479 ssh_encode_identity_ssh2(&msg, key, comment);
460 break; 480 break;
461 default: 481 default:
462 buffer_free(&msg); 482 buffer_free(&msg);
@@ -487,13 +507,13 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key)
487 507
488 buffer_init(&msg); 508 buffer_init(&msg);
489 509
490 if (key->type == KEY_RSA) { 510 if (key->type == KEY_RSA1) {
491 buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY); 511 buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY);
492 buffer_put_int(&msg, BN_num_bits(key->rsa->n)); 512 buffer_put_int(&msg, BN_num_bits(key->rsa->n));
493 buffer_put_bignum(&msg, key->rsa->e); 513 buffer_put_bignum(&msg, key->rsa->e);
494 buffer_put_bignum(&msg, key->rsa->n); 514 buffer_put_bignum(&msg, key->rsa->n);
495 } else if (key->type == KEY_DSA) { 515 } else if (key->type == KEY_DSA || key->type == KEY_RSA) {
496 dsa_make_key_blob(key, &blob, &blen); 516 key_to_blob(key, &blob, &blen);
497 buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY); 517 buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY);
498 buffer_put_string(&msg, blob, blen); 518 buffer_put_string(&msg, blob, blen);
499 xfree(blob); 519 xfree(blob);
diff --git a/authfd.h b/authfd.h
index 2d2465206..65471ad7c 100644
--- a/authfd.h
+++ b/authfd.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: authfd.h,v 1.13 2000/10/09 21:51:00 markus Exp $"); */ 14/* RCSID("$OpenBSD: authfd.h,v 1.14 2000/11/12 19:50:37 markus Exp $"); */
15 15
16#ifndef AUTHFD_H 16#ifndef AUTHFD_H
17#define AUTHFD_H 17#define AUTHFD_H
@@ -75,6 +75,11 @@ AuthenticationConnection *ssh_get_authentication_connection();
75void ssh_close_authentication_connection(AuthenticationConnection *auth); 75void ssh_close_authentication_connection(AuthenticationConnection *auth);
76 76
77/* 77/*
78 * Returns the number authentication identity held by the agent.
79 */
80int ssh_get_num_identities(AuthenticationConnection *auth, int version);
81
82/*
78 * Returns the first authentication identity held by the agent or NULL if 83 * Returns the first authentication identity held by the agent or NULL if
79 * no identies are available. Caller must free comment and key. 84 * no identies are available. Caller must free comment and key.
80 * Note that you cannot mix calls with different versions. 85 * Note that you cannot mix calls with different versions.
diff --git a/authfile.c b/authfile.c
index d1a97d773..986b10f6b 100644
--- a/authfile.c
+++ b/authfile.c
@@ -36,11 +36,12 @@
36 */ 36 */
37 37
38#include "includes.h" 38#include "includes.h"
39RCSID("$OpenBSD: authfile.c,v 1.20 2000/10/11 20:27:23 markus Exp $"); 39RCSID("$OpenBSD: authfile.c,v 1.21 2000/11/12 19:50:37 markus Exp $");
40 40
41#include <openssl/bn.h> 41#include <openssl/bn.h>
42#include <openssl/dsa.h> 42#include <openssl/dsa.h>
43#include <openssl/rsa.h> 43#include <openssl/rsa.h>
44#include <openssl/err.h>
44#include <openssl/pem.h> 45#include <openssl/pem.h>
45#include <openssl/evp.h> 46#include <openssl/evp.h>
46 47
@@ -61,7 +62,7 @@ RCSID("$OpenBSD: authfile.c,v 1.20 2000/10/11 20:27:23 markus Exp $");
61 */ 62 */
62 63
63int 64int
64save_private_key_rsa(const char *filename, const char *passphrase, 65save_private_key_rsa1(const char *filename, const char *passphrase,
65 RSA *key, const char *comment) 66 RSA *key, const char *comment)
66{ 67{
67 Buffer buffer, encrypted; 68 Buffer buffer, encrypted;
@@ -155,16 +156,17 @@ save_private_key_rsa(const char *filename, const char *passphrase,
155 return 1; 156 return 1;
156} 157}
157 158
158/* save DSA key in OpenSSL PEM format */ 159/* save SSH2 key in OpenSSL PEM format */
159
160int 160int
161save_private_key_dsa(const char *filename, const char *passphrase, 161save_private_key_ssh2(const char *filename, const char *_passphrase,
162 DSA *dsa, const char *comment) 162 Key *key, const char *comment)
163{ 163{
164 FILE *fp; 164 FILE *fp;
165 int fd; 165 int fd;
166 int success = 1; 166 int success = 0;
167 int len = strlen(passphrase); 167 int len = strlen(_passphrase);
168 char *passphrase = (len > 0) ? (char *)_passphrase : NULL;
169 EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
168 170
169 if (len > 0 && len <= 4) { 171 if (len > 0 && len <= 4) {
170 error("passphrase too short: %d bytes", len); 172 error("passphrase too short: %d bytes", len);
@@ -182,14 +184,15 @@ save_private_key_dsa(const char *filename, const char *passphrase,
182 close(fd); 184 close(fd);
183 return 0; 185 return 0;
184 } 186 }
185 if (len > 0) { 187 switch (key->type) {
186 if (!PEM_write_DSAPrivateKey(fp, dsa, EVP_des_ede3_cbc(), 188 case KEY_DSA:
187 (char *)passphrase, strlen(passphrase), NULL, NULL)) 189 success = PEM_write_DSAPrivateKey(fp, key->dsa,
188 success = 0; 190 cipher, passphrase, len, NULL, NULL);
189 } else { 191 break;
190 if (!PEM_write_DSAPrivateKey(fp, dsa, NULL, 192 case KEY_RSA:
191 NULL, 0, NULL, NULL)) 193 success = PEM_write_RSAPrivateKey(fp, key->rsa,
192 success = 0; 194 cipher, passphrase, len, NULL, NULL);
195 break;
193 } 196 }
194 fclose(fp); 197 fclose(fp);
195 return success; 198 return success;
@@ -200,11 +203,12 @@ save_private_key(const char *filename, const char *passphrase, Key *key,
200 const char *comment) 203 const char *comment)
201{ 204{
202 switch (key->type) { 205 switch (key->type) {
203 case KEY_RSA: 206 case KEY_RSA1:
204 return save_private_key_rsa(filename, passphrase, key->rsa, comment); 207 return save_private_key_rsa1(filename, passphrase, key->rsa, comment);
205 break; 208 break;
206 case KEY_DSA: 209 case KEY_DSA:
207 return save_private_key_dsa(filename, passphrase, key->dsa, comment); 210 case KEY_RSA:
211 return save_private_key_ssh2(filename, passphrase, key, comment);
208 break; 212 break;
209 default: 213 default:
210 break; 214 break;
@@ -246,7 +250,7 @@ load_public_key_rsa(const char *filename, RSA * pub, char **comment_return)
246 250
247 /* Check that it is at least big enought to contain the ID string. */ 251 /* Check that it is at least big enought to contain the ID string. */
248 if (len < strlen(AUTHFILE_ID_STRING) + 1) { 252 if (len < strlen(AUTHFILE_ID_STRING) + 1) {
249 debug("Bad key file %.200s.", filename); 253 debug3("Bad RSA1 key file %.200s.", filename);
250 buffer_free(&buffer); 254 buffer_free(&buffer);
251 return 0; 255 return 0;
252 } 256 }
@@ -256,7 +260,7 @@ load_public_key_rsa(const char *filename, RSA * pub, char **comment_return)
256 */ 260 */
257 for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) 261 for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++)
258 if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) { 262 if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) {
259 debug("Bad key file %.200s.", filename); 263 debug3("Bad RSA1 key file %.200s.", filename);
260 buffer_free(&buffer); 264 buffer_free(&buffer);
261 return 0; 265 return 0;
262 } 266 }
@@ -288,10 +292,11 @@ int
288load_public_key(const char *filename, Key * key, char **comment_return) 292load_public_key(const char *filename, Key * key, char **comment_return)
289{ 293{
290 switch (key->type) { 294 switch (key->type) {
291 case KEY_RSA: 295 case KEY_RSA1:
292 return load_public_key_rsa(filename, key->rsa, comment_return); 296 return load_public_key_rsa(filename, key->rsa, comment_return);
293 break; 297 break;
294 case KEY_DSA: 298 case KEY_DSA:
299 case KEY_RSA:
295 default: 300 default:
296 break; 301 break;
297 } 302 }
@@ -306,7 +311,7 @@ load_public_key(const char *filename, Key * key, char **comment_return)
306 */ 311 */
307 312
308int 313int
309load_private_key_rsa(int fd, const char *filename, 314load_private_key_rsa1(int fd, const char *filename,
310 const char *passphrase, RSA * prv, char **comment_return) 315 const char *passphrase, RSA * prv, char **comment_return)
311{ 316{
312 int i, check1, check2, cipher_type; 317 int i, check1, check2, cipher_type;
@@ -326,7 +331,7 @@ load_private_key_rsa(int fd, const char *filename,
326 331
327 if (read(fd, cp, (size_t) len) != (size_t) len) { 332 if (read(fd, cp, (size_t) len) != (size_t) len) {
328 debug("Read from key file %.200s failed: %.100s", filename, 333 debug("Read from key file %.200s failed: %.100s", filename,
329 strerror(errno)); 334 strerror(errno));
330 buffer_free(&buffer); 335 buffer_free(&buffer);
331 close(fd); 336 close(fd);
332 return 0; 337 return 0;
@@ -335,7 +340,7 @@ load_private_key_rsa(int fd, const char *filename,
335 340
336 /* Check that it is at least big enought to contain the ID string. */ 341 /* Check that it is at least big enought to contain the ID string. */
337 if (len < strlen(AUTHFILE_ID_STRING) + 1) { 342 if (len < strlen(AUTHFILE_ID_STRING) + 1) {
338 debug("Bad key file %.200s.", filename); 343 debug3("Bad RSA1 key file %.200s.", filename);
339 buffer_free(&buffer); 344 buffer_free(&buffer);
340 return 0; 345 return 0;
341 } 346 }
@@ -344,8 +349,8 @@ load_private_key_rsa(int fd, const char *filename,
344 * from the buffer. 349 * from the buffer.
345 */ 350 */
346 for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) 351 for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++)
347 if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) { 352 if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) {
348 debug("Bad key file %.200s.", filename); 353 debug3("Bad RSA1 key file %.200s.", filename);
349 buffer_free(&buffer); 354 buffer_free(&buffer);
350 return 0; 355 return 0;
351 } 356 }
@@ -431,40 +436,59 @@ fail:
431} 436}
432 437
433int 438int
434load_private_key_dsa(int fd, const char *passphrase, Key *k, char **comment_return) 439load_private_key_ssh2(int fd, const char *passphrase, Key *k, char **comment_return)
435{ 440{
436 DSA *dsa;
437 BIO *in;
438 FILE *fp; 441 FILE *fp;
442 int success = 0;
443 EVP_PKEY *pk = NULL;
444 char *name = "<no key>";
439 445
440 in = BIO_new(BIO_s_file());
441 if (in == NULL) {
442 error("BIO_new failed");
443 return 0;
444 }
445 fp = fdopen(fd, "r"); 446 fp = fdopen(fd, "r");
446 if (fp == NULL) { 447 if (fp == NULL) {
447 error("fdopen failed"); 448 error("fdopen failed");
448 return 0; 449 return 0;
449 } 450 }
450 BIO_set_fp(in, fp, BIO_NOCLOSE); 451 pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase);
451 dsa = PEM_read_bio_DSAPrivateKey(in, NULL, NULL, (char *)passphrase); 452 if (pk == NULL) {
452 if (dsa == NULL) { 453 debug("PEM_read_PrivateKey failed");
453 debug("PEM_read_bio_DSAPrivateKey failed"); 454 (void)ERR_get_error();
454 } else { 455 } else if (pk->type == EVP_PKEY_RSA) {
456 /* replace k->rsa with loaded key */
457 if (k->type == KEY_RSA || k->type == KEY_UNSPEC) {
458 if (k->rsa != NULL)
459 RSA_free(k->rsa);
460 k->rsa = EVP_PKEY_get1_RSA(pk);
461 k->type = KEY_RSA;
462 name = "rsa w/o comment";
463 success = 1;
464#ifdef DEBUG_PK
465 RSA_print_fp(stderr, k->rsa, 8);
466#endif
467 }
468 } else if (pk->type == EVP_PKEY_DSA) {
455 /* replace k->dsa with loaded key */ 469 /* replace k->dsa with loaded key */
456 DSA_free(k->dsa); 470 if (k->type == KEY_DSA || k->type == KEY_UNSPEC) {
457 k->dsa = dsa; 471 if (k->dsa != NULL)
472 DSA_free(k->dsa);
473 k->dsa = EVP_PKEY_get1_DSA(pk);
474 k->type = KEY_DSA;
475 name = "dsa w/o comment";
476#ifdef DEBUG_PK
477 DSA_print_fp(stderr, k->dsa, 8);
478#endif
479 success = 1;
480 }
481 } else {
482 error("PEM_read_PrivateKey: mismatch or "
483 "unknown EVP_PKEY save_type %d", pk->save_type);
458 } 484 }
459 BIO_free(in);
460 fclose(fp); 485 fclose(fp);
461 if (comment_return) 486 if (pk != NULL)
462 *comment_return = xstrdup("dsa w/o comment"); 487 EVP_PKEY_free(pk);
463 debug("read DSA private key done"); 488 if (success && comment_return)
464#ifdef DEBUG_DSS 489 *comment_return = xstrdup(name);
465 DSA_print_fp(stderr, dsa, 8); 490 debug("read SSH2 private key done: name %s success %d", name, success);
466#endif 491 return success;
467 return dsa != NULL ? 1 : 0;
468} 492}
469 493
470int 494int
@@ -496,7 +520,7 @@ load_private_key(const char *filename, const char *passphrase, Key *key,
496 return 0; 520 return 0;
497 } 521 }
498 switch (key->type) { 522 switch (key->type) {
499 case KEY_RSA: 523 case KEY_RSA1:
500 if (key->rsa->e != NULL) { 524 if (key->rsa->e != NULL) {
501 BN_clear_free(key->rsa->e); 525 BN_clear_free(key->rsa->e);
502 key->rsa->e = NULL; 526 key->rsa->e = NULL;
@@ -505,11 +529,13 @@ load_private_key(const char *filename, const char *passphrase, Key *key,
505 BN_clear_free(key->rsa->n); 529 BN_clear_free(key->rsa->n);
506 key->rsa->n = NULL; 530 key->rsa->n = NULL;
507 } 531 }
508 ret = load_private_key_rsa(fd, filename, passphrase, 532 ret = load_private_key_rsa1(fd, filename, passphrase,
509 key->rsa, comment_return); 533 key->rsa, comment_return);
510 break; 534 break;
511 case KEY_DSA: 535 case KEY_DSA:
512 ret = load_private_key_dsa(fd, passphrase, key, comment_return); 536 case KEY_RSA:
537 case KEY_UNSPEC:
538 ret = load_private_key_ssh2(fd, passphrase, key, comment_return);
513 default: 539 default:
514 break; 540 break;
515 } 541 }
@@ -521,7 +547,6 @@ int
521do_load_public_key(const char *filename, Key *k, char **commentp) 547do_load_public_key(const char *filename, Key *k, char **commentp)
522{ 548{
523 FILE *f; 549 FILE *f;
524 unsigned int bits;
525 char line[1024]; 550 char line[1024];
526 char *cp; 551 char *cp;
527 552
@@ -540,8 +565,7 @@ do_load_public_key(const char *filename, Key *k, char **commentp)
540 for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) 565 for (; *cp && (*cp == ' ' || *cp == '\t'); cp++)
541 ; 566 ;
542 if (*cp) { 567 if (*cp) {
543 bits = key_read(k, &cp); 568 if (key_read(k, &cp) == 1) {
544 if (bits != 0) {
545 if (commentp) 569 if (commentp)
546 *commentp=xstrdup(filename); 570 *commentp=xstrdup(filename);
547 fclose(f); 571 fclose(f);
diff --git a/channels.c b/channels.c
index 028c09e6a..0886a91ef 100644
--- a/channels.c
+++ b/channels.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: channels.c,v 1.72 2000/10/27 07:48:22 markus Exp $"); 43RCSID("$OpenBSD: channels.c,v 1.73 2000/11/06 23:04:55 markus Exp $");
44 44
45#include "ssh.h" 45#include "ssh.h"
46#include "packet.h" 46#include "packet.h"
@@ -588,9 +588,12 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
588 struct sockaddr addr; 588 struct sockaddr addr;
589 int newsock, newch; 589 int newsock, newch;
590 socklen_t addrlen; 590 socklen_t addrlen;
591 char buf[1024], *remote_hostname; 591 char buf[1024], *remote_hostname, *rtype;
592 int remote_port; 592 int remote_port;
593 593
594 rtype = (c->type == SSH_CHANNEL_RPORT_LISTENER) ?
595 "forwarded-tcpip" : "direct-tcpip";
596
594 if (FD_ISSET(c->sock, readset)) { 597 if (FD_ISSET(c->sock, readset)) {
595 debug("Connection to port %d forwarding " 598 debug("Connection to port %d forwarding "
596 "to %.100s port %d requested.", 599 "to %.100s port %d requested.",
@@ -608,19 +611,26 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
608 "connect from %.200s port %d", 611 "connect from %.200s port %d",
609 c->listening_port, c->path, c->host_port, 612 c->listening_port, c->path, c->host_port,
610 remote_hostname, remote_port); 613 remote_hostname, remote_port);
611 newch = channel_new("direct-tcpip", 614
615 newch = channel_new(rtype,
612 SSH_CHANNEL_OPENING, newsock, newsock, -1, 616 SSH_CHANNEL_OPENING, newsock, newsock, -1,
613 c->local_window_max, c->local_maxpacket, 617 c->local_window_max, c->local_maxpacket,
614 0, xstrdup(buf), 1); 618 0, xstrdup(buf), 1);
615 if (compat20) { 619 if (compat20) {
616 packet_start(SSH2_MSG_CHANNEL_OPEN); 620 packet_start(SSH2_MSG_CHANNEL_OPEN);
617 packet_put_cstring("direct-tcpip"); 621 packet_put_cstring(rtype);
618 packet_put_int(newch); 622 packet_put_int(newch);
619 packet_put_int(c->local_window_max); 623 packet_put_int(c->local_window_max);
620 packet_put_int(c->local_maxpacket); 624 packet_put_int(c->local_maxpacket);
621 /* target host and port */ 625 if (c->type == SSH_CHANNEL_RPORT_LISTENER) {
622 packet_put_string(c->path, strlen(c->path)); 626 /* listen address, port */
623 packet_put_int(c->host_port); 627 packet_put_string(c->path, strlen(c->path));
628 packet_put_int(c->listening_port);
629 } else {
630 /* target host, port */
631 packet_put_string(c->path, strlen(c->path));
632 packet_put_int(c->host_port);
633 }
624 /* originator host and port */ 634 /* originator host and port */
625 packet_put_cstring(remote_hostname); 635 packet_put_cstring(remote_hostname);
626 packet_put_int(remote_port); 636 packet_put_int(remote_port);
@@ -657,10 +667,20 @@ channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)
657 error("accept from auth socket: %.100s", strerror(errno)); 667 error("accept from auth socket: %.100s", strerror(errno));
658 return; 668 return;
659 } 669 }
660 newch = channel_allocate(SSH_CHANNEL_OPENING, newsock, 670 newch = channel_new("accepted auth socket",
661 xstrdup("accepted auth socket")); 671 SSH_CHANNEL_OPENING, newsock, newsock, -1,
662 packet_start(SSH_SMSG_AGENT_OPEN); 672 c->local_window_max, c->local_maxpacket,
663 packet_put_int(newch); 673 0, xstrdup("accepted auth socket"), 1);
674 if (compat20) {
675 packet_start(SSH2_MSG_CHANNEL_OPEN);
676 packet_put_cstring("auth-agent@openssh.com");
677 packet_put_int(newch);
678 packet_put_int(c->local_window_max);
679 packet_put_int(c->local_maxpacket);
680 } else {
681 packet_start(SSH_SMSG_AGENT_OPEN);
682 packet_put_int(newch);
683 }
664 packet_send(); 684 packet_send();
665 } 685 }
666} 686}
@@ -820,11 +840,15 @@ channel_handler_init_20(void)
820 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_20; 840 channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_20;
821 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open; 841 channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;
822 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener; 842 channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
843 channel_pre[SSH_CHANNEL_RPORT_LISTENER] = &channel_pre_listener;
823 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener; 844 channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
845 channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
824 846
825 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_2; 847 channel_post[SSH_CHANNEL_OPEN] = &channel_post_open_2;
826 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener; 848 channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
849 channel_post[SSH_CHANNEL_RPORT_LISTENER] = &channel_post_port_listener;
827 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener; 850 channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
851 channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
828} 852}
829 853
830void 854void
@@ -1326,6 +1350,7 @@ channel_stop_listening()
1326 channel_free(i); 1350 channel_free(i);
1327 break; 1351 break;
1328 case SSH_CHANNEL_PORT_LISTENER: 1352 case SSH_CHANNEL_PORT_LISTENER:
1353 case SSH_CHANNEL_RPORT_LISTENER:
1329 case SSH_CHANNEL_X11_LISTENER: 1354 case SSH_CHANNEL_X11_LISTENER:
1330 close(channels[i].sock); 1355 close(channels[i].sock);
1331 channel_free(i); 1356 channel_free(i);
@@ -1369,6 +1394,7 @@ channel_still_open()
1369 case SSH_CHANNEL_FREE: 1394 case SSH_CHANNEL_FREE:
1370 case SSH_CHANNEL_X11_LISTENER: 1395 case SSH_CHANNEL_X11_LISTENER:
1371 case SSH_CHANNEL_PORT_LISTENER: 1396 case SSH_CHANNEL_PORT_LISTENER:
1397 case SSH_CHANNEL_RPORT_LISTENER:
1372 case SSH_CHANNEL_CLOSED: 1398 case SSH_CHANNEL_CLOSED:
1373 case SSH_CHANNEL_AUTH_SOCKET: 1399 case SSH_CHANNEL_AUTH_SOCKET:
1374 continue; 1400 continue;
@@ -1414,6 +1440,7 @@ channel_open_message()
1414 case SSH_CHANNEL_FREE: 1440 case SSH_CHANNEL_FREE:
1415 case SSH_CHANNEL_X11_LISTENER: 1441 case SSH_CHANNEL_X11_LISTENER:
1416 case SSH_CHANNEL_PORT_LISTENER: 1442 case SSH_CHANNEL_PORT_LISTENER:
1443 case SSH_CHANNEL_RPORT_LISTENER:
1417 case SSH_CHANNEL_CLOSED: 1444 case SSH_CHANNEL_CLOSED:
1418 case SSH_CHANNEL_AUTH_SOCKET: 1445 case SSH_CHANNEL_AUTH_SOCKET:
1419 continue; 1446 continue;
@@ -1446,19 +1473,44 @@ channel_open_message()
1446 * Initiate forwarding of connections to local port "port" through the secure 1473 * Initiate forwarding of connections to local port "port" through the secure
1447 * channel to host:port from remote side. 1474 * channel to host:port from remote side.
1448 */ 1475 */
1476void
1477channel_request_local_forwarding(u_short listen_port, const char *host_to_connect,
1478 u_short port_to_connect, int gateway_ports)
1479{
1480 channel_request_forwarding(
1481 NULL, listen_port,
1482 host_to_connect, port_to_connect,
1483 gateway_ports, /*remote_fwd*/ 0);
1484}
1449 1485
1486/*
1487 * If 'remote_fwd' is true we have a '-R style' listener for protocol 2
1488 * (SSH_CHANNEL_RPORT_LISTENER).
1489 */
1450void 1490void
1451channel_request_local_forwarding(u_short port, const char *host, 1491channel_request_forwarding(
1452 u_short host_port, int gateway_ports) 1492 const char *listen_address, u_short listen_port,
1493 const char *host_to_connect, u_short port_to_connect,
1494 int gateway_ports, int remote_fwd)
1453{ 1495{
1454 int success, ch, sock, on = 1; 1496 int success, ch, sock, on = 1, ctype;
1455 struct addrinfo hints, *ai, *aitop; 1497 struct addrinfo hints, *ai, *aitop;
1456 char ntop[NI_MAXHOST], strport[NI_MAXSERV]; 1498 char ntop[NI_MAXHOST], strport[NI_MAXSERV];
1499 const char *host;
1457 struct linger linger; 1500 struct linger linger;
1458 1501
1502 if (remote_fwd) {
1503 host = listen_address;
1504 ctype = SSH_CHANNEL_RPORT_LISTENER;
1505 } else {
1506 host = host_to_connect;
1507 ctype =SSH_CHANNEL_PORT_LISTENER;
1508 }
1509
1459 if (strlen(host) > sizeof(channels[0].path) - 1) 1510 if (strlen(host) > sizeof(channels[0].path) - 1)
1460 packet_disconnect("Forward host name too long."); 1511 packet_disconnect("Forward host name too long.");
1461 1512
1513 /* XXX listen_address is currently ignored */
1462 /* 1514 /*
1463 * getaddrinfo returns a loopback address if the hostname is 1515 * getaddrinfo returns a loopback address if the hostname is
1464 * set to NULL and hints.ai_flags is not AI_PASSIVE 1516 * set to NULL and hints.ai_flags is not AI_PASSIVE
@@ -1467,7 +1519,7 @@ channel_request_local_forwarding(u_short port, const char *host,
1467 hints.ai_family = IPv4or6; 1519 hints.ai_family = IPv4or6;
1468 hints.ai_flags = gateway_ports ? AI_PASSIVE : 0; 1520 hints.ai_flags = gateway_ports ? AI_PASSIVE : 0;
1469 hints.ai_socktype = SOCK_STREAM; 1521 hints.ai_socktype = SOCK_STREAM;
1470 snprintf(strport, sizeof strport, "%d", port); 1522 snprintf(strport, sizeof strport, "%d", listen_port);
1471 if (getaddrinfo(NULL, strport, &hints, &aitop) != 0) 1523 if (getaddrinfo(NULL, strport, &hints, &aitop) != 0)
1472 packet_disconnect("getaddrinfo: fatal error"); 1524 packet_disconnect("getaddrinfo: fatal error");
1473 1525
@@ -1477,7 +1529,7 @@ channel_request_local_forwarding(u_short port, const char *host,
1477 continue; 1529 continue;
1478 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), 1530 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop),
1479 strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { 1531 strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
1480 error("channel_request_local_forwarding: getnameinfo failed"); 1532 error("channel_request_forwarding: getnameinfo failed");
1481 continue; 1533 continue;
1482 } 1534 }
1483 /* Create a port to listen for the host. */ 1535 /* Create a port to listen for the host. */
@@ -1515,18 +1567,16 @@ channel_request_local_forwarding(u_short port, const char *host,
1515 continue; 1567 continue;
1516 } 1568 }
1517 /* Allocate a channel number for the socket. */ 1569 /* Allocate a channel number for the socket. */
1518 ch = channel_new( 1570 ch = channel_new("port listener", ctype, sock, sock, -1,
1519 "port listener", SSH_CHANNEL_PORT_LISTENER,
1520 sock, sock, -1,
1521 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 1571 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
1522 0, xstrdup("port listener"), 1); 1572 0, xstrdup("port listener"), 1);
1523 strlcpy(channels[ch].path, host, sizeof(channels[ch].path)); 1573 strlcpy(channels[ch].path, host, sizeof(channels[ch].path));
1524 channels[ch].host_port = host_port; 1574 channels[ch].host_port = port_to_connect;
1525 channels[ch].listening_port = port; 1575 channels[ch].listening_port = listen_port;
1526 success = 1; 1576 success = 1;
1527 } 1577 }
1528 if (success == 0) 1578 if (success == 0)
1529 packet_disconnect("cannot listen port: %d", port); 1579 packet_disconnect("cannot listen port: %d", listen_port); /*XXX ?disconnect? */
1530 freeaddrinfo(aitop); 1580 freeaddrinfo(aitop);
1531} 1581}
1532 1582
@@ -1536,19 +1586,15 @@ channel_request_local_forwarding(u_short port, const char *host,
1536 */ 1586 */
1537 1587
1538void 1588void
1539channel_request_remote_forwarding(u_short listen_port, const char *host_to_connect, 1589channel_request_remote_forwarding(u_short listen_port,
1540 u_short port_to_connect) 1590 const char *host_to_connect, u_short port_to_connect)
1541{ 1591{
1542 int payload_len; 1592 int payload_len, type, success = 0;
1593
1543 /* Record locally that connection to this host/port is permitted. */ 1594 /* Record locally that connection to this host/port is permitted. */
1544 if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION) 1595 if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
1545 fatal("channel_request_remote_forwarding: too many forwards"); 1596 fatal("channel_request_remote_forwarding: too many forwards");
1546 1597
1547 permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect);
1548 permitted_opens[num_permitted_opens].port_to_connect = port_to_connect;
1549 permitted_opens[num_permitted_opens].listen_port = listen_port;
1550 num_permitted_opens++;
1551
1552 /* Send the forward request to the remote side. */ 1598 /* Send the forward request to the remote side. */
1553 if (compat20) { 1599 if (compat20) {
1554 const char *address_to_bind = "0.0.0.0"; 1600 const char *address_to_bind = "0.0.0.0";
@@ -1557,6 +1603,10 @@ channel_request_remote_forwarding(u_short listen_port, const char *host_to_conne
1557 packet_put_char(0); /* boolean: want reply */ 1603 packet_put_char(0); /* boolean: want reply */
1558 packet_put_cstring(address_to_bind); 1604 packet_put_cstring(address_to_bind);
1559 packet_put_int(listen_port); 1605 packet_put_int(listen_port);
1606 packet_send();
1607 packet_write_wait();
1608 /* Assume that server accepts the request */
1609 success = 1;
1560 } else { 1610 } else {
1561 packet_start(SSH_CMSG_PORT_FORWARD_REQUEST); 1611 packet_start(SSH_CMSG_PORT_FORWARD_REQUEST);
1562 packet_put_int(listen_port); 1612 packet_put_int(listen_port);
@@ -1564,11 +1614,27 @@ channel_request_remote_forwarding(u_short listen_port, const char *host_to_conne
1564 packet_put_int(port_to_connect); 1614 packet_put_int(port_to_connect);
1565 packet_send(); 1615 packet_send();
1566 packet_write_wait(); 1616 packet_write_wait();
1567 /* 1617
1568 * Wait for response from the remote side. It will send a disconnect 1618 /* Wait for response from the remote side. */
1569 * message on failure, and we will never see it here. 1619 type = packet_read(&payload_len);
1570 */ 1620 switch (type) {
1571 packet_read_expect(&payload_len, SSH_SMSG_SUCCESS); 1621 case SSH_SMSG_SUCCESS:
1622 success = 1;
1623 break;
1624 case SSH_SMSG_FAILURE:
1625 log("Warning: Server denied remote port forwarding.");
1626 break;
1627 default:
1628 /* Unknown packet */
1629 packet_disconnect("Protocol error for port forward request:"
1630 "received packet type %d.", type);
1631 }
1632 }
1633 if (success) {
1634 permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect);
1635 permitted_opens[num_permitted_opens].port_to_connect = port_to_connect;
1636 permitted_opens[num_permitted_opens].listen_port = listen_port;
1637 num_permitted_opens++;
1572 } 1638 }
1573} 1639}
1574 1640
@@ -1598,9 +1664,7 @@ channel_input_port_forward_request(int is_root, int gateway_ports)
1598 packet_disconnect("Requested forwarding of port %d but user is not root.", 1664 packet_disconnect("Requested forwarding of port %d but user is not root.",
1599 port); 1665 port);
1600#endif 1666#endif
1601 /* 1667 /* Initiate forwarding */
1602 * Initiate forwarding,
1603 */
1604 channel_request_local_forwarding(port, hostname, host_port, gateway_ports); 1668 channel_request_local_forwarding(port, hostname, host_port, gateway_ports);
1605 1669
1606 /* Free the argument string. */ 1670 /* Free the argument string. */
@@ -1656,6 +1720,18 @@ channel_connect_to(const char *host, u_short host_port)
1656 /* success */ 1720 /* success */
1657 return sock; 1721 return sock;
1658} 1722}
1723int
1724channel_connect_by_listen_adress(u_short listen_port)
1725{
1726 int i;
1727 for (i = 0; i < num_permitted_opens; i++)
1728 if (permitted_opens[i].listen_port == listen_port)
1729 return channel_connect_to(
1730 permitted_opens[i].host_to_connect,
1731 permitted_opens[i].port_to_connect);
1732 debug("channel_connect_by_listen_adress: unknown listen_port %d", listen_port);
1733 return -1;
1734}
1659 1735
1660/* 1736/*
1661 * This is called after receiving PORT_OPEN message. This attempts to 1737 * This is called after receiving PORT_OPEN message. This attempts to
@@ -2233,8 +2309,11 @@ auth_input_request_forwarding(struct passwd * pw)
2233 packet_disconnect("listen: %.100s", strerror(errno)); 2309 packet_disconnect("listen: %.100s", strerror(errno));
2234 2310
2235 /* Allocate a channel for the authentication agent socket. */ 2311 /* Allocate a channel for the authentication agent socket. */
2236 newch = channel_allocate(SSH_CHANNEL_AUTH_SOCKET, sock, 2312 newch = channel_new("auth socket",
2237 xstrdup("auth socket")); 2313 SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
2314 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
2315 0, xstrdup("auth socket"), 1);
2316
2238 strlcpy(channels[newch].path, channel_forwarded_auth_socket_name, 2317 strlcpy(channels[newch].path, channel_forwarded_auth_socket_name,
2239 sizeof(channels[newch].path)); 2318 sizeof(channels[newch].path));
2240 return 1; 2319 return 1;
diff --git a/channels.h b/channels.h
index 00526860c..8f5e987fc 100644
--- a/channels.h
+++ b/channels.h
@@ -32,7 +32,7 @@
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35/* RCSID("$OpenBSD: channels.h,v 1.22 2000/10/27 07:48:22 markus Exp $"); */ 35/* RCSID("$OpenBSD: channels.h,v 1.23 2000/11/06 23:04:56 markus Exp $"); */
36 36
37#ifndef CHANNELS_H 37#ifndef CHANNELS_H
38#define CHANNELS_H 38#define CHANNELS_H
@@ -49,7 +49,8 @@
49#define SSH_CHANNEL_INPUT_DRAINING 8 /* sending remaining data to conn */ 49#define SSH_CHANNEL_INPUT_DRAINING 8 /* sending remaining data to conn */
50#define SSH_CHANNEL_OUTPUT_DRAINING 9 /* sending remaining data to app */ 50#define SSH_CHANNEL_OUTPUT_DRAINING 9 /* sending remaining data to app */
51#define SSH_CHANNEL_LARVAL 10 /* larval session */ 51#define SSH_CHANNEL_LARVAL 10 /* larval session */
52#define SSH_CHANNEL_MAX_TYPE 11 52#define SSH_CHANNEL_RPORT_LISTENER 11 /* Listening to a R-style port */
53#define SSH_CHANNEL_MAX_TYPE 12
53 54
54/* 55/*
55 * Data structure for channel data. This is iniailized in channel_allocate 56 * Data structure for channel data. This is iniailized in channel_allocate
@@ -147,7 +148,6 @@ void channel_input_open_confirmation(int type, int plen, void *ctxt);
147void channel_input_open_failure(int type, int plen, void *ctxt); 148void channel_input_open_failure(int type, int plen, void *ctxt);
148void channel_input_port_open(int type, int plen, void *ctxt); 149void channel_input_port_open(int type, int plen, void *ctxt);
149void channel_input_window_adjust(int type, int plen, void *ctxt); 150void channel_input_window_adjust(int type, int plen, void *ctxt);
150void channel_input_open(int type, int plen, void *ctxt);
151 151
152/* Sets specific protocol options. */ 152/* Sets specific protocol options. */
153void channel_set_options(int hostname_in_open); 153void channel_set_options(int hostname_in_open);
@@ -202,12 +202,15 @@ char *channel_open_message(void);
202 202
203/* 203/*
204 * Initiate forwarding of connections to local port "port" through the secure 204 * Initiate forwarding of connections to local port "port" through the secure
205 * channel to host:port from remote side. This never returns if there was an 205 * channel to host:port from remote side.
206 * error.
207 */ 206 */
208void 207void
209channel_request_local_forwarding(u_short port, const char *host, 208channel_request_local_forwarding(u_short listen_port,
210 u_short remote_port, int gateway_ports); 209 const char *host_to_connect, u_short port_to_connect, int gateway_ports);
210void
211channel_request_forwarding(const char *listen_address, u_short listen_port,
212 const char *host_to_connect, u_short port_to_connect, int gateway_ports,
213 int remote_fwd);
211 214
212/* 215/*
213 * Initiate forwarding of connections to port "port" on remote host through 216 * Initiate forwarding of connections to port "port" on remote host through
@@ -288,6 +291,7 @@ void auth_input_open_request(int type, int plen, void *ctxt);
288 291
289/* XXX */ 292/* XXX */
290int channel_connect_to(const char *host, u_short host_port); 293int channel_connect_to(const char *host, u_short host_port);
294int channel_connect_by_listen_adress(u_short listen_port);
291int x11_connect_display(void); 295int x11_connect_display(void);
292 296
293#endif 297#endif
diff --git a/clientloop.c b/clientloop.c
index bccb9be2f..8f16d2fb9 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -59,7 +59,7 @@
59 */ 59 */
60 60
61#include "includes.h" 61#include "includes.h"
62RCSID("$OpenBSD: clientloop.c,v 1.39 2000/10/27 07:48:22 markus Exp $"); 62RCSID("$OpenBSD: clientloop.c,v 1.40 2000/11/06 23:04:56 markus Exp $");
63 63
64#include "xmalloc.h" 64#include "xmalloc.h"
65#include "ssh.h" 65#include "ssh.h"
@@ -75,6 +75,10 @@ RCSID("$OpenBSD: clientloop.c,v 1.39 2000/10/27 07:48:22 markus Exp $");
75#include "buffer.h" 75#include "buffer.h"
76#include "bufaux.h" 76#include "bufaux.h"
77 77
78#include <openssl/dsa.h>
79#include <openssl/rsa.h>
80#include "key.h"
81#include "authfd.h"
78 82
79/* import options */ 83/* import options */
80extern Options options; 84extern Options options;
@@ -1016,13 +1020,99 @@ client_input_exit_status(int type, int plen, void *ctxt)
1016 quit_pending = 1; 1020 quit_pending = 1;
1017} 1021}
1018 1022
1023Channel *
1024client_request_forwarded_tcpip(const char *request_type, int rchan)
1025{
1026 Channel* c = NULL;
1027 char *listen_address, *originator_address;
1028 int listen_port, originator_port;
1029 int sock, newch;
1030
1031 /* Get rest of the packet */
1032 listen_address = packet_get_string(NULL);
1033 listen_port = packet_get_int();
1034 originator_address = packet_get_string(NULL);
1035 originator_port = packet_get_int();
1036 packet_done();
1037
1038 debug("client_request_forwarded_tcpip: listen %s port %d, originator %s port %d",
1039 listen_address, listen_port, originator_address, originator_port);
1040
1041 sock = channel_connect_by_listen_adress(listen_port);
1042 if (sock >= 0) {
1043 newch = channel_new("forwarded-tcpip",
1044 SSH_CHANNEL_OPEN, sock, sock, -1,
1045 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
1046 xstrdup(originator_address), 1);
1047 c = channel_lookup(newch);
1048 }
1049 xfree(originator_address);
1050 xfree(listen_address);
1051 return c;
1052}
1053
1054Channel*
1055client_request_x11(const char *request_type, int rchan)
1056{
1057 Channel *c = NULL;
1058 char *originator;
1059 int originator_port;
1060 int sock, newch;
1061
1062 if (!options.forward_x11) {
1063 error("Warning: ssh server tried X11 forwarding.");
1064 error("Warning: this is probably a break in attempt by a malicious server.");
1065 return NULL;
1066 }
1067 originator = packet_get_string(NULL);
1068 if (datafellows & SSH_BUG_X11FWD) {
1069 debug2("buggy server: x11 request w/o originator_port");
1070 originator_port = 0;
1071 } else {
1072 originator_port = packet_get_int();
1073 }
1074 packet_done();
1075 /* XXX check permission */
1076 sock = x11_connect_display();
1077 if (sock >= 0) {
1078 newch = channel_new("x11",
1079 SSH_CHANNEL_X11_OPEN, sock, sock, -1,
1080 CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0,
1081 xstrdup("x11"), 1);
1082 c = channel_lookup(newch);
1083 }
1084 xfree(originator);
1085 return c;
1086}
1087
1088Channel*
1089client_request_agent(const char *request_type, int rchan)
1090{
1091 Channel *c = NULL;
1092 int sock, newch;
1093
1094 if (!options.forward_agent) {
1095 error("Warning: ssh server tried agent forwarding.");
1096 error("Warning: this is probably a break in attempt by a malicious server.");
1097 return NULL;
1098 }
1099 sock = ssh_get_authentication_socket();
1100 if (sock >= 0) {
1101 newch = channel_new("authentication agent connection",
1102 SSH_CHANNEL_OPEN, sock, sock, -1,
1103 CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
1104 xstrdup("authentication agent connection"), 1);
1105 c = channel_lookup(newch);
1106 }
1107 return c;
1108}
1109
1019/* XXXX move to generic input handler */ 1110/* XXXX move to generic input handler */
1020void 1111void
1021client_input_channel_open(int type, int plen, void *ctxt) 1112client_input_channel_open(int type, int plen, void *ctxt)
1022{ 1113{
1023 Channel *c = NULL; 1114 Channel *c = NULL;
1024 char *ctype; 1115 char *ctype;
1025 int id;
1026 unsigned int len; 1116 unsigned int len;
1027 int rchan; 1117 int rchan;
1028 int rmaxpack; 1118 int rmaxpack;
@@ -1036,28 +1126,12 @@ client_input_channel_open(int type, int plen, void *ctxt)
1036 debug("client_input_channel_open: ctype %s rchan %d win %d max %d", 1126 debug("client_input_channel_open: ctype %s rchan %d win %d max %d",
1037 ctype, rchan, rwindow, rmaxpack); 1127 ctype, rchan, rwindow, rmaxpack);
1038 1128
1039 if (strcmp(ctype, "x11") == 0 && options.forward_x11) { 1129 if (strcmp(ctype, "forwarded-tcpip") == 0) {
1040 int sock; 1130 c = client_request_forwarded_tcpip(ctype, rchan);
1041 char *originator; 1131 } else if (strcmp(ctype, "x11") == 0) {
1042 int originator_port; 1132 c = client_request_x11(ctype, rchan);
1043 originator = packet_get_string(NULL); 1133 } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) {
1044 if (datafellows & SSH_BUG_X11FWD) { 1134 c = client_request_agent(ctype, rchan);
1045 debug2("buggy server: x11 request w/o originator_port");
1046 originator_port = 0;
1047 } else {
1048 originator_port = packet_get_int();
1049 }
1050 packet_done();
1051 /* XXX check permission */
1052 xfree(originator);
1053 /* XXX move to channels.c */
1054 sock = x11_connect_display();
1055 if (sock >= 0) {
1056 id = channel_new("x11", SSH_CHANNEL_X11_OPEN,
1057 sock, sock, -1, CHAN_X11_WINDOW_DEFAULT,
1058 CHAN_X11_PACKET_DEFAULT, 0, xstrdup("x11"), 1);
1059 c = channel_lookup(id);
1060 }
1061 } 1135 }
1062/* XXX duplicate : */ 1136/* XXX duplicate : */
1063 if (c != NULL) { 1137 if (c != NULL) {
diff --git a/contrib/redhat/sshd.init b/contrib/redhat/sshd.init
index 41f98ad88..a4df64276 100755
--- a/contrib/redhat/sshd.init
+++ b/contrib/redhat/sshd.init
@@ -19,13 +19,27 @@ RETVAL=0
19 19
20# Some functions to make the below more readable 20# Some functions to make the below more readable
21KEYGEN=/usr/bin/ssh-keygen 21KEYGEN=/usr/bin/ssh-keygen
22RSA_KEY=/etc/ssh/ssh_host_key 22RSA1_KEY=/etc/ssh/ssh_host_key
23RSA_KEY=/etc/ssh/ssh_host_rsa_key
23DSA_KEY=/etc/ssh/ssh_host_dsa_key 24DSA_KEY=/etc/ssh/ssh_host_dsa_key
24PID_FILE=/var/run/sshd.pid 25PID_FILE=/var/run/sshd.pid
26do_rsa1_keygen() {
27 if ! test -f $RSA1_KEY ; then
28 echo -n "Generating SSH1 RSA host key: "
29 if $KEYGEN -q -t rsa1 -f $RSA1_KEY -C '' -N '' >&/dev/null; then
30 success "RSA1 key generation"
31 echo
32 else
33 failure "RSA1 key generation"
34 echo
35 exit 1
36 fi
37 fi
38}
25do_rsa_keygen() { 39do_rsa_keygen() {
26 if $KEYGEN -R && ! test -f $RSA_KEY ; then 40 if ! test -f $RSA_KEY ; then
27 echo -n "Generating SSH RSA host key: " 41 echo -n "Generating SSH2 RSA host key: "
28 if $KEYGEN -q -b 1024 -f $RSA_KEY -C '' -N '' >&/dev/null; then 42 if $KEYGEN -q -t rsa -f $RSA_KEY -C '' -N '' >&/dev/null; then
29 success "RSA key generation" 43 success "RSA key generation"
30 echo 44 echo
31 else 45 else
@@ -37,8 +51,8 @@ do_rsa_keygen() {
37} 51}
38do_dsa_keygen() { 52do_dsa_keygen() {
39 if ! test -f $DSA_KEY ; then 53 if ! test -f $DSA_KEY ; then
40 echo -n "Generating SSH DSA host key: " 54 echo -n "Generating SSH2 DSA host key: "
41 if $KEYGEN -q -d -b 1024 -f $DSA_KEY -C '' -N '' >&/dev/null; then 55 if $KEYGEN -q -t dsa -f $DSA_KEY -C '' -N '' >&/dev/null; then
42 success "DSA key generation" 56 success "DSA key generation"
43 echo 57 echo
44 else 58 else
@@ -52,6 +66,7 @@ do_dsa_keygen() {
52case "$1" in 66case "$1" in
53 start) 67 start)
54 # Create keys if necessary 68 # Create keys if necessary
69 do_rsa1_keygen;
55 do_rsa_keygen; 70 do_rsa_keygen;
56 do_dsa_keygen; 71 do_dsa_keygen;
57 72
diff --git a/hostfile.c b/hostfile.c
index 9c03a4688..3b0f286fd 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.20 2000/09/07 20:27:51 deraadt Exp $"); 39RCSID("$OpenBSD: hostfile.c,v 1.21 2000/11/12 19:50:37 markus Exp $");
40 40
41#include "packet.h" 41#include "packet.h"
42#include "match.h" 42#include "match.h"
@@ -54,15 +54,13 @@ RCSID("$OpenBSD: hostfile.c,v 1.20 2000/09/07 20:27:51 deraadt Exp $");
54int 54int
55hostfile_read_key(char **cpp, unsigned int *bitsp, Key *ret) 55hostfile_read_key(char **cpp, unsigned int *bitsp, Key *ret)
56{ 56{
57 unsigned int bits;
58 char *cp; 57 char *cp;
59 58
60 /* Skip leading whitespace. */ 59 /* Skip leading whitespace. */
61 for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) 60 for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++)
62 ; 61 ;
63 62
64 bits = key_read(ret, &cp); 63 if (key_read(ret, &cp) != 1)
65 if (bits == 0)
66 return 0; 64 return 0;
67 65
68 /* Skip trailing whitespace. */ 66 /* Skip trailing whitespace. */
@@ -71,14 +69,14 @@ hostfile_read_key(char **cpp, unsigned int *bitsp, Key *ret)
71 69
72 /* Return results. */ 70 /* Return results. */
73 *cpp = cp; 71 *cpp = cp;
74 *bitsp = bits; 72 *bitsp = key_size(ret);
75 return 1; 73 return 1;
76} 74}
77 75
78int 76int
79auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n) 77auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
80{ 78{
81 Key *k = key_new(KEY_RSA); 79 Key *k = key_new(KEY_RSA1);
82 int ret = hostfile_read_key(cpp, bitsp, k); 80 int ret = hostfile_read_key(cpp, bitsp, k);
83 BN_copy(e, k->rsa->e); 81 BN_copy(e, k->rsa->e);
84 BN_copy(n, k->rsa->n); 82 BN_copy(n, k->rsa->n);
@@ -89,7 +87,7 @@ auth_rsa_read_key(char **cpp, unsigned int *bitsp, BIGNUM * e, BIGNUM * n)
89int 87int
90hostfile_check_key(int bits, Key *key, const char *host, const char *filename, int linenum) 88hostfile_check_key(int bits, Key *key, const char *host, const char *filename, int linenum)
91{ 89{
92 if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) 90 if (key == NULL || key->type != KEY_RSA1 || key->rsa == NULL)
93 return 1; 91 return 1;
94 if (bits != BN_num_bits(key->rsa->n)) { 92 if (bits != BN_num_bits(key->rsa->n)) {
95 log("Warning: %s, line %d: keysize mismatch for host %s: " 93 log("Warning: %s, line %d: keysize mismatch for host %s: "
diff --git a/kex.c b/kex.c
index 68b9e522e..2dbac9b13 100644
--- a/kex.c
+++ b/kex.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: kex.c,v 1.12 2000/10/11 20:27:23 markus Exp $"); 26RCSID("$OpenBSD: kex.c,v 1.13 2000/11/12 19:50:37 markus Exp $");
27 27
28#include "ssh.h" 28#include "ssh.h"
29#include "ssh2.h" 29#include "ssh2.h"
@@ -43,6 +43,7 @@ RCSID("$OpenBSD: kex.c,v 1.12 2000/10/11 20:27:23 markus Exp $");
43#include <openssl/pem.h> 43#include <openssl/pem.h>
44 44
45#include "kex.h" 45#include "kex.h"
46#include "key.h"
46 47
47#define KEX_COOKIE_LEN 16 48#define KEX_COOKIE_LEN 16
48 49
@@ -454,11 +455,12 @@ choose_kex(Kex *k, char *client, char *server)
454void 455void
455choose_hostkeyalg(Kex *k, char *client, char *server) 456choose_hostkeyalg(Kex *k, char *client, char *server)
456{ 457{
457 k->hostkeyalg = get_match(client, server); 458 char *hostkeyalg = get_match(client, server);
458 if (k->hostkeyalg == NULL) 459 if (hostkeyalg == NULL)
459 fatal("no hostkey alg"); 460 fatal("no hostkey alg");
460 if (strcmp(k->hostkeyalg, KEX_DSS) != 0) 461 k->hostkey_type = key_type_from_name(hostkeyalg);
461 fatal("bad hostkey alg %s", k->hostkeyalg); 462 if (k->hostkey_type == KEY_UNSPEC)
463 fatal("bad hostkey alg '%s'", hostkeyalg);
462} 464}
463 465
464Kex * 466Kex *
diff --git a/kex.h b/kex.h
index 212958131..1890fc025 100644
--- a/kex.h
+++ b/kex.h
@@ -85,7 +85,7 @@ struct Kex {
85 int we_need; 85 int we_need;
86 int server; 86 int server;
87 char *name; 87 char *name;
88 char *hostkeyalg; 88 int hostkey_type;
89 int kex_type; 89 int kex_type;
90}; 90};
91 91
diff --git a/key.c b/key.c
index f7df0bb1d..a6b25b7ae 100644
--- a/key.c
+++ b/key.c
@@ -39,12 +39,14 @@
39#include <openssl/evp.h> 39#include <openssl/evp.h>
40#include "xmalloc.h" 40#include "xmalloc.h"
41#include "key.h" 41#include "key.h"
42#include "dsa.h" 42#include "rsa.h"
43#include "ssh-dss.h"
44#include "ssh-rsa.h"
43#include "uuencode.h" 45#include "uuencode.h"
46#include "buffer.h"
47#include "bufaux.h"
44 48
45RCSID("$OpenBSD: key.c,v 1.11 2000/09/07 20:27:51 deraadt Exp $"); 49RCSID("$OpenBSD: key.c,v 1.12 2000/11/12 19:50:37 markus Exp $");
46
47#define SSH_DSS "ssh-dss"
48 50
49Key * 51Key *
50key_new(int type) 52key_new(int type)
@@ -57,6 +59,7 @@ key_new(int type)
57 k->dsa = NULL; 59 k->dsa = NULL;
58 k->rsa = NULL; 60 k->rsa = NULL;
59 switch (k->type) { 61 switch (k->type) {
62 case KEY_RSA1:
60 case KEY_RSA: 63 case KEY_RSA:
61 rsa = RSA_new(); 64 rsa = RSA_new();
62 rsa->n = BN_new(); 65 rsa->n = BN_new();
@@ -71,7 +74,7 @@ key_new(int type)
71 dsa->pub_key = BN_new(); 74 dsa->pub_key = BN_new();
72 k->dsa = dsa; 75 k->dsa = dsa;
73 break; 76 break;
74 case KEY_EMPTY: 77 case KEY_UNSPEC:
75 break; 78 break;
76 default: 79 default:
77 fatal("key_new: bad key type %d", k->type); 80 fatal("key_new: bad key type %d", k->type);
@@ -79,10 +82,35 @@ key_new(int type)
79 } 82 }
80 return k; 83 return k;
81} 84}
85Key *
86key_new_private(int type)
87{
88 Key *k = key_new(type);
89 switch (k->type) {
90 case KEY_RSA1:
91 case KEY_RSA:
92 k->rsa->d = BN_new();
93 k->rsa->iqmp = BN_new();
94 k->rsa->q = BN_new();
95 k->rsa->p = BN_new();
96 k->rsa->dmq1 = BN_new();
97 k->rsa->dmp1 = BN_new();
98 break;
99 case KEY_DSA:
100 k->dsa->priv_key = BN_new();
101 break;
102 case KEY_UNSPEC:
103 break;
104 default:
105 break;
106 }
107 return k;
108}
82void 109void
83key_free(Key *k) 110key_free(Key *k)
84{ 111{
85 switch (k->type) { 112 switch (k->type) {
113 case KEY_RSA1:
86 case KEY_RSA: 114 case KEY_RSA:
87 if (k->rsa != NULL) 115 if (k->rsa != NULL)
88 RSA_free(k->rsa); 116 RSA_free(k->rsa);
@@ -93,6 +121,8 @@ key_free(Key *k)
93 DSA_free(k->dsa); 121 DSA_free(k->dsa);
94 k->dsa = NULL; 122 k->dsa = NULL;
95 break; 123 break;
124 case KEY_UNSPEC:
125 break;
96 default: 126 default:
97 fatal("key_free: bad key type %d", k->type); 127 fatal("key_free: bad key type %d", k->type);
98 break; 128 break;
@@ -105,6 +135,7 @@ key_equal(Key *a, Key *b)
105 if (a == NULL || b == NULL || a->type != b->type) 135 if (a == NULL || b == NULL || a->type != b->type)
106 return 0; 136 return 0;
107 switch (a->type) { 137 switch (a->type) {
138 case KEY_RSA1:
108 case KEY_RSA: 139 case KEY_RSA:
109 return a->rsa != NULL && b->rsa != NULL && 140 return a->rsa != NULL && b->rsa != NULL &&
110 BN_cmp(a->rsa->e, b->rsa->e) == 0 && 141 BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
@@ -136,8 +167,9 @@ key_fingerprint(Key *k)
136 int len = 0; 167 int len = 0;
137 int nlen, elen; 168 int nlen, elen;
138 169
170 retval[0] = '\0';
139 switch (k->type) { 171 switch (k->type) {
140 case KEY_RSA: 172 case KEY_RSA1:
141 nlen = BN_num_bytes(k->rsa->n); 173 nlen = BN_num_bytes(k->rsa->n);
142 elen = BN_num_bytes(k->rsa->e); 174 elen = BN_num_bytes(k->rsa->e);
143 len = nlen + elen; 175 len = nlen + elen;
@@ -146,14 +178,16 @@ key_fingerprint(Key *k)
146 BN_bn2bin(k->rsa->e, blob + nlen); 178 BN_bn2bin(k->rsa->e, blob + nlen);
147 break; 179 break;
148 case KEY_DSA: 180 case KEY_DSA:
149 dsa_make_key_blob(k, &blob, &len); 181 case KEY_RSA:
182 key_to_blob(k, &blob, &len);
183 break;
184 case KEY_UNSPEC:
185 return retval;
150 break; 186 break;
151 default: 187 default:
152 fatal("key_fingerprint: bad key type %d", k->type); 188 fatal("key_fingerprint: bad key type %d", k->type);
153 break; 189 break;
154 } 190 }
155 retval[0] = '\0';
156
157 if (blob != NULL) { 191 if (blob != NULL) {
158 int i; 192 int i;
159 unsigned char digest[EVP_MAX_MD_SIZE]; 193 unsigned char digest[EVP_MAX_MD_SIZE];
@@ -229,56 +263,106 @@ write_bignum(FILE *f, BIGNUM *num)
229 free(buf); 263 free(buf);
230 return 1; 264 return 1;
231} 265}
232unsigned int 266
267/* returns 1 ok, -1 error, 0 type mismatch */
268int
233key_read(Key *ret, char **cpp) 269key_read(Key *ret, char **cpp)
234{ 270{
235 Key *k; 271 Key *k;
236 unsigned int bits = 0; 272 int success = -1;
237 char *cp; 273 char *cp, *space;
238 int len, n; 274 int len, n, type;
275 u_int bits;
239 unsigned char *blob; 276 unsigned char *blob;
240 277
241 cp = *cpp; 278 cp = *cpp;
242 279
243 switch(ret->type) { 280 switch(ret->type) {
244 case KEY_RSA: 281 case KEY_RSA1:
245 /* Get number of bits. */ 282 /* Get number of bits. */
246 if (*cp < '0' || *cp > '9') 283 if (*cp < '0' || *cp > '9')
247 return 0; /* Bad bit count... */ 284 return -1; /* Bad bit count... */
248 for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) 285 for (bits = 0; *cp >= '0' && *cp <= '9'; cp++)
249 bits = 10 * bits + *cp - '0'; 286 bits = 10 * bits + *cp - '0';
250 if (bits == 0) 287 if (bits == 0)
251 return 0; 288 return -1;
252 *cpp = cp; 289 *cpp = cp;
253 /* Get public exponent, public modulus. */ 290 /* Get public exponent, public modulus. */
254 if (!read_bignum(cpp, ret->rsa->e)) 291 if (!read_bignum(cpp, ret->rsa->e))
255 return 0; 292 return -1;
256 if (!read_bignum(cpp, ret->rsa->n)) 293 if (!read_bignum(cpp, ret->rsa->n))
257 return 0; 294 return -1;
295 success = 1;
258 break; 296 break;
297 case KEY_UNSPEC:
298 case KEY_RSA:
259 case KEY_DSA: 299 case KEY_DSA:
260 if (strncmp(cp, SSH_DSS " ", 7) != 0) 300 space = strchr(cp, ' ');
301 if (space == NULL) {
302 debug3("key_read: no space");
303 return -1;
304 }
305 *space = '\0';
306 type = key_type_from_name(cp);
307 *space = ' ';
308 if (type == KEY_UNSPEC) {
309 debug3("key_read: no key found");
310 return -1;
311 }
312 cp = space+1;
313 if (*cp == '\0') {
314 debug3("key_read: short string");
315 return -1;
316 }
317 if (ret->type == KEY_UNSPEC) {
318 ret->type = type;
319 } else if (ret->type != type) {
320 /* is a key, but different type */
321 debug3("key_read: type mismatch");
261 return 0; 322 return 0;
262 cp += 7; 323 }
263 len = 2*strlen(cp); 324 len = 2*strlen(cp);
264 blob = xmalloc(len); 325 blob = xmalloc(len);
265 n = uudecode(cp, blob, len); 326 n = uudecode(cp, blob, len);
266 if (n < 0) { 327 if (n < 0) {
267 error("key_read: uudecode %s failed", cp); 328 error("key_read: uudecode %s failed", cp);
268 return 0; 329 return -1;
269 } 330 }
270 k = dsa_key_from_blob(blob, n); 331 k = key_from_blob(blob, n);
271 if (k == NULL) { 332 if (k == NULL) {
272 error("key_read: dsa_key_from_blob %s failed", cp); 333 error("key_read: key_from_blob %s failed", cp);
273 return 0; 334 return -1;
274 } 335 }
275 xfree(blob); 336 xfree(blob);
276 if (ret->dsa != NULL) 337 if (k->type != type) {
277 DSA_free(ret->dsa); 338 error("key_read: type mismatch: encoding error");
278 ret->dsa = k->dsa; 339 key_free(k);
279 k->dsa = NULL; 340 return -1;
341 }
342/*XXXX*/
343 if (ret->type == KEY_RSA) {
344 if (ret->rsa != NULL)
345 RSA_free(ret->rsa);
346 ret->rsa = k->rsa;
347 k->rsa = NULL;
348 success = 1;
349#ifdef DEBUG_PK
350 RSA_print_fp(stderr, ret->rsa, 8);
351#endif
352 } else {
353 if (ret->dsa != NULL)
354 DSA_free(ret->dsa);
355 ret->dsa = k->dsa;
356 k->dsa = NULL;
357 success = 1;
358#ifdef DEBUG_PK
359 DSA_print_fp(stderr, ret->dsa, 8);
360#endif
361 }
362/*XXXX*/
363 if (success != 1)
364 break;
280 key_free(k); 365 key_free(k);
281 bits = BN_num_bits(ret->dsa->p);
282 /* advance cp: skip whitespace and data */ 366 /* advance cp: skip whitespace and data */
283 while (*cp == ' ' || *cp == '\t') 367 while (*cp == ' ' || *cp == '\t')
284 cp++; 368 cp++;
@@ -290,7 +374,7 @@ key_read(Key *ret, char **cpp)
290 fatal("key_read: bad key type: %d", ret->type); 374 fatal("key_read: bad key type: %d", ret->type);
291 break; 375 break;
292 } 376 }
293 return bits; 377 return success;
294} 378}
295int 379int
296key_write(Key *key, FILE *f) 380key_write(Key *key, FILE *f)
@@ -298,7 +382,7 @@ key_write(Key *key, FILE *f)
298 int success = 0; 382 int success = 0;
299 unsigned int bits = 0; 383 unsigned int bits = 0;
300 384
301 if (key->type == KEY_RSA && key->rsa != NULL) { 385 if (key->type == KEY_RSA1 && key->rsa != NULL) {
302 /* size of modulus 'n' */ 386 /* size of modulus 'n' */
303 bits = BN_num_bits(key->rsa->n); 387 bits = BN_num_bits(key->rsa->n);
304 fprintf(f, "%u", bits); 388 fprintf(f, "%u", bits);
@@ -308,14 +392,15 @@ key_write(Key *key, FILE *f)
308 } else { 392 } else {
309 error("key_write: failed for RSA key"); 393 error("key_write: failed for RSA key");
310 } 394 }
311 } else if (key->type == KEY_DSA && key->dsa != NULL) { 395 } else if ((key->type == KEY_DSA && key->dsa != NULL) ||
396 (key->type == KEY_RSA && key->rsa != NULL)) {
312 int len, n; 397 int len, n;
313 unsigned char *blob, *uu; 398 unsigned char *blob, *uu;
314 dsa_make_key_blob(key, &blob, &len); 399 key_to_blob(key, &blob, &len);
315 uu = xmalloc(2*len); 400 uu = xmalloc(2*len);
316 n = uuencode(blob, len, uu, 2*len); 401 n = uuencode(blob, len, uu, 2*len);
317 if (n > 0) { 402 if (n > 0) {
318 fprintf(f, "%s %s", SSH_DSS, uu); 403 fprintf(f, "%s %s", key_ssh_name(key), uu);
319 success = 1; 404 success = 1;
320 } 405 }
321 xfree(blob); 406 xfree(blob);
@@ -327,6 +412,9 @@ char *
327key_type(Key *k) 412key_type(Key *k)
328{ 413{
329 switch (k->type) { 414 switch (k->type) {
415 case KEY_RSA1:
416 return "RSA1";
417 break;
330 case KEY_RSA: 418 case KEY_RSA:
331 return "RSA"; 419 return "RSA";
332 break; 420 break;
@@ -336,9 +424,23 @@ key_type(Key *k)
336 } 424 }
337 return "unknown"; 425 return "unknown";
338} 426}
339unsigned int 427char *
428key_ssh_name(Key *k)
429{
430 switch (k->type) {
431 case KEY_RSA:
432 return "ssh-rsa";
433 break;
434 case KEY_DSA:
435 return "ssh-dss";
436 break;
437 }
438 return "ssh-unknown";
439}
440u_int
340key_size(Key *k){ 441key_size(Key *k){
341 switch (k->type) { 442 switch (k->type) {
443 case KEY_RSA1:
342 case KEY_RSA: 444 case KEY_RSA:
343 return BN_num_bits(k->rsa->n); 445 return BN_num_bits(k->rsa->n);
344 break; 446 break;
@@ -348,3 +450,219 @@ key_size(Key *k){
348 } 450 }
349 return 0; 451 return 0;
350} 452}
453
454RSA *
455rsa_generate_private_key(unsigned int bits)
456{
457 RSA *private;
458 private = RSA_generate_key(bits, 35, NULL, NULL);
459 if (private == NULL)
460 fatal("rsa_generate_private_key: key generation failed.");
461 return private;
462}
463
464DSA*
465dsa_generate_private_key(unsigned int bits)
466{
467 DSA *private = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
468 if (private == NULL)
469 fatal("dsa_generate_private_key: DSA_generate_parameters failed");
470 if (!DSA_generate_key(private))
471 fatal("dsa_generate_private_key: DSA_generate_key failed.");
472 if (private == NULL)
473 fatal("dsa_generate_private_key: NULL.");
474 return private;
475}
476
477Key *
478key_generate(int type, unsigned int bits)
479{
480 Key *k = key_new(KEY_UNSPEC);
481 switch (type) {
482 case KEY_DSA:
483 k->dsa = dsa_generate_private_key(bits);
484 break;
485 case KEY_RSA:
486 case KEY_RSA1:
487 k->rsa = rsa_generate_private_key(bits);
488 break;
489 default:
490 fatal("key_generate: unknown type %d", type);
491 }
492 k->type = type;
493 return k;
494}
495
496Key *
497key_from_private(Key *k)
498{
499 Key *n = NULL;
500 switch (k->type) {
501 case KEY_DSA:
502 n = key_new(k->type);
503 BN_copy(n->dsa->p, k->dsa->p);
504 BN_copy(n->dsa->q, k->dsa->q);
505 BN_copy(n->dsa->g, k->dsa->g);
506 BN_copy(n->dsa->pub_key, k->dsa->pub_key);
507 break;
508 case KEY_RSA:
509 case KEY_RSA1:
510 n = key_new(k->type);
511 BN_copy(n->rsa->n, k->rsa->n);
512 BN_copy(n->rsa->e, k->rsa->e);
513 break;
514 default:
515 fatal("key_from_private: unknown type %d", k->type);
516 break;
517 }
518 return n;
519}
520
521int
522key_type_from_name(char *name)
523{
524 if (strcmp(name, "rsa1") == 0){
525 return KEY_RSA1;
526 } else if (strcmp(name, "rsa") == 0){
527 return KEY_RSA;
528 } else if (strcmp(name, "dsa") == 0){
529 return KEY_DSA;
530 } else if (strcmp(name, "ssh-rsa") == 0){
531 return KEY_RSA;
532 } else if (strcmp(name, "ssh-dss") == 0){
533 return KEY_DSA;
534 }
535 debug("key_type_from_name: unknown key type '%s'", name);
536 return KEY_UNSPEC;
537}
538
539Key *
540key_from_blob(char *blob, int blen)
541{
542 Buffer b;
543 char *ktype;
544 int rlen, type;
545 Key *key = NULL;
546
547#ifdef DEBUG_PK
548 dump_base64(stderr, blob, blen);
549#endif
550 buffer_init(&b);
551 buffer_append(&b, blob, blen);
552 ktype = buffer_get_string(&b, NULL);
553 type = key_type_from_name(ktype);
554
555 switch(type){
556 case KEY_RSA:
557 key = key_new(type);
558 buffer_get_bignum2(&b, key->rsa->n);
559 buffer_get_bignum2(&b, key->rsa->e);
560#ifdef DEBUG_PK
561 RSA_print_fp(stderr, key->rsa, 8);
562#endif
563 break;
564 case KEY_DSA:
565 key = key_new(type);
566 buffer_get_bignum2(&b, key->dsa->p);
567 buffer_get_bignum2(&b, key->dsa->q);
568 buffer_get_bignum2(&b, key->dsa->g);
569 buffer_get_bignum2(&b, key->dsa->pub_key);
570#ifdef DEBUG_PK
571 DSA_print_fp(stderr, key->dsa, 8);
572#endif
573 break;
574 case KEY_UNSPEC:
575 key = key_new(type);
576 break;
577 default:
578 error("key_from_blob: cannot handle type %s", ktype);
579 break;
580 }
581 rlen = buffer_len(&b);
582 if (key != NULL && rlen != 0)
583 error("key_from_blob: remaining bytes in key blob %d", rlen);
584 xfree(ktype);
585 buffer_free(&b);
586 return key;
587}
588
589int
590key_to_blob(Key *key, unsigned char **blobp, unsigned int *lenp)
591{
592 Buffer b;
593 int len;
594 unsigned char *buf;
595
596 if (key == NULL) {
597 error("key_to_blob: key == NULL");
598 return 0;
599 }
600 buffer_init(&b);
601 switch(key->type){
602 case KEY_DSA:
603 buffer_put_cstring(&b, key_ssh_name(key));
604 buffer_put_bignum2(&b, key->dsa->p);
605 buffer_put_bignum2(&b, key->dsa->q);
606 buffer_put_bignum2(&b, key->dsa->g);
607 buffer_put_bignum2(&b, key->dsa->pub_key);
608 break;
609 case KEY_RSA:
610 buffer_put_cstring(&b, key_ssh_name(key));
611 buffer_put_bignum2(&b, key->rsa->n);
612 buffer_put_bignum2(&b, key->rsa->e);
613 break;
614 default:
615 error("key_to_blob: illegal key type %d", key->type);
616 break;
617 }
618 len = buffer_len(&b);
619 buf = xmalloc(len);
620 memcpy(buf, buffer_ptr(&b), len);
621 memset(buffer_ptr(&b), 0, len);
622 buffer_free(&b);
623 if (lenp != NULL)
624 *lenp = len;
625 if (blobp != NULL)
626 *blobp = buf;
627 return len;
628}
629
630int
631key_sign(
632 Key *key,
633 unsigned char **sigp, int *lenp,
634 unsigned char *data, int datalen)
635{
636 switch(key->type){
637 case KEY_DSA:
638 return ssh_dss_sign(key, sigp, lenp, data, datalen);
639 break;
640 case KEY_RSA:
641 return ssh_rsa_sign(key, sigp, lenp, data, datalen);
642 break;
643 default:
644 error("key_sign: illegal key type %d", key->type);
645 return -1;
646 break;
647 }
648}
649
650int
651key_verify(
652 Key *key,
653 unsigned char *signature, int signaturelen,
654 unsigned char *data, int datalen)
655{
656 switch(key->type){
657 case KEY_DSA:
658 return ssh_dss_verify(key, signature, signaturelen, data, datalen);
659 break;
660 case KEY_RSA:
661 return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
662 break;
663 default:
664 error("key_verify: illegal key type %d", key->type);
665 return -1;
666 break;
667 }
668}
diff --git a/key.h b/key.h
index 8e1e0a98d..b6c3eb010 100644
--- a/key.h
+++ b/key.h
@@ -26,9 +26,10 @@
26 26
27typedef struct Key Key; 27typedef struct Key Key;
28enum types { 28enum types {
29 KEY_RSA1,
29 KEY_RSA, 30 KEY_RSA,
30 KEY_DSA, 31 KEY_DSA,
31 KEY_EMPTY 32 KEY_UNSPEC
32}; 33};
33struct Key { 34struct Key {
34 int type; 35 int type;
@@ -37,12 +38,33 @@ struct Key {
37}; 38};
38 39
39Key *key_new(int type); 40Key *key_new(int type);
41Key *key_new_private(int type);
40void key_free(Key *k); 42void key_free(Key *k);
41int key_equal(Key *a, Key *b); 43int key_equal(Key *a, Key *b);
42char *key_fingerprint(Key *k); 44char *key_fingerprint(Key *k);
43char *key_type(Key *k); 45char *key_type(Key *k);
44int key_write(Key *key, FILE *f); 46int key_write(Key *key, FILE *f);
45unsigned int key_read(Key *key, char **cpp); 47int key_read(Key *key, char **cpp);
46unsigned int key_size(Key *k); 48u_int key_size(Key *k);
49
50Key *key_generate(int type, unsigned int bits);
51Key *key_from_private(Key *k);
52int key_type_from_name(char *name);
53
54Key *key_from_blob(char *blob, int blen);
55int key_to_blob(Key *key, unsigned char **blobp, unsigned int *lenp);
56char *key_ssh_name(Key *k);
57
58int
59key_sign(
60 Key *key,
61 unsigned char **sigp, int *lenp,
62 unsigned char *data, int datalen);
63
64int
65key_verify(
66 Key *key,
67 unsigned char *signature, int signaturelen,
68 unsigned char *data, int datalen);
47 69
48#endif 70#endif
diff --git a/myproposal.h b/myproposal.h
index 98060dc35..5abb0e5a6 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -22,7 +22,7 @@
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#define KEX_DEFAULT_KEX "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1" 24#define KEX_DEFAULT_KEX "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1"
25#define KEX_DEFAULT_PK_ALG "ssh-dss" 25#define KEX_DEFAULT_PK_ALG "ssh-rsa,ssh-dss"
26#define KEX_DEFAULT_ENCRYPT \ 26#define KEX_DEFAULT_ENCRYPT \
27 "3des-cbc,blowfish-cbc,cast128-cbc,arcfour," \ 27 "3des-cbc,blowfish-cbc,cast128-cbc,arcfour," \
28 "aes128-cbc,aes192-cbc,aes256-cbc," \ 28 "aes128-cbc,aes192-cbc,aes256-cbc," \
diff --git a/nchan.c b/nchan.c
index 55d391e03..02c213c20 100644
--- a/nchan.c
+++ b/nchan.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: nchan.c,v 1.19 2000/09/07 20:27:52 deraadt Exp $"); 26RCSID("$OpenBSD: nchan.c,v 1.20 2000/11/06 23:04:56 markus Exp $");
27 27
28#include "ssh.h" 28#include "ssh.h"
29 29
@@ -253,6 +253,8 @@ chan_send_oclose1(Channel *c)
253static void 253static void
254chan_delete_if_full_closed1(Channel *c) 254chan_delete_if_full_closed1(Channel *c)
255{ 255{
256 debug3("channel %d: chan_delete_if_full_closed1: istate %d ostate %d",
257 c->self, c->istate, c->ostate);
256 if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) { 258 if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) {
257 debug("channel %d: full closed", c->self); 259 debug("channel %d: full closed", c->self);
258 channel_free(c->self); 260 channel_free(c->self);
@@ -403,6 +405,8 @@ chan_send_close2(Channel *c)
403static void 405static void
404chan_delete_if_full_closed2(Channel *c) 406chan_delete_if_full_closed2(Channel *c)
405{ 407{
408 debug3("channel %d: chan_delete_if_full_closed2: istate %d ostate %d",
409 c->self, c->istate, c->ostate);
406 if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) { 410 if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) {
407 if (!(c->flags & CHAN_CLOSE_SENT)) { 411 if (!(c->flags & CHAN_CLOSE_SENT)) {
408 chan_send_close2(c); 412 chan_send_close2(c);
diff --git a/readconf.c b/readconf.c
index c6fdd5308..c821d8408 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.49 2000/10/11 20:27:23 markus Exp $"); 15RCSID("$OpenBSD: readconf.c,v 1.50 2000/11/12 19:50:37 markus Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "readconf.h" 18#include "readconf.h"
@@ -68,7 +68,7 @@ RCSID("$OpenBSD: readconf.c,v 1.49 2000/10/11 20:27:23 markus Exp $");
68 # Defaults for various options 68 # Defaults for various options
69 Host * 69 Host *
70 ForwardAgent no 70 ForwardAgent no
71 ForwardX11 yes 71 ForwardX11 no
72 RhostsAuthentication yes 72 RhostsAuthentication yes
73 PasswordAuthentication yes 73 PasswordAuthentication yes
74 RSAAuthentication yes 74 RSAAuthentication yes
@@ -101,8 +101,8 @@ typedef enum {
101 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 101 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
102 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 102 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
103 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication, 103 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
104 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oIdentityFile2, 104 oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol,
105 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oDSAAuthentication, 105 oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
106 oKbdInteractiveAuthentication, oKbdInteractiveDevices 106 oKbdInteractiveAuthentication, oKbdInteractiveDevices
107} OpCodes; 107} OpCodes;
108 108
@@ -122,7 +122,8 @@ static struct {
122 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, 122 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
123 { "kbdinteractivedevices", oKbdInteractiveDevices }, 123 { "kbdinteractivedevices", oKbdInteractiveDevices },
124 { "rsaauthentication", oRSAAuthentication }, 124 { "rsaauthentication", oRSAAuthentication },
125 { "dsaauthentication", oDSAAuthentication }, 125 { "pubkeyauthentication", oPubkeyAuthentication },
126 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
126 { "skeyauthentication", oSkeyAuthentication }, 127 { "skeyauthentication", oSkeyAuthentication },
127#ifdef KRB4 128#ifdef KRB4
128 { "kerberosauthentication", oKerberosAuthentication }, 129 { "kerberosauthentication", oKerberosAuthentication },
@@ -134,7 +135,7 @@ static struct {
134 { "fallbacktorsh", oFallBackToRsh }, 135 { "fallbacktorsh", oFallBackToRsh },
135 { "usersh", oUseRsh }, 136 { "usersh", oUseRsh },
136 { "identityfile", oIdentityFile }, 137 { "identityfile", oIdentityFile },
137 { "identityfile2", oIdentityFile2 }, 138 { "identityfile2", oIdentityFile }, /* alias */
138 { "hostname", oHostName }, 139 { "hostname", oHostName },
139 { "proxycommand", oProxyCommand }, 140 { "proxycommand", oProxyCommand },
140 { "port", oPort }, 141 { "port", oPort },
@@ -300,8 +301,8 @@ parse_flag:
300 charptr = &options->kbd_interactive_devices; 301 charptr = &options->kbd_interactive_devices;
301 goto parse_string; 302 goto parse_string;
302 303
303 case oDSAAuthentication: 304 case oPubkeyAuthentication:
304 intptr = &options->dsa_authentication; 305 intptr = &options->pubkey_authentication;
305 goto parse_flag; 306 goto parse_flag;
306 307
307 case oRSAAuthentication: 308 case oRSAAuthentication:
@@ -386,20 +387,15 @@ parse_flag:
386 goto parse_int; 387 goto parse_int;
387 388
388 case oIdentityFile: 389 case oIdentityFile:
389 case oIdentityFile2:
390 arg = strdelim(&s); 390 arg = strdelim(&s);
391 if (!arg || *arg == '\0') 391 if (!arg || *arg == '\0')
392 fatal("%.200s line %d: Missing argument.", filename, linenum); 392 fatal("%.200s line %d: Missing argument.", filename, linenum);
393 if (*activep) { 393 if (*activep) {
394 intptr = (opcode == oIdentityFile) ? 394 intptr = &options->num_identity_files;
395 &options->num_identity_files :
396 &options->num_identity_files2;
397 if (*intptr >= SSH_MAX_IDENTITY_FILES) 395 if (*intptr >= SSH_MAX_IDENTITY_FILES)
398 fatal("%.200s line %d: Too many identity files specified (max %d).", 396 fatal("%.200s line %d: Too many identity files specified (max %d).",
399 filename, linenum, SSH_MAX_IDENTITY_FILES); 397 filename, linenum, SSH_MAX_IDENTITY_FILES);
400 charptr = (opcode == oIdentityFile) ? 398 charptr = &options->identity_files[*intptr];
401 &options->identity_files[*intptr] :
402 &options->identity_files2[*intptr];
403 *charptr = xstrdup(arg); 399 *charptr = xstrdup(arg);
404 *intptr = *intptr + 1; 400 *intptr = *intptr + 1;
405 } 401 }
@@ -664,7 +660,7 @@ initialize_options(Options * options)
664 options->use_privileged_port = -1; 660 options->use_privileged_port = -1;
665 options->rhosts_authentication = -1; 661 options->rhosts_authentication = -1;
666 options->rsa_authentication = -1; 662 options->rsa_authentication = -1;
667 options->dsa_authentication = -1; 663 options->pubkey_authentication = -1;
668 options->skey_authentication = -1; 664 options->skey_authentication = -1;
669#ifdef KRB4 665#ifdef KRB4
670 options->kerberos_authentication = -1; 666 options->kerberos_authentication = -1;
@@ -692,7 +688,6 @@ initialize_options(Options * options)
692 options->ciphers = NULL; 688 options->ciphers = NULL;
693 options->protocol = SSH_PROTO_UNKNOWN; 689 options->protocol = SSH_PROTO_UNKNOWN;
694 options->num_identity_files = 0; 690 options->num_identity_files = 0;
695 options->num_identity_files2 = 0;
696 options->hostname = NULL; 691 options->hostname = NULL;
697 options->proxy_command = NULL; 692 options->proxy_command = NULL;
698 options->user = NULL; 693 options->user = NULL;
@@ -730,8 +725,8 @@ fill_default_options(Options * options)
730 options->rhosts_authentication = 1; 725 options->rhosts_authentication = 1;
731 if (options->rsa_authentication == -1) 726 if (options->rsa_authentication == -1)
732 options->rsa_authentication = 1; 727 options->rsa_authentication = 1;
733 if (options->dsa_authentication == -1) 728 if (options->pubkey_authentication == -1)
734 options->dsa_authentication = 1; 729 options->pubkey_authentication = 1;
735 if (options->skey_authentication == -1) 730 if (options->skey_authentication == -1)
736 options->skey_authentication = 0; 731 options->skey_authentication = 0;
737#ifdef KRB4 732#ifdef KRB4
@@ -779,16 +774,18 @@ fill_default_options(Options * options)
779 if (options->protocol == SSH_PROTO_UNKNOWN) 774 if (options->protocol == SSH_PROTO_UNKNOWN)
780 options->protocol = SSH_PROTO_1|SSH_PROTO_2|SSH_PROTO_1_PREFERRED; 775 options->protocol = SSH_PROTO_1|SSH_PROTO_2|SSH_PROTO_1_PREFERRED;
781 if (options->num_identity_files == 0) { 776 if (options->num_identity_files == 0) {
782 options->identity_files[0] = 777 if (options->protocol & SSH_PROTO_1) {
783 xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1); 778 options->identity_files[options->num_identity_files] =
784 sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY); 779 xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1);
785 options->num_identity_files = 1; 780 sprintf(options->identity_files[options->num_identity_files++],
786 } 781 "~/%.100s", SSH_CLIENT_IDENTITY);
787 if (options->num_identity_files2 == 0) { 782 }
788 options->identity_files2[0] = 783 if (options->protocol & SSH_PROTO_2) {
789 xmalloc(2 + strlen(SSH_CLIENT_ID_DSA) + 1); 784 options->identity_files[options->num_identity_files] =
790 sprintf(options->identity_files2[0], "~/%.100s", SSH_CLIENT_ID_DSA); 785 xmalloc(2 + strlen(SSH_CLIENT_ID_DSA) + 1);
791 options->num_identity_files2 = 1; 786 sprintf(options->identity_files[options->num_identity_files++],
787 "~/%.100s", SSH_CLIENT_ID_DSA);
788 }
792 } 789 }
793 if (options->escape_char == -1) 790 if (options->escape_char == -1)
794 options->escape_char = '~'; 791 options->escape_char = '~';
diff --git a/readconf.h b/readconf.h
index e94213fa1..85d937d87 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.22 2000/10/11 20:14:39 markus Exp $"); */ 14/* RCSID("$OpenBSD: readconf.h,v 1.23 2000/11/12 19:50:37 markus Exp $"); */
15 15
16#ifndef READCONF_H 16#ifndef READCONF_H
17#define READCONF_H 17#define READCONF_H
@@ -35,7 +35,7 @@ typedef struct {
35 int rhosts_rsa_authentication; /* Try rhosts with RSA 35 int rhosts_rsa_authentication; /* Try rhosts with RSA
36 * authentication. */ 36 * authentication. */
37 int rsa_authentication; /* Try RSA authentication. */ 37 int rsa_authentication; /* Try RSA authentication. */
38 int dsa_authentication; /* Try DSA authentication. */ 38 int pubkey_authentication; /* Try ssh2 pubkey authentication. */
39 int skey_authentication; /* Try S/Key or TIS authentication. */ 39 int skey_authentication; /* Try S/Key or TIS authentication. */
40#ifdef KRB4 40#ifdef KRB4
41 int kerberos_authentication; /* Try Kerberos 41 int kerberos_authentication; /* Try Kerberos
@@ -78,10 +78,9 @@ typedef struct {
78 char *system_hostfile2; 78 char *system_hostfile2;
79 char *user_hostfile2; 79 char *user_hostfile2;
80 80
81 int num_identity_files; /* Number of files for RSA identities. */ 81 int num_identity_files; /* Number of files for RSA/DSA identities. */
82 int num_identity_files2; /* DSA identities. */
83 char *identity_files[SSH_MAX_IDENTITY_FILES]; 82 char *identity_files[SSH_MAX_IDENTITY_FILES];
84 char *identity_files2[SSH_MAX_IDENTITY_FILES]; 83 int identity_files_type[SSH_MAX_IDENTITY_FILES];
85 84
86 /* Local TCP/IP forward requests. */ 85 /* Local TCP/IP forward requests. */
87 int num_local_forwards; 86 int num_local_forwards;
diff --git a/rsa.c b/rsa.c
index 0c9aef791..7cfcc80db 100644
--- a/rsa.c
+++ b/rsa.c
@@ -60,82 +60,13 @@
60 */ 60 */
61 61
62#include "includes.h" 62#include "includes.h"
63RCSID("$OpenBSD: rsa.c,v 1.16 2000/09/07 20:27:53 deraadt Exp $"); 63RCSID("$OpenBSD: rsa.c,v 1.17 2000/11/12 19:50:37 markus Exp $");
64 64
65#include "rsa.h" 65#include "rsa.h"
66#include "ssh.h" 66#include "ssh.h"
67#include "xmalloc.h" 67#include "xmalloc.h"
68#include "entropy.h" 68#include "entropy.h"
69 69
70int rsa_verbose = 1;
71
72int
73rsa_alive()
74{
75 RSA *key;
76
77 seed_rng();
78 key = RSA_generate_key(32, 3, NULL, NULL);
79 if (key == NULL)
80 return (0);
81 RSA_free(key);
82 return (1);
83}
84
85/*
86 * Generates RSA public and private keys. This initializes the data
87 * structures; they should be freed with rsa_clear_private_key and
88 * rsa_clear_public_key.
89 */
90
91void
92rsa_generate_key(RSA *prv, RSA *pub, unsigned int bits)
93{
94 RSA *key;
95
96 seed_rng();
97
98 if (rsa_verbose) {
99 printf("Generating RSA keys: ");
100 fflush(stdout);
101 }
102 key = RSA_generate_key(bits, 35, NULL, NULL);
103 if (key == NULL)
104 fatal("rsa_generate_key: key generation failed.");
105
106 /* Copy public key parameters */
107 pub->n = BN_new();
108 BN_copy(pub->n, key->n);
109 pub->e = BN_new();
110 BN_copy(pub->e, key->e);
111
112 /* Copy private key parameters */
113 prv->n = BN_new();
114 BN_copy(prv->n, key->n);
115 prv->e = BN_new();
116 BN_copy(prv->e, key->e);
117 prv->d = BN_new();
118 BN_copy(prv->d, key->d);
119 prv->p = BN_new();
120 BN_copy(prv->p, key->p);
121 prv->q = BN_new();
122 BN_copy(prv->q, key->q);
123
124 prv->dmp1 = BN_new();
125 BN_copy(prv->dmp1, key->dmp1);
126
127 prv->dmq1 = BN_new();
128 BN_copy(prv->dmq1, key->dmq1);
129
130 prv->iqmp = BN_new();
131 BN_copy(prv->iqmp, key->iqmp);
132
133 RSA_free(key);
134
135 if (rsa_verbose)
136 printf("Key generation complete.\n");
137}
138
139void 70void
140rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key) 71rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key)
141{ 72{
@@ -188,11 +119,3 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
188 xfree(outbuf); 119 xfree(outbuf);
189 xfree(inbuf); 120 xfree(inbuf);
190} 121}
191
192/* Set whether to output verbose messages during key generation. */
193
194void
195rsa_set_verbose(int verbose)
196{
197 rsa_verbose = verbose;
198}
diff --git a/rsa.h b/rsa.h
index 93a2dac85..57d72cc78 100644
--- a/rsa.h
+++ b/rsa.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: rsa.h,v 1.8 2000/09/07 20:27:53 deraadt Exp $"); */ 14/* RCSID("$OpenBSD: rsa.h,v 1.9 2000/11/12 19:50:38 markus Exp $"); */
15 15
16#ifndef RSA_H 16#ifndef RSA_H
17#define RSA_H 17#define RSA_H
@@ -19,17 +19,6 @@
19#include <openssl/bn.h> 19#include <openssl/bn.h>
20#include <openssl/rsa.h> 20#include <openssl/rsa.h>
21 21
22/* Calls SSL RSA_generate_key, only copies to prv and pub */
23void rsa_generate_key(RSA * prv, RSA * pub, unsigned int bits);
24
25/*
26 * Indicates whether the rsa module is permitted to show messages on the
27 * terminal.
28 */
29void rsa_set_verbose __P((int verbose));
30
31int rsa_alive __P((void));
32
33void rsa_public_encrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv)); 22void rsa_public_encrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv));
34void rsa_private_decrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv)); 23void rsa_private_decrypt __P((BIGNUM * out, BIGNUM * in, RSA * prv));
35 24
diff --git a/servconf.c b/servconf.c
index 76702a836..5da55de03 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.53 2000/10/14 12:12:09 markus Exp $"); 13RCSID("$OpenBSD: servconf.c,v 1.54 2000/11/12 19:50:38 markus Exp $");
14 14
15#include "ssh.h" 15#include "ssh.h"
16#include "servconf.h" 16#include "servconf.h"
@@ -29,8 +29,7 @@ initialize_server_options(ServerOptions *options)
29 options->num_ports = 0; 29 options->num_ports = 0;
30 options->ports_from_cmdline = 0; 30 options->ports_from_cmdline = 0;
31 options->listen_addrs = NULL; 31 options->listen_addrs = NULL;
32 options->host_key_file = NULL; 32 options->num_host_key_files = 0;
33 options->host_dsa_key_file = NULL;
34 options->pid_file = NULL; 33 options->pid_file = NULL;
35 options->server_key_bits = -1; 34 options->server_key_bits = -1;
36 options->login_grace_time = -1; 35 options->login_grace_time = -1;
@@ -50,7 +49,7 @@ initialize_server_options(ServerOptions *options)
50 options->rhosts_authentication = -1; 49 options->rhosts_authentication = -1;
51 options->rhosts_rsa_authentication = -1; 50 options->rhosts_rsa_authentication = -1;
52 options->rsa_authentication = -1; 51 options->rsa_authentication = -1;
53 options->dsa_authentication = -1; 52 options->pubkey_authentication = -1;
54#ifdef KRB4 53#ifdef KRB4
55 options->kerberos_authentication = -1; 54 options->kerberos_authentication = -1;
56 options->kerberos_or_local_passwd = -1; 55 options->kerberos_or_local_passwd = -1;
@@ -84,14 +83,19 @@ initialize_server_options(ServerOptions *options)
84void 83void
85fill_default_server_options(ServerOptions *options) 84fill_default_server_options(ServerOptions *options)
86{ 85{
86 if (options->protocol == SSH_PROTO_UNKNOWN)
87 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
88 if (options->num_host_key_files == 0) {
89 /* fill default hostkeys for protocols */
90 if (options->protocol & SSH_PROTO_1)
91 options->host_key_files[options->num_host_key_files++] = HOST_KEY_FILE;
92 if (options->protocol & SSH_PROTO_2)
93 options->host_key_files[options->num_host_key_files++] = HOST_DSA_KEY_FILE;
94 }
87 if (options->num_ports == 0) 95 if (options->num_ports == 0)
88 options->ports[options->num_ports++] = SSH_DEFAULT_PORT; 96 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
89 if (options->listen_addrs == NULL) 97 if (options->listen_addrs == NULL)
90 add_listen_addr(options, NULL); 98 add_listen_addr(options, NULL);
91 if (options->host_key_file == NULL)
92 options->host_key_file = HOST_KEY_FILE;
93 if (options->host_dsa_key_file == NULL)
94 options->host_dsa_key_file = HOST_DSA_KEY_FILE;
95 if (options->pid_file == NULL) 99 if (options->pid_file == NULL)
96 options->pid_file = SSH_DAEMON_PID_FILE; 100 options->pid_file = SSH_DAEMON_PID_FILE;
97 if (options->server_key_bits == -1) 101 if (options->server_key_bits == -1)
@@ -132,8 +136,8 @@ fill_default_server_options(ServerOptions *options)
132 options->rhosts_rsa_authentication = 0; 136 options->rhosts_rsa_authentication = 0;
133 if (options->rsa_authentication == -1) 137 if (options->rsa_authentication == -1)
134 options->rsa_authentication = 1; 138 options->rsa_authentication = 1;
135 if (options->dsa_authentication == -1) 139 if (options->pubkey_authentication == -1)
136 options->dsa_authentication = 1; 140 options->pubkey_authentication = 1;
137#ifdef KRB4 141#ifdef KRB4
138 if (options->kerberos_authentication == -1) 142 if (options->kerberos_authentication == -1)
139 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0); 143 options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
@@ -162,8 +166,6 @@ fill_default_server_options(ServerOptions *options)
162 options->use_login = 0; 166 options->use_login = 0;
163 if (options->allow_tcp_forwarding == -1) 167 if (options->allow_tcp_forwarding == -1)
164 options->allow_tcp_forwarding = 1; 168 options->allow_tcp_forwarding = 1;
165 if (options->protocol == SSH_PROTO_UNKNOWN)
166 options->protocol = SSH_PROTO_1|SSH_PROTO_2;
167 if (options->gateway_ports == -1) 169 if (options->gateway_ports == -1)
168 options->gateway_ports = 0; 170 options->gateway_ports = 0;
169 if (options->max_startups == -1) 171 if (options->max_startups == -1)
@@ -194,8 +196,8 @@ typedef enum {
194 sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, 196 sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
195 sUseLogin, sAllowTcpForwarding, 197 sUseLogin, sAllowTcpForwarding,
196 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, 198 sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
197 sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile, 199 sIgnoreUserKnownHosts, sCiphers, sProtocol, sPidFile,
198 sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem, sMaxStartups 200 sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups,
199} ServerOpCodes; 201} ServerOpCodes;
200 202
201/* Textual representation of the tokens. */ 203/* Textual representation of the tokens. */
@@ -205,7 +207,7 @@ static struct {
205} keywords[] = { 207} keywords[] = {
206 { "port", sPort }, 208 { "port", sPort },
207 { "hostkey", sHostKeyFile }, 209 { "hostkey", sHostKeyFile },
208 { "hostdsakey", sHostDSAKeyFile }, 210 { "hostdsakey", sHostKeyFile }, /* alias */
209 { "pidfile", sPidFile }, 211 { "pidfile", sPidFile },
210 { "serverkeybits", sServerKeyBits }, 212 { "serverkeybits", sServerKeyBits },
211 { "logingracetime", sLoginGraceTime }, 213 { "logingracetime", sLoginGraceTime },
@@ -216,7 +218,8 @@ static struct {
216 { "rhostsauthentication", sRhostsAuthentication }, 218 { "rhostsauthentication", sRhostsAuthentication },
217 { "rhostsrsaauthentication", sRhostsRSAAuthentication }, 219 { "rhostsrsaauthentication", sRhostsRSAAuthentication },
218 { "rsaauthentication", sRSAAuthentication }, 220 { "rsaauthentication", sRSAAuthentication },
219 { "dsaauthentication", sDSAAuthentication }, 221 { "pubkeyauthentication", sPubkeyAuthentication },
222 { "dsaauthentication", sPubkeyAuthentication }, /* alias */
220#ifdef KRB4 223#ifdef KRB4
221 { "kerberosauthentication", sKerberosAuthentication }, 224 { "kerberosauthentication", sKerberosAuthentication },
222 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd }, 225 { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
@@ -336,6 +339,8 @@ read_server_config(ServerOptions *options, const char *filename)
336 arg = strdelim(&cp); 339 arg = strdelim(&cp);
337 if (!*arg || *arg == '#') 340 if (!*arg || *arg == '#')
338 continue; 341 continue;
342 intptr = NULL;
343 charptr = NULL;
339 opcode = parse_token(arg, filename, linenum); 344 opcode = parse_token(arg, filename, linenum);
340 switch (opcode) { 345 switch (opcode) {
341 case sBadOption: 346 case sBadOption:
@@ -389,9 +394,13 @@ parse_int:
389 break; 394 break;
390 395
391 case sHostKeyFile: 396 case sHostKeyFile:
392 case sHostDSAKeyFile: 397 intptr = &options->num_host_key_files;
393 charptr = (opcode == sHostKeyFile ) ? 398 if (*intptr >= MAX_HOSTKEYS) {
394 &options->host_key_file : &options->host_dsa_key_file; 399 fprintf(stderr, "%s line %d: to many host keys specified (max %d).\n",
400 filename, linenum, MAX_HOSTKEYS);
401 exit(1);
402 }
403 charptr = &options->host_key_files[*intptr];
395parse_filename: 404parse_filename:
396 arg = strdelim(&cp); 405 arg = strdelim(&cp);
397 if (!arg || *arg == '\0') { 406 if (!arg || *arg == '\0') {
@@ -399,8 +408,12 @@ parse_filename:
399 filename, linenum); 408 filename, linenum);
400 exit(1); 409 exit(1);
401 } 410 }
402 if (*charptr == NULL) 411 if (*charptr == NULL) {
403 *charptr = tilde_expand_filename(arg, getuid()); 412 *charptr = tilde_expand_filename(arg, getuid());
413 /* increase optional counter */
414 if (intptr != NULL)
415 *intptr = *intptr + 1;
416 }
404 break; 417 break;
405 418
406 case sPidFile: 419 case sPidFile:
@@ -474,8 +487,8 @@ parse_flag:
474 intptr = &options->rsa_authentication; 487 intptr = &options->rsa_authentication;
475 goto parse_flag; 488 goto parse_flag;
476 489
477 case sDSAAuthentication: 490 case sPubkeyAuthentication:
478 intptr = &options->dsa_authentication; 491 intptr = &options->pubkey_authentication;
479 goto parse_flag; 492 goto parse_flag;
480 493
481#ifdef KRB4 494#ifdef KRB4
diff --git a/servconf.h b/servconf.h
index 0188b9b89..3ecf6a00d 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.30 2000/10/14 12:12:09 markus Exp $"); */ 14/* RCSID("$OpenBSD: servconf.h,v 1.31 2000/11/12 19:50:38 markus Exp $"); */
15 15
16#ifndef SERVCONF_H 16#ifndef SERVCONF_H
17#define SERVCONF_H 17#define SERVCONF_H
@@ -23,6 +23,7 @@
23#define MAX_ALLOW_GROUPS 256 /* Max # groups on allow list. */ 23#define MAX_ALLOW_GROUPS 256 /* Max # groups on allow list. */
24#define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */ 24#define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */
25#define MAX_SUBSYSTEMS 256 /* Max # subsystems. */ 25#define MAX_SUBSYSTEMS 256 /* Max # subsystems. */
26#define MAX_HOSTKEYS 256 /* Max # hostkeys. */
26 27
27typedef struct { 28typedef struct {
28 unsigned int num_ports; 29 unsigned int num_ports;
@@ -30,8 +31,8 @@ typedef struct {
30 u_short ports[MAX_PORTS]; /* Port number to listen on. */ 31 u_short ports[MAX_PORTS]; /* Port number to listen on. */
31 char *listen_addr; /* Address on which the server listens. */ 32 char *listen_addr; /* Address on which the server listens. */
32 struct addrinfo *listen_addrs; /* Addresses on which the server listens. */ 33 struct addrinfo *listen_addrs; /* Addresses on which the server listens. */
33 char *host_key_file; /* File containing host key. */ 34 char *host_key_files[MAX_HOSTKEYS]; /* Files containing host keys. */
34 char *host_dsa_key_file; /* File containing dsa host key. */ 35 int num_host_key_files; /* Number of files for host keys. */
35 char *pid_file; /* Where to put our pid */ 36 char *pid_file; /* Where to put our pid */
36 int server_key_bits;/* Size of the server key. */ 37 int server_key_bits;/* Size of the server key. */
37 int login_grace_time; /* Disconnect if no auth in this time 38 int login_grace_time; /* Disconnect if no auth in this time
@@ -59,7 +60,7 @@ typedef struct {
59 int rhosts_rsa_authentication; /* If true, permit rhosts RSA 60 int rhosts_rsa_authentication; /* If true, permit rhosts RSA
60 * authentication. */ 61 * authentication. */
61 int rsa_authentication; /* If true, permit RSA authentication. */ 62 int rsa_authentication; /* If true, permit RSA authentication. */
62 int dsa_authentication; /* If true, permit DSA authentication. */ 63 int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */
63#ifdef KRB4 64#ifdef KRB4
64 int kerberos_authentication; /* If true, permit Kerberos 65 int kerberos_authentication; /* If true, permit Kerberos
65 * authentication. */ 66 * authentication. */
diff --git a/serverloop.c b/serverloop.c
index 6a81806bb..dfef6f333 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$OpenBSD: serverloop.c,v 1.34 2000/10/27 07:32:18 markus Exp $"); 38RCSID("$OpenBSD: serverloop.c,v 1.35 2000/11/06 23:04:56 markus Exp $");
39 39
40#include "xmalloc.h" 40#include "xmalloc.h"
41#include "ssh.h" 41#include "ssh.h"
@@ -50,6 +50,7 @@ RCSID("$OpenBSD: serverloop.c,v 1.34 2000/10/27 07:32:18 markus Exp $");
50#include "session.h" 50#include "session.h"
51#include "dispatch.h" 51#include "dispatch.h"
52#include "auth-options.h" 52#include "auth-options.h"
53#include "auth.h"
53 54
54extern ServerOptions options; 55extern ServerOptions options;
55 56
@@ -739,10 +740,10 @@ server_input_window_size(int type, int plen, void *ctxt)
739 pty_change_window_size(fdin, row, col, xpixel, ypixel); 740 pty_change_window_size(fdin, row, col, xpixel, ypixel);
740} 741}
741 742
742int 743Channel *
743input_direct_tcpip(void) 744server_request_direct_tcpip(char *ctype)
744{ 745{
745 int sock; 746 int sock, newch;
746 char *target, *originator; 747 char *target, *originator;
747 int target_port, originator_port; 748 int target_port, originator_port;
748 749
@@ -752,23 +753,52 @@ input_direct_tcpip(void)
752 originator_port = packet_get_int(); 753 originator_port = packet_get_int();
753 packet_done(); 754 packet_done();
754 755
755 debug("open direct-tcpip: from %s port %d to %s port %d", 756 debug("server_request_direct_tcpip: originator %s port %d, target %s port %d",
756 originator, originator_port, target, target_port); 757 originator, originator_port, target, target_port);
757 758
758 /* XXX check permission */ 759 /* XXX check permission */
759 if (no_port_forwarding_flag || !options.allow_tcp_forwarding) { 760 if (no_port_forwarding_flag || !options.allow_tcp_forwarding) {
760 xfree(target); 761 xfree(target);
761 xfree(originator); 762 xfree(originator);
762 return -1; 763 return NULL;
763 } 764 }
764 sock = channel_connect_to(target, target_port); 765 sock = channel_connect_to(target, target_port);
765 xfree(target); 766 xfree(target);
766 xfree(originator); 767 xfree(originator);
767 if (sock < 0) 768 if (sock < 0)
768 return -1; 769 return NULL;
769 return channel_new("direct-tcpip", SSH_CHANNEL_OPEN, 770 newch = channel_new(ctype, SSH_CHANNEL_OPEN,
770 sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, 771 sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
771 CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip"), 1); 772 CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip"), 1);
773 return (newch >= 0) ? channel_lookup(newch) : NULL;
774}
775
776Channel *
777server_request_session(char *ctype)
778{
779 int newch;
780
781 debug("input_session_request");
782 packet_done();
783 /*
784 * A server session has no fd to read or write until a
785 * CHANNEL_REQUEST for a shell is made, so we set the type to
786 * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all
787 * CHANNEL_REQUEST messages is registered.
788 */
789 newch = channel_new(ctype, SSH_CHANNEL_LARVAL,
790 -1, -1, -1, 0, CHAN_SES_PACKET_DEFAULT,
791 0, xstrdup("server-session"), 1);
792 if (session_open(newch) == 1) {
793 channel_register_callback(newch, SSH2_MSG_CHANNEL_REQUEST,
794 session_input_channel_req, (void *)0);
795 channel_register_cleanup(newch, session_close_by_channel);
796 return channel_lookup(newch);
797 } else {
798 debug("session open failed, free channel %d", newch);
799 channel_free(newch);
800 }
801 return NULL;
772} 802}
773 803
774void 804void
@@ -776,7 +806,6 @@ server_input_channel_open(int type, int plen, void *ctxt)
776{ 806{
777 Channel *c = NULL; 807 Channel *c = NULL;
778 char *ctype; 808 char *ctype;
779 int id;
780 unsigned int len; 809 unsigned int len;
781 int rchan; 810 int rchan;
782 int rmaxpack; 811 int rmaxpack;
@@ -791,34 +820,12 @@ server_input_channel_open(int type, int plen, void *ctxt)
791 ctype, rchan, rwindow, rmaxpack); 820 ctype, rchan, rwindow, rmaxpack);
792 821
793 if (strcmp(ctype, "session") == 0) { 822 if (strcmp(ctype, "session") == 0) {
794 debug("open session"); 823 c = server_request_session(ctype);
795 packet_done();
796 /*
797 * A server session has no fd to read or write
798 * until a CHANNEL_REQUEST for a shell is made,
799 * so we set the type to SSH_CHANNEL_LARVAL.
800 * Additionally, a callback for handling all
801 * CHANNEL_REQUEST messages is registered.
802 */
803 id = channel_new(ctype, SSH_CHANNEL_LARVAL,
804 -1, -1, -1, 0, CHAN_SES_PACKET_DEFAULT,
805 0, xstrdup("server-session"), 1);
806 if (session_open(id) == 1) {
807 channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST,
808 session_input_channel_req, (void *)0);
809 channel_register_cleanup(id, session_close_by_channel);
810 c = channel_lookup(id);
811 } else {
812 debug("session open failed, free channel %d", id);
813 channel_free(id);
814 }
815 } else if (strcmp(ctype, "direct-tcpip") == 0) { 824 } else if (strcmp(ctype, "direct-tcpip") == 0) {
816 id = input_direct_tcpip(); 825 c = server_request_direct_tcpip(ctype);
817 if (id >= 0)
818 c = channel_lookup(id);
819 } 826 }
820 if (c != NULL) { 827 if (c != NULL) {
821 debug("confirm %s", ctype); 828 debug("server_input_channel_open: confirm %s", ctype);
822 c->remote_id = rchan; 829 c->remote_id = rchan;
823 c->remote_window = rwindow; 830 c->remote_window = rwindow;
824 c->remote_maxpacket = rmaxpack; 831 c->remote_maxpacket = rmaxpack;
@@ -830,7 +837,7 @@ server_input_channel_open(int type, int plen, void *ctxt)
830 packet_put_int(c->local_maxpacket); 837 packet_put_int(c->local_maxpacket);
831 packet_send(); 838 packet_send();
832 } else { 839 } else {
833 debug("failure %s", ctype); 840 debug("server_input_channel_open: failure %s", ctype);
834 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); 841 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
835 packet_put_int(rchan); 842 packet_put_int(rchan);
836 packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); 843 packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
@@ -841,6 +848,56 @@ server_input_channel_open(int type, int plen, void *ctxt)
841 xfree(ctype); 848 xfree(ctype);
842} 849}
843 850
851void
852server_input_global_request(int type, int plen, void *ctxt)
853{
854 char *rtype;
855 int want_reply;
856 int success = 0;
857
858 rtype = packet_get_string(NULL);
859 want_reply = packet_get_char();
860 debug("server_input_global_request: rtype %s want_reply %d", rtype, want_reply);
861
862 if (strcmp(rtype, "tcpip-forward") == 0) {
863 struct passwd *pw;
864 char *listen_address;
865 u_short listen_port;
866
867 pw = auth_get_user();
868 if (pw == NULL)
869 fatal("server_input_global_request: no user");
870 listen_address = packet_get_string(NULL); /* XXX currently ignored */
871 listen_port = (u_short)packet_get_int();
872 debug("server_input_global_request: tcpip-forward listen %s port %d",
873 listen_address, listen_port);
874
875 /* check permissions */
876 if (!options.allow_tcp_forwarding ||
877 no_port_forwarding_flag ||
878 (listen_port < IPPORT_RESERVED && pw->pw_uid != 0)) {
879 success = 0;
880 packet_send_debug("Server has disabled port forwarding.");
881 } else {
882 /* Start listening on the port */
883 channel_request_forwarding(
884 listen_address, listen_port,
885 /*unspec host_to_connect*/ "<unspec host>",
886 /*unspec port_to_connect*/ 0,
887 options.gateway_ports, /*remote*/ 1);
888 success = 1;
889 }
890 xfree(listen_address);
891 }
892 if (want_reply) {
893 packet_start(success ?
894 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
895 packet_send();
896 packet_write_wait();
897 }
898 xfree(rtype);
899}
900
844void 901void
845server_init_dispatch_20() 902server_init_dispatch_20()
846{ 903{
@@ -855,6 +912,7 @@ server_init_dispatch_20()
855 dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); 912 dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
856 dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request); 913 dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request);
857 dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); 914 dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
915 dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);
858} 916}
859void 917void
860server_init_dispatch_13() 918server_init_dispatch_13()
diff --git a/session.c b/session.c
index 6794d3d6a..b94c8e84d 100644
--- a/session.c
+++ b/session.c
@@ -33,7 +33,7 @@
33 */ 33 */
34 34
35#include "includes.h" 35#include "includes.h"
36RCSID("$OpenBSD: session.c,v 1.42 2000/10/27 07:32:18 markus Exp $"); 36RCSID("$OpenBSD: session.c,v 1.43 2000/11/06 23:04:56 markus Exp $");
37 37
38#include "xmalloc.h" 38#include "xmalloc.h"
39#include "ssh.h" 39#include "ssh.h"
@@ -1735,6 +1735,19 @@ session_exec_req(Session *s)
1735 return 1; 1735 return 1;
1736} 1736}
1737 1737
1738int
1739session_auth_agent_req(Session *s)
1740{
1741 static int called = 0;
1742 packet_done();
1743 if (called) {
1744 return 0;
1745 } else {
1746 called = 1;
1747 return auth_input_request_forwarding(s->pw);
1748 }
1749}
1750
1738void 1751void
1739session_input_channel_req(int id, void *arg) 1752session_input_channel_req(int id, void *arg)
1740{ 1753{
@@ -1771,6 +1784,8 @@ session_input_channel_req(int id, void *arg)
1771 success = session_pty_req(s); 1784 success = session_pty_req(s);
1772 } else if (strcmp(rtype, "x11-req") == 0) { 1785 } else if (strcmp(rtype, "x11-req") == 0) {
1773 success = session_x11_req(s); 1786 success = session_x11_req(s);
1787 } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
1788 success = session_auth_agent_req(s);
1774 } else if (strcmp(rtype, "subsystem") == 0) { 1789 } else if (strcmp(rtype, "subsystem") == 0) {
1775 success = session_subsystem_req(s); 1790 success = session_subsystem_req(s);
1776 } 1791 }
diff --git a/sftp-server.8 b/sftp-server.8
index fb4706c43..b8d579a9f 100644
--- a/sftp-server.8
+++ b/sftp-server.8
@@ -1,4 +1,4 @@
1.\" $OpenBSD: sftp-server.8,v 1.3 2000/10/13 17:20:44 aaron Exp $ 1.\" $OpenBSD: sftp-server.8,v 1.4 2000/11/10 05:10:40 aaron Exp $
2.\" 2.\"
3.\" Copyright (c) 2000 Markus Friedl. All rights reserved. 3.\" Copyright (c) 2000 Markus Friedl. All rights reserved.
4.\" 4.\"
@@ -48,7 +48,7 @@ for more information.
48.Xr ssh-add 1 , 48.Xr ssh-add 1 ,
49.Xr ssh-keygen 1 , 49.Xr ssh-keygen 1 ,
50.Xr sshd 8 50.Xr sshd 8
51.Sh AUTHOR 51.Sh AUTHORS
52Markus Friedl <markus@openbsd.org> 52Markus Friedl <markus@openbsd.org>
53.Sh HISTORY 53.Sh HISTORY
54.Nm 54.Nm
diff --git a/ssh-add.1 b/ssh-add.1
index aa12ef34d..7d641c026 100644
--- a/ssh-add.1
+++ b/ssh-add.1
@@ -116,7 +116,7 @@ may be necessary to redirect the input from
116.Pa /dev/null 116.Pa /dev/null
117to make this work.) 117to make this work.)
118.El 118.El
119.Sh AUTHOR 119.Sh AUTHORS
120Tatu Ylonen <ylo@cs.hut.fi> 120Tatu Ylonen <ylo@cs.hut.fi>
121.Pp 121.Pp
122OpenSSH 122OpenSSH
diff --git a/ssh-add.c b/ssh-add.c
index 3adc2509f..f49d13fb5 100644
--- a/ssh-add.c
+++ b/ssh-add.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$OpenBSD: ssh-add.c,v 1.22 2000/09/07 20:27:54 deraadt Exp $"); 38RCSID("$OpenBSD: ssh-add.c,v 1.23 2000/11/12 19:50:38 markus Exp $");
39 39
40#include <openssl/evp.h> 40#include <openssl/evp.h>
41#include <openssl/rsa.h> 41#include <openssl/rsa.h>
@@ -60,10 +60,10 @@ delete_file(AuthenticationConnection *ac, const char *filename)
60 Key *public; 60 Key *public;
61 char *comment; 61 char *comment;
62 62
63 public = key_new(KEY_RSA); 63 public = key_new(KEY_RSA1);
64 if (!load_public_key(filename, public, &comment)) { 64 if (!load_public_key(filename, public, &comment)) {
65 key_free(public); 65 key_free(public);
66 public = key_new(KEY_DSA); 66 public = key_new(KEY_UNSPEC);
67 if (!try_load_public_key(filename, public, &comment)) { 67 if (!try_load_public_key(filename, public, &comment)) {
68 printf("Bad key file %s\n", filename); 68 printf("Bad key file %s\n", filename);
69 return; 69 return;
@@ -144,7 +144,7 @@ add_file(AuthenticationConnection *ac, const char *filename)
144 char buf[1024], msg[1024]; 144 char buf[1024], msg[1024];
145 int success; 145 int success;
146 int interactive = isatty(STDIN_FILENO); 146 int interactive = isatty(STDIN_FILENO);
147 int type = KEY_RSA; 147 int type = KEY_RSA1;
148 148
149 if (stat(filename, &st) < 0) { 149 if (stat(filename, &st) < 0) {
150 perror(filename); 150 perror(filename);
@@ -154,10 +154,10 @@ add_file(AuthenticationConnection *ac, const char *filename)
154 * try to load the public key. right now this only works for RSA, 154 * try to load the public key. right now this only works for RSA,
155 * since DSA keys are fully encrypted 155 * since DSA keys are fully encrypted
156 */ 156 */
157 public = key_new(KEY_RSA); 157 public = key_new(KEY_RSA1);
158 if (!load_public_key(filename, public, &saved_comment)) { 158 if (!load_public_key(filename, public, &saved_comment)) {
159 /* ok, so we will asume this is a DSA key */ 159 /* ok, so we will assume this is 'some' key */
160 type = KEY_DSA; 160 type = KEY_UNSPEC;
161 saved_comment = xstrdup(filename); 161 saved_comment = xstrdup(filename);
162 } 162 }
163 key_free(public); 163 key_free(public);
@@ -223,8 +223,9 @@ list_identities(AuthenticationConnection *ac, int fp)
223 key = ssh_get_next_identity(ac, &comment, version)) { 223 key = ssh_get_next_identity(ac, &comment, version)) {
224 had_identities = 1; 224 had_identities = 1;
225 if (fp) { 225 if (fp) {
226 printf("%d %s %s\n", 226 printf("%d %s %s (%s)\n",
227 key_size(key), key_fingerprint(key), comment); 227 key_size(key), key_fingerprint(key),
228 comment, key_type(key));
228 } else { 229 } else {
229 if (!key_write(key, stdout)) 230 if (!key_write(key, stdout))
230 fprintf(stderr, "key_write failed"); 231 fprintf(stderr, "key_write failed");
@@ -250,13 +251,6 @@ main(int argc, char **argv)
250 251
251 init_rng(); 252 init_rng();
252 253
253 /* check if RSA support exists */
254 if (rsa_alive() == 0) {
255 fprintf(stderr,
256 "%s: no RSA support in libssl and libcrypto. See ssl(8).\n",
257 __progname);
258 exit(1);
259 }
260 SSLeay_add_all_algorithms(); 254 SSLeay_add_all_algorithms();
261 255
262 /* At first, get a connection to the authentication agent. */ 256 /* At first, get a connection to the authentication agent. */
diff --git a/ssh-agent.1 b/ssh-agent.1
index 064d9d4cf..31ea2b318 100644
--- a/ssh-agent.1
+++ b/ssh-agent.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-agent.1,v 1.16 2000/09/07 20:27:54 deraadt Exp $ 1.\" $OpenBSD: ssh-agent.1,v 1.17 2000/11/10 05:10:40 aaron Exp $
2.\" 2.\"
3.\" Author: Tatu Ylonen <ylo@cs.hut.fi> 3.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
4.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -160,7 +160,7 @@ authentication agent.
160These sockets should only be readable by the owner. 160These sockets should only be readable by the owner.
161The sockets should get automatically removed when the agent exits. 161The sockets should get automatically removed when the agent exits.
162.El 162.El
163.Sh AUTHOR 163.Sh AUTHORS
164Tatu Ylonen <ylo@cs.hut.fi> 164Tatu Ylonen <ylo@cs.hut.fi>
165.Pp 165.Pp
166OpenSSH 166OpenSSH
diff --git a/ssh-agent.c b/ssh-agent.c
index 479388fab..9f61aec3b 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.37 2000/09/21 11:07:51 markus Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.39 2000/11/12 19:50:38 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -37,7 +37,7 @@
37 */ 37 */
38 38
39#include "includes.h" 39#include "includes.h"
40RCSID("$OpenBSD: ssh-agent.c,v 1.37 2000/09/21 11:07:51 markus Exp $"); 40RCSID("$OpenBSD: ssh-agent.c,v 1.39 2000/11/12 19:50:38 markus Exp $");
41 41
42#include "ssh.h" 42#include "ssh.h"
43#include "rsa.h" 43#include "rsa.h"
@@ -54,7 +54,6 @@ RCSID("$OpenBSD: ssh-agent.c,v 1.37 2000/09/21 11:07:51 markus Exp $");
54#include <openssl/rsa.h> 54#include <openssl/rsa.h>
55#include "key.h" 55#include "key.h"
56#include "authfd.h" 56#include "authfd.h"
57#include "dsa.h"
58#include "kex.h" 57#include "kex.h"
59#include "compat.h" 58#include "compat.h"
60 59
@@ -147,14 +146,14 @@ process_request_identities(SocketEntry *e, int version)
147 buffer_put_int(&msg, tab->nentries); 146 buffer_put_int(&msg, tab->nentries);
148 for (i = 0; i < tab->nentries; i++) { 147 for (i = 0; i < tab->nentries; i++) {
149 Identity *id = &tab->identities[i]; 148 Identity *id = &tab->identities[i];
150 if (id->key->type == KEY_RSA) { 149 if (id->key->type == KEY_RSA1) {
151 buffer_put_int(&msg, BN_num_bits(id->key->rsa->n)); 150 buffer_put_int(&msg, BN_num_bits(id->key->rsa->n));
152 buffer_put_bignum(&msg, id->key->rsa->e); 151 buffer_put_bignum(&msg, id->key->rsa->e);
153 buffer_put_bignum(&msg, id->key->rsa->n); 152 buffer_put_bignum(&msg, id->key->rsa->n);
154 } else { 153 } else {
155 unsigned char *blob; 154 unsigned char *blob;
156 unsigned int blen; 155 unsigned int blen;
157 dsa_make_key_blob(id->key, &blob, &blen); 156 key_to_blob(id->key, &blob, &blen);
158 buffer_put_string(&msg, blob, blen); 157 buffer_put_string(&msg, blob, blen);
159 xfree(blob); 158 xfree(blob);
160 } 159 }
@@ -178,7 +177,7 @@ process_authentication_challenge1(SocketEntry *e)
178 unsigned int response_type; 177 unsigned int response_type;
179 178
180 buffer_init(&msg); 179 buffer_init(&msg);
181 key = key_new(KEY_RSA); 180 key = key_new(KEY_RSA1);
182 challenge = BN_new(); 181 challenge = BN_new();
183 182
184 buffer_get_int(&e->input); /* ignored */ 183 buffer_get_int(&e->input); /* ignored */
@@ -251,11 +250,11 @@ process_sign_request2(SocketEntry *e)
251 if (flags & SSH_AGENT_OLD_SIGNATURE) 250 if (flags & SSH_AGENT_OLD_SIGNATURE)
252 datafellows = SSH_BUG_SIGBLOB; 251 datafellows = SSH_BUG_SIGBLOB;
253 252
254 key = dsa_key_from_blob(blob, blen); 253 key = key_from_blob(blob, blen);
255 if (key != NULL) { 254 if (key != NULL) {
256 private = lookup_private_key(key, NULL, 2); 255 private = lookup_private_key(key, NULL, 2);
257 if (private != NULL) 256 if (private != NULL)
258 ok = dsa_sign(private, &signature, &slen, data, dlen); 257 ok = key_sign(private, &signature, &slen, data, dlen);
259 } 258 }
260 key_free(key); 259 key_free(key);
261 buffer_init(&msg); 260 buffer_init(&msg);
@@ -287,7 +286,7 @@ process_remove_identity(SocketEntry *e, int version)
287 286
288 switch(version){ 287 switch(version){
289 case 1: 288 case 1:
290 key = key_new(KEY_RSA); 289 key = key_new(KEY_RSA1);
291 bits = buffer_get_int(&e->input); 290 bits = buffer_get_int(&e->input);
292 buffer_get_bignum(&e->input, key->rsa->e); 291 buffer_get_bignum(&e->input, key->rsa->e);
293 buffer_get_bignum(&e->input, key->rsa->n); 292 buffer_get_bignum(&e->input, key->rsa->n);
@@ -298,7 +297,7 @@ process_remove_identity(SocketEntry *e, int version)
298 break; 297 break;
299 case 2: 298 case 2:
300 blob = buffer_get_string(&e->input, &blen); 299 blob = buffer_get_string(&e->input, &blen);
301 key = dsa_key_from_blob(blob, blen); 300 key = key_from_blob(blob, blen);
302 xfree(blob); 301 xfree(blob);
303 break; 302 break;
304 } 303 }
@@ -315,8 +314,12 @@ process_remove_identity(SocketEntry *e, int version)
315 Idtab *tab = idtab_lookup(version); 314 Idtab *tab = idtab_lookup(version);
316 key_free(tab->identities[idx].key); 315 key_free(tab->identities[idx].key);
317 xfree(tab->identities[idx].comment); 316 xfree(tab->identities[idx].comment);
318 if (idx != tab->nentries) 317 if (tab->nentries < 1)
319 tab->identities[idx] = tab->identities[tab->nentries]; 318 fatal("process_remove_identity: "
319 "internal error: tab->nentries %d",
320 tab->nentries);
321 if (idx != tab->nentries - 1)
322 tab->identities[idx] = tab->identities[tab->nentries - 1];
320 tab->nentries--; 323 tab->nentries--;
321 success = 1; 324 success = 1;
322 } 325 }
@@ -349,79 +352,80 @@ process_remove_all_identities(SocketEntry *e, int version)
349} 352}
350 353
351void 354void
352process_add_identity(SocketEntry *e, int version) 355generate_additional_parameters(RSA *rsa)
353{ 356{
354 Key *k = NULL;
355 RSA *rsa;
356 BIGNUM *aux; 357 BIGNUM *aux;
357 BN_CTX *ctx; 358 BN_CTX *ctx;
358 char *type; 359 /* Generate additional parameters */
360 aux = BN_new();
361 ctx = BN_CTX_new();
362
363 BN_sub(aux, rsa->q, BN_value_one());
364 BN_mod(rsa->dmq1, rsa->d, aux, ctx);
365
366 BN_sub(aux, rsa->p, BN_value_one());
367 BN_mod(rsa->dmp1, rsa->d, aux, ctx);
368
369 BN_clear_free(aux);
370 BN_CTX_free(ctx);
371}
372
373void
374process_add_identity(SocketEntry *e, int version)
375{
376 Key *k = NULL;
377 char *type_name;
359 char *comment; 378 char *comment;
360 int success = 0; 379 int type, success = 0;
361 Idtab *tab = idtab_lookup(version); 380 Idtab *tab = idtab_lookup(version);
362 381
363 switch (version) { 382 switch (version) {
364 case 1: 383 case 1:
365 k = key_new(KEY_RSA); 384 k = key_new_private(KEY_RSA1);
366 rsa = k->rsa; 385 buffer_get_int(&e->input); /* ignored */
367 386 buffer_get_bignum(&e->input, k->rsa->n);
368 /* allocate mem for private key */ 387 buffer_get_bignum(&e->input, k->rsa->e);
369 /* XXX rsa->n and rsa->e are already allocated */ 388 buffer_get_bignum(&e->input, k->rsa->d);
370 rsa->d = BN_new(); 389 buffer_get_bignum(&e->input, k->rsa->iqmp);
371 rsa->iqmp = BN_new();
372 rsa->q = BN_new();
373 rsa->p = BN_new();
374 rsa->dmq1 = BN_new();
375 rsa->dmp1 = BN_new();
376
377 buffer_get_int(&e->input); /* ignored */
378
379 buffer_get_bignum(&e->input, rsa->n);
380 buffer_get_bignum(&e->input, rsa->e);
381 buffer_get_bignum(&e->input, rsa->d);
382 buffer_get_bignum(&e->input, rsa->iqmp);
383 390
384 /* SSH and SSL have p and q swapped */ 391 /* SSH and SSL have p and q swapped */
385 buffer_get_bignum(&e->input, rsa->q); /* p */ 392 buffer_get_bignum(&e->input, k->rsa->q); /* p */
386 buffer_get_bignum(&e->input, rsa->p); /* q */ 393 buffer_get_bignum(&e->input, k->rsa->p); /* q */
387 394
388 /* Generate additional parameters */ 395 /* Generate additional parameters */
389 aux = BN_new(); 396 generate_additional_parameters(k->rsa);
390 ctx = BN_CTX_new();
391
392 BN_sub(aux, rsa->q, BN_value_one());
393 BN_mod(rsa->dmq1, rsa->d, aux, ctx);
394
395 BN_sub(aux, rsa->p, BN_value_one());
396 BN_mod(rsa->dmp1, rsa->d, aux, ctx);
397
398 BN_clear_free(aux);
399 BN_CTX_free(ctx);
400
401 break; 397 break;
402 case 2: 398 case 2:
403 type = buffer_get_string(&e->input, NULL); 399 type_name = buffer_get_string(&e->input, NULL);
404 if (strcmp(type, KEX_DSS)) { 400 type = key_type_from_name(type_name);
401 xfree(type_name);
402 switch(type) {
403 case KEY_DSA:
404 k = key_new_private(type);
405 buffer_get_bignum2(&e->input, k->dsa->p);
406 buffer_get_bignum2(&e->input, k->dsa->q);
407 buffer_get_bignum2(&e->input, k->dsa->g);
408 buffer_get_bignum2(&e->input, k->dsa->pub_key);
409 buffer_get_bignum2(&e->input, k->dsa->priv_key);
410 break;
411 case KEY_RSA:
412 k = key_new_private(type);
413 buffer_get_bignum2(&e->input, k->rsa->n);
414 buffer_get_bignum2(&e->input, k->rsa->e);
415 buffer_get_bignum2(&e->input, k->rsa->d);
416 buffer_get_bignum2(&e->input, k->rsa->iqmp);
417 buffer_get_bignum2(&e->input, k->rsa->p);
418 buffer_get_bignum2(&e->input, k->rsa->q);
419
420 /* Generate additional parameters */
421 generate_additional_parameters(k->rsa);
422 break;
423 default:
405 buffer_clear(&e->input); 424 buffer_clear(&e->input);
406 xfree(type);
407 goto send; 425 goto send;
408 } 426 }
409 xfree(type);
410
411 k = key_new(KEY_DSA);
412
413 /* allocate mem for private key */
414 k->dsa->priv_key = BN_new();
415
416 buffer_get_bignum2(&e->input, k->dsa->p);
417 buffer_get_bignum2(&e->input, k->dsa->q);
418 buffer_get_bignum2(&e->input, k->dsa->g);
419 buffer_get_bignum2(&e->input, k->dsa->pub_key);
420 buffer_get_bignum2(&e->input, k->dsa->priv_key);
421
422 break; 427 break;
423 } 428 }
424
425 comment = buffer_get_string(&e->input, NULL); 429 comment = buffer_get_string(&e->input, NULL);
426 if (k == NULL) { 430 if (k == NULL) {
427 xfree(comment); 431 xfree(comment);
@@ -670,13 +674,6 @@ main(int ac, char **av)
670 674
671 init_rng(); 675 init_rng();
672 676
673 /* check if RSA support exists */
674 if (rsa_alive() == 0) {
675 fprintf(stderr,
676 "%s: no RSA support in libssl and libcrypto. See ssl(8).\n",
677 __progname);
678 exit(1);
679 }
680#ifdef __GNU_LIBRARY__ 677#ifdef __GNU_LIBRARY__
681 while ((ch = getopt(ac, av, "+cks")) != -1) { 678 while ((ch = getopt(ac, av, "+cks")) != -1) {
682#else /* __GNU_LIBRARY__ */ 679#else /* __GNU_LIBRARY__ */
diff --git a/dsa.c b/ssh-dss.c
index 4ff4b58f2..fea1fe2d5 100644
--- a/dsa.c
+++ b/ssh-dss.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: dsa.c,v 1.11 2000/09/07 20:27:51 deraadt Exp $"); 26RCSID("$OpenBSD: ssh-dss.c,v 1.1 2000/11/12 19:50:38 markus Exp $");
27 27
28#include "ssh.h" 28#include "ssh.h"
29#include "xmalloc.h" 29#include "xmalloc.h"
@@ -32,88 +32,17 @@ RCSID("$OpenBSD: dsa.c,v 1.11 2000/09/07 20:27:51 deraadt Exp $");
32#include "compat.h" 32#include "compat.h"
33 33
34#include <openssl/bn.h> 34#include <openssl/bn.h>
35#include <openssl/dh.h>
36#include <openssl/rsa.h> 35#include <openssl/rsa.h>
37#include <openssl/dsa.h> 36#include <openssl/dsa.h>
38#include <openssl/evp.h> 37#include <openssl/evp.h>
39#include <openssl/bio.h>
40#include <openssl/pem.h>
41 38
42#include <openssl/hmac.h>
43#include "kex.h"
44#include "key.h" 39#include "key.h"
45#include "uuencode.h"
46 40
47#define INTBLOB_LEN 20 41#define INTBLOB_LEN 20
48#define SIGBLOB_LEN (2*INTBLOB_LEN) 42#define SIGBLOB_LEN (2*INTBLOB_LEN)
49 43
50Key *
51dsa_key_from_blob(char *blob, int blen)
52{
53 Buffer b;
54 char *ktype;
55 int rlen;
56 DSA *dsa;
57 Key *key;
58
59#ifdef DEBUG_DSS
60 dump_base64(stderr, blob, blen);
61#endif
62 /* fetch & parse DSA/DSS pubkey */
63 buffer_init(&b);
64 buffer_append(&b, blob, blen);
65 ktype = buffer_get_string(&b, NULL);
66 if (strcmp(KEX_DSS, ktype) != 0) {
67 error("dsa_key_from_blob: cannot handle type %s", ktype);
68 buffer_free(&b);
69 xfree(ktype);
70 return NULL;
71 }
72 key = key_new(KEY_DSA);
73 dsa = key->dsa;
74 buffer_get_bignum2(&b, dsa->p);
75 buffer_get_bignum2(&b, dsa->q);
76 buffer_get_bignum2(&b, dsa->g);
77 buffer_get_bignum2(&b, dsa->pub_key);
78 rlen = buffer_len(&b);
79 if(rlen != 0)
80 error("dsa_key_from_blob: remaining bytes in key blob %d", rlen);
81 buffer_free(&b);
82 xfree(ktype);
83
84#ifdef DEBUG_DSS
85 DSA_print_fp(stderr, dsa, 8);
86#endif
87 return key;
88}
89int
90dsa_make_key_blob(Key *key, unsigned char **blobp, unsigned int *lenp)
91{
92 Buffer b;
93 int len;
94 unsigned char *buf;
95
96 if (key == NULL || key->type != KEY_DSA)
97 return 0;
98 buffer_init(&b);
99 buffer_put_cstring(&b, KEX_DSS);
100 buffer_put_bignum2(&b, key->dsa->p);
101 buffer_put_bignum2(&b, key->dsa->q);
102 buffer_put_bignum2(&b, key->dsa->g);
103 buffer_put_bignum2(&b, key->dsa->pub_key);
104 len = buffer_len(&b);
105 buf = xmalloc(len);
106 memcpy(buf, buffer_ptr(&b), len);
107 memset(buffer_ptr(&b), 0, len);
108 buffer_free(&b);
109 if (lenp != NULL)
110 *lenp = len;
111 if (blobp != NULL)
112 *blobp = buf;
113 return len;
114}
115int 44int
116dsa_sign( 45ssh_dss_sign(
117 Key *key, 46 Key *key,
118 unsigned char **sigp, int *lenp, 47 unsigned char **sigp, int *lenp,
119 unsigned char *data, int datalen) 48 unsigned char *data, int datalen)
@@ -130,7 +59,7 @@ dsa_sign(
130 Buffer b; 59 Buffer b;
131 60
132 if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { 61 if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
133 error("dsa_sign: no DSA key"); 62 error("ssh_dss_sign: no DSA key");
134 return -1; 63 return -1;
135 } 64 }
136 digest = xmalloc(evp_md->md_size); 65 digest = xmalloc(evp_md->md_size);
@@ -140,7 +69,7 @@ dsa_sign(
140 69
141 sig = DSA_do_sign(digest, evp_md->md_size, key->dsa); 70 sig = DSA_do_sign(digest, evp_md->md_size, key->dsa);
142 if (sig == NULL) { 71 if (sig == NULL) {
143 fatal("dsa_sign: cannot sign"); 72 fatal("ssh_dss_sign: cannot sign");
144 } 73 }
145 74
146 rlen = BN_num_bytes(sig->r); 75 rlen = BN_num_bytes(sig->r);
@@ -168,7 +97,7 @@ dsa_sign(
168 } else { 97 } else {
169 /* ietf-drafts */ 98 /* ietf-drafts */
170 buffer_init(&b); 99 buffer_init(&b);
171 buffer_put_cstring(&b, KEX_DSS); 100 buffer_put_cstring(&b, "ssh-dss");
172 buffer_put_string(&b, sigblob, SIGBLOB_LEN); 101 buffer_put_string(&b, sigblob, SIGBLOB_LEN);
173 len = buffer_len(&b); 102 len = buffer_len(&b);
174 ret = xmalloc(len); 103 ret = xmalloc(len);
@@ -182,7 +111,7 @@ dsa_sign(
182 return 0; 111 return 0;
183} 112}
184int 113int
185dsa_verify( 114ssh_dss_verify(
186 Key *key, 115 Key *key,
187 unsigned char *signature, int signaturelen, 116 unsigned char *signature, int signaturelen,
188 unsigned char *data, int datalen) 117 unsigned char *data, int datalen)
@@ -194,12 +123,12 @@ dsa_verify(
194 EVP_MD_CTX md; 123 EVP_MD_CTX md;
195 unsigned char *sigblob; 124 unsigned char *sigblob;
196 char *txt; 125 char *txt;
197 unsigned int len; 126 unsigned int len, dlen;
198 int rlen; 127 int rlen;
199 int ret; 128 int ret;
200 129
201 if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { 130 if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
202 error("dsa_verify: no DSA key"); 131 error("ssh_dss_verify: no DSA key");
203 return -1; 132 return -1;
204 } 133 }
205 134
@@ -225,8 +154,8 @@ dsa_verify(
225 buffer_init(&b); 154 buffer_init(&b);
226 buffer_append(&b, (char *) signature, signaturelen); 155 buffer_append(&b, (char *) signature, signaturelen);
227 ktype = buffer_get_string(&b, NULL); 156 ktype = buffer_get_string(&b, NULL);
228 if (strcmp(KEX_DSS, ktype) != 0) { 157 if (strcmp("ssh-dss", ktype) != 0) {
229 error("dsa_verify: cannot handle type %s", ktype); 158 error("ssh_dss_verify: cannot handle type %s", ktype);
230 buffer_free(&b); 159 buffer_free(&b);
231 return -1; 160 return -1;
232 } 161 }
@@ -258,14 +187,15 @@ dsa_verify(
258 } 187 }
259 188
260 /* sha1 the data */ 189 /* sha1 the data */
261 digest = xmalloc(evp_md->md_size); 190 dlen = evp_md->md_size;
191 digest = xmalloc(dlen);
262 EVP_DigestInit(&md, evp_md); 192 EVP_DigestInit(&md, evp_md);
263 EVP_DigestUpdate(&md, data, datalen); 193 EVP_DigestUpdate(&md, data, datalen);
264 EVP_DigestFinal(&md, digest, NULL); 194 EVP_DigestFinal(&md, digest, NULL);
265 195
266 ret = DSA_do_verify(digest, evp_md->md_size, sig, key->dsa); 196 ret = DSA_do_verify(digest, dlen, sig, key->dsa);
267 197
268 memset(digest, 0, evp_md->md_size); 198 memset(digest, 0, dlen);
269 xfree(digest); 199 xfree(digest);
270 DSA_SIG_free(sig); 200 DSA_SIG_free(sig);
271 201
@@ -281,24 +211,6 @@ dsa_verify(
281 txt = "error"; 211 txt = "error";
282 break; 212 break;
283 } 213 }
284 debug("dsa_verify: signature %s", txt); 214 debug("ssh_dss_verify: signature %s", txt);
285 return ret; 215 return ret;
286} 216}
287
288Key *
289dsa_generate_key(unsigned int bits)
290{
291 DSA *dsa = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
292 Key *k;
293 if (dsa == NULL) {
294 fatal("DSA_generate_parameters failed");
295 }
296 if (!DSA_generate_key(dsa)) {
297 fatal("DSA_generate_keys failed");
298 }
299
300 k = key_new(KEY_EMPTY);
301 k->type = KEY_DSA;
302 k->dsa = dsa;
303 return k;
304}
diff --git a/dsa.h b/ssh-dss.h
index 252e7880b..7b376e82f 100644
--- a/dsa.h
+++ b/ssh-dss.h
@@ -24,22 +24,16 @@
24#ifndef DSA_H 24#ifndef DSA_H
25#define DSA_H 25#define DSA_H
26 26
27Key *dsa_key_from_blob(char *blob, int blen);
28int dsa_make_key_blob(Key *key, unsigned char **blobp, unsigned int *lenp);
29
30int 27int
31dsa_sign( 28ssh_dss_sign(
32 Key *key, 29 Key *key,
33 unsigned char **sigp, int *lenp, 30 unsigned char **sigp, int *lenp,
34 unsigned char *data, int datalen); 31 unsigned char *data, int datalen);
35 32
36int 33int
37dsa_verify( 34ssh_dss_verify(
38 Key *key, 35 Key *key,
39 unsigned char *signature, int signaturelen, 36 unsigned char *signature, int signaturelen,
40 unsigned char *data, int datalen); 37 unsigned char *data, int datalen);
41 38
42Key *
43dsa_generate_key(unsigned int bits);
44
45#endif 39#endif
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index b91a09827..b1430f143 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -43,8 +43,9 @@
43.Nd authentication key generation 43.Nd authentication key generation
44.Sh SYNOPSIS 44.Sh SYNOPSIS
45.Nm ssh-keygen 45.Nm ssh-keygen
46.Op Fl dq 46.Op Fl q
47.Op Fl b Ar bits 47.Op Fl b Ar bits
48.Op Fl t Ar type
48.Op Fl N Ar new_passphrase 49.Op Fl N Ar new_passphrase
49.Op Fl C Ar comment 50.Op Fl C Ar comment
50.Op Fl f Ar output_keyfile 51.Op Fl f Ar output_keyfile
@@ -79,8 +80,8 @@ generates and manages authentication keys for
79.Nm 80.Nm
80defaults to generating an RSA key for use by protocols 1.3 and 1.5; 81defaults to generating an RSA key for use by protocols 1.3 and 1.5;
81specifying the 82specifying the
82.Fl d 83.Fl t
83flag will create a DSA key instead for use by protocol 2.0. 84allows you to create a key for use by protocol 2.0.
84.Pp 85.Pp
85Normally each user wishing to use SSH 86Normally each user wishing to use SSH
86with RSA or DSA authentication runs this once to create the authentication 87with RSA or DSA authentication runs this once to create the authentication
@@ -154,6 +155,17 @@ Silence
154Used by 155Used by
155.Pa /etc/rc 156.Pa /etc/rc
156when creating a new key. 157when creating a new key.
158.It Fl t Ar type
159Specifies the type of the key to create.
160The possible values are
161.Dq rsa1
162for protocol version 1 and
163.Dq rsa
164or
165.Dq dsa
166for protocol version 2.
167The default is
168.Dq rsa .
157.It Fl C Ar comment 169.It Fl C Ar comment
158Provides the new comment. 170Provides the new comment.
159.It Fl N Ar new_passphrase 171.It Fl N Ar new_passphrase
@@ -173,7 +185,7 @@ SSH2-compatible private (or public) key file and
173print an OpenSSH compatible private (or public) key to stdout. 185print an OpenSSH compatible private (or public) key to stdout.
174.It Fl y 186.It Fl y
175This option will read a private 187This option will read a private
176OpenSSH DSA format file and print an OpenSSH DSA public key to stdout. 188OpenSSH format file and print an OpenSSH public key to stdout.
177.El 189.El
178.Sh FILES 190.Sh FILES
179.Bl -tag -width Ds 191.Bl -tag -width Ds
@@ -211,10 +223,10 @@ Contains the public key for authentication.
211The contents of this file should be added to 223The contents of this file should be added to
212.Pa $HOME/.ssh/authorized_keys2 224.Pa $HOME/.ssh/authorized_keys2
213on all machines 225on all machines
214where you wish to log in using DSA authentication. 226where you wish to log in using public key authentication.
215There is no need to keep the contents of this file secret. 227There is no need to keep the contents of this file secret.
216.El 228.El
217.Sh AUTHOR 229.Sh AUTHORS
218Tatu Ylonen <ylo@cs.hut.fi> 230Tatu Ylonen <ylo@cs.hut.fi>
219.Pp 231.Pp
220OpenSSH 232OpenSSH
diff --git a/ssh-keygen.c b/ssh-keygen.c
index e050f4051..76edc5301 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: ssh-keygen.c,v 1.32 2000/10/09 21:30:44 markus Exp $"); 15RCSID("$OpenBSD: ssh-keygen.c,v 1.33 2000/11/12 19:50:38 markus Exp $");
16 16
17#include <openssl/evp.h> 17#include <openssl/evp.h>
18#include <openssl/pem.h> 18#include <openssl/pem.h>
@@ -23,7 +23,6 @@ RCSID("$OpenBSD: ssh-keygen.c,v 1.32 2000/10/09 21:30:44 markus Exp $");
23#include "xmalloc.h" 23#include "xmalloc.h"
24#include "key.h" 24#include "key.h"
25#include "rsa.h" 25#include "rsa.h"
26#include "dsa.h"
27#include "authfile.h" 26#include "authfile.h"
28#include "uuencode.h" 27#include "uuencode.h"
29 28
@@ -67,7 +66,10 @@ char *identity_comment = NULL;
67int convert_to_ssh2 = 0; 66int convert_to_ssh2 = 0;
68int convert_from_ssh2 = 0; 67int convert_from_ssh2 = 0;
69int print_public = 0; 68int print_public = 0;
70int dsa_mode = 0; 69
70/* key type */
71int dsa_mode = 0; /* compat */
72char *key_type_name = NULL;
71 73
72/* argv0 */ 74/* argv0 */
73#ifdef HAVE___PROGNAME 75#ifdef HAVE___PROGNAME
@@ -130,12 +132,12 @@ do_convert_to_ssh2(struct passwd *pw)
130 perror(identity_file); 132 perror(identity_file);
131 exit(1); 133 exit(1);
132 } 134 }
133 k = key_new(KEY_DSA); 135 k = key_new(KEY_UNSPEC);
134 if (!try_load_key(identity_file, k)) { 136 if (!try_load_key(identity_file, k)) {
135 fprintf(stderr, "load failed\n"); 137 fprintf(stderr, "load failed\n");
136 exit(1); 138 exit(1);
137 } 139 }
138 dsa_make_key_blob(k, &blob, &len); 140 key_to_blob(k, &blob, &len);
139 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN); 141 fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
140 fprintf(stdout, 142 fprintf(stdout,
141 "Comment: \"%d-bit %s, converted from OpenSSH by %s@%s\"\n", 143 "Comment: \"%d-bit %s, converted from OpenSSH by %s@%s\"\n",
@@ -266,7 +268,7 @@ do_convert_from_ssh2(struct passwd *pw)
266 } 268 }
267 k = private ? 269 k = private ?
268 do_convert_private_ssh2_from_blob(blob, blen) : 270 do_convert_private_ssh2_from_blob(blob, blen) :
269 dsa_key_from_blob(blob, blen); 271 key_from_blob(blob, blen);
270 if (k == NULL) { 272 if (k == NULL) {
271 fprintf(stderr, "decode blob failed.\n"); 273 fprintf(stderr, "decode blob failed.\n");
272 exit(1); 274 exit(1);
@@ -288,8 +290,6 @@ void
288do_print_public(struct passwd *pw) 290do_print_public(struct passwd *pw)
289{ 291{
290 Key *k; 292 Key *k;
291 int len;
292 unsigned char *blob;
293 struct stat st; 293 struct stat st;
294 294
295 if (!have_identity) 295 if (!have_identity)
@@ -298,16 +298,14 @@ do_print_public(struct passwd *pw)
298 perror(identity_file); 298 perror(identity_file);
299 exit(1); 299 exit(1);
300 } 300 }
301 k = key_new(KEY_DSA); 301 k = key_new(KEY_UNSPEC);
302 if (!try_load_key(identity_file, k)) { 302 if (!try_load_key(identity_file, k)) {
303 fprintf(stderr, "load failed\n"); 303 fprintf(stderr, "load failed\n");
304 exit(1); 304 exit(1);
305 } 305 }
306 dsa_make_key_blob(k, &blob, &len);
307 if (!key_write(k, stdout)) 306 if (!key_write(k, stdout))
308 fprintf(stderr, "key_write failed"); 307 fprintf(stderr, "key_write failed");
309 key_free(k); 308 key_free(k);
310 xfree(blob);
311 fprintf(stdout, "\n"); 309 fprintf(stdout, "\n");
312 exit(0); 310 exit(0);
313} 311}
@@ -315,12 +313,11 @@ do_print_public(struct passwd *pw)
315void 313void
316do_fingerprint(struct passwd *pw) 314do_fingerprint(struct passwd *pw)
317{ 315{
318 /* XXX RSA1 only */
319 316
320 FILE *f; 317 FILE *f;
321 Key *public; 318 Key *public;
322 char *comment = NULL, *cp, *ep, line[16*1024]; 319 char *comment = NULL, *cp, *ep, line[16*1024];
323 int i, skip = 0, num = 1, invalid = 1; 320 int i, skip = 0, num = 1, invalid = 1, success = 0;
324 unsigned int ignore; 321 unsigned int ignore;
325 struct stat st; 322 struct stat st;
326 323
@@ -330,14 +327,27 @@ do_fingerprint(struct passwd *pw)
330 perror(identity_file); 327 perror(identity_file);
331 exit(1); 328 exit(1);
332 } 329 }
333 public = key_new(KEY_RSA); 330 public = key_new(KEY_RSA1);
334 if (load_public_key(identity_file, public, &comment)) { 331 if (load_public_key(identity_file, public, &comment)) {
335 printf("%d %s %s\n", BN_num_bits(public->rsa->n), 332 success = 1;
336 key_fingerprint(public), comment); 333 } else {
334 key_free(public);
335 public = key_new(KEY_UNSPEC);
336 if (try_load_public_key(identity_file, public, &comment))
337 success = 1;
338 else
339 error("try_load_public_key KEY_UNSPEC failed");
340 }
341 if (success) {
342 printf("%d %s %s\n", key_size(public), key_fingerprint(public), comment);
337 key_free(public); 343 key_free(public);
344 xfree(comment);
338 exit(0); 345 exit(0);
339 } 346 }
340 347
348 /* XXX RSA1 only */
349
350 public = key_new(KEY_RSA1);
341 f = fopen(identity_file, "r"); 351 f = fopen(identity_file, "r");
342 if (f != NULL) { 352 if (f != NULL) {
343 while (fgets(line, sizeof(line), f)) { 353 while (fgets(line, sizeof(line), f)) {
@@ -404,7 +414,7 @@ do_change_passphrase(struct passwd *pw)
404 struct stat st; 414 struct stat st;
405 Key *private; 415 Key *private;
406 Key *public; 416 Key *public;
407 int type = dsa_mode ? KEY_DSA : KEY_RSA; 417 int type = KEY_RSA1;
408 418
409 if (!have_identity) 419 if (!have_identity)
410 ask_filename(pw, "Enter file in which the key is"); 420 ask_filename(pw, "Enter file in which the key is");
@@ -412,18 +422,13 @@ do_change_passphrase(struct passwd *pw)
412 perror(identity_file); 422 perror(identity_file);
413 exit(1); 423 exit(1);
414 } 424 }
415 425 public = key_new(type);
416 if (type == KEY_RSA) { 426 if (!load_public_key(identity_file, public, NULL)) {
417 /* XXX this works currently only for RSA */ 427 type = KEY_UNSPEC;
418 public = key_new(type); 428 } else {
419 if (!load_public_key(identity_file, public, NULL)) {
420 printf("%s is not a valid key file.\n", identity_file);
421 exit(1);
422 }
423 /* Clear the public key since we are just about to load the whole file. */ 429 /* Clear the public key since we are just about to load the whole file. */
424 key_free(public); 430 key_free(public);
425 } 431 }
426
427 /* Try to load the file with empty passphrase. */ 432 /* Try to load the file with empty passphrase. */
428 private = key_new(type); 433 private = key_new(type);
429 if (!load_private_key(identity_file, "", private, &comment)) { 434 if (!load_private_key(identity_file, "", private, &comment)) {
@@ -508,13 +513,13 @@ do_change_comment(struct passwd *pw)
508 * Try to load the public key from the file the verify that it is 513 * Try to load the public key from the file the verify that it is
509 * readable and of the proper format. 514 * readable and of the proper format.
510 */ 515 */
511 public = key_new(KEY_RSA); 516 public = key_new(KEY_RSA1);
512 if (!load_public_key(identity_file, public, NULL)) { 517 if (!load_public_key(identity_file, public, NULL)) {
513 printf("%s is not a valid key file.\n", identity_file); 518 printf("%s is not a valid key file.\n", identity_file);
514 exit(1); 519 exit(1);
515 } 520 }
516 521
517 private = key_new(KEY_RSA); 522 private = key_new(KEY_RSA1);
518 if (load_private_key(identity_file, "", private, &comment)) 523 if (load_private_key(identity_file, "", private, &comment))
519 passphrase = xstrdup(""); 524 passphrase = xstrdup("");
520 else { 525 else {
@@ -583,7 +588,7 @@ do_change_comment(struct passwd *pw)
583void 588void
584usage(void) 589usage(void)
585{ 590{
586 printf("Usage: %s [-lpqxXydc] [-b bits] [-f file] [-C comment] [-N new-pass] [-P pass]\n", __progname); 591 printf("Usage: %s [-lpqxXyc] [-t type] [-b bits] [-f file] [-C comment] [-N new-pass] [-P pass]\n", __progname);
587 exit(1); 592 exit(1);
588} 593}
589 594
@@ -598,8 +603,10 @@ main(int ac, char **av)
598 int opt; 603 int opt;
599 struct stat st; 604 struct stat st;
600 FILE *f; 605 FILE *f;
606 int type = KEY_RSA1;
601 Key *private; 607 Key *private;
602 Key *public; 608 Key *public;
609
603 extern int optind; 610 extern int optind;
604 extern char *optarg; 611 extern char *optarg;
605 612
@@ -618,7 +625,7 @@ main(int ac, char **av)
618 exit(1); 625 exit(1);
619 } 626 }
620 627
621 while ((opt = getopt(ac, av, "dqpclRxXyb:f:P:N:C:")) != EOF) { 628 while ((opt = getopt(ac, av, "dqpclRxXyb:f:t:P:N:C:")) != EOF) {
622 switch (opt) { 629 switch (opt) {
623 case 'b': 630 case 'b':
624 bits = atoi(optarg); 631 bits = atoi(optarg);
@@ -662,10 +669,8 @@ main(int ac, char **av)
662 break; 669 break;
663 670
664 case 'R': 671 case 'R':
665 if (rsa_alive() == 0) 672 /* unused */
666 exit(1); 673 exit(0);
667 else
668 exit(0);
669 break; 674 break;
670 675
671 case 'x': 676 case 'x':
@@ -681,9 +686,15 @@ main(int ac, char **av)
681 break; 686 break;
682 687
683 case 'd': 688 case 'd':
689 key_type_name = "dsa";
684 dsa_mode = 1; 690 dsa_mode = 1;
685 break; 691 break;
686 692
693 case 't':
694 key_type_name = optarg;
695 dsa_mode = (strcmp(optarg, "dsa") == 0);
696 break;
697
687 case '?': 698 case '?':
688 default: 699 default:
689 usage(); 700 usage();
@@ -697,13 +708,6 @@ main(int ac, char **av)
697 printf("Can only have one of -p and -c.\n"); 708 printf("Can only have one of -p and -c.\n");
698 usage(); 709 usage();
699 } 710 }
700 /* check if RSA support is needed and exists */
701 if (dsa_mode == 0 && rsa_alive() == 0) {
702 fprintf(stderr,
703 "%s: no RSA support in libssl and libcrypto. See ssl(8).\n",
704 __progname);
705 exit(1);
706 }
707 if (print_fingerprint) 711 if (print_fingerprint)
708 do_fingerprint(pw); 712 do_fingerprint(pw);
709 if (change_passphrase) 713 if (change_passphrase)
@@ -719,22 +723,21 @@ main(int ac, char **av)
719 723
720 arc4random_stir(); 724 arc4random_stir();
721 725
722 if (dsa_mode != 0) { 726 if (key_type_name != NULL) {
723 if (!quiet) 727 type = key_type_from_name(key_type_name);
724 printf("Generating DSA parameter and key.\n"); 728 if (type == KEY_UNSPEC) {
725 public = private = dsa_generate_key(bits); 729 fprintf(stderr, "unknown key type %s", key_type_name);
726 if (private == NULL) {
727 fprintf(stderr, "dsa_generate_keys failed");
728 exit(1); 730 exit(1);
729 } 731 }
730 } else {
731 if (quiet)
732 rsa_set_verbose(0);
733 /* Generate the rsa key pair. */
734 public = key_new(KEY_RSA);
735 private = key_new(KEY_RSA);
736 rsa_generate_key(private->rsa, public->rsa, bits);
737 } 732 }
733 if (!quiet)
734 printf("Generating public/private key pair.\n");
735 private = key_generate(type, bits);
736 if (private == NULL) {
737 fprintf(stderr, "key_generate failed");
738 exit(1);
739 }
740 public = key_from_private(private);
738 741
739 if (!have_identity) 742 if (!have_identity)
740 ask_filename(pw, "Enter file in which to save the key"); 743 ask_filename(pw, "Enter file in which to save the key");
@@ -803,9 +806,7 @@ passphrase_again:
803 xfree(passphrase1); 806 xfree(passphrase1);
804 807
805 /* Clear the private key and the random number generator. */ 808 /* Clear the private key and the random number generator. */
806 if (private != public) { 809 key_free(private);
807 key_free(private);
808 }
809 arc4random_stir(); 810 arc4random_stir();
810 811
811 if (!quiet) 812 if (!quiet)
diff --git a/ssh-rsa.c b/ssh-rsa.c
new file mode 100644
index 000000000..cc31154d9
--- /dev/null
+++ b/ssh-rsa.c
@@ -0,0 +1,163 @@
1/*
2 * Copyright (c) 2000 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
23 */
24
25#include "includes.h"
26RCSID("$OpenBSD: ssh-rsa.c,v 1.1 2000/11/12 19:50:38 markus Exp $");
27
28#include "ssh.h"
29#include "xmalloc.h"
30#include "buffer.h"
31#include "bufaux.h"
32
33#include <openssl/evp.h>
34#include <openssl/dsa.h>
35#include <openssl/rsa.h>
36#include <openssl/err.h>
37
38#include "key.h"
39
40#define INTBLOB_LEN 20
41#define SIGBLOB_LEN (2*INTBLOB_LEN)
42
43/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
44int
45ssh_rsa_sign(
46 Key *key,
47 unsigned char **sigp, int *lenp,
48 unsigned char *data, int datalen)
49{
50 EVP_MD *evp_md = EVP_sha1();
51 EVP_MD_CTX md;
52 unsigned char *digest, *sig, *ret;
53 unsigned int slen, dlen, len;
54 int ok;
55 Buffer b;
56
57 if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
58 error("ssh_rsa_sign: no RSA key");
59 return -1;
60 }
61 slen = RSA_size(key->rsa);
62 sig = xmalloc(slen);
63
64 dlen = evp_md->md_size;
65 digest = xmalloc(dlen);
66 EVP_DigestInit(&md, evp_md);
67 EVP_DigestUpdate(&md, data, datalen);
68 EVP_DigestFinal(&md, digest, NULL);
69
70 ok = RSA_sign(NID_sha1, digest, dlen, sig, &len, key->rsa);
71 memset(digest, 'd', dlen);
72 xfree(digest);
73
74 if (ok != 1) {
75 int ecode = ERR_get_error();
76 error("ssh_rsa_sign: RSA_sign failed: %s", ERR_error_string(ecode, NULL));
77 xfree(sig);
78 return -1;
79 }
80 if (len < slen) {
81 int diff = slen - len;
82 debug("slen %d > len %d", slen, len);
83 memmove(sig + diff, sig, len);
84 memset(sig, 0, diff);
85 } else if (len > slen) {
86 error("ssh_rsa_sign: slen %d slen2 %d", slen, len);
87 xfree(sig);
88 return -1;
89 }
90 /* encode signature */
91 buffer_init(&b);
92 buffer_put_cstring(&b, "ssh-rsa");
93 buffer_put_string(&b, sig, slen);
94 len = buffer_len(&b);
95 ret = xmalloc(len);
96 memcpy(ret, buffer_ptr(&b), len);
97 buffer_free(&b);
98 memset(sig, 's', slen);
99 xfree(sig);
100
101 if (lenp != NULL)
102 *lenp = len;
103 if (sigp != NULL)
104 *sigp = ret;
105 debug2("ssh_rsa_sign: done");
106 return 0;
107}
108
109int
110ssh_rsa_verify(
111 Key *key,
112 unsigned char *signature, int signaturelen,
113 unsigned char *data, int datalen)
114{
115 Buffer b;
116 EVP_MD *evp_md = EVP_sha1();
117 EVP_MD_CTX md;
118 char *ktype;
119 unsigned char *sigblob, *digest;
120 unsigned int len, dlen;
121 int rlen;
122 int ret;
123
124 if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
125 error("ssh_rsa_verify: no RSA key");
126 return -1;
127 }
128 buffer_init(&b);
129 buffer_append(&b, (char *) signature, signaturelen);
130 ktype = buffer_get_string(&b, NULL);
131 if (strcmp("ssh-rsa", ktype) != 0) {
132 error("ssh_rsa_verify: cannot handle type %s", ktype);
133 buffer_free(&b);
134 xfree(ktype);
135 return -1;
136 }
137 xfree(ktype);
138 sigblob = (unsigned char *)buffer_get_string(&b, &len);
139 rlen = buffer_len(&b);
140 buffer_free(&b);
141 if(rlen != 0) {
142 error("ssh_rsa_verify: remaining bytes in signature %d", rlen);
143 return -1;
144 }
145
146 dlen = evp_md->md_size;
147 digest = xmalloc(dlen);
148 EVP_DigestInit(&md, evp_md);
149 EVP_DigestUpdate(&md, data, datalen);
150 EVP_DigestFinal(&md, digest, NULL);
151
152 ret = RSA_verify(NID_sha1, digest, dlen, sigblob, len, key->rsa);
153 memset(digest, 'd', dlen);
154 xfree(digest);
155 memset(sigblob, 's', len);
156 xfree(sigblob);
157 if (ret == 0) {
158 int ecode = ERR_get_error();
159 error("ssh_rsa_verify: RSA_verify failed: %s", ERR_error_string(ecode, NULL));
160 }
161 debug("ssh_rsa_verify: signature %scorrect", (ret==0) ? "in" : "");
162 return ret;
163}
diff --git a/ssh-rsa.h b/ssh-rsa.h
new file mode 100644
index 000000000..29a0c029c
--- /dev/null
+++ b/ssh-rsa.h
@@ -0,0 +1,39 @@
1/*
2 * Copyright (c) 2000 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
23 */
24#ifndef SSH_RSA_H
25#define SSH_RSA_H
26
27int
28ssh_rsa_sign(
29 Key *key,
30 unsigned char **sigp, int *lenp,
31 unsigned char *data, int datalen);
32
33int
34ssh_rsa_verify(
35 Key *key,
36 unsigned char *signature, int signaturelen,
37 unsigned char *data, int datalen);
38
39#endif
diff --git a/ssh.1 b/ssh.1
index 786df1843..4bbfe34c0 100644
--- a/ssh.1
+++ b/ssh.1
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: ssh.1,v 1.64 2000/10/16 21:46:31 markus Exp $ 37.\" $OpenBSD: ssh.1,v 1.68 2000/11/12 19:50:38 markus Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSH 1 39.Dt SSH 1
40.Os 40.Os
@@ -209,9 +209,9 @@ At first, the client attempts to authenticate using the public key method.
209If this method fails password authentication is tried. 209If this method fails password authentication is tried.
210.Pp 210.Pp
211The public key method is similar to RSA authentication described 211The public key method is similar to RSA authentication described
212in the previous section except that the DSA algorithm is used 212in the previous section except that the DSA or RSA algorithm is used
213instead of the patented RSA algorithm. 213instead.
214The client uses his private DSA key 214The client uses his private key
215.Pa $HOME/.ssh/id_dsa 215.Pa $HOME/.ssh/id_dsa
216to sign the session identifier and sends the result to the server. 216to sign the session identifier and sends the result to the server.
217The server checks whether the matching public key is listed in 217The server checks whether the matching public key is listed in
@@ -331,7 +331,7 @@ identifications for all hosts it has ever been used with.
331RSA host keys are stored in 331RSA host keys are stored in
332.Pa $HOME/.ssh/known_hosts 332.Pa $HOME/.ssh/known_hosts
333and 333and
334DSA host keys are stored in 334host keys used in the protocol version 2 are stored in
335.Pa $HOME/.ssh/known_hosts2 335.Pa $HOME/.ssh/known_hosts2
336in the user's home directory. 336in the user's home directory.
337Additionally, the files 337Additionally, the files
@@ -352,7 +352,8 @@ The
352.Cm StrictHostKeyChecking 352.Cm StrictHostKeyChecking
353option (see below) can be used to prevent logins to machines whose 353option (see below) can be used to prevent logins to machines whose
354host key is not known or has changed. 354host key is not known or has changed.
355.Sh OPTIONS 355.Pp
356The options are as follows:
356.Bl -tag -width Ds 357.Bl -tag -width Ds
357.It Fl a 358.It Fl a
358Disables forwarding of the authentication agent connection. 359Disables forwarding of the authentication agent connection.
@@ -407,7 +408,7 @@ something like
407Allows remote hosts to connect to local forwarded ports. 408Allows remote hosts to connect to local forwarded ports.
408.It Fl i Ar identity_file 409.It Fl i Ar identity_file
409Selects the file from which the identity (private key) for 410Selects the file from which the identity (private key) for
410RSA authentication is read. 411RSA or DSA authentication is read.
411Default is 412Default is
412.Pa $HOME/.ssh/identity 413.Pa $HOME/.ssh/identity
413in the user's home directory. 414in the user's home directory.
@@ -552,6 +553,22 @@ Forces
552.Nm 553.Nm
553to use IPv6 addresses only. 554to use IPv6 addresses only.
554.El 555.El
556.Pp
557If
558.Nm
559is not invoked with one of the standard program names
560.Pf ( Dq ssh ,
561.Dq slogin ,
562.Dq rsh ,
563.Dq rlogin ,
564or
565.Dq remsh ) ,
566it uses this name as its
567.Ar hostname
568argument.
569This is consistent with traditional
570.Xr rsh 1
571behavior.
555.Sh CONFIGURATION FILES 572.Sh CONFIGURATION FILES
556.Nm 573.Nm
557obtains configuration data from the following sources (in this order): 574obtains configuration data from the following sources (in this order):
@@ -660,14 +677,12 @@ Specifies the number of tries (one per second) to make before falling
660back to rsh or exiting. 677back to rsh or exiting.
661The argument must be an integer. 678The argument must be an integer.
662This may be useful in scripts if the connection sometimes fails. 679This may be useful in scripts if the connection sometimes fails.
663.It Cm DSAAuthentication 680.It Cm PubkeyAuthentication
664Specifies whether to try DSA authentication. 681Specifies whether to try public key authentication.
665The argument to this keyword must be 682The argument to this keyword must be
666.Dq yes 683.Dq yes
667or 684or
668.Dq no . 685.Dq no .
669DSA authentication will only be
670attempted if a DSA identity file exists.
671Note that this option applies to protocol version 2 only. 686Note that this option applies to protocol version 2 only.
672.It Cm EscapeChar 687.It Cm EscapeChar
673Sets the escape character (default: 688Sets the escape character (default:
@@ -745,16 +760,6 @@ syntax to refer to a user's home directory.
745It is possible to have 760It is possible to have
746multiple identity files specified in configuration files; all these 761multiple identity files specified in configuration files; all these
747identities will be tried in sequence. 762identities will be tried in sequence.
748.It Cm IdentityFile2
749Specifies the file from which the user's DSA authentication identity
750is read (default
751.Pa $HOME/.ssh/id_dsa
752in the user's home directory).
753The file name may use the tilde
754syntax to refer to a user's home directory.
755It is possible to have
756multiple identity files specified in configuration files; all these
757identities will be tried in sequence.
758.It Cm KeepAlive 763.It Cm KeepAlive
759Specifies whether the system should send keepalive messages to the 764Specifies whether the system should send keepalive messages to the
760other side. 765other side.
@@ -1096,7 +1101,7 @@ spaces).
1096This file is not highly sensitive, but the recommended 1101This file is not highly sensitive, but the recommended
1097permissions are read/write for the user, and not accessible by others. 1102permissions are read/write for the user, and not accessible by others.
1098.It Pa $HOME/.ssh/authorized_keys2 1103.It Pa $HOME/.ssh/authorized_keys2
1099Lists the DSA keys that can be used for logging in as this user. 1104Lists the public keys (DSA/RSA) that can be used for logging in as this user.
1100This file is not highly sensitive, but the recommended 1105This file is not highly sensitive, but the recommended
1101permissions are read/write for the user, and not accessible by others. 1106permissions are read/write for the user, and not accessible by others.
1102.It Pa /etc/ssh_known_hosts, /etc/ssh_known_hosts2 1107.It Pa /etc/ssh_known_hosts, /etc/ssh_known_hosts2
@@ -1104,7 +1109,7 @@ Systemwide list of known host keys.
1104.Pa /etc/ssh_known_hosts 1109.Pa /etc/ssh_known_hosts
1105contains RSA and 1110contains RSA and
1106.Pa /etc/ssh_known_hosts2 1111.Pa /etc/ssh_known_hosts2
1107contains DSA keys. 1112contains DSA or RSA keys for protocol version 2.
1108These files should be prepared by the 1113These files should be prepared by the
1109system administrator to contain the public host keys of all machines in the 1114system administrator to contain the public host keys of all machines in the
1110organization. 1115organization.
@@ -1219,7 +1224,7 @@ above.
1219A version of this library which includes support for the RSA algorithm 1224A version of this library which includes support for the RSA algorithm
1220is required for proper operation. 1225is required for proper operation.
1221.El 1226.El
1222.Sh AUTHOR 1227.Sh AUTHORS
1223OpenSSH 1228OpenSSH
1224is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, 1229is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen,
1225but with bugs removed and newer features re-added. 1230but with bugs removed and newer features re-added.
diff --git a/ssh.c b/ssh.c
index 429d571b2..ab32e3b8d 100644
--- a/ssh.c
+++ b/ssh.c
@@ -39,11 +39,12 @@
39 */ 39 */
40 40
41#include "includes.h" 41#include "includes.h"
42RCSID("$OpenBSD: ssh.c,v 1.69 2000/10/27 07:32:19 markus Exp $"); 42RCSID("$OpenBSD: ssh.c,v 1.72 2000/11/12 19:50:38 markus Exp $");
43 43
44#include <openssl/evp.h> 44#include <openssl/evp.h>
45#include <openssl/dsa.h> 45#include <openssl/dsa.h>
46#include <openssl/rsa.h> 46#include <openssl/rsa.h>
47#include <openssl/err.h>
47 48
48#include "xmalloc.h" 49#include "xmalloc.h"
49#include "ssh.h" 50#include "ssh.h"
@@ -218,8 +219,9 @@ rsh_connect(char *host, char *user, Buffer * command)
218 exit(1); 219 exit(1);
219} 220}
220 221
221int ssh_session(void); 222int ssh_session(void);
222int ssh_session2(void); 223int ssh_session2(void);
224int guess_identity_file_type(const char *filename);
223 225
224/* 226/*
225 * Main program for the ssh client. 227 * Main program for the ssh client.
@@ -370,14 +372,13 @@ main(int ac, char **av)
370 case 'i': 372 case 'i':
371 if (stat(optarg, &st) < 0) { 373 if (stat(optarg, &st) < 0) {
372 fprintf(stderr, "Warning: Identity file %s does not exist.\n", 374 fprintf(stderr, "Warning: Identity file %s does not exist.\n",
373 optarg); 375 optarg);
374 break; 376 break;
375 } 377 }
376 if (options.num_identity_files >= SSH_MAX_IDENTITY_FILES) 378 if (options.num_identity_files >= SSH_MAX_IDENTITY_FILES)
377 fatal("Too many identity files specified (max %d)", 379 fatal("Too many identity files specified (max %d)",
378 SSH_MAX_IDENTITY_FILES); 380 SSH_MAX_IDENTITY_FILES);
379 options.identity_files[options.num_identity_files++] = 381 options.identity_files[options.num_identity_files++] = xstrdup(optarg);
380 xstrdup(optarg);
381 break; 382 break;
382 case 't': 383 case 't':
383 tty_flag = 1; 384 tty_flag = 1;
@@ -487,6 +488,7 @@ main(int ac, char **av)
487 usage(); 488 usage();
488 489
489 SSLeay_add_all_algorithms(); 490 SSLeay_add_all_algorithms();
491 ERR_load_crypto_strings();
490 492
491 /* Initialize the command to execute on remote host. */ 493 /* Initialize the command to execute on remote host. */
492 buffer_init(&command); 494 buffer_init(&command);
@@ -563,20 +565,6 @@ main(int ac, char **av)
563 /* reinit */ 565 /* reinit */
564 log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0); 566 log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 0);
565 567
566 /* check if RSA support exists */
567 if ((options.protocol & SSH_PROTO_1) &&
568 rsa_alive() == 0) {
569 log("%s: no RSA support in libssl and libcrypto. See ssl(8).",
570 __progname);
571 log("Disabling protocol version 1");
572 options.protocol &= ~ (SSH_PROTO_1|SSH_PROTO_1_PREFERRED);
573 }
574 if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) {
575 fprintf(stderr, "%s: No protocol version available.\n",
576 __progname);
577 exit(1);
578 }
579
580 if (options.user == NULL) 568 if (options.user == NULL)
581 options.user = xstrdup(pw->pw_name); 569 options.user = xstrdup(pw->pw_name);
582 570
@@ -589,6 +577,8 @@ main(int ac, char **av)
589 if (!options.use_privileged_port) { 577 if (!options.use_privileged_port) {
590#else 578#else
591 if (original_effective_uid != 0 || !options.use_privileged_port) { 579 if (original_effective_uid != 0 || !options.use_privileged_port) {
580 debug("Rhosts Authentication methods disabled, "
581 "originating port will not be trusted.");
592#endif 582#endif
593 options.rhosts_authentication = 0; 583 options.rhosts_authentication = 0;
594 options.rhosts_rsa_authentication = 0; 584 options.rhosts_rsa_authentication = 0;
@@ -635,7 +625,7 @@ main(int ac, char **av)
635 if (ok && (options.protocol & SSH_PROTO_1)) { 625 if (ok && (options.protocol & SSH_PROTO_1)) {
636 Key k; 626 Key k;
637 host_private_key = RSA_new(); 627 host_private_key = RSA_new();
638 k.type = KEY_RSA; 628 k.type = KEY_RSA1;
639 k.rsa = host_private_key; 629 k.rsa = host_private_key;
640 if (load_private_key(HOST_KEY_FILE, "", &k, NULL)) 630 if (load_private_key(HOST_KEY_FILE, "", &k, NULL))
641 host_private_key_loaded = 1; 631 host_private_key_loaded = 1;
@@ -682,23 +672,23 @@ main(int ac, char **av)
682 } 672 }
683 exit(1); 673 exit(1);
684 } 674 }
685 /* Expand ~ in options.identity_files. */ 675 /* Expand ~ in options.identity_files, known host file names. */
686 /* XXX mem-leaks */ 676 /* XXX mem-leaks */
687 for (i = 0; i < options.num_identity_files; i++) 677 for (i = 0; i < options.num_identity_files; i++) {
688 options.identity_files[i] = 678 options.identity_files[i] =
689 tilde_expand_filename(options.identity_files[i], original_real_uid); 679 tilde_expand_filename(options.identity_files[i], original_real_uid);
690 for (i = 0; i < options.num_identity_files2; i++) 680 options.identity_files_type[i] = guess_identity_file_type(options.identity_files[i]);
691 options.identity_files2[i] = 681 debug("identity file %s type %d", options.identity_files[i],
692 tilde_expand_filename(options.identity_files2[i], original_real_uid); 682 options.identity_files_type[i]);
693 /* Expand ~ in known host file names. */ 683 }
694 options.system_hostfile = tilde_expand_filename(options.system_hostfile, 684 options.system_hostfile =
695 original_real_uid); 685 tilde_expand_filename(options.system_hostfile, original_real_uid);
696 options.user_hostfile = tilde_expand_filename(options.user_hostfile, 686 options.user_hostfile =
697 original_real_uid); 687 tilde_expand_filename(options.user_hostfile, original_real_uid);
698 options.system_hostfile2 = tilde_expand_filename(options.system_hostfile2, 688 options.system_hostfile2 =
699 original_real_uid); 689 tilde_expand_filename(options.system_hostfile2, original_real_uid);
700 options.user_hostfile2 = tilde_expand_filename(options.user_hostfile2, 690 options.user_hostfile2 =
701 original_real_uid); 691 tilde_expand_filename(options.user_hostfile2, original_real_uid);
702 692
703 /* Log into the remote system. This never returns if the login fails. */ 693 /* Log into the remote system. This never returns if the login fails. */
704 ssh_login(host_private_key_loaded, host_private_key, 694 ssh_login(host_private_key_loaded, host_private_key,
@@ -752,16 +742,57 @@ x11_get_proto(char *proto, int proto_len, char *data, int data_len)
752 } 742 }
753} 743}
754 744
745void
746ssh_init_forwarding(void)
747{
748 int i;
749 /* Initiate local TCP/IP port forwardings. */
750 for (i = 0; i < options.num_local_forwards; i++) {
751 debug("Connections to local port %d forwarded to remote address %.200s:%d",
752 options.local_forwards[i].port,
753 options.local_forwards[i].host,
754 options.local_forwards[i].host_port);
755 channel_request_local_forwarding(
756 options.local_forwards[i].port,
757 options.local_forwards[i].host,
758 options.local_forwards[i].host_port,
759 options.gateway_ports);
760 }
761
762 /* Initiate remote TCP/IP port forwardings. */
763 for (i = 0; i < options.num_remote_forwards; i++) {
764 debug("Connections to remote port %d forwarded to local address %.200s:%d",
765 options.remote_forwards[i].port,
766 options.remote_forwards[i].host,
767 options.remote_forwards[i].host_port);
768 channel_request_remote_forwarding(
769 options.remote_forwards[i].port,
770 options.remote_forwards[i].host,
771 options.remote_forwards[i].host_port);
772 }
773}
774
775void
776check_agent_present(void)
777{
778 if (options.forward_agent) {
779 /* Clear agent forwarding if we don\'t have an agent. */
780 int authfd = ssh_get_authentication_socket();
781 if (authfd < 0)
782 options.forward_agent = 0;
783 else
784 ssh_close_authentication_socket(authfd);
785 }
786}
787
755int 788int
756ssh_session(void) 789ssh_session(void)
757{ 790{
758 int type; 791 int type;
759 int i;
760 int plen; 792 int plen;
761 int interactive = 0; 793 int interactive = 0;
762 int have_tty = 0; 794 int have_tty = 0;
763 struct winsize ws; 795 struct winsize ws;
764 int authfd;
765 char *cp; 796 char *cp;
766 797
767 /* Enable compression if requested. */ 798 /* Enable compression if requested. */
@@ -845,14 +876,10 @@ ssh_session(void)
845 /* Tell the packet module whether this is an interactive session. */ 876 /* Tell the packet module whether this is an interactive session. */
846 packet_set_interactive(interactive, options.keepalives); 877 packet_set_interactive(interactive, options.keepalives);
847 878
848 /* Clear agent forwarding if we don\'t have an agent. */
849 authfd = ssh_get_authentication_socket();
850 if (authfd < 0)
851 options.forward_agent = 0;
852 else
853 ssh_close_authentication_socket(authfd);
854 879
855 /* Request authentication agent forwarding if appropriate. */ 880 /* Request authentication agent forwarding if appropriate. */
881 check_agent_present();
882
856 if (options.forward_agent) { 883 if (options.forward_agent) {
857 debug("Requesting authentication agent forwarding."); 884 debug("Requesting authentication agent forwarding.");
858 auth_request_forwarding(); 885 auth_request_forwarding();
@@ -863,28 +890,9 @@ ssh_session(void)
863 if (type != SSH_SMSG_SUCCESS) 890 if (type != SSH_SMSG_SUCCESS)
864 log("Warning: Remote host denied authentication agent forwarding."); 891 log("Warning: Remote host denied authentication agent forwarding.");
865 } 892 }
866 /* Initiate local TCP/IP port forwardings. */
867 for (i = 0; i < options.num_local_forwards; i++) {
868 debug("Connections to local port %d forwarded to remote address %.200s:%d",
869 options.local_forwards[i].port,
870 options.local_forwards[i].host,
871 options.local_forwards[i].host_port);
872 channel_request_local_forwarding(options.local_forwards[i].port,
873 options.local_forwards[i].host,
874 options.local_forwards[i].host_port,
875 options.gateway_ports);
876 }
877 893
878 /* Initiate remote TCP/IP port forwardings. */ 894 /* Initiate port forwardings. */
879 for (i = 0; i < options.num_remote_forwards; i++) { 895 ssh_init_forwarding();
880 debug("Connections to remote port %d forwarded to local address %.200s:%d",
881 options.remote_forwards[i].port,
882 options.remote_forwards[i].host,
883 options.remote_forwards[i].host_port);
884 channel_request_remote_forwarding(options.remote_forwards[i].port,
885 options.remote_forwards[i].host,
886 options.remote_forwards[i].host_port);
887 }
888 896
889 /* If requested, let ssh continue in the background. */ 897 /* If requested, let ssh continue in the background. */
890 if (fork_after_authentication_flag) 898 if (fork_after_authentication_flag)
@@ -915,27 +923,10 @@ ssh_session(void)
915 return client_loop(have_tty, tty_flag ? options.escape_char : -1, 0); 923 return client_loop(have_tty, tty_flag ? options.escape_char : -1, 0);
916} 924}
917 925
918void
919init_local_fwd(void)
920{
921 int i;
922 /* Initiate local TCP/IP port forwardings. */
923 for (i = 0; i < options.num_local_forwards; i++) {
924 debug("Connections to local port %d forwarded to remote address %.200s:%d",
925 options.local_forwards[i].port,
926 options.local_forwards[i].host,
927 options.local_forwards[i].host_port);
928 channel_request_local_forwarding(options.local_forwards[i].port,
929 options.local_forwards[i].host,
930 options.local_forwards[i].host_port,
931 options.gateway_ports);
932 }
933}
934
935extern void client_set_session_ident(int id); 926extern void client_set_session_ident(int id);
936 927
937void 928void
938client_init(int id, void *arg) 929ssh_session2_callback(int id, void *arg)
939{ 930{
940 int len; 931 int len;
941 debug("client_init id %d arg %d", id, (int)arg); 932 debug("client_init id %d arg %d", id, (int)arg);
@@ -974,6 +965,13 @@ client_init(int id, void *arg)
974 /* XXX wait for reply */ 965 /* XXX wait for reply */
975 } 966 }
976 967
968 check_agent_present();
969 if (options.forward_agent) {
970 debug("Requesting authentication agent forwarding.");
971 channel_request_start(id, "auth-agent-req@openssh.com", 0);
972 packet_send();
973 }
974
977 len = buffer_len(&command); 975 len = buffer_len(&command);
978 if (len > 0) { 976 if (len > 0) {
979 if (len > 900) 977 if (len > 900)
@@ -1016,8 +1014,8 @@ ssh_session2(void)
1016 if (!isatty(err)) 1014 if (!isatty(err))
1017 set_nonblock(err); 1015 set_nonblock(err);
1018 1016
1019 /* should be pre-session */ 1017 /* XXX should be pre-session */
1020 init_local_fwd(); 1018 ssh_init_forwarding();
1021 1019
1022 /* If requested, let ssh continue in the background. */ 1020 /* If requested, let ssh continue in the background. */
1023 if (fork_after_authentication_flag) 1021 if (fork_after_authentication_flag)
@@ -1036,7 +1034,28 @@ ssh_session2(void)
1036 xstrdup("client-session"), /*nonblock*/0); 1034 xstrdup("client-session"), /*nonblock*/0);
1037 1035
1038 channel_open(id); 1036 channel_open(id);
1039 channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, client_init, (void *)0); 1037 channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION,
1038 ssh_session2_callback, (void *)0);
1040 1039
1041 return client_loop(tty_flag, tty_flag ? options.escape_char : -1, id); 1040 return client_loop(tty_flag, tty_flag ? options.escape_char : -1, id);
1042} 1041}
1042
1043int
1044guess_identity_file_type(const char *filename)
1045{
1046 struct stat st;
1047 Key *public;
1048 int type = KEY_RSA1; /* default */
1049
1050 if (stat(filename, &st) < 0) {
1051 perror(filename);
1052 return KEY_UNSPEC;
1053 }
1054 public = key_new(type);
1055 if (!load_public_key(filename, public, NULL)) {
1056 /* ok, so we will assume this is 'some' key */
1057 type = KEY_UNSPEC;
1058 }
1059 key_free(public);
1060 return type;
1061}
diff --git a/ssh_config b/ssh_config
index cb360d04b..fdac1313c 100644
--- a/ssh_config
+++ b/ssh_config
@@ -13,9 +13,9 @@
13# Site-wide defaults for various options 13# Site-wide defaults for various options
14 14
15# Host * 15# Host *
16# ForwardAgent yes 16# ForwardAgent no
17# ForwardX11 yes 17# ForwardX11 no
18# RhostsAuthentication yes 18# RhostsAuthentication no
19# RhostsRSAAuthentication yes 19# RhostsRSAAuthentication yes
20# RSAAuthentication yes 20# RSAAuthentication yes
21# PasswordAuthentication yes 21# PasswordAuthentication yes
@@ -23,9 +23,12 @@
23# UseRsh no 23# UseRsh no
24# BatchMode no 24# BatchMode no
25# CheckHostIP yes 25# CheckHostIP yes
26# StrictHostKeyChecking no 26# StrictHostKeyChecking yes
27# IdentityFile ~/.ssh/identity 27# IdentityFile ~/.ssh/identity
28# IdentityFile ~/.ssh/id_dsa
29# IdentityFile ~/.ssh/id_rsa1
30# IdentityFile ~/.ssh/id_rsa2
28# Port 22 31# Port 22
29# Protocol 2,1 32# Protocol 1,2
30# Cipher blowfish 33# Cipher blowfish
31# EscapeChar ~ 34# EscapeChar ~
diff --git a/sshconnect.c b/sshconnect.c
index d6072b36c..12ca69fd6 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.79 2000/09/17 15:52:51 markus Exp $"); 16RCSID("$OpenBSD: sshconnect.c,v 1.81 2000/11/06 23:16:35 markus Exp $");
17 17
18#include <openssl/bn.h> 18#include <openssl/bn.h>
19#include <openssl/dsa.h> 19#include <openssl/dsa.h>
@@ -249,9 +249,9 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
249 /* Create a socket for connecting. */ 249 /* Create a socket for connecting. */
250 sock = ssh_create_socket(original_real_uid, 250 sock = ssh_create_socket(original_real_uid,
251#ifdef HAVE_CYGWIN 251#ifdef HAVE_CYGWIN
252 !anonymous && port < IPPORT_RESERVED, 252 !anonymous,
253#else 253#else
254 !anonymous && geteuid() == 0 && port < IPPORT_RESERVED, 254 !anonymous && geteuid() == 0,
255#endif 255#endif
256 ai->ai_family); 256 ai->ai_family);
257 if (sock < 0) 257 if (sock < 0)
@@ -321,6 +321,7 @@ ssh_exchange_identification()
321 int remote_major, remote_minor, i, mismatch; 321 int remote_major, remote_minor, i, mismatch;
322 int connection_in = packet_get_connection_in(); 322 int connection_in = packet_get_connection_in();
323 int connection_out = packet_get_connection_out(); 323 int connection_out = packet_get_connection_out();
324 int minor1 = PROTOCOL_MINOR_1;
324 325
325 /* Read other side\'s version identification. */ 326 /* Read other side\'s version identification. */
326 for (;;) { 327 for (;;) {
@@ -374,9 +375,10 @@ ssh_exchange_identification()
374 } 375 }
375 if (remote_minor < 3) { 376 if (remote_minor < 3) {
376 fatal("Remote machine has too old SSH software version."); 377 fatal("Remote machine has too old SSH software version.");
377 } else if (remote_minor == 3) { 378 } else if (remote_minor == 3 || remote_minor == 4) {
378 /* We speak 1.3, too. */ 379 /* We speak 1.3, too. */
379 enable_compat13(); 380 enable_compat13();
381 minor1 = 3;
380 if (options.forward_agent) { 382 if (options.forward_agent) {
381 log("Agent forwarding disabled for protocol 1.3"); 383 log("Agent forwarding disabled for protocol 1.3");
382 options.forward_agent = 0; 384 options.forward_agent = 0;
@@ -402,7 +404,7 @@ ssh_exchange_identification()
402 /* Send our own protocol version identification. */ 404 /* Send our own protocol version identification. */
403 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", 405 snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
404 compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, 406 compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
405 compat20 ? PROTOCOL_MINOR_2 : PROTOCOL_MINOR_1, 407 compat20 ? PROTOCOL_MINOR_2 : minor1,
406 SSH_VERSION); 408 SSH_VERSION);
407 if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf)) 409 if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))
408 fatal("write: %.100s", strerror(errno)); 410 fatal("write: %.100s", strerror(errno));
diff --git a/sshconnect1.c b/sshconnect1.c
index ce560791c..227e10b4b 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.8 2000/10/12 09:59:19 markus Exp $"); 16RCSID("$OpenBSD: sshconnect1.c,v 1.9 2000/11/12 19:50:38 markus Exp $");
17 17
18#include <openssl/bn.h> 18#include <openssl/bn.h>
19#include <openssl/dsa.h> 19#include <openssl/dsa.h>
@@ -62,7 +62,7 @@ try_agent_authentication()
62 return 0; 62 return 0;
63 63
64 challenge = BN_new(); 64 challenge = BN_new();
65 key = key_new(KEY_RSA); 65 key = key_new(KEY_RSA1);
66 66
67 /* Loop through identities served by the agent. */ 67 /* Loop through identities served by the agent. */
68 for (key = ssh_get_first_identity(auth, &comment, 1); 68 for (key = ssh_get_first_identity(auth, &comment, 1);
@@ -196,7 +196,7 @@ try_rsa_authentication(const char *authfile)
196 int plen, clen; 196 int plen, clen;
197 197
198 /* Try to load identification for the authentication key. */ 198 /* Try to load identification for the authentication key. */
199 public = key_new(KEY_RSA); 199 public = key_new(KEY_RSA1);
200 if (!load_public_key(authfile, public, &comment)) { 200 if (!load_public_key(authfile, public, &comment)) {
201 key_free(public); 201 key_free(public);
202 /* Could not load it. Fail. */ 202 /* Could not load it. Fail. */
@@ -237,7 +237,7 @@ try_rsa_authentication(const char *authfile)
237 237
238 debug("Received RSA challenge from server."); 238 debug("Received RSA challenge from server.");
239 239
240 private = key_new(KEY_RSA); 240 private = key_new(KEY_RSA1);
241 /* 241 /*
242 * Load the private key. Try first with empty passphrase; if it 242 * Load the private key. Try first with empty passphrase; if it
243 * fails, ask for a passphrase. 243 * fails, ask for a passphrase.
@@ -760,7 +760,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
760 packet_integrity_check(payload_len, 760 packet_integrity_check(payload_len,
761 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4, 761 8 + 4 + sum_len + 0 + 4 + 0 + 0 + 4 + 4 + 4,
762 SSH_SMSG_PUBLIC_KEY); 762 SSH_SMSG_PUBLIC_KEY);
763 k.type = KEY_RSA; 763 k.type = KEY_RSA1;
764 k.rsa = host_key; 764 k.rsa = host_key;
765 check_host_key(host, hostaddr, &k, 765 check_host_key(host, hostaddr, &k,
766 options.user_hostfile, options.system_hostfile); 766 options.user_hostfile, options.system_hostfile);
@@ -994,7 +994,8 @@ ssh_userauth(
994 994
995 /* Try RSA authentication for each identity. */ 995 /* Try RSA authentication for each identity. */
996 for (i = 0; i < options.num_identity_files; i++) 996 for (i = 0; i < options.num_identity_files; i++)
997 if (try_rsa_authentication(options.identity_files[i])) 997 if (options.identity_files_type[i] == KEY_RSA1 &&
998 try_rsa_authentication(options.identity_files[i]))
998 return; 999 return;
999 } 1000 }
1000 /* Try skey authentication if the server supports it. */ 1001 /* Try skey authentication if the server supports it. */
diff --git a/sshconnect2.c b/sshconnect2.c
index 6ba23d445..bb4774aa4 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.27 2000/10/19 16:45:16 provos Exp $"); 26RCSID("$OpenBSD: sshconnect2.c,v 1.28 2000/11/12 19:50:38 markus Exp $");
27 27
28#include <openssl/bn.h> 28#include <openssl/bn.h>
29#include <openssl/rsa.h> 29#include <openssl/rsa.h>
@@ -45,7 +45,6 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.27 2000/10/19 16:45:16 provos Exp $");
45#include "kex.h" 45#include "kex.h"
46#include "myproposal.h" 46#include "myproposal.h"
47#include "key.h" 47#include "key.h"
48#include "dsa.h"
49#include "sshconnect.h" 48#include "sshconnect.h"
50#include "authfile.h" 49#include "authfile.h"
51#include "cli.h" 50#include "cli.h"
@@ -196,7 +195,7 @@ ssh_dh1_client(Kex *kex, char *host, struct sockaddr *hostaddr,
196 195
197 /* key, cert */ 196 /* key, cert */
198 server_host_key_blob = packet_get_string(&sbloblen); 197 server_host_key_blob = packet_get_string(&sbloblen);
199 server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen); 198 server_host_key = key_from_blob(server_host_key_blob, sbloblen);
200 if (server_host_key == NULL) 199 if (server_host_key == NULL)
201 fatal("cannot decode server_host_key_blob"); 200 fatal("cannot decode server_host_key_blob");
202 201
@@ -258,8 +257,8 @@ ssh_dh1_client(Kex *kex, char *host, struct sockaddr *hostaddr,
258 fprintf(stderr, "%02x", (hash[i])&0xff); 257 fprintf(stderr, "%02x", (hash[i])&0xff);
259 fprintf(stderr, "\n"); 258 fprintf(stderr, "\n");
260#endif 259#endif
261 if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1) 260 if (key_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
262 fatal("dsa_verify failed for server_host_key"); 261 fatal("key_verify failed for server_host_key");
263 key_free(server_host_key); 262 key_free(server_host_key);
264 263
265 kex_derive_keys(kex, hash, shared_secret); 264 kex_derive_keys(kex, hash, shared_secret);
@@ -366,7 +365,7 @@ ssh_dhgex_client(Kex *kex, char *host, struct sockaddr *hostaddr,
366 365
367 /* key, cert */ 366 /* key, cert */
368 server_host_key_blob = packet_get_string(&sbloblen); 367 server_host_key_blob = packet_get_string(&sbloblen);
369 server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen); 368 server_host_key = key_from_blob(server_host_key_blob, sbloblen);
370 if (server_host_key == NULL) 369 if (server_host_key == NULL)
371 fatal("cannot decode server_host_key_blob"); 370 fatal("cannot decode server_host_key_blob");
372 371
@@ -429,8 +428,8 @@ ssh_dhgex_client(Kex *kex, char *host, struct sockaddr *hostaddr,
429 fprintf(stderr, "%02x", (hash[i])&0xff); 428 fprintf(stderr, "%02x", (hash[i])&0xff);
430 fprintf(stderr, "\n"); 429 fprintf(stderr, "\n");
431#endif 430#endif
432 if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1) 431 if (key_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
433 fatal("dsa_verify failed for server_host_key"); 432 fatal("key_verify failed for server_host_key");
434 key_free(server_host_key); 433 key_free(server_host_key);
435 434
436 kex_derive_keys(kex, hash, shared_secret); 435 kex_derive_keys(kex, hash, shared_secret);
@@ -485,7 +484,7 @@ Authmethod *authmethod_lookup(const char *name);
485Authmethod authmethods[] = { 484Authmethod authmethods[] = {
486 {"publickey", 485 {"publickey",
487 userauth_pubkey, 486 userauth_pubkey,
488 &options.dsa_authentication, 487 &options.pubkey_authentication,
489 NULL}, 488 NULL},
490 {"password", 489 {"password",
491 userauth_passwd, 490 userauth_passwd,
@@ -653,8 +652,10 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
653 int ret = -1; 652 int ret = -1;
654 int have_sig = 1; 653 int have_sig = 1;
655 654
656 dsa_make_key_blob(k, &blob, &bloblen); 655 if (key_to_blob(k, &blob, &bloblen) == 0) {
657 656 /* we cannot handle this key */
657 return 0;
658 }
658 /* data to be signed */ 659 /* data to be signed */
659 buffer_init(&b); 660 buffer_init(&b);
660 if (datafellows & SSH_OLD_SESSIONID) { 661 if (datafellows & SSH_OLD_SESSIONID) {
@@ -672,7 +673,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
672 authctxt->service); 673 authctxt->service);
673 buffer_put_cstring(&b, authctxt->method->name); 674 buffer_put_cstring(&b, authctxt->method->name);
674 buffer_put_char(&b, have_sig); 675 buffer_put_char(&b, have_sig);
675 buffer_put_cstring(&b, KEX_DSS); 676 buffer_put_cstring(&b, key_ssh_name(k));
676 buffer_put_string(&b, blob, bloblen); 677 buffer_put_string(&b, blob, bloblen);
677 678
678 /* generate signature */ 679 /* generate signature */
@@ -682,7 +683,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
682 buffer_free(&b); 683 buffer_free(&b);
683 return 0; 684 return 0;
684 } 685 }
685#ifdef DEBUG_DSS 686#ifdef DEBUG_PK
686 buffer_dump(&b); 687 buffer_dump(&b);
687#endif 688#endif
688 if (datafellows & SSH_BUG_PUBKEYAUTH) { 689 if (datafellows & SSH_BUG_PUBKEYAUTH) {
@@ -693,7 +694,7 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
693 buffer_put_cstring(&b, authctxt->service); 694 buffer_put_cstring(&b, authctxt->service);
694 buffer_put_cstring(&b, authctxt->method->name); 695 buffer_put_cstring(&b, authctxt->method->name);
695 buffer_put_char(&b, have_sig); 696 buffer_put_char(&b, have_sig);
696 buffer_put_cstring(&b, KEX_DSS); 697 buffer_put_cstring(&b, key_ssh_name(k));
697 buffer_put_string(&b, blob, bloblen); 698 buffer_put_string(&b, blob, bloblen);
698 } 699 }
699 xfree(blob); 700 xfree(blob);
@@ -719,10 +720,10 @@ sign_and_send_pubkey(Authctxt *authctxt, Key *k, sign_cb_fn *sign_callback)
719} 720}
720 721
721/* sign callback */ 722/* sign callback */
722int dsa_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp, 723int key_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,
723 unsigned char *data, int datalen) 724 unsigned char *data, int datalen)
724{ 725{
725 return dsa_sign(key, sigp, lenp, data, datalen); 726 return key_sign(key, sigp, lenp, data, datalen);
726} 727}
727 728
728int 729int
@@ -738,14 +739,13 @@ userauth_pubkey_identity(Authctxt *authctxt, char *filename)
738 } 739 }
739 debug("try pubkey: %s", filename); 740 debug("try pubkey: %s", filename);
740 741
741 k = key_new(KEY_DSA); 742 k = key_new(KEY_UNSPEC);
742 if (!load_private_key(filename, "", k, NULL)) { 743 if (!load_private_key(filename, "", k, NULL)) {
743 int success = 0; 744 int success = 0;
744 char *passphrase; 745 char *passphrase;
745 char prompt[300]; 746 char prompt[300];
746 snprintf(prompt, sizeof prompt, 747 snprintf(prompt, sizeof prompt,
747 "Enter passphrase for %s key '%.100s': ", 748 "Enter passphrase for key '%.100s': ", filename);
748 key_type(k), filename);
749 for (i = 0; i < options.number_of_password_prompts; i++) { 749 for (i = 0; i < options.number_of_password_prompts; i++) {
750 passphrase = read_passphrase(prompt, 0); 750 passphrase = read_passphrase(prompt, 0);
751 if (strcmp(passphrase, "") != 0) { 751 if (strcmp(passphrase, "") != 0) {
@@ -766,7 +766,7 @@ userauth_pubkey_identity(Authctxt *authctxt, char *filename)
766 return 0; 766 return 0;
767 } 767 }
768 } 768 }
769 ret = sign_and_send_pubkey(authctxt, k, dsa_sign_cb); 769 ret = sign_and_send_pubkey(authctxt, k, key_sign_cb);
770 key_free(k); 770 key_free(k);
771 return ret; 771 return ret;
772} 772}
@@ -782,24 +782,26 @@ int
782userauth_pubkey_agent(Authctxt *authctxt) 782userauth_pubkey_agent(Authctxt *authctxt)
783{ 783{
784 static int called = 0; 784 static int called = 0;
785 int ret = 0;
785 char *comment; 786 char *comment;
786 Key *k; 787 Key *k;
787 int ret;
788 788
789 if (called == 0) { 789 if (called == 0) {
790 k = ssh_get_first_identity(authctxt->agent, &comment, 2); 790 if (ssh_get_num_identities(authctxt->agent, 2) == 0)
791 debug2("userauth_pubkey_agent: no keys at all");
791 called = 1; 792 called = 1;
792 } else {
793 k = ssh_get_next_identity(authctxt->agent, &comment, 2);
794 } 793 }
794 k = ssh_get_next_identity(authctxt->agent, &comment, 2);
795 if (k == NULL) { 795 if (k == NULL) {
796 debug2("no more DSA keys from agent"); 796 debug2("userauth_pubkey_agent: no more keys");
797 return 0; 797 } else {
798 debug("userauth_pubkey_agent: trying agent key %s", comment);
799 xfree(comment);
800 ret = sign_and_send_pubkey(authctxt, k, agent_sign_cb);
801 key_free(k);
798 } 802 }
799 debug("trying DSA agent key %s", comment); 803 if (ret == 0)
800 xfree(comment); 804 debug2("userauth_pubkey_agent: no message sent");
801 ret = sign_and_send_pubkey(authctxt, k, agent_sign_cb);
802 key_free(k);
803 return ret; 805 return ret;
804} 806}
805 807
@@ -809,10 +811,17 @@ userauth_pubkey(Authctxt *authctxt)
809 static int idx = 0; 811 static int idx = 0;
810 int sent = 0; 812 int sent = 0;
811 813
812 if (authctxt->agent != NULL) 814 if (authctxt->agent != NULL) {
813 sent = userauth_pubkey_agent(authctxt); 815 do {
814 while (sent == 0 && idx < options.num_identity_files2) 816 sent = userauth_pubkey_agent(authctxt);
815 sent = userauth_pubkey_identity(authctxt, options.identity_files2[idx++]); 817 } while(!sent && authctxt->agent->howmany > 0);
818 }
819 while (!sent && idx < options.num_identity_files) {
820 if (options.identity_files_type[idx] != KEY_RSA1)
821 sent = userauth_pubkey_identity(authctxt,
822 options.identity_files[idx]);
823 idx++;
824 }
816 return sent; 825 return sent;
817} 826}
818 827
diff --git a/sshd.8 b/sshd.8
index e53eebe82..823282018 100644
--- a/sshd.8
+++ b/sshd.8
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: sshd.8,v 1.70 2000/10/16 09:38:44 djm Exp $ 37.\" $OpenBSD: sshd.8,v 1.72 2000/11/12 19:50:38 markus Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSHD 8 39.Dt SSHD 8
40.Os 40.Os
@@ -144,7 +144,7 @@ through a cryptographic message authentication code
144(hmac-sha1 or hmac-md5). 144(hmac-sha1 or hmac-md5).
145.Pp 145.Pp
146Protocol version 2 provides a public key based 146Protocol version 2 provides a public key based
147user authentication method (DSAAuthentication) 147user authentication method (PubkeyAuthentication)
148and conventional password authentication. 148and conventional password authentication.
149.Pp 149.Pp
150.Ss Command execution and data forwarding 150.Ss Command execution and data forwarding
@@ -359,8 +359,8 @@ and
359can be used as wildcards in the patterns. 359can be used as wildcards in the patterns.
360Only user names are valid; a numerical user ID isn't recognized. 360Only user names are valid; a numerical user ID isn't recognized.
361By default login is allowed regardless of the user name. 361By default login is allowed regardless of the user name.
362.It Cm DSAAuthentication 362.It Cm PubkeyAuthentication
363Specifies whether DSA authentication is allowed. 363Specifies whether public key authentication is allowed.
364The default is 364The default is
365.Dq yes . 365.Dq yes .
366Note that this option applies to protocol version 2 only. 366Note that this option applies to protocol version 2 only.
@@ -373,20 +373,20 @@ or
373.Dq no . 373.Dq no .
374The default is 374The default is
375.Dq no . 375.Dq no .
376.It Cm HostDSAKey
377Specifies the file containing the private DSA host key (default
378.Pa /etc/ssh_host_dsa_key )
379used by SSH protocol 2.0.
380Note that
381.Nm
382disables protocol 2.0 if this file is group/world-accessible.
383.It Cm HostKey 376.It Cm HostKey
384Specifies the file containing the private RSA host key (default 377Specifies the file containing the private host keys (default
385.Pa /etc/ssh_host_key ) 378.Pa /etc/ssh_host_key )
386used by SSH protocols 1.3 and 1.5. 379used by SSH protocol versions 1 and 2.
387Note that 380Note that
388.Nm 381.Nm
389disables protocols 1.3 and 1.5 if this file is group/world-accessible. 382if this file is group/world-accessible.
383It is possible to have multiple host key files.
384.Dq rsa1
385keys are used for version 1 and
386.Dq dsa
387or
388.Dq rsa
389are used for version 2 of the SSH protocol.
390.It Cm IgnoreRhosts 390.It Cm IgnoreRhosts
391Specifies that 391Specifies that
392.Pa .rhosts 392.Pa .rhosts
@@ -1039,7 +1039,7 @@ This can be used to specify
1039machine-specific login-time initializations globally. 1039machine-specific login-time initializations globally.
1040This file should be writable only by root, and should be world-readable. 1040This file should be writable only by root, and should be world-readable.
1041.El 1041.El
1042.Sh AUTHOR 1042.Sh AUTHORS
1043OpenSSH 1043OpenSSH
1044is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen, 1044is a derivative of the original (free) ssh 1.2.12 release by Tatu Ylonen,
1045but with bugs removed and newer features re-added. 1045but with bugs removed and newer features re-added.
diff --git a/sshd.c b/sshd.c
index e5c2508a1..56a39bd01 100644
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: sshd.c,v 1.132 2000/10/13 18:34:46 markus Exp $"); 43RCSID("$OpenBSD: sshd.c,v 1.134 2000/11/12 19:50:38 markus Exp $");
44 44
45#include "xmalloc.h" 45#include "xmalloc.h"
46#include "rsa.h" 46#include "rsa.h"
@@ -61,7 +61,6 @@ RCSID("$OpenBSD: sshd.c,v 1.132 2000/10/13 18:34:46 markus Exp $");
61#include <openssl/dsa.h> 61#include <openssl/dsa.h>
62#include <openssl/rsa.h> 62#include <openssl/rsa.h>
63#include "key.h" 63#include "key.h"
64#include "dsa.h"
65#include "dh.h" 64#include "dh.h"
66 65
67#include "auth.h" 66#include "auth.h"
@@ -140,9 +139,11 @@ char *server_version_string = NULL;
140 * not very useful. Currently, memory locking is not implemented. 139 * not very useful. Currently, memory locking is not implemented.
141 */ 140 */
142struct { 141struct {
143 RSA *private_key; /* Private part of empheral server key. */ 142 Key *server_key; /* empheral server key */
144 RSA *host_key; /* Private part of host key. */ 143 Key *ssh1_host_key; /* ssh1 host key */
145 Key *dsa_host_key; /* Private DSA host key. */ 144 Key **host_keys; /* all private host keys */
145 int have_ssh1_key;
146 int have_ssh2_key;
146} sensitive_data; 147} sensitive_data;
147 148
148/* 149/*
@@ -154,10 +155,6 @@ int key_used = 0;
154/* This is set to true when SIGHUP is received. */ 155/* This is set to true when SIGHUP is received. */
155int received_sighup = 0; 156int received_sighup = 0;
156 157
157/* Public side of the server key. This value is regenerated regularly with
158 the private key. */
159RSA *public_key;
160
161/* session identifier, used by RSA-auth */ 158/* session identifier, used by RSA-auth */
162unsigned char session_id[16]; 159unsigned char session_id[16];
163 160
@@ -266,6 +263,17 @@ grace_alarm_handler(int sig)
266 */ 263 */
267/* XXX do we really want this work to be done in a signal handler ? -m */ 264/* XXX do we really want this work to be done in a signal handler ? -m */
268void 265void
266generate_empheral_server_key(void)
267{
268 log("Generating %s%d bit RSA key.", sensitive_data.server_key ? "new " : "",
269 options.server_key_bits);
270 if (sensitive_data.server_key != NULL)
271 key_free(sensitive_data.server_key);
272 sensitive_data.server_key = key_generate(KEY_RSA1, options.server_key_bits);
273 arc4random_stir();
274 log("RSA key generation complete.");
275}
276void
269key_regeneration_alarm(int sig) 277key_regeneration_alarm(int sig)
270{ 278{
271 int save_errno = errno; 279 int save_errno = errno;
@@ -273,21 +281,8 @@ key_regeneration_alarm(int sig)
273 /* Check if we should generate a new key. */ 281 /* Check if we should generate a new key. */
274 if (key_used) { 282 if (key_used) {
275 /* This should really be done in the background. */ 283 /* This should really be done in the background. */
276 log("Generating new %d bit RSA key.", options.server_key_bits); 284 generate_empheral_server_key();
277
278 if (sensitive_data.private_key != NULL)
279 RSA_free(sensitive_data.private_key);
280 sensitive_data.private_key = RSA_new();
281
282 if (public_key != NULL)
283 RSA_free(public_key);
284 public_key = RSA_new();
285
286 rsa_generate_key(sensitive_data.private_key, public_key,
287 options.server_key_bits);
288 arc4random_stir();
289 key_used = 0; 285 key_used = 0;
290 log("RSA key generation complete.");
291 } 286 }
292 /* Reschedule the alarm. */ 287 /* Reschedule the alarm. */
293 signal(SIGALRM, key_regeneration_alarm); 288 signal(SIGALRM, key_regeneration_alarm);
@@ -422,18 +417,93 @@ sshd_exchange_identification(int sock_in, int sock_out)
422} 417}
423 418
424 419
420/* Destroy the host and server keys. They will no longer be needed. */
425void 421void
426destroy_sensitive_data(void) 422destroy_sensitive_data(void)
427{ 423{
428 /* Destroy the private and public keys. They will no longer be needed. */ 424 int i;
429 if (public_key) 425
430 RSA_free(public_key); 426 if (sensitive_data.server_key) {
431 if (sensitive_data.private_key) 427 key_free(sensitive_data.server_key);
432 RSA_free(sensitive_data.private_key); 428 sensitive_data.server_key = NULL;
433 if (sensitive_data.host_key) 429 }
434 RSA_free(sensitive_data.host_key); 430 for(i = 0; i < options.num_host_key_files; i++) {
435 if (sensitive_data.dsa_host_key != NULL) 431 if (sensitive_data.host_keys[i]) {
436 key_free(sensitive_data.dsa_host_key); 432 key_free(sensitive_data.host_keys[i]);
433 sensitive_data.host_keys[i] = NULL;
434 }
435 }
436 sensitive_data.ssh1_host_key = NULL;
437}
438Key *
439load_private_key_autodetect(const char *filename)
440{
441 struct stat st;
442 int type;
443 Key *public, *private;
444
445 if (stat(filename, &st) < 0) {
446 perror(filename);
447 return NULL;
448 }
449 /*
450 * try to load the public key. right now this only works for RSA1,
451 * since SSH2 keys are fully encrypted
452 */
453 type = KEY_RSA1;
454 public = key_new(type);
455 if (!load_public_key(filename, public, NULL)) {
456 /* ok, so we will assume this is 'some' key */
457 type = KEY_UNSPEC;
458 }
459 key_free(public);
460
461 /* Ok, try key with empty passphrase */
462 private = key_new(type);
463 if (load_private_key(filename, "", private, NULL)) {
464 debug("load_private_key_autodetect: type %d %s",
465 private->type, key_type(private));
466 return private;
467 }
468 key_free(private);
469 return NULL;
470}
471
472char *
473list_hostkey_types(void)
474{
475 static char buf[1024];
476 int i;
477 buf[0] = '\0';
478 for(i = 0; i < options.num_host_key_files; i++) {
479 Key *key = sensitive_data.host_keys[i];
480 if (key == NULL)
481 continue;
482 switch(key->type) {
483 case KEY_RSA:
484 case KEY_DSA:
485 strlcat(buf, key_ssh_name(key), sizeof buf);
486 strlcat(buf, ",", sizeof buf);
487 break;
488 }
489 }
490 i = strlen(buf);
491 if (i > 0 && buf[i-1] == ',')
492 buf[i-1] = '\0';
493 debug("list_hostkey_types: %s", buf);
494 return buf;
495}
496
497Key *
498get_hostkey_by_type(int type)
499{
500 int i;
501 for(i = 0; i < options.num_host_key_files; i++) {
502 Key *key = sensitive_data.host_keys[i];
503 if (key != NULL && key->type == type)
504 return key;
505 }
506 return NULL;
437} 507}
438 508
439/* 509/*
@@ -555,7 +625,11 @@ main(int ac, char **av)
555 options.key_regeneration_time = atoi(optarg); 625 options.key_regeneration_time = atoi(optarg);
556 break; 626 break;
557 case 'h': 627 case 'h':
558 options.host_key_file = optarg; 628 if (options.num_host_key_files >= MAX_HOSTKEYS) {
629 fprintf(stderr, "too many host keys.\n");
630 exit(1);
631 }
632 options.host_key_files[options.num_host_key_files++] = optarg;
559 break; 633 break;
560 case 'V': 634 case 'V':
561 client_version_string = optarg; 635 client_version_string = optarg;
@@ -610,39 +684,39 @@ main(int ac, char **av)
610 684
611 debug("sshd version %.100s", SSH_VERSION); 685 debug("sshd version %.100s", SSH_VERSION);
612 686
613 sensitive_data.dsa_host_key = NULL; 687 /* load private host keys */
614 sensitive_data.host_key = NULL; 688 sensitive_data.host_keys = xmalloc(options.num_host_key_files*sizeof(Key*));
689 sensitive_data.server_key = NULL;
690 sensitive_data.ssh1_host_key = NULL;
691 sensitive_data.have_ssh1_key = 0;
692 sensitive_data.have_ssh2_key = 0;
615 693
616 /* check if RSA support exists */ 694 for(i = 0; i < options.num_host_key_files; i++) {
617 if ((options.protocol & SSH_PROTO_1) && 695 Key *key = load_private_key_autodetect(options.host_key_files[i]);
618 rsa_alive() == 0) { 696 if (key == NULL) {
619 log("no RSA support in libssl and libcrypto. See ssl(8)");
620 log("Disabling protocol version 1");
621 options.protocol &= ~SSH_PROTO_1;
622 }
623 /* Load the RSA/DSA host key. It must have empty passphrase. */
624 if (options.protocol & SSH_PROTO_1) {
625 Key k;
626 sensitive_data.host_key = RSA_new();
627 k.type = KEY_RSA;
628 k.rsa = sensitive_data.host_key;
629 errno = 0;
630 if (!load_private_key(options.host_key_file, "", &k, NULL)) {
631 error("Could not load host key: %.200s: %.100s", 697 error("Could not load host key: %.200s: %.100s",
632 options.host_key_file, strerror(errno)); 698 options.host_key_files[i], strerror(errno));
633 log("Disabling protocol version 1"); 699 continue;
634 options.protocol &= ~SSH_PROTO_1;
635 } 700 }
636 k.rsa = NULL; 701 switch(key->type){
637 } 702 case KEY_RSA1:
638 if (options.protocol & SSH_PROTO_2) { 703 sensitive_data.ssh1_host_key = key;
639 sensitive_data.dsa_host_key = key_new(KEY_DSA); 704 sensitive_data.have_ssh1_key = 1;
640 if (!load_private_key(options.host_dsa_key_file, "", sensitive_data.dsa_host_key, NULL)) { 705 break;
641 706 case KEY_RSA:
642 error("Could not load DSA host key: %.200s", options.host_dsa_key_file); 707 case KEY_DSA:
643 log("Disabling protocol version 2"); 708 sensitive_data.have_ssh2_key = 1;
644 options.protocol &= ~SSH_PROTO_2; 709 break;
645 } 710 }
711 sensitive_data.host_keys[i] = key;
712 }
713 if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) {
714 log("Disabling protocol version 1. Could not load host key");
715 options.protocol &= ~SSH_PROTO_1;
716 }
717 if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
718 log("Disabling protocol version 2. Could not load host key");
719 options.protocol &= ~SSH_PROTO_2;
646 } 720 }
647 if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) { 721 if (! options.protocol & (SSH_PROTO_1|SSH_PROTO_2)) {
648 if (silent == 0) 722 if (silent == 0)
@@ -664,11 +738,11 @@ main(int ac, char **av)
664 * hate software patents. I dont know if this can go? Niels 738 * hate software patents. I dont know if this can go? Niels
665 */ 739 */
666 if (options.server_key_bits > 740 if (options.server_key_bits >
667 BN_num_bits(sensitive_data.host_key->n) - SSH_KEY_BITS_RESERVED && 741 BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) - SSH_KEY_BITS_RESERVED &&
668 options.server_key_bits < 742 options.server_key_bits <
669 BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) { 743 BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
670 options.server_key_bits = 744 options.server_key_bits =
671 BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED; 745 BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED;
672 debug("Forcing server key to %d bits to make it differ from host key.", 746 debug("Forcing server key to %d bits to make it differ from host key.",
673 options.server_key_bits); 747 options.server_key_bits);
674 } 748 }
@@ -707,9 +781,6 @@ main(int ac, char **av)
707 /* Reinitialize the log (because of the fork above). */ 781 /* Reinitialize the log (because of the fork above). */
708 log_init(av0, options.log_level, options.log_facility, log_stderr); 782 log_init(av0, options.log_level, options.log_facility, log_stderr);
709 783
710 /* Do not display messages to stdout in RSA code. */
711 rsa_set_verbose(0);
712
713 /* Initialize the random number generator. */ 784 /* Initialize the random number generator. */
714 arc4random_stir(); 785 arc4random_stir();
715 786
@@ -731,16 +802,8 @@ main(int ac, char **av)
731 * ttyfd happens to be one of those. 802 * ttyfd happens to be one of those.
732 */ 803 */
733 debug("inetd sockets after dupping: %d, %d", sock_in, sock_out); 804 debug("inetd sockets after dupping: %d, %d", sock_in, sock_out);
734 805 if (options.protocol & SSH_PROTO_1)
735 if (options.protocol & SSH_PROTO_1) { 806 generate_empheral_server_key();
736 public_key = RSA_new();
737 sensitive_data.private_key = RSA_new();
738 log("Generating %d bit RSA key.", options.server_key_bits);
739 rsa_generate_key(sensitive_data.private_key, public_key,
740 options.server_key_bits);
741 arc4random_stir();
742 log("RSA key generation complete.");
743 }
744 } else { 807 } else {
745 for (ai = options.listen_addrs; ai; ai = ai->ai_next) { 808 for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
746 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) 809 if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
@@ -818,14 +881,7 @@ main(int ac, char **av)
818 } 881 }
819 } 882 }
820 if (options.protocol & SSH_PROTO_1) { 883 if (options.protocol & SSH_PROTO_1) {
821 public_key = RSA_new(); 884 generate_empheral_server_key();
822 sensitive_data.private_key = RSA_new();
823
824 log("Generating %d bit RSA key.", options.server_key_bits);
825 rsa_generate_key(sensitive_data.private_key, public_key,
826 options.server_key_bits);
827 arc4random_stir();
828 log("RSA key generation complete.");
829 885
830 /* Schedule server key regeneration alarm. */ 886 /* Schedule server key regeneration alarm. */
831 signal(SIGALRM, key_regeneration_alarm); 887 signal(SIGALRM, key_regeneration_alarm);
@@ -1065,6 +1121,8 @@ main(int ac, char **av)
1065 */ 1121 */
1066 if (remote_port >= IPPORT_RESERVED || 1122 if (remote_port >= IPPORT_RESERVED ||
1067 remote_port < IPPORT_RESERVED / 2) { 1123 remote_port < IPPORT_RESERVED / 2) {
1124 debug("Rhosts Authentication methods disabled, "
1125 "originating port not trusted.");
1068 options.rhosts_authentication = 0; 1126 options.rhosts_authentication = 0;
1069 options.rhosts_rsa_authentication = 0; 1127 options.rhosts_rsa_authentication = 0;
1070 } 1128 }
@@ -1145,14 +1203,14 @@ do_ssh1_kex()
1145 packet_put_char(cookie[i]); 1203 packet_put_char(cookie[i]);
1146 1204
1147 /* Store our public server RSA key. */ 1205 /* Store our public server RSA key. */
1148 packet_put_int(BN_num_bits(public_key->n)); 1206 packet_put_int(BN_num_bits(sensitive_data.server_key->rsa->n));
1149 packet_put_bignum(public_key->e); 1207 packet_put_bignum(sensitive_data.server_key->rsa->e);
1150 packet_put_bignum(public_key->n); 1208 packet_put_bignum(sensitive_data.server_key->rsa->n);
1151 1209
1152 /* Store our public host RSA key. */ 1210 /* Store our public host RSA key. */
1153 packet_put_int(BN_num_bits(sensitive_data.host_key->n)); 1211 packet_put_int(BN_num_bits(sensitive_data.ssh1_host_key->rsa->n));
1154 packet_put_bignum(sensitive_data.host_key->e); 1212 packet_put_bignum(sensitive_data.ssh1_host_key->rsa->e);
1155 packet_put_bignum(sensitive_data.host_key->n); 1213 packet_put_bignum(sensitive_data.ssh1_host_key->rsa->n);
1156 1214
1157 /* Put protocol flags. */ 1215 /* Put protocol flags. */
1158 packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); 1216 packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
@@ -1190,8 +1248,9 @@ do_ssh1_kex()
1190 packet_send(); 1248 packet_send();
1191 packet_write_wait(); 1249 packet_write_wait();
1192 1250
1193 debug("Sent %d bit public key and %d bit host key.", 1251 debug("Sent %d bit server key and %d bit host key.",
1194 BN_num_bits(public_key->n), BN_num_bits(sensitive_data.host_key->n)); 1252 BN_num_bits(sensitive_data.server_key->rsa->n),
1253 BN_num_bits(sensitive_data.ssh1_host_key->rsa->n));
1195 1254
1196 /* Read clients reply (cipher type and session key). */ 1255 /* Read clients reply (cipher type and session key). */
1197 packet_read_expect(&plen, SSH_CMSG_SESSION_KEY); 1256 packet_read_expect(&plen, SSH_CMSG_SESSION_KEY);
@@ -1223,39 +1282,39 @@ do_ssh1_kex()
1223 * Decrypt it using our private server key and private host key (key 1282 * Decrypt it using our private server key and private host key (key
1224 * with larger modulus first). 1283 * with larger modulus first).
1225 */ 1284 */
1226 if (BN_cmp(sensitive_data.private_key->n, sensitive_data.host_key->n) > 0) { 1285 if (BN_cmp(sensitive_data.server_key->rsa->n, sensitive_data.ssh1_host_key->rsa->n) > 0) {
1227 /* Private key has bigger modulus. */ 1286 /* Private key has bigger modulus. */
1228 if (BN_num_bits(sensitive_data.private_key->n) < 1287 if (BN_num_bits(sensitive_data.server_key->rsa->n) <
1229 BN_num_bits(sensitive_data.host_key->n) + SSH_KEY_BITS_RESERVED) { 1288 BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
1230 fatal("do_connection: %s: private_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", 1289 fatal("do_connection: %s: server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d",
1231 get_remote_ipaddr(), 1290 get_remote_ipaddr(),
1232 BN_num_bits(sensitive_data.private_key->n), 1291 BN_num_bits(sensitive_data.server_key->rsa->n),
1233 BN_num_bits(sensitive_data.host_key->n), 1292 BN_num_bits(sensitive_data.ssh1_host_key->rsa->n),
1234 SSH_KEY_BITS_RESERVED); 1293 SSH_KEY_BITS_RESERVED);
1235 } 1294 }
1236 rsa_private_decrypt(session_key_int, session_key_int, 1295 rsa_private_decrypt(session_key_int, session_key_int,
1237 sensitive_data.private_key); 1296 sensitive_data.server_key->rsa);
1238 rsa_private_decrypt(session_key_int, session_key_int, 1297 rsa_private_decrypt(session_key_int, session_key_int,
1239 sensitive_data.host_key); 1298 sensitive_data.ssh1_host_key->rsa);
1240 } else { 1299 } else {
1241 /* Host key has bigger modulus (or they are equal). */ 1300 /* Host key has bigger modulus (or they are equal). */
1242 if (BN_num_bits(sensitive_data.host_key->n) < 1301 if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) <
1243 BN_num_bits(sensitive_data.private_key->n) + SSH_KEY_BITS_RESERVED) { 1302 BN_num_bits(sensitive_data.server_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
1244 fatal("do_connection: %s: host_key %d < private_key %d + SSH_KEY_BITS_RESERVED %d", 1303 fatal("do_connection: %s: host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d",
1245 get_remote_ipaddr(), 1304 get_remote_ipaddr(),
1246 BN_num_bits(sensitive_data.host_key->n), 1305 BN_num_bits(sensitive_data.ssh1_host_key->rsa->n),
1247 BN_num_bits(sensitive_data.private_key->n), 1306 BN_num_bits(sensitive_data.server_key->rsa->n),
1248 SSH_KEY_BITS_RESERVED); 1307 SSH_KEY_BITS_RESERVED);
1249 } 1308 }
1250 rsa_private_decrypt(session_key_int, session_key_int, 1309 rsa_private_decrypt(session_key_int, session_key_int,
1251 sensitive_data.host_key); 1310 sensitive_data.ssh1_host_key->rsa);
1252 rsa_private_decrypt(session_key_int, session_key_int, 1311 rsa_private_decrypt(session_key_int, session_key_int,
1253 sensitive_data.private_key); 1312 sensitive_data.server_key->rsa);
1254 } 1313 }
1255 1314
1256 compute_session_id(session_id, cookie, 1315 compute_session_id(session_id, cookie,
1257 sensitive_data.host_key->n, 1316 sensitive_data.ssh1_host_key->rsa->n,
1258 sensitive_data.private_key->n); 1317 sensitive_data.server_key->rsa->n);
1259 1318
1260 /* Destroy the private and public keys. They will no longer be needed. */ 1319 /* Destroy the private and public keys. They will no longer be needed. */
1261 destroy_sensitive_data(); 1320 destroy_sensitive_data();
@@ -1269,8 +1328,8 @@ do_ssh1_kex()
1269 len = BN_num_bytes(session_key_int); 1328 len = BN_num_bytes(session_key_int);
1270 if (len < 0 || len > sizeof(session_key)) 1329 if (len < 0 || len > sizeof(session_key))
1271 fatal("do_connection: bad len from %s: session_key_int %d > sizeof(session_key) %d", 1330 fatal("do_connection: bad len from %s: session_key_int %d > sizeof(session_key) %d",
1272 get_remote_ipaddr(), 1331 get_remote_ipaddr(),
1273 len, (int) sizeof(session_key)); 1332 len, sizeof(session_key));
1274 memset(session_key, 0, sizeof(session_key)); 1333 memset(session_key, 0, sizeof(session_key));
1275 BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len); 1334 BN_bn2bin(session_key_int, session_key + sizeof(session_key) - len);
1276 1335
@@ -1314,6 +1373,8 @@ do_ssh2_kex()
1314 myproposal[PROPOSAL_ENC_ALGS_CTOS] = 1373 myproposal[PROPOSAL_ENC_ALGS_CTOS] =
1315 myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; 1374 myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
1316 } 1375 }
1376 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
1377
1317 server_kexinit = kex_init(myproposal); 1378 server_kexinit = kex_init(myproposal);
1318 client_kexinit = xmalloc(sizeof(*client_kexinit)); 1379 client_kexinit = xmalloc(sizeof(*client_kexinit));
1319 buffer_init(client_kexinit); 1380 buffer_init(client_kexinit);
@@ -1379,6 +1440,11 @@ ssh_dh1_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
1379 BIGNUM *shared_secret = 0; 1440 BIGNUM *shared_secret = 0;
1380 DH *dh; 1441 DH *dh;
1381 BIGNUM *dh_client_pub = 0; 1442 BIGNUM *dh_client_pub = 0;
1443 Key *hostkey;
1444
1445 hostkey = get_hostkey_by_type(kex->hostkey_type);
1446 if (hostkey == NULL)
1447 fatal("Unsupported hostkey type %d", kex->hostkey_type);
1382 1448
1383/* KEXDH */ 1449/* KEXDH */
1384 debug("Wait SSH2_MSG_KEXDH_INIT."); 1450 debug("Wait SSH2_MSG_KEXDH_INIT.");
@@ -1431,8 +1497,7 @@ ssh_dh1_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
1431 xfree(kbuf); 1497 xfree(kbuf);
1432 1498
1433 /* XXX precompute? */ 1499 /* XXX precompute? */
1434 dsa_make_key_blob(sensitive_data.dsa_host_key, 1500 key_to_blob(hostkey, &server_host_key_blob, &sbloblen);
1435 &server_host_key_blob, &sbloblen);
1436 1501
1437 /* calc H */ /* XXX depends on 'kex' */ 1502 /* calc H */ /* XXX depends on 'kex' */
1438 hash = kex_hash( 1503 hash = kex_hash(
@@ -1463,7 +1528,7 @@ ssh_dh1_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
1463 1528
1464 /* sign H */ 1529 /* sign H */
1465 /* XXX hashlen depends on KEX */ 1530 /* XXX hashlen depends on KEX */
1466 dsa_sign(sensitive_data.dsa_host_key, &signature, &slen, hash, 20); 1531 key_sign(hostkey, &signature, &slen, hash, 20);
1467 1532
1468 destroy_sensitive_data(); 1533 destroy_sensitive_data();
1469 1534
@@ -1503,6 +1568,11 @@ ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
1503 BIGNUM *shared_secret = 0; 1568 BIGNUM *shared_secret = 0;
1504 DH *dh; 1569 DH *dh;
1505 BIGNUM *dh_client_pub = 0; 1570 BIGNUM *dh_client_pub = 0;
1571 Key *hostkey;
1572
1573 hostkey = get_hostkey_by_type(kex->hostkey_type);
1574 if (hostkey == NULL)
1575 fatal("Unsupported hostkey type %d", kex->hostkey_type);
1506 1576
1507/* KEXDHGEX */ 1577/* KEXDHGEX */
1508 debug("Wait SSH2_MSG_KEX_DH_GEX_REQUEST."); 1578 debug("Wait SSH2_MSG_KEX_DH_GEX_REQUEST.");
@@ -1564,8 +1634,7 @@ ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
1564 xfree(kbuf); 1634 xfree(kbuf);
1565 1635
1566 /* XXX precompute? */ 1636 /* XXX precompute? */
1567 dsa_make_key_blob(sensitive_data.dsa_host_key, 1637 key_to_blob(hostkey, &server_host_key_blob, &sbloblen);
1568 &server_host_key_blob, &sbloblen);
1569 1638
1570 /* calc H */ /* XXX depends on 'kex' */ 1639 /* calc H */ /* XXX depends on 'kex' */
1571 hash = kex_hash_gex( 1640 hash = kex_hash_gex(
@@ -1597,7 +1666,7 @@ ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
1597 1666
1598 /* sign H */ 1667 /* sign H */
1599 /* XXX hashlen depends on KEX */ 1668 /* XXX hashlen depends on KEX */
1600 dsa_sign(sensitive_data.dsa_host_key, &signature, &slen, hash, 20); 1669 key_sign(hostkey, &signature, &slen, hash, 20);
1601 1670
1602 destroy_sensitive_data(); 1671 destroy_sensitive_data();
1603 1672
@@ -1617,4 +1686,3 @@ ssh_dhgex_server(Kex *kex, Buffer *client_kexinit, Buffer *server_kexinit)
1617 /* have keys, free DH */ 1686 /* have keys, free DH */
1618 DH_free(dh); 1687 DH_free(dh);
1619} 1688}
1620
diff --git a/sshd_config b/sshd_config
index 3b88062fa..f368b97ac 100644
--- a/sshd_config
+++ b/sshd_config
@@ -5,6 +5,8 @@ Port 22
5ListenAddress 0.0.0.0 5ListenAddress 0.0.0.0
6#ListenAddress :: 6#ListenAddress ::
7HostKey /etc/ssh_host_key 7HostKey /etc/ssh_host_key
8HostKey /etc/ssh_host_rsa_key
9HostKey /etc/ssh_host_dsa_key
8ServerKeyBits 768 10ServerKeyBits 768
9LoginGraceTime 600 11LoginGraceTime 600
10KeyRegenerationInterval 3600 12KeyRegenerationInterval 3600