Improved error messages if you use the wrong key type: you should
[u/mdw/putty] / ssh.c
diff --git a/ssh.c b/ssh.c
index 51bbf44..d9981ed 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -2430,8 +2430,22 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
        }
        if (pwpkt_type == SSH1_CMSG_AUTH_RSA) {
            char *comment = NULL;
+           int type;
+           char msgbuf[256];
            if (flags & FLAG_VERBOSE)
                c_write_str("Trying public key authentication.\r\n");
+           sprintf(msgbuf, "Trying public key \"%.200s\"", cfg.keyfile);
+           logevent(msgbuf);
+           type = key_type(cfg.keyfile);
+           if (type != SSH_KEYTYPE_SSH1) {
+               sprintf(msgbuf, "Key is of wrong type (%s)",
+                       key_type_to_str(type));
+               logevent(msgbuf);
+               c_write_str(msgbuf);
+               c_write_str("\r\n");
+               tried_publickey = 1;
+               continue;
+           }
            if (!rsakey_encrypted(cfg.keyfile, &comment)) {
                if (flags & FLAG_VERBOSE)
                    c_write_str("No passphrase required.\r\n");
@@ -2831,11 +2845,13 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt)
     }
 
     {
-       char type, *e;
+       char type;
+       static char *e;
        int n;
-       int sport,dport;
+       int sport,dport,sserv,dserv;
        char sports[256], dports[256], host[256];
        char buf[1024];
+       struct servent *se;
 
        ssh_rportfwds = newtree234(ssh_rportcmp_ssh1);
         /* Add port forwardings. */
@@ -2860,12 +2876,43 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt)
            dports[n] = 0;
            e++;
            dport = atoi(dports);
+           dserv = 0;
+           if (dport == 0) {
+               dserv = 1;
+               se = getservbyname(dports, NULL);
+               if (se != NULL) {
+                   dport = ntohs(se->s_port);
+               } else {
+                   sprintf(buf,
+                           "Service lookup failed for destination port \"%s\"",
+                           dports);
+                   logevent(buf);
+               }
+           }
            sport = atoi(sports);
+           sserv = 0;
+           if (sport == 0) {
+               sserv = 1;
+               se = getservbyname(sports, NULL);
+               if (se != NULL) {
+                   sport = ntohs(se->s_port);
+               } else {
+                   sprintf(buf,
+                           "Service lookup failed for source port \"%s\"",
+                           sports);
+                   logevent(buf);
+               }
+           }
            if (sport && dport) {
                if (type == 'L') {
                    pfd_addforward(host, dport, sport);
-                   sprintf(buf, "Local port %d forwarding to %s:%d",
-                           sport, host, dport);
+                   sprintf(buf, "Local port %.*s%.*s%d%.*s forwarding to"
+                           " %s:%.*s%.*s%d%.*s",
+                           sserv ? strlen(sports) : 0, sports,
+                           sserv, "(", sport, sserv, ")",
+                           host,
+                           dserv ? strlen(dports) : 0, dports,
+                           dserv, "(", dport, dserv, ")");
                    logevent(buf);
                } else {
                    struct ssh_rportfwd *pf;
@@ -2879,14 +2926,31 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt)
                        logevent(buf);
                        sfree(pf);
                    } else {
-                       sprintf(buf, "Requesting remote port %d forward to %s:%d",
-                               sport, host, dport);
+                       sprintf(buf, "Requesting remote port %.*s%.*s%d%.*s"
+                               " forward to %s:%.*s%.*s%d%.*s",
+                           sserv ? strlen(sports) : 0, sports,
+                           sserv, "(", sport, sserv, ")",
+                           host,
+                           dserv ? strlen(dports) : 0, dports,
+                           dserv, "(", dport, dserv, ")");
                        logevent(buf);
                        send_packet(SSH1_CMSG_PORT_FORWARD_REQUEST,
                                    PKT_INT, sport,
                                    PKT_STR, host,
                                    PKT_INT, dport,
                                    PKT_END);
+                       do {
+                           crReturnV;
+                       } while (!ispkt);
+                       if (pktin.type != SSH1_SMSG_SUCCESS
+                           && pktin.type != SSH1_SMSG_FAILURE) {
+                           bombout(("Protocol confusion"));
+                           crReturnV;
+                       } else if (pktin.type == SSH1_SMSG_FAILURE) {
+                           c_write_str("Server refused port forwarding\r\n");
+                           ssh_editing = ssh_echoing = 1;
+                       }
+                       logevent("Remote port forwarding enabled");
                    }
                }
            }
@@ -4035,8 +4099,21 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
        kbd_inter_running = FALSE;
        /* Load the pub half of cfg.keyfile so we notice if it's in Pageant */
        if (*cfg.keyfile) {
-           publickey_blob = ssh2_userkey_loadpub(cfg.keyfile, NULL,
-                                                 &publickey_bloblen);
+           int keytype;
+           logeventf("Reading private key file \"%.150s\"", cfg.keyfile);
+           keytype = key_type(cfg.keyfile);
+           if (keytype == SSH_KEYTYPE_SSH2)
+               publickey_blob = ssh2_userkey_loadpub(cfg.keyfile, NULL,
+                                                     &publickey_bloblen);
+           else {
+               char msgbuf[256];
+               logeventf("Unable to use this key file (%s)",
+                       key_type_to_str(keytype));
+               sprintf(msgbuf, "Unable to use key file \"%.150s\" (%s)\r\n",
+                       cfg.keyfile, key_type_to_str(keytype));
+               c_write_str(msgbuf);
+               publickey_blob = NULL;
+           }
        } else
            publickey_blob = NULL;
 
@@ -4295,7 +4372,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
                }
            }
 
-           if (!method && can_pubkey && *cfg.keyfile
+           if (!method && can_pubkey && publickey_blob
                && !tried_pubkey_config) {
                unsigned char *pub_blob;
                char *algorithm, *comment;
@@ -4714,9 +4791,10 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
        static char *e;                /* preserve across crReturn */
        char type;
        int n;
-       int sport,dport;
+       int sport,dport,sserv,dserv;
        char sports[256], dports[256], host[256];
        char buf[1024];
+       struct servent *se;
 
        ssh_rportfwds = newtree234(ssh_rportcmp_ssh2);
         /* Add port forwardings. */
@@ -4741,12 +4819,43 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
            dports[n] = 0;
            e++;
            dport = atoi(dports);
+           dserv = 0;
+           if (dport == 0) {
+               dserv = 1;
+               se = getservbyname(dports, NULL);
+               if (se != NULL) {
+                   dport = ntohs(se->s_port);
+               } else {
+                   sprintf(buf,
+                           "Service lookup failed for destination port \"%s\"",
+                           dports);
+                   logevent(buf);
+               }
+           }
            sport = atoi(sports);
+           sserv = 0;
+           if (sport == 0) {
+               sserv = 1;
+               se = getservbyname(sports, NULL);
+               if (se != NULL) {
+                   sport = ntohs(se->s_port);
+               } else {
+                   sprintf(buf,
+                           "Service lookup failed for source port \"%s\"",
+                           sports);
+                   logevent(buf);
+               }
+           }
            if (sport && dport) {
                if (type == 'L') {
                    pfd_addforward(host, dport, sport);
-                   sprintf(buf, "Local port %d forwarding to %s:%d",
-                           sport, host, dport);
+                   sprintf(buf, "Local port %.*s%.*s%d%.*s forwarding to"
+                           " %s:%.*s%.*s%d%.*s",
+                           sserv ? strlen(sports) : 0, sports,
+                           sserv, "(", sport, sserv, ")",
+                           host,
+                           dserv ? strlen(dports) : 0, dports,
+                           dserv, "(", dport, dserv, ")");
                    logevent(buf);
                } else {
                    struct ssh_rportfwd *pf;
@@ -4761,8 +4870,13 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
                        logevent(buf);
                        sfree(pf);
                    } else {
-                       sprintf(buf, "Requesting remote port %d (forwarded to %s:%d)",
-                               sport, host, dport);
+                       sprintf(buf, "Requesting remote port %.*s%.*s%d%.*s"
+                               " forward to %s:%.*s%.*s%d%.*s",
+                           sserv ? strlen(sports) : 0, sports,
+                           sserv, "(", sport, sserv, ")",
+                           host,
+                           dserv ? strlen(dports) : 0, dports,
+                           dserv, "(", dport, dserv, ")");
                        logevent(buf);
                        ssh2_pkt_init(SSH2_MSG_GLOBAL_REQUEST);
                        ssh2_pkt_addstring("tcpip-forward");