Add pluggable access to shell session so that cmd & powershell runs like natively

#define WIN32_PRAGMA_REMCON in config.h.vs or in channels.c, session.c
and sshpty.c files . cmdserver.exe runtime in Pragma Fortress SSH
package needed to access shell session.
This commit is contained in:
quamrulmina 2016-02-01 04:10:36 -06:00
parent f43f33da8b
commit 829f799ad9
4 changed files with 94 additions and 14 deletions

View File

@ -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

View File

@ -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

View File

@ -42,6 +42,7 @@
#undef GSSAPI
#undef KRB5
#define WIN32_USER_AUTH 1
//#define WIN32_PRAGMA_REMCON
#endif
#include <sys/types.h>
@ -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;
}

View File

@ -21,6 +21,7 @@
#ifdef WIN32_FIXME
#undef GSSAPI
#undef KRB5
//#define WIN32_PRAGMA_REMCON
#endif
#include <sys/types.h>
@ -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
}