Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: shinyhut/vernacular-vnc
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: xpipe-io/vernacular-vnc
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Able to merge. These branches can be automatically merged.
  • 14 commits
  • 43 files changed
  • 1 contributor

Commits on Apr 10, 2024

  1. Copy the full SHA
    0a213b5 View commit details
  2. Rebase fixes

    crschnick committed Apr 10, 2024
    Copy the full SHA
    d996224 View commit details

Commits on Apr 22, 2024

  1. Fix NPE

    crschnick committed Apr 22, 2024
    Copy the full SHA
    f4e07b1 View commit details

Commits on May 27, 2024

  1. Protocol version fixes

    crschnick committed May 27, 2024
    Copy the full SHA
    a7b145e View commit details

Commits on Jun 2, 2024

  1. Fix version check

    crschnick committed Jun 2, 2024
    Copy the full SHA
    d077eaa View commit details

Commits on Jul 17, 2024

  1. Implement aes eax

    crschnick committed Jul 17, 2024
    Copy the full SHA
    dca8889 View commit details
  2. Nonce fixes

    crschnick committed Jul 17, 2024
    Copy the full SHA
    94ab827 View commit details

Commits on Jul 19, 2024

  1. Various auth fixes

    crschnick committed Jul 19, 2024
    Copy the full SHA
    17e290a View commit details

Commits on Jul 22, 2024

  1. Auth fixes

    crschnick committed Jul 22, 2024
    Copy the full SHA
    3f6f873 View commit details

Commits on Sep 5, 2024

  1. Add more sec types

    crschnick committed Sep 5, 2024
    Copy the full SHA
    640530a View commit details

Commits on Nov 19, 2024

  1. Fix auth

    crschnick committed Nov 19, 2024
    Copy the full SHA
    fd38c7b View commit details
  2. Bump deps

    crschnick committed Nov 19, 2024
    Copy the full SHA
    dd4fa08 View commit details

Commits on Mar 19, 2025

  1. Properly match color depth

    crschnick committed Mar 19, 2025
    Copy the full SHA
    f29fe4a View commit details

Commits on Mar 20, 2025

  1. Copy the full SHA
    ccff9de View commit details
Showing with 919 additions and 196 deletions.
  1. +44 −9 pom.xml
  2. +22 −30 src/main/java/com/shinyhut/vernacular/VernacularViewer.java
  3. +1 −1 src/main/java/com/shinyhut/vernacular/client/ClientEventHandler.java
  4. +2 −2 src/main/java/com/shinyhut/vernacular/client/ServerEventHandler.java
  5. +5 −2 src/main/java/com/shinyhut/vernacular/client/VernacularClient.java
  6. +14 −31 src/main/java/com/shinyhut/vernacular/client/VernacularConfig.java
  7. +11 −3 src/main/java/com/shinyhut/vernacular/client/VncSession.java
  8. +20 −2 src/main/java/com/shinyhut/vernacular/client/exceptions/NoSupportedSecurityTypesException.java
  9. +38 −0 src/main/java/com/shinyhut/vernacular/client/exceptions/RealVncProtocolVersionException.java
  10. +8 −0 src/main/java/com/shinyhut/vernacular/client/exceptions/SecurityTypeFailedException.java
  11. +0 −1 src/main/java/com/shinyhut/vernacular/client/exceptions/UnsupportedProtocolVersionException.java
  12. +13 −21 src/main/java/com/shinyhut/vernacular/client/rendering/Framebuffer.java
  13. +70 −0 src/main/java/com/shinyhut/vernacular/client/rendering/ImageBuffer.java
  14. +3 −6 src/main/java/com/shinyhut/vernacular/client/rendering/renderers/CopyRectRenderer.java
  15. +3 −6 src/main/java/com/shinyhut/vernacular/client/rendering/renderers/CursorRenderer.java
  16. +4 −8 src/main/java/com/shinyhut/vernacular/client/rendering/renderers/HextileRenderer.java
  17. +4 −0 src/main/java/com/shinyhut/vernacular/client/rendering/renderers/Pixel.java
  18. +4 −9 src/main/java/com/shinyhut/vernacular/client/rendering/renderers/RRERenderer.java
  19. +4 −5 src/main/java/com/shinyhut/vernacular/client/rendering/renderers/RawRenderer.java
  20. +2 −2 src/main/java/com/shinyhut/vernacular/client/rendering/renderers/Renderer.java
  21. +2 −2 src/main/java/com/shinyhut/vernacular/client/rendering/renderers/ZLibRenderer.java
  22. +1 −1 src/main/java/com/shinyhut/vernacular/protocol/auth/NoSecurityHandler.java
  23. +297 −0 src/main/java/com/shinyhut/vernacular/protocol/auth/RsaAesAuthenticationHandler.java
  24. +11 −0 src/main/java/com/shinyhut/vernacular/protocol/auth/SecurityHandler.java
  25. +3 −1 src/main/java/com/shinyhut/vernacular/protocol/handshaking/Handshaker.java
  26. +11 −0 src/main/java/com/shinyhut/vernacular/protocol/handshaking/ProtocolVersionNegotiator.java
  27. +17 −11 src/main/java/com/shinyhut/vernacular/protocol/handshaking/SecurityTypeNegotiator.java
  28. +19 −16 src/main/java/com/shinyhut/vernacular/protocol/initialization/Initializer.java
  29. +47 −0 src/main/java/com/shinyhut/vernacular/protocol/messages/Decoder.java
  30. +36 −0 src/main/java/com/shinyhut/vernacular/protocol/messages/Encoder.java
  31. +1 −2 src/main/java/com/shinyhut/vernacular/protocol/messages/Encoding.java
  32. +2 −1 src/main/java/com/shinyhut/vernacular/protocol/messages/ErrorMessage.java
  33. +7 −1 src/main/java/com/shinyhut/vernacular/protocol/messages/ProtocolVersion.java
  34. +1 −1 src/main/java/com/shinyhut/vernacular/protocol/messages/SecurityResult.java
  35. +13 −8 src/main/java/com/shinyhut/vernacular/protocol/messages/SecurityType.java
  36. +2 −2 src/main/java/com/shinyhut/vernacular/protocol/messages/ServerSecurityType.java
  37. +6 −5 src/main/java/com/shinyhut/vernacular/protocol/messages/ServerSecurityTypes.java
  38. +46 −0 src/main/java/com/shinyhut/vernacular/utils/AesEaxInputStream.java
  39. +51 −0 src/main/java/com/shinyhut/vernacular/utils/AesEaxOutputStream.java
  40. +18 −0 src/main/java/com/shinyhut/vernacular/utils/ByteUtils.java
  41. +37 −0 src/main/java/com/shinyhut/vernacular/utils/CryptoUtils.java
  42. +3 −7 src/main/java/com/shinyhut/vernacular/utils/KeySyms.java
  43. +16 −0 src/main/java/module-info.java
53 changes: 44 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
<groupId>com.shinyhut</groupId>
<artifactId>vernacular</artifactId>
<packaging>jar</packaging>
<version>1.15-SNAPSHOT</version>
<version>1.16</version>

<name>vernacular</name>
<description>A pure Java VNC client library and viewer application.</description>
@@ -35,8 +35,8 @@
</scm>

<properties>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<maven.compiler.source>21</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

@@ -45,14 +45,27 @@
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-bom</artifactId>
<version>2.0-groovy-3.0</version>
<version>2.3-groovy-4.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>1.79</version>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.32</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-core</artifactId>
@@ -64,27 +77,41 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy</artifactId>
<version>3.0.9</version>
<version>4.0.18</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.11.0</version>
<version>1.14.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>3.2</version>
<version>3.3</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.32</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
@@ -126,7 +153,7 @@
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.12.0</version>
<version>3.0.2</version>
<executions>
<execution>
<goals>
@@ -148,6 +175,14 @@
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<mainClass>com.shinyhut.vernacular.VernacularViewer</mainClass>
</configuration>
</plugin>
</plugins>
</build>

52 changes: 22 additions & 30 deletions src/main/java/com/shinyhut/vernacular/VernacularViewer.java
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

import com.shinyhut.vernacular.client.VernacularClient;
import com.shinyhut.vernacular.client.VernacularConfig;
import com.shinyhut.vernacular.client.rendering.ImageBuffer;

import javax.swing.*;
import javax.swing.event.AncestorEvent;
@@ -10,6 +11,7 @@
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.*;
import java.awt.image.BufferedImage;

import static com.shinyhut.vernacular.client.rendering.ColorDepth.*;
import static java.awt.BorderLayout.CENTER;
@@ -36,9 +38,6 @@ public class VernacularViewer extends JFrame {
private JMenuItem connectMenuItem;
private JMenuItem disconnectMenuItem;

private JMenuItem bpp8IndexedColorMenuItem;
private JMenuItem bpp16TrueColorMenuItem;
private JMenuItem bpp24TrueColorMenuItem;
private JMenuItem localCursorMenuItem;

private JMenu encodingsMenu;
@@ -210,21 +209,36 @@ public void paintComponent(Graphics g) {

private void initialiseVernacularClient() {
config = new VernacularConfig();
config.setColorDepth(BPP_16_TRUE);
config.setErrorListener(e -> {
e.printStackTrace();
showMessageDialog(this, e.getMessage(), "Error", ERROR_MESSAGE);
resetUI();
});
config.setUsernameSupplier(this::showUsernameDialog);
config.setPasswordSupplier(this::showPasswordDialog);
config.setScreenUpdateListener(this::renderFrame);
config.setMousePointerUpdateListener((p, h) -> this.setCursor(getDefaultToolkit().createCustomCursor(p, h, "vnc")));
config.setScreenUpdateListener(imageBuffer -> {
renderFrame(bufferToImage(imageBuffer));
});
config.setMousePointerUpdateListener((x, y, imageBuffer) -> {
this.setCursor(getDefaultToolkit().createCustomCursor(bufferToImage(imageBuffer), new Point(x, y), "vnc"));
});
config.setBellListener(v -> getDefaultToolkit().beep());
config.setRemoteClipboardListener(t -> getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(t), null));
config.setUseLocalMousePointer(localCursorMenuItem.isSelected());
client = new VernacularClient(config);
}

private BufferedImage bufferToImage(ImageBuffer buffer) {
var img = new BufferedImage(buffer.getWidth(), buffer.getHeight(),buffer.isAlpha() ?
BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < buffer.getWidth(); x++) {
for (int y = 0; y < buffer.getHeight(); y++) {
img.setRGB(x,y, buffer.get(x, y));
}
}
return img;
}

private void addMenu() {
JMenuBar menu = new JMenuBar();

@@ -243,19 +257,6 @@ private void addMenu() {
disconnectMenuItem.setEnabled(false);
disconnectMenuItem.addActionListener(event -> disconnect());

ButtonGroup colorDepths = new ButtonGroup();

bpp8IndexedColorMenuItem = new JRadioButtonMenuItem("8-bit Indexed Color");
bpp16TrueColorMenuItem = new JRadioButtonMenuItem("16-bit True Color", true);
bpp24TrueColorMenuItem = new JRadioButtonMenuItem("24-bit True Color");
colorDepths.add(bpp8IndexedColorMenuItem);
colorDepths.add(bpp16TrueColorMenuItem);
colorDepths.add(bpp24TrueColorMenuItem);

bpp8IndexedColorMenuItem.addActionListener(event -> config.setColorDepth(BPP_8_INDEXED));
bpp16TrueColorMenuItem.addActionListener(event -> config.setColorDepth(BPP_16_TRUE));
bpp24TrueColorMenuItem.addActionListener(event -> config.setColorDepth(BPP_24_TRUE));

localCursorMenuItem = new JCheckBoxMenuItem("Use Local Cursor", true);
localCursorMenuItem.addActionListener(event -> config.setUseLocalMousePointer(localCursorMenuItem.isSelected()));

@@ -287,9 +288,6 @@ private void addMenu() {
file.add(connectMenuItem);
file.add(disconnectMenuItem);
file.add(exit);
options.add(bpp8IndexedColorMenuItem);
options.add(bpp16TrueColorMenuItem);
options.add(bpp24TrueColorMenuItem);
options.add(localCursorMenuItem);
options.add(encodingsMenu);
menu.add(file);
@@ -299,9 +297,9 @@ private void addMenu() {

private void showConnectDialog() {
JPanel connectDialog = new JPanel();
JTextField hostField = new JTextField(20);
JTextField hostField = new JTextField("localhost", 20);
hostField.addAncestorListener(focusRequester);
JTextField portField = new JTextField("5900", 4);
JTextField portField = new JTextField("60782", 5);
JLabel hostLabel = new JLabel("Host");
hostLabel.setLabelFor(hostField);
JLabel portLabel = new JLabel("Port");
@@ -371,17 +369,11 @@ private void setMenuState(boolean running) {
if (running) {
connectMenuItem.setEnabled(false);
disconnectMenuItem.setEnabled(true);
bpp8IndexedColorMenuItem.setEnabled(false);
bpp16TrueColorMenuItem.setEnabled(false);
bpp24TrueColorMenuItem.setEnabled(false);
localCursorMenuItem.setEnabled(false);
encodingsMenu.setEnabled(false);
} else {
connectMenuItem.setEnabled(true);
disconnectMenuItem.setEnabled(false);
bpp8IndexedColorMenuItem.setEnabled(true);
bpp16TrueColorMenuItem.setEnabled(true);
bpp24TrueColorMenuItem.setEnabled(true);
localCursorMenuItem.setEnabled(true);
encodingsMenu.setEnabled(true);
}
Original file line number Diff line number Diff line change
@@ -146,7 +146,7 @@ private void requestFramebufferUpdate(boolean incremental) throws IOException {
private void sendMessage(Encodable message) throws IOException {
outputLock.lock();
try {
message.encode(session.getOutputStream());
session.getMessageEncoder().encode(message);
} finally {
outputLock.unlock();
}
Original file line number Diff line number Diff line change
@@ -28,8 +28,8 @@ public class ServerEventHandler {
this.framebuffer = new Framebuffer(session);
}

void start() {
PushbackInputStream in = new PushbackInputStream(session.getInputStream());
void start() throws IOException {
PushbackInputStream in = new PushbackInputStream(session.getMessageDecoder().getInputStream());

running = true;

Original file line number Diff line number Diff line change
@@ -177,7 +177,7 @@ public void scrollDown() {
* @see java.awt.event.KeyEvent KeyEvent
*/
public void handleKeyEvent(KeyEvent event) {
KeySyms.forEvent(event).ifPresent(k -> {
KeySyms.map(event.getKeyCode(), event.getKeyChar(), event.isShiftDown()).ifPresent(k -> {
switch (event.getID()) {
case KEY_PRESSED:
case KEY_RELEASED:
@@ -276,7 +276,10 @@ private void createSession(Socket socket) throws IOException, VncException {
OutputStream out = socket.getOutputStream();
session = new VncSession(config, in, out);

handshaker.handshake(session);
var handler = handshaker.handshake(session);
session.setMessageDecoder(handler.getSessionDecoder(session));
session.setMessageEncoder(handler.getSessionEncoder(session));

initializer.initialise(session);
}

45 changes: 14 additions & 31 deletions src/main/java/com/shinyhut/vernacular/client/VernacularConfig.java
Original file line number Diff line number Diff line change
@@ -3,11 +3,10 @@
import com.shinyhut.vernacular.client.exceptions.VncException;
import com.shinyhut.vernacular.client.rendering.ColorDepth;
import com.shinyhut.vernacular.protocol.messages.MessageHeaderFlags;
import com.shinyhut.vernacular.client.rendering.ImageBuffer;

import java.awt.*;
import java.util.EnumMap;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;

@@ -18,21 +17,19 @@ public class VernacularConfig {
private Supplier<String> usernameSupplier;
private Supplier<String> passwordSupplier;
private Consumer<VncException> errorListener;
private Consumer<Image> screenUpdateListener;
private Consumer<ImageBuffer> screenUpdateListener;
private Consumer<Void> bellListener;
private Consumer<String> remoteClipboardListener;
private BiConsumer<Image, Point> mousePointerUpdateListener;
private MousePointerUpdateListener mousePointerUpdateListener;
private boolean shared = true;
private int targetFramesPerSecond = 30;
private ColorDepth colorDepth = BPP_8_INDEXED;
private boolean useLocalMousePointer = false;
private boolean enableCopyrectEncoding = true;
private boolean enableExtendedClipboard = true;
private boolean enableRreEncoding = true;
private boolean enableHextileEncoding = true;
private boolean enableZLibEncoding = false;

private Map<MessageHeaderFlags, Integer> maxSizePerFormat = new EnumMap<>(MessageHeaderFlags.class);
private final Map<MessageHeaderFlags, Integer> maxSizePerFormat = new EnumMap<>(MessageHeaderFlags.class);

public Supplier<String> getUsernameSupplier() {
return usernameSupplier;
@@ -74,7 +71,7 @@ public void setErrorListener(Consumer<VncException> errorListener) {
this.errorListener = errorListener;
}

public Consumer<Image> getScreenUpdateListener() {
public Consumer<ImageBuffer> getScreenUpdateListener() {
return screenUpdateListener;
}

@@ -83,13 +80,17 @@ public Consumer<Image> getScreenUpdateListener() {
* we receive a screen update.
*
* @param screenUpdateListener A Consumer which will receive Images representing the updated remote desktop
* @see java.awt.Image Image
*/
public void setScreenUpdateListener(Consumer<Image> screenUpdateListener) {
public void setScreenUpdateListener(Consumer<ImageBuffer> screenUpdateListener) {
this.screenUpdateListener = screenUpdateListener;
}

public BiConsumer<Image, Point> getMousePointerUpdateListener() {
public static interface MousePointerUpdateListener {

void update(int x, int y, ImageBuffer imageBuffer);
}

public MousePointerUpdateListener getMousePointerUpdateListener() {
return mousePointerUpdateListener;
}

@@ -99,9 +100,8 @@ public BiConsumer<Image, Point> getMousePointerUpdateListener() {
* screen).
*
* @param mousePointerUpdateListener A Consumer which will receive Images representing the updated cursor shape
* @see java.awt.Image Image
*/
public void setMousePointerUpdateListener(BiConsumer<Image, Point> mousePointerUpdateListener) {
public void setMousePointerUpdateListener(MousePointerUpdateListener mousePointerUpdateListener) {
this.mousePointerUpdateListener = mousePointerUpdateListener;
}

@@ -166,29 +166,12 @@ public void setTargetFramesPerSecond(int targetFramesPerSecond) {
this.targetFramesPerSecond = targetFramesPerSecond;
}

public ColorDepth getColorDepth() {
return colorDepth;
}

/**
* Specifies the color depth to request from the remote server. Note that the greater the color depth, the more
* bandwidth we will consume.
* <p>
* Default: 8 bits per pixel
*
* @param colorDepth The color depth for rendering the remote desktop
* @see com.shinyhut.vernacular.client.rendering.ColorDepth ColorDepth
*/
public void setColorDepth(ColorDepth colorDepth) {
this.colorDepth = colorDepth;
}

/**
* Indicate to the server that the client can draw the mouse pointer locally. The server should not include the
* mouse pointer in framebuffer updates, and it should send separate notifications when the mouse pointer image
* changes
*
* @see #setMousePointerUpdateListener(BiConsumer)
* @see #setMousePointerUpdateListener(MousePointerUpdateListener)
* @param useLocalMousePointer enable or disable client side mouse pointer rendering
*/
public void setUseLocalMousePointer(boolean useLocalMousePointer) {
Loading