Skip to content

Commit 829f799

Browse files
committed
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.
1 parent f43f33d commit 829f799

File tree

4 files changed

+94
-14
lines changed

4 files changed

+94
-14
lines changed

channels.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "includes.h"
4343

4444
#ifdef WIN32_FIXME
45+
//#define WIN32_PRAGMA_REMCON
4546
#ifdef ECONNABORTED
4647
#undef ECONNABORTED
4748
#endif
@@ -2482,6 +2483,9 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
24822483
if ( c->client_tty )
24832484
telProcessNetwork ( data, data_len ); // run it by ANSI engine if it is the ssh client
24842485
else {
2486+
#ifdef WIN32_PRAGMA_REMCON
2487+
buffer_append(&c->output, data, data_len); // it is the sshd server, so pass it on
2488+
#else
24852489
if ( ( c->isatty) && (data_len ==1) && (data[0] == '\003') ) {
24862490
/* send control-c to the shell process */
24872491
if ( GenerateConsoleCtrlEvent ( CTRL_C_EVENT, 0 ) ) {
@@ -2492,7 +2496,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
24922496
}
24932497
else {
24942498
// avoid sending the 4 arrow keys out to remote for now "ESC[A" ..
2495-
if ( (c->isatty) && (data_len ==3) && (data[0] == '\033') && (data[1] == '[')) {
2499+
if ( (c->isatty) && (data_len ==3) && (data[0] == '\033') && (data[1] == '[')) {
24962500
if ( ( data[2] == 'A') || (data[2] == 'B') || (data[2] == 'C') || (data[2] == 'D'))
24972501
packet_check_eom();
24982502
return 0;
@@ -2515,6 +2519,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
25152519
charinline = 0; // a line has ended, begin char in line count again
25162520
}
25172521
}
2522+
#endif // WIN32_PRAGMA_REMCON
25182523
}
25192524

25202525
#endif

contrib/win32/openssh/config.h.vs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1707,5 +1707,7 @@ struct iovec
17071707

17081708
// define building with MS Visual Studio Compiler and runtime and not with MingW/gcc compiler
17091709
#define WIN32_VS 1
1710-
1710+
// Use Pragma Systems Remote Console modules for shell sessions so that cmd/powershell fully
1711+
// works remotely over SSH like they operate in a local machine
1712+
//#define WIN32_PRAGMA_REMCON
17111713

session.c

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#undef GSSAPI
4343
#undef KRB5
4444
#define WIN32_USER_AUTH 1
45+
//#define WIN32_PRAGMA_REMCON
4546
#endif
4647

4748
#include <sys/types.h>
@@ -589,11 +590,20 @@ do_exec_no_pty(Session *s, const char *command)
589590
char buf[256];
590591
int prot_scr_width = 80;
591592
int prot_scr_height = 25;
593+
#ifdef WIN32_PRAGMA_REMCON
594+
char exec_command_str[512];
595+
#endif
592596

593597
if (!command)
594598
{
599+
#ifndef WIN32_PRAGMA_REMCON
595600
exec_command = s->pw->pw_shell;
596-
//exec_command = "c:\\tools\\echoit.exe"; // temp
601+
#else
602+
snprintf(exec_command_str, sizeof(exec_command_str),
603+
"\\program files\\pragma\\shared files\\cmdserver.exe SSHD %d %d",
604+
s->row, s->col );
605+
exec_command = exec_command_str;
606+
#endif
597607
}
598608
else
599609
{
@@ -606,28 +616,42 @@ do_exec_no_pty(Session *s, const char *command)
606616
* Create three socket pairs for stdin, stdout and stderr
607617
*/
608618

609-
HANDLE wfdtocmd = -1;
619+
#ifdef WIN32_PRAGMA_REMCON
620+
610621
int retcode = -1;
611622
if ( (!s -> is_subsystem) && (s ->ttyfd != -1))
612623
{
613-
//FreeConsole();
614-
//AllocConsole();
615-
MakeNewConsole();
616624
prot_scr_width = s->col;
617625
prot_scr_height = s->row;
618626
extern HANDLE hConsole ;
619627
hConsole = GetStdHandle (STD_OUTPUT_HANDLE);
620628
ConSetScreenSize( s->col, s->row );
621-
s->ptyfd = hConsole ; // the pty is the Windows console output handle in our Win32 port
622-
623-
wfdtocmd = GetStdHandle (STD_INPUT_HANDLE) ; // we use this console handle to feed input to Windows shell cmd.exe
624-
sockin[1] = allocate_sfd((int)wfdtocmd); // put the std input handle in our global general handle table
625-
//if (sockin[1] >= 0)
626-
// sfd_set_to_console(sockin[1]); // mark it as Console type
627-
629+
socketpair(sockin);
630+
s->ptyfd = sockin[1]; // hConsole; // the pty is the Windows console output handle in our Win32 port
628631
}
629632
else
630633
socketpair(sockin);
634+
#else
635+
HANDLE wfdtocmd = -1;
636+
int retcode = -1;
637+
if ((!s->is_subsystem) && (s->ttyfd != -1))
638+
{
639+
//FreeConsole();
640+
//AllocConsole();
641+
MakeNewConsole();
642+
prot_scr_width = s->col;
643+
prot_scr_height = s->row;
644+
extern HANDLE hConsole;
645+
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
646+
ConSetScreenSize(s->col, s->row);
647+
s->ptyfd = hConsole; // the pty is the Windows console output handle in our Win32 port
648+
649+
wfdtocmd = GetStdHandle(STD_INPUT_HANDLE); // we use this console handle to feed input to Windows shell cmd.exe
650+
sockin[1] = allocate_sfd((int)wfdtocmd); // put the std input handle in our global general handle table
651+
}
652+
else
653+
socketpair(sockin);
654+
#endif
631655

632656
socketpair(sockout);
633657
socketpair(sockerr);
@@ -636,12 +660,14 @@ do_exec_no_pty(Session *s, const char *command)
636660
debug3("sockout[0]: %d sockout[1]: %d", sockout[0], sockout[1]);
637661
debug3("sockerr[0]: %d sockerr[1]: %d", sockerr[0], sockerr[1]);
638662

663+
#ifndef WIN32_PRAGMA_REMCON
639664
if ( (s -> is_subsystem) || (s ->ttyfd == -1))
640665
crlf_sfd(sockin[1]);
641666

642667
crlf_sfd(sockout[1]);
643668

644669
if ( (s -> is_subsystem) || (s ->ttyfd == -1))
670+
#endif
645671
SetHandleInformation(sfd_to_handle(sockin[1]), HANDLE_FLAG_INHERIT, 0);
646672

647673
SetHandleInformation(sfd_to_handle(sockout[1]), HANDLE_FLAG_INHERIT, 0);
@@ -668,11 +694,16 @@ do_exec_no_pty(Session *s, const char *command)
668694
si.cbReserved2 = 0;
669695
si.lpReserved2 = 0;
670696

697+
#ifdef WIN32_PRAGMA_REMCON
698+
if (0) {
699+
#else
671700
if ( (!s -> is_subsystem) && (s ->ttyfd != -1) ) {
701+
672702
si.hStdInput = GetStdHandle (STD_INPUT_HANDLE) ; // shell tty interactive session gets a console input for Win32
673703
si.hStdOutput = (HANDLE) sfd_to_handle(sockout[0]);
674704
si.hStdError = (HANDLE) sfd_to_handle(sockerr[0]);
675705
si.lpDesktop = NULL ; //winstadtname_w ;
706+
#endif
676707
}
677708
else {
678709
si.hStdInput = (HANDLE) sfd_to_handle(sockin[0]);
@@ -889,13 +920,15 @@ do_exec_no_pty(Session *s, const char *command)
889920

890921
GetUserName(name, &size);
891922

923+
#ifndef WIN32_PRAGMA_REMCON
892924
if ( (!s -> is_subsystem) && (s ->ttyfd != -1)) {
893925
// Send to the remote client ANSI/VT Sequence so that they send us CRLF in place of LF
894926
char *inittermseq = "\033[20h\033[?7h\0" ; // LFtoCRLF AUTOWRAPON
895927
Channel *c=channel_by_id ( s->chanid );
896928
buffer_append(&c->input, inittermseq, strlen(inittermseq));
897929
channel_output_poll();
898930
}
931+
#endif
899932

900933
//if (s ->ttyfd != -1) {
901934
// set the channel to tty interactive type
@@ -975,8 +1008,12 @@ do_exec_no_pty(Session *s, const char *command)
9751008
/*
9761009
* We are the parent. Close the child sides of the socket pairs.
9771010
*/
1011+
#ifndef WIN32_PRAGMA_REMCON
9781012
if ( (s -> is_subsystem) || (s ->ttyfd == -1))
9791013
close(sockin[0]);
1014+
#else
1015+
close(sockin[0]);
1016+
#endif
9801017

9811018
close(sockout[0]);
9821019
close(sockerr[0]);
@@ -2734,7 +2771,9 @@ session_pty_req(Session *s)
27342771
/* for SSH1 the tty modes length is not given */
27352772
if (!compat20)
27362773
n_bytes = packet_remaining();
2774+
#ifndef WIN32_PRAGMA_REMCON
27372775
tty_parse_modes(s->ttyfd, &n_bytes);
2776+
#endif
27382777

27392778
if (!use_privsep)
27402779
pty_setowner(s->pw, s->tty);
@@ -2744,7 +2783,9 @@ session_pty_req(Session *s)
27442783
pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
27452784
#endif
27462785

2786+
#ifndef WIN32_PRAGMA_REMCON
27472787
packet_check_eom();
2788+
#endif
27482789
session_proctitle(s);
27492790
return 1;
27502791
}

sshpty.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#ifdef WIN32_FIXME
2222
#undef GSSAPI
2323
#undef KRB5
24+
//#define WIN32_PRAGMA_REMCON
2425
#endif
2526

2627
#include <sys/types.h>
@@ -196,6 +197,32 @@ pty_make_controlling_tty(int *ttyfd, const char *tty)
196197
#endif
197198
}
198199

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
199226
/* Changes the window size associated with the pty. */
200227

201228
void
@@ -214,7 +241,12 @@ pty_change_window_size(int ptyfd, u_int row, u_int col,
214241
#else
215242
extern HANDLE hConsole ;
216243
hConsole = ptyfd;
244+
#ifndef WIN32_PRAGMA_REMCON
217245
ConSetScreenSize( col, row );
246+
#else
247+
if (ptyfd > 0 )
248+
pty_change_window_size_oob(ptyfd, row, col, xpixel, ypixel);
249+
#endif
218250
#endif
219251
}
220252

0 commit comments

Comments
 (0)