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:
parent
ea8d61f2d9
commit
180b62b6b0
53
plink.c
53
plink.c
@ -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
18
putty.h
@ -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
2
scp.c
@ -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
1
scp.h
@ -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
86
ssh.c
@ -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 */
|
||||
}
|
||||
|
2
window.c
2
window.c
@ -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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user