1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00

Miscellaneous ssh2 fixes. plink is now relatively sane

[originally from svn r608]
This commit is contained in:
Simon Tatham 2000-09-21 14:34:32 +00:00
parent ea8d61f2d9
commit 180b62b6b0
6 changed files with 122 additions and 40 deletions

53
plink.c
View File

@ -43,6 +43,50 @@ struct input_data {
HANDLE event;
};
static int get_password(const char *prompt, char *str, int maxlen)
{
HANDLE hin, hout;
DWORD savemode, i;
#if 0 /* this allows specifying a password some other way */
if (password) {
static int tried_once = 0;
if (tried_once) {
return 0;
} else {
strncpy(str, password, maxlen);
str[maxlen-1] = '\0';
tried_once = 1;
return 1;
}
}
#endif
hin = GetStdHandle(STD_INPUT_HANDLE);
hout = GetStdHandle(STD_OUTPUT_HANDLE);
if (hin == INVALID_HANDLE_VALUE || hout == INVALID_HANDLE_VALUE) {
fprintf(stderr, "Cannot get standard input/output handles");
return 0;
}
GetConsoleMode(hin, &savemode);
SetConsoleMode(hin, (savemode & (~ENABLE_ECHO_INPUT)) |
ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT);
WriteFile(hout, prompt, strlen(prompt), &i, NULL);
ReadFile(hin, str, maxlen-1, &i, NULL);
SetConsoleMode(hin, savemode);
if ((int)i > maxlen) i = maxlen-1; else i = i - 2;
str[i] = '\0';
WriteFile(hout, "\r\n", 2, &i, NULL);
return 1;
}
int WINAPI stdin_read_thread(void *param) {
struct input_data *idata = (struct input_data *)param;
HANDLE inhandle;
@ -70,7 +114,9 @@ int main(int argc, char **argv) {
struct input_data idata;
int sending;
flags = FLAG_CONNECTION;
ssh_get_password = get_password;
flags = FLAG_STDERR;
/*
* Process the command line.
*/
@ -83,6 +129,8 @@ int main(int argc, char **argv) {
if (!strcmp(p, "-ssh")) {
default_protocol = cfg.protocol = PROT_SSH;
default_port = cfg.port = 22;
} else if (!strcmp(p, "-v")) {
flags |= FLAG_VERBOSE;
} else if (!strcmp(p, "-log")) {
logfile = "putty.log";
}
@ -165,6 +213,9 @@ int main(int argc, char **argv) {
}
}
if (!*cfg.remote_cmd)
flags |= FLAG_INTERACTIVE;
/*
* Select protocol. This is farmed out into a table in a
* separate file to enable an ssh-free variant.

18
putty.h
View File

@ -203,10 +203,21 @@ typedef struct {
/*
* Some global flags denoting the type of application.
*
* FLAG_VERBOSE is set when the user requests verbose details.
*
* FLAG_STDERR is set in command-line applications (which have a
* functioning stderr that it makes sense to write to) and not in
* GUI applications (which don't).
*
* FLAG_INTERACTIVE is set when a full interactive shell session is
* being run, _either_ because no remote command has been provided
* _or_ because the application is GUI and can't run non-
* interactively.
*/
#define FLAG_VERBOSE 0x0001
#define FLAG_WINDOWED 0x0002
#define FLAG_CONNECTION 0x0004
#define FLAG_VERBOSE 0x0001
#define FLAG_STDERR 0x0002
#define FLAG_INTERACTIVE 0x0004
GLOBAL int flags;
GLOBAL Config cfg;
@ -292,6 +303,7 @@ extern Backend telnet_backend;
* Exports from ssh.c.
*/
extern int (*ssh_get_password)(const char *prompt, char *str, int maxlen);
extern Backend ssh_backend;
/*

2
scp.c
View File

@ -957,7 +957,7 @@ int main(int argc, char *argv[])
default_protocol = PROT_TELNET;
flags = 0;
flags = FLAG_STDERR;
ssh_get_password = &get_password;
init_winsock();

1
scp.h
View File

@ -5,7 +5,6 @@
/* Exported from ssh.c */
extern int scp_flags;
extern int (*ssh_get_password)(const char *prompt, char *str, int maxlen);
char * ssh_scp_init(char *host, int port, char *cmd, char **realhost);
int ssh_scp_recv(unsigned char *buf, int len);
void ssh_scp_send(unsigned char *buf, int len);

86
ssh.c
View File

@ -17,7 +17,7 @@
#endif
#define logevent(s) { logevent(s); \
if (!(flags & FLAG_CONNECTION) && (flags & FLAG_VERBOSE)) \
if ((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)) \
fprintf(stderr, "%s\n", s); }
#define SSH1_MSG_DISCONNECT 1 /* 0x1 */
@ -269,7 +269,7 @@ static int s_read (char *buf, int len) {
}
static void c_write (char *buf, int len) {
if (!(flags & FLAG_CONNECTION)) {
if ((flags & FLAG_STDERR)) {
int i;
for (i = 0; i < len; i++)
if (buf[i] != '\r')
@ -1190,8 +1190,9 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
static char username[100];
static int pos = 0;
static char c;
if ((flags & FLAG_CONNECTION) && !*cfg.username) {
if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
c_write("login as: ", 10);
ssh_send_ok = 1;
while (pos >= 0) {
crWaitUntil(!ispkt);
while (inlen--) switch (c = *in++) {
@ -1230,7 +1231,7 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
char stuff[200];
strncpy(username, cfg.username, 99);
username[99] = '\0';
if (flags & FLAG_VERBOSE) {
if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
sprintf(stuff, "Sent username \"%s\".\r\n", username);
c_write(stuff, strlen(stuff));
}
@ -1362,7 +1363,8 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
if (*cfg.keyfile && !tried_publickey)
pwpkt_type = SSH1_CMSG_AUTH_RSA;
if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD && !FLAG_WINDOWED) {
if (pwpkt_type == SSH1_CMSG_AUTH_PASSWORD &&
!(flags & FLAG_INTERACTIVE)) {
char prompt[200];
sprintf(prompt, "%s@%s's password: ", cfg.username, savedhost);
if (!ssh_get_password(prompt, password, sizeof(password))) {
@ -1431,6 +1433,7 @@ static int do_ssh1_login(unsigned char *in, int inlen, int ispkt)
}
pos = 0;
ssh_send_ok = 1;
while (pos >= 0) {
crWaitUntil(!ispkt);
while (inlen--) switch (c = *in++) {
@ -2079,8 +2082,9 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
static int pos = 0;
static char c;
if ((flags & FLAG_CONNECTION) && !*cfg.username) {
if ((flags & FLAG_INTERACTIVE) && !*cfg.username) {
c_write("login as: ", 10);
ssh_send_ok = 1;
while (pos >= 0) {
crWaitUntilV(!ispkt);
while (inlen--) switch (c = *in++) {
@ -2119,13 +2123,13 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
char stuff[200];
strncpy(username, cfg.username, 99);
username[99] = '\0';
if (flags & FLAG_VERBOSE) {
if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
sprintf(stuff, "Using username \"%s\".\r\n", username);
c_write(stuff, strlen(stuff));
}
}
if (!(flags & FLAG_WINDOWED)) {
if (!(flags & FLAG_INTERACTIVE)) {
char prompt[200];
sprintf(prompt, "%s@%s's password: ", cfg.username, savedhost);
if (!ssh_get_password(prompt, password, sizeof(password))) {
@ -2141,6 +2145,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
}
} else {
c_write("password: ", 10);
ssh_send_ok = 1;
pos = 0;
while (pos >= 0) {
@ -2222,39 +2227,53 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
/*
* Now allocate a pty for the session.
*/
ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(mainchan->remoteid); /* recipient channel */
ssh2_pkt_addstring("pty-req");
ssh2_pkt_addbool(1); /* want reply */
ssh2_pkt_addstring(cfg.termtype);
ssh2_pkt_adduint32(cols);
ssh2_pkt_adduint32(rows);
ssh2_pkt_adduint32(0); /* pixel width */
ssh2_pkt_adduint32(0); /* pixel height */
ssh2_pkt_addstring_start();
ssh2_pkt_addstring_data("\0", 1); /* TTY_OP_END, no special options */
ssh2_pkt_send();
if (!cfg.nopty) {
ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(mainchan->remoteid); /* recipient channel */
ssh2_pkt_addstring("pty-req");
ssh2_pkt_addbool(1); /* want reply */
ssh2_pkt_addstring(cfg.termtype);
ssh2_pkt_adduint32(cols);
ssh2_pkt_adduint32(rows);
ssh2_pkt_adduint32(0); /* pixel width */
ssh2_pkt_adduint32(0); /* pixel height */
ssh2_pkt_addstring_start();
ssh2_pkt_addstring_data("\0", 1);/* TTY_OP_END, no special options */
ssh2_pkt_send();
do { /* FIXME: pay attention to these */
crWaitUntilV(ispkt);
} while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);
do {
crWaitUntilV(ispkt);
if (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST) {
/* FIXME: be able to handle other channels here */
if (ssh2_pkt_getuint32() != mainchan->localid)
continue; /* wrong channel */
mainchan->u.v2.remwindow += ssh2_pkt_getuint32();
}
} while (pktin.type == SSH2_MSG_CHANNEL_WINDOW_ADJUST);
if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) {
if (pktin.type != SSH2_MSG_CHANNEL_FAILURE) {
fatalbox("Server got confused by pty request");
if (pktin.type != SSH2_MSG_CHANNEL_SUCCESS) {
if (pktin.type != SSH2_MSG_CHANNEL_FAILURE) {
fatalbox("Server got confused by pty request");
}
c_write("Server refused to allocate pty\r\n", 32);
} else {
logevent("Allocated pty");
}
c_write("Server refused to allocate pty\r\n", 32);
} else {
logevent("Allocated pty");
}
/*
* Start a shell.
* Start a shell or a remote command.
*/
ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(mainchan->remoteid); /* recipient channel */
ssh2_pkt_addstring("shell");
ssh2_pkt_addbool(1); /* want reply */
if (*cfg.remote_cmd) {
ssh2_pkt_addstring("exec");
ssh2_pkt_addbool(1); /* want reply */
ssh2_pkt_addstring(cfg.remote_cmd);
} else {
ssh2_pkt_addstring("shell");
ssh2_pkt_addbool(1); /* want reply */
}
ssh2_pkt_send();
do {
crWaitUntilV(ispkt);
@ -2502,13 +2521,14 @@ static void ssh_size(void) {
*/
static void ssh_special (Telnet_Special code) {
if (code == TS_EOF) {
if (ssh_version = 1) {
if (ssh_version == 1) {
send_packet(SSH1_CMSG_EOF, PKT_END);
} else {
ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF);
ssh2_pkt_adduint32(mainchan->remoteid);
ssh2_pkt_send();
}
logevent("Sent EOF message");
} else {
/* do nothing */
}

View File

@ -90,7 +90,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
int guess_width, guess_height;
putty_inst = inst;
flags = FLAG_VERBOSE | FLAG_WINDOWED | FLAG_CONNECTION;
flags = FLAG_VERBOSE | FLAG_INTERACTIVE;
winsock_ver = MAKEWORD(1, 1);
if (WSAStartup(winsock_ver, &wsadata)) {