#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
+#ifndef AUTO_WINSOCK
+#ifdef WINSOCK_TWO
+#include <winsock2.h>
+#else
#include <winsock.h>
+#endif
+#endif
#include "putty.h"
#include "tree234.h"
#include "ssh.h"
-#include "scp.h"
#ifndef FALSE
#define FALSE 0
c_write1(*buf++);
}
+static void c_writedata (char *buf, int len) {
+ while (len--)
+ c_write1(*buf++);
+}
+
struct Packet {
long length;
int type;
j = makekey(pktin.body+8+i, &hostkey, &keystr2, 0);
/*
- * Hash the host key and print the hash in the log box. Just as
- * a last resort in case the registry's host key checking is
- * compromised, we'll allow the user some ability to verify
- * host keys by eye.
+ * Log the host key fingerprint.
*/
- MD5Init(&md5c);
- MD5Update(&md5c, keystr2, hostkey.bytes);
- MD5Final(session_id, &md5c);
{
char logmsg[80];
- int i;
- logevent("Host key MD5 is:");
+ logevent("Host key fingerprint is:");
strcpy(logmsg, " ");
- for (i = 0; i < 16; i++)
- sprintf(logmsg+strlen(logmsg), "%02x", session_id[i]);
+ hostkey.comment = NULL;
+ rsa_fingerprint(logmsg+strlen(logmsg), sizeof(logmsg)-strlen(logmsg),
+ &hostkey);
logevent(logmsg);
}
while (pktin.type == SSH1_SMSG_FAILURE) {
static char password[100];
+ static char prompt[200];
static int pos;
static char c;
static int pwpkt_type;
crWaitUntil(ispkt);
if (pktin.type == SSH1_SMSG_SUCCESS) {
logevent("Pageant's response accepted");
- c_write("Authenticated using RSA key \"",
- 29);
- c_write(commentp, commentlen);
- c_write("\" from agent\r\n", 14);
+ if (flags & FLAG_VERBOSE) {
+ c_write("Authenticated using RSA key \"",
+ 29);
+ c_write(commentp, commentlen);
+ c_write("\" from agent\r\n", 14);
+ }
authed = TRUE;
} else
logevent("Pageant's response not accepted");
if (*cfg.keyfile && !tried_publickey)
pwpkt_type = SSH1_CMSG_AUTH_RSA;
- if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD &&
- !(flags & FLAG_INTERACTIVE)) {
- char prompt[200];
- sprintf(prompt, "%s@%s's password: ", cfg.username, savedhost);
+ if (pktin.type == SSH1_SMSG_FAILURE &&
+ cfg.try_tis_auth &&
+ (supported_auths_mask & (1<<SSH1_AUTH_TIS))) {
+ pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
+ logevent("Requested TIS authentication");
+ send_packet(SSH1_CMSG_AUTH_TIS, PKT_END);
+ crWaitUntil(ispkt);
+ if (pktin.type != SSH1_SMSG_AUTH_TIS_CHALLENGE) {
+ logevent("TIS authentication declined");
+ if (flags & FLAG_INTERACTIVE)
+ c_write("TIS authentication refused.\r\n", 29);
+ } else {
+ int challengelen = ((pktin.body[0] << 24) |
+ (pktin.body[1] << 16) |
+ (pktin.body[2] << 8) |
+ (pktin.body[3]));
+ logevent("Received TIS challenge");
+ if (challengelen > sizeof(prompt)-1)
+ challengelen = sizeof(prompt)-1; /* prevent overrun */
+ memcpy(prompt, pktin.body+4, challengelen);
+ prompt[challengelen] = '\0';
+ }
+ }
+ if (pktin.type == SSH1_SMSG_FAILURE &&
+ cfg.try_tis_auth &&
+ (supported_auths_mask & (1<<SSH1_AUTH_CCARD))) {
+ pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
+ logevent("Requested CryptoCard authentication");
+ send_packet(SSH1_CMSG_AUTH_CCARD, PKT_END);
+ crWaitUntil(ispkt);
+ if (pktin.type != SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
+ logevent("CryptoCard authentication declined");
+ c_write("CryptoCard authentication refused.\r\n", 29);
+ } else {
+ int challengelen = ((pktin.body[0] << 24) |
+ (pktin.body[1] << 16) |
+ (pktin.body[2] << 8) |
+ (pktin.body[3]));
+ logevent("Received CryptoCard challenge");
+ if (challengelen > sizeof(prompt)-1)
+ challengelen = sizeof(prompt)-1; /* prevent overrun */
+ memcpy(prompt, pktin.body+4, challengelen);
+ strncpy(prompt + challengelen, "\r\nResponse : ",
+ sizeof(prompt)-challengelen);
+ prompt[sizeof(prompt)-1] = '\0';
+ }
+ }
+ if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
+ sprintf(prompt, "%.90s@%.90s's password: ",
+ cfg.username, savedhost);
+ }
+ if (pwpkt_type == SSH1_CMSG_AUTH_RSA) {
+ char *comment = NULL;
+ if (flags & FLAG_VERBOSE)
+ c_write("Trying public key authentication.\r\n", 35);
+ if (!rsakey_encrypted(cfg.keyfile, &comment)) {
+ if (flags & FLAG_VERBOSE)
+ c_write("No passphrase required.\r\n", 25);
+ goto tryauth;
+ }
+ sprintf(prompt, "Passphrase for key \"%.100s\": ", comment);
+ free(comment);
+ }
+
+ if (!(flags & FLAG_INTERACTIVE)) {
if (!ssh_get_password(prompt, password, sizeof(password))) {
/*
* get_password failed to get a password (for
crReturn(1);
}
} else {
-
- if (pktin.type == SSH1_SMSG_FAILURE &&
- cfg.try_tis_auth &&
- (supported_auths_mask & (1<<SSH1_AUTH_TIS))) {
- pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
- logevent("Requested TIS authentication");
- send_packet(SSH1_CMSG_AUTH_TIS, PKT_END);
- crWaitUntil(ispkt);
- if (pktin.type != SSH1_SMSG_AUTH_TIS_CHALLENGE) {
- logevent("TIS authentication declined");
- c_write("TIS authentication refused.\r\n", 29);
- } else {
- int challengelen = ((pktin.body[0] << 24) |
- (pktin.body[1] << 16) |
- (pktin.body[2] << 8) |
- (pktin.body[3]));
- logevent("Received TIS challenge");
- c_write(pktin.body+4, challengelen);
- }
- }
- if (pktin.type == SSH1_SMSG_FAILURE &&
- cfg.try_tis_auth &&
- (supported_auths_mask & (1<<SSH1_AUTH_CCARD))) {
- pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
- logevent("Requested CryptoCard authentication");
- send_packet(SSH1_CMSG_AUTH_CCARD, PKT_END);
- crWaitUntil(ispkt);
- if (pktin.type != SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
- logevent("CryptoCard authentication declined");
- c_write("CryptoCard authentication refused.\r\n", 29);
- } else {
- int challengelen = ((pktin.body[0] << 24) |
- (pktin.body[1] << 16) |
- (pktin.body[2] << 8) |
- (pktin.body[3]));
- logevent("Received CryptoCard challenge");
- c_write(pktin.body+4, challengelen);
- c_write("\r\nResponse : ", 13);
- }
- }
- if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD)
- c_write("password: ", 10);
- if (pwpkt_type == SSH1_CMSG_AUTH_RSA) {
- if (flags & FLAG_VERBOSE)
- c_write("Trying public key authentication.\r\n", 35);
- if (!rsakey_encrypted(cfg.keyfile)) {
- if (flags & FLAG_VERBOSE)
- c_write("No passphrase required.\r\n", 25);
- goto tryauth;
- }
- c_write("passphrase: ", 12);
- }
-
+ c_write(prompt, strlen(prompt));
pos = 0;
ssh_send_ok = 1;
while (pos >= 0) {
}
}
c_write("\r\n", 2);
-
- }
+ }
tryauth:
if (pwpkt_type == SSH1_CMSG_AUTH_RSA) {
crWaitUntil(ispkt);
if (pktin.type == SSH1_SMSG_FAILURE) {
- if (flags & FLAG_VERBOSE)
- c_write("Server refused our public key.\r\n", 32);
+ c_write("Server refused our public key.\r\n", 32);
continue; /* go and try password */
}
if (pktin.type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
if (pktin.type == SSH1_SMSG_STDOUT_DATA ||
pktin.type == SSH1_SMSG_STDERR_DATA) {
long len = GET_32BIT(pktin.body);
- c_write(pktin.body+4, len);
+ c_writedata(pktin.body+4, len);
} else if (pktin.type == SSH1_MSG_DISCONNECT) {
ssh_state = SSH_STATE_CLOSED;
logevent("Received disconnect request");
c->localid = i;
c->closes = 0;
c->type = SSH1_SMSG_AGENT_OPEN; /* identify channel type */
+ c->u.a.lensofar = 0;
add234(ssh_channels, c);
send_packet(SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,
PKT_INT, c->remoteid, PKT_INT, c->localid,
if (!(flags & FLAG_INTERACTIVE)) {
char prompt[200];
- sprintf(prompt, "%s@%s's password: ", cfg.username, savedhost);
+ sprintf(prompt, "%.90s@%.90s's password: ", cfg.username, savedhost);
if (!ssh_get_password(prompt, password, sizeof(password))) {
/*
* get_password failed to get a password (for
continue; /* extended but not stderr */
ssh2_pkt_getstring(&data, &length);
if (data) {
- c_write(data, length);
+ c_writedata(data, length);
/*
* Enlarge the window again at the remote side,
* just in case it ever runs down and they fail
}
}
-
-/*
- * Read and decrypt one incoming SSH packet.
- * (only used by pSCP)
- */
-static void get_packet(void)
-{
- unsigned char buf[4096], *p;
- long to_read;
- int len;
-
- p = NULL;
- len = 0;
-
- while ((to_read = s_rdpkt(&p, &len)) > 0) {
- if (to_read > sizeof(buf)) to_read = sizeof(buf);
- len = s_read(buf, to_read);
- if (len != to_read) {
- closesocket(s);
- s = INVALID_SOCKET;
- return;
- }
- p = buf;
- }
-
- assert(len == 0);
-}
-
-/*
- * Receive a block of data over the SSH link. Block until
- * all data is available. Return nr of bytes read (0 if lost connection).
- * (only used by pSCP)
- */
-int ssh_scp_recv(unsigned char *buf, int len)
-{
- static int pending_input_len = 0;
- static unsigned char *pending_input_ptr;
- int to_read = len;
-
- if (pending_input_len >= to_read) {
- memcpy(buf, pending_input_ptr, to_read);
- pending_input_ptr += to_read;
- pending_input_len -= to_read;
- return len;
- }
-
- if (pending_input_len > 0) {
- memcpy(buf, pending_input_ptr, pending_input_len);
- buf += pending_input_len;
- to_read -= pending_input_len;
- pending_input_len = 0;
- }
-
- if (s == INVALID_SOCKET)
- return 0;
- while (to_read > 0) {
- get_packet();
- if (s == INVALID_SOCKET)
- return 0;
- if (pktin.type == SSH1_SMSG_STDOUT_DATA) {
- int plen = GET_32BIT(pktin.body);
- if (plen <= to_read) {
- memcpy(buf, pktin.body + 4, plen);
- buf += plen;
- to_read -= plen;
- } else {
- memcpy(buf, pktin.body + 4, to_read);
- pending_input_len = plen - to_read;
- pending_input_ptr = pktin.body + 4 + to_read;
- to_read = 0;
- }
- } else if (pktin.type == SSH1_SMSG_STDERR_DATA) {
- int plen = GET_32BIT(pktin.body);
- fwrite(pktin.body + 4, plen, 1, stderr);
- } else if (pktin.type == SSH1_MSG_DISCONNECT) {
- logevent("Received disconnect request");
- } else if (pktin.type == SSH1_SMSG_SUCCESS ||
- pktin.type == SSH1_SMSG_FAILURE) {
- /* ignore */
- } else if (pktin.type == SSH1_SMSG_EXIT_STATUS) {
- char logbuf[100];
- sprintf(logbuf, "Remote exit status: %d", GET_32BIT(pktin.body));
- logevent(logbuf);
- send_packet(SSH1_CMSG_EXIT_CONFIRMATION, PKT_END);
- logevent("Closing connection");
- closesocket(s);
- s = INVALID_SOCKET;
- } else {
- bombout(("Strange packet received: type %d", pktin.type));
- return 0;
- }
- }
-
- return len;
-}
-
-/*
- * Send a block of data over the SSH link.
- * Block until all data is sent.
- * (only used by pSCP)
- */
-void ssh_scp_send(unsigned char *buf, int len)
-{
- if (s == INVALID_SOCKET)
- return;
- send_packet(SSH1_CMSG_STDIN_DATA,
- PKT_INT, len, PKT_DATA, buf, len, PKT_END);
-}
-
-/*
- * Send an EOF notification to the server.
- * (only used by pSCP)
- */
-void ssh_scp_send_eof(void)
-{
- if (s == INVALID_SOCKET)
- return;
- send_packet(SSH1_CMSG_EOF, PKT_END);
-}
-
-/*
- * Set up the connection, login on the remote host and
- * start execution of a command.
- * Returns an error message, or NULL on success.
- * (only used by pSCP)
- */
-char *ssh_scp_init(char *host, int port, char *cmd, char **realhost)
-{
- char buf[160], *p;
-
-#ifdef MSCRYPTOAPI
- if (crypto_startup() == 0)
- return "Microsoft high encryption pack not installed!";
-#endif
-
- p = connect_to_host(host, port, realhost);
- if (p != NULL)
- return p;
-
- random_init();
-
- if (!do_ssh_init())
- return "Protocol initialisation error";
-
- /* Exchange keys and login */
- do {
- get_packet();
- if (s == INVALID_SOCKET)
- return "Connection closed by remote host";
- } while (!do_ssh1_login(NULL, 0, 1));
-
- if (ssh_state == SSH_STATE_CLOSED) {
- closesocket(s);
- s = INVALID_SOCKET;
- return "Session initialisation error";
- }
-
- /* Execute command */
- sprintf(buf, "Sending command: %.100s", cmd);
- logevent(buf);
- send_packet(SSH1_CMSG_EXEC_CMD, PKT_STR, cmd, PKT_END);
-
- return NULL;
-}
-
static SOCKET ssh_socket(void) { return s; }
static int ssh_sendok(void) { return ssh_send_ok; }