The attached patch for 4.6p1 adds a feature (-u) that will check to see if a key exists on a remote host. I use this for auditing my users transition to v2 keys very useful. If there is any interest I'll provide a patch for v2 ssh keys also. http://vapid.dhs.org/dokuwiki/doku.php?id=vapidlabs:openssh_check_key_patch -- Thanks Larry --- orig/openssh-4.6p1/sshconnect1.c 2006-11-07 07:14:42.000000000 -0500 +++ openssh-4.6p1/sshconnect1.c 2007-05-15 03:31:06.740012440 -0400 @@ -69,10 +69,11 @@ u_int i; Key *key; BIGNUM *challenge; + u_char buf[300]; /* Get connection to the agent. */ auth = ssh_get_authentication_connection(); - if (!auth) +if (!auth) return 0; if ((challenge = BN_new()) == NULL) @@ -84,7 +85,7 @@ /* Try this identity. */ debug("Trying RSA authentication via agent with '%.100s'", comment); - xfree(comment); + if (!options.checkey) xfree(comment); /* Tell the server that we are willing to authenticate using this key. */ packet_start(SSH_CMSG_AUTH_RSA); @@ -107,9 +108,17 @@ packet_disconnect("Protocol error during RSA authentication: %d", type); + /*if -u is enabled print a message and then exit*/ + if (options.checkey) { + snprintf(buf, sizeof(buf), "RSA key '%.100s' is Valid",comment); + xfree(comment); + packet_disconnect("%s",buf); + } + packet_get_bignum(challenge); packet_check_eom(); + debug("Received RSA challenge from server."); /* Ask the agent to decrypt the challenge. */ @@ -136,12 +145,16 @@ type = packet_read(); /* The server returns success if it accepted the authentication. */ + if (type == SSH_SMSG_SUCCESS) { ssh_close_authentication_connection(auth); BN_clear_free(challenge); debug("RSA authentication accepted by server."); return 1; } + + + /* Otherwise it should return failure. */ if (type != SSH_SMSG_FAILURE) packet_disconnect("Protocol error waiting RSA auth response: %d", @@ -234,7 +247,8 @@ xfree(comment); return 0; } - /* Otherwise, the server should respond with a challenge. */ + + /* Otherwise, the server should respond with a challenge. */ if (type != SSH_SMSG_AUTH_RSA_CHALLENGE) packet_disconnect("Protocol error during RSA authentication: %d", type); @@ -256,7 +270,15 @@ else private = key_load_private_type(KEY_RSA1, authfile, "", NULL, &perm_ok); - if (private == NULL && !options.batch_mode && perm_ok) { + + /*if -u flag is set just check to see if key is valid and exit.*/ + if (options.checkey && perm_ok) { + snprintf(buf, sizeof(buf), "RSA key '%.100s' is Valid",comment); + xfree(comment); + packet_disconnect("%s",buf); + } + + if (private == NULL && !options.batch_mode && perm_ok && !options.checkey) { snprintf(buf, sizeof(buf), "Enter passphrase for RSA key '%.100s': ", comment); for (i = 0; i < options.number_of_password_prompts; i++) { --- orig/openssh-4.6p1/ssh.c 2007-01-05 00:30:17.000000000 -0500 +++ openssh-4.6p1/ssh.c 2007-05-10 11:40:06.279706888 -0400 @@ -185,7 +185,7 @@ usage(void) { fprintf(stderr, -"usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" +"usage: ssh [-1246AaCfgkMNnqsTtuVvXxY] [-b bind_address] [-c cipher_spec]\n" " [-D [bind_address:]port] [-e escape_char] [-F configfile]\n" " [-i identity_file] [-L [bind_address:]port:host:hostport]\n" " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" @@ -272,7 +272,7 @@ again: while ((opt = getopt(ac, av, - "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVw:XY")) != -1) { + "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TuVw:XY")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; @@ -523,6 +523,9 @@ case 'F': config = optarg; break; + case 'u': + options.checkey = 1; + break; default: usage(); } --- orig/openssh-4.6p1/readconf.c 2007-02-19 06:12:54.000000000 -0500 +++ openssh-4.6p1/readconf.c 2007-05-10 11:31:54.924404248 -0400 @@ -1065,6 +1065,7 @@ options->tun_remote = -1; options->local_command = NULL; options->permit_local_command = -1; + options->checkey = 0; } /* --- orig/openssh-4.6p1/readconf.h 2006-08-04 22:39:40.000000000 -0400 +++ openssh-4.6p1/readconf.h 2007-05-10 11:29:55.636538760 -0400 @@ -120,6 +120,7 @@ char *local_command; int permit_local_command; + int checkey; } Options;