patch to allow client to select rsa/dss

Jon Peatfield J.S.Peatfield at damtp.cam.ac.uk
Mon Mar 12 10:34:50 EST 2001


Here is a quick patch against openssh-2.5.1p1 to add a new config
option (pkalg) for the ssh client allowing the selection of which
public keys are obtained/verified.

--cut-here-
diff -c3 -r orig/openssh-2.5.1p1/key.c openssh-2.5.1p1/key.c
*** orig/openssh-2.5.1p1/key.c	Mon Feb  5 18:16:28 2001
--- openssh-2.5.1p1/key.c	Sun Mar 11 23:10:10 2001
***************
*** 534,539 ****
--- 534,567 ----
  	return KEY_UNSPEC;
  }
  
+ #define	PKALG_SEP	","
+ int
+ pkalg_valid(const char *names)
+ {
+         int k;
+ 	char *keys, *kp;
+ 	char *p;
+ 
+ 	if (names == NULL || strcmp(names, "") == 0)
+ 		return 0;
+ 	keys = kp = xstrdup(names);
+ 	for ((p = strsep(&kp, PKALG_SEP)); p && *p != '\0';
+ 	     (p = strsep(&kp, PKALG_SEP))) {
+ 	        if ((strcmp(p, "ssh-rsa") != 0) &&
+ 		    (strcmp(p, "ssh-dss") != 0)) {
+ 			debug("bad pkalg %s [%s]", p, names);
+ 			xfree(keys);
+ 			return 0;
+ 		} else {
+ 			debug3("pkalg ok: %s [%s]", p, names);
+ 		}
+ 	}
+ 	debug3("pkalgs ok: [%s]", names);
+ 	xfree(keys);
+ 	return 1;
+ }
+ 
+ 
  Key *
  key_from_blob(char *blob, int blen)
  {
diff -c3 -r orig/openssh-2.5.1p1/key.h openssh-2.5.1p1/key.h
*** orig/openssh-2.5.1p1/key.h	Mon Jan 29 07:39:26 2001
--- openssh-2.5.1p1/key.h	Sun Mar 11 22:50:23 2001
***************
*** 55,60 ****
--- 55,61 ----
  Key	*key_generate(int type, u_int bits);
  Key	*key_from_private(Key *k);
  int	key_type_from_name(char *name);
+ int	pkalg_valid(const char *name);
  
  Key	*key_from_blob(char *blob, int blen);
  int	key_to_blob(Key *key, u_char **blobp, u_int *lenp);
Only in orig/openssh-2.5.1p1/: mkstring
diff -c3 -r orig/openssh-2.5.1p1/readconf.c openssh-2.5.1p1/readconf.c
*** orig/openssh-2.5.1p1/readconf.c	Thu Feb 15 03:02:00 2001
--- openssh-2.5.1p1/readconf.c	Sun Mar 11 23:12:34 2001
***************
*** 25,30 ****
--- 25,31 ----
  #include "misc.h"
  #include "kex.h"
  #include "mac.h"
+ #include "key.h"
  
  /* Format of the configuration file:
  
***************
*** 107,113 ****
  	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
  	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
  	oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
! 	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
  	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
  	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias
  } OpCodes;
--- 108,114 ----
  	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
  	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
  	oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
! 	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs, oPkalg,
  	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
  	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias
  } OpCodes;
***************
*** 151,156 ****
--- 152,158 ----
  	{ "cipher", oCipher },
  	{ "ciphers", oCiphers },
  	{ "macs", oMacs },
+ 	{ "pkalg", oPkalg },
  	{ "protocol", oProtocol },
  	{ "remoteforward", oRemoteForward },
  	{ "localforward", oLocalForward },
***************
*** 516,521 ****
--- 518,534 ----
  			options->macs = xstrdup(arg);
  		break;
  
+ 	case oPkalg:
+ 		arg = strdelim(&s);
+ 		if (!arg || *arg == '\0')
+ 			fatal("%.200s line %d: Missing argument.", filename, linenum);
+ 		if (!pkalg_valid(arg))
+ 			fatal("%.200s line %d: Bad SSH2 PKalg spec '%s'.",
+ 			      filename, linenum, arg ? arg : "<NONE>");
+ 		if (*activep && options->pkalg == NULL)
+ 			options->pkalg = xstrdup(arg);
+ 		break;
+ 
  	case oProtocol:
  		intptr = &options->protocol;
  		arg = strdelim(&s);
***************
*** 708,713 ****
--- 721,727 ----
  	options->cipher = -1;
  	options->ciphers = NULL;
  	options->macs = NULL;
+ 	options->pkalg = NULL;
  	options->protocol = SSH_PROTO_UNKNOWN;
  	options->num_identity_files = 0;
  	options->hostname = NULL;
diff -c3 -r orig/openssh-2.5.1p1/readconf.h openssh-2.5.1p1/readconf.h
*** orig/openssh-2.5.1p1/readconf.h	Thu Feb 15 03:02:00 2001
--- openssh-2.5.1p1/readconf.h	Sun Mar 11 22:50:23 2001
***************
*** 69,74 ****
--- 69,75 ----
  	int     cipher;		/* Cipher to use. */
  	char   *ciphers;	/* SSH2 ciphers in order of preference. */
  	char   *macs;		/* SSH2 macs in order of preference. */
+         char   *pkalg;          /* SSH2 PK_ALG list to use */
  	int	protocol;	/* Protocol in order of preference. */
  	char   *hostname;	/* Real host to connect. */
  	char   *host_key_alias;	/* hostname alias for .ssh/known_hosts */
diff -c3 -r orig/openssh-2.5.1p1/sshconnect2.c openssh-2.5.1p1/sshconnect2.c
*** orig/openssh-2.5.1p1/sshconnect2.c	Fri Feb 16 01:34:57 2001
--- openssh-2.5.1p1/sshconnect2.c	Sun Mar 11 23:15:37 2001
***************
*** 94,99 ****
--- 94,104 ----
  		myproposal[PROPOSAL_MAC_ALGS_CTOS] =
  		myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
  	}
+ 	if (options.pkalg != NULL) {
+                 debug("Copying pkalg=%.100s to mypromposal", options.pkalg);
+ 	        myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = options.pkalg;
+ 	}
+ 
  
  	/* buffers with raw kexinit messages */
  	server_kexinit = xmalloc(sizeof(*server_kexinit));
--cut-here-

Most of the patch is based on the handling of 'macs', and 'ciphers',
it is quite possible that there is a cleaner way to achieve the same
effect.  I wasn't sure that key.c was the right place to put
pkalg_valid(), but it seems to do the right thing for me:

$ ./ssh -o 'pkalg ssh-rsa' -2 testhost uptime
The authenticity of host 'testhost (10.16.18.11)' can't be established.
RSA key fingerprint is
e9:20:0b:9a:22:e9:69:b3:52:76:27:ff:41:50:cb:81.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'testhost,10.16.18.11' (RSA) to the list of
known hosts.
<snip>

$ ./ssh -o 'pkalg ssh-dss' -2 testhost uptime
The authenticity of host 'testhost (10.16.18.11)' can't be established.
DSA key fingerprint is
95:df:c5:cc:d9:3b:53:7a:a3:de:42:9c:93:bd:93:2e.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'testhost,10.16.18.11' (DSA) to the list of
known hosts.

Of course I may have missed somthing important, and I've currently
only tested it on one implementation (Linux).  Any improvements or
suggestions welcome.
-- 
Jon Peatfield,  DAMTP,  Computer Officer,   University of Cambridge
Telephone: +44 1223  3 37852    Mail: J.S.Peatfield at damtp.cam.ac.uk





More information about the openssh-unix-dev mailing list