- (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
diff --git a/authfd.c b/authfd.c
index d06cc53..9036a8d 100644
--- a/authfd.c
+++ b/authfd.c
@@ -35,7 +35,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: authfd.c,v 1.29 2000/10/09 21:51:00 markus Exp $");
+RCSID("$OpenBSD: authfd.c,v 1.30 2000/11/12 19:50:37 markus Exp $");
 
 #include "ssh.h"
 #include "rsa.h"
@@ -50,7 +50,6 @@
 #include "key.h"
 #include "authfd.h"
 #include "kex.h"
-#include "dsa.h"
 #include "compat.h"
 
 /* helper */
@@ -211,8 +210,8 @@
  * Returns the first authentication identity held by the agent.
  */
 
-Key *
-ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version)
+int
+ssh_get_num_identities(AuthenticationConnection *auth, int version)
 {
 	int type, code1 = 0, code2 = 0;
 	Buffer request;
@@ -227,7 +226,7 @@
 		code2 = SSH2_AGENT_IDENTITIES_ANSWER;
 		break;
 	default:
-		return NULL;
+		return 0;
 	}
 
 	/*
@@ -240,14 +239,14 @@
 	buffer_clear(&auth->identities);
 	if (ssh_request_reply(auth, &request, &auth->identities) == 0) {
 		buffer_free(&request);
-		return NULL;
+		return 0;
 	}
 	buffer_free(&request);
 
 	/* Get message type, and verify that we got a proper answer. */
 	type = buffer_get_char(&auth->identities);
 	if (agent_failed(type)) {
-		return NULL;
+		return 0;
 	} else if (type != code2) {
 		fatal("Bad authentication reply message type: %d", type);
 	}
@@ -258,8 +257,16 @@
 		fatal("Too many identities in authentication reply: %d\n",
 		    auth->howmany);
 
-	/* Return the first entry (if any). */
-	return ssh_get_next_identity(auth, comment, version);
+	return auth->howmany;
+}
+
+Key *
+ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version)
+{
+	/* get number of identities and return the first entry (if any). */
+	if (ssh_get_num_identities(auth, version) > 0)
+		return ssh_get_next_identity(auth, comment, version);
+	return NULL;
 }
 
 Key *
@@ -280,7 +287,7 @@
 	 */
 	switch(version){
 	case 1:
-		key = key_new(KEY_RSA);
+		key = key_new(KEY_RSA1);
 		bits = buffer_get_int(&auth->identities);
 		buffer_get_bignum(&auth->identities, key->rsa->e);
 		buffer_get_bignum(&auth->identities, key->rsa->n);
@@ -292,7 +299,7 @@
 	case 2:
 		blob = buffer_get_string(&auth->identities, &blen);
 		*comment = buffer_get_string(&auth->identities, NULL);
-		key = dsa_key_from_blob(blob, blen);
+		key = key_from_blob(blob, blen);
 		xfree(blob);
 		break;
 	default:
@@ -324,7 +331,7 @@
 	int i;
 	int type;
 
-	if (key->type != KEY_RSA)
+	if (key->type != KEY_RSA1)
 		return 0;
 	if (response_type == 0) {
 		log("Compatibility with ssh protocol version 1.0 no longer supported.");
@@ -376,7 +383,7 @@
 	int type, flags = 0;
 	int ret = -1;
 
-	if (dsa_make_key_blob(key, &blob, &blen) == 0)
+	if (key_to_blob(key, &blob, &blen) == 0)
 		return -1;
 
 	if (datafellows & SSH_BUG_SIGBLOB)
@@ -409,7 +416,7 @@
 /* Encode key for a message to the agent. */
 
 void
-ssh_encode_identity_rsa(Buffer *b, RSA *key, const char *comment)
+ssh_encode_identity_rsa1(Buffer *b, RSA *key, const char *comment)
 {
 	buffer_clear(b);
 	buffer_put_char(b, SSH_AGENTC_ADD_RSA_IDENTITY);
@@ -425,17 +432,29 @@
 }
 
 void
-ssh_encode_identity_dsa(Buffer *b, DSA *key, const char *comment)
+ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
 {
 	buffer_clear(b);
 	buffer_put_char(b, SSH2_AGENTC_ADD_IDENTITY);
-	buffer_put_cstring(b, KEX_DSS);
-	buffer_put_bignum2(b, key->p);
-	buffer_put_bignum2(b, key->q);
-	buffer_put_bignum2(b, key->g);
-	buffer_put_bignum2(b, key->pub_key);
-	buffer_put_bignum2(b, key->priv_key);
-	buffer_put_string(b, comment, strlen(comment));
+	buffer_put_cstring(b, key_ssh_name(key));
+	switch(key->type){
+	case KEY_RSA:
+		buffer_put_bignum2(b, key->rsa->n);
+		buffer_put_bignum2(b, key->rsa->e);
+		buffer_put_bignum2(b, key->rsa->d);
+		buffer_put_bignum2(b, key->rsa->iqmp);
+		buffer_put_bignum2(b, key->rsa->p);
+		buffer_put_bignum2(b, key->rsa->q);
+		break;
+	case KEY_DSA:
+		buffer_put_bignum2(b, key->dsa->p);
+		buffer_put_bignum2(b, key->dsa->q);
+		buffer_put_bignum2(b, key->dsa->g);
+		buffer_put_bignum2(b, key->dsa->pub_key);
+		buffer_put_bignum2(b, key->dsa->priv_key);
+		break;
+	}
+	buffer_put_cstring(b, comment);
 }
 
 /*
@@ -452,11 +471,12 @@
 	buffer_init(&msg);
 
 	switch (key->type) {
-	case KEY_RSA:
-		ssh_encode_identity_rsa(&msg, key->rsa, comment);
+	case KEY_RSA1:
+		ssh_encode_identity_rsa1(&msg, key->rsa, comment);
 		break;
+	case KEY_RSA:
 	case KEY_DSA:
-		ssh_encode_identity_dsa(&msg, key->dsa, comment);
+		ssh_encode_identity_ssh2(&msg, key, comment);
 		break;
 	default:
 		buffer_free(&msg);
@@ -487,13 +507,13 @@
 
 	buffer_init(&msg);
 
-	if (key->type == KEY_RSA) {
+	if (key->type == KEY_RSA1) {
 		buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY);
 		buffer_put_int(&msg, BN_num_bits(key->rsa->n));
 		buffer_put_bignum(&msg, key->rsa->e);
 		buffer_put_bignum(&msg, key->rsa->n);
-	} else if (key->type == KEY_DSA) {
-		dsa_make_key_blob(key, &blob, &blen);
+	} else if (key->type == KEY_DSA || key->type == KEY_RSA) {
+		key_to_blob(key, &blob, &blen);
 		buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY);
 		buffer_put_string(&msg, blob, blen);
 		xfree(blob);