Commit 21f30a4f authored by Paul Tvete's avatar Paul Tvete
Browse files

WIP start implementing VeNCrypt

parent 50df3f81
......@@ -588,10 +588,17 @@ void QVncClient::readClient()
} else {
// Authentication negotiation
QByteArray supportedSecurity;
// TESTING
if (0) {
supportedSecurity.append(char(SecurityVeNCrypt));
}
#ifdef QT_VNC_AUTH
if (!m_password.isEmpty())
supportedSecurity.append(char(SecurityVncAuthentication));
#endif
supportedSecurity.append(char(SecurityNone));
const char size = supportedSecurity.size();
......@@ -637,9 +644,64 @@ void QVncClient::readClient()
m_state = ClientState::Disconnected;
}
}
if (m_securityType == SecurityVeNCrypt && m_clientSocket->bytesAvailable() >= 2) {
char version[2];
m_clientSocket->read(version, 2);
qDebug() << "VeN version" << uint(version[0]) << uint(version[1]);
bool versionSupported = version[0] == 0 && version[1] >= 2;
char response = versionSupported ? 0 : 1; // 0 success, 1 failure
m_clientSocket->write(&response, 1);
qDebug() << "Supported?" << uint(response);
if (!versionSupported) {
m_state = ClientState::Disconnected;
discardClient();
break;
}
const quint32 subtypes[] = {
//VenCryptPlain,
htonl(VenCryptTLSNone),
htonl(VenCryptTLSVnc),
htonl(VenCryptTLSPlain),
htonl(SecurityVncAuthentication) // #### TESTING
// VenCryptX509None,
// VenCryptX509Vnc,
// VenCryptX509Plain,
// VenCryptTLSSASL,
// VenCryptX509SASL
};
const char size = sizeof(subtypes) / sizeof(quint32);
m_clientSocket->write(&size, 1);
m_clientSocket->write(reinterpret_cast<const char*>(subtypes), sizeof(subtypes));
m_state = ClientState::VeNCrypt;
qDebug() << "Wrote size:" << uint(size) << "bytes:" << sizeof(subtypes);
qDebug() << "bytes available" << m_clientSocket->bytesAvailable();
}
#endif // QT_VNC_AUTH
break;
case ClientState::VeNCrypt:
if (m_clientSocket->bytesAvailable() >= 4) {
quint32 subtype;
m_clientSocket->read(reinterpret_cast<char *>(&subtype), sizeof(subtype));
qDebug() << "Got VenCrypt subtype" << ntohl(subtype);
// just give up now, since we don't actually support anything yet
const char response = 0; //1 success, because why be consistent? Everything else failure
m_clientSocket->write(&response, 1);
}
break;
case ClientState::Security:
if (m_clientSocket->bytesAvailable() >= 1) {
m_clientSocket->read(reinterpret_cast<char *>(&m_securityType), 1);
......@@ -656,6 +718,23 @@ void QVncClient::readClient()
break;
}
#endif
if (m_securityType == SecurityVeNCrypt) {
char version[] = {0, 2};
m_clientSocket->write(version, sizeof(version));
m_state = ClientState::Authentication;
break;
}
if (m_securityType != SecurityNone || !m_password.isEmpty()) {
// Abort connection, since we want security, but got none
qCWarning(lcVnc) << "Authentication type" << m_securityType << "not handled, aborting connection.";
m_state = ClientState::Disconnected;
discardClient();
break;
}
if (m_protocolVersion >= ProtocolVersion::V3_8) {
// SecurityResult
// OK = 0, Failed = 1 (TooManyAttempts = 2)
......
......@@ -164,6 +164,8 @@ private:
Protocol,
Authentication,
Security,
VeNCrypt, //TODO: move auth state machine to separate class
//VeNCrypt2, //TODO: move auth state machine to separate class
Init,
Connected
};
......@@ -173,6 +175,18 @@ private:
V3_8
};
enum VeNCryptSecurity : quint32 {
VenCryptPlain = 256,
VenCryptTLSNone = 257,
VenCryptTLSVnc = 258,
VenCryptTLSPlain = 259,
VenCryptX509None = 260,
VenCryptX509Vnc = 261,
VenCryptX509Plain = 262,
VenCryptTLSSASL = 263,
VenCryptX509SASL = 264
};
enum SecurityType : uchar {
SecurityInvalid = 0,
SecurityNone = 1,
......
import QtQuick
import QtQuick.Controls
import QtQuickVnc
Window {
width: 1024
height: 768
visible: true
property bool rotateRect: true
property bool animateEverything: false
VncItem {
id: grabber
anchors.fill: parent
password: "hunter2"
Rectangle {
id: sourceRect
color: "#ccffcc"
anchors.fill: parent
Rectangle {
anchors.top: parent.top
anchors.right: parent.right
width: 200
height: 100
color: "cyan"
Text {
anchors.centerIn: parent
text: "Active\nconnection"
font.bold: true
font.pixelSize: 24
color: "red"
}
visible: grabber.connectionActive
}
Rectangle {
anchors.centerIn: parent
width: 100
height: 100
color: "red"
NumberAnimation on rotation {
from: 0
to: 90
loops: -1
running: rotateRect
}
}
Rectangle {
id: mouseIndicator
width: 30
height: 30
radius: 15
color: "blue"
}
MouseArea {
anchors.fill: parent
onPositionChanged: (mouse) => {
mouseIndicator.x = mouse.x - 15
mouseIndicator.y = mouse.y - 15
}
onPressed: (mouse) => {
mouseIndicator.color = "orange"
mouseIndicator.x = mouse.x - 15
mouseIndicator.y = mouse.y - 15
console.log("mouse", mouse.x, mouse.y)
}
onReleased: (mouse) => mouseIndicator.color = "blue"
}
Rectangle {
width: 200
height: 50
color: "white"
x: 10
y: 10
TextInput {
anchors.fill: parent
text: "Input..."
selectByMouse: true
}
}
Rectangle {
width: 200
height: 50
color: "white"
x: 10
y: 100
TextField {
anchors.fill: parent
text: "Other input..."
selectByMouse: true
}
}
Rectangle {
id: mouseHandlerArea
color: "#ccccff"
x: 50
y: 150
width: 200
height: 200
Rectangle {
id: mouseIndicator2
width: 20
height: 20
radius: 10
x: ph.point.position.x - radius
y: ph.point.position.y - radius
color: ph.active? "maroon" : "teal"
}
PointHandler {
id: ph
}
}
Rectangle {
id: otherMouseArea
color: "#ffcccc"
x: 50
y: 400
width: 200
height: 200
Rectangle {
id: mouseIndicator3
width: 20
height: 20
radius: 10
color: "lightblue"
}
MouseArea {
hoverEnabled: true
anchors.fill: parent
onEntered: otherMouseArea.color = "#ffaaaa";
onExited: otherMouseArea.color = "#ffcccc";
onPositionChanged: (mouse) => {
mouseIndicator3.x = mouse.x - 10
mouseIndicator3.y = mouse.y - 10
}
onPressed: (mouse) => {
mouseIndicator3.color = "lightgreen"
mouseIndicator3.x = mouse.x - 10
mouseIndicator3.y = mouse.y - 10
console.log("mouse", mouse.x, mouse.y)
}
onReleased: (mouse) => mouseIndicator3.color = "lightblue"
}
}
Rectangle {
id: overlay
visible: animateEverything
anchors.fill: parent
opacity: 0.5
ColorAnimation on color {
from: "#00ff77"
to: "#ff77ff"
duration: 1000
loops: -1
running: animateEverything
}
}
} // sourceRect
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment