#endif
#define logevent(s) { logevent(s); \
- if (IS_SCP && (scp_flags & SCP_VERBOSE) != 0) \
+ if (!(flags & FLAG_CONNECTION) && (flags & FLAG_VERBOSE)) \
fprintf(stderr, "%s\n", s); }
#define SSH1_MSG_DISCONNECT 1
static struct ssh_compress *sccomp = NULL;
static struct ssh_kex *kex = NULL;
static struct ssh_hostkey *hostkey = NULL;
-int scp_flags = 0;
int (*ssh_get_password)(const char *prompt, char *str, int maxlen) = NULL;
static char *savedhost;
+static int ssh_send_ok;
static enum {
SSH_STATE_BEFORE_SIZE,
static void s_write (char *buf, int len) {
while (len > 0) {
int i = send (s, buf, len, 0);
- if (IS_SCP) {
- noise_ultralight(i);
- if (i <= 0)
- fatalbox("Lost connection while sending");
- }
+ noise_ultralight(i);
+ if (i <= 0)
+ fatalbox("Lost connection while sending");
if (i > 0)
len -= i, buf += i;
}
int ret = 0;
while (len > 0) {
int i = recv (s, buf, len, 0);
- if (IS_SCP)
- noise_ultralight(i);
+ noise_ultralight(i);
if (i > 0)
len -= i, buf += i, ret += i;
else
}
static void c_write (char *buf, int len) {
- if (IS_SCP) {
- if (len > 0 && buf[len-1] == '\n') len--;
- if (len > 0 && buf[len-1] == '\r') len--;
- if (len > 0) { fwrite(buf, len, 1, stderr); fputc('\n', stderr); }
+ if (!(flags & FLAG_CONNECTION)) {
+ int i;
+ for (i = 0; i < len; i++)
+ if (buf[i] != '\r')
+ fputc(buf[i], stderr);
return;
}
while (len--)
static struct Packet pktin = { 0, 0, NULL, NULL, 0 };
static struct Packet pktout = { 0, 0, NULL, NULL, 0 };
+static int ssh_version;
static void (*ssh_protocol)(unsigned char *in, int inlen, int ispkt);
static void ssh1_protocol(unsigned char *in, int inlen, int ispkt);
static void ssh2_protocol(unsigned char *in, int inlen, int ispkt);
logevent("Using SSH protocol version 2");
s_write(vstring, strlen(vstring));
ssh_protocol = ssh2_protocol;
+ ssh_version = 2;
s_rdpkt = ssh2_rdpkt;
} else {
/*
logevent("Using SSH protocol version 1");
s_write(vstring, strlen(vstring));
ssh_protocol = ssh1_protocol;
+ ssh_version = 1;
s_rdpkt = ssh1_rdpkt;
}
+ ssh_send_ok = 0;
return 1;
}
static char username[100];
static int pos = 0;
static char c;
- if (!IS_SCP && !*cfg.username) {
+ if (!(flags & FLAG_CONNECTION) && !*cfg.username) {
c_write("login as: ", 10);
while (pos >= 0) {
crWaitUntil(!ispkt);
char stuff[200];
strncpy(username, cfg.username, 99);
username[99] = '\0';
- if (!IS_SCP) {
+ if (flags & FLAG_VERBOSE) {
sprintf(stuff, "Sent username \"%s\".\r\n", username);
- c_write(stuff, strlen(stuff));
+ c_write(stuff, strlen(stuff));
}
}
if (*cfg.keyfile && !tried_publickey)
pwpkt_type = SSH1_CMSG_AUTH_RSA;
- if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD && IS_SCP) {
+ if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD && !FLAG_WINDOWED) {
char prompt[200];
sprintf(prompt, "%s@%s's password: ", cfg.username, savedhost);
if (!ssh_get_password(prompt, password, sizeof(password))) {
if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD)
c_write("password: ", 10);
if (pwpkt_type == SSH1_CMSG_AUTH_RSA) {
- c_write("Trying public key authentication.\r\n", 35);
+ if (flags & FLAG_VERBOSE)
+ c_write("Trying public key authentication.\r\n", 35);
if (!rsakey_encrypted(cfg.keyfile)) {
- c_write("No passphrase required.\r\n", 25);
+ if (flags & FLAG_VERBOSE)
+ c_write("No passphrase required.\r\n", 25);
goto tryauth;
}
c_write("passphrase: ", 12);
crWaitUntil(ispkt);
if (pktin.type == SSH1_SMSG_FAILURE) {
- c_write("Server refused our public key.\r\n", 32);
+ if (flags & FLAG_VERBOSE)
+ c_write("Server refused our public key.\r\n", 32);
continue; /* go and try password */
}
if (pktin.type != SSH1_SMSG_AUTH_RSA_CHALLENGE)
crWaitUntil(ispkt);
if (pktin.type == SSH1_SMSG_FAILURE) {
- c_write("Failed to authenticate with our public key.\r\n", 45);
+ if (flags & FLAG_VERBOSE)
+ c_write("Failed to authenticate with our public key.\r\n",
+ 45);
continue; /* go and try password */
} else if (pktin.type != SSH1_SMSG_SUCCESS) {
fatalbox("Bizarre response to RSA authentication response");
memset(password, 0, strlen(password));
crWaitUntil(ispkt);
if (pktin.type == SSH1_SMSG_FAILURE) {
- c_write("Access denied\r\n", 15);
+ if (flags & FLAG_VERBOSE)
+ c_write("Access denied\r\n", 15);
logevent("Authentication refused");
} else if (pktin.type == SSH1_MSG_DISCONNECT) {
logevent("Received disconnect request");
logevent("Allocated pty");
}
- send_packet(SSH1_CMSG_EXEC_SHELL, PKT_END);
+ if (*cfg.remote_cmd)
+ send_packet(SSH1_CMSG_EXEC_CMD, PKT_STR, cfg.remote_cmd, PKT_END);
+ else
+ send_packet(SSH1_CMSG_EXEC_SHELL, PKT_END);
logevent("Started session");
ssh_state = SSH_STATE_SESSION;
if (size_needed)
ssh_size();
+ ssh_send_ok = 1;
while (1) {
crReturnV;
if (ispkt) {
}
/*
+ * SSH2: remote identifier for the main session channel.
+ */
+static unsigned long ssh_remote_channel;
+
+/*
* Handle the SSH2 userauth and connection layers.
*/
static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
{
- static unsigned long their_channel;
static unsigned long remote_winsize;
static unsigned long remote_maxpkt;
static int pos = 0;
static char c;
- if (!IS_SCP && !*cfg.username) {
+ if ((flags & FLAG_CONNECTION) && !*cfg.username) {
c_write("login as: ", 10);
while (pos >= 0) {
crWaitUntilV(!ispkt);
char stuff[200];
strncpy(username, cfg.username, 99);
username[99] = '\0';
- if (!IS_SCP) {
+ if (flags & FLAG_VERBOSE) {
sprintf(stuff, "Using username \"%s\".\r\n", username);
c_write(stuff, strlen(stuff));
}
}
- if (IS_SCP) {
+ if (!(flags & FLAG_WINDOWED)) {
char prompt[200];
sprintf(prompt, "%s@%s's password: ", cfg.username, savedhost);
if (!ssh_get_password(prompt, password, sizeof(password))) {
if (ssh2_pkt_getuint32() != 100) {
fatalbox("Server's channel confirmation cited wrong channel");
}
- their_channel = ssh2_pkt_getuint32();
+ ssh_remote_channel = ssh2_pkt_getuint32();
remote_winsize = ssh2_pkt_getuint32();
remote_maxpkt = ssh2_pkt_getuint32();
logevent("Opened channel for session");
* Now allocate a pty for the session.
*/
ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
- ssh2_pkt_adduint32(their_channel); /* recipient channel */
+ ssh2_pkt_adduint32(ssh_remote_channel); /* recipient channel */
ssh2_pkt_addstring("pty-req");
ssh2_pkt_addbool(1); /* want reply */
ssh2_pkt_addstring(cfg.termtype);
* Start a shell.
*/
ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
- ssh2_pkt_adduint32(their_channel); /* recipient channel */
+ ssh2_pkt_adduint32(ssh_remote_channel); /* recipient channel */
ssh2_pkt_addstring("shell");
ssh2_pkt_addbool(1); /* want reply */
ssh2_pkt_send();
/*
* Transfer data!
*/
+ ssh_send_ok = 1;
while (1) {
crReturnV;
if (ispkt) {
} else {
/* FIXME: for now, ignore window size */
ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA);
- ssh2_pkt_adduint32(their_channel);
+ ssh2_pkt_adduint32(ssh_remote_channel);
ssh2_pkt_addstring_start();
ssh2_pkt_addstring_data(in, inlen);
ssh2_pkt_send();
if (!do_ssh_init())
return "Protocol initialisation error";
- if (WSAAsyncSelect (s, hwnd, WM_NETEVENT, FD_READ | FD_CLOSE) == SOCKET_ERROR)
+ if (hwnd && WSAAsyncSelect (s, hwnd, WM_NETEVENT, FD_READ | FD_CLOSE) == SOCKET_ERROR)
switch (WSAGetLastError()) {
case WSAENETDOWN: return "Network is down";
default: return "WSAAsyncSelect(): unknown error";
}
/*
- * (Send Telnet special codes)
+ * Send Telnet special codes. TS_EOF is useful for `plink', so you
+ * can send an EOF and collect resulting output (e.g. `plink
+ * hostname sort').
*/
static void ssh_special (Telnet_Special code) {
- /* do nothing */
+ if (code == TS_EOF) {
+ if (ssh_version = 1) {
+ send_packet(SSH1_CMSG_EOF, PKT_END);
+ } else {
+ ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF);
+ ssh2_pkt_adduint32(ssh_remote_channel);
+ ssh2_pkt_send();
+ }
+ } else {
+ /* do nothing */
+ }
}
long to_read;
int len;
- assert(IS_SCP);
-
p = NULL;
len = 0;
static unsigned char *pending_input_ptr;
int to_read = len;
- assert(IS_SCP);
-
if (pending_input_len >= to_read) {
memcpy(buf, pending_input_ptr, to_read);
pending_input_ptr += to_read;
*/
void ssh_scp_send(unsigned char *buf, int len)
{
- assert(IS_SCP);
if (s == INVALID_SOCKET)
return;
send_packet(SSH1_CMSG_STDIN_DATA,
*/
void ssh_scp_send_eof(void)
{
- assert(IS_SCP);
if (s == INVALID_SOCKET)
return;
send_packet(SSH1_CMSG_EOF, PKT_END);
{
char buf[160], *p;
- assert(IS_SCP);
-
#ifdef MSCRYPTOAPI
if (crypto_startup() == 0)
return "Microsoft high encryption pack not installed!";
return NULL;
}
+static SOCKET ssh_socket(void) { return s; }
+
+static int ssh_sendok(void) { return ssh_send_ok; }
Backend ssh_backend = {
ssh_init,
ssh_msg,
ssh_send,
ssh_size,
- ssh_special
+ ssh_special,
+ ssh_socket,
+ ssh_sendok
};