]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - ssh.c
Unix Pageant: factor out have_controlling_tty().
[PuTTY.git] / ssh.c
diff --git a/ssh.c b/ssh.c
index dfdf7227c39c1ba637e4665291329e786d589e48..0f4712d89360e622c2a012c09b23148e00323931 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -406,6 +406,7 @@ static void ssh_channel_destroy(struct ssh_channel *c);
 #define OUR_V2_PACKETLIMIT 0x9000UL
 
 const static struct ssh_signkey *hostkey_algs[] = {
+    &ssh_ecdsa_ed25519,
     &ssh_ecdsa_nistp256, &ssh_ecdsa_nistp384, &ssh_ecdsa_nistp521,
     &ssh_rsa, &ssh_dss
 };
@@ -2126,17 +2127,16 @@ static void ssh_pkt_addstring_start(struct Packet *pkt)
     ssh_pkt_adduint32(pkt, 0);
     pkt->savedpos = pkt->length;
 }
-static void ssh_pkt_addstring_str(struct Packet *pkt, const char *data)
-{
-    ssh_pkt_adddata(pkt, data, strlen(data));
-    PUT_32BIT(pkt->data + pkt->savedpos - 4, pkt->length - pkt->savedpos);
-}
 static void ssh_pkt_addstring_data(struct Packet *pkt, const char *data,
                                    int len)
 {
     ssh_pkt_adddata(pkt, data, len);
     PUT_32BIT(pkt->data + pkt->savedpos - 4, pkt->length - pkt->savedpos);
 }
+static void ssh_pkt_addstring_str(struct Packet *pkt, const char *data)
+{
+  ssh_pkt_addstring_data(pkt, data, strlen(data));
+}
 static void ssh_pkt_addstring(struct Packet *pkt, const char *data)
 {
     ssh_pkt_addstring_start(pkt);
@@ -2908,7 +2908,8 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
         (wc_match("OpenSSH_2.[235]*", imp)))) {
        /*
         * These versions only support the original (pre-RFC4419)
-        * SSH-2 GEX request.
+        * SSH-2 GEX request, and disconnect with a protocol error if
+        * we use the newer version.
         */
        ssh->remote_bugs |= BUG_SSH2_OLDGEX;
        logevent("We believe remote version has outdated SSH-2 GEX");
@@ -3875,7 +3876,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen,
        void *publickey_blob;
        int publickey_bloblen;
        char *publickey_comment;
-       int publickey_encrypted;
+       int privatekey_available, privatekey_encrypted;
        prompts_t *cur_prompt;
        char c;
        int pwpkt_type;
@@ -4209,20 +4210,24 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen,
     s->keyfile = conf_get_filename(ssh->conf, CONF_keyfile);
     if (!filename_is_null(s->keyfile)) {
        int keytype;
-       logeventf(ssh, "Reading private key file \"%.150s\"",
+       logeventf(ssh, "Reading key file \"%.150s\"",
                  filename_to_str(s->keyfile));
        keytype = key_type(s->keyfile);
-       if (keytype == SSH_KEYTYPE_SSH1) {
+       if (keytype == SSH_KEYTYPE_SSH1 ||
+            keytype == SSH_KEYTYPE_SSH1_PUBLIC) {
            const char *error;
            if (rsakey_pubblob(s->keyfile,
                               &s->publickey_blob, &s->publickey_bloblen,
                               &s->publickey_comment, &error)) {
-               s->publickey_encrypted = rsakey_encrypted(s->keyfile,
-                                                         NULL);
+                s->privatekey_available = (keytype == SSH_KEYTYPE_SSH1);
+                if (!s->privatekey_available)
+                    logeventf(ssh, "Key file contains public key only");
+               s->privatekey_encrypted = rsakey_encrypted(s->keyfile,
+                                                           NULL);
            } else {
                char *msgbuf;
-               logeventf(ssh, "Unable to load private key (%s)", error);
-               msgbuf = dupprintf("Unable to load private key file "
+               logeventf(ssh, "Unable to load key (%s)", error);
+               msgbuf = dupprintf("Unable to load key file "
                                   "\"%.150s\" (%s)\r\n",
                                   filename_to_str(s->keyfile),
                                   error);
@@ -4430,7 +4435,8 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen,
            if (s->authed)
                break;
        }
-       if (s->publickey_blob && !s->tried_publickey) {
+       if (s->publickey_blob && s->privatekey_available &&
+            !s->tried_publickey) {
            /*
             * Try public key authentication with the specified
             * key file.
@@ -4449,7 +4455,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen,
                 */
                char *passphrase = NULL;    /* only written after crReturn */
                const char *error;
-               if (!s->publickey_encrypted) {
+               if (!s->privatekey_encrypted) {
                    if (flags & FLAG_VERBOSE)
                        c_write_str(ssh, "No passphrase required.\r\n");
                    passphrase = NULL;
@@ -7036,7 +7042,7 @@ static void do_ssh2_transport(Ssh ssh, void *vin, int inlen,
          * Authenticate remote host: verify host key. (We've already
          * checked the signature of the exchange hash.)
          */
-        s->fingerprint = ssh->hostkey->fingerprint(s->hkey);
+        s->fingerprint = ssh2_fingerprint(ssh->hostkey, s->hkey);
         logevent("Host key fingerprint is:");
         logevent(s->fingerprint);
         /* First check against manually configured host keys. */
@@ -8851,7 +8857,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
        int got_username;
        void *publickey_blob;
        int publickey_bloblen;
-       int publickey_encrypted;
+       int privatekey_available, privatekey_encrypted;
        char *publickey_algorithm;
        char *publickey_comment;
        unsigned char agent_request[5], *agent_response, *agentp;
@@ -8957,10 +8963,12 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
        s->keyfile = conf_get_filename(ssh->conf, CONF_keyfile);
        if (!filename_is_null(s->keyfile)) {
            int keytype;
-           logeventf(ssh, "Reading private key file \"%.150s\"",
+           logeventf(ssh, "Reading key file \"%.150s\"",
                      filename_to_str(s->keyfile));
            keytype = key_type(s->keyfile);
-           if (keytype == SSH_KEYTYPE_SSH2) {
+           if (keytype == SSH_KEYTYPE_SSH2 ||
+                keytype == SSH_KEYTYPE_SSH2_PUBLIC_RFC4716 ||
+                keytype == SSH_KEYTYPE_SSH2_PUBLIC_OPENSSH) {
                const char *error;
                s->publickey_blob =
                    ssh2_userkey_loadpub(s->keyfile,
@@ -8968,13 +8976,16 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
                                         &s->publickey_bloblen, 
                                         &s->publickey_comment, &error);
                if (s->publickey_blob) {
-                   s->publickey_encrypted =
+                   s->privatekey_available = (keytype == SSH_KEYTYPE_SSH2);
+                    if (!s->privatekey_available)
+                        logeventf(ssh, "Key file contains public key only");
+                   s->privatekey_encrypted =
                        ssh2_userkey_encrypted(s->keyfile, NULL);
                } else {
                    char *msgbuf;
-                   logeventf(ssh, "Unable to load private key (%s)", 
+                   logeventf(ssh, "Unable to load key (%s)", 
                              error);
-                   msgbuf = dupprintf("Unable to load private key file "
+                   msgbuf = dupprintf("Unable to load key file "
                                       "\"%.150s\" (%s)\r\n",
                                       filename_to_str(s->keyfile),
                                       error);
@@ -9488,7 +9499,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
                }
 
            } else if (s->can_pubkey && s->publickey_blob &&
-                      !s->tried_pubkey_config) {
+                      s->privatekey_available && !s->tried_pubkey_config) {
 
                struct ssh2_userkey *key;   /* not live over crReturn */
                char *passphrase;           /* not live over crReturn */
@@ -9539,7 +9550,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
                key = NULL;
                while (!key) {
                    const char *error;  /* not live over crReturn */
-                   if (s->publickey_encrypted) {
+                   if (s->privatekey_encrypted) {
                        /*
                         * Get a passphrase from the user.
                         */