diff options
-rw-r--r-- | common/rfb/SSecurityTLS.cxx | 14 | ||||
-rw-r--r-- | release/tigervnc.iss.in | 5 | ||||
-rw-r--r-- | win/vncconfig/Authentication.h | 55 |
3 files changed, 68 insertions, 6 deletions
diff --git a/common/rfb/SSecurityTLS.cxx b/common/rfb/SSecurityTLS.cxx index b9460223..5576a060 100644 --- a/common/rfb/SSecurityTLS.cxx +++ b/common/rfb/SSecurityTLS.cxx @@ -35,6 +35,7 @@ #include <rfb/Exception.h> #include <rdr/TLSInStream.h> #include <rdr/TLSOutStream.h> +#include <gnutls/x509.h> #define DH_BITS 1024 /* XXX This should be configurable! */ @@ -207,9 +208,16 @@ void SSecurityTLS::setParams(gnutls_session_t session) gnutls_certificate_set_dh_params(cert_cred, dh_params); - if (gnutls_certificate_set_x509_key_file(cert_cred, certfile, keyfile, - GNUTLS_X509_FMT_PEM) != GNUTLS_E_SUCCESS) - throw AuthFailureException("load of key failed"); + switch (gnutls_certificate_set_x509_key_file(cert_cred, certfile, keyfile, GNUTLS_X509_FMT_PEM)) { + case GNUTLS_E_SUCCESS: + break; + case GNUTLS_E_CERTIFICATE_KEY_MISMATCH: + throw AuthFailureException("Private key does not match certificate"); + case GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE: + throw AuthFailureException("Unsupported certificate type"); + default: + throw AuthFailureException("Error loading X509 certificate or key"); + } if (gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cert_cred) != GNUTLS_E_SUCCESS) 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..82971148 100644 --- a/win/vncconfig/Authentication.h +++ b/win/vncconfig/Authentication.h @@ -18,6 +18,9 @@ #ifndef WINVNCCONF_AUTHENTICATION #define WINVNCCONF_AUTHENTICATION +#include <windows.h> +#include <commctrl.h> + #include <vncconfig/PasswordDialog.h> #include <rfb_win32/Registry.h> #include <rfb_win32/SecurityPage.h> @@ -26,6 +29,7 @@ #include <rfb/Security.h> #include <rfb/SecurityServer.h> #include <rfb/SSecurityVncAuth.h> +#include <rfb/SSecurityTLS.h> #include <rfb/Password.h> static rfb::BoolParameter queryOnlyIfLoggedOn("QueryOnlyIfLoggedOn", @@ -53,11 +57,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 +89,13 @@ namespace rfb { regKey.setBinary(_T("Password"), 0, 0); } +#ifdef HAVE_GNUTLS + if (isItemChecked(IDC_ENC_X509)) { + SSecurityTLS::X509_CertFile.setParam(regKey.getString("X509Cert")); + SSecurityTLS::X509_CertFile.setParam(regKey.getString("X509Key")); + } +#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 +144,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; } }; |