Skip to content

Commit

Permalink
Merge branch 'main' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
dcommander committed Sep 14, 2023
2 parents 3c821c7 + 0a91b71 commit ca0fb8c
Show file tree
Hide file tree
Showing 18 changed files with 691 additions and 120 deletions.
35 changes: 34 additions & 1 deletion ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
3.2
===

### Significant changes relative to 3.1 beta2:
### Significant changes relative to 3.1:

1. Since all supported TurboVNC host platforms now contain new enough libraries
to build xorg-server 1.20.x, the TurboVNC Server is now dynamically linked
Expand All @@ -13,6 +13,39 @@ on x86 platforms to disable the in-tree SIMD-accelerated Intel zlib
implementation and build against the system-supplied zlib implementation.


3.1
===

### Significant changes relative to 3.1 beta2:

1. Improved the TurboVNC Viewer's handling of SSH usernames in the following
ways:

- Fixed a regression introduced in 3.1 beta1[3] whereby the SSH username
was ignored if it was specified in the `Server` parameter or if it was
specified in the TurboVNC Viewer Options dialog without also specifying the
gateway host.
- Fixed an issue whereby the SSH username was not saved and restored if it
was specified in the TurboVNC Viewer Options dialog without also specifying the
gateway host.
- Fixed an issue whereby the SSH username was ignored if it was specified
in the `Server` or `Via` parameter in **~/.vnc/default.turbovnc**.
- Added a new parameter (`SSHUser`) that can optionally be used to specify
the SSH username. This parameter is set automatically from an SSH username
specified in the `Server` or `Via` parameter, or it can be set manually.
- To better emulate the behavior of OpenSSH, the TurboVNC Viewer's
built-in SSH client now allows an SSH username specified on the command line or
in a connection info file to override an SSH username specified in the OpenSSH
config file.
- The `LocalUsernameLC` parameter now affects the SSH username if the SSH
username is unspecified.

2. The TurboVNC Server now includes various security fixes (CVE-2022-2319,
CVE-2022-2320, CVE-2022-4283, CVE-2022-46340, CVE-2022-46341, CVE-2022-46342,
CVE-2022-46343, CVE-2022-46344, CVE-2023-0494, and CVE-2023-1393) from the
xorg-server 21.1.x code base.


3.1 beta2
=========

Expand Down
38 changes: 10 additions & 28 deletions java/com/turbovnc/rfb/Hostname.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Copyright (C) 2012, 2016, 2018, 2020, 2022 D. R. Commander.
* All Rights Reserved.
/* Copyright (C) 2012, 2016, 2018, 2020, 2022-2023 D. R. Commander.
* All Rights Reserved.
* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
Expand All @@ -24,7 +24,7 @@

public final class Hostname {

public static String getHost(String vncServerName) {
private static int getColonPos(String vncServerName) {
int colonPos = vncServerName.lastIndexOf(':');
int bracketPos = vncServerName.lastIndexOf(']');
boolean doubleColon = false;
Expand All @@ -45,38 +45,20 @@ public static String getHost(String vncServerName) {
}
}
}

return colonPos;
}

public static String getHost(String vncServerName) {
int colonPos = getColonPos(vncServerName);

if (colonPos == 0)
return "localhost";
if (colonPos == -1)
colonPos = vncServerName.length();
return vncServerName.substring(0, colonPos).replaceAll("\\s", "");
}

private static int getColonPos(String vncServerName) {
int colonPos = vncServerName.lastIndexOf(':');
int bracketPos = vncServerName.lastIndexOf(']');
boolean doubleColon = false;

if (bracketPos != -1 && colonPos < bracketPos)
colonPos = -1;
while (colonPos > 0 && vncServerName.charAt(colonPos - 1) == ':') {
colonPos--;
doubleColon = true;
}
if (doubleColon) {
// Check for preceding single colon, indicating an IPv6 address
for (int p = colonPos - 1; p >= 0; p--) {
if (vncServerName.charAt(p) == ':') {
if (p == 0 || vncServerName.charAt(p - 1) != ':')
colonPos = -1;
break;
}
}
}

return colonPos;
}

public static int getPort(String vncServerName) {
int colonPos = getColonPos(vncServerName);

Expand Down
40 changes: 16 additions & 24 deletions java/com/turbovnc/rfb/Params.java
Original file line number Diff line number Diff line change
Expand Up @@ -433,15 +433,8 @@ public void print(String message) {
while (current != null) {
if (!(current instanceof HeaderParameter)) {
String str = current.getStr();
if (tunnel.get() && current.getName().equalsIgnoreCase("Server") &&
str != null && sshUser != null)
System.out.println(current.getName() + " = " + sshUser + "@" + str);
else if (!tunnel.get() && current.getName().equalsIgnoreCase("Via") &&
str != null && sshUser != null)
System.out.println(current.getName() + " = " + sshUser + "@" + str);
else
System.out.println(current.getName() + " = " +
(str == null ? "" : str));
System.out.println(current.getName() + " = " +
(str == null ? "" : str));
}
current = current.next();
}
Expand All @@ -465,8 +458,6 @@ public void resetGUI() {
current.reset();
current = current.next();
}
if (!via.isCommandLine() && !server.isCommandLine())
sshUser = null;

reconcile();
}
Expand All @@ -481,10 +472,7 @@ public void save(String node) {
String name = current.getName();
String value = current.getStr();

if (name.equalsIgnoreCase("Via") && value != null && sshUser != null)
UserPreferences.set(node, name, sshUser + "@" + value);
else
UserPreferences.set(node, name, value);
UserPreferences.set(node, name, value);
}
current = current.next();
}
Expand Down Expand Up @@ -935,7 +923,8 @@ public void save(String node) {

public BoolParameter localUsernameLC =
new BoolParameter("LocalUsernameLC", this, false,
"When the SendLocalUsername parameter is set, setting this parameter will " +
"When the SendLocalUsername parameter is set, or when using SSH " +
"tunneling without a specified SSH username, setting this parameter will " +
"cause the local username to be sent in lowercase, which may be useful " +
"when using the viewer on Windows machines (Windows allows mixed-case " +
"usernames, whereas Un*x and Mac platforms generally don't.)", false);
Expand Down Expand Up @@ -1052,14 +1041,20 @@ public void save(String node) {
"When using the built-in SSH client, this parameter specifies the TCP " +
"port on which the SSH server is listening.", 22, 0, 65535);

public StringParameter sshUser =
new StringParameter("SSHUser", this, true,
"The username (default = local username) that should be used when " +
"authenticating with the SSH server. When using the Tunnel parameter or " +
"the TurboVNC Session Manager, the SSH username can also be specified by " +
"prefixing the VNC host with the username followed by @. When using the " +
"Via parameter with an SSH server, the SSH username can also be specified " +
"by prefixing the gateway host with the username followed by @.", null);

public BoolParameter tunnel =
new BoolParameter("Tunnel", this, true,
"Setting this parameter is equivalent to using the Via parameter with an " +
"SSH gateway, except that the gateway host is assumed to be the same as " +
"the VNC host, so you do not need to specify it separately. When using " +
"the Tunnel parameter, the VNC host can be prefixed with {user}@ to " +
"indicate that username {user} (default = local username) should be used " +
"when authenticating with the SSH server.\n " +
"the VNC host, so you do not need to specify it separately.\n " +

"When using the TurboVNC Session Manager, this parameter is effectively " +
"set unless the SessMgrAuto parameter is disabled.\n " +
Expand Down Expand Up @@ -1091,9 +1086,7 @@ public void save(String node) {
"and listening on port 5900 (VNC display :0.) If using the UltraVNC " +
"Repeater in \"Mode II\", then specify ID:xxxx as the VNC server name, " +
"where xxxx is the ID number of the VNC server to which you want to " +
"connect. If using an SSH server, then the gateway host can be prefixed " +
"with {user}@ to indicate that username {user} (default = local username) " +
"should be used when authenticating with the SSH server.", null);
"connect.", null);

public StringParameter x509ca =
new StringParameter("X509CA", this, true,
Expand All @@ -1111,7 +1104,6 @@ public void save(String node) {

public boolean sessMgrActive, sshTunnelActive;
public com.jcraft.jsch.Session sshSession;
public String sshUser;
public Socket stdioSocket;
public String udsPath;

Expand Down
16 changes: 12 additions & 4 deletions java/com/turbovnc/rfb/ServerNameParameter.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,24 @@ public synchronized boolean set(String str) {
str = str.replaceAll("\\s", "");
int atIndex = str.lastIndexOf('@');
if (atIndex >= 0) {
params.sshUser = str.substring(0, atIndex);
params.sshUser.set(str.substring(0, atIndex));
if (isCommandLine() || getName().equalsIgnoreCase("Server"))
params.sshUser.setCommandLine(true);
return super.set(str.substring(atIndex + 1));
}
}
return super.set(str);
}

public synchronized boolean setDefault(String str) {
boolean retval = set(str);
retval &= super.setDefault(value);
return retval;
if (str != null && !str.isEmpty()) {
str = str.replaceAll("\\s", "");
int atIndex = str.lastIndexOf('@');
if (atIndex >= 0) {
params.sshUser.setDefault(str.substring(0, atIndex));
return super.setDefault(str.substring(atIndex + 1));
}
}
return super.setDefault(str);
}
}
1 change: 1 addition & 0 deletions java/com/turbovnc/rfb/VoidParameter.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public VoidParameter(String name_, Params params_, boolean isGUI_,
public abstract boolean set(String str);

public final boolean set(String str, boolean commandLine_) {
setCommandLine(commandLine_);
boolean retval = set(str);
setCommandLine(commandLine_);
return retval;
Expand Down
6 changes: 3 additions & 3 deletions java/com/turbovnc/vncviewer/OptionsDialog.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2012-2018, 2020-2022 D. R. Commander. All Rights Reserved.
/* Copyright (C) 2012-2018, 2020-2023 D. R. Commander. All Rights Reserved.
* Copyright (C) 2011-2013 Brian P. Hinz
* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
Expand Down Expand Up @@ -1261,7 +1261,7 @@ public void setOptions(boolean enableDesktopSize, boolean disableShared,
x509crl.setText(params.x509crl.get());

// Security: Gateway
sshUser.setText(params.sshUser);
sshUser.setText(params.sshUser.get());
gateway.setText(params.via.get());
tunnel.setSelected(params.tunnel.get());

Expand Down Expand Up @@ -1373,7 +1373,7 @@ public void getOptions() {
params.x509crl.set(x509crl.getText().isEmpty() ? null : x509crl.getText());

// Security: Gateway
params.sshUser = sshUser.getText().isEmpty() ? null : sshUser.getText();
params.sshUser.set(sshUser.getText().isEmpty() ? null : sshUser.getText());
params.via.set(gateway.getText().isEmpty() ? null : gateway.getText());
params.tunnel.set(tunnel.isSelected());

Expand Down
16 changes: 10 additions & 6 deletions java/com/turbovnc/vncviewer/Tunnel.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,7 @@ protected static void createTunnelJSch(String host, Params params)

// username and passphrase will be given via UserInfo interface.
int port = params.sshPort.get();
String user = params.sshUser;
if (user == null)
user = (String)System.getProperties().get("user.name");
String user = params.sshUser.get();

File sshConfigFile = new File(params.sshConfig.get());
if (sshConfigFile.exists() && sshConfigFile.canRead()) {
Expand All @@ -191,7 +189,7 @@ protected static void createTunnelJSch(String host, Params params)
// getSession() if the configuration has already been set using an
// OpenSSH configuration file.
String repoUser = repo.getConfig(host).getUser();
if (repoUser != null)
if (repoUser != null && user == null)
user = repoUser;
String[] identityFiles = repo.getConfig(host).getValues("IdentityFile");
if (identityFiles != null) {
Expand All @@ -209,6 +207,12 @@ protected static void createTunnelJSch(String host, Params params)
}
}

if (user == null) {
user = (String)System.getProperties().get("user.name");
if (params.localUsernameLC.get())
user = user.toLowerCase();
}

if (useDefaultPrivateKeyFiles) {
privateKeys.add(new File(homeDir + "/.ssh/id_rsa"));
privateKeys.add(new File(homeDir + "/.ssh/id_dsa"));
Expand Down Expand Up @@ -348,8 +352,8 @@ private static String fillCmdPattern(String pattern, String gatewayHost,
boolean hFound = false, gFound = false, rFound = false, lFound = false;
String command = "";

if (params.sshUser != null)
gatewayHost = params.sshUser + "@" + gatewayHost;
if (params.sshUser.get() != null)
gatewayHost = params.sshUser.get() + "@" + gatewayHost;

for (i = 0; i < pattern.length(); i++) {
if (pattern.charAt(i) == '%') {
Expand Down
2 changes: 1 addition & 1 deletion unix/Xvnc/programs/Xserver/Xext/saver.c
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,7 @@ ScreenSaverSetAttributes(ClientPtr client)
pVlist++;
}
if (pPriv->attr)
FreeScreenAttr(pPriv->attr);
FreeResource(pPriv->attr->resource, AttrType);
pPriv->attr = pAttr;
pAttr->resource = FakeClientID(client->index);
if (!AddResource(pAttr->resource, AttrType, (void *) pAttr))
Expand Down
5 changes: 3 additions & 2 deletions unix/Xvnc/programs/Xserver/Xext/xtest.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,10 +501,11 @@ XTestSwapFakeInput(ClientPtr client, xReq * req)

nev = ((req->length << 2) - sizeof(xReq)) / sizeof(xEvent);
for (ev = (xEvent *) &req[1]; --nev >= 0; ev++) {
int evtype = ev->u.u.type & 0x177;
/* Swap event */
proc = EventSwapVector[ev->u.u.type & 0177];
proc = EventSwapVector[evtype];
/* no swapping proc; invalid event type? */
if (!proc || proc == NotImplemented) {
if (!proc || proc == NotImplemented || evtype == GenericEvent) {
client->errorValue = ev->u.u.type;
return BadValue;
}
Expand Down
4 changes: 3 additions & 1 deletion unix/Xvnc/programs/Xserver/Xext/xvmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -811,8 +811,10 @@ XvdiSelectVideoNotify(ClientPtr client, DrawablePtr pDraw, BOOL onoff)
tpn = pn;
while (tpn) {
if (tpn->client == client) {
if (!onoff)
if (!onoff) {
tpn->client = NULL;
FreeResource(tpn->id, XvRTVideoNotify);
}
return Success;
}
if (!tpn->client)
Expand Down
4 changes: 3 additions & 1 deletion unix/Xvnc/programs/Xserver/Xi/exevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,8 +575,10 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
memcpy(to->button->xkb_acts, from->button->xkb_acts,
sizeof(XkbAction));
}
else
else {
free(to->button->xkb_acts);
to->button->xkb_acts = NULL;
}

memcpy(to->button->labels, from->button->labels,
from->button->numButtons * sizeof(Atom));
Expand Down
22 changes: 14 additions & 8 deletions unix/Xvnc/programs/Xserver/Xi/xipassivegrab.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ ProcXIPassiveGrabDevice(ClientPtr client)
return BadValue;
}

/* XI2 allows 32-bit keycodes but thanks to XKB we can never
* implement this. Just return an error for all keycodes that
* cannot work anyway, same for buttons > 255. */
if (stuff->detail > 255)
return XIAlreadyGrabbed;

if (XICheckInvalidMaskBits(client, (unsigned char *) &stuff[1],
stuff->mask_len * 4) != Success)
return BadValue;
Expand Down Expand Up @@ -203,14 +209,8 @@ ProcXIPassiveGrabDevice(ClientPtr client)
&param, XI2, &mask);
break;
case XIGrabtypeKeycode:
/* XI2 allows 32-bit keycodes but thanks to XKB we can never
* implement this. Just return an error for all keycodes that
* cannot work anyway */
if (stuff->detail > 255)
status = XIAlreadyGrabbed;
else
status = GrabKey(client, dev, mod_dev, stuff->detail,
&param, XI2, &mask);
status = GrabKey(client, dev, mod_dev, stuff->detail,
&param, XI2, &mask);
break;
case XIGrabtypeEnter:
case XIGrabtypeFocusIn:
Expand Down Expand Up @@ -319,6 +319,12 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
return BadValue;
}

/* We don't allow passive grabs for details > 255 anyway */
if (stuff->detail > 255) {
client->errorValue = stuff->detail;
return BadValue;
}

rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
if (rc != Success)
return rc;
Expand Down
Loading

0 comments on commit ca0fb8c

Please sign in to comment.