Commit 3713346f authored by Salvador Fandino's avatar Salvador Fandino Committed by Mike Gabriel

Provide support for channel endpoints being UNIX file sockets in addition to being TCP/IP sockets.

parent b326eda7
/**************************************************************************/
/* */
/* 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;
}
/**************************************************************************/
/* */
/* 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
......@@ -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");
}
}
......
......@@ -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:
......
......@@ -149,6 +149,7 @@ CXXSRC = Loop.cpp \
ClientChannel.cpp \
ServerChannel.cpp \
GenericChannel.cpp \
ChannelEndPoint.cpp \
ReadBuffer.cpp \
ProxyReadBuffer.cpp \
ClientReadBuffer.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' )
{
......
......@@ -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);
......
/**************************************************************************/
/* */
/* 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:
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment