]> source.dussan.org Git - tigervnc.git/commitdiff
Hook up the "Load X.509 Cert/Key" dialogs in winvnc
authorBrian P. Hinz <bphinz@users.sf.net>
Mon, 21 Aug 2017 22:10:32 +0000 (18:10 -0400)
committerBrian P. Hinz <bphinz@users.sf.net>
Mon, 21 Aug 2017 22:10:32 +0000 (18:10 -0400)
release/tigervnc.iss.in
win/vncconfig/Authentication.h

index a27b971f39640b29a100b75cd56630b1f5e4aacd..b78b4e571479b23bcc1e37c139aef5b52d2f9fb2 100644 (file)
@@ -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; 
index 7fa85a2f46b5ecd4c849a34801001a300b79bb64..2967444af27edad267ff734521162200dfb02674 100644 (file)
 #ifndef WINVNCCONF_AUTHENTICATION
 #define WINVNCCONF_AUTHENTICATION
 
+#include <windows.h>
+#include <commctrl.h>
+
+#ifdef HAVE_GNUTLS
+#include <assert.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#define CHECK(x) assert((x)>=0)
+#endif
+
 #include <vncconfig/PasswordDialog.h>
 #include <rfb_win32/Registry.h>
 #include <rfb_win32/SecurityPage.h>
@@ -26,6 +36,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 +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;
       }
     };