Jacob's patch for a drag-list to select SSH ciphers. Heavily hacked
[u/mdw/putty] / psftp.c
diff --git a/psftp.c b/psftp.c
index 0ab453c..ef99cde 100644 (file)
--- a/psftp.c
+++ b/psftp.c
 #include "sftp.h"
 #include "int64.h"
 
+/*
+ * Since SFTP is a request-response oriented protocol, it requires
+ * no buffer management: when we send data, we stop and wait for an
+ * acknowledgement _anyway_, and so we can't possibly overfill our
+ * send buffer.
+ */
+
 /* ----------------------------------------------------------------------
  * String handling routines.
  */
@@ -841,6 +848,46 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
 }
 
 /*
+ * Ask whether the selected cipher is acceptable (since it was
+ * below the configured 'warn' threshold).
+ * cs: 0 = both ways, 1 = client->server, 2 = server->client
+ */
+void askcipher(char *ciphername, int cs)
+{
+    HANDLE hin;
+    DWORD savemode, i;
+
+    static const char msg[] =
+       "The first %scipher supported by the server is\n"
+       "%s, which is below the configured warning threshold.\n"
+       "Continue with connection? (y/n) ";
+    static const char abandoned[] = "Connection abandoned.\n";
+
+    char line[32];
+
+    fprintf(stderr, msg,
+           (cs == 0) ? "" :
+           (cs == 1) ? "client-to-server " :
+                       "server-to-client ",
+           ciphername);
+    fflush(stderr);
+
+    hin = GetStdHandle(STD_INPUT_HANDLE);
+    GetConsoleMode(hin, &savemode);
+    SetConsoleMode(hin, (savemode | ENABLE_ECHO_INPUT |
+                        ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT));
+    ReadFile(hin, line, sizeof(line) - 1, &i, NULL);
+    SetConsoleMode(hin, savemode);
+
+    if (line[0] == 'y' || line[0] == 'Y') {
+       return;
+    } else {
+       fprintf(stderr, abandoned);
+       exit(0);
+    }
+}
+
+/*
  *  Print an error message and perform a fatal exit.
  */
 void fatalbox(char *fmt, ...)
@@ -912,7 +959,7 @@ static unsigned char *outptr;              /* where to put the data */
 static unsigned outlen;                       /* how much data required */
 static unsigned char *pending = NULL;  /* any spare data */
 static unsigned pendlen = 0, pendsize = 0;     /* length and phys. size of buffer */
-void from_backend(int is_stderr, char *data, int datalen)
+int from_backend(int is_stderr, char *data, int datalen)
 {
     unsigned char *p = (unsigned char *) data;
     unsigned len = (unsigned) datalen;
@@ -923,14 +970,14 @@ void from_backend(int is_stderr, char *data, int datalen)
      */
     if (is_stderr) {
        fwrite(data, 1, len, stderr);
-       return;
+       return 0;
     }
 
     /*
      * If this is before the real session begins, just return.
      */
     if (!outptr)
-       return;
+       return 0;
 
     if (outlen > 0) {
        unsigned used = outlen;
@@ -954,6 +1001,8 @@ void from_backend(int is_stderr, char *data, int datalen)
        memcpy(pending + pendlen, p, len);
        pendlen += len;
     }
+
+    return 0;
 }
 int sftp_recvdata(char *buf, int len)
 {