aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2023-01-13 12:47:48 +0100
committerPierre Ossman <ossman@cendio.se>2023-02-04 14:03:13 +0100
commitb99daadb05e14e85da6c5e905057e10fc27c0fcf (patch)
tree752e6fea3900b604d44ef6a498539e9a785bf22f /common
parente6c5b29f12780303299506fe04f089bc98b80c91 (diff)
downloadtigervnc-b99daadb05e14e85da6c5e905057e10fc27c0fcf.tar.gz
tigervnc-b99daadb05e14e85da6c5e905057e10fc27c0fcf.zip
Use std::string instead of CharArray
Let's use a more common type instead of something homegrown. Should be more familiar to new developers.
Diffstat (limited to 'common')
-rw-r--r--common/network/TcpSocket.cxx1
-rw-r--r--common/rfb/CConnection.cxx4
-rw-r--r--common/rfb/CConnection.h5
-rw-r--r--common/rfb/CMakeLists.txt2
-rw-r--r--common/rfb/CSecurityRSAAES.cxx5
-rw-r--r--common/rfb/CSecurityTLS.cxx93
-rw-r--r--common/rfb/Configuration.cxx2
-rw-r--r--common/rfb/Configuration.h12
-rw-r--r--common/rfb/Congestion.cxx1
-rw-r--r--common/rfb/KeyRemapper.cxx1
-rw-r--r--common/rfb/SConnection.cxx9
-rw-r--r--common/rfb/SConnection.h2
-rw-r--r--common/rfb/SSecurityRSAAES.cxx8
-rw-r--r--common/rfb/SSecurityVncAuth.cxx48
-rw-r--r--common/rfb/SSecurityVncAuth.h7
-rw-r--r--common/rfb/VNCSConnectionST.cxx13
-rw-r--r--common/rfb/VNCSConnectionST.h6
-rw-r--r--common/rfb/VNCServerST.cxx12
-rw-r--r--common/rfb/VNCServerST.h4
-rw-r--r--common/rfb/obfuscate.cxx (renamed from common/rfb/Password.cxx)64
-rw-r--r--common/rfb/obfuscate.h (renamed from common/rfb/Password.h)32
-rw-r--r--common/rfb/util.cxx29
-rw-r--r--common/rfb/util.h6
23 files changed, 196 insertions, 170 deletions
diff --git a/common/network/TcpSocket.cxx b/common/network/TcpSocket.cxx
index 4feab0ae..87f2e757 100644
--- a/common/network/TcpSocket.cxx
+++ b/common/network/TcpSocket.cxx
@@ -41,6 +41,7 @@
#include <network/TcpSocket.h>
#include <rfb/LogWriter.h>
#include <rfb/Configuration.h>
+#include <rfb/util.h>
#ifdef WIN32
#include <os/winerrno.h>
diff --git a/common/rfb/CConnection.cxx b/common/rfb/CConnection.cxx
index 8e545b2f..79adec5c 100644
--- a/common/rfb/CConnection.cxx
+++ b/common/rfb/CConnection.cxx
@@ -52,7 +52,7 @@ CConnection::CConnection()
supportsDesktopResize(false), supportsLEDState(false),
is(0), os(0), reader_(0), writer_(0),
shared(false),
- state_(RFBSTATE_UNINITIALISED), serverName(strDup("")),
+ state_(RFBSTATE_UNINITIALISED),
pendingPFChange(false), preferredEncoding(encodingTight),
compressLevel(2), qualityLevel(-1),
formatChange(false), encodingChange(false),
@@ -72,7 +72,7 @@ void CConnection::setServerName(const char* name_)
{
if (name_ == NULL)
name_ = "";
- serverName.replaceBuf(strDup(name_));
+ serverName = name_;
}
void CConnection::setStreams(rdr::InStream* is_, rdr::OutStream* os_)
diff --git a/common/rfb/CConnection.h b/common/rfb/CConnection.h
index 7e5c611e..0cf47962 100644
--- a/common/rfb/CConnection.h
+++ b/common/rfb/CConnection.h
@@ -27,7 +27,6 @@
#include <rfb/CMsgHandler.h>
#include <rfb/DecodeManager.h>
#include <rfb/SecurityClient.h>
-#include <rfb/util.h>
namespace rfb {
@@ -206,7 +205,7 @@ namespace rfb {
// Access method used by SSecurity implementations that can verify servers'
// Identities, to determine the unique(ish) name of the server.
- const char* getServerName() const { return serverName.buf; }
+ const char* getServerName() const { return serverName.c_str(); }
bool isSecure() const { return csecurity ? csecurity->isSecure() : false; }
@@ -271,7 +270,7 @@ namespace rfb {
bool shared;
stateEnum state_;
- CharArray serverName;
+ std::string serverName;
bool pendingPFChange;
rfb::PixelFormat pendingPF;
diff --git a/common/rfb/CMakeLists.txt b/common/rfb/CMakeLists.txt
index e18cff34..85cdc2db 100644
--- a/common/rfb/CMakeLists.txt
+++ b/common/rfb/CMakeLists.txt
@@ -32,7 +32,6 @@ add_library(rfb STATIC
Logger.cxx
Logger_file.cxx
Logger_stdio.cxx
- Password.cxx
PixelBuffer.cxx
PixelFormat.cxx
RREEncoder.cxx
@@ -64,6 +63,7 @@ add_library(rfb STATIC
ZRLEEncoder.cxx
ZRLEDecoder.cxx
encodings.cxx
+ obfuscate.cxx
util.cxx)
target_link_libraries(rfb os rdr)
diff --git a/common/rfb/CSecurityRSAAES.cxx b/common/rfb/CSecurityRSAAES.cxx
index f48e2523..24d1a9fe 100644
--- a/common/rfb/CSecurityRSAAES.cxx
+++ b/common/rfb/CSecurityRSAAES.cxx
@@ -208,13 +208,12 @@ void CSecurityRSAAES::verifyServer()
sha1_update(&ctx, serverKey.size, serverKeyE);
sha1_digest(&ctx, sizeof(f), f);
const char *title = "Server key fingerprint";
- CharArray text;
- text.format(
+ std::string text = strFormat(
"The server has provided the following identifying information:\n"
"Fingerprint: %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x\n"
"Please verify that the information is correct and press \"Yes\". "
"Otherwise press \"No\"", f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]);
- if (!msg->showMsgBox(UserMsgBox::M_YESNO, title, text.buf))
+ if (!msg->showMsgBox(UserMsgBox::M_YESNO, title, text.c_str()))
throw AuthFailureException("server key mismatch");
}
diff --git a/common/rfb/CSecurityTLS.cxx b/common/rfb/CSecurityTLS.cxx
index c702280d..92a89193 100644
--- a/common/rfb/CSecurityTLS.cxx
+++ b/common/rfb/CSecurityTLS.cxx
@@ -354,12 +354,14 @@ void CSecurityTLS::checkSession()
throw AuthFailureException("decoding of certificate failed");
if (gnutls_x509_crt_check_hostname(crt, client->getServerName()) == 0) {
- CharArray text;
+ std::string text;
vlog.debug("hostname mismatch");
- text.format("Hostname (%s) does not match the server certificate, "
- "do you want to continue?", client->getServerName());
+ text = strFormat("Hostname (%s) does not match the server "
+ "certificate, do you want to continue?",
+ client->getServerName());
if (!msg->showMsgBox(UserMsgBox::M_YESNO,
- "Certificate hostname mismatch", text.buf))
+ "Certificate hostname mismatch",
+ text.c_str()))
throw AuthFailureException("Certificate hostname mismatch");
}
@@ -395,10 +397,10 @@ void CSecurityTLS::checkSession()
"path for known hosts storage");
}
- CharArray dbPath(strlen(homeDir) + strlen("/x509_known_hosts") + 1);
- sprintf(dbPath.buf, "%s/x509_known_hosts", homeDir);
+ std::string dbPath;
+ dbPath = (std::string)homeDir + "/x509_known_hosts";
- err = gnutls_verify_stored_pubkey(dbPath.buf, NULL,
+ err = gnutls_verify_stored_pubkey(dbPath.c_str(), NULL,
client->getServerName(), NULL,
GNUTLS_CRT_X509, &cert_list[0], 0);
@@ -425,73 +427,94 @@ void CSecurityTLS::checkSession()
/* New host */
if (err == GNUTLS_E_NO_CERTIFICATE_FOUND) {
- CharArray text;
+ std::string text;
vlog.debug("Server host not previously known");
vlog.debug("%s", info.data);
if (status & (GNUTLS_CERT_SIGNER_NOT_FOUND |
GNUTLS_CERT_SIGNER_NOT_CA)) {
- text.format("This certificate has been signed by an unknown "
- "authority:\n\n%s\n\nSomeone could be trying to "
- "impersonate the site and you should not "
- "continue.\n\nDo you want to make an exception "
- "for this server?", info.data);
+ text = strFormat("This certificate has been signed by an "
+ "unknown authority:\n"
+ "\n"
+ "%s\n"
+ "\n"
+ "Someone could be trying to impersonate the "
+ "site and you should not continue.\n"
+ "\n"
+ "Do you want to make an exception for this "
+ "server?", info.data);
if (!msg->showMsgBox(UserMsgBox::M_YESNO,
"Unknown certificate issuer",
- text.buf))
+ text.c_str()))
throw AuthFailureException("Unknown certificate issuer");
}
if (status & GNUTLS_CERT_EXPIRED) {
- text.format("This certificate has expired:\n\n%s\n\nSomeone "
- "could be trying to impersonate the site and you "
- "should not continue.\n\nDo you want to make an "
- "exception for this server?", info.data);
+ text = strFormat("This certificate has expired:\n"
+ "\n"
+ "%s\n"
+ "\n"
+ "Someone could be trying to impersonate the "
+ "site and you should not continue.\n"
+ "\n"
+ "Do you want to make an exception for this "
+ "server?", info.data);
if (!msg->showMsgBox(UserMsgBox::M_YESNO,
"Expired certificate",
- text.buf))
+ text.c_str()))
throw AuthFailureException("Expired certificate");
}
} else if (err == GNUTLS_E_CERTIFICATE_KEY_MISMATCH) {
- CharArray text;
+ std::string text;
vlog.debug("Server host key mismatch");
vlog.debug("%s", info.data);
if (status & (GNUTLS_CERT_SIGNER_NOT_FOUND |
GNUTLS_CERT_SIGNER_NOT_CA)) {
- text.format("This host is previously known with a different "
- "certificate, and the new certificate has been "
- "signed by an unknown authority:\n\n%s\n\nSomeone "
- "could be trying to impersonate the site and you "
- "should not continue.\n\nDo you want to make an "
- "exception for this server?", info.data);
+ text = strFormat("This host is previously known with a "
+ "different certificate, and the new "
+ "certificate has been signed by an "
+ "unknown authority:\n"
+ "\n"
+ "%s\n"
+ "\n"
+ "Someone could be trying to impersonate the "
+ "site and you should not continue.\n"
+ "\n"
+ "Do you want to make an exception for this "
+ "server?", info.data);
if (!msg->showMsgBox(UserMsgBox::M_YESNO,
"Unexpected server certificate",
- text.buf))
+ text.c_str()))
throw AuthFailureException("Unexpected server certificate");
}
if (status & GNUTLS_CERT_EXPIRED) {
- text.format("This host is previously known with a different "
- "certificate, and the new certificate has expired:"
- "\n\n%s\n\nSomeone could be trying to impersonate "
- "the site and you should not continue.\n\nDo you "
- "want to make an exception for this server?",
- info.data);
+ text = strFormat("This host is previously known with a "
+ "different certificate, and the new "
+ "certificate has expired:\n"
+ "\n"
+ "%s\n"
+ "\n"
+ "Someone could be trying to impersonate the "
+ "site and you should not continue.\n"
+ "\n"
+ "Do you want to make an exception for this "
+ "server?", info.data);
if (!msg->showMsgBox(UserMsgBox::M_YESNO,
"Unexpected server certificate",
- text.buf))
+ text.c_str()))
throw AuthFailureException("Unexpected server certificate");
}
}
- if (gnutls_store_pubkey(dbPath.buf, NULL, client->getServerName(),
+ if (gnutls_store_pubkey(dbPath.c_str(), NULL, client->getServerName(),
NULL, GNUTLS_CRT_X509, &cert_list[0], 0, 0))
vlog.error("Failed to store server certificate to known hosts database");
diff --git a/common/rfb/Configuration.cxx b/common/rfb/Configuration.cxx
index 9cbfa53d..0fc2bde6 100644
--- a/common/rfb/Configuration.cxx
+++ b/common/rfb/Configuration.cxx
@@ -133,7 +133,7 @@ VoidParameter* Configuration::get(const char* param)
void Configuration::list(int width, int nameWidth) {
VoidParameter* current = head;
- fprintf(stderr, "%s Parameters:\n", name.buf);
+ fprintf(stderr, "%s Parameters:\n", name.c_str());
while (current) {
std::string def_str = current->getDefaultStr();
const char* desc = current->getDescription();
diff --git a/common/rfb/Configuration.h b/common/rfb/Configuration.h
index 20552364..eef89d93 100644
--- a/common/rfb/Configuration.h
+++ b/common/rfb/Configuration.h
@@ -44,9 +44,11 @@
#ifndef __RFB_CONFIGURATION_H__
#define __RFB_CONFIGURATION_H__
-#include <vector>
+#include <limits.h>
+#include <stdint.h>
-#include <rfb/util.h>
+#include <string>
+#include <vector>
namespace os { class Mutex; }
@@ -62,10 +64,10 @@ namespace rfb {
class Configuration {
public:
// - Create a new Configuration object
- Configuration(const char* name_) : name(strDup(name_)), head(0), _next(0) {}
+ Configuration(const char* name_) : name(name_), head(0), _next(0) {}
// - Return the buffer containing the Configuration's name
- const char* getName() const { return name.buf; }
+ const char* getName() const { return name.c_str(); }
// - Set named parameter to value
bool set(const char* param, const char* value, bool immutable=false);
@@ -131,7 +133,7 @@ namespace rfb {
friend struct ParameterIterator;
// Name for this Configuration
- CharArray name;
+ std::string name;
// - Pointer to first Parameter in this group
VoidParameter* head;
diff --git a/common/rfb/Congestion.cxx b/common/rfb/Congestion.cxx
index f642752e..1e252165 100644
--- a/common/rfb/Congestion.cxx
+++ b/common/rfb/Congestion.cxx
@@ -38,6 +38,7 @@
#endif
#include <assert.h>
+#include <string.h>
#include <sys/time.h>
#ifdef __linux__
diff --git a/common/rfb/KeyRemapper.cxx b/common/rfb/KeyRemapper.cxx
index 700ae298..731eb256 100644
--- a/common/rfb/KeyRemapper.cxx
+++ b/common/rfb/KeyRemapper.cxx
@@ -21,6 +21,7 @@
#endif
#include <stdio.h>
+#include <string.h>
#include <os/Mutex.h>
diff --git a/common/rfb/SConnection.cxx b/common/rfb/SConnection.cxx
index 211fbd98..244fb324 100644
--- a/common/rfb/SConnection.cxx
+++ b/common/rfb/SConnection.cxx
@@ -247,7 +247,7 @@ bool SConnection::processSecurityMsg()
state_ = RFBSTATE_SECURITY_FAILURE;
// Introduce a slight delay of the authentication failure response
// to make it difficult to brute force a password
- authFailureMsg.replaceBuf(strDup(e.str()));
+ authFailureMsg = e.str();
authFailureTimer.start(100);
return true;
}
@@ -296,9 +296,8 @@ bool SConnection::handleAuthFailureTimeout(Timer* /*t*/)
try {
os->writeU32(secResultFailed);
if (!client.beforeVersion(3,8)) { // 3.8 onwards have failure message
- const char* reason = authFailureMsg.buf;
- os->writeU32(strlen(reason));
- os->writeBytes(reason, strlen(reason));
+ os->writeU32(authFailureMsg.size());
+ os->writeBytes(authFailureMsg.data(), authFailureMsg.size());
}
os->flush();
} catch (rdr::Exception& e) {
@@ -306,7 +305,7 @@ bool SConnection::handleAuthFailureTimeout(Timer* /*t*/)
return false;
}
- close(authFailureMsg.buf);
+ close(authFailureMsg.c_str());
return false;
}
diff --git a/common/rfb/SConnection.h b/common/rfb/SConnection.h
index 113811b9..54acdd9c 100644
--- a/common/rfb/SConnection.h
+++ b/common/rfb/SConnection.h
@@ -257,7 +257,7 @@ namespace rfb {
SSecurity* ssecurity;
MethodTimer<SConnection> authFailureTimer;
- CharArray authFailureMsg;
+ std::string authFailureMsg;
stateEnum state_;
int32_t preferredEncoding;
diff --git a/common/rfb/SSecurityRSAAES.cxx b/common/rfb/SSecurityRSAAES.cxx
index 4cca7d6d..042e4838 100644
--- a/common/rfb/SSecurityRSAAES.cxx
+++ b/common/rfb/SSecurityRSAAES.cxx
@@ -571,18 +571,18 @@ void SSecurityRSAAES::verifyUserPass()
void SSecurityRSAAES::verifyPass()
{
VncAuthPasswdGetter* pg = &SSecurityVncAuth::vncAuthPasswd;
- PlainPasswd passwd, passwdReadOnly;
+ std::string passwd, passwdReadOnly;
pg->getVncAuthPasswd(&passwd, &passwdReadOnly);
- if (!passwd.buf)
+ if (passwd.empty())
throw AuthFailureException("No password configured for VNC Auth");
- if (strcmp(password, passwd.buf) == 0) {
+ if (password == passwd) {
accessRights = SConnection::AccessDefault;
return;
}
- if (passwdReadOnly.buf && strcmp(password, passwdReadOnly.buf) == 0) {
+ if (!passwdReadOnly.empty() && password == passwdReadOnly) {
accessRights = SConnection::AccessView;
return;
}
diff --git a/common/rfb/SSecurityVncAuth.cxx b/common/rfb/SSecurityVncAuth.cxx
index bb644cf2..cbd0ccd2 100644
--- a/common/rfb/SSecurityVncAuth.cxx
+++ b/common/rfb/SSecurityVncAuth.cxx
@@ -28,10 +28,11 @@
#include <rfb/SSecurityVncAuth.h>
#include <rdr/RandomStream.h>
#include <rfb/SConnection.h>
-#include <rfb/Password.h>
#include <rfb/Configuration.h>
#include <rfb/LogWriter.h>
#include <rfb/Exception.h>
+#include <rfb/obfuscate.h>
+#include <assert.h>
#include <string.h>
#include <stdio.h>
extern "C" {
@@ -57,15 +58,15 @@ SSecurityVncAuth::SSecurityVncAuth(SConnection* sc)
{
}
-bool SSecurityVncAuth::verifyResponse(const PlainPasswd &password)
+bool SSecurityVncAuth::verifyResponse(const char* password)
{
uint8_t expectedResponse[vncAuthChallengeSize];
// Calculate the expected response
uint8_t key[8];
- int pwdLen = strlen(password.buf);
+ int pwdLen = strlen(password);
for (int i=0; i<8; i++)
- key[i] = i<pwdLen ? password.buf[i] : 0;
+ key[i] = i<pwdLen ? password[i] : 0;
deskey(key, EN0);
for (int j = 0; j < vncAuthChallengeSize; j += 8)
des(challenge+j, expectedResponse+j);
@@ -95,18 +96,19 @@ bool SSecurityVncAuth::processMsg()
is->readBytes(response, vncAuthChallengeSize);
- PlainPasswd passwd, passwdReadOnly;
+ std::string passwd, passwdReadOnly;
pg->getVncAuthPasswd(&passwd, &passwdReadOnly);
- if (!passwd.buf)
+ if (passwd.empty())
throw AuthFailureException("No password configured for VNC Auth");
- if (verifyResponse(passwd)) {
+ if (verifyResponse(passwd.c_str())) {
accessRights = SConnection::AccessDefault;
return true;
}
- if (passwdReadOnly.buf && verifyResponse(passwdReadOnly)) {
+ if (!passwdReadOnly.empty() &&
+ verifyResponse(passwdReadOnly.c_str())) {
accessRights = SConnection::AccessView;
return true;
}
@@ -120,16 +122,11 @@ VncAuthPasswdParameter::VncAuthPasswdParameter(const char* name,
: BinaryParameter(name, desc, 0, 0, ConfServer), passwdFile(passwdFile_) {
}
-void VncAuthPasswdParameter::getVncAuthPasswd(PlainPasswd *password, PlainPasswd *readOnlyPassword) {
- ObfuscatedPasswd obfuscated, obfuscatedReadOnly;
- std::vector<uint8_t> data = getData();
- obfuscated.length = data.size();
- if (!data.empty()) {
- obfuscated.buf = new char[data.size()];
- memcpy(obfuscated.buf, data.data(), data.size());
- }
+void VncAuthPasswdParameter::getVncAuthPasswd(std::string *password, std::string *readOnlyPassword) {
+ std::vector<uint8_t> obfuscated, obfuscatedReadOnly;
+ obfuscated = getData();
- if (obfuscated.length == 0) {
+ if (obfuscated.size() == 0) {
if (passwdFile) {
const char *fname = *passwdFile;
if (!fname[0]) {
@@ -144,21 +141,22 @@ void VncAuthPasswdParameter::getVncAuthPasswd(PlainPasswd *password, PlainPasswd
}
vlog.debug("reading password file");
- obfuscated.buf = new char[8];
- obfuscated.length = fread(obfuscated.buf, 1, 8, fp);
- obfuscatedReadOnly.buf = new char[8];
- obfuscatedReadOnly.length = fread(obfuscatedReadOnly.buf, 1, 8, fp);
+ obfuscated.resize(8);
+ obfuscated.resize(fread(obfuscated.data(), 1, 8, fp));
+ obfuscatedReadOnly.resize(8);
+ obfuscatedReadOnly.resize(fread(obfuscatedReadOnly.data(), 1, 8, fp));
fclose(fp);
} else {
vlog.info("%s parameter not set", getName());
}
}
+ assert(password != NULL);
+ assert(readOnlyPassword != NULL);
+
try {
- PlainPasswd plainPassword(obfuscated);
- password->replaceBuf(plainPassword.takeBuf());
- PlainPasswd plainPasswordReadOnly(obfuscatedReadOnly);
- readOnlyPassword->replaceBuf(plainPasswordReadOnly.takeBuf());
+ *password = deobfuscate(obfuscated.data(), obfuscated.size());
+ *readOnlyPassword = deobfuscate(obfuscatedReadOnly.data(), obfuscatedReadOnly.size());
} catch (...) {
}
}
diff --git a/common/rfb/SSecurityVncAuth.h b/common/rfb/SSecurityVncAuth.h
index c6c329c4..2bd27791 100644
--- a/common/rfb/SSecurityVncAuth.h
+++ b/common/rfb/SSecurityVncAuth.h
@@ -27,7 +27,6 @@
#include <stdint.h>
#include <rfb/Configuration.h>
-#include <rfb/Password.h>
#include <rfb/SSecurity.h>
#include <rfb/Security.h>
@@ -37,7 +36,7 @@ namespace rfb {
public:
// getVncAuthPasswd() fills buffer of given password and readOnlyPassword.
// If there was no read only password in the file, readOnlyPassword buffer is null.
- virtual void getVncAuthPasswd(PlainPasswd *password, PlainPasswd *readOnlyPassword)=0;
+ virtual void getVncAuthPasswd(std::string *password, std::string *readOnlyPassword)=0;
virtual ~VncAuthPasswdGetter() { }
};
@@ -45,7 +44,7 @@ namespace rfb {
class VncAuthPasswdParameter : public VncAuthPasswdGetter, BinaryParameter {
public:
VncAuthPasswdParameter(const char* name, const char* desc, StringParameter* passwdFile_);
- virtual void getVncAuthPasswd(PlainPasswd *password, PlainPasswd *readOnlyPassword);
+ virtual void getVncAuthPasswd(std::string *password, std::string *readOnlyPassword);
protected:
StringParameter* passwdFile;
};
@@ -60,7 +59,7 @@ namespace rfb {
static StringParameter vncAuthPasswdFile;
static VncAuthPasswdParameter vncAuthPasswd;
private:
- bool verifyResponse(const PlainPasswd &password);
+ bool verifyResponse(const char* password);
enum {vncAuthChallengeSize = 16};
uint8_t challenge[vncAuthChallengeSize];
uint8_t response[vncAuthChallengeSize];
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index f27264c3..1d890c28 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -59,7 +59,7 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
pointerEventTime(0), clientHasCursor(false)
{
setStreams(&sock->inStream(), &sock->outStream());
- peerEndpoint.buf = strDup(sock->getPeerEndpoint());
+ peerEndpoint = sock->getPeerEndpoint();
// Kick off the idle timer
if (rfb::Server::idleTimeout) {
@@ -75,8 +75,9 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
VNCSConnectionST::~VNCSConnectionST()
{
// If we reach here then VNCServerST is deleting us!
- if (closeReason.buf)
- vlog.info("closing %s: %s", peerEndpoint.buf, closeReason.buf);
+ if (!closeReason.empty())
+ vlog.info("closing %s: %s", peerEndpoint.c_str(),
+ closeReason.c_str());
// Release any keys the client still had pressed
while (!pressedKeys.empty()) {
@@ -112,10 +113,10 @@ void VNCSConnectionST::close(const char* reason)
SConnection::close(reason);
// Log the reason for the close
- if (!closeReason.buf)
- closeReason.buf = strDup(reason);
+ if (closeReason.empty())
+ closeReason = reason;
else
- vlog.debug("second close: %s (%s)", peerEndpoint.buf, reason);
+ vlog.debug("second close: %s (%s)", peerEndpoint.c_str(), reason);
try {
if (sock->outStream().hasBufferedData()) {
diff --git a/common/rfb/VNCSConnectionST.h b/common/rfb/VNCSConnectionST.h
index 23215d24..79f0b4fe 100644
--- a/common/rfb/VNCSConnectionST.h
+++ b/common/rfb/VNCSConnectionST.h
@@ -112,7 +112,7 @@ namespace rfb {
updates.add_copied(dest, delta);
}
- const char* getPeerEndpoint() const {return peerEndpoint.buf;}
+ const char* getPeerEndpoint() const {return peerEndpoint.c_str();}
private:
// SConnection callbacks
@@ -166,7 +166,7 @@ namespace rfb {
private:
network::Socket* sock;
- CharArray peerEndpoint;
+ std::string peerEndpoint;
bool reverseConnection;
bool inProcessMessages;
@@ -197,7 +197,7 @@ namespace rfb {
Point pointerEventPos;
bool clientHasCursor;
- CharArray closeReason;
+ std::string closeReason;
};
}
#endif
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
index aaa59eaa..1122b0a7 100644
--- a/common/rfb/VNCServerST.cxx
+++ b/common/rfb/VNCServerST.cxx
@@ -80,14 +80,14 @@ static LogWriter connectionsLog("Connections");
VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
: blHosts(&blacklist), desktop(desktop_), desktopStarted(false),
blockCounter(0), pb(0), ledState(ledUnknown),
- name(strDup(name_)), pointerClient(0), clipboardClient(0),
+ name(name_), pointerClient(0), clipboardClient(0),
comparer(0), cursor(new Cursor(0, 0, Point(), NULL)),
renderedCursorInvalid(false),
keyRemapper(&KeyRemapper::defInstance),
idleTimer(this), disconnectTimer(this), connectTimer(this),
frameTimer(this)
{
- slog.debug("creating single-threaded server %s", name.buf);
+ slog.debug("creating single-threaded server %s", name.c_str());
// FIXME: Do we really want to kick off these right away?
if (rfb::Server::maxIdleTime)
@@ -98,7 +98,7 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
VNCServerST::~VNCServerST()
{
- slog.debug("shutting down server %s", name.buf);
+ slog.debug("shutting down server %s", name.c_str());
// Close any active clients, with appropriate logging & cleanup
closeClients("Server shutdown");
@@ -175,14 +175,14 @@ void VNCServerST::removeSocket(network::Socket* sock) {
handleClipboardAnnounce(*ci, false);
clipboardRequestors.remove(*ci);
- CharArray name(strDup((*ci)->getPeerEndpoint()));
+ std::string name((*ci)->getPeerEndpoint());
// - Delete the per-Socket resources
delete *ci;
clients.remove(*ci);
- connectionsLog.status("closed: %s", name.buf);
+ connectionsLog.status("closed: %s", name.c_str());
// - Check that the desktop object is still required
if (authClientCount() == 0)
@@ -386,7 +386,7 @@ void VNCServerST::bell()
void VNCServerST::setName(const char* name_)
{
- name.replaceBuf(strDup(name_));
+ name = name_;
std::list<VNCSConnectionST*>::iterator ci, ci_next;
for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {
ci_next = ci; ci_next++;
diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h
index 26059574..028903c9 100644
--- a/common/rfb/VNCServerST.h
+++ b/common/rfb/VNCServerST.h
@@ -112,7 +112,7 @@ namespace rfb {
const ScreenSet& getScreenLayout() const { return screenLayout; }
const Cursor* getCursor() const { return cursor; }
const Point& getCursorPos() const { return cursorPos; }
- const char* getName() const { return name.buf; }
+ const char* getName() const { return name.c_str(); }
unsigned getLEDState() const { return ledState; }
// Event handlers
@@ -183,7 +183,7 @@ namespace rfb {
ScreenSet screenLayout;
unsigned int ledState;
- CharArray name;
+ std::string name;
std::list<VNCSConnectionST*> clients;
VNCSConnectionST* pointerClient;
diff --git a/common/rfb/Password.cxx b/common/rfb/obfuscate.cxx
index b1cce2bb..1f785893 100644
--- a/common/rfb/Password.cxx
+++ b/common/rfb/obfuscate.cxx
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2023 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
@@ -24,62 +25,45 @@
#include <config.h>
#endif
+#include <assert.h>
#include <string.h>
-#include <stdint.h>
+
extern "C" {
#include <rfb/d3des.h>
}
#include <rdr/Exception.h>
-#include <rfb/Password.h>
-
-using namespace rfb;
+#include <rfb/obfuscate.h>
static unsigned char d3desObfuscationKey[] = {23,82,107,6,35,78,88,7};
+std::vector<uint8_t> rfb::obfuscate(const char *str)
+{
+ std::vector<uint8_t> buf(8);
-PlainPasswd::PlainPasswd() {}
-
-PlainPasswd::PlainPasswd(char* pwd) : CharArray(pwd) {
-}
-
-PlainPasswd::PlainPasswd(size_t len) : CharArray(len) {
-}
-
-PlainPasswd::PlainPasswd(const ObfuscatedPasswd& obfPwd) : CharArray(9) {
- if (obfPwd.length < 8)
- throw rdr::Exception("bad obfuscated password length");
- deskey(d3desObfuscationKey, DE1);
- des((uint8_t*)obfPwd.buf, (uint8_t*)buf);
- buf[8] = 0;
-}
+ assert(str != NULL);
-PlainPasswd::~PlainPasswd() {
- replaceBuf(0);
-}
+ size_t l = strlen(str), i;
+ for (i=0; i<8; i++)
+ buf[i] = i<l ? str[i] : 0;
+ deskey(d3desObfuscationKey, EN0);
+ des(buf.data(), buf.data());
-void PlainPasswd::replaceBuf(char* b) {
- if (buf)
- memset(buf, 0, strlen(buf));
- CharArray::replaceBuf(b);
+ return buf;
}
+std::string rfb::deobfuscate(const uint8_t *data, size_t len)
+{
+ char buf[9];
-ObfuscatedPasswd::ObfuscatedPasswd() : length(0) {
-}
+ assert(data != NULL);
-ObfuscatedPasswd::ObfuscatedPasswd(size_t len) : CharArray(len), length(len) {
-}
+ if (len != 8)
+ throw rdr::Exception("bad obfuscated password length");
-ObfuscatedPasswd::ObfuscatedPasswd(const PlainPasswd& plainPwd) : CharArray(8), length(8) {
- size_t l = strlen(plainPwd.buf), i;
- for (i=0; i<8; i++)
- buf[i] = i<l ? plainPwd.buf[i] : 0;
- deskey(d3desObfuscationKey, EN0);
- des((uint8_t*)buf, (uint8_t*)buf);
-}
+ deskey(d3desObfuscationKey, DE1);
+ des((uint8_t*)data, (uint8_t*)buf);
+ buf[8] = 0;
-ObfuscatedPasswd::~ObfuscatedPasswd() {
- if (buf)
- memset(buf, 0, length);
+ return buf;
}
diff --git a/common/rfb/Password.h b/common/rfb/obfuscate.h
index 712bc813..96a90e44 100644
--- a/common/rfb/Password.h
+++ b/common/rfb/obfuscate.h
@@ -1,4 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2023 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
@@ -15,33 +16,20 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
-#ifndef __RFB_PASSWORD_H__
-#define __RFB_PASSWORD_H__
-#include <rfb/util.h>
+#ifndef __RFB_OBFUSCATE_H__
+#define __RFB_OBFUSCATE_H__
-namespace rfb {
+#include <stdint.h>
- class ObfuscatedPasswd;
+#include <string>
+#include <vector>
- class PlainPasswd : public CharArray {
- public:
- PlainPasswd();
- PlainPasswd(char* pwd);
- PlainPasswd(size_t len);
- PlainPasswd(const ObfuscatedPasswd& obfPwd);
- ~PlainPasswd();
- void replaceBuf(char* b);
- };
+namespace rfb {
- class ObfuscatedPasswd : public CharArray {
- public:
- ObfuscatedPasswd();
- ObfuscatedPasswd(size_t l);
- ObfuscatedPasswd(const PlainPasswd& plainPwd);
- ~ObfuscatedPasswd();
- size_t length;
- };
+ std::vector<uint8_t> obfuscate(const char *str);
+ std::string deobfuscate(const uint8_t *data, size_t len);
}
+
#endif
diff --git a/common/rfb/util.cxx b/common/rfb/util.cxx
index 6f12ad7d..c5eeed92 100644
--- a/common/rfb/util.cxx
+++ b/common/rfb/util.cxx
@@ -1,5 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2011-2022 Pierre Ossman for Cendio AB
+ * Copyright 2011-2023 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
@@ -66,6 +66,33 @@ namespace rfb {
delete [] s;
}
+ std::string strFormat(const char *fmt, ...)
+ {
+ va_list ap;
+ int len;
+ char *buf;
+ std::string out;
+
+ va_start(ap, fmt);
+ len = vsnprintf(NULL, 0, fmt, ap);
+ va_end(ap);
+
+ if (len < 0)
+ return "";
+
+ buf = new char[len+1];
+
+ va_start(ap, fmt);
+ vsnprintf(buf, len+1, fmt, ap);
+ va_end(ap);
+
+ out = buf;
+
+ delete [] buf;
+
+ return out;
+ }
+
std::vector<std::string> strSplit(const char* src,
const char delimiter)
{
diff --git a/common/rfb/util.h b/common/rfb/util.h
index 2540ab3b..b361aa11 100644
--- a/common/rfb/util.h
+++ b/common/rfb/util.h
@@ -1,5 +1,5 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
- * Copyright 2011-2022 Pierre Ossman for Cendio AB
+ * Copyright 2011-2023 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
@@ -61,6 +61,10 @@ namespace rfb {
char* strDup(const char* s);
void strFree(char* s);
+ // Formats according to printf(), with a dynamic allocation
+ std::string strFormat(const char *fmt, ...)
+ __attribute__((__format__ (__printf__, 1, 2)));
+
// Splits a string with the specified delimiter
std::vector<std::string> strSplit(const char* src,
const char delimiter);