Skip to content

Commit f5226a3

Browse files
committed
Added PTY support to account for client TTY window size changes
1 parent d6a1ff4 commit f5226a3

File tree

7 files changed

+65
-112
lines changed

7 files changed

+65
-112
lines changed

channels.c

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3895,7 +3895,6 @@ channel_connect_to_path(const char *path, char *ctype, char *rname)
38953895
return connect_to(path, PORT_STREAMLOCAL, ctype, rname);
38963896
}
38973897

3898-
#ifndef WIN32_FIXME//N
38993898
void
39003899
channel_send_window_changes(void)
39013900
{
@@ -3907,8 +3906,21 @@ channel_send_window_changes(void)
39073906
if (channels[i] == NULL || !channels[i]->client_tty ||
39083907
channels[i]->type != SSH_CHANNEL_OPEN)
39093908
continue;
3909+
#ifndef WIN32_FIXME
39103910
if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0)
3911-
continue;
3911+
continue
3912+
#else
3913+
{
3914+
CONSOLE_SCREEN_BUFFER_INFO c_info;
3915+
/* TODO - Fix this for multiple channels*/
3916+
if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &c_info))
3917+
continue;
3918+
ws.ws_col = c_info.dwSize.X;
3919+
ws.ws_row = c_info.dwSize.Y;
3920+
ws.ws_xpixel = 640;
3921+
ws.ws_ypixel = 480;
3922+
}
3923+
#endif
39123924
channel_request_start(i, "window-change", 0);
39133925
packet_put_int((u_int)ws.ws_col);
39143926
packet_put_int((u_int)ws.ws_row);
@@ -3918,27 +3930,6 @@ channel_send_window_changes(void)
39183930
}
39193931
}
39203932

3921-
#else // WIN32_FIXME
3922-
void
3923-
channel_send_window_changes(int col, int row, int xpixel, int ypixel)
3924-
{
3925-
u_int i;
3926-
struct winsize ws;
3927-
3928-
for (i = 0; i < channels_alloc; i++) {
3929-
if (channels[i] == NULL || !channels[i]->client_tty ||
3930-
channels[i]->type != SSH_CHANNEL_OPEN)
3931-
continue;
3932-
channel_request_start(i, "window-change", 0);
3933-
packet_put_int((u_int)col);
3934-
packet_put_int((u_int)row);
3935-
packet_put_int((u_int)xpixel);
3936-
packet_put_int((u_int)ypixel);
3937-
packet_send();
3938-
}
3939-
}
3940-
#endif
3941-
39423933

39433934
/* -- X11 forwarding */
39443935

channels.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,7 @@ void channel_register_status_confirm(int, channel_confirm_cb *,
226226
channel_confirm_abandon_cb *, void *);
227227
void channel_cancel_cleanup(int);
228228
int channel_close_fd(int *);
229-
#ifndef WIN32_FIXME
230229
void channel_send_window_changes(void);
231-
#else
232-
void channel_send_window_changes(int, int, int, int);
233-
#endif
234230

235231

236232
/* protocol handler */

clientloop.c

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ client_make_packets_from_stdin_data(void)
537537
static void
538538
client_check_window_change(void)
539539
{
540-
#ifndef WIN32_FIXME
540+
541541
struct winsize ws;
542542

543543
if (! received_window_change_signal)
@@ -550,6 +550,7 @@ client_check_window_change(void)
550550
if (compat20) {
551551
channel_send_window_changes();
552552
} else {
553+
#ifndef WIN32_FIXME
553554
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
554555
return;
555556
packet_start(SSH_CMSG_WINDOW_SIZE);
@@ -558,27 +559,8 @@ client_check_window_change(void)
558559
packet_put_int((u_int)ws.ws_xpixel);
559560
packet_put_int((u_int)ws.ws_ypixel);
560561
packet_send();
562+
#endif
561563
}
562-
#else
563-
564-
if (! win_received_window_change_signal)
565-
return;
566-
/** XXX race */
567-
win_received_window_change_signal = 0;
568-
569-
debug2("client_check_window_change: changed");
570-
571-
if (compat20) {
572-
channel_send_window_changes(ScreenX, ScrollBottom, 640, 480);
573-
} else {
574-
packet_start(SSH_CMSG_WINDOW_SIZE);
575-
packet_put_int((u_int)ScreenX);
576-
packet_put_int((u_int)ScrollBottom);
577-
packet_put_int((u_int)640);
578-
packet_put_int((u_int)480);
579-
packet_send();
580-
}
581-
#endif /* !WIN32_FIXME */
582564
}
583565

584566
static int

contrib/win32/win32compat/signal.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,20 @@ native_sig_handler(DWORD dwCtrlType)
8686
}
8787
}
8888

89+
static VOID CALLBACK
90+
sigwinch_APCProc(
91+
_In_ ULONG_PTR dwParam
92+
) {
93+
debug3("SIGTERM APCProc()");
94+
sigaddset(&pending_signals, W32_SIGWINCH);
95+
}
96+
97+
98+
void
99+
queue_terminal_window_change_event() {
100+
QueueUserAPC(sigwinch_APCProc, main_thread, (ULONG_PTR)NULL);
101+
}
102+
89103
void
90104
sw_init_signal_handler_table() {
91105
int i;
@@ -163,7 +177,7 @@ sw_process_pending_signals() {
163177
BOOL sig_int = FALSE; /* has any signal actually interrupted */
164178

165179
debug3("process_signals()");
166-
int i, exp[] = { W32_SIGCHLD , W32_SIGINT , W32_SIGALRM, W32_SIGTERM, W32_SIGTSTP };
180+
int i, exp[] = { W32_SIGCHLD , W32_SIGINT , W32_SIGALRM, W32_SIGTERM, W32_SIGTSTP, W32_SIGWINCH };
167181

168182
/* check for expected signals*/
169183
for (i = 0; i < (sizeof(exp) / sizeof(exp[0])); i++)

contrib/win32/win32compat/tncon.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ BOOL DataAvailable(HANDLE h)
116116
return FALSE;
117117
}
118118

119+
void queue_terminal_window_change_event();
120+
119121
int ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
120122
{
121123
HANDLE hHandle[] = { hInput, NULL };
@@ -148,11 +150,7 @@ int ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
148150
switch (InputRecord.EventType)
149151
{
150152
case WINDOW_BUFFER_SIZE_EVENT:
151-
memcpy(szResponse, NAWSSTR, 9);
152-
szResponse[4] = ConScreenSizeX();
153-
szResponse[6] = ConWindowSizeY();
154-
ScreenX = ConScreenSizeX();
155-
ScreenY = ConWindowSizeY();
153+
queue_terminal_window_change_event();
156154
break;
157155

158156
case FOCUS_EVENT:

session.c

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,10 @@ do_authenticated1(Authctxt *authctxt)
497497
#define USE_PIPES 1
498498
#endif
499499

500+
#ifdef WIN32_FIXME
501+
extern int debug_flag;
502+
#endif
503+
500504
/*
501505
* This is called to fork and execute a command when we have no tty. This
502506
* will call do_child from the child, and server_loop from the parent after
@@ -548,8 +552,6 @@ do_exec_no_pty(Session *s, const char *command)
548552
char *exec_command;
549553
char *laddr;
550554
char buf[256];
551-
int prot_scr_width = 80;
552-
int prot_scr_height = 25;
553555
#ifdef WIN32_PRAGMA_REMCON
554556
char exec_command_str[512];
555557
#endif
@@ -590,8 +592,6 @@ do_exec_no_pty(Session *s, const char *command)
590592
int retcode = -1;
591593
if ( (!s -> is_subsystem) && (s ->ttyfd != -1))
592594
{
593-
prot_scr_width = s->col;
594-
prot_scr_height = s->row;
595595
extern HANDLE hInputConsole;
596596
extern HANDLE hOutputConsole ;
597597
hInputConsole = GetConsoleInputHandle();
@@ -620,10 +620,10 @@ do_exec_no_pty(Session *s, const char *command)
620620
si.lpTitle = NULL; /* NULL means use exe name as title */
621621
si.dwX = 0;
622622
si.dwY = 0;
623-
si.dwXSize = 640;
624-
si.dwYSize = 480;
625-
si.dwXCountChars = prot_scr_width;
626-
si.dwYCountChars = prot_scr_height;
623+
si.dwXSize = 5;
624+
si.dwYSize = 5;
625+
si.dwXCountChars = s->col;
626+
si.dwYCountChars = s->row;
627627
si.dwFillAttribute = 0;
628628
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESIZE | STARTF_USECOUNTCHARS;
629629
si.wShowWindow = 0; // FALSE ;
@@ -794,32 +794,35 @@ do_exec_no_pty(Session *s, const char *command)
794794
wchar_t exec_command_w[MAX_PATH];
795795

796796
MultiByteToWideChar(CP_UTF8, 0, exec_command, -1, exec_command_w, MAX_PATH);
797-
DWORD dwStartupFlags = 0;// CREATE_SUSPENDED; // 0
797+
DWORD dwStartupFlags = DETACHED_PROCESS;// CREATE_SUSPENDED; // 0
798798

799799
SetConsoleCtrlHandler(NULL, FALSE);
800-
b = CreateProcessAsUserW(hToken, NULL, exec_command_w, NULL, NULL, TRUE,
800+
if (debug_flag)
801+
b = CreateProcessW(NULL, exec_command_w, NULL, NULL, TRUE,
802+
/*CREATE_NEW_PROCESS_GROUP*/ dwStartupFlags, NULL, s->pw->pw_dir,
803+
&si, &pi);
804+
else
805+
b = CreateProcessAsUserW(hToken, NULL, exec_command_w, NULL, NULL, TRUE,
801806
/*CREATE_NEW_PROCESS_GROUP*/ dwStartupFlags, NULL, s -> pw -> pw_dir,
802807
&si, &pi);
803-
/*
804-
* If CreateProcessAsUser() fails we will try CreateProcess()
805-
* but only if current user and login user are the same.
806-
*/
807-
808-
if ((!b) && (strcmp(name, s -> pw -> pw_name) == 0))
809-
{
810-
b = CreateProcessW(NULL, exec_command_w, NULL, NULL, TRUE,
811-
/*CREATE_NEW_PROCESS_GROUP*/ dwStartupFlags, NULL, s -> pw -> pw_dir,
812-
&si, &pi);
813-
}
814-
815808
if (!b)
816809
{
817-
debug("ERROR. Cannot create process as new user (%u).\n", GetLastError());
810+
debug("ERROR. Cannot create process (%u).\n", GetLastError());
818811

819812
CloseHandle(hToken);
820813

821814
exit(1);
822815
}
816+
else {
817+
FreeConsole();
818+
if (!debug_flag)
819+
ImpersonateLoggedOnUser(hToken);
820+
while (AttachConsole(pi.dwProcessId) == FALSE) {
821+
Sleep(200);
822+
}
823+
if (!debug_flag)
824+
RevertToSelf();
825+
}
823826

824827
/*
825828
* Save token used for create child process. We'll need it on cleanup

sshpty.c

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -197,32 +197,6 @@ pty_make_controlling_tty(int *ttyfd, const char *tty)
197197
#endif
198198
}
199199

200-
#ifdef WIN32_PRAGMA_REMCON
201-
/* Changes the window size associated with the pty. */
202-
203-
void pty_change_window_size_oob(int ptyfd, u_int row, u_int col, u_int xpixel, u_int ypixel)
204-
{
205-
int rc;
206-
char unsigned data[16];
207-
size_t data_len;
208-
209-
// IAC SB NAWS <16-bit value width> <16-bit value height> IAC
210-
//sprintf (data,"%c%c%c%c%c%c%c%c", 255, 250, 31, 0, col, 0, row, 255 );
211-
data[0] = 255; // IAC;
212-
data[1] = 250; // SB
213-
data[2] = 31; // NAWS
214-
data[3] = 0;
215-
data[4] = (unsigned char)col;
216-
data[5] = 0;
217-
data[6] = (unsigned char)row;
218-
data[7] = 255; // IAC
219-
data[8] = 240; // iac end
220-
data_len = 9; //strlen (data);
221-
rc = write(ptyfd, data, (DWORD)data_len);
222-
//rc = AsyncWrite(c->hInputHandle, (char *)data, (DWORD)data_len);
223-
}
224-
225-
#endif
226200
/* Changes the window size associated with the pty. */
227201

228202
void
@@ -239,15 +213,10 @@ pty_change_window_size(int ptyfd, u_int row, u_int col,
239213
w.ws_ypixel = ypixel;
240214
(void) ioctl(ptyfd, TIOCSWINSZ, &w);
241215
#else
242-
extern HANDLE hOutputConsole ;
243-
#ifndef WIN32_PRAGMA_REMCON
244-
if (hOutputConsole != NULL) {
245-
ConSetScreenSize(col, row);
246-
}
247-
#else
248-
if (ptyfd > 0 )
249-
pty_change_window_size_oob(ptyfd, row, col, xpixel, ypixel);
250-
#endif
216+
COORD coord;
217+
coord.X = col;
218+
coord.Y = row;
219+
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coord);
251220
#endif
252221
}
253222

0 commit comments

Comments
 (0)