aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/rfb/SSecurityTLS.cxx14
-rw-r--r--release/tigervnc.iss.in5
-rw-r--r--win/vncconfig/Authentication.h55
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;
}
};