Browse Source

Use std::string instead of CharArray

Let's use a more common type instead of something homegrown. Should be
more familiar to new developers.
pull/1587/head
Pierre Ossman 1 year ago
parent
commit
b99daadb05
58 changed files with 391 additions and 375 deletions
  1. 1
    0
      common/network/TcpSocket.cxx
  2. 2
    2
      common/rfb/CConnection.cxx
  3. 2
    3
      common/rfb/CConnection.h
  4. 1
    1
      common/rfb/CMakeLists.txt
  5. 2
    3
      common/rfb/CSecurityRSAAES.cxx
  6. 58
    35
      common/rfb/CSecurityTLS.cxx
  7. 1
    1
      common/rfb/Configuration.cxx
  8. 7
    5
      common/rfb/Configuration.h
  9. 1
    0
      common/rfb/Congestion.cxx
  10. 1
    0
      common/rfb/KeyRemapper.cxx
  11. 4
    5
      common/rfb/SConnection.cxx
  12. 1
    1
      common/rfb/SConnection.h
  13. 4
    4
      common/rfb/SSecurityRSAAES.cxx
  14. 23
    25
      common/rfb/SSecurityVncAuth.cxx
  15. 3
    4
      common/rfb/SSecurityVncAuth.h
  16. 7
    6
      common/rfb/VNCSConnectionST.cxx
  17. 3
    3
      common/rfb/VNCSConnectionST.h
  18. 6
    6
      common/rfb/VNCServerST.cxx
  19. 2
    2
      common/rfb/VNCServerST.h
  20. 24
    40
      common/rfb/obfuscate.cxx
  21. 10
    22
      common/rfb/obfuscate.h
  22. 28
    1
      common/rfb/util.cxx
  23. 5
    1
      common/rfb/util.h
  24. 5
    5
      unix/tx/TXButton.h
  25. 14
    14
      unix/tx/TXLabel.h
  26. 26
    31
      unix/vncpasswd/vncpasswd.cxx
  27. 2
    0
      unix/x0vncserver/Geometry.cxx
  28. 1
    0
      unix/x0vncserver/Image.cxx
  29. 1
    0
      unix/xserver/hw/vnc/RFBGlue.cc
  30. 4
    4
      unix/xserver/hw/vnc/XserverDesktop.cc
  31. 2
    2
      unix/xserver/hw/vnc/XserverDesktop.h
  32. 1
    0
      vncviewer/ServerDialog.cxx
  33. 4
    5
      vncviewer/UserDialog.cxx
  34. 3
    1
      win/rfb_win32/CurrentUser.cxx
  35. 3
    2
      win/rfb_win32/CurrentUser.h
  36. 3
    3
      win/rfb_win32/Dialog.cxx
  37. 3
    3
      win/rfb_win32/Dialog.h
  38. 15
    13
      win/rfb_win32/LaunchProcess.cxx
  39. 4
    4
      win/rfb_win32/LaunchProcess.h
  40. 6
    7
      win/rfb_win32/MsgBox.h
  41. 5
    5
      win/rfb_win32/MsgWindow.cxx
  42. 4
    4
      win/rfb_win32/MsgWindow.h
  43. 1
    0
      win/rfb_win32/Registry.cxx
  44. 11
    10
      win/rfb_win32/Service.cxx
  45. 1
    0
      win/rfb_win32/SocketManager.cxx
  46. 4
    4
      win/rfb_win32/Win32Util.cxx
  47. 2
    3
      win/vncconfig/Authentication.h
  48. 16
    18
      win/vncconfig/Connections.h
  49. 9
    17
      win/vncconfig/Legacy.cxx
  50. 6
    7
      win/vncconfig/PasswordDialog.cxx
  51. 5
    5
      win/winvnc/AddNewClientDialog.h
  52. 6
    7
      win/winvnc/QueryConnectDialog.cxx
  53. 2
    3
      win/winvnc/QueryConnectDialog.h
  54. 5
    8
      win/winvnc/STrayIcon.cxx
  55. 1
    1
      win/winvnc/STrayIcon.h
  56. 5
    3
      win/winvnc/VNCServerService.cxx
  57. 4
    5
      win/winvnc/VNCServerWin32.cxx
  58. 11
    11
      win/winvnc/winvnc.cxx

+ 1
- 0
common/network/TcpSocket.cxx View File

@@ -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>

+ 2
- 2
common/rfb/CConnection.cxx View File

@@ -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_)

+ 2
- 3
common/rfb/CConnection.h View File

@@ -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;

+ 1
- 1
common/rfb/CMakeLists.txt View File

@@ -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)

+ 2
- 3
common/rfb/CSecurityRSAAES.cxx View File

@@ -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");
}


+ 58
- 35
common/rfb/CSecurityTLS.cxx View File

@@ -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");


+ 1
- 1
common/rfb/Configuration.cxx View File

@@ -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();

+ 7
- 5
common/rfb/Configuration.h View File

@@ -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;

+ 1
- 0
common/rfb/Congestion.cxx View File

@@ -38,6 +38,7 @@
#endif

#include <assert.h>
#include <string.h>
#include <sys/time.h>

#ifdef __linux__

+ 1
- 0
common/rfb/KeyRemapper.cxx View File

@@ -21,6 +21,7 @@
#endif

#include <stdio.h>
#include <string.h>

#include <os/Mutex.h>


+ 4
- 5
common/rfb/SConnection.cxx View File

@@ -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;
}

+ 1
- 1
common/rfb/SConnection.h View File

@@ -257,7 +257,7 @@ namespace rfb {
SSecurity* ssecurity;

MethodTimer<SConnection> authFailureTimer;
CharArray authFailureMsg;
std::string authFailureMsg;

stateEnum state_;
int32_t preferredEncoding;

+ 4
- 4
common/rfb/SSecurityRSAAES.cxx View File

@@ -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;
}

+ 23
- 25
common/rfb/SSecurityVncAuth.cxx View File

@@ -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 (...) {
}
}

+ 3
- 4
common/rfb/SSecurityVncAuth.h View File

@@ -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];

+ 7
- 6
common/rfb/VNCSConnectionST.cxx View File

@@ -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()) {

+ 3
- 3
common/rfb/VNCSConnectionST.h View File

@@ -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

+ 6
- 6
common/rfb/VNCServerST.cxx View File

@@ -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++;

+ 2
- 2
common/rfb/VNCServerST.h View File

@@ -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;

common/rfb/Password.cxx → common/rfb/obfuscate.cxx View File

@@ -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;
}

common/rfb/Password.h → common/rfb/obfuscate.h View File

@@ -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

+ 28
- 1
common/rfb/util.cxx View File

@@ -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)
{

+ 5
- 1
common/rfb/util.h View File

@@ -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);

+ 5
- 5
unix/tx/TXButton.h View File

@@ -59,8 +59,8 @@ public:

// setText() changes the text in the button.
void setText(const char* text_) {
text.buf = rfb::strDup(text_);
int textWidth = XTextWidth(defaultFS, text.buf, strlen(text.buf));
text = text_;
int textWidth = XTextWidth(defaultFS, text.data(), text.size());
int textHeight = (defaultFS->ascent + defaultFS->descent);
int newWidth = __rfbmax(width(), textWidth + xPad*2 + bevel*2);
int newHeight = __rfbmax(height(), textHeight + yPad*2 + bevel*2);
@@ -77,7 +77,7 @@ public:
private:

void paint() {
int tw = XTextWidth(defaultFS, text.buf, strlen(text.buf));
int tw = XTextWidth(defaultFS, text.data(), text.size());
int startx = (width() - tw) / 2;
int starty = (height() + defaultFS->ascent - defaultFS->descent) / 2;
if (down || disabled_) {
@@ -88,7 +88,7 @@ private:
}

XSetForeground(dpy, gc, disabled_ ? disabledFg : defaultFg);
XDrawString(dpy, win(), gc, startx, starty, text.buf, strlen(text.buf));
XDrawString(dpy, win(), gc, startx, starty, text.data(), text.size());
}

virtual void handleEvent(TXWindow* /*w*/, XEvent* ev) {
@@ -115,7 +115,7 @@ private:
}

GC gc;
rfb::CharArray text;
std::string text;
TXButtonCallback* cb;
bool down;
bool disabled_;

+ 14
- 14
unix/tx/TXLabel.h View File

@@ -47,20 +47,20 @@ public:

// setText() changes the text in the label.
void setText(const char* text_) {
text.buf = rfb::strDup(text_);
text = text_;
lines = 0;
int lineStart = 0;
size_t lineStart = 0;
int textWidth = 0;
int i = -1;
size_t i = -1;
do {
i++;
if (text.buf[i] == '\n' || text.buf[i] == 0) {
int tw = XTextWidth(defaultFS, &text.buf[lineStart], i-lineStart);
if (i >= text.size() || text[i] == '\n') {
int tw = XTextWidth(defaultFS, &text[lineStart], i-lineStart);
if (tw > textWidth) textWidth = tw;
lineStart = i+1;
lines++;
}
} while (text.buf[i] != 0);
} while (i < text.size());
int textHeight = ((defaultFS->ascent + defaultFS->descent + lineSpacing)
* lines);
int newWidth = __rfbmax(width(), textWidth + xPad*2);
@@ -93,19 +93,19 @@ private:
}

void paint() {
int lineNum = 0;
int lineStart = 0;
int i = -1;
size_t lineNum = 0;
size_t lineStart = 0;
size_t i = -1;
do {
i++;
if (text.buf[i] == '\n' || text.buf[i] == 0) {
int tw = XTextWidth(defaultFS, &text.buf[lineStart], i-lineStart);
if (i >= text.size() || text[i] == '\n') {
int tw = XTextWidth(defaultFS, &text[lineStart], i-lineStart);
XDrawString(dpy, win(), defaultGC, xOffset(tw), yOffset(lineNum),
&text.buf[lineStart], i-lineStart);
&text[lineStart], i-lineStart);
lineStart = i+1;
lineNum++;
}
} while (text.buf[i] != 0);
} while (i < text.size());
}

virtual void handleEvent(TXWindow* /*w*/, XEvent* ev) {
@@ -117,7 +117,7 @@ private:
}

int lineSpacing;
rfb::CharArray text;
std::string text;
int lines;
HAlign halign;
VAlign valign;

+ 26
- 31
unix/vncpasswd/vncpasswd.cxx View File

@@ -1,6 +1,7 @@
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
* Copyright (C) 2010 Antoine Martin. All Rights Reserved.
* Copyright (C) 2010 D. R. Commander. All Rights Reserved.
* Copyright 2018-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
@@ -30,7 +31,8 @@
#include <sys/stat.h>
#include <unistd.h>
#include <os/os.h>
#include <rfb/Password.h>

#include <rfb/obfuscate.h>

#include <termios.h>

@@ -58,16 +60,16 @@ static void enableEcho(bool enable) {
tcsetattr(fileno(stdin), TCSAFLUSH, &attrs);
}

static char* getpassword(const char* prompt) {
PlainPasswd buf(256);
static const char* getpassword(const char* prompt) {
static char buf[256];
if (prompt) fputs(prompt, stdout);
enableEcho(false);
char* result = fgets(buf.buf, 256, stdin);
char* result = fgets(buf, 256, stdin);
enableEcho(true);
if (result) {
if (result[strlen(result)-1] == '\n')
result[strlen(result)-1] = 0;
return buf.takeBuf();
return buf;
}
return 0;
}
@@ -78,12 +80,12 @@ static int encrypt_pipe() {

// We support a maximum of two passwords right now
for (i = 0;i < 2;i++) {
char *result = getpassword(NULL);
const char *result = getpassword(NULL);
if (!result)
break;

ObfuscatedPasswd obfuscated(result);
if (fwrite(obfuscated.buf, obfuscated.length, 1, stdout) != 1) {
std::vector<uint8_t> obfuscated = obfuscate(result);
if (fwrite(obfuscated.data(), obfuscated.size(), 1, stdout) != 1) {
fprintf(stderr,"Writing to stdout failed\n");
return 1;
}
@@ -96,15 +98,16 @@ static int encrypt_pipe() {
return 0;
}

static ObfuscatedPasswd* readpassword() {
static std::vector<uint8_t> readpassword() {
while (true) {
PlainPasswd passwd(getpassword("Password:"));
if (!passwd.buf) {
const char *passwd = getpassword("Password:");
if (passwd == NULL) {
perror("getpassword error");
exit(1);
}
if (strlen(passwd.buf) < 6) {
if (strlen(passwd.buf) == 0) {
std::string first = passwd;
if (first.size() < 6) {
if (first.empty()) {
fprintf(stderr,"Password not changed\n");
exit(1);
}
@@ -112,17 +115,18 @@ static ObfuscatedPasswd* readpassword() {
continue;
}

PlainPasswd passwd2(getpassword("Verify:"));
if (!passwd2.buf) {
passwd = getpassword("Verify:");
if (passwd == NULL) {
perror("getpass error");
exit(1);
}
if (strcmp(passwd.buf, passwd2.buf) != 0) {
std::string second = passwd;
if (first != second) {
fprintf(stderr,"Passwords don't match - try again\n");
continue;
}

return new ObfuscatedPasswd(passwd);
return obfuscate(first.c_str());
}
}

@@ -162,8 +166,8 @@ int main(int argc, char** argv)
}

while (true) {
ObfuscatedPasswd* obfuscated = readpassword();
ObfuscatedPasswd* obfuscatedReadOnly = 0;
std::vector<uint8_t> obfuscated = readpassword();
std::vector<uint8_t> obfuscatedReadOnly;

fprintf(stderr, "Would you like to enter a view-only password (y/n)? ");
char yesno[3];
@@ -176,33 +180,24 @@ int main(int argc, char** argv)
FILE* fp = fopen(fname,"w");
if (!fp) {
fprintf(stderr,"Couldn't open %s for writing\n",fname);
delete obfuscated;
delete obfuscatedReadOnly;
exit(1);
}
chmod(fname, S_IRUSR|S_IWUSR);

if (fwrite(obfuscated->buf, obfuscated->length, 1, fp) != 1) {
if (fwrite(obfuscated.data(), obfuscated.size(), 1, fp) != 1) {
fprintf(stderr,"Writing to %s failed\n",fname);
delete obfuscated;
delete obfuscatedReadOnly;
exit(1);
}

delete obfuscated;

if (obfuscatedReadOnly) {
if (fwrite(obfuscatedReadOnly->buf, obfuscatedReadOnly->length, 1, fp) != 1) {
if (!obfuscatedReadOnly.empty()) {
if (fwrite(obfuscatedReadOnly.data(), obfuscatedReadOnly.size(), 1, fp) != 1) {
fprintf(stderr,"Writing to %s failed\n",fname);
delete obfuscatedReadOnly;
exit(1);
}
}

fclose(fp);

delete obfuscatedReadOnly;

return 0;
}
}

+ 2
- 0
unix/x0vncserver/Geometry.cxx View File

@@ -24,6 +24,8 @@
#include <config.h>
#endif

#include <string.h>

#include <rfb/LogWriter.h>
#include <x0vncserver/Geometry.h>


+ 1
- 0
unix/x0vncserver/Image.cxx View File

@@ -26,6 +26,7 @@

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include <sys/ipc.h>

+ 1
- 0
unix/xserver/hw/vnc/RFBGlue.cc View File

@@ -28,6 +28,7 @@
#include <rfb/LogWriter.h>
#include <rfb/Logger_stdio.h>
#include <rfb/Logger_syslog.h>
#include <rfb/util.h>

#include "RFBGlue.h"


+ 4
- 4
unix/xserver/hw/vnc/XserverDesktop.cc View File

@@ -172,10 +172,10 @@ void XserverDesktop::queryConnection(network::Socket* sock,
return;
}

queryConnectAddress.replaceBuf(strDup(sock->getPeerAddress()));
queryConnectAddress = sock->getPeerAddress();
if (!userName)
userName = "(anonymous)";
queryConnectUsername.replaceBuf(strDup(userName));
queryConnectUsername = userName;
queryConnectId = (uint32_t)(intptr_t)sock;
queryConnectSocket = sock;

@@ -428,8 +428,8 @@ void XserverDesktop::getQueryConnect(uint32_t* opaqueId,
*username = "";
*timeout = 0;
} else {
*address = queryConnectAddress.buf;
*username = queryConnectUsername.buf;
*address = queryConnectAddress.c_str();
*username = queryConnectUsername.c_str();
*timeout = queryConnectTimeout;
}
}

+ 2
- 2
unix/xserver/hw/vnc/XserverDesktop.h View File

@@ -123,8 +123,8 @@ private:

uint32_t queryConnectId;
network::Socket* queryConnectSocket;
rfb::CharArray queryConnectAddress;
rfb::CharArray queryConnectUsername;
std::string queryConnectAddress;
std::string queryConnectUsername;
rfb::Timer queryConnectTimer;

OutputIdMap outputIdMap;

+ 1
- 0
vncviewer/ServerDialog.cxx View File

@@ -38,6 +38,7 @@
#include <os/os.h>
#include <rfb/Exception.h>
#include <rfb/LogWriter.h>
#include <rfb/util.h>

#include "fltk/layout.h"
#include "ServerDialog.h"

+ 4
- 5
vncviewer/UserDialog.cxx View File

@@ -34,8 +34,8 @@
#include <FL/Fl_Return_Button.H>
#include <FL/Fl_Pixmap.H>

#include <rfb/Password.h>
#include <rfb/Exception.h>
#include <rfb/obfuscate.h>

#include "fltk/layout.h"
#include "fltk/util.h"
@@ -91,18 +91,17 @@ void UserDialog::getUserPasswd(bool secure, std::string* user,
}

if (!user && passwordFileName[0]) {
ObfuscatedPasswd obfPwd(256);
std::vector<uint8_t> obfPwd(256);
FILE* fp;

fp = fopen(passwordFileName, "rb");
if (!fp)
throw rfb::Exception(_("Opening password file failed"));

obfPwd.length = fread(obfPwd.buf, 1, obfPwd.length, fp);
obfPwd.resize(fread(obfPwd.data(), 1, obfPwd.size(), fp));
fclose(fp);

PlainPasswd passwd(obfPwd);
*password = passwd.buf;
*password = deobfuscate(obfPwd.data(), obfPwd.size());

return;
}

+ 3
- 1
win/rfb_win32/CurrentUser.cxx View File

@@ -110,10 +110,12 @@ ImpersonateCurrentUser::~ImpersonateCurrentUser() {
}


UserName::UserName() : CharArray(UNLEN+1) {
UserName::UserName() {
char buf[UNLEN+1];
DWORD len = UNLEN+1;
if (!GetUserName(buf, &len))
throw rdr::SystemException("GetUserName failed", GetLastError());
assign(buf);
}



+ 3
- 2
win/rfb_win32/CurrentUser.h View File

@@ -26,7 +26,8 @@
#ifndef __RFB_WIN32_CURRENT_USER_H__
#define __RFB_WIN32_CURRENT_USER_H__

#include <rfb/util.h>
#include <string>

#include <rfb_win32/Handle.h>
#include <rfb_win32/Security.h>

@@ -67,7 +68,7 @@ namespace rfb {
// Returns the name of the user the thread is currently running as.
// Raises a SystemException in case of error.

struct UserName : public CharArray {
struct UserName : public std::string {
UserName();
};


+ 3
- 3
win/rfb_win32/Dialog.cxx View File

@@ -207,7 +207,7 @@ BOOL PropSheetPage::dialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam


PropSheet::PropSheet(HINSTANCE inst_, const char* title_, std::list<PropSheetPage*> pages_, HICON icon_)
: icon(icon_), pages(pages_), inst(inst_), title(strDup(title_)), handle(0), alreadyShowing(0) {
: icon(icon_), pages(pages_), inst(inst_), title(title_), handle(0), alreadyShowing(0) {
}

PropSheet::~PropSheet() {
@@ -264,7 +264,7 @@ bool PropSheet::showPropSheet(HWND owner, bool showApply, bool showCtxtHelp, boo
header.pfnCallback = removeCtxtHelp;
header.hwndParent = owner;
header.hInstance = inst;
header.pszCaption = title.buf;
header.pszCaption = title.c_str();
header.nPages = count;
header.nStartPage = 0;
header.phpage = hpages;
@@ -282,7 +282,7 @@ bool PropSheet::showPropSheet(HWND owner, bool showApply, bool showCtxtHelp, boo
(void)capture;
#ifdef _DIALOG_CAPTURE
if (capture) {
plog.info("capturing \"%s\"", title.buf);
plog.info("capturing \"%s\"", title.c_str());
char* tmpdir = getenv("TEMP");
HDC dc = GetWindowDC(handle);
DeviceFrameBuffer fb(dc);

+ 3
- 3
win/rfb_win32/Dialog.h View File

@@ -25,12 +25,12 @@
#ifndef __RFB_WIN32_DIALOG_H__
#define __RFB_WIN32_DIALOG_H__

#include <string>

#include <windows.h>
#include <prsht.h>
#include <list>

#include <rfb/util.h>

namespace rfb {

namespace win32 {
@@ -131,7 +131,7 @@ namespace rfb {
HICON icon;
std::list<PropSheetPage*> pages;
HINSTANCE inst;
CharArray title;
std::string title;
HWND handle;
bool alreadyShowing;
};

+ 15
- 13
win/rfb_win32/LaunchProcess.cxx View File

@@ -33,7 +33,7 @@ using namespace win32;


LaunchProcess::LaunchProcess(const char* exeName_, const char* params_)
: exeName(strDup(exeName_)), params(strDup(params_)) {
: exeName(exeName_), params(params_) {
memset(&procInfo, 0, sizeof(procInfo));
}

@@ -64,30 +64,32 @@ void LaunchProcess::start(HANDLE userToken, bool createConsole) {
sinfo.lpDesktop = desktopName;

// - Concoct a suitable command-line
CharArray exePath;
if (!strContains(exeName.buf, '\\')) {
std::string exePath;
if (exeName.find('\\') == std::string::npos) {
ModuleFileName filename;
CharArray path(strDup(filename.buf));
if (strContains(path.buf, '\\'))
*strrchr(path.buf, '\\') = '\0';
exePath.buf = new char[strlen(path.buf) + strlen(exeName.buf) + 2];
sprintf(exePath.buf, "%s\\%s", path.buf, exeName.buf);
std::string path(filename.buf);
if (path.rfind('\\') != std::string::npos)
path.resize(path.rfind('\\'));
exePath = path + '\\' + exeName;
} else {
exePath.buf = strDup(exeName.buf);
exePath = exeName;
}

// - Start the process
// Note: We specify the exe's precise path in the ApplicationName parameter,
// AND include the name as the first part of the CommandLine parameter,
// because CreateProcess doesn't make ApplicationName argv[0] in C programs.
CharArray cmdLine(strlen(exeName.buf) + 3 + strlen(params.buf) + 1);
sprintf(cmdLine.buf, "\"%s\" %s", exeName.buf, params.buf);
std::string cmdLine;
cmdLine = (std::string)"\"" + exeName + "\" " + params;
DWORD flags = createConsole ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW;
BOOL success;
if (userToken != INVALID_HANDLE_VALUE)
success = CreateProcessAsUser(userToken, exePath.buf, cmdLine.buf, 0, 0, FALSE, flags, 0, 0, &sinfo, &procInfo);
success = CreateProcessAsUser(userToken, exePath.c_str(),
(char*)cmdLine.c_str(), 0, 0, FALSE,
flags, 0, 0, &sinfo, &procInfo);
else
success = CreateProcess(exePath.buf, cmdLine.buf, 0, 0, FALSE, flags, 0, 0, &sinfo, &procInfo);
success = CreateProcess(exePath.c_str(), (char*)cmdLine.c_str(), 0,
0, FALSE, flags, 0, 0, &sinfo, &procInfo);
if (!success)
throw rdr::SystemException("unable to launch process", GetLastError());


+ 4
- 4
win/rfb_win32/LaunchProcess.h View File

@@ -24,9 +24,9 @@
#ifndef __RFB_WIN32_LAUNCHPROCESS_H__
#define __RFB_WIN32_LAUNCHPROCESS_H__

#include <windows.h>
#include <string>

#include <rfb/util.h>
#include <windows.h>

namespace rfb {

@@ -60,8 +60,8 @@ namespace rfb {
PROCESS_INFORMATION procInfo;
DWORD returnCode;
protected:
CharArray exeName;
CharArray params;
std::string exeName;
std::string params;
};



+ 6
- 7
win/rfb_win32/MsgBox.h View File

@@ -19,9 +19,9 @@
#ifndef __RFB_WIN32_MSGBOX_H__
#define __RFB_WIN32_MSGBOX_H__

#include <windows.h>
#include <string>

#include <rfb/util.h>
#include <windows.h>

namespace rfb {
namespace win32 {
@@ -49,13 +49,12 @@ namespace rfb {
flags |= MB_TOPMOST | MB_SETFOREGROUND;
int len = strlen(AppName) + 1;
if (msgType) len += strlen(msgType) + 3;
CharArray title(new char[len]);
strcpy(title.buf, AppName);
std::string title = AppName;
if (msgType) {
strcat(title.buf, " : ");
strcat(title.buf, msgType);
title += " : ";
title += msgType;
}
return MessageBox(parent, msg, title.buf, flags);
return MessageBox(parent, msg, title.c_str(), flags);
}

};

+ 5
- 5
win/rfb_win32/MsgWindow.cxx View File

@@ -98,21 +98,21 @@ static MsgWindowClass baseClass;
// -=- MsgWindow
//

MsgWindow::MsgWindow(const char* name_) : name(strDup(name_)), handle(0) {
vlog.debug("creating window \"%s\"", name.buf);
MsgWindow::MsgWindow(const char* name_) : name(name_), handle(0) {
vlog.debug("creating window \"%s\"", name.c_str());
handle = CreateWindow((const char*)(intptr_t)baseClass.classAtom,
name.buf, WS_OVERLAPPED, 0, 0, 10, 10, 0, 0,
name.c_str(), WS_OVERLAPPED, 0, 0, 10, 10, 0, 0,
baseClass.instance, this);
if (!handle) {
throw rdr::SystemException("unable to create WMNotifier window instance", GetLastError());
}
vlog.debug("created window \"%s\" (%p)", name.buf, handle);
vlog.debug("created window \"%s\" (%p)", name.c_str(), handle);
}

MsgWindow::~MsgWindow() {
if (handle)
DestroyWindow(handle);
vlog.debug("destroyed window \"%s\" (%p)", name.buf, handle);
vlog.debug("destroyed window \"%s\" (%p)", name.c_str(), handle);
}

LRESULT

+ 4
- 4
win/rfb_win32/MsgWindow.h View File

@@ -24,9 +24,9 @@
#ifndef __RFB_WIN32_MSG_WINDOW_H__
#define __RFB_WIN32_MSG_WINDOW_H__

#include <windows.h>
#include <string>

#include <rfb/util.h>
#include <windows.h>

namespace rfb {

@@ -37,13 +37,13 @@ namespace rfb {
MsgWindow(const char* _name);
virtual ~MsgWindow();

const char* getName() {return name.buf;}
const char* getName() {return name.c_str();}
HWND getHandle() const {return handle;}

virtual LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam);

protected:
CharArray name;
std::string name;
HWND handle;
};


+ 1
- 0
win/rfb_win32/Registry.cxx View File

@@ -29,6 +29,7 @@
#include <rdr/HexInStream.h>
#include <stdlib.h>
#include <rfb/LogWriter.h>
#include <rfb/util.h>

// These flags are required to control access control inheritance,
// but are not defined by VC6's headers. These definitions comes

+ 11
- 10
win/rfb_win32/Service.cxx View File

@@ -30,6 +30,7 @@
#include <logmessages/messages.h>
#include <rdr/Exception.h>
#include <rfb/LogWriter.h>
#include <rfb/util.h>


using namespace rdr;
@@ -321,12 +322,12 @@ bool rfb::win32::registerService(const char* name,
}

// - Add the supplied extra parameters to the command line
CharArray cmdline(cmdline_len+strlen(defaultcmdline));
sprintf(cmdline.buf, "\"%s\" %s", buffer.buf, defaultcmdline);
std::string cmdline;
cmdline = strFormat("\"%s\" %s", buffer.buf, defaultcmdline);
for (i=0; i<argc; i++) {
strcat(cmdline.buf, " \"");
strcat(cmdline.buf, argv[i]);
strcat(cmdline.buf, "\"");
cmdline += " \"";
cmdline += argv[i];
cmdline += "\"";
}
// - Register the service
@@ -341,7 +342,7 @@ bool rfb::win32::registerService(const char* name,
name, display, SC_MANAGER_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,
cmdline.buf, NULL, NULL, NULL, NULL, NULL);
cmdline.c_str(), NULL, NULL, NULL, NULL, NULL);
if (!service)
throw rdr::SystemException("unable to create service", GetLastError());

@@ -363,11 +364,11 @@ bool rfb::win32::registerService(const char* name,
}

const char* dllFilename = "logmessages.dll";
CharArray dllPath(strlen(buffer.buf) + strlen(dllFilename) + 1);
strcpy(dllPath.buf, buffer.buf);
strcat(dllPath.buf, dllFilename);
std::string dllPath;
dllPath = buffer.buf;
dllPath += dllFilename;

hk.setExpandString("EventMessageFile", dllPath.buf);
hk.setExpandString("EventMessageFile", dllPath.c_str());
hk.setInt("TypesSupported", EVENTLOG_ERROR_TYPE | EVENTLOG_INFORMATION_TYPE);

Sleep(500);

+ 1
- 0
win/rfb_win32/SocketManager.cxx View File

@@ -26,6 +26,7 @@
#include <list>
#include <rfb/LogWriter.h>
#include <rfb/Timer.h>
#include <rfb/util.h>
#include <rfb_win32/SocketManager.h>

using namespace rfb;

+ 4
- 4
win/rfb_win32/Win32Util.cxx View File

@@ -73,14 +73,14 @@ const char* FileVersionInfo::getVerString(const char* name, DWORD langId) {
}

std::string langIdStr(binToHex(langIdBuf, sizeof(langId)));
CharArray infoName(strlen("StringFileInfo") + 4 + strlen(name) + strlen(langIdStr.c_str()));
sprintf(infoName.buf, "\\StringFileInfo\\%s\\%s", langIdStr.c_str(), name);
std::string infoName;
infoName = strFormat("\\StringFileInfo\\%s\\%s", langIdStr.c_str(), name);

// Locate the required version string within the version info
char* buffer = 0;
UINT length = 0;
if (!VerQueryValue(buf, infoName.buf, (void**)&buffer, &length)) {
printf("unable to find %s version string", infoName.buf);
if (!VerQueryValue(buf, infoName.c_str(), (void**)&buffer, &length)) {
printf("unable to find %s version string", infoName.c_str());
throw rdr::Exception("VerQueryValue failed");
}
return buffer;

+ 2
- 3
win/vncconfig/Authentication.h View File

@@ -32,7 +32,6 @@
#ifdef HAVE_GNUTLS
#include <rfb/SSecurityTLS.h>
#endif
#include <rfb/Password.h>

static rfb::BoolParameter queryOnlyIfLoggedOn("QueryOnlyIfLoggedOn",
"Only prompt for a local user to accept incoming connections if there is a user logged on", false);
@@ -113,9 +112,9 @@ namespace rfb {


static bool haveVncPassword() {
PlainPasswd password, passwordReadOnly;
std::string password, passwordReadOnly;
SSecurityVncAuth::vncAuthPasswd.getVncAuthPasswd(&password, &passwordReadOnly);
return password.buf && strlen(password.buf) != 0;
return !password.empty();
}

static void verifyVncPassword(const RegKey& regKey) {

+ 16
- 18
win/vncconfig/Connections.h View File

@@ -42,47 +42,45 @@ namespace rfb {
public:
ConnHostDialog() : Dialog(GetModuleHandle(0)) {}
bool showDialog(const char* pat) {
pattern.replaceBuf(strDup(pat));
pattern = pat;
return Dialog::showDialog(MAKEINTRESOURCE(IDD_CONN_HOST));
}
void initDialog() {
if (strlen(pattern.buf) == 0)
pattern.replaceBuf(strDup("+"));
if (pattern.empty())
pattern = "+";

if (pattern.buf[0] == '+')
if (pattern[0] == '+')
setItemChecked(IDC_ALLOW, true);
else if (pattern.buf[0] == '?')
else if (pattern[0] == '?')
setItemChecked(IDC_QUERY, true);
else
setItemChecked(IDC_DENY, true);

setItemString(IDC_HOST_PATTERN, &pattern.buf[1]);
pattern.replaceBuf(0);
setItemString(IDC_HOST_PATTERN, &pattern.c_str()[1]);
pattern.clear();
}
bool onOk() {
CharArray host(strDup(getItemString(IDC_HOST_PATTERN)));
CharArray newPat(strlen(host.buf)+2);
std::string newPat;
if (isItemChecked(IDC_ALLOW))
newPat.buf[0] = '+';
newPat = '+';
else if (isItemChecked(IDC_QUERY))
newPat.buf[0] = '?';
newPat = '?';
else
newPat.buf[0] = '-';
newPat.buf[1] = 0;
strcat(newPat.buf, host.buf);
newPat = '-';
newPat += getItemString(IDC_HOST_PATTERN);

try {
network::TcpFilter::Pattern pat(network::TcpFilter::parsePattern(newPat.buf));
pattern.replaceBuf(strDup(network::TcpFilter::patternToStr(pat).c_str()));
network::TcpFilter::Pattern pat(network::TcpFilter::parsePattern(newPat.c_str()));
pattern = network::TcpFilter::patternToStr(pat);
} catch(rdr::Exception& e) {
MsgBox(NULL, e.str(), MB_ICONEXCLAMATION | MB_OK);
return false;
}
return true;
}
const char* getPattern() {return pattern.buf;}
const char* getPattern() {return pattern.c_str();}
protected:
CharArray pattern;
std::string pattern;
};

class ConnectionsPage : public PropSheetPage {

+ 9
- 17
win/vncconfig/Legacy.cxx View File

@@ -38,10 +38,9 @@ void LegacyPage::LoadPrefs()
// settings from HKCU/Software/ORL/WinVNC3.

// Get the name of the current user
CharArray username;
std::string username;
try {
UserName name;
username.buf = name.takeBuf();
username = UserName();
} catch (rdr::SystemException& e) {
if (e.err != ERROR_NOT_LOGGED_ON)
throw;
@@ -64,8 +63,7 @@ void LegacyPage::LoadPrefs()
std::string authHosts = winvnc3.getString("AuthHosts", "");
if (!authHosts.empty()) {
CharArray newHosts;
newHosts.buf = strDup("");
std::string newHosts;

// Reformat AuthHosts to Hosts. Wish I'd left the format the same. :( :( :(
try {
@@ -107,20 +105,14 @@ void LegacyPage::LoadPrefs()
strcat(pattern, buf);

// Append this pattern to the Hosts value
int length = strlen(newHosts.buf) + strlen(pattern) + 2;
CharArray tmpHosts(length);
strcpy(tmpHosts.buf, pattern);
if (strlen(newHosts.buf)) {
strcat(tmpHosts.buf, ",");
strcat(tmpHosts.buf, newHosts.buf);
}
delete [] newHosts.buf;
newHosts.buf = tmpHosts.takeBuf();
if (!newHosts.empty())
newHosts += ",";
newHosts += pattern;
}
}

// Finally, save the Hosts value
regKey.setString("Hosts", newHosts.buf);
regKey.setString("Hosts", newHosts.c_str());
} catch (rdr::Exception&) {
MsgBox(0, "Unable to convert AuthHosts setting to Hosts format.",
MB_ICONWARNING | MB_OK);
@@ -157,10 +149,10 @@ void LegacyPage::LoadPrefs()
}

// Open the local, user-specific settings
if (userSettings && username.buf) {
if (userSettings && !username.empty()) {
try {
RegKey userKey;
userKey.openKey(winvnc3, username.buf);
userKey.openKey(winvnc3, username.c_str());
vlog.info("loading local User prefs");
LoadUserPrefs(userKey);
} catch(rdr::Exception& e) {

+ 6
- 7
win/vncconfig/PasswordDialog.cxx View File

@@ -19,7 +19,7 @@
#include <vncconfig/resource.h>
#include <vncconfig/PasswordDialog.h>
#include <rfb_win32/MsgBox.h>
#include <rfb/Password.h>
#include <rfb/obfuscate.h>

using namespace rfb;
using namespace win32;
@@ -33,9 +33,9 @@ bool PasswordDialog::showDialog(HWND owner) {
}

bool PasswordDialog::onOk() {
PlainPasswd password1(strDup(getItemString(IDC_PASSWORD1)));
PlainPasswd password2(strDup(getItemString(IDC_PASSWORD2)));
if (strcmp(password1.buf, password2.buf) != 0) {
std::string password1(getItemString(IDC_PASSWORD1));
std::string password2(getItemString(IDC_PASSWORD2));
if (password1 != password2) {
MsgBox(0, "The supplied passwords do not match",
MB_ICONEXCLAMATION | MB_OK);
return false;
@@ -45,8 +45,7 @@ bool PasswordDialog::onOk() {
"Are you sure you wish to continue?",
MB_YESNO | MB_ICONWARNING) == IDNO))
return false;
PlainPasswd password(strDup(password1.buf));
ObfuscatedPasswd obfPwd(password);
regKey.setBinary("Password", obfPwd.buf, obfPwd.length);
std::vector<uint8_t> obfPwd = obfuscate(password1.c_str());
regKey.setBinary("Password", obfPwd.data(), obfPwd.size());
return true;
}

+ 5
- 5
win/winvnc/AddNewClientDialog.h View File

@@ -34,20 +34,20 @@ namespace winvnc {
virtual bool showDialog() {
return Dialog::showDialog(MAKEINTRESOURCE(IDD_ADD_NEW_CLIENT));
}
const char* getHostName() const {return hostName.buf;}
const char* getHostName() const {return hostName.c_str();}
protected:

// Dialog methods (protected)
virtual void initDialog() {
if (hostName.buf)
setItemString(IDC_HOST, hostName.buf);
if (!hostName.empty())
setItemString(IDC_HOST, hostName.c_str());
}
virtual bool onOk() {
hostName.replaceBuf(rfb::strDup(getItemString(IDC_HOST)));
hostName = getItemString(IDC_HOST);
return true;
}

rfb::CharArray hostName;
std::string hostName;
};

};

+ 6
- 7
win/winvnc/QueryConnectDialog.cxx View File

@@ -45,9 +45,8 @@ QueryConnectDialog::QueryConnectDialog(network::Socket* sock_,
const char* userName_,
VNCServerWin32* s)
: Dialog(GetModuleHandle(0)),
sock(sock_), approve(false), server(s) {
peerIp.buf = strDup(sock->getPeerAddress());
userName.buf = strDup(userName_);
sock(sock_), peerIp(sock->getPeerAddress()), userName(userName_),
approve(false), server(s) {
}

void QueryConnectDialog::startDialog() {
@@ -76,10 +75,10 @@ void QueryConnectDialog::worker() {
void QueryConnectDialog::initDialog() {
if (!SetTimer(handle, 1, 1000, 0))
throw rdr::SystemException("SetTimer", GetLastError());
setItemString(IDC_QUERY_HOST, peerIp.buf);
if (!userName.buf)
userName.buf = strDup("(anonymous)");
setItemString(IDC_QUERY_USER, userName.buf);
setItemString(IDC_QUERY_HOST, peerIp.c_str());
if (userName.empty())
userName = "(anonymous)";
setItemString(IDC_QUERY_USER, userName.c_str());
setCountdownLabel();
}


+ 2
- 3
win/winvnc/QueryConnectDialog.h View File

@@ -22,7 +22,6 @@
#define __WINVNC_QUERY_CONNECT_DIALOG_H__

#include <rfb_win32/Dialog.h>
#include <rfb/util.h>

namespace os { class Thread; }

@@ -51,8 +50,8 @@ namespace winvnc {

int countdown;
network::Socket* sock;
rfb::CharArray peerIp;
rfb::CharArray userName;
std::string peerIp;
std::string userName;
bool approve;
VNCServerWin32* server;
};

+ 5
- 8
win/winvnc/STrayIcon.cxx View File

@@ -180,10 +180,8 @@ public:
switch (command->dwData) {
case 1:
{
CharArray viewer(command->cbData + 1);
memcpy(viewer.buf, command->lpData, command->cbData);
viewer.buf[command->cbData] = 0;
return thread.server.addNewClient(viewer.buf) ? 1 : 0;
std::string viewer((char*)command->lpData, command->cbData);
return thread.server.addNewClient(viewer.c_str()) ? 1 : 0;
}
case 2:
return thread.server.disconnectClients("IPC disconnect") ? 1 : 0;
@@ -220,8 +218,8 @@ public:
case WM_SET_TOOLTIP:
{
os::AutoMutex a(thread.lock);
if (thread.toolTip.buf)
setToolTip(thread.toolTip.buf);
if (!thread.toolTip.empty())
setToolTip(thread.toolTip.c_str());
}
return 0;

@@ -280,8 +278,7 @@ void STrayIconThread::worker() {
void STrayIconThread::setToolTip(const char* text) {
if (!windowHandle) return;
os::AutoMutex a(lock);
delete [] toolTip.buf;
toolTip.buf = strDup(text);
toolTip = text;
PostMessage(windowHandle, WM_SET_TOOLTIP, 0, 0);
}


+ 1
- 1
win/winvnc/STrayIcon.h View File

@@ -47,7 +47,7 @@ namespace winvnc {
os::Mutex* lock;
DWORD thread_id;
HWND windowHandle;
rfb::CharArray toolTip;
std::string toolTip;
VNCServerWin32& server;
UINT inactiveIcon;
UINT activeIcon;

+ 5
- 3
win/winvnc/VNCServerService.cxx View File

@@ -108,14 +108,16 @@ HANDLE LaunchProcessWin(DWORD /*dwSessionId*/)
if (GetSessionUserTokenWin(&hToken))
{
ModuleFileName filename;
CharArray cmdLine;
cmdLine.format("\"%s\" -noconsole -service_run", filename.buf);
std::string cmdLine;
cmdLine = strFormat("\"%s\" -noconsole -service_run", filename.buf);
STARTUPINFO si;
ZeroMemory(&si, sizeof si);
si.cb = sizeof si;
si.dwFlags = STARTF_USESHOWWINDOW;
PROCESS_INFORMATION pi;
if (CreateProcessAsUser(hToken, NULL, cmdLine.buf, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &si, &pi))
if (CreateProcessAsUser(hToken, NULL, (char*)cmdLine.c_str(),
NULL, NULL, FALSE, DETACHED_PROCESS,
NULL, NULL, &si, &pi))
{
CloseHandle(pi.hThread);
hProcess = pi.hProcess;

+ 4
- 5
win/winvnc/VNCServerWin32.cxx View File

@@ -130,18 +130,17 @@ void VNCServerWin32::processAddressChange() {
length += i->size() + 1;

// Build the new tip
CharArray toolTip(length);
strcpy(toolTip.buf, prefix);
std::string toolTip(prefix);
for (i=addrs.begin(); i!= addrs.end(); i=next_i) {
next_i = i; next_i ++;
strcat(toolTip.buf, i->c_str());
toolTip += *i;
if (next_i != addrs.end())
strcat(toolTip.buf, ",");
toolTip += ",";
}
// Pass the new tip to the tray icon
vlog.info("Refreshing tray icon");
trayIcon->setToolTip(toolTip.buf);
trayIcon->setToolTip(toolTip.c_str());
}

void VNCServerWin32::regConfigChanged() {

+ 11
- 11
win/winvnc/winvnc.cxx View File

@@ -106,23 +106,23 @@ static void processParams(int argc, char** argv) {

if (strcasecmp(argv[i], "-connect") == 0) {
runServer = false;
CharArray host;
const char *host = NULL;
if (i+1 < argc) {
host.buf = strDup(argv[i+1]);
host = argv[i+1];
i++;
} else {
AddNewClientDialog ancd;
if (ancd.showDialog())
host.buf = strDup(ancd.getHostName());
host = ancd.getHostName();
}
if (host.buf) {
if (host != NULL) {
HWND hwnd = FindWindow(0, "winvnc::IPC_Interface");
if (!hwnd)
throw rdr::Exception("Unable to locate existing VNC Server.");
COPYDATASTRUCT copyData;
copyData.dwData = 1; // *** AddNewClient
copyData.cbData = strlen(host.buf);
copyData.lpData = (void*)host.buf;
copyData.cbData = strlen(host);
copyData.lpData = (void*)host;
printf("Sending connect request to VNC Server...\n");
if (!SendMessage(hwnd, WM_COPYDATA, 0, (LPARAM)&copyData))
MsgBoxOrLog("Connection failed.", true);
@@ -152,12 +152,12 @@ static void processParams(int argc, char** argv) {
} else if (strcasecmp(argv[i], "-status") == 0) {
printf("Querying service status...\n");
runServer = false;
CharArray result;
std::string result;
DWORD state = rfb::win32::getServiceState(VNCServerService::Name);
result.format("The %s Service is in the %s state.",
VNCServerService::Name,
rfb::win32::serviceStateName(state));
MsgBoxOrLog(result.buf);
result = strFormat("The %s Service is in the %s state.",
VNCServerService::Name,
rfb::win32::serviceStateName(state));
MsgBoxOrLog(result.c_str());
} else if (strcasecmp(argv[i], "-service") == 0) {
printf("Run in service mode\n");
runServer = false;

Loading…
Cancel
Save