From 6a7f9082fd783a1b24387cef0755426e90a0402d Mon Sep 17 00:00:00 2001 From: "Brian P. Hinz" Date: Mon, 21 Aug 2017 18:10:32 -0400 Subject: [PATCH] Hook up the "Load X.509 Cert/Key" dialogs in winvnc --- release/tigervnc.iss.in | 5 ++ win/vncconfig/Authentication.h | 86 ++++++++++++++++++++++++++++++++-- 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/release/tigervnc.iss.in b/release/tigervnc.iss.in index a27b971f..b78b4e57 100644 --- a/release/tigervnc.iss.in +++ b/release/tigervnc.iss.in @@ -18,6 +18,11 @@ DefaultGroupName=TigerVNC #endif LicenseFile=@CMAKE_SOURCE_DIR@\LICENCE.txt +[Dirs] +; This directory is necessary to prevent the X509 file chooser from causing +; an error dialog to appear when GetOpenFileName is called by SYSTEM account. +Name: "{sys}\config\systemprofile\Desktop" + [Files] #ifdef BUILD_WINVNC Source: "@CMAKE_CURRENT_BINARY_DIR@\win\winvnc\winvnc4.exe"; DestDir: "{app}"; Flags: ignoreversion restartreplace; diff --git a/win/vncconfig/Authentication.h b/win/vncconfig/Authentication.h index 7fa85a2f..2967444a 100644 --- a/win/vncconfig/Authentication.h +++ b/win/vncconfig/Authentication.h @@ -18,6 +18,16 @@ #ifndef WINVNCCONF_AUTHENTICATION #define WINVNCCONF_AUTHENTICATION +#include +#include + +#ifdef HAVE_GNUTLS +#include +#include +#include +#define CHECK(x) assert((x)>=0) +#endif + #include #include #include @@ -26,6 +36,7 @@ #include #include #include +#include #include static rfb::BoolParameter queryOnlyIfLoggedOn("QueryOnlyIfLoggedOn", @@ -53,11 +64,20 @@ namespace rfb { bool onCommand(int id, int cmd) { SecurityPage::onCommand(id, cmd); - setChanged(true); + setChanged(true); if (id == IDC_AUTH_VNC_PASSWD) { PasswordDialog passwdDlg(regKey, registryInsecure); passwdDlg.showDialog(handle); + } else if (id == IDC_LOAD_CERT) { + const TCHAR* title = _T("X509Cert"); + const TCHAR* filter = + _T("X.509 Certificates (*.crt;*.cer;*.pem)\0*.crt;*.cer;*.pem\0All\0*.*\0"); + showFileChooser(regKey, title, filter, handle); + } else if (id == IDC_LOAD_CERTKEY) { + const TCHAR* title = _T("X509Key"); + const TCHAR* filter = _T("X.509 Keys (*.key;*.pem)\0*.key;*.pem\0All\0*.*\0"); + showFileChooser(regKey, title, filter, handle); } else if (id == IDC_QUERY_LOGGED_ON) { enableItem(IDC_QUERY_LOGGED_ON, enableQueryOnlyIfLoggedOn()); } @@ -76,6 +96,37 @@ namespace rfb { regKey.setBinary(_T("Password"), 0, 0); } +#ifdef HAVE_GNUTLS + if (isItemChecked(IDC_ENC_X509)) { + gnutls_certificate_credentials_t xcred; + CHECK(gnutls_global_init()); + CHECK(gnutls_certificate_allocate_credentials(&xcred)); + int ret = gnutls_certificate_set_x509_key_file (xcred, + regKey.getString("X509Cert"), + regKey.getString("X509Key"), + GNUTLS_X509_FMT_PEM); + if (ret >= 0) { + SSecurityTLS::X509_CertFile.setParam(regKey.getString("X509Cert")); + SSecurityTLS::X509_CertFile.setParam(regKey.getString("X509Key")); + } else { + if (ret == GNUTLS_E_CERTIFICATE_KEY_MISMATCH) { + MsgBox(0, _T("Private key does not match certificate.\n") + _T("X.509 security types will not be enabled!"), + MB_ICONWARNING | MB_OK); + } else if (ret == GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE) { + MsgBox(0, _T("Unsupported certificate type.\n") + _T("X.509 security types will not be enabled!"), + MB_ICONWARNING | MB_OK); + } else { + MsgBox(0, _T("Unknown error while importing X.509 certificate or private key.\n") + _T("X.509 security types will not be enabled!"), + MB_ICONWARNING | MB_OK); + } + } + gnutls_global_deinit(); + } +#endif + regKey.setString(_T("SecurityTypes"), security->ToString()); regKey.setBool(_T("QueryConnect"), isItemChecked(IDC_QUERY_CONNECT)); regKey.setBool(_T("QueryOnlyIfLoggedOn"), isItemChecked(IDC_QUERY_LOGGED_ON)); @@ -124,8 +175,37 @@ namespace rfb { private: inline void modifyAuthMethod(int enc_idc, int auth_idc, bool enable) { - setItemChecked(enc_idc, enable); - setItemChecked(auth_idc, enable); + setItemChecked(enc_idc, enable); + setItemChecked(auth_idc, enable); + } + inline bool showFileChooser(const RegKey& rk, + const char* title, + const char* filter, + HWND hwnd) + { + OPENFILENAME ofn; + char filename[MAX_PATH]; + + ZeroMemory(&ofn, sizeof(ofn)); + ZeroMemory(&filename, sizeof(filename)); + filename[0] = '\0'; + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFile = filename; + ofn.nMaxFile = sizeof(filename); + ofn.lpstrFilter = (char*)filter; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrTitle = (char*)title; + ofn.lpstrInitialDir = NULL; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + + if (GetOpenFileName(&ofn)==TRUE) { + regKey.setString(title, filename); + return true; + } + return false; } }; -- 2.39.5