nvazquez commented on code in PR #7015:
URL: https://github.com/apache/cloudstack/pull/7015#discussion_r1055639044


##########
services/console-proxy/server/src/main/java/com/cloud/consoleproxy/vnc/NoVncClient.java:
##########
@@ -239,16 +273,349 @@ public byte[] encodePassword(byte[] challenge, String 
password) throws Exception
         return response;
     }
 
+    /**
+     * Decide the RFB protocol version with the VNC server
+     * Reference: 
https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#711protocolversion
+     */
+    protected String handshakeProtocolVersion(RemoteEndpoint clientRemote) 
throws IOException {
+        // Read protocol version
+        byte[] buf = new byte[12];
+        tunnelInputStream.readFully(buf);
+        String rfbProtocol = new String(buf);
+
+        // Server should use RFB protocol 3.x
+        if (!rfbProtocol.contains(RfbConstants.RFB_PROTOCOL_VERSION_MAJOR)) {
+            s_logger.error("Cannot handshake with VNC server. Unsupported 
protocol version: \"" + rfbProtocol + "\".");
+            throw new RuntimeException(
+                    "Cannot handshake with VNC server. Unsupported protocol 
version: \"" + rfbProtocol + "\".");
+        }
+        tunnelOutputStream.write(buf);
+        return RfbConstants.RFB_PROTOCOL_VERSION + "\n";
+    }
+
+    /**
+     * Agree on the security type with the VNC server
+     * Reference: 
https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#712security
+     * @return list of the security types to be processed
+     */
+    protected List<VncSecurity> handshakeSecurityTypes(RemoteEndpoint 
clientRemote, String vmPassword,
+                                                       String host, int port) 
throws IOException {
+        int securityType = selectFromTheServerOfferedSecurityTypes();
+
+        // Inform the server about our decision
+        this.tunnelOutputStream.writeByte(securityType);
+
+        byte[] numberTypesToClient = new byte[] { 1, (byte) securityType };
+        clientRemote.sendBytes(ByteBuffer.wrap(numberTypesToClient, 0, 2));
+
+        if (securityType == RfbConstants.V_ENCRYPT) {
+            securityType = getVEncryptSecuritySubtype();
+        }
+        return VncSecurity.getSecurityStack(securityType, vmPassword, host, 
port);
+    }
+
+    /**
+     * Obtain the VEncrypt subtype from the VNC server
+     *
+     * Reference: 
https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#724vencrypt
+     */
+    protected int getVEncryptSecuritySubtype() throws IOException {
+        int majorVEncryptVersion = socketConnection.readUnsignedInteger(8);
+        int minorVEncryptVersion = socketConnection.readUnsignedInteger(8);
+        int vEncryptVersion = (majorVEncryptVersion << 8) | 
minorVEncryptVersion;
+        s_logger.debug("VEncrypt version: " + vEncryptVersion);
+        socketConnection.writeUnsignedInteger(8, majorVEncryptVersion);
+        if (vEncryptVersion >= 0x0002) {
+            socketConnection.writeUnsignedInteger(8, 2);
+            socketConnection.flushWriteBuffer();
+        } else {
+            socketConnection.writeUnsignedInteger(8, 0);
+            socketConnection.flushWriteBuffer();
+            throw new CloudRuntimeException("Server reported an unsupported 
VeNCrypt version");
+        }
+        int ack = socketConnection.readUnsignedInteger(8);
+        if (ack != 0) {
+            throw new IOException("The VNC server did not agree on the 
VEncrypt version");
+        }
+
+        int numberOfSubtypes = socketConnection.readUnsignedInteger(8);
+        if (numberOfSubtypes <= 0) {
+            throw new CloudRuntimeException("The server reported no VeNCrypt 
sub-types");
+        }
+        int selectedSubtype = 0;
+        for (int i = 0; i < numberOfSubtypes; i++) {
+            while (!socketConnection.checkIfBytesAreAvailableForReading(4)) {
+                s_logger.trace("Waiting for vEncrypt subtype");

Review Comment:
   I've refactored this a bit, maybe the trace logs could be removed



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to