diff --git a/channels.c b/channels.c index 408dee7..e7d2a51 100644 --- a/channels.c +++ b/channels.c @@ -42,6 +42,7 @@ #include "includes.h" #ifdef WIN32_FIXME +//#define WIN32_PRAGMA_REMCON #ifdef ECONNABORTED #undef ECONNABORTED #endif @@ -2482,6 +2483,9 @@ channel_input_data(int type, u_int32_t seq, void *ctxt) if ( c->client_tty ) telProcessNetwork ( data, data_len ); // run it by ANSI engine if it is the ssh client else { + #ifdef WIN32_PRAGMA_REMCON + buffer_append(&c->output, data, data_len); // it is the sshd server, so pass it on + #else if ( ( c->isatty) && (data_len ==1) && (data[0] == '\003') ) { /* send control-c to the shell process */ if ( GenerateConsoleCtrlEvent ( CTRL_C_EVENT, 0 ) ) { @@ -2492,7 +2496,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt) } else { // avoid sending the 4 arrow keys out to remote for now "ESC[A" .. - if ( (c->isatty) && (data_len ==3) && (data[0] == '\033') && (data[1] == '[')) { + if ( (c->isatty) && (data_len ==3) && (data[0] == '\033') && (data[1] == '[')) { if ( ( data[2] == 'A') || (data[2] == 'B') || (data[2] == 'C') || (data[2] == 'D')) packet_check_eom(); return 0; @@ -2515,6 +2519,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt) charinline = 0; // a line has ended, begin char in line count again } } + #endif // WIN32_PRAGMA_REMCON } #endif diff --git a/contrib/win32/openssh/config.h.vs b/contrib/win32/openssh/config.h.vs index b673805..5035572 100644 --- a/contrib/win32/openssh/config.h.vs +++ b/contrib/win32/openssh/config.h.vs @@ -1707,5 +1707,7 @@ struct iovec // define building with MS Visual Studio Compiler and runtime and not with MingW/gcc compiler #define WIN32_VS 1 - +// Use Pragma Systems Remote Console modules for shell sessions so that cmd/powershell fully +// works remotely over SSH like they operate in a local machine +//#define WIN32_PRAGMA_REMCON diff --git a/session.c b/session.c index af08490..a01b7eb 100644 --- a/session.c +++ b/session.c @@ -42,6 +42,7 @@ #undef GSSAPI #undef KRB5 #define WIN32_USER_AUTH 1 + //#define WIN32_PRAGMA_REMCON #endif #include @@ -589,11 +590,20 @@ do_exec_no_pty(Session *s, const char *command) char buf[256]; int prot_scr_width = 80; int prot_scr_height = 25; + #ifdef WIN32_PRAGMA_REMCON + char exec_command_str[512]; + #endif if (!command) { + #ifndef WIN32_PRAGMA_REMCON exec_command = s->pw->pw_shell; - //exec_command = "c:\\tools\\echoit.exe"; // temp + #else + snprintf(exec_command_str, sizeof(exec_command_str), + "\\program files\\pragma\\shared files\\cmdserver.exe SSHD %d %d", + s->row, s->col ); + exec_command = exec_command_str; + #endif } else { @@ -606,28 +616,42 @@ do_exec_no_pty(Session *s, const char *command) * Create three socket pairs for stdin, stdout and stderr */ - HANDLE wfdtocmd = -1; + #ifdef WIN32_PRAGMA_REMCON + int retcode = -1; if ( (!s -> is_subsystem) && (s ->ttyfd != -1)) { - //FreeConsole(); - //AllocConsole(); - MakeNewConsole(); prot_scr_width = s->col; prot_scr_height = s->row; extern HANDLE hConsole ; hConsole = GetStdHandle (STD_OUTPUT_HANDLE); ConSetScreenSize( s->col, s->row ); - s->ptyfd = hConsole ; // the pty is the Windows console output handle in our Win32 port - - wfdtocmd = GetStdHandle (STD_INPUT_HANDLE) ; // we use this console handle to feed input to Windows shell cmd.exe - sockin[1] = allocate_sfd((int)wfdtocmd); // put the std input handle in our global general handle table - //if (sockin[1] >= 0) - // sfd_set_to_console(sockin[1]); // mark it as Console type - + socketpair(sockin); + s->ptyfd = sockin[1]; // hConsole; // the pty is the Windows console output handle in our Win32 port } else socketpair(sockin); + #else + HANDLE wfdtocmd = -1; + int retcode = -1; + if ((!s->is_subsystem) && (s->ttyfd != -1)) + { + //FreeConsole(); + //AllocConsole(); + MakeNewConsole(); + prot_scr_width = s->col; + prot_scr_height = s->row; + extern HANDLE hConsole; + hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + ConSetScreenSize(s->col, s->row); + s->ptyfd = hConsole; // the pty is the Windows console output handle in our Win32 port + + wfdtocmd = GetStdHandle(STD_INPUT_HANDLE); // we use this console handle to feed input to Windows shell cmd.exe + sockin[1] = allocate_sfd((int)wfdtocmd); // put the std input handle in our global general handle table + } + else + socketpair(sockin); + #endif socketpair(sockout); socketpair(sockerr); @@ -636,12 +660,14 @@ do_exec_no_pty(Session *s, const char *command) debug3("sockout[0]: %d sockout[1]: %d", sockout[0], sockout[1]); debug3("sockerr[0]: %d sockerr[1]: %d", sockerr[0], sockerr[1]); + #ifndef WIN32_PRAGMA_REMCON if ( (s -> is_subsystem) || (s ->ttyfd == -1)) crlf_sfd(sockin[1]); crlf_sfd(sockout[1]); if ( (s -> is_subsystem) || (s ->ttyfd == -1)) + #endif SetHandleInformation(sfd_to_handle(sockin[1]), HANDLE_FLAG_INHERIT, 0); SetHandleInformation(sfd_to_handle(sockout[1]), HANDLE_FLAG_INHERIT, 0); @@ -668,11 +694,16 @@ do_exec_no_pty(Session *s, const char *command) si.cbReserved2 = 0; si.lpReserved2 = 0; + #ifdef WIN32_PRAGMA_REMCON + if (0) { + #else if ( (!s -> is_subsystem) && (s ->ttyfd != -1) ) { + si.hStdInput = GetStdHandle (STD_INPUT_HANDLE) ; // shell tty interactive session gets a console input for Win32 si.hStdOutput = (HANDLE) sfd_to_handle(sockout[0]); si.hStdError = (HANDLE) sfd_to_handle(sockerr[0]); si.lpDesktop = NULL ; //winstadtname_w ; + #endif } else { si.hStdInput = (HANDLE) sfd_to_handle(sockin[0]); @@ -889,6 +920,7 @@ do_exec_no_pty(Session *s, const char *command) GetUserName(name, &size); +#ifndef WIN32_PRAGMA_REMCON if ( (!s -> is_subsystem) && (s ->ttyfd != -1)) { // Send to the remote client ANSI/VT Sequence so that they send us CRLF in place of LF char *inittermseq = "\033[20h\033[?7h\0" ; // LFtoCRLF AUTOWRAPON @@ -896,6 +928,7 @@ do_exec_no_pty(Session *s, const char *command) buffer_append(&c->input, inittermseq, strlen(inittermseq)); channel_output_poll(); } +#endif //if (s ->ttyfd != -1) { // set the channel to tty interactive type @@ -975,8 +1008,12 @@ do_exec_no_pty(Session *s, const char *command) /* * We are the parent. Close the child sides of the socket pairs. */ + #ifndef WIN32_PRAGMA_REMCON if ( (s -> is_subsystem) || (s ->ttyfd == -1)) close(sockin[0]); + #else + close(sockin[0]); + #endif close(sockout[0]); close(sockerr[0]); @@ -2734,7 +2771,9 @@ session_pty_req(Session *s) /* for SSH1 the tty modes length is not given */ if (!compat20) n_bytes = packet_remaining(); + #ifndef WIN32_PRAGMA_REMCON tty_parse_modes(s->ttyfd, &n_bytes); + #endif if (!use_privsep) pty_setowner(s->pw, s->tty); @@ -2744,7 +2783,9 @@ session_pty_req(Session *s) pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); #endif + #ifndef WIN32_PRAGMA_REMCON packet_check_eom(); + #endif session_proctitle(s); return 1; } diff --git a/sshpty.c b/sshpty.c index 8f8b5d6..2e15ac8 100644 --- a/sshpty.c +++ b/sshpty.c @@ -21,6 +21,7 @@ #ifdef WIN32_FIXME #undef GSSAPI #undef KRB5 +//#define WIN32_PRAGMA_REMCON #endif #include @@ -196,6 +197,32 @@ pty_make_controlling_tty(int *ttyfd, const char *tty) #endif } +#ifdef WIN32_PRAGMA_REMCON +/* Changes the window size associated with the pty. */ + +void pty_change_window_size_oob(int ptyfd, u_int row, u_int col, u_int xpixel, u_int ypixel) +{ + int rc; + char unsigned data[16]; + size_t data_len; + + // IAC SB NAWS <16-bit value width> <16-bit value height> IAC + //sprintf (data,"%c%c%c%c%c%c%c%c", 255, 250, 31, 0, col, 0, row, 255 ); + data[0] = 255; // IAC; + data[1] = 250; // SB + data[2] = 31; // NAWS + data[3] = 0; + data[4] = (unsigned char)col; + data[5] = 0; + data[6] = (unsigned char)row; + data[7] = 255; // IAC + data[8] = 240; // iac end + data_len = 9; //strlen (data); + rc = write(ptyfd, data, (DWORD)data_len); + //rc = AsyncWrite(c->hInputHandle, (char *)data, (DWORD)data_len); +} + +#endif /* Changes the window size associated with the pty. */ void @@ -214,7 +241,12 @@ pty_change_window_size(int ptyfd, u_int row, u_int col, #else extern HANDLE hConsole ; hConsole = ptyfd; + #ifndef WIN32_PRAGMA_REMCON ConSetScreenSize( col, row ); + #else + if (ptyfd > 0 ) + pty_change_window_size_oob(ptyfd, row, col, xpixel, ypixel); + #endif #endif }