void cork(bool enable) { outstream->cork(enable); }
// information about the remote end of the socket
- virtual char* getPeerAddress() = 0; // a string e.g. "192.168.0.1"
- virtual char* getPeerEndpoint() = 0; // <address>::<port>
+ virtual const char* getPeerAddress() = 0; // a string e.g. "192.168.0.1"
+ virtual const char* getPeerEndpoint() = 0; // <address>::<port>
// Was there a "?" in the ConnectionFilter used to accept this Socket?
void setRequiresQuery();
enableNagles(false);
}
-char* TcpSocket::getPeerAddress() {
+const char* TcpSocket::getPeerAddress() {
vnc_sockaddr_t sa;
socklen_t sa_size = sizeof(sa);
if (getpeername(getFd(), &sa.u.sa, &sa_size) != 0) {
vlog.error("unable to get peer name for socket");
- return rfb::strDup("");
+ return "";
}
if (sa.u.sa.sa_family == AF_INET6) {
- char buffer[INET6_ADDRSTRLEN + 2];
+ static char buffer[INET6_ADDRSTRLEN + 2];
int ret;
buffer[0] = '[';
NI_NUMERICHOST);
if (ret != 0) {
vlog.error("unable to convert peer name to a string");
- return rfb::strDup("");
+ return "";
}
strcat(buffer, "]");
- return rfb::strDup(buffer);
+ return buffer;
}
if (sa.u.sa.sa_family == AF_INET) {
name = inet_ntoa(sa.u.sin.sin_addr);
if (name == NULL) {
vlog.error("unable to convert peer name to a string");
- return rfb::strDup("");
+ return "";
}
- return rfb::strDup(name);
+ return name;
}
vlog.error("unknown address family for socket");
- return rfb::strDup("");
+ return "";
}
-char* TcpSocket::getPeerEndpoint() {
- rfb::CharArray address; address.buf = getPeerAddress();
+const char* TcpSocket::getPeerEndpoint() {
+ static char buffer[INET6_ADDRSTRLEN + 2 + 32];
vnc_sockaddr_t sa;
socklen_t sa_size = sizeof(sa);
int port;
else
port = 0;
- int buflen = strlen(address.buf) + 32;
- char* buffer = new char[buflen];
- sprintf(buffer, "%s::%d", address.buf, port);
+ sprintf(buffer, "%s::%d", getPeerAddress(), port);
+
return buffer;
}
bool
TcpFilter::verifyConnection(Socket* s) {
- rfb::CharArray name;
vnc_sockaddr_t sa;
socklen_t sa_size = sizeof(sa);
if (getpeername(s->getFd(), &sa.u.sa, &sa_size) != 0)
return false;
- name.buf = s->getPeerAddress();
std::list<TcpFilter::Pattern>::iterator i;
for (i=filter.begin(); i!=filter.end(); i++) {
if (patternMatchIP(*i, &sa)) {
switch ((*i).action) {
case Accept:
- vlog.debug("ACCEPT %s", name.buf);
+ vlog.debug("ACCEPT %s", s->getPeerAddress());
return true;
case Query:
- vlog.debug("QUERY %s", name.buf);
+ vlog.debug("QUERY %s", s->getPeerAddress());
s->setRequiresQuery();
return true;
case Reject:
- vlog.debug("REJECT %s", name.buf);
+ vlog.debug("REJECT %s", s->getPeerAddress());
return false;
}
}
}
- vlog.debug("[REJECT] %s", name.buf);
+ vlog.debug("[REJECT] %s", s->getPeerAddress());
return false;
}
TcpSocket(int sock);
TcpSocket(const char *name, int port);
- virtual char* getPeerAddress();
- virtual char* getPeerEndpoint();
+ virtual const char* getPeerAddress();
+ virtual const char* getPeerEndpoint();
protected:
bool enableNagles(bool enable);
setFd(sock);
}
-char* UnixSocket::getPeerAddress() {
- struct sockaddr_un addr;
+const char* UnixSocket::getPeerAddress() {
+ static struct sockaddr_un addr;
socklen_t salen;
// AF_UNIX only has a single address (the server side).
salen = sizeof(addr);
if (getpeername(getFd(), (struct sockaddr *)&addr, &salen) != 0) {
vlog.error("unable to get peer name for socket");
- return rfb::strDup("");
+ return "";
}
if (salen > offsetof(struct sockaddr_un, sun_path))
- return rfb::strDup(addr.sun_path);
+ return addr.sun_path;
salen = sizeof(addr);
if (getsockname(getFd(), (struct sockaddr *)&addr, &salen) != 0) {
vlog.error("unable to get local name for socket");
- return rfb::strDup("");
+ return "";
}
if (salen > offsetof(struct sockaddr_un, sun_path))
- return rfb::strDup(addr.sun_path);
+ return addr.sun_path;
// socketpair() will create unnamed sockets
- return rfb::strDup("(unnamed UNIX socket)");
+ return "(unnamed UNIX socket)";
}
-char* UnixSocket::getPeerEndpoint() {
+const char* UnixSocket::getPeerEndpoint() {
return getPeerAddress();
}
UnixSocket(int sock);
UnixSocket(const char *name);
- virtual char* getPeerAddress();
- virtual char* getPeerEndpoint();
+ virtual const char* getPeerAddress();
+ virtual const char* getPeerEndpoint();
};
class UnixListener : public SocketListener {
/* Copyright (C) 2010 TightVNC Team. All Rights Reserved.
+ * Copyright 2021-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
#ifndef WIN32
#include <pwd.h>
+#include <limits.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <shlobj.h>
#endif
-static int gethomedir(char **dirp, bool userDir)
+static const char* gethomedir(bool userDir)
{
+ static char dir[PATH_MAX];
+
#ifndef WIN32
- char *homedir, *dir;
- size_t len;
+ char *homedir;
uid_t uid;
struct passwd *passwd;
#else
- char *dir;
BOOL ret;
#endif
- assert(dirp != NULL && *dirp == NULL);
-
#ifndef WIN32
homedir = getenv("HOME");
if (homedir == NULL) {
passwd = getpwuid(uid);
if (passwd == NULL) {
/* Do we want emit error msg here? */
- return -1;
+ return NULL;
}
homedir = passwd->pw_dir;
}
- len = strlen(homedir);
- dir = new char[len+7];
- if (dir == NULL)
- return -1;
-
- memcpy(dir, homedir, len);
if (userDir)
- dir[len]='\0';
- else
- memcpy(dir + len, "/.vnc/\0", 7);
-#else
- dir = new char[MAX_PATH];
- if (dir == NULL)
- return -1;
+ return homedir;
+
+ snprintf(dir, sizeof(dir), "%s/.vnc/", homedir);
+ return dir;
+#else
if (userDir)
ret = SHGetSpecialFolderPath(NULL, dir, CSIDL_PROFILE, FALSE);
else
ret = SHGetSpecialFolderPath(NULL, dir, CSIDL_APPDATA, FALSE);
- if (ret == FALSE) {
- delete [] dir;
- return -1;
- }
+ if (ret == FALSE)
+ return NULL;
+
if (userDir)
- dir[strlen(dir)+1] = '\0';
- else
- memcpy(dir+strlen(dir), "\\vnc\\\0", 6);
+ return dir;
+
+ if (strlen(dir) + strlen("\\vnc\\") >= sizeof(dir))
+ return NULL;
+
+ strcat(dir, "\\vnc\\");
+
+ return dir;
#endif
- *dirp = dir;
- return 0;
}
-int getvnchomedir(char **dirp)
+const char* getvnchomedir()
{
- return gethomedir(dirp, false);
+ return gethomedir(false);
}
-int getuserhomedir(char **dirp)
+const char* getuserhomedir()
{
- return gethomedir(dirp, true);
+ return gethomedir(true);
}
/* Copyright (C) 2010 TightVNC Team. All Rights Reserved.
+ * Copyright 2021-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
* If HOME environment variable is set then it is used.
* Otherwise home directory is obtained via getpwuid function.
*
- * Returns:
- * 0 - Success
- * -1 - Failure
+ * Returns NULL on failure.
*/
-int getvnchomedir(char **dirp);
+const char* getvnchomedir();
/*
* Get user home directory.
* If HOME environment variable is set then it is used.
* Otherwise home directory is obtained via getpwuid function.
*
- * Returns:
- * 0 - Success
- * -1 - Failure
+ * Returns NULL on failure.
*/
-int getuserhomedir(char **dirp);
+const char* getuserhomedir();
#endif /* OS_OS_H */
static const char* homedirfn(const char* fn)
{
static char full_path[PATH_MAX];
- char* homedir = NULL;
+ const char* homedir;
- if (getvnchomedir(&homedir) == -1)
+ homedir = getvnchomedir();
+ if (homedir == NULL)
return "";
snprintf(full_path, sizeof(full_path), "%s%s", homedir, fn);
- delete [] homedir;
-
return full_path;
}
unsigned int cert_list_size = 0;
int err;
- char *homeDir;
+ const char *homeDir;
gnutls_datum_t info;
size_t len;
/* Certificate is fine, except we don't know the issuer, so TOFU time */
- homeDir = NULL;
- if (getvnchomedir(&homeDir) == -1) {
+ homeDir = getvnchomedir();
+ if (homeDir == NULL) {
throw AuthFailureException("Could not obtain VNC home directory "
"path for known hosts storage");
}
CharArray dbPath(strlen(homeDir) + 16 + 1);
sprintf(dbPath.buf, "%sx509_known_hosts", homeDir);
- delete [] homeDir;
err = gnutls_verify_stored_pubkey(dbPath.buf, NULL,
client->getServerName(), NULL,
pointerEventTime(0), clientHasCursor(false)
{
setStreams(&sock->inStream(), &sock->outStream());
- peerEndpoint.buf = sock->getPeerEndpoint();
+ peerEndpoint.buf = strDup(sock->getPeerEndpoint());
// Kick off the idle timer
if (rfb::Server::idleTimeout) {
{
// - Check the connection isn't black-marked
// *** do this in getSecurity instead?
- CharArray address(sock->getPeerAddress());
- if (blHosts->isBlackmarked(address.buf)) {
- connectionsLog.error("blacklisted: %s", address.buf);
+ const char *address = sock->getPeerAddress();
+ if (blHosts->isBlackmarked(address)) {
+ connectionsLog.error("blacklisted: %s", address);
try {
rdr::OutStream& os = sock->outStream();
return;
}
- CharArray name;
- name.buf = sock->getPeerEndpoint();
- connectionsLog.status("accepted: %s", name.buf);
+ connectionsLog.status("accepted: %s", sock->getPeerEndpoint());
// Adjust the exit timers
if (rfb::Server::maxConnectionTime && clients.empty())
const char* userName)
{
// - Authentication succeeded - clear from blacklist
- CharArray name;
- name.buf = client->getSock()->getPeerAddress();
- blHosts->clearBlackmark(name.buf);
+ blHosts->clearBlackmark(client->getSock()->getPeerAddress());
// - Prepare the desktop for that the client will start requiring
// resources after this
}
if (!fname) {
- char *homeDir = NULL;
- if (getvnchomedir(&homeDir) == -1) {
+ const char *homeDir = getvnchomedir();
+ if (homeDir == NULL) {
fprintf(stderr, "Can't obtain VNC home directory\n");
exit(1);
}
mkdir(homeDir, 0777);
fname = new char[strlen(homeDir) + 7];
sprintf(fname, "%spasswd", homeDir);
- delete [] homeDir;
}
while (true) {
queryConnectSock = sock;
- CharArray address(sock->getPeerAddress());
delete queryConnectDialog;
- queryConnectDialog = new QueryConnectDialog(dpy, address.buf,
+ queryConnectDialog = new QueryConnectDialog(dpy,
+ sock->getPeerAddress(),
userName,
queryConnectTimeout,
this);
return;
}
- queryConnectAddress.replaceBuf(sock->getPeerAddress());
+ queryConnectAddress.replaceBuf(strDup(sock->getPeerAddress()));
if (!userName)
userName = "(anonymous)";
queryConnectUsername.replaceBuf(strDup(userName));
#include <rfb/Hostname.h>
#include <rfb/LogWriter.h>
#include <rfb/Security.h>
-#include <rfb/util.h>
#include <rfb/screenTypes.h>
#include <rfb/fenceTypes.h>
#include <rfb/Timer.h>
#ifndef WIN32
if (strchr(vncServerName, '/') != NULL) {
sock = new network::UnixSocket(vncServerName);
- serverHost = sock->getPeerAddress();
+ serverHost = strDup(sock->getPeerAddress());
vlog.info(_("Connected to socket %s"), serverHost);
} else
#endif
ServerDialog *dialog = (ServerDialog*)data;
if (!dialog->usedDir)
- getuserhomedir(&(dialog->usedDir));
+ dialog->usedDir = strDup(getuserhomedir());
Fl_File_Chooser* file_chooser = new Fl_File_Chooser(dialog->usedDir, _("TigerVNC configuration (*.tigervnc)"),
0, _("Select a TigerVNC configuration file"));
const char* servername = dialog->serverName->value();
const char* filename;
if (!dialog->usedDir)
- getuserhomedir(&dialog->usedDir);
+ dialog->usedDir = strDup(getuserhomedir());
Fl_File_Chooser* file_chooser = new Fl_File_Chooser(dialog->usedDir, _("TigerVNC configuration (*.tigervnc)"),
2, _("Save the TigerVNC configuration to file"));
return;
#endif
- char* homeDir = NULL;
- if (getvnchomedir(&homeDir) == -1)
+ const char* homeDir = getvnchomedir();
+ if (homeDir == NULL)
throw Exception(_("Could not obtain the home directory path"));
char filepath[PATH_MAX];
snprintf(filepath, sizeof(filepath), "%s%s", homeDir, SERVER_HISTORY);
- delete[] homeDir;
/* Read server history from file */
FILE* f = fopen(filepath, "r");
return;
#endif
- char* homeDir = NULL;
- if (getvnchomedir(&homeDir) == -1)
+ const char* homeDir = getvnchomedir();
+ if (homeDir == NULL)
throw Exception(_("Could not obtain the home directory path"));
char filepath[PATH_MAX];
snprintf(filepath, sizeof(filepath), "%s%s", homeDir, SERVER_HISTORY);
- delete[] homeDir;
/* Write server history to file */
FILE* f = fopen(filepath, "w+");
return;
#endif
- char* homeDir = NULL;
- if (getvnchomedir(&homeDir) == -1)
+ const char* homeDir = getvnchomedir();
+ if (homeDir == NULL)
throw Exception(_("Could not obtain the home directory path"));
snprintf(filepath, sizeof(filepath), "%sdefault.tigervnc", homeDir);
- delete[] homeDir;
} else {
snprintf(filepath, sizeof(filepath), "%s", filename);
}
return loadFromReg();
#endif
- char* homeDir = NULL;
- if (getvnchomedir(&homeDir) == -1)
+ const char* homeDir = getvnchomedir();
+ if (homeDir == NULL)
throw Exception(_("Could not obtain the home directory path"));
snprintf(filepath, sizeof(filepath), "%sdefault.tigervnc", homeDir);
- delete[] homeDir;
} else {
snprintf(filepath, sizeof(filepath), "%s", filename);
}
static void mkvnchomedir()
{
// Create .vnc in the user's home directory if it doesn't already exist
- char* homeDir = NULL;
-
- if (getvnchomedir(&homeDir) == -1) {
+ const char* homeDir = getvnchomedir();
+ if (homeDir == NULL) {
vlog.error(_("Could not obtain the home directory path"));
} else {
int result = mkdir(homeDir, 0755);
if (result == -1 && errno != EEXIST)
vlog.error(_("Could not create VNC home directory: %s"), strerror(errno));
- delete [] homeDir;
}
}
throw rdr::Exception("unable to read dialog Int");
return result;
}
-char* Dialog::getItemString(int id) {
- CharArray tmp(256);
- if (!GetDlgItemText(handle, id, tmp.buf, 256))
- tmp.buf[0] = 0;
- return tmp.takeBuf();
+const char* Dialog::getItemString(int id) {
+ static char tmp[256];
+ if (!GetDlgItemText(handle, id, tmp, 256))
+ return "";
+ return tmp;
}
void Dialog::setItemChecked(int id, bool state) {
// Read the states of items
bool isItemChecked(int id);
int getItemInt(int id);
- char* getItemString(int id); // Recipient owns string storage
+ const char *getItemString(int id);
// Set the states of items
void setItemChecked(int id, bool state);
return status.dwCurrentState;
}
-char* rfb::win32::serviceStateName(DWORD state) {
+const char* rfb::win32::serviceStateName(DWORD state) {
switch (state) {
- case SERVICE_RUNNING: return strDup("Running");
- case SERVICE_STOPPED: return strDup("Stopped");
- case SERVICE_STOP_PENDING: return strDup("Stopping");
+ case SERVICE_RUNNING: return "Running";
+ case SERVICE_STOPPED: return "Stopped";
+ case SERVICE_STOP_PENDING: return "Stopping";
};
- CharArray tmp(32);
- sprintf(tmp.buf, "Unknown (%lu)", state);
- return tmp.takeBuf();
+ static char tmp[32];
+ sprintf(tmp, "Unknown (%lu)", state);
+ return tmp;
}
DWORD getServiceState(const char* name);
// -=- Convert a supplied service state value to a printable string e.g. Running, Stopped...
- // The caller must delete the returned string buffer
- char* serviceStateName(DWORD state);
+ const char* serviceStateName(DWORD state);
// -=- Routine to determine whether the host process is running a service
bool isServiceProcess();
pattern.replaceBuf(0);
}
bool onOk() {
- CharArray host(getItemString(IDC_HOST_PATTERN));
+ CharArray host(strDup(getItemString(IDC_HOST_PATTERN)));
CharArray newPat(strlen(host.buf)+2);
if (isItemChecked(IDC_ALLOW))
newPat.buf[0] = '+';
}
bool PasswordDialog::onOk() {
- PlainPasswd password1(getItemString(IDC_PASSWORD1));
- PlainPasswd password2(getItemString(IDC_PASSWORD2));
+ PlainPasswd password1(strDup(getItemString(IDC_PASSWORD1)));
+ PlainPasswd password2(strDup(getItemString(IDC_PASSWORD2)));
if (strcmp(password1.buf, password2.buf) != 0) {
MsgBox(0, "The supplied passwords do not match",
MB_ICONEXCLAMATION | MB_OK);
VNCServerWin32* s)
: Dialog(GetModuleHandle(0)),
sock(sock_), approve(false), server(s) {
- peerIp.buf = sock->getPeerAddress();
+ peerIp.buf = strDup(sock->getPeerAddress());
userName.buf = strDup(userName_);
}