aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nxcomp/ChannelEndPoint.cpp245
-rw-r--r--nxcomp/ChannelEndPoint.h61
-rw-r--r--nxcomp/ClientProxy.cpp13
-rw-r--r--nxcomp/ClientProxy.h7
-rw-r--r--nxcomp/Loop.cpp528
-rw-r--r--nxcomp/Makefile.in1
-rw-r--r--nxcomp/Proxy.cpp35
-rw-r--r--nxcomp/Proxy.h17
-rw-r--r--nxcomp/ServerProxy.cpp25
-rw-r--r--nxcomp/ServerProxy.h17
10 files changed, 634 insertions, 315 deletions
diff --git a/nxcomp/ChannelEndPoint.cpp b/nxcomp/ChannelEndPoint.cpp
new file mode 100644
index 000000000..cb35e52d2
--- /dev/null
+++ b/nxcomp/ChannelEndPoint.cpp
@@ -0,0 +1,245 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2015 Qindel Formacion y Servicios SL. */
+/* */
+/* This program is free software; you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License Version 2, as */
+/* published by the Free Software Foundation. */
+/* */
+/* This program is distributed in the hope that it will be useful, but */
+/* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTA- */
+/* BILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General */
+/* Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, you can request a copy to Qindel */
+/* or write to the Free Software Foundation, Inc., 59 Temple Place, Suite */
+/* 330, Boston, MA 02111-1307 USA */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "ChannelEndPoint.h"
+
+#include "NXalert.h"
+
+ChannelEndPoint::ChannelEndPoint(const char *spec)
+ : defaultTCPPort_(0), defaultTCPInterface_(0),
+ defaultUnixPath_(NULL) {
+ spec_ = (spec ? strdup(spec) : NULL);
+}
+
+void
+ChannelEndPoint::setSpec(const char *spec) {
+ if (spec_) free(spec_);
+
+ if (spec && strlen(spec))
+ spec_ = strdup(spec);
+ else
+ spec_ = NULL;
+}
+
+void
+ChannelEndPoint::setSpec(int port) {
+ if (port >= 0) {
+ char tmp[20];
+ sprintf(tmp, "%d", port);
+ setSpec(tmp);
+ }
+ else setSpec((char*)NULL);
+}
+
+void
+ChannelEndPoint::setDefaultTCPPort(long port) {
+ defaultTCPPort_ = port;
+}
+
+void
+ChannelEndPoint::setDefaultTCPInterface(int publicInterface) {
+ defaultTCPInterface_ = publicInterface;
+}
+
+void
+ChannelEndPoint::setDefaultUnixPath(char *path) {
+ if (defaultUnixPath_) free(defaultUnixPath_);
+
+ if (path && strlen(path))
+ defaultUnixPath_ = strdup(path);
+ else
+ defaultUnixPath_ = NULL;
+}
+
+void
+ChannelEndPoint::disable() { setSpec("0"); }
+
+bool
+ChannelEndPoint::specIsPort(long *port) const {
+ if (port) *port = 0;
+ long p = -1;
+ if (spec_) {
+ char *end;
+ p = strtol(spec_, &end, 10);
+ if ((end == spec_) || (*end != '\0'))
+ return false;
+ }
+
+ if (port) *port = p;
+ return true;
+}
+
+bool
+ChannelEndPoint::getUnixPath(char **unixPath) const {
+
+ if (unixPath) *unixPath = 0;
+
+ long p;
+ char *path = NULL;
+
+ if (specIsPort(&p)) {
+ if (p != 1) return false;
+ }
+ else if (spec_ && (strncmp("unix:", spec_, 5) == 0)) {
+ path = spec_ + 5;
+ }
+ else
+ return false;
+
+ if (!path || (*path == '\0')) {
+ path = defaultUnixPath_;
+ if (!path)
+ return false;
+ }
+
+ if (unixPath)
+ *unixPath = strdup(path);
+
+ return true;
+}
+
+// FIXME!!!
+static const char *
+getComputerName() {
+ //
+ // Strangely enough, under some Windows OSes SMB
+ // service doesn't bind to localhost. Fall back
+ // to localhost if can't find computer name in
+ // the environment. In future we should try to
+ // bind to localhost and then try the other IPs.
+ //
+
+ const char *hostname = NULL;
+
+ #ifdef __CYGWIN32__
+
+ hostname = getenv("COMPUTERNAME");
+
+ #endif
+
+ if (hostname == NULL)
+ {
+ hostname = "localhost";
+ }
+
+ return hostname;
+}
+
+bool
+ChannelEndPoint::getTCPHostAndPort(char **host, long *port) const {
+ long p;
+ char *h = NULL;
+ ssize_t h_len;
+
+ if (host) *host = NULL;
+ if (port) *port = 0;
+
+ if (specIsPort(&p)) {
+ h_len = 0;
+ }
+ else if (spec_ && (strncmp("tcp:", spec_, 4) == 0)) {
+ h = spec_ + 4;
+ char *colon = strrchr(h, ':');
+ if (colon) {
+ char *end;
+ h_len = colon++ - h;
+ p = strtol(colon, &end, 10);
+ if ((end == colon) || (*end != '\0'))
+ return false;
+ }
+ else {
+ h_len = strlen(h);
+ p = 1;
+ }
+ }
+ else
+ return false;
+
+ if (p == 1) p = defaultTCPPort_;
+ if (p < 1) return false;
+
+ if (port)
+ *port = p;
+
+ if (host)
+ *host = ( h_len
+ ? strndup(h, h_len)
+ : strdup(defaultTCPInterface_ ? getComputerName() : "localhost"));
+
+ return true;
+}
+
+bool
+ChannelEndPoint::enabled() const {
+ return (getUnixPath() || getTCPHostAndPort());
+}
+
+long ChannelEndPoint::getTCPPort() const {
+ long port;
+ if (getTCPHostAndPort(NULL, &port)) return port;
+ return -1;
+}
+
+bool
+ChannelEndPoint::validateSpec() {
+ return (specIsPort() || getUnixPath() || getTCPHostAndPort());
+}
+
+ChannelEndPoint &ChannelEndPoint::operator=(const ChannelEndPoint &other) {
+ char *old;
+ defaultTCPPort_ = other.defaultTCPPort_;
+ defaultTCPInterface_ = other.defaultTCPInterface_;
+ old = defaultUnixPath_;
+ defaultUnixPath_ = (other.defaultUnixPath_ ? strdup(other.defaultUnixPath_) : NULL);
+ free(old);
+ old = spec_;
+ spec_ = (other.spec_ ? strdup(other.spec_) : NULL);
+ free(old);
+ return *this;
+}
+
+std::ostream& operator<<(std::ostream& os, const ChannelEndPoint& endPoint) {
+ if (endPoint.enabled()) {
+ char *unixPath, *host;
+ long port;
+ if (endPoint.getUnixPath(&unixPath)) {
+ os << "unix:" << unixPath;
+ free(unixPath);
+ }
+ else if (endPoint.getTCPHostAndPort(&host, &port)) {
+ os << "tcp:" << host << ":" << port;
+ free(host);
+ }
+ else {
+ os << "(invalid)";
+ }
+ }
+ else {
+ os << "(disabled)";
+ }
+ return os;
+}
diff --git a/nxcomp/ChannelEndPoint.h b/nxcomp/ChannelEndPoint.h
new file mode 100644
index 000000000..5b4e75345
--- /dev/null
+++ b/nxcomp/ChannelEndPoint.h
@@ -0,0 +1,61 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2015 Qindel Formacion y Servicios SL. */
+/* */
+/* This program is free software; you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License Version 2, as */
+/* published by the Free Software Foundation. */
+/* */
+/* This program is distributed in the hope that it will be useful, but */
+/* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTA- */
+/* BILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General */
+/* Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, you can request a copy to Qindel */
+/* or write to the Free Software Foundation, Inc., 59 Temple Place, Suite */
+/* 330, Boston, MA 02111-1307 USA */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+#ifndef ChannelEndPoint_H
+#define ChannelEndPoint_H
+
+#include <iostream>
+#include <sys/un.h>
+
+class ChannelEndPoint
+{
+ private:
+ long defaultTCPPort_;
+ int defaultTCPInterface_; // 0=localhost, otherwise IP of public interface.
+ char *defaultUnixPath_;
+ char *spec_;
+
+ bool specIsPort(long *port = NULL) const;
+
+ public:
+ ChannelEndPoint(const char *spec = NULL);
+ ChannelEndPoint &operator=(const ChannelEndPoint &other);
+
+ bool enabled() const;
+ bool disabled() { return !enabled(); }
+ void disable();
+ void setSpec(const char *spec);
+ void setSpec(int port);
+ void setDefaultTCPPort(long port);
+ void setDefaultTCPInterface(int publicInterface);
+ void setDefaultUnixPath(char *path);
+
+ bool getUnixPath(char **path = NULL) const;
+ bool getTCPHostAndPort(char **hostname = NULL, long *port = NULL) const;
+ long getTCPPort() const;
+
+ bool validateSpec();
+};
+
+std::ostream& operator<<(std::ostream& os, const ChannelEndPoint& endPoint);
+
+#endif
diff --git a/nxcomp/ClientProxy.cpp b/nxcomp/ClientProxy.cpp
index ef63bb0eb..7dd3dbbc6 100644
--- a/nxcomp/ClientProxy.cpp
+++ b/nxcomp/ClientProxy.cpp
@@ -68,8 +68,11 @@ void ClientProxy::handleDisplayConfiguration(const char *xServerDisplay, int xSe
#endif
}
-void ClientProxy::handlePortConfiguration(int cupsServerPort, int smbServerPort, int mediaServerPort,
- int httpServerPort, const char *fontServerPort)
+void ClientProxy::handlePortConfiguration(ChannelEndPoint &cupsServerPort,
+ ChannelEndPoint &smbServerPort,
+ ChannelEndPoint &mediaServerPort,
+ ChannelEndPoint &httpServerPort,
+ const char *fontServerPort)
{
delete [] fontServerPort_;
@@ -141,8 +144,8 @@ int ClientProxy::handleNewConnectionFromProxy(T_channel_type type, int channelId
// Connect on the TCP port number.
//
- return handleNewGenericConnectionFromProxy(channelId, channel_font, "localhost",
- port, "font");
+ return handleNewGenericConnectionFromProxyTCP(channelId, channel_font, "localhost",
+ port, "font");
}
else
{
@@ -150,7 +153,7 @@ int ClientProxy::handleNewConnectionFromProxy(T_channel_type type, int channelId
// Connect to the Unix path.
//
- return handleNewGenericConnectionFromProxy(channelId, channel_font, "localhost",
+ return handleNewGenericConnectionFromProxyUnix(channelId, channel_font,
fontServerPort_, "font");
}
}
diff --git a/nxcomp/ClientProxy.h b/nxcomp/ClientProxy.h
index 88d345f00..d58fae77b 100644
--- a/nxcomp/ClientProxy.h
+++ b/nxcomp/ClientProxy.h
@@ -38,8 +38,11 @@ class ClientProxy : public Proxy
virtual void handleDisplayConfiguration(const char *xServerDisplay, int xServerAddrFamily,
sockaddr *xServerAddr, unsigned int xServerAddrLength);
- virtual void handlePortConfiguration(int cupsServerPort, int smbServerPort, int mediaServerPort,
- int httpServerPort, const char *fontServerPort);
+ virtual void handlePortConfiguration(ChannelEndPoint &cupsServerPort,
+ ChannelEndPoint &smbServerPort,
+ ChannelEndPoint &mediaServerPort,
+ ChannelEndPoint &httpServerPort,
+ const char *fontServerPort);
protected:
diff --git a/nxcomp/Loop.cpp b/nxcomp/Loop.cpp
index a60bfc9ae..97020d162 100644
--- a/nxcomp/Loop.cpp
+++ b/nxcomp/Loop.cpp
@@ -36,7 +36,7 @@
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/utsname.h>
-
+#include <sys/un.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -89,6 +89,7 @@ typedef int socklen_t;
#include "ServerProxy.h"
#include "Message.h"
+#include "ChannelEndPoint.h"
//
// System specific defines.
@@ -437,7 +438,10 @@ static int SetupDisplaySocket(int &xServerAddrFamily, sockaddr *&xServerAddr,
// a new connection.
//
-static int ListenConnection(int port, const char *label);
+static int ListenConnection(ChannelEndPoint &endPoint, const char *label);
+static int ListenConnectionTCP(const char *host, long port, const char *label);
+static int ListenConnectionUnix(const char *unixPath, const char *label);
+static int ListenConnectionAny(sockaddr *addr, socklen_t addrlen, const char *label);
static int AcceptConnection(int fd, int domain, const char *label);
//
@@ -475,6 +479,8 @@ static const char *GetArg(int &argi, int argc, const char **argv);
static int CheckArg(const char *type, const char *name, const char *value);
static int ParseArg(const char *type, const char *name, const char *value);
static int ValidateArg(const char *type, const char *name, const char *value);
+static void SetAndValidateChannelEndPointArg(const char *type, const char *name, const char *value,
+ ChannelEndPoint &endPoint);
static int LowercaseArg(const char *type, const char *name, char *value);
static int CheckSignal(int signal);
@@ -978,12 +984,12 @@ static int connectPort = -1;
// Helper channels are disabled by default.
//
-static int cupsPort = -1;
-static int auxPort = -1;
-static int smbPort = -1;
-static int mediaPort = -1;
-static int httpPort = -1;
-static int slavePort = -1;
+static ChannelEndPoint cupsPort;
+static ChannelEndPoint auxPort;
+static ChannelEndPoint smbPort;
+static ChannelEndPoint mediaPort;
+static ChannelEndPoint httpPort;
+static ChannelEndPoint slavePort;
//
// Can be either a port number or a Unix
@@ -4474,7 +4480,7 @@ int SetupServiceSockets()
// Since ProtoStep7 (#issue 108)
int port = atoi(fontPort);
- if ((fontFD = ListenConnection(port, "font")) < 0)
+ if ((fontFD = ListenConnectionTCP("localhost", port, "font")) < 0)
{
useFontSocket = 0;
}
@@ -4504,56 +4510,41 @@ int SetupServiceSockets()
return 1;
}
-int ListenConnection(int port, const char *label)
+int ListenConnectionAny(sockaddr *addr, socklen_t addrlen, const char *label)
{
- sockaddr_in tcpAddr;
-
- unsigned int portTCP = port;
-
- int newFD = socket(AF_INET, SOCK_STREAM, PF_UNSPEC);
+ int newFD = socket(addr->sa_family, SOCK_STREAM, PF_UNSPEC);
if (newFD == -1)
{
#ifdef PANIC
*logofs << "Loop: PANIC! Call to socket failed for " << label
- << " TCP socket. Error is " << EGET() << " '"
+ << " socket. Error is " << EGET() << " '"
<< ESTR() << "'.\n" << logofs_flush;
#endif
cerr << "Error" << ": Call to socket failed for " << label
- << " TCP socket. Error is " << EGET() << " '"
+ << " socket. Error is " << EGET() << " '"
<< ESTR() << "'.\n";
goto SetupSocketError;
}
- else if (SetReuseAddress(newFD) < 0)
+ if (SetReuseAddress(newFD) < 0)
{
+ // SetReuseAddress already warns with an error
goto SetupSocketError;
}
- tcpAddr.sin_family = AF_INET;
- tcpAddr.sin_port = htons(portTCP);
- if ( loopbackBind )
- {
- tcpAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- }
- else
- {
- tcpAddr.sin_addr.s_addr = htonl(INADDR_ANY);
- }
-
- if (bind(newFD, (sockaddr *) &tcpAddr, sizeof(tcpAddr)) == -1)
+ if (bind(newFD, addr, addrlen) == -1)
{
#ifdef PANIC
*logofs << "Loop: PANIC! Call to bind failed for " << label
- << " TCP port " << port << ". Error is " << EGET()
+ << ". Error is " << EGET()
<< " '" << ESTR() << "'.\n" << logofs_flush;
#endif
cerr << "Error" << ": Call to bind failed for " << label
- << " TCP port " << port << ". Error is " << EGET()
+ << ". Error is " << EGET()
<< " '" << ESTR() << "'.\n";
-
goto SetupSocketError;
}
@@ -4561,12 +4552,12 @@ int ListenConnection(int port, const char *label)
{
#ifdef PANIC
*logofs << "Loop: PANIC! Call to bind failed for " << label
- << " TCP port " << port << ". Error is " << EGET()
+ << ". Error is " << EGET()
<< " '" << ESTR() << "'.\n" << logofs_flush;
#endif
cerr << "Error" << ": Call to bind failed for " << label
- << " TCP port " << port << ". Error is " << EGET()
+ << ". Error is " << EGET()
<< " '" << ESTR() << "'.\n";
goto SetupSocketError;
@@ -4590,6 +4581,82 @@ SetupSocketError:
//
HandleCleanup();
+ return -1;
+}
+
+int ListenConnectionUnix(const char *path, const char *label)
+{
+
+ sockaddr_un unixAddr;
+ unixAddr.sun_family = AF_UNIX;
+#ifdef UNIX_PATH_MAX
+ if (strlen(path) >= UNIX_PATH_MAX)
+#else
+ if (strlen(path) >= sizeof(unixAddr.sun_path))
+#endif
+ {
+ #ifdef PANIC
+ *logofs << "Loop: PANIC! Socket path \"" << path << "\" for "
+ << label << " is too long.\n" << logofs_flush;
+ #endif
+
+ cerr << "Error" << ": Socket path \"" << path << "\" for "
+ << label << " is too long.\n";
+
+ HandleCleanup();
+ return -1;
+ }
+
+ strcpy(unixAddr.sun_path, path);
+ return ListenConnectionAny((sockaddr *)&unixAddr, sizeof(unixAddr), label);
+}
+
+int ListenConnectionTCP(const char *host, long port, const char *label)
+{
+ sockaddr_in tcpAddr;
+ tcpAddr.sin_family = AF_INET;
+ tcpAddr.sin_port = htons(port);
+
+ if (loopbackBind ||
+ !host ||
+ !strcmp(host, "") ||
+ !strcmp(host, "localhost")) {
+ tcpAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ }
+ else if(strcmp(host, "*") == 0) {
+ tcpAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ }
+ else {
+ int ip = tcpAddr.sin_addr.s_addr = GetHostAddress(host);
+ if (ip == 0)
+ {
+ #ifdef PANIC
+ *logofs << "Loop: PANIC! Unknown " << label << " host '" << host
+ << "'.\n" << logofs_flush;
+ #endif
+
+ cerr << "Error" << ": Unknown " << label << " host '" << host
+ << "'.\n";
+
+ HandleCleanup();
+ return -1;
+ }
+ }
+
+ return ListenConnectionAny((sockaddr *)&tcpAddr, sizeof(tcpAddr), label);
+}
+
+int ListenConnection(ChannelEndPoint &endpoint, const char *label)
+{
+ char *unixPath, *host;
+ long port;
+ if (endpoint.getUnixPath(&unixPath)) {
+ return ListenConnectionUnix(unixPath, label);
+ }
+ else if (endpoint.getTCPHostAndPort(&host, &port)) {
+ return ListenConnectionTCP(host, port, label);
+ }
+ return -1;
}
static int AcceptConnection(int fd, int domain, const char *label)
@@ -5521,12 +5588,12 @@ void CleanupLocal()
listenPort = -1;
connectPort = -1;
- cupsPort = -1;
- auxPort = -1;
- smbPort = -1;
- mediaPort = -1;
- httpPort = -1;
- slavePort = -1;
+ cupsPort.disable();
+ auxPort.disable();
+ smbPort.disable();
+ mediaPort.disable();
+ httpPort.disable();
+ slavePort.disable();
*fontPort = '\0';
@@ -8070,6 +8137,35 @@ int ReadRemoteData(int fd, char *buffer, int size, char stop)
return -1;
}
+static int
+hexval(char c) {
+ if ((c >= '0') && (c <= '9'))
+ return c - '0';
+ if ((c >= 'a') && (c <= 'f'))
+ return c - 'a' + 10;
+ if ((c >= 'A') && (c <= 'F'))
+ return c - 'A' + 10;
+ return -1;
+}
+
+static void
+URLDecodeInPlace(char *str) {
+ if (str) {
+ char *to = str;
+ while (str[0]) {
+ if ((str[0] == '%') &&
+ (hexval(str[1]) >= 0) &&
+ (hexval(str[2]) >= 0)) {
+ *(to++) = hexval(str[1]) * 16 + hexval(str[2]);
+ str += 3;
+ }
+ else
+ *(to++) = *(str++);
+ }
+ *to = '\0';
+ }
+}
+
int WriteLocalData(int fd, const char *buffer, int size)
{
int position = 0;
@@ -8357,6 +8453,7 @@ int ParseEnvironmentOptions(const char *env, int force)
while (name)
{
value = strtok(NULL, ",");
+ URLDecodeInPlace(value);
if (CheckArg("environment", name, value) < 0)
{
@@ -8750,7 +8847,7 @@ int ParseEnvironmentOptions(const char *env, int force)
}
else if (strcasecmp(name, "cups") == 0)
{
- cupsPort = ValidateArg("local", name, value);
+ SetAndValidateChannelEndPointArg("local", name, value, cupsPort);
}
else if (strcasecmp(name, "sync") == 0)
{
@@ -8762,25 +8859,25 @@ int ParseEnvironmentOptions(const char *env, int force)
cerr << "Warning" << ": No 'sync' channel in current version. "
<< "Assuming 'cups' channel.\n";
- cupsPort = ValidateArg("local", name, value);
+ SetAndValidateChannelEndPointArg("local", name, value, cupsPort);
}
else if (strcasecmp(name, "keybd") == 0 ||
strcasecmp(name, "aux") == 0)
{
- auxPort = ValidateArg("local", name, value);
+ SetAndValidateChannelEndPointArg("local", name, value, auxPort);
}
else if (strcasecmp(name, "samba") == 0 ||
strcasecmp(name, "smb") == 0)
{
- smbPort = ValidateArg("local", name, value);
+ SetAndValidateChannelEndPointArg("local", name, value, smbPort);
}
else if (strcasecmp(name, "media") == 0)
{
- mediaPort = ValidateArg("local", name, value);
+ SetAndValidateChannelEndPointArg("local", name, value, mediaPort);
}
else if (strcasecmp(name, "http") == 0)
{
- httpPort = ValidateArg("local", name, value);
+ SetAndValidateChannelEndPointArg("local", name, value, httpPort);
}
else if (strcasecmp(name, "font") == 0)
{
@@ -8788,7 +8885,7 @@ int ParseEnvironmentOptions(const char *env, int force)
}
else if (strcasecmp(name, "slave") == 0)
{
- slavePort = ValidateArg("local", name, value);
+ SetAndValidateChannelEndPointArg("local", name, value, slavePort);
}
else if (strcasecmp(name, "mask") == 0)
{
@@ -11515,237 +11612,105 @@ int SetPorts()
// ing, causing a loop.
//
- if (cupsPort <= 0)
- {
- #ifdef TEST
- *logofs << "Loop: Disabling cups connections.\n"
- << logofs_flush;
- #endif
-
- cupsPort = 0;
-
- useCupsSocket = 0;
- }
- else
- {
- if (control -> ProxyMode == proxy_client)
- {
- if (cupsPort == 1)
- {
- cupsPort = DEFAULT_NX_CUPS_PORT_OFFSET + proxyPort;
- }
-
+ useCupsSocket = 0;
+ if (cupsPort.enabled()) {
+ if (control -> ProxyMode == proxy_client) {
+ cupsPort.setDefaultTCPPort(DEFAULT_NX_CUPS_PORT_OFFSET + proxyPort);
useCupsSocket = 1;
}
else
- {
- if (cupsPort == 1)
- {
- //
- // Use the well-known 631/tcp port of the
- // Internet Printing Protocol.
- //
-
- cupsPort = 631;
- }
-
- useCupsSocket = 0;
- }
-
- #ifdef TEST
- *logofs << "Loop: Using cups port '" << cupsPort
- << "'.\n" << logofs_flush;
- #endif
+ cupsPort.setDefaultTCPPort(631);
}
- if (auxPort <= 0)
- {
- #ifdef TEST
- *logofs << "Loop: Disabling auxiliary X11 connections.\n"
+#ifdef TEST
+ *logofs << "Loop: cups port: " << cupsPort->getDebugSpec() << "\n"
<< logofs_flush;
- #endif
-
- auxPort = 0;
-
- useAuxSocket = 0;
- }
- else
- {
- if (control -> ProxyMode == proxy_client)
- {
- if (auxPort == 1)
- {
- auxPort = DEFAULT_NX_AUX_PORT_OFFSET + proxyPort;
- }
+#endif
+ useAuxSocket = 0;
+ if (auxPort.enabled()) {
+ if (control -> ProxyMode == proxy_client) {
+ auxPort.setDefaultTCPPort(DEFAULT_NX_AUX_PORT_OFFSET + proxyPort);
useAuxSocket = 1;
}
- else
- {
- //
- // Auxiliary X connections are always forwarded
- // to the display where the session is running.
- // The only value accepted is 1.
- //
+ else {
+ auxPort.setDefaultTCPPort(1);
- if (auxPort != 1)
- {
- #ifdef WARNING
+ if (auxPort.getTCPPort() != 1) {
+
+#ifdef WARNING
*logofs << "Loop: WARNING! Overriding auxiliary X11 "
<< "port with new value '" << 1 << "'.\n"
<< logofs_flush;
- #endif
+#endif
cerr << "Warning" << ": Overriding auxiliary X11 "
<< "port with new value '" << 1 << "'.\n";
- auxPort = 1;
+ auxPort.setSpec("1");
}
-
- useAuxSocket = 0;
}
-
- #ifdef TEST
- *logofs << "Loop: Using auxiliary X11 port '" << auxPort
- << "'.\n" << logofs_flush;
- #endif
}
- if (smbPort <= 0)
- {
- #ifdef TEST
- *logofs << "Loop: Disabling SMB connections.\n"
- << logofs_flush;
- #endif
-
- smbPort = 0;
-
- useSmbSocket = 0;
- }
- else
- {
- if (control -> ProxyMode == proxy_client)
- {
- if (smbPort == 1)
- {
- smbPort = DEFAULT_NX_SMB_PORT_OFFSET + proxyPort;
- }
+#ifdef TEST
+ *logofs << "Loop: aux port: " << auxPort->getDebugSpec() << "\n"
+ << logofs_flush;
+#endif
- useSmbSocket = 1;
+ useSmbSocket = 0;
+ if (smbPort.enabled()) {
+ if (control -> ProxyMode == proxy_client) {
+ auxPort.setDefaultTCPPort(DEFAULT_NX_SMB_PORT_OFFSET + proxyPort);
+ useAuxSocket = 1;
}
else
- {
- if (smbPort == 1)
- {
- //
- // Assume the 139/tcp port used for SMB
- // over NetBIOS over TCP.
- //
-
- smbPort = 139;
- }
-
- useSmbSocket = 0;
- }
-
- #ifdef TEST
- *logofs << "Loop: Using SMB port '" << smbPort
- << "'.\n" << logofs_flush;
- #endif
+ auxPort.setDefaultTCPPort(139);
}
- if (mediaPort <= 0)
- {
- #ifdef TEST
- *logofs << "Loop: Disabling multimedia connections.\n"
- << logofs_flush;
- #endif
-
- mediaPort = 0;
- useMediaSocket = 0;
- }
- else
- {
- if (control -> ProxyMode == proxy_client)
- {
- if (mediaPort == 1)
- {
- mediaPort = DEFAULT_NX_MEDIA_PORT_OFFSET + proxyPort;
- }
+#ifdef TEST
+ *logofs << "Loop: smb port: " << smbPort->getDebugSpec() << "\n"
+ << logofs_flush;
+#endif
+ useMediaSocket = 0;
+ if (mediaPort.enabled()) {
+ if (control -> ProxyMode == proxy_client) {
+ mediaPort.setDefaultTCPPort(DEFAULT_NX_MEDIA_PORT_OFFSET + proxyPort);
useMediaSocket = 1;
}
- else
- {
- if (mediaPort == 1)
- {
- //
- // We don't have a well-known port to
- // be used for media connections.
- //
-
- #ifdef PANIC
- *logofs << "Loop: PANIC! No port specified for multimedia connections.\n"
- << logofs_flush;
- #endif
+ else if (mediaPort.getTCPPort() == 1) {
+#ifdef PANIC
+ *logofs << "Loop: PANIC! No port specified for multimedia connections.\n"
+ << logofs_flush;
+#endif
- cerr << "Error" << ": No port specified for multimedia connections.\n";
+ cerr << "Error" << ": No port specified for multimedia connections.\n";
- HandleCleanup();
- }
-
- useMediaSocket = 0;
+ HandleCleanup();
}
-
- #ifdef TEST
- *logofs << "Loop: Using multimedia port '" << mediaPort
- << "'.\n" << logofs_flush;
- #endif
}
- if (httpPort <= 0)
- {
- #ifdef TEST
- *logofs << "Loop: Disabling HTTP connections.\n"
- << logofs_flush;
- #endif
-
- httpPort = 0;
-
- useHttpSocket = 0;
- }
- else
- {
- if (control -> ProxyMode == proxy_client)
- {
- if (httpPort == 1)
- {
- httpPort = DEFAULT_NX_HTTP_PORT_OFFSET + proxyPort;
- }
+#ifdef TEST
+ *logofs << "Loop: Using multimedia port '" << mediaPort->getDebugSpec()
+ << "'.\n" << logofs_flush;
+#endif
+ useHttpSocket = 0;
+ if (httpPort.enabled()) {
+ if (control -> ProxyMode == proxy_client) {
+ httpPort.setDefaultTCPPort(DEFAULT_NX_HTTP_PORT_OFFSET + proxyPort);
useHttpSocket = 1;
}
else
- {
- if (httpPort == 1)
- {
- //
- // Use the well-known 80/tcp port.
- //
-
- httpPort = 80;
- }
-
- useHttpSocket = 0;
- }
-
- #ifdef TEST
- *logofs << "Loop: Using HTTP port '" << httpPort
- << "'.\n" << logofs_flush;
- #endif
+ httpPort.setDefaultTCPPort(80);
}
+#ifdef TEST
+ *logofs << "Loop: Using HTTP port '" << httpPort->getDebugSpec()
+ << "'.\n" << logofs_flush;
+#endif
+
if (ParseFontPath(fontPort) <= 0)
{
#ifdef TEST
@@ -11781,44 +11746,20 @@ int SetPorts()
#endif
}
- if (slavePort <= 0)
- {
- #ifdef TEST
- *logofs << "Loop: Disabling slave connections.\n"
- << logofs_flush;
- #endif
-
- slavePort = 0;
-
- useSlaveSocket = 0;
- }
- else
- {
- //
- // File transfer connections can
- // be originated by both sides.
- //
-
- if (slavePort == 1)
- {
- if (control -> ProxyMode == proxy_client)
- {
- slavePort = DEFAULT_NX_SLAVE_PORT_CLIENT_OFFSET + proxyPort;
- }
- else
- {
- slavePort = DEFAULT_NX_SLAVE_PORT_SERVER_OFFSET + proxyPort;
- }
- }
-
+ useSlaveSocket = 0;
+ if (slavePort.enabled()) {
useSlaveSocket = 1;
-
- #ifdef TEST
- *logofs << "Loop: Using slave port '" << slavePort
- << "'.\n" << logofs_flush;
- #endif
+ if (control -> ProxyMode == proxy_client)
+ slavePort.setDefaultTCPPort(DEFAULT_NX_SLAVE_PORT_CLIENT_OFFSET + proxyPort);
+ else
+ slavePort.setDefaultTCPPort(DEFAULT_NX_SLAVE_PORT_SERVER_OFFSET + proxyPort);
}
+#ifdef TEST
+ *logofs << "Loop: Using slave port '" << slavePort->getDebugSpec()
+ << "'.\n" << logofs_flush;
+#endif
+
return 1;
}
@@ -14109,65 +14050,65 @@ void PrintConnectionInfo()
}
if (control -> ProxyMode == proxy_client &&
- useCupsSocket > 0 && cupsPort > 0)
+ useCupsSocket > 0 && cupsPort.enabled())
{
cerr << "Info" << ": Listening to CUPS connections "
<< "on port '" << cupsPort << "'.\n";
}
else if (control -> ProxyMode == proxy_server &&
- cupsPort > 0)
+ cupsPort.enabled())
{
cerr << "Info" << ": Forwarding CUPS connections "
<< "to port '" << cupsPort << "'.\n";
}
if (control -> ProxyMode == proxy_client &&
- useAuxSocket > 0 && auxPort > 0)
+ useAuxSocket > 0 && auxPort.enabled())
{
cerr << "Info" << ": Listening to auxiliary X11 connections "
<< "on port '" << auxPort << "'.\n";
}
else if (control -> ProxyMode == proxy_server &&
- auxPort > 0)
+ auxPort.enabled())
{
cerr << "Info" << ": Forwarding auxiliary X11 connections "
<< "to display '" << displayHost << "'.\n";
}
if (control -> ProxyMode == proxy_client &&
- useSmbSocket > 0 && smbPort > 0)
+ useSmbSocket > 0 && smbPort.enabled())
{
cerr << "Info" << ": Listening to SMB connections "
<< "on port '" << smbPort << "'.\n";
}
else if (control -> ProxyMode == proxy_server &&
- smbPort > 0)
+ smbPort.enabled())
{
cerr << "Info" << ": Forwarding SMB connections "
<< "to port '" << smbPort << "'.\n";
}
if (control -> ProxyMode == proxy_client &&
- useMediaSocket > 0 && mediaPort > 0)
+ useMediaSocket > 0 && mediaPort.enabled())
{
cerr << "Info" << ": Listening to multimedia connections "
<< "on port '" << mediaPort << "'.\n";
}
else if (control -> ProxyMode == proxy_server &&
- mediaPort > 0)
+ mediaPort.enabled())
{
cerr << "Info" << ": Forwarding multimedia connections "
<< "to port '" << mediaPort << "'.\n";
}
if (control -> ProxyMode == proxy_client &&
- useHttpSocket > 0 && httpPort > 0)
+ useHttpSocket > 0 && httpPort.enabled())
{
cerr << "Info" << ": Listening to HTTP connections "
<< "on port '" << httpPort << "'.\n";
}
else if (control -> ProxyMode == proxy_server &&
- httpPort > 0)
+ httpPort.enabled())
{
cerr << "Info" << ": Forwarding HTTP connections "
<< "to port '" << httpPort << "'.\n";
@@ -14186,7 +14127,7 @@ void PrintConnectionInfo()
<< "to port '" << fontPort << "'.\n";
}
- if (useSlaveSocket > 0 && slavePort > 0)
+ if (useSlaveSocket > 0 && slavePort.enabled())
{
cerr << "Info" << ": Listening to slave connections "
<< "on port '" << slavePort << "'.\n";
@@ -14443,6 +14384,25 @@ int ParseArg(const char *type, const char *name, const char *value)
return (int) result;
}
+void SetAndValidateChannelEndPointArg(const char *type, const char *name, const char *value,
+ ChannelEndPoint &endPoint) {
+ endPoint.setSpec(value);
+ if (!endPoint.validateSpec()) {
+ #ifdef PANIC
+ *logofs << "Loop: PANIC! Invalid " << type
+ << " option '" << name << "' with value '"
+ << value << "'.\n" << logofs_flush;
+ #endif
+
+ cerr << "Error" << ": Invalid " << type
+ << " option '" << name << "' with value '"
+ << value << "'.\n";
+
+ HandleCleanup();
+ }
+}
+
+
int ValidateArg(const char *type, const char *name, const char *value)
{
int number = atoi(value);
diff --git a/nxcomp/Makefile.in b/nxcomp/Makefile.in
index c2cdceead..8fc37407f 100644
--- a/nxcomp/Makefile.in
+++ b/nxcomp/Makefile.in
@@ -149,6 +149,7 @@ CXXSRC = Loop.cpp \
ClientChannel.cpp \
ServerChannel.cpp \
GenericChannel.cpp \
+ ChannelEndPoint.cpp \
ReadBuffer.cpp \
ProxyReadBuffer.cpp \
ClientReadBuffer.cpp \
diff --git a/nxcomp/Proxy.cpp b/nxcomp/Proxy.cpp
index 7655ccb40..1693590db 100644
--- a/nxcomp/Proxy.cpp
+++ b/nxcomp/Proxy.cpp
@@ -65,6 +65,7 @@ struct sockaddr_un
#include "ClientChannel.h"
#include "ServerChannel.h"
#include "GenericChannel.h"
+#include "ChannelEndPoint.h"
//
// We need to adjust some values related
@@ -6053,8 +6054,36 @@ int Proxy::handleNewSlaveConnection(int clientFd)
return handleNewGenericConnection(clientFd, channel_slave, "slave");
}
+
+
int Proxy::handleNewGenericConnectionFromProxy(int channelId, T_channel_type type,
- const char *hostname, int port, const char *label)
+ ChannelEndPoint &endPoint, const char *label)
+{
+ char *unixPath, *host;
+ long port;
+
+ if (endPoint.getUnixPath(&unixPath)) {
+ return handleNewGenericConnectionFromProxyUnix(channelId, type, unixPath, label);
+ }
+
+ if (endPoint.getTCPHostAndPort(&host, &port)) {
+ return handleNewGenericConnectionFromProxyTCP(channelId, type, host, port, label);
+ }
+
+ #ifdef WARNING
+ *logofs << "Proxy: WARNING! Refusing attempted connection "
+ << "to " << label << " server.\n" << logofs_flush;
+ #endif
+
+ cerr << "Warning" << ": Refusing attempted connection "
+ << "to " << label << " server.\n";
+
+ return -1;
+}
+
+int Proxy::handleNewGenericConnectionFromProxyTCP(int channelId, T_channel_type type,
+ const char *hostname, long port, const char *label)
+
{
if (port <= 0)
{
@@ -6173,8 +6202,8 @@ int Proxy::handleNewGenericConnectionFromProxy(int channelId, T_channel_type typ
return 1;
}
-int Proxy::handleNewGenericConnectionFromProxy(int channelId, T_channel_type type,
- const char *hostname, const char *path, const char *label)
+int Proxy::handleNewGenericConnectionFromProxyUnix(int channelId, T_channel_type type,
+ const char *path, const char *label)
{
if (path == NULL || *path == '\0' )
{
diff --git a/nxcomp/Proxy.h b/nxcomp/Proxy.h
index c0fdfcce9..87ea1ce8a 100644
--- a/nxcomp/Proxy.h
+++ b/nxcomp/Proxy.h
@@ -32,6 +32,7 @@
#include "Transport.h"
#include "EncodeBuffer.h"
#include "ProxyReadBuffer.h"
+#include "ChannelEndPoint.h"
//
// Forward declaration as we
@@ -258,8 +259,11 @@ class Proxy
virtual void handleDisplayConfiguration(const char *xServerDisplay, int xServerAddrFamily,
sockaddr * xServerAddr, unsigned int xServerAddrLength) = 0;
- virtual void handlePortConfiguration(int cupsServerPort, int smbServerPort, int mediaServerPort,
- int httpServerPort, const char *fontServerPort) = 0;
+ virtual void handlePortConfiguration(ChannelEndPoint &cupsServerPort,
+ ChannelEndPoint &smbServerPort,
+ ChannelEndPoint &mediaServerPort,
+ ChannelEndPoint &httpServerPort,
+ const char *fontServerPort) = 0;
//
// Create new tunneled channels.
@@ -278,10 +282,13 @@ class Proxy
int handleNewGenericConnection(int clientFd, T_channel_type type, const char *label);
int handleNewGenericConnectionFromProxy(int channelId, T_channel_type type,
- const char *hostname, int port, const char *label);
+ ChannelEndPoint &endpoint, const char *label);
- int handleNewGenericConnectionFromProxy(int channelId, T_channel_type type,
- const char *hostname, const char *path, const char *label);
+ int handleNewGenericConnectionFromProxyUnix(int channelId, T_channel_type type,
+ const char *path, const char *label);
+
+ int handleNewGenericConnectionFromProxyTCP(int channelId, T_channel_type type,
+ const char *hostname, long port, const char *label);
int handleNewSlaveConnection(int clientFd);
diff --git a/nxcomp/ServerProxy.cpp b/nxcomp/ServerProxy.cpp
index 0a72fc301..3060e829d 100644
--- a/nxcomp/ServerProxy.cpp
+++ b/nxcomp/ServerProxy.cpp
@@ -1,6 +1,7 @@
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2011 NoMachine, http://www.nomachine.com/. */
+/* Copyright (c) 2015 Qindel Formacion y Servicios S.L. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
@@ -51,10 +52,10 @@ ServerProxy::ServerProxy(int proxyFd) : Proxy(proxyFd)
xServerAddr_ = NULL;
xServerDisplay_ = NULL;
- cupsServerPort_ = -1;
- smbServerPort_ = -1;
- mediaServerPort_ = -1;
- httpServerPort_ = -1;
+ cupsServerPort_ = NULL;
+ smbServerPort_ = NULL;
+ mediaServerPort_ = NULL;
+ httpServerPort_ = NULL;
fontServerPort_ = NULL;
@@ -101,8 +102,11 @@ void ServerProxy::handleDisplayConfiguration(const char *xServerDisplay, int xSe
#endif
}
-void ServerProxy::handlePortConfiguration(int cupsServerPort, int smbServerPort, int mediaServerPort,
- int httpServerPort, const char *fontServerPort)
+void ServerProxy::handlePortConfiguration(ChannelEndPoint &cupsServerPort,
+ ChannelEndPoint &smbServerPort,
+ ChannelEndPoint &mediaServerPort,
+ ChannelEndPoint &httpServerPort,
+ const char *fontServerPort)
{
cupsServerPort_ = cupsServerPort;
smbServerPort_ = smbServerPort;
@@ -161,22 +165,23 @@ int ServerProxy::handleNewConnectionFromProxy(T_channel_type type, int channelId
}
case channel_cups:
{
- return handleNewGenericConnectionFromProxy(channelId, channel_cups, "localhost",
+ return handleNewGenericConnectionFromProxy(channelId, channel_cups,
cupsServerPort_, "CUPS");
}
case channel_smb:
{
- return handleNewGenericConnectionFromProxy(channelId, channel_smb, getComputerName(),
+ smbServerPort_.setDefaultTCPInterface(1);
+ return handleNewGenericConnectionFromProxy(channelId, channel_smb,
smbServerPort_, "SMB");
}
case channel_media:
{
- return handleNewGenericConnectionFromProxy(channelId, channel_media, "localhost",
+ return handleNewGenericConnectionFromProxy(channelId, channel_media,
mediaServerPort_, "media");
}
case channel_http:
{
- return handleNewGenericConnectionFromProxy(channelId, channel_http, getComputerName(),
+ return handleNewGenericConnectionFromProxy(channelId, channel_http,
httpServerPort_, "HTTP");
}
case channel_slave:
diff --git a/nxcomp/ServerProxy.h b/nxcomp/ServerProxy.h
index 54bc0f748..cc8191795 100644
--- a/nxcomp/ServerProxy.h
+++ b/nxcomp/ServerProxy.h
@@ -24,6 +24,7 @@
#include "Proxy.h"
#include "Misc.h"
+#include "ChannelEndPoint.h"
//
// Set the verbosity level.
@@ -43,8 +44,11 @@ class ServerProxy : public Proxy
virtual void handleDisplayConfiguration(const char *xServerDisplay, int xServerAddrFamily,
sockaddr *xServerAddr, unsigned int xServerAddrLength);
- virtual void handlePortConfiguration(int cupsServerPort, int smbServerPort, int mediaServerPort,
- int httpServerPort, const char *fontServerPort);
+ virtual void handlePortConfiguration(ChannelEndPoint &cupsServerPort,
+ ChannelEndPoint &smbServerPort,
+ ChannelEndPoint &mediaServerPort,
+ ChannelEndPoint &httpServerPort,
+ const char *fontServerPort);
protected:
@@ -108,6 +112,7 @@ class ServerProxy : public Proxy
private:
+ // FIXME: Use a ChannelEndPoint object also for the X server!
int xServerAddrFamily_;
sockaddr *xServerAddr_;
unsigned int xServerAddrLength_;
@@ -124,10 +129,10 @@ class ServerProxy : public Proxy
// TCP connections.
//
- int cupsServerPort_;
- int smbServerPort_;
- int mediaServerPort_;
- int httpServerPort_;
+ ChannelEndPoint cupsServerPort_;
+ ChannelEndPoint smbServerPort_;
+ ChannelEndPoint mediaServerPort_;
+ ChannelEndPoint httpServerPort_;
//
// It will have to be passed to the channel