Make it easier to identify communication issues.
if (sscanf(verStr, "RFB %03d.%03d\n",
&majorVersion, &minorVersion) != 2) {
state_ = RFBSTATE_INVALID;
- throw Exception("reading version failed: not an RFB server?");
+ throw ProtocolException("reading version failed: not an RFB server?");
}
server.setVersion(majorVersion, minorVersion);
vlog.error("Server gave unsupported RFB protocol version %d.%d",
server.majorVersion, server.minorVersion);
state_ = RFBSTATE_INVALID;
- throw Exception(format("Server gave unsupported RFB protocol version %d.%d",
- server.majorVersion, server.minorVersion));
+ throw ProtocolException(format("Server gave unsupported RFB "
+ "protocol version %d.%d",
+ server.majorVersion,
+ server.minorVersion));
} else if (server.beforeVersion(3,7)) {
server.setVersion(3,3);
} else if (server.afterVersion(3,8)) {
secType = secTypeInvalid;
} else {
vlog.error("Unknown 3.3 security type %d", secType);
- throw Exception("Unknown 3.3 security type");
+ throw ProtocolException("Unknown 3.3 security type");
}
} else {
if (secType == secTypeInvalid) {
state_ = RFBSTATE_INVALID;
vlog.error("No matching security types");
- throw Exception("No matching security types");
+ throw ProtocolException("No matching security types");
}
state_ = RFBSTATE_SECURITY;
vlog.debug("auth failed - too many tries");
break;
default:
- throw Exception("Unknown security result from server");
+ throw ProtocolException("Unknown security result from server");
}
if (server.beforeVersion(3,8)) {
ret = readEndOfContinuousUpdates();
break;
default:
- throw Exception(format("Unknown message type %d", currentMsgType));
+ throw ProtocolException(format("Unknown message type %d", currentMsgType));
}
if (ret)
return false;
if (len < 4)
- throw Exception("Invalid extended clipboard message");
+ throw ProtocolException("Invalid extended clipboard message");
if (len > maxCutText) {
vlog.error("Extended clipboard message too long (%d bytes) - ignoring", len);
is->skip(len);
}
if (len < (int32_t)(4 + 4*num))
- throw Exception("Invalid extended clipboard message");
+ throw ProtocolException("Invalid extended clipboard message");
num = 0;
for (i = 0;i < 16;i++) {
continue;
if (!zis.hasData(4))
- throw Exception("Extended clipboard decode error");
+ throw ProtocolException("Extended clipboard decode error");
lengths[num] = zis.readU32();
size_t chunk;
if (!zis.hasData(1))
- throw Exception("Extended clipboard decode error");
+ throw ProtocolException("Extended clipboard decode error");
chunk = zis.avail();
if (chunk > lengths[num])
}
if (!zis.hasData(lengths[num]))
- throw Exception("Extended clipboard decode error");
+ throw ProtocolException("Extended clipboard decode error");
buffers[num] = new uint8_t[lengths[num]];
zis.readBytes(buffers[num], lengths[num]);
handler->handleClipboardNotify(flags);
break;
default:
- throw Exception("Invalid extended clipboard action");
+ throw ProtocolException("Invalid extended clipboard action");
}
}
vlog.error("Rect too big: %dx%d at %d,%d exceeds %dx%d",
r.width(), r.height(), r.tl.x, r.tl.y,
handler->server.width(), handler->server.height());
- throw Exception("Rect too big");
+ throw ProtocolException("Rect too big");
}
if (r.is_empty())
bool CMsgReader::readSetXCursor(int width, int height, const Point& hotspot)
{
if (width > maxCursorSize || height > maxCursorSize)
- throw Exception("Too big cursor");
+ throw ProtocolException("Too big cursor");
std::vector<uint8_t> rgba(width*height*4);
bool CMsgReader::readSetCursor(int width, int height, const Point& hotspot)
{
if (width > maxCursorSize || height > maxCursorSize)
- throw Exception("Too big cursor");
+ throw ProtocolException("Too big cursor");
int data_len = width * height * (handler->server.pf().bpp/8);
int mask_len = ((width+7)/8) * height;
bool CMsgReader::readSetCursorWithAlpha(int width, int height, const Point& hotspot)
{
if (width > maxCursorSize || height > maxCursorSize)
- throw Exception("Too big cursor");
+ throw ProtocolException("Too big cursor");
const PixelFormat rgbaPF(32, 32, false, true, 255, 255, 255, 16, 8, 0);
ManagedPixelBuffer pb(rgbaPF, width, height);
bool CMsgReader::readSetVMwareCursor(int width, int height, const Point& hotspot)
{
if (width > maxCursorSize || height > maxCursorSize)
- throw Exception("Too big cursor");
+ throw ProtocolException("Too big cursor");
uint8_t type;
handler->setCursor(width, height, hotspot, data.data());
} else {
- throw Exception("Unknown cursor type");
+ throw ProtocolException("Unknown cursor type");
}
return true;
uint16_t gen = is->readU16();
keyLength = is->readU16();
if (keyLength < MinKeyLength)
- throw Exception("DH key is too short");
+ throw ProtocolException("DH key is too short");
if (keyLength > MaxKeyLength)
- throw Exception("DH key is too long");
+ throw ProtocolException("DH key is too long");
if (!is->hasDataOrRestore(keyLength * 2))
return false;
is->clearRestorePoint();
is->setRestorePoint();
serverKeyLength = is->readU32();
if (serverKeyLength < MinKeyLength)
- throw Exception("server key is too short");
+ throw ProtocolException("server key is too short");
if (serverKeyLength > MaxKeyLength)
- throw Exception("server key is too long");
+ throw ProtocolException("server key is too long");
size_t size = (serverKeyLength + 7) / 8;
if (!is->hasDataOrRestore(size * 2))
return false;
nettle_mpz_set_str_256_u(serverKey.n, size, serverKeyN);
nettle_mpz_set_str_256_u(serverKey.e, size, serverKeyE);
if (!rsa_public_key_prepare(&serverKey))
- throw Exception("server key is invalid");
+ throw ProtocolException("server key is invalid");
return true;
}
is->setRestorePoint();
size_t size = is->readU16();
if (size != clientKey.size)
- throw Exception("client key length doesn't match");
+ throw ProtocolException("client key length doesn't match");
if (!is->hasDataOrRestore(size))
return false;
is->clearRestorePoint();
if (!rsa_decrypt(&clientKey, &randomSize, serverRandom, x) ||
randomSize != (size_t)keySize / 8) {
mpz_clear(x);
- throw Exception("failed to decrypt server random");
+ throw ProtocolException("failed to decrypt server random");
}
mpz_clear(x);
return true;
sha256_digest(&ctx, hashSize, realHash);
}
if (memcmp(hash, realHash, hashSize) != 0)
- throw Exception("hash doesn't match");
+ throw ProtocolException("hash doesn't match");
return true;
}
return false;
subtype = rais->readU8();
if (subtype != secTypeRA2UserPass && subtype != secTypeRA2Pass)
- throw Exception("unknown RSA-AES subtype");
+ throw ProtocolException("unknown RSA-AES subtype");
return true;
}
return false;
if (is->readU8() == 0)
- throw Exception("Server failed to initialize TLS session");
+ throw ProtocolException("Server failed to initialize TLS session");
ret = gnutls_init(&session, GNUTLS_CLIENT);
if (ret != GNUTLS_E_SUCCESS)
return;
if (gnutls_certificate_type_get(session) != GNUTLS_CRT_X509)
- throw Exception("unsupported certificate type");
+ throw ProtocolException("unsupported certificate type");
err = gnutls_certificate_verify_peers2(session, &status);
if (err != 0) {
gnutls_free(status_str.data);
- throw Exception(format("Invalid server certificate: %s",
- error.c_str()));
+ throw ProtocolException(format("Invalid server certificate: %s",
+ error.c_str()));
}
err = gnutls_certificate_verification_status_print(status,
cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
if (!cert_list_size)
- throw Exception("empty certificate chain");
+ throw ProtocolException("empty certificate chain");
/* Process only server's certificate, not issuer's certificate */
gnutls_x509_crt_t crt;
os->writeU8(0);
os->writeU8(0);
os->flush();
- throw Exception("The server reported an unsupported VeNCrypt version");
+ throw ProtocolException("The server reported an unsupported VeNCrypt version");
}
haveSentVersion = true;
return false;
if (is->readU8())
- throw Exception("The server reported it could not support the "
- "VeNCrypt version");
+ throw ProtocolException("The server reported it could not "
+ "support the VeNCrypt version");
haveAgreedVersion = true;
}
nAvailableTypes = is->readU8();
if (!nAvailableTypes)
- throw Exception("The server reported no VeNCrypt sub-types");
+ throw ProtocolException("The server reported no VeNCrypt sub-types");
availableTypes = new uint32_t[nAvailableTypes];
haveNumberOfTypes = true;
/* Set up the stack according to the chosen type: */
if (chosenType == secTypeInvalid || chosenType == secTypeVeNCrypt)
- throw Exception("No valid VeNCrypt sub-type");
+ throw ProtocolException("No valid VeNCrypt sub-type");
vlog.info("Choosing security type %s (%d)", secTypeName(chosenType),
chosenType);
* happen, since if the server supports 0 sub-types, it doesn't support
* this security type
*/
- throw Exception("The server reported 0 VeNCrypt sub-types");
+ throw ProtocolException("The server reported 0 VeNCrypt sub-types");
}
return csecurity->processMsg();
if (!Decoder::supported(encoding)) {
vlog.error("Unknown encoding %d", encoding);
- throw rdr::Exception("Unknown encoding");
+ throw ProtocolException("Unknown encoding");
}
if (!decoders[encoding]) {
decoders[encoding] = Decoder::createDecoder(encoding);
if (!decoders[encoding]) {
vlog.error("Unknown encoding %d", encoding);
- throw rdr::Exception("Unknown encoding");
+ throw ProtocolException("Unknown encoding");
}
}
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2014-2024 Pierre Ossman for Cendio AB
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
namespace rfb {
typedef rdr::Exception Exception;
+
+ class ProtocolException : public Exception {
+ public:
+ ProtocolException(const char* what_arg) : Exception(what_arg) {}
+ ProtocolException(const std::string& what_arg) : Exception(what_arg) {}
+ };
+
struct AuthFailureException : public Exception {
AuthFailureException(const char* reason)
: Exception(reason) {}
int w = ((wh >> 4) & 15) + 1;
int h = (wh & 15) + 1;
if (x + w > 16 || y + h > 16) {
- throw rfb::Exception("HEXTILE_DECODE: Hextile out of bounds");
+ throw ProtocolException("HEXTILE_DECODE: Hextile out of bounds");
}
ptr = buf + y * t.width() + x;
int rowAdd = t.width() - w;
#endif
#include <rfb/JpegDecompressor.h>
-#include <rdr/Exception.h>
+#include <rfb/Exception.h>
#include <rfb/Rect.h>
#include <rfb/PixelFormat.h>
jpeg_abort_decompress(dinfo);
if (dstBufIsTemp && dstBuf) delete[] dstBuf;
if (rowPointer) delete[] rowPointer;
- throw rdr::Exception("Tight Decoding: Wrong JPEG data received.\n");
+ throw ProtocolException("Tight Decoding: Wrong JPEG data received.\n");
}
while (dinfo->output_scanline < dinfo->output_height) {
}
if (!isSane())
- throw Exception("invalid pixel format");
+ throw ProtocolException("invalid pixel format");
updateState();
}
int h = is->readU16();
if (((x+w) > r.width()) || ((y+h) > r.height()))
- throw Exception ("RRE decode error");
+ throw ProtocolException("RRE decode error");
pb->fillRect(pf, Rect(r.tl.x+x, r.tl.y+y, r.tl.x+x+w, r.tl.y+y+h), &pix);
}
if (sscanf(verStr, "RFB %03d.%03d\n",
&majorVersion, &minorVersion) != 2) {
state_ = RFBSTATE_INVALID;
- throw Exception("reading version failed: not an RFB client?");
+ throw ProtocolException("reading version failed: not an RFB client?");
}
client.setVersion(majorVersion, minorVersion);
secTypes = security.GetEnabledSecTypes();
if (std::find(secTypes.begin(), secTypes.end(),
secType) == secTypes.end())
- throw Exception("Requested security type not available");
+ throw ProtocolException("Requested security type not available");
vlog.info("Client requests security type %s(%d)",
secTypeName(secType),secType);
}
state_ = RFBSTATE_INVALID;
- throw Exception(message);
+ throw ProtocolException(message);
}
void SConnection::failConnection(const std::string& message)
break;
default:
vlog.error("unknown message type %d", currentMsgType);
- throw Exception("unknown message type");
+ throw ProtocolException("unknown message type");
}
if (ret)
return false;
if (len < 4)
- throw Exception("Invalid extended clipboard message");
+ throw ProtocolException("Invalid extended clipboard message");
if (len > maxCutText) {
vlog.error("Extended clipboard message too long (%d bytes) - ignoring", len);
is->skip(len);
}
if (len < (int32_t)(4 + 4*num))
- throw Exception("Invalid extended clipboard message");
+ throw ProtocolException("Invalid extended clipboard message");
num = 0;
for (i = 0;i < 16;i++) {
continue;
if (!zis.hasData(4))
- throw Exception("Extended clipboard decode error");
+ throw ProtocolException("Extended clipboard decode error");
lengths[num] = zis.readU32();
size_t chunk;
if (!zis.hasData(1))
- throw Exception("Extended clipboard decode error");
+ throw ProtocolException("Extended clipboard decode error");
chunk = zis.avail();
if (chunk > lengths[num])
}
if (!zis.hasData(lengths[num]))
- throw Exception("Extended clipboard decode error");
+ throw ProtocolException("Extended clipboard decode error");
buffers[num] = new uint8_t[lengths[num]];
zis.readBytes(buffers[num], lengths[num]);
handler->handleClipboardNotify(flags);
break;
default:
- throw Exception("Invalid extended clipboard action");
+ throw ProtocolException("Invalid extended clipboard action");
}
}
ret = readQEMUKeyEvent();
break;
default:
- throw Exception(format("unknown QEMU submessage type %d", subType));
+ throw ProtocolException(format("unknown QEMU submessage type %d", subType));
}
if (!ret) {
#include <nettle/sha2.h>
#include <nettle/base64.h>
#include <nettle/asn1.h>
+
#include <rfb/SSecurityRSAAES.h>
#include <rfb/SConnection.h>
#include <rfb/LogWriter.h>
is->setRestorePoint();
clientKeyLength = is->readU32();
if (clientKeyLength < MinKeyLength)
- throw Exception("client key is too short");
+ throw ProtocolException("client key is too short");
if (clientKeyLength > MaxKeyLength)
- throw Exception("client key is too long");
+ throw ProtocolException("client key is too long");
size_t size = (clientKeyLength + 7) / 8;
if (!is->hasDataOrRestore(size * 2))
return false;
nettle_mpz_set_str_256_u(clientKey.n, size, clientKeyN);
nettle_mpz_set_str_256_u(clientKey.e, size, clientKeyE);
if (!rsa_public_key_prepare(&clientKey))
- throw Exception("client key is invalid");
+ throw ProtocolException("client key is invalid");
return true;
}
is->setRestorePoint();
size_t size = is->readU16();
if (size != serverKey.size)
- throw Exception("server key length doesn't match");
+ throw ProtocolException("server key length doesn't match");
if (!is->hasDataOrRestore(size))
return false;
is->clearRestorePoint();
if (!rsa_decrypt(&serverKey, &randomSize, clientRandom, x) ||
randomSize != (size_t)keySize / 8) {
mpz_clear(x);
- throw Exception("failed to decrypt client random");
+ throw ProtocolException("failed to decrypt client random");
}
mpz_clear(x);
return true;
sha256_digest(&ctx, hashSize, realHash);
}
if (memcmp(hash, realHash, hashSize) != 0)
- throw Exception("hash doesn't match");
+ throw ProtocolException("hash doesn't match");
return true;
}
case 0x0001: /* 0.1 Legacy VeNCrypt, not supported */
os->writeU8(0xFF); /* This is not OK */
os->flush();
- throw Exception("The client cannot support the server's "
- "VeNCrypt version");
+ throw ProtocolException("The client cannot support the server's "
+ "VeNCrypt version");
case 0x0002: /* 0.2 */
os->writeU8(0); /* OK */
default:
os->writeU8(0xFF); /* Not OK */
os->flush();
- throw Exception("The client returned an unsupported VeNCrypt version");
+ throw ProtocolException("The client returned an unsupported VeNCrypt version");
}
}
os->flush();
haveSentTypes = true;
} else
- throw Exception("There are no VeNCrypt sub-types to send to the client");
+ throw ProtocolException("There are no VeNCrypt sub-types to send to the client");
}
/* get type back from client (must be one of the ones we sent) */
/* Set up the stack according to the chosen type */
if (chosenType == secTypeInvalid || chosenType == secTypeVeNCrypt)
- throw Exception("No valid VeNCrypt sub-type");
+ throw ProtocolException("No valid VeNCrypt sub-type");
ssecurity = security->GetSSecurity(sc, chosenType);
}
// Quit on unsupported compression type.
if (comp_ctl > tightMaxSubencoding)
- throw Exception("TightDecoder: bad subencoding value received");
+ throw ProtocolException("TightDecoder: bad subencoding value received");
// "Basic" compression type.
int palSize = 0;
if (r.width() > TIGHT_MAX_WIDTH)
- throw Exception(format("TightDecoder: too large rectangle (%d pixels)", r.width()));
+ throw ProtocolException(format("TightDecoder: too large rectangle (%d pixels)", r.width()));
// Possible palette
if ((comp_ctl & tightExplicitFilter) != 0) {
break;
case tightFilterGradient:
if (server.pf().bpp == 8)
- throw Exception("TightDecoder: invalid BPP for gradient filter");
+ throw ProtocolException("TightDecoder: invalid BPP for gradient filter");
break;
case tightFilterCopy:
break;
default:
- throw Exception("TightDecoder: unknown filter code received");
+ throw ProtocolException("TightDecoder: unknown filter code received");
}
}
netbuf = new uint8_t[dataSize];
if (!zis[streamId].hasData(dataSize))
- throw Exception("Tight decode error");
+ throw ProtocolException("Tight decode error");
zis[streamId].readBytes(netbuf, dataSize);
zis[streamId].flushUnderlying();
Rect rect;
if (!client.supportsFence() || !client.supportsContinuousUpdates())
- throw Exception("Client tried to enable continuous updates when not allowed");
+ throw ProtocolException("Client tried to enable continuous updates when not allowed");
continuousUpdates = enable;
static inline void zlibHasData(rdr::ZlibInStream* zis, size_t length)
{
if (!zis->hasData(length))
- throw Exception("ZRLE decode error");
+ throw ProtocolException("ZRLE decode error");
}
ZRLEDecoder::ZRLEDecoder() : Decoder(DecoderOrdered)
} while (b == 255);
if (end - ptr < len) {
- throw Exception ("ZRLE decode error");
+ throw ProtocolException("ZRLE decode error");
}
while (len-- > 0) *ptr++ = pix;
} while (b == 255);
if (end - ptr < len) {
- throw Exception ("ZRLE decode error");
+ throw ProtocolException("ZRLE decode error");
}
}