Let's use a more common type instead of something homegrown. Should be more familiar to new developers.pull/1587/head
@@ -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> |
@@ -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_) |
@@ -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; |
@@ -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) |
@@ -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"); | |||
} | |||
@@ -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"); | |||
@@ -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(); |
@@ -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; |
@@ -38,6 +38,7 @@ | |||
#endif | |||
#include <assert.h> | |||
#include <string.h> | |||
#include <sys/time.h> | |||
#ifdef __linux__ |
@@ -21,6 +21,7 @@ | |||
#endif | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include <os/Mutex.h> | |||
@@ -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; | |||
} |
@@ -257,7 +257,7 @@ namespace rfb { | |||
SSecurity* ssecurity; | |||
MethodTimer<SConnection> authFailureTimer; | |||
CharArray authFailureMsg; | |||
std::string authFailureMsg; | |||
stateEnum state_; | |||
int32_t preferredEncoding; |
@@ -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; | |||
} |
@@ -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 (...) { | |||
} | |||
} |
@@ -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]; |
@@ -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()) { |
@@ -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 |
@@ -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++; |
@@ -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; |
@@ -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; | |||
} |
@@ -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 |
@@ -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) | |||
{ |
@@ -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); |
@@ -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_; |
@@ -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; |
@@ -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; | |||
} | |||
} |
@@ -24,6 +24,8 @@ | |||
#include <config.h> | |||
#endif | |||
#include <string.h> | |||
#include <rfb/LogWriter.h> | |||
#include <x0vncserver/Geometry.h> | |||
@@ -26,6 +26,7 @@ | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <sys/types.h> | |||
#include <sys/ipc.h> |
@@ -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" | |||
@@ -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; | |||
} | |||
} |
@@ -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; |
@@ -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" |
@@ -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; | |||
} |
@@ -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); | |||
} | |||
@@ -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(); | |||
}; | |||
@@ -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); |
@@ -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; | |||
}; |
@@ -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()); | |||
@@ -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; | |||
}; | |||
@@ -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); | |||
} | |||
}; |
@@ -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 |
@@ -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; | |||
}; | |||
@@ -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 |
@@ -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); |
@@ -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; |
@@ -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; |
@@ -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) { |
@@ -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 { |
@@ -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) { |
@@ -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; | |||
} |
@@ -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; | |||
}; | |||
}; |
@@ -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(); | |||
} | |||
@@ -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; | |||
}; |
@@ -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); | |||
} | |||
@@ -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; |
@@ -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; |
@@ -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() { |
@@ -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)©Data)) | |||
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; |