/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #include #include #include #include using namespace rfb; using namespace win32; static LogWriter vlog("Legacy"); void LegacyPage::LoadPrefs() { // VNC 3.3.3R3 Preferences Algorithm, as described by vncProperties.cpp // - Load user-specific settings, based on logged-on user name, // from HKLM/Software/ORL/WinVNC3/. If they don't exist, // try again with username "Default". // - Load system-wide settings from HKLM/Software/ORL/WinVNC3. // - If AllowProperties is non-zero then load the user's own // settings from HKCU/Software/ORL/WinVNC3. // Get the name of the current user std::string username; try { username = UserName(); } catch (rdr::win32_error& e) { if (e.err != ERROR_NOT_LOGGED_ON) throw; } // Open and read the WinVNC3 registry key allowProperties = true; RegKey winvnc3; try { winvnc3.openKey(HKEY_LOCAL_MACHINE, "Software\\ORL\\WinVNC3"); int debugMode = winvnc3.getInt("DebugMode", 0); const char* debugTarget = nullptr; if (debugMode & 2) debugTarget = "file"; if (debugMode & 4) debugTarget = "stderr"; if (debugTarget) { char logSetting[32]; sprintf(logSetting, "*:%s:%d", debugTarget, winvnc3.getInt("DebugLevel", 0)); regKey.setString("Log", logSetting); } std::string authHosts = winvnc3.getString("AuthHosts", ""); if (!authHosts.empty()) { std::string newHosts; // Reformat AuthHosts to Hosts. Wish I'd left the format the same. :( :( :( try { // Split the AuthHosts string into patterns to match std::vector patterns; patterns = rfb::split(authHosts.c_str(), ':'); for (size_t i = 0; i < patterns.size(); i++) { if (!patterns[i].empty()) { int bits = 0; char pattern[1+4*4+4]; pattern[0] = patterns[i][0]; pattern[1] = 0; // Split the pattern into IP address parts and process std::vector parts; parts = rfb::split(&patterns[i][1], '.'); for (size_t j = 0; j < parts.size(); j++) { if (bits) strcat(pattern, "."); if (parts[j].size() > 3) throw std::invalid_argument("Invalid IP address part"); if (!parts[j].empty()) { strcat(pattern, parts[j].c_str()); bits += 8; } } // Pad out the address specification if required int addrBits = bits; while (addrBits < 32) { if (addrBits) strcat(pattern, "."); strcat(pattern, "0"); addrBits += 8; } // Append the number of bits to match char buf[4]; sprintf(buf, "/%d", bits); strcat(pattern, buf); // Append this pattern to the Hosts value if (!newHosts.empty()) newHosts += ","; newHosts += pattern; } } // Finally, save the Hosts value regKey.setString("Hosts", newHosts.c_str()); } catch (std::exception&) { MsgBox(nullptr, "Unable to convert AuthHosts setting to Hosts format.", MB_ICONWARNING | MB_OK); } } else { regKey.setString("Hosts", "+"); } regKey.setBool("LocalHost", winvnc3.getBool("LoopbackOnly", false)); // *** check AllowLoopback? if (winvnc3.getBool("AuthRequired", true)) regKey.setString("SecurityTypes", "VncAuth"); else regKey.setString("SecurityTypes", "None"); int connectPriority = winvnc3.getInt("ConnectPriority", 0); regKey.setBool("DisconnectClients", connectPriority == 0); regKey.setBool("AlwaysShared", connectPriority == 1); regKey.setBool("NeverShared", connectPriority == 2); } catch(std::exception&) { } // Open the local, default-user settings allowProperties = true; try { RegKey userKey; userKey.openKey(winvnc3, "Default"); vlog.info("Loading default prefs"); LoadUserPrefs(userKey); } catch(std::exception& e) { vlog.error("Error reading Default settings:%s", e.what()); } // Open the local, user-specific settings if (userSettings && !username.empty()) { try { RegKey userKey; userKey.openKey(winvnc3, username.c_str()); vlog.info("Loading local user prefs"); LoadUserPrefs(userKey); } catch(std::exception& e) { vlog.error("Error reading local User settings:%s", e.what()); } // Open the user's own settings if (allowProperties) { try { RegKey userKey; userKey.openKey(HKEY_CURRENT_USER, "Software\\ORL\\WinVNC3"); vlog.info("Loading global user prefs"); LoadUserPrefs(userKey); } catch(std::exception& e) { vlog.error("Error reading global User settings:%s", e.what()); } } } // Disable the Options menu item if appropriate regKey.setBool("DisableOptions", !allowProperties); } void LegacyPage::LoadUserPrefs(const RegKey& key) { regKey.setInt("PortNumber", key.getBool("SocketConnect") ? key.getInt("PortNumber", 5900) : 0); if (key.getBool("AutoPortSelect", false)) { MsgBox(nullptr, "The AutoPortSelect setting is not supported by this release." "The port number will default to 5900.", MB_ICONWARNING | MB_OK); regKey.setInt("PortNumber", 5900); } regKey.setInt("IdleTimeout", key.getInt("IdleTimeout", 0)); regKey.setBool("RemoveWallpaper", key.getBool("RemoveWallpaper")); regKey.setBool("DisableEffects", key.getBool("DisableEffects")); if (key.getInt("QuerySetting", 2) != 2) { regKey.setBool("QueryConnect", key.getInt("QuerySetting") > 2); MsgBox(nullptr, "The QuerySetting option has been replaced by QueryConnect." "Please see the documentation for details of the QueryConnect option.", MB_ICONWARNING | MB_OK); } regKey.setInt("QueryTimeout", key.getInt("QueryTimeout", 10)); std::vector passwd; passwd = key.getBinary("Password"); regKey.setBinary("Password", passwd.data(), passwd.size()); bool enableInputs = key.getBool("InputsEnabled", true); regKey.setBool("AcceptKeyEvents", enableInputs); regKey.setBool("AcceptPointerEvents", enableInputs); regKey.setBool("AcceptCutText", enableInputs); regKey.setBool("SendCutText", enableInputs); switch (key.getInt("LockSetting", 0)) { case 0: regKey.setString("DisconnectAction", "None"); break; case 1: regKey.setString("DisconnectAction", "Lock"); break; case 2: regKey.setString("DisconnectAction", "Logoff"); break; }; regKey.setBool("DisableLocalInputs", key.getBool("LocalInputsDisabled", false)); // *** ignore polling preferences // PollUnderCursor, PollForeground, OnlyPollConsole, OnlyPollOnEvent regKey.setBool("UseHooks", !key.getBool("PollFullScreen", false)); if (key.isValue("AllowShutdown")) MsgBox(nullptr, "The AllowShutdown option is not supported by this release.", MB_ICONWARNING | MB_OK); if (key.isValue("AllowEditClients")) MsgBox(nullptr, "The AllowEditClients option is not supported by this release.", MB_ICONWARNING | MB_OK); allowProperties = key.getBool("AllowProperties", allowProperties); }