From 480a7a0a6c9a8fae5b8fc7b7688173d5e425ae0e Mon Sep 17 00:00:00 2001 From: marha Date: Fri, 9 Nov 2012 12:31:43 +0100 Subject: Allow specifying a key file in putty format when starting a remote program Now plink is a real console application in the release build (no -console option anymore) --- xorg-server/hw/xwin/xlaunch/config.cc | 2 + xorg-server/hw/xwin/xlaunch/config.h | 2 + xorg-server/hw/xwin/xlaunch/main.cc | 107 ++++++++++++++++++++-- xorg-server/hw/xwin/xlaunch/resources/dialog.rc | 13 ++- xorg-server/hw/xwin/xlaunch/resources/resources.h | 2 + xorg-server/hw/xwin/xlaunch/resources/strings.rc | 3 +- 6 files changed, 114 insertions(+), 15 deletions(-) (limited to 'xorg-server/hw') diff --git a/xorg-server/hw/xwin/xlaunch/config.cc b/xorg-server/hw/xwin/xlaunch/config.cc index c7ac398fb..fc268e2e8 100644 --- a/xorg-server/hw/xwin/xlaunch/config.cc +++ b/xorg-server/hw/xwin/xlaunch/config.cc @@ -83,6 +83,7 @@ void CConfig::Save(const char *filename) setAttribute(root, "LocalProgram", localprogram.c_str()); setAttribute(root, "RemoteProgram", remoteprogram.c_str()); setAttribute(root, "RemotePassword", remotepassword.c_str()); + setAttribute(root, "PrivateKey", privatekey.c_str()); setAttribute(root, "RemoteHost", host.c_str()); setAttribute(root, "RemoteUser", user.c_str()); setAttribute(root, "XDMCPHost", xdmcp_host.c_str()); @@ -174,6 +175,7 @@ void CConfig::Load(const char *filename) getAttribute(root, "LocalProgram", localprogram); getAttribute(root, "RemoteProgram", remoteprogram); getAttribute(root, "RemotePassword", remotepassword); + getAttribute(root, "PrivateKey", privatekey); getAttribute(root, "RemoteHost", host); getAttribute(root, "RemoteUser", user); getAttribute(root, "XDMCPHost", xdmcp_host); diff --git a/xorg-server/hw/xwin/xlaunch/config.h b/xorg-server/hw/xwin/xlaunch/config.h index d9ec96ede..d4ae5e35d 100644 --- a/xorg-server/hw/xwin/xlaunch/config.h +++ b/xorg-server/hw/xwin/xlaunch/config.h @@ -50,6 +50,7 @@ struct CConfig std::string host; std::string user; std::string remotepassword; + std::string privatekey; bool broadcast; bool indirect; std::string xdmcp_host; @@ -62,6 +63,7 @@ struct CConfig CConfig() : window(MultiWindow), client(NoClient), display("-1"), local(false), remotepassword(""), + privatekey(""), localprogram("xcalc"), remoteprogram("xterm"), compress(false), diff --git a/xorg-server/hw/xwin/xlaunch/main.cc b/xorg-server/hw/xwin/xlaunch/main.cc index dcbb36d64..476f8c2bc 100644 --- a/xorg-server/hw/xwin/xlaunch/main.cc +++ b/xorg-server/hw/xwin/xlaunch/main.cc @@ -23,6 +23,14 @@ * holders shall not be used in advertising or otherwise to promote the sale, * use or other dealings in this Software without prior written authorization. */ +#define SAVEPOSIX _POSIX_ +#undef _POSIX_ +#include +#include +#include +#include +#define _POSIX_ SAVEPOSIX + #include "window/util.h" #include "window/wizard.h" #include "resources/resources.h" @@ -34,10 +42,6 @@ #include -#include -// Define here because it is not defined in stdlib.h because of the _POSIX_ defined -extern "C" -_Check_return_ _CRTIMP int __cdecl _putenv(_In_z_ const char * _EnvString); #include /// @brief Send WM_ENDSESSION to all program windows. @@ -169,6 +173,9 @@ class CMyWizard : public CWizard GetDlgItemText(hwndDlg, IDC_CLIENT_PASSWORD, buffer, 512); buffer[511] = 0; config.remotepassword = buffer; + GetDlgItemText(hwndDlg, IDC_CLIENT_PRIVATEKEY, buffer, 512); + buffer[511] = 0; + config.privatekey = buffer; } // Check for valid input if (!config.local && (config.host.empty() || config.localprogram.empty() || config.remoteprogram.empty())) @@ -330,6 +337,8 @@ class CMyWizard : public CWizard EnableWindow(GetDlgItem(hwndDlg, IDC_CLIENT_USER_DESC), state); EnableWindow(GetDlgItem(hwndDlg, IDC_CLIENT_REMOTEPROGRAM), state); EnableWindow(GetDlgItem(hwndDlg, IDC_CLIENT_REMOTEPROGRAM_DESC), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_CLIENT_PRIVATEKEY), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_CLIENT_PRIVATEKEY_DESC), state); EnableWindow(GetDlgItem(hwndDlg, IDC_CLIENT_PROGRAM), !state); EnableWindow(GetDlgItem(hwndDlg, IDC_CLIENT_PROGRAM_DESC), !state); } @@ -456,13 +465,12 @@ class CMyWizard : public CWizard // Fill combo boxes FillProgramBox(hwndDlg); // Set edit fields - if (!config.localprogram.empty()) - SetDlgItemText(hwndDlg, IDC_CLIENT_PROGRAM, config.localprogram.c_str()); - if (!config.remoteprogram.empty()) - SetDlgItemText(hwndDlg, IDC_CLIENT_REMOTEPROGRAM, config.remoteprogram.c_str()); + SetDlgItemText(hwndDlg, IDC_CLIENT_PROGRAM, config.localprogram.c_str()); + SetDlgItemText(hwndDlg, IDC_CLIENT_REMOTEPROGRAM, config.remoteprogram.c_str()); SetDlgItemText(hwndDlg, IDC_CLIENT_USER, config.user.c_str()); SetDlgItemText(hwndDlg, IDC_CLIENT_HOST, config.host.c_str()); SetDlgItemText(hwndDlg, IDC_CLIENT_PASSWORD, config.remotepassword.c_str()); + SetDlgItemText(hwndDlg, IDC_CLIENT_PRIVATEKEY, config.privatekey.c_str()); break; case IDD_XDMCP: // Init XDMCP dialog. Check broadcast and indirect button @@ -621,8 +629,10 @@ class CMyWizard : public CWizard host = config.user + "@" + config.host; if (!config.remotepassword.empty()) remotepassword=std::string(" -pw ")+config.remotepassword; + if (!config.privatekey.empty()) + remotepassword+=std::string(" -i \"")+config.privatekey+"\""; // Need to use -console since certain commands will not execute when no console - _snprintf(cmdline,512,"plink -console -ssh -X%s %s %s", + _snprintf(cmdline,512,"plink -ssh -X%s %s %s", remotepassword.c_str(), host.c_str(),config.remoteprogram.c_str()); client += cmdline; } @@ -716,6 +726,84 @@ class CMyWizard : public CWizard } #endif + #if 1 + { + HANDLE hChildStdinRd; + HANDLE hChildStdinWr; + HANDLE hChildStdoutRd; + HANDLE hChildStdoutWr; + HANDLE hChildStdinWrDup; + HANDLE hChildStdoutRdDup; + SECURITY_ATTRIBUTES saAttr; + BOOL fSuccess; + STARTUPINFO StartupInfo; + memset(&StartupInfo,0,sizeof(StartupInfo)); + StartupInfo.cb=sizeof(STARTUPINFO); + PROCESS_INFORMATION ProcessInfo; + + saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); + saAttr.bInheritHandle = TRUE; + saAttr.lpSecurityDescriptor = NULL; + + if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) + throw win32_error("CreatePipe failed", GetLastError()); + + /* Create new output read handle and the input write handle. Set + * the inheritance properties to FALSE. Otherwise, the child inherits + * the these handles; resulting in non-closeable handles to the pipes + * being created. */ + fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr, + GetCurrentProcess(), &hChildStdinWrDup, 0, + FALSE, DUPLICATE_SAME_ACCESS); + if (!fSuccess) + throw win32_error("DuplicateHandle failed", GetLastError()); + /* Close the inheritable version of ChildStdin that we're using. */ + CloseHandle(hChildStdinWr); + + if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) + throw win32_error("CreatePipe failed", GetLastError()); + + fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd, + GetCurrentProcess(), &hChildStdoutRdDup, 0, + FALSE, DUPLICATE_SAME_ACCESS); + if (!fSuccess) + throw win32_error("DuplicateHandle failed", GetLastError()); + CloseHandle(hChildStdoutRd); + + int hStdIn = _open_osfhandle((long)hChildStdinWrDup, _O_WRONLY|_O_TEXT); + FILE *pStdIn = _fdopen(hStdIn, "w"); + int hStdOut = _open_osfhandle((long)hChildStdoutRdDup, _O_RDONLY|_O_TEXT); + FILE *pStdOut = _fdopen(hStdOut, "r"); + + StartupInfo.dwFlags = STARTF_USESTDHANDLES; + StartupInfo.hStdInput = hChildStdinRd; + StartupInfo.hStdOutput = hChildStdoutWr; + StartupInfo.hStdError = hChildStdoutWr; + + if (!CreateProcess(NULL,(CHAR*)client.c_str(),NULL,NULL,TRUE,CREATE_NO_WINDOW,NULL, CurDir, &StartupInfo, &ProcessInfo)) + { + DWORD err = GetLastError(); + while (hcount--) + TerminateProcess(handles[hcount], (DWORD)-1); + throw win32_error("CreateProcess failed", err); + } + CloseHandle(hChildStdinRd); + CloseHandle(hChildStdoutWr); + + CloseHandle(ProcessInfo.hThread); + char Buf[256]; + size_t Nbr; + std::string output; + while ( (Nbr=fread(Buf,1,sizeof(Buf)-1,pStdOut)) > 0) + { + output+=Buf; + } + if (!output.empty()) + { + MessageBox(NULL,output.c_str(),"Child output",MB_OK); + } + } + #else if( !CreateProcess( NULL, (CHAR*)client.c_str(), NULL, NULL, FALSE, 0, NULL, CurDir, &sic, &pic )) { @@ -724,6 +812,7 @@ class CMyWizard : public CWizard TerminateProcess(handles[hcount], (DWORD)-1); throw win32_error("CreateProcess failed", err); } + #endif handles[hcount++] = pic.hProcess; #ifdef WITHFLASH ShowWindow( GetConsoleWindow(), SW_HIDE ); // make it hidden diff --git a/xorg-server/hw/xwin/xlaunch/resources/dialog.rc b/xorg-server/hw/xwin/xlaunch/resources/dialog.rc index 2809bcc4b..fd7dae522 100644 --- a/xorg-server/hw/xwin/xlaunch/resources/dialog.rc +++ b/xorg-server/hw/xwin/xlaunch/resources/dialog.rc @@ -73,21 +73,24 @@ BEGIN AUTORADIOBUTTON STR_CLIENT_REMOTE,IDC_CLIENT_REMOTE,7,50,300,10 LTEXT STR_CLIENT_PROGRAM_DESC,IDC_CLIENT_PROGRAM_DESC,19,28,64,10 - COMBOBOX IDC_CLIENT_PROGRAM,100,26,64,54,CBS_DROPDOWN | WS_VSCROLL + COMBOBOX IDC_CLIENT_PROGRAM,110,26,64,54,CBS_DROPDOWN | WS_VSCROLL LTEXT STR_CLIENT_REMOTEPROGRAM_DESC,IDC_CLIENT_REMOTEPROGRAM_DESC,19,64,70,10 - EDITTEXT IDC_CLIENT_REMOTEPROGRAM,100,62,200,12, WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL + EDITTEXT IDC_CLIENT_REMOTEPROGRAM,110,62,200,12, WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL LTEXT STR_CLIENT_PASSWORD_DESC,IDC_CLIENT_PASSWORD_DESC,19,78,70,10 - EDITTEXT IDC_CLIENT_PASSWORD,100,76,64,12, WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL + EDITTEXT IDC_CLIENT_PASSWORD,110,76,64,12, WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL LTEXT STR_CLIENT_HOST_DESC,IDC_CLIENT_HOST_DESC,19,92,70,10 - EDITTEXT IDC_CLIENT_HOST,100,90,64,12, WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL + EDITTEXT IDC_CLIENT_HOST,110,90,64,12, WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL LTEXT STR_CLIENT_USER_DESC,IDC_CLIENT_USER_DESC,19,106,70,10 - EDITTEXT IDC_CLIENT_USER,100,104,64,12, WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL + EDITTEXT IDC_CLIENT_USER,110,104,64,12, WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL + + LTEXT STR_CLIENT_PRIVATEKEY_DESC,IDC_CLIENT_PRIVATEKEY_DESC,19,120,90,10 + EDITTEXT IDC_CLIENT_PRIVATEKEY,110,118,200,12, WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL END IDD_XDMCP DIALOGEX 0, 0, 317, 143 diff --git a/xorg-server/hw/xwin/xlaunch/resources/resources.h b/xorg-server/hw/xwin/xlaunch/resources/resources.h index 8db7ef190..bccfb1702 100644 --- a/xorg-server/hw/xwin/xlaunch/resources/resources.h +++ b/xorg-server/hw/xwin/xlaunch/resources/resources.h @@ -73,6 +73,8 @@ #define IDC_CLIENT_PASSWORD_DESC 232 #define IDC_CLIENT_REMOTEPROGRAM 233 #define IDC_CLIENT_REMOTEPROGRAM_DESC 234 +#define IDC_CLIENT_PRIVATEKEY 235 +#define IDC_CLIENT_PRIVATEKEY_DESC 236 #define IDC_FONTPATH_DESC 240 diff --git a/xorg-server/hw/xwin/xlaunch/resources/strings.rc b/xorg-server/hw/xwin/xlaunch/resources/strings.rc index 8a3c487f5..f34f46208 100644 --- a/xorg-server/hw/xwin/xlaunch/resources/strings.rc +++ b/xorg-server/hw/xwin/xlaunch/resources/strings.rc @@ -48,7 +48,8 @@ #define STR_CLIENT_HOST_DESC "Connect to computer" #define STR_CLIENT_USER_DESC "Login as user" -#define STR_CLIENT_REMOTEPROGRAM_DESC "Remote program" +#define STR_CLIENT_REMOTEPROGRAM_DESC "Remote program" +#define STR_CLIENT_PRIVATEKEY_DESC "Private key (putty format)" #define STR_CAPTION_XDMCP "XDMCP settings" -- cgit v1.2.3