- (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/sshconnect2.c b/sshconnect2.c
index 6ba23d4..bb4774a 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.27 2000/10/19 16:45:16 provos Exp $");
+RCSID("$OpenBSD: sshconnect2.c,v 1.28 2000/11/12 19:50:38 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/rsa.h>
@@ -45,7 +45,6 @@
 #include "kex.h"
 #include "myproposal.h"
 #include "key.h"
-#include "dsa.h"
 #include "sshconnect.h"
 #include "authfile.h"
 #include "cli.h"
@@ -196,7 +195,7 @@
 
 	/* key, cert */
 	server_host_key_blob = packet_get_string(&sbloblen);
-	server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen);
+	server_host_key = key_from_blob(server_host_key_blob, sbloblen);
 	if (server_host_key == NULL)
 		fatal("cannot decode server_host_key_blob");
 
@@ -258,8 +257,8 @@
 		fprintf(stderr, "%02x", (hash[i])&0xff);
 	fprintf(stderr, "\n");
 #endif
-	if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
-		fatal("dsa_verify failed for server_host_key");
+	if (key_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
+		fatal("key_verify failed for server_host_key");
 	key_free(server_host_key);
 
 	kex_derive_keys(kex, hash, shared_secret);
@@ -366,7 +365,7 @@
 
 	/* key, cert */
 	server_host_key_blob = packet_get_string(&sbloblen);
-	server_host_key = dsa_key_from_blob(server_host_key_blob, sbloblen);
+	server_host_key = key_from_blob(server_host_key_blob, sbloblen);
 	if (server_host_key == NULL)
 		fatal("cannot decode server_host_key_blob");
 
@@ -429,8 +428,8 @@
 		fprintf(stderr, "%02x", (hash[i])&0xff);
 	fprintf(stderr, "\n");
 #endif
-	if (dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
-		fatal("dsa_verify failed for server_host_key");
+	if (key_verify(server_host_key, (unsigned char *)signature, slen, hash, 20) != 1)
+		fatal("key_verify failed for server_host_key");
 	key_free(server_host_key);
 
 	kex_derive_keys(kex, hash, shared_secret);
@@ -485,7 +484,7 @@
 Authmethod authmethods[] = {
 	{"publickey",
 		userauth_pubkey,
-		&options.dsa_authentication,
+		&options.pubkey_authentication,
 		NULL},
 	{"password",
 		userauth_passwd,
@@ -653,8 +652,10 @@
 	int ret = -1;
 	int have_sig = 1;
 
-	dsa_make_key_blob(k, &blob, &bloblen);
-
+	if (key_to_blob(k, &blob, &bloblen) == 0) {
+		/* we cannot handle this key */
+		return 0;
+	}
 	/* data to be signed */
 	buffer_init(&b);
 	if (datafellows & SSH_OLD_SESSIONID) {
@@ -672,7 +673,7 @@
 	    authctxt->service);
 	buffer_put_cstring(&b, authctxt->method->name);
 	buffer_put_char(&b, have_sig);
-	buffer_put_cstring(&b, KEX_DSS); 
+	buffer_put_cstring(&b, key_ssh_name(k)); 
 	buffer_put_string(&b, blob, bloblen);
 
 	/* generate signature */
@@ -682,7 +683,7 @@
 		buffer_free(&b);
 		return 0;
 	}
-#ifdef DEBUG_DSS
+#ifdef DEBUG_PK
 	buffer_dump(&b);
 #endif
 	if (datafellows & SSH_BUG_PUBKEYAUTH) {
@@ -693,7 +694,7 @@
 		buffer_put_cstring(&b, authctxt->service);
 		buffer_put_cstring(&b, authctxt->method->name);
 		buffer_put_char(&b, have_sig);
-		buffer_put_cstring(&b, KEX_DSS); 
+		buffer_put_cstring(&b, key_ssh_name(k)); 
 		buffer_put_string(&b, blob, bloblen);
 	}
 	xfree(blob);
@@ -719,10 +720,10 @@
 }
 
 /* sign callback */
-int dsa_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,
+int key_sign_cb(Authctxt *authctxt, Key *key, unsigned char **sigp, int *lenp,
     unsigned char *data, int datalen)
 {
-	return dsa_sign(key, sigp, lenp, data, datalen);
+	return key_sign(key, sigp, lenp, data, datalen);
 }
 
 int
@@ -738,14 +739,13 @@
 	}
 	debug("try pubkey: %s", filename);
 
-	k = key_new(KEY_DSA);
+	k = key_new(KEY_UNSPEC);
 	if (!load_private_key(filename, "", k, NULL)) {
 		int success = 0;
 		char *passphrase;
 		char prompt[300];
 		snprintf(prompt, sizeof prompt,
-		     "Enter passphrase for %s key '%.100s': ",
-		     key_type(k), filename);
+		     "Enter passphrase for key '%.100s': ", filename);
 		for (i = 0; i < options.number_of_password_prompts; i++) {
 			passphrase = read_passphrase(prompt, 0);
 			if (strcmp(passphrase, "") != 0) {
@@ -766,7 +766,7 @@
 			return 0;
 		}
 	}
-	ret = sign_and_send_pubkey(authctxt, k, dsa_sign_cb);
+	ret = sign_and_send_pubkey(authctxt, k, key_sign_cb);
 	key_free(k);
 	return ret;
 }
@@ -782,24 +782,26 @@
 userauth_pubkey_agent(Authctxt *authctxt)
 {
 	static int called = 0;
+	int ret = 0;
 	char *comment;
 	Key *k;
-	int ret;
 
 	if (called == 0) {
-		k = ssh_get_first_identity(authctxt->agent, &comment, 2);
+		if (ssh_get_num_identities(authctxt->agent, 2) == 0)
+			debug2("userauth_pubkey_agent: no keys at all");
 		called = 1;
-	} else {
-		k = ssh_get_next_identity(authctxt->agent, &comment, 2);
 	}
+	k = ssh_get_next_identity(authctxt->agent, &comment, 2);
 	if (k == NULL) {
-		debug2("no more DSA keys from agent");
-		return 0;
+		debug2("userauth_pubkey_agent: no more keys");
+	} else {
+		debug("userauth_pubkey_agent: trying agent key %s", comment);
+		xfree(comment);
+		ret = sign_and_send_pubkey(authctxt, k, agent_sign_cb);
+		key_free(k);
 	}
-	debug("trying DSA agent key %s", comment);
-	xfree(comment);
-	ret = sign_and_send_pubkey(authctxt, k, agent_sign_cb);
-	key_free(k);
+	if (ret == 0)
+		debug2("userauth_pubkey_agent: no message sent");
 	return ret;
 }
 
@@ -809,10 +811,17 @@
 	static int idx = 0;
 	int sent = 0;
 
-	if (authctxt->agent != NULL)
-		sent = userauth_pubkey_agent(authctxt);
-	while (sent == 0 && idx < options.num_identity_files2)
-		sent = userauth_pubkey_identity(authctxt, options.identity_files2[idx++]);
+	if (authctxt->agent != NULL) {
+		do {
+			sent = userauth_pubkey_agent(authctxt);
+		} while(!sent && authctxt->agent->howmany > 0);
+	}
+	while (!sent && idx < options.num_identity_files) {
+		if (options.identity_files_type[idx] != KEY_RSA1)
+			sent = userauth_pubkey_identity(authctxt,
+			    options.identity_files[idx]);
+		idx++;
+	}
 	return sent;
 }