123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576 |
- /* Copyright (C) 2016-2019 Brian P. Hinz
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
-
- package com.tigervnc.vncviewer;
-
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileReader;
- import java.io.IOException;
- import java.io.LineNumberReader;
- import java.io.PrintWriter;
- import java.util.StringTokenizer;
-
- import com.tigervnc.rfb.*;
- import com.tigervnc.rfb.Exception;
-
- public class Parameters {
-
- public static BoolParameter noLionFS
- = new BoolParameter("NoLionFS",
- "On Mac systems, setting this parameter will force the use of the old "+
- "(pre-Lion) full-screen mode, even if the viewer is running on OS X 10.7 "+
- "Lion or later.",
- false);
-
- public static BoolParameter dotWhenNoCursor
- = new BoolParameter("DotWhenNoCursor",
- "Show the dot cursor when the server sends an invisible cursor",
- false);
-
- public static BoolParameter sendLocalUsername
- = new BoolParameter("SendLocalUsername",
- "Send the local username for SecurityTypes "+
- "such as Plain rather than prompting",
- true);
-
- public static StringParameter passwordFile
- = new StringParameter("PasswordFile",
- "Password file for VNC authentication",
- "");
-
- public static AliasParameter passwd
- = new AliasParameter("passwd",
- "Alias for PasswordFile",
- passwordFile);
-
- public static BoolParameter autoSelect
- = new BoolParameter("AutoSelect",
- "Auto select pixel format and encoding",
- true);
-
- public static BoolParameter fullColor
- = new BoolParameter("FullColor",
- "Use full color - otherwise 6-bit colour is used "+
- "until AutoSelect decides the link is fast enough",
- true);
-
- public static AliasParameter fullColorAlias
- = new AliasParameter("FullColour",
- "Alias for FullColor",
- Parameters.fullColor);
-
- public static IntParameter lowColorLevel
- = new IntParameter("LowColorLevel",
- "Color level to use on slow connections. "+
- "0 = Very Low, 1 = Low, 2 = Medium",
- 2);
-
- public static AliasParameter lowColorLevelAlias
- = new AliasParameter("LowColourLevel",
- "Alias for LowColorLevel",
- lowColorLevel);
-
- public static StringParameter preferredEncoding
- = new StringParameter("PreferredEncoding",
- "Preferred encoding to use (Tight, ZRLE, "+
- "hextile or raw) - implies AutoSelect=0",
- "Tight");
-
- public static BoolParameter remoteResize
- = new BoolParameter("RemoteResize",
- "Dynamically resize the remote desktop size as "+
- "the size of the local client window changes. "+
- "(Does not work with all servers)",
- true);
-
- public static BoolParameter viewOnly
- = new BoolParameter("ViewOnly",
- "Don't send any mouse or keyboard events to the server",
- false);
-
- public static BoolParameter shared
- = new BoolParameter("Shared",
- "Don't disconnect other viewers upon "+
- "connection - share the desktop instead",
- false);
-
- public static BoolParameter maximize
- = new BoolParameter("Maximize",
- "Maximize viewer window",
- false);
-
- public static BoolParameter fullScreen
- = new BoolParameter("FullScreen",
- "Enable full screen",
- false);
-
- public static BoolParameter fullScreenAllMonitors
- = new BoolParameter("FullScreenAllMonitors",
- "Enable full screen over all monitors",
- true);
-
- public static BoolParameter acceptClipboard
- = new BoolParameter("AcceptClipboard",
- "Accept clipboard changes from the server",
- true);
-
- public static BoolParameter sendClipboard
- = new BoolParameter("SendClipboard",
- "Send clipboard changes to the server",
- true);
-
- public static IntParameter maxCutText
- = new IntParameter("MaxCutText",
- "Maximum permitted length of an outgoing clipboard update",
- 262144);
-
- public static StringParameter menuKey
- = new StringParameter("MenuKey",
- "The key which brings up the popup menu",
- "F8");
-
- public static StringParameter desktopSize
- = new StringParameter("DesktopSize",
- "Reconfigure desktop size on the server on connect (if possible)",
- "");
-
- public static BoolParameter listenMode
- = new BoolParameter("listen",
- "Listen for connections from VNC servers",
- false);
-
- public static StringParameter scalingFactor
- = new StringParameter("ScalingFactor",
- "Reduce or enlarge the remote desktop image. "+
- "The value is interpreted as a scaling factor "+
- "in percent. If the parameter is set to "+
- "\"Auto\", then automatic scaling is "+
- "performed. Auto-scaling tries to choose a "+
- "scaling factor in such a way that the whole "+
- "remote desktop will fit on the local screen. "+
- "If the parameter is set to \"FixedRatio\", "+
- "then automatic scaling is performed, but the "+
- "original aspect ratio is preserved.",
- "100");
-
- public static BoolParameter alwaysShowServerDialog
- = new BoolParameter("AlwaysShowServerDialog",
- "Always show the server dialog even if a server has been "+
- "specified in an applet parameter or on the command line",
- false);
-
- public static BoolParameter acceptBell
- = new BoolParameter("AcceptBell",
- "Produce a system beep when requested to by the server.",
- true);
-
- public static StringParameter via
- = new StringParameter("Via",
- "Automatically create an encrypted TCP tunnel to "+
- "the gateway machine, then connect to the VNC host "+
- "through that tunnel. By default, this option invokes "+
- "SSH local port forwarding using the embedded JSch "+
- "client, however an external SSH client may be specified "+
- "using the \"-extSSH\" parameter. Note that when using "+
- "the -via option, the VNC host machine name should be "+
- "specified from the point of view of the gateway machine, "+
- "e.g. \"localhost\" denotes the gateway, "+
- "not the machine on which the viewer was launched. "+
- "See the System Properties section below for "+
- "information on configuring the -Via option.", "");
-
- public static BoolParameter tunnel
- = new BoolParameter("Tunnel",
- "The -Tunnel command is basically a shorthand for the "+
- "-via command when the VNC server and SSH gateway are "+
- "one and the same. -Tunnel creates an SSH connection "+
- "to the server and forwards the VNC through the tunnel "+
- "without the need to specify anything else.", false);
-
- public static BoolParameter extSSH
- = new BoolParameter("extSSH",
- "By default, SSH tunneling uses the embedded JSch client "+
- "for tunnel creation. This option causes the client to "+
- "invoke an external SSH client application for all tunneling "+
- "operations. By default, \"/usr/bin/ssh\" is used, however "+
- "the path to the external application may be specified using "+
- "the -SSHClient option.", false);
-
- public static StringParameter extSSHClient
- = new StringParameter("extSSHClient",
- "Specifies the path to an external SSH client application "+
- "that is to be used for tunneling operations when the -extSSH "+
- "option is in effect.", "/usr/bin/ssh");
-
- public static StringParameter extSSHArgs
- = new StringParameter("extSSHArgs",
- "Specifies the arguments string or command template to be used "+
- "by the external SSH client application when the -extSSH option "+
- "is in effect. The string will be processed according to the same "+
- "pattern substitution rules as the VNC_TUNNEL_CMD and VNC_VIA_CMD "+
- "system properties, and can be used to override those in a more "+
- "command-line friendly way. If not specified, then the appropriate "+
- "VNC_TUNNEL_CMD or VNC_VIA_CMD command template will be used.", "");
-
- public static StringParameter sshConfig
- = new StringParameter("SSHConfig",
- "Specifies the path to an OpenSSH configuration file that to "+
- "be parsed by the embedded JSch SSH client during tunneling "+
- "operations.", FileUtils.getHomeDir()+".ssh/config");
-
- public static StringParameter sshKey
- = new StringParameter("SSHKey",
- "When using the Via or Tunnel options with the embedded SSH client, "+
- "this parameter specifies the text of the SSH private key to use when "+
- "authenticating with the SSH server. You can use \\n within the string "+
- "to specify a new line.", "");
-
- public static StringParameter sshKeyFile
- = new StringParameter("SSHKeyFile",
- "When using the Via or Tunnel options with the embedded SSH client, "+
- "this parameter specifies a file that contains an SSH private key "+
- "(or keys) to use when authenticating with the SSH server. If not "+
- "specified, ~/.ssh/id_dsa or ~/.ssh/id_rsa will be used (if they exist). "+
- "Otherwise, the client will fallback to prompting for an SSH password.",
- "");
-
- public static StringParameter sshKeyPass
- = new StringParameter("SSHKeyPass",
- "When using the Via or Tunnel options with the embedded SSH client, "+
- "this parameter specifies the passphrase for the SSH key.", "");
-
- public static BoolParameter customCompressLevel
- = new BoolParameter("CustomCompressLevel",
- "Use custom compression level. Default if CompressLevel is specified.",
- false);
-
- public static IntParameter compressLevel
- = new IntParameter("CompressLevel",
- "Use specified lossless compression level. 0 = Low, 9 = High. Default is 2.",
- 2);
-
- public static BoolParameter noJpeg
- = new BoolParameter("NoJPEG",
- "Disable lossy JPEG compression in Tight encoding.",
- false);
-
- public static IntParameter qualityLevel
- = new IntParameter("QualityLevel",
- "JPEG quality level. 0 = Low, 9 = High",
- 8);
-
- private static final String IDENTIFIER_STRING
- = "TigerVNC Configuration file Version 1.0";
-
- static VoidParameter[] parameterArray = {
- CSecurityTLS.X509CA,
- CSecurityTLS.X509CRL,
- SecurityClient.secTypes,
- dotWhenNoCursor,
- autoSelect,
- fullColor,
- lowColorLevel,
- preferredEncoding,
- customCompressLevel,
- compressLevel,
- noJpeg,
- qualityLevel,
- maximize,
- fullScreen,
- fullScreenAllMonitors,
- desktopSize,
- remoteResize,
- viewOnly,
- shared,
- acceptClipboard,
- sendClipboard,
- menuKey,
- noLionFS,
- sendLocalUsername,
- maxCutText,
- scalingFactor,
- acceptBell,
- via,
- tunnel,
- extSSH,
- extSSHClient,
- extSSHArgs,
- sshConfig,
- sshKeyFile,
- };
-
-
- static LogWriter vlog = new LogWriter("Parameters");
-
- public static void saveViewerParameters(String filename, String servername) {
-
- // Write to the registry or a predefined file if no filename was specified.
- String filepath;
- if (filename == null || filename.isEmpty()) {
- saveToReg(servername);
- return;
- } else {
- filepath = filename;
- }
-
- /* Write parameters to file */
- File f = new File(filepath);
- if (f.exists() && !f.canWrite())
- throw new Exception(String.format("Failed to write configuration file,"+
- "can't open %s", filepath));
-
- PrintWriter pw = null;
- try {
- pw = new PrintWriter(f, "UTF-8");
- } catch (java.lang.Exception e) {
- throw new Exception(e.getMessage());
- }
-
- pw.println(IDENTIFIER_STRING);
- pw.println("");
-
- if (servername != null && !servername.isEmpty()) {
- pw.println(String.format("ServerName=%s\n", servername));
- updateConnHistory(servername);
- }
-
- for (int i = 0; i < parameterArray.length; i++) {
- if (parameterArray[i] instanceof StringParameter) {
- //if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName()))
- pw.println(String.format("%s=%s",parameterArray[i].getName(),
- parameterArray[i].getValueStr()));
- } else if (parameterArray[i] instanceof IntParameter) {
- //if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName()))
- pw.println(String.format("%s=%s",parameterArray[i].getName(),
- parameterArray[i].getValueStr()));
- } else if (parameterArray[i] instanceof BoolParameter) {
- //if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName()))
- pw.println(String.format("%s=%s",parameterArray[i].getName(),
- parameterArray[i].getValueStr()));
- } else {
- vlog.error(String.format("Unknown parameter type for parameter %s",
- parameterArray[i].getName()));
- }
- }
-
- pw.flush();
- pw.close();
- }
-
- public static String loadViewerParameters(String filename) throws Exception {
- String servername = "";
-
- String filepath;
- if (filename == null) {
- return loadFromReg();
- } else {
- filepath = filename;
- }
-
- /* Read parameters from file */
- File f = new File(filepath);
- if (!f.exists() || !f.canRead()) {
- if (filename == null || filename.isEmpty())
- return null;
- throw new Exception(String.format("Failed to read configuration file, can't open %s",
- filepath));
- }
-
- String line = "";
- LineNumberReader reader;
- try {
- reader = new LineNumberReader(new FileReader(f));
- } catch (FileNotFoundException e) {
- throw new Exception(e.getMessage());
- }
-
- int lineNr = 0;
- while (line != null) {
-
- // Read the next line
- try {
- line = reader.readLine();
- lineNr = reader.getLineNumber();
- if (line == null)
- break;
- } catch (IOException e) {
- throw new Exception(String.format("Failed to read line %d in file %s: %s",
- lineNr, filepath, e.getMessage()));
- }
-
- // Make sure that the first line of the file has the file identifier string
- if(lineNr == 1) {
- if(line.equals(IDENTIFIER_STRING))
- continue;
- else
- throw new Exception(String.format("Configuration file %s is in an invalid format", filename));
- }
-
- // Skip empty lines and comments
- if (line.trim().isEmpty() || line.trim().startsWith("#"))
- continue;
-
- // Find the parameter value
- int idx = line.indexOf("=");
- if (idx == -1) {
- vlog.error(String.format("Failed to read line %d in file %s: %s",
- lineNr, filename, "Invalid format"));
- continue;
- }
- String value = line.substring(idx+1).trim();
- boolean invalidParameterName = true; // Will be set to false below if
- // the line contains a valid name.
-
- if (line.substring(0,idx).trim().equalsIgnoreCase("ServerName")) {
- if (value.length() > 256) {
- vlog.error(String.format("Failed to read line %d in file %s: %s",
- lineNr, filepath, "Invalid format or too large value"));
- continue;
- }
- servername = value;
- invalidParameterName = false;
- } else {
- for (int i = 0; i < parameterArray.length; i++) {
- if (parameterArray[i] instanceof StringParameter) {
- if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName())) {
- if (value.length() > 256) {
- vlog.error(String.format("Failed to read line %d in file %s: %s",
- lineNr, filepath, "Invalid format or too large value"));
- continue;
- }
- ((StringParameter)parameterArray[i]).setParam(value);
- invalidParameterName = false;
- }
- } else if (parameterArray[i] instanceof IntParameter) {
- if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName())) {
- ((IntParameter)parameterArray[i]).setParam(value);
- invalidParameterName = false;
- }
- } else if (parameterArray[i] instanceof BoolParameter) {
- if (line.substring(0,idx).trim().equalsIgnoreCase(parameterArray[i].getName())) {
- ((BoolParameter)parameterArray[i]).setParam(value);
- invalidParameterName = false;
- }
- } else {
- vlog.error(String.format("Unknown parameter type for parameter %s",
- parameterArray[i].getName()));
-
- }
- }
- }
-
- if (invalidParameterName)
- vlog.info(String.format("Unknown parameter %s on line %d in file %s",
- line, lineNr, filepath));
- }
- try {
- reader.close();
- } catch (IOException e) {
- vlog.info(e.getMessage());
- } finally {
- try {
- if (reader != null)
- reader.close();
- } catch (IOException e) { }
- }
-
- return servername;
- }
-
- public static void saveToReg(String servername) {
- String hKey = "global";
-
- if (servername != null && !servername.isEmpty()) {
- UserPreferences.set(hKey, "ServerName", servername);
- updateConnHistory(servername);
- }
-
- for (int i = 0; i < parameterArray.length; i++) {
- if (parameterArray[i] instanceof StringParameter) {
- UserPreferences.set(hKey, parameterArray[i].getName(),
- parameterArray[i].getValueStr());
- } else if (parameterArray[i] instanceof IntParameter) {
- UserPreferences.set(hKey, parameterArray[i].getName(),
- ((IntParameter)parameterArray[i]).getValue());
- } else if (parameterArray[i] instanceof BoolParameter) {
- UserPreferences.set(hKey, parameterArray[i].getName(),
- ((BoolParameter)parameterArray[i]).getValue());
- } else {
- vlog.error(String.format("Unknown parameter type for parameter %s",
- parameterArray[i].getName()));
- }
- }
-
- UserPreferences.save(hKey);
- }
-
- public static String loadFromReg() {
-
- String hKey = "global";
-
- String servername = UserPreferences.get(hKey, "ServerName");
- if (servername == null)
- servername = "";
-
- for (int i = 0; i < parameterArray.length; i++) {
- if (parameterArray[i] instanceof StringParameter) {
- if (UserPreferences.get(hKey, parameterArray[i].getName()) != null) {
- String stringValue =
- UserPreferences.get(hKey, parameterArray[i].getName());
- ((StringParameter)parameterArray[i]).setParam(stringValue);
- }
- } else if (parameterArray[i] instanceof IntParameter) {
- if (UserPreferences.get(hKey, parameterArray[i].getName()) != null) {
- int intValue =
- UserPreferences.getInt(hKey, parameterArray[i].getName());
- ((IntParameter)parameterArray[i]).setParam(intValue);
- }
- } else if (parameterArray[i] instanceof BoolParameter) {
- if (UserPreferences.get(hKey, parameterArray[i].getName()) != null) {
- boolean booleanValue =
- UserPreferences.getBool(hKey, parameterArray[i].getName());
- ((BoolParameter)parameterArray[i]).setParam(booleanValue);
- }
- } else {
- vlog.error(String.format("Unknown parameter type for parameter %s",
- parameterArray[i].getName()));
- }
- }
-
- return servername;
- }
-
- private static void updateConnHistory(String serverName) {
- String hKey = "ServerDialog";
- if (serverName != null && !serverName.isEmpty()) {
- String valueStr = UserPreferences.get(hKey, "history");
- String t = (valueStr == null) ? "" : valueStr;
- StringTokenizer st = new StringTokenizer(t, ",");
- StringBuffer sb = new StringBuffer().append(serverName);
- while (st.hasMoreTokens()) {
- String str = st.nextToken();
- if (!str.equals(serverName) && !str.equals(""))
- sb.append(',').append(str);
- }
- UserPreferences.set(hKey, "history", sb.toString());
- UserPreferences.save(hKey);
- }
- }
-
- }
|