diff options
author | Pierre Ossman <ossman@cendio.se> | 2023-01-13 12:47:48 +0100 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2023-02-04 14:03:13 +0100 |
commit | b99daadb05e14e85da6c5e905057e10fc27c0fcf (patch) | |
tree | 752e6fea3900b604d44ef6a498539e9a785bf22f /common | |
parent | e6c5b29f12780303299506fe04f089bc98b80c91 (diff) | |
download | tigervnc-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.cxx | 1 | ||||
-rw-r--r-- | common/rfb/CConnection.cxx | 4 | ||||
-rw-r--r-- | common/rfb/CConnection.h | 5 | ||||
-rw-r--r-- | common/rfb/CMakeLists.txt | 2 | ||||
-rw-r--r-- | common/rfb/CSecurityRSAAES.cxx | 5 | ||||
-rw-r--r-- | common/rfb/CSecurityTLS.cxx | 93 | ||||
-rw-r--r-- | common/rfb/Configuration.cxx | 2 | ||||
-rw-r--r-- | common/rfb/Configuration.h | 12 | ||||
-rw-r--r-- | common/rfb/Congestion.cxx | 1 | ||||
-rw-r--r-- | common/rfb/KeyRemapper.cxx | 1 | ||||
-rw-r--r-- | common/rfb/SConnection.cxx | 9 | ||||
-rw-r--r-- | common/rfb/SConnection.h | 2 | ||||
-rw-r--r-- | common/rfb/SSecurityRSAAES.cxx | 8 | ||||
-rw-r--r-- | common/rfb/SSecurityVncAuth.cxx | 48 | ||||
-rw-r--r-- | common/rfb/SSecurityVncAuth.h | 7 | ||||
-rw-r--r-- | common/rfb/VNCSConnectionST.cxx | 13 | ||||
-rw-r--r-- | common/rfb/VNCSConnectionST.h | 6 | ||||
-rw-r--r-- | common/rfb/VNCServerST.cxx | 12 | ||||
-rw-r--r-- | common/rfb/VNCServerST.h | 4 | ||||
-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.cxx | 29 | ||||
-rw-r--r-- | common/rfb/util.h | 6 |
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); |