mirror of
https://github.com/kasmtech/KasmVNC.git
synced 2024-11-25 01:24:04 +01:00
Add support for relaying unix sockets
This commit is contained in:
parent
61613c4e65
commit
3bae812364
@ -88,6 +88,9 @@ namespace rfb {
|
|||||||
|
|
||||||
virtual void clearLocalClipboards() {}
|
virtual void clearLocalClipboards() {}
|
||||||
|
|
||||||
|
virtual void receivedUnixRelayData(const char name[], const unsigned char *buf,
|
||||||
|
const unsigned len) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~SDesktop() {}
|
virtual ~SDesktop() {}
|
||||||
};
|
};
|
||||||
|
@ -98,6 +98,9 @@ namespace rfb {
|
|||||||
virtual void udpUpgrade(const char *resp) = 0;
|
virtual void udpUpgrade(const char *resp) = 0;
|
||||||
virtual void udpDowngrade(const bool) = 0;
|
virtual void udpDowngrade(const bool) = 0;
|
||||||
|
|
||||||
|
virtual void subscribeUnixRelay(const char *name) = 0;
|
||||||
|
virtual void unixRelay(const char *name, const rdr::U8 *buf, const unsigned len) = 0;
|
||||||
|
|
||||||
ConnParams cp;
|
ConnParams cp;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,12 @@ void SMsgReader::readMsg()
|
|||||||
case msgTypeUpgradeToUdp:
|
case msgTypeUpgradeToUdp:
|
||||||
readUpgradeToUdp();
|
readUpgradeToUdp();
|
||||||
break;
|
break;
|
||||||
|
case msgTypeSubscribeUnixRelay:
|
||||||
|
readSubscribeUnixRelay();
|
||||||
|
break;
|
||||||
|
case msgTypeUnixRelay:
|
||||||
|
readUnixRelay();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "unknown message type %d\n", msgType);
|
fprintf(stderr, "unknown message type %d\n", msgType);
|
||||||
throw Exception("unknown message type");
|
throw Exception("unknown message type");
|
||||||
@ -357,3 +363,42 @@ void SMsgReader::readUpgradeToUdp()
|
|||||||
|
|
||||||
handler->udpUpgrade(resp);
|
handler->udpUpgrade(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SMsgReader::readSubscribeUnixRelay()
|
||||||
|
{
|
||||||
|
const rdr::U8 namelen = is->readU8();
|
||||||
|
char name[64];
|
||||||
|
if (namelen >= sizeof(name)) {
|
||||||
|
vlog.error("Ignoring subscribe with too large name");
|
||||||
|
is->skip(namelen);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
is->readBytes(name, namelen);
|
||||||
|
name[namelen] = '\0';
|
||||||
|
|
||||||
|
handler->subscribeUnixRelay(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMsgReader::readUnixRelay()
|
||||||
|
{
|
||||||
|
const rdr::U8 namelen = is->readU8();
|
||||||
|
char name[64];
|
||||||
|
if (namelen >= sizeof(name)) {
|
||||||
|
vlog.error("Ignoring relay packet with too large name");
|
||||||
|
is->skip(namelen);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
is->readBytes(name, namelen);
|
||||||
|
name[namelen] = '\0';
|
||||||
|
|
||||||
|
const rdr::U32 len = is->readU32();
|
||||||
|
rdr::U8 buf[1024 * 1024];
|
||||||
|
if (len >= sizeof(buf)) {
|
||||||
|
vlog.error("Ignoring relay packet with too large data");
|
||||||
|
is->skip(len);
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
is->readBytes(buf, len);
|
||||||
|
|
||||||
|
handler->unixRelay(name, buf, len);
|
||||||
|
}
|
||||||
|
@ -65,6 +65,9 @@ namespace rfb {
|
|||||||
|
|
||||||
void readUpgradeToUdp();
|
void readUpgradeToUdp();
|
||||||
|
|
||||||
|
void readSubscribeUnixRelay();
|
||||||
|
void readUnixRelay();
|
||||||
|
|
||||||
SMsgHandler* handler;
|
SMsgHandler* handler;
|
||||||
rdr::InStream* is;
|
rdr::InStream* is;
|
||||||
};
|
};
|
||||||
|
@ -749,3 +749,29 @@ void SMsgWriter::writeUdpUpgrade(const char *resp)
|
|||||||
|
|
||||||
endMsg();
|
endMsg();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SMsgWriter::writeSubscribeUnixRelay(const bool success, const char *msg)
|
||||||
|
{
|
||||||
|
startMsg(msgTypeSubscribeUnixRelay);
|
||||||
|
|
||||||
|
const rdr::U8 len = strlen(msg);
|
||||||
|
os->writeU8(success);
|
||||||
|
os->writeU8(len);
|
||||||
|
os->writeBytes(msg, len);
|
||||||
|
|
||||||
|
endMsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMsgWriter::writeUnixRelay(const char *name, const rdr::U8 *buf, const unsigned len)
|
||||||
|
{
|
||||||
|
startMsg(msgTypeUnixRelay);
|
||||||
|
|
||||||
|
const rdr::U8 namelen = strlen(name);
|
||||||
|
os->writeU8(namelen);
|
||||||
|
os->writeBytes(name, namelen);
|
||||||
|
|
||||||
|
os->writeU32(len);
|
||||||
|
os->writeBytes(buf, len);
|
||||||
|
|
||||||
|
endMsg();
|
||||||
|
}
|
||||||
|
@ -129,6 +129,9 @@ namespace rfb {
|
|||||||
|
|
||||||
void writeUdpUpgrade(const char *resp);
|
void writeUdpUpgrade(const char *resp);
|
||||||
|
|
||||||
|
void writeSubscribeUnixRelay(const bool success, const char *msg);
|
||||||
|
void writeUnixRelay(const char *name, const rdr::U8 *buf, const unsigned len);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void startMsg(int type);
|
void startMsg(int type);
|
||||||
void endMsg();
|
void endMsg();
|
||||||
|
@ -51,6 +51,8 @@ static Cursor emptyCursor(0, 0, Point(0, 0), NULL);
|
|||||||
|
|
||||||
extern rfb::BoolParameter disablebasicauth;
|
extern rfb::BoolParameter disablebasicauth;
|
||||||
|
|
||||||
|
extern "C" char unixrelaynames[MAX_UNIX_RELAYS][MAX_UNIX_RELAY_NAME_LEN];
|
||||||
|
|
||||||
VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
|
VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
|
||||||
bool reverse)
|
bool reverse)
|
||||||
: upgradingToUdp(false), sock(s), reverseConnection(reverse),
|
: upgradingToUdp(false), sock(s), reverseConnection(reverse),
|
||||||
@ -73,6 +75,10 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
|
|||||||
memset(bstats_total, 0, sizeof(bstats_total));
|
memset(bstats_total, 0, sizeof(bstats_total));
|
||||||
gettimeofday(&connStart, NULL);
|
gettimeofday(&connStart, NULL);
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++)
|
||||||
|
unixRelaySubscriptions[i][0] = '\0';
|
||||||
|
|
||||||
// Check their permissions, if applicable
|
// Check their permissions, if applicable
|
||||||
kasmpasswdpath[0] = '\0';
|
kasmpasswdpath[0] = '\0';
|
||||||
wordexp_t wexp;
|
wordexp_t wexp;
|
||||||
@ -1780,3 +1786,54 @@ void VNCSConnectionST::udpDowngrade(const bool byServer)
|
|||||||
vlog.info("Client %s downgrading from udp by %s", sock->getPeerAddress(),
|
vlog.info("Client %s downgrading from udp by %s", sock->getPeerAddress(),
|
||||||
byServer ? "the server" : "its own request");
|
byServer ? "the server" : "its own request");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VNCSConnectionST::subscribeUnixRelay(const char *name)
|
||||||
|
{
|
||||||
|
bool read, write, owner;
|
||||||
|
if (!getPerms(read, write, owner) || !write) {
|
||||||
|
// Need write permissions to subscribe
|
||||||
|
writer()->writeSubscribeUnixRelay(false, "No permissions");
|
||||||
|
vlog.info("Client tried to subscribe to unix channel %s without permissions", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
bool found = false;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (!strcmp(name, unixrelaynames[i])) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
writer()->writeSubscribeUnixRelay(false, "No such unix channel");
|
||||||
|
vlog.info("Client tried to subscribe to nonexistent unix channel %s", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer()->writeSubscribeUnixRelay(true, "Ok");
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (!unixRelaySubscriptions[i][0]) {
|
||||||
|
strcpy(unixRelaySubscriptions[i], name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VNCSConnectionST::unixRelay(const char *name, const rdr::U8 *buf, const unsigned len)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (!strcmp(unixRelaySubscriptions[i], name)) {
|
||||||
|
server->desktop->receivedUnixRelayData(name, buf, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VNCSConnectionST::sendUnixRelayData(const char name[], const unsigned char *buf,
|
||||||
|
const unsigned len)
|
||||||
|
{
|
||||||
|
writer()->writeUnixRelay(name, buf, len);
|
||||||
|
}
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <rfb/EncodeManager.h>
|
#include <rfb/EncodeManager.h>
|
||||||
#include <rfb/SConnection.h>
|
#include <rfb/SConnection.h>
|
||||||
#include <rfb/Timer.h>
|
#include <rfb/Timer.h>
|
||||||
|
#include <rfb/unixRelayLimits.h>
|
||||||
|
|
||||||
namespace rfb {
|
namespace rfb {
|
||||||
class VNCServerST;
|
class VNCServerST;
|
||||||
@ -200,6 +201,18 @@ namespace rfb {
|
|||||||
|
|
||||||
bool upgradingToUdp;
|
bool upgradingToUdp;
|
||||||
|
|
||||||
|
bool isSubscribedToUnixRelay(const char *name) const {
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (!strcmp(unixRelaySubscriptions[i], name))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void sendUnixRelayData(const char name[], const unsigned char *buf,
|
||||||
|
const unsigned len);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// SConnection callbacks
|
// SConnection callbacks
|
||||||
|
|
||||||
@ -222,6 +235,8 @@ namespace rfb {
|
|||||||
virtual void handleClipboardAnnounce(bool available);
|
virtual void handleClipboardAnnounce(bool available);
|
||||||
virtual void handleClipboardAnnounceBinary(const unsigned num, const char mimes[][32]);
|
virtual void handleClipboardAnnounceBinary(const unsigned num, const char mimes[][32]);
|
||||||
virtual void udpUpgrade(const char *resp);
|
virtual void udpUpgrade(const char *resp);
|
||||||
|
virtual void subscribeUnixRelay(const char *name);
|
||||||
|
virtual void unixRelay(const char *name, const rdr::U8 *buf, const unsigned len);
|
||||||
virtual void supportsLocalCursor();
|
virtual void supportsLocalCursor();
|
||||||
virtual void supportsFence();
|
virtual void supportsFence();
|
||||||
virtual void supportsContinuousUpdates();
|
virtual void supportsContinuousUpdates();
|
||||||
@ -324,6 +339,8 @@ namespace rfb {
|
|||||||
|
|
||||||
bool frameTracking;
|
bool frameTracking;
|
||||||
uint32_t udpFramesSinceFull;
|
uint32_t udpFramesSinceFull;
|
||||||
|
|
||||||
|
char unixRelaySubscriptions[MAX_UNIX_RELAYS][MAX_UNIX_RELAY_NAME_LEN];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1244,3 +1244,15 @@ void VNCServerST::refreshClients()
|
|||||||
(*i)->add_changed_all();
|
(*i)->add_changed_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VNCServerST::sendUnixRelayData(const char name[],
|
||||||
|
const unsigned char *buf, const unsigned len)
|
||||||
|
{
|
||||||
|
// For each client subscribed to this channel, send the data to them
|
||||||
|
std::list<VNCSConnectionST*>::iterator i;
|
||||||
|
for (i = clients.begin(); i != clients.end(); i++) {
|
||||||
|
if ((*i)->isSubscribedToUnixRelay(name)) {
|
||||||
|
(*i)->sendUnixRelayData(name, buf, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -198,6 +198,7 @@ namespace rfb {
|
|||||||
const char mimes[][32]);
|
const char mimes[][32]);
|
||||||
|
|
||||||
void refreshClients();
|
void refreshClients();
|
||||||
|
void sendUnixRelayData(const char name[], const unsigned char *buf, const unsigned len);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -33,6 +33,8 @@ namespace rfb {
|
|||||||
const int msgTypeRequestFrameStats = 179;
|
const int msgTypeRequestFrameStats = 179;
|
||||||
const int msgTypeBinaryClipboard = 180;
|
const int msgTypeBinaryClipboard = 180;
|
||||||
const int msgTypeUpgradeToUdp = 181;
|
const int msgTypeUpgradeToUdp = 181;
|
||||||
|
const int msgTypeSubscribeUnixRelay = 182;
|
||||||
|
const int msgTypeUnixRelay = 183;
|
||||||
|
|
||||||
const int msgTypeServerFence = 248;
|
const int msgTypeServerFence = 248;
|
||||||
|
|
||||||
@ -54,6 +56,8 @@ namespace rfb {
|
|||||||
// same as the other direction
|
// same as the other direction
|
||||||
//const int msgTypeBinaryClipboard = 180;
|
//const int msgTypeBinaryClipboard = 180;
|
||||||
//const int msgTypeUpgradeToUdp = 181;
|
//const int msgTypeUpgradeToUdp = 181;
|
||||||
|
//const int msgTypeSubscribeUnixRelay = 182;
|
||||||
|
//const int msgTypeUnixRelay = 183;
|
||||||
|
|
||||||
const int msgTypeClientFence = 248;
|
const int msgTypeClientFence = 248;
|
||||||
|
|
||||||
|
7
common/rfb/unixRelayLimits.h
Normal file
7
common/rfb/unixRelayLimits.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef UNIX_RELAY_LIMITS_H
|
||||||
|
#define UNIX_RELAY_LIMITS_H
|
||||||
|
|
||||||
|
#define MAX_UNIX_RELAYS 4
|
||||||
|
#define MAX_UNIX_RELAY_NAME_LEN 64
|
||||||
|
|
||||||
|
#endif
|
@ -29,6 +29,8 @@
|
|||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
@ -51,6 +53,7 @@ extern "C" {
|
|||||||
void vncSetGlueContext(int screenIndex);
|
void vncSetGlueContext(int screenIndex);
|
||||||
|
|
||||||
extern int wakeuppipe[2];
|
extern int wakeuppipe[2];
|
||||||
|
extern struct sockaddr_un unixrelayclients[MAX_UNIX_RELAYS];
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace rfb;
|
using namespace rfb;
|
||||||
@ -323,6 +326,26 @@ void XserverDesktop::handleSocketEvent(int fd, bool read, bool write)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (unixrelays[i] == -1)
|
||||||
|
break;
|
||||||
|
if (fd == unixrelays[i]) {
|
||||||
|
do {
|
||||||
|
struct sockaddr_un client;
|
||||||
|
socklen_t addrlen = sizeof(struct sockaddr_un);
|
||||||
|
const ssize_t len = recvfrom(unixrelays[i], unixbuf, sizeof(unixbuf),
|
||||||
|
MSG_DONTWAIT,
|
||||||
|
(struct sockaddr *) &client, &addrlen);
|
||||||
|
if (len <= 0)
|
||||||
|
break;
|
||||||
|
memcpy(&unixrelayclients[i], &client, addrlen);
|
||||||
|
server->sendUnixRelayData(unixrelaynames[i], unixbuf, len);
|
||||||
|
} while (1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (handleListenerEvent(fd, &listeners, server))
|
if (handleListenerEvent(fd, &listeners, server))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -557,3 +580,21 @@ bool XserverDesktop::handleTimeout(Timer* t)
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void XserverDesktop::receivedUnixRelayData(const char name[], const unsigned char *buf,
|
||||||
|
const unsigned len)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (unixrelays[i] == -1)
|
||||||
|
break;
|
||||||
|
if (strcmp(name, unixrelaynames[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (sendto(unixrelays[i], buf, len, 0,
|
||||||
|
(struct sockaddr *) &unixrelayclients[i], sizeof(struct sockaddr_un)) == -1)
|
||||||
|
vlog.error("Error writing unix relay data to %s", name);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -110,6 +110,9 @@ public:
|
|||||||
const char* userName,
|
const char* userName,
|
||||||
char** reason);
|
char** reason);
|
||||||
|
|
||||||
|
virtual void receivedUnixRelayData(const char name[], const unsigned char *buf,
|
||||||
|
const unsigned len);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool handleListenerEvent(int fd,
|
bool handleListenerEvent(int fd,
|
||||||
std::list<network::SocketListener*>* sockets,
|
std::list<network::SocketListener*>* sockets,
|
||||||
@ -138,5 +141,7 @@ private:
|
|||||||
rfb::Point oldCursorPos;
|
rfb::Point oldCursorPos;
|
||||||
|
|
||||||
bool resizing;
|
bool resizing;
|
||||||
|
|
||||||
|
uint8_t unixbuf[1024 * 1024];
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -89,6 +89,11 @@ Use IPv4 for incoming and outgoing connections. Default is on.
|
|||||||
Use IPv6 for incoming and outgoing connections. Default is on.
|
Use IPv6 for incoming and outgoing connections. Default is on.
|
||||||
.
|
.
|
||||||
.TP
|
.TP
|
||||||
|
.B \-UnixRelay \fIname:path\fP
|
||||||
|
Create a local named unix socket, for relaying data. May be given multiple times.
|
||||||
|
Example: -UnixRelay audio:/tmp/audiosock
|
||||||
|
.
|
||||||
|
.TP
|
||||||
.B \-rfbunixpath \fIpath\fP
|
.B \-rfbunixpath \fIpath\fP
|
||||||
Specifies the path of a Unix domain socket on which Xvnc listens for
|
Specifies the path of a Unix domain socket on which Xvnc listens for
|
||||||
connections from viewers, instead of listening on a TCP port.
|
connections from viewers, instead of listening on a TCP port.
|
||||||
|
@ -237,6 +237,14 @@ void vncExtensionInit(void)
|
|||||||
fcntl(wakeuppipe[0], F_SETFL, flags | O_NONBLOCK);
|
fcntl(wakeuppipe[0], F_SETFL, flags | O_NONBLOCK);
|
||||||
vncSetNotifyFd(wakeuppipe[0], 0, true, false);
|
vncSetNotifyFd(wakeuppipe[0], 0, true, false);
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (unixrelays[i] == -1)
|
||||||
|
break;
|
||||||
|
vncSetNotifyFd(unixrelays[i], 0, true, false);
|
||||||
|
vlog.info("Listening to unix relay socket %s", unixrelaynames[i]);
|
||||||
|
}
|
||||||
|
|
||||||
initialised = true;
|
initialised = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
|
||||||
|
#include <rfb/unixRelayLimits.h>
|
||||||
|
|
||||||
// Only from C++
|
// Only from C++
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
namespace rfb { class StringParameter; };
|
namespace rfb { class StringParameter; };
|
||||||
@ -106,6 +108,9 @@ void vncRefreshScreenLayout(int scrIdx);
|
|||||||
|
|
||||||
int vncOverrideParam(const char *nameAndValue);
|
int vncOverrideParam(const char *nameAndValue);
|
||||||
|
|
||||||
|
extern int unixrelays[MAX_UNIX_RELAYS];
|
||||||
|
extern char unixrelaynames[MAX_UNIX_RELAYS][MAX_UNIX_RELAY_NAME_LEN];
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -61,8 +61,11 @@ from the X Consortium.
|
|||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "mipointer.h"
|
#include "mipointer.h"
|
||||||
#include "micmap.h"
|
#include "micmap.h"
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -155,6 +158,73 @@ static char displayNumStr[16];
|
|||||||
|
|
||||||
static int vncVerbose = DEFAULT_LOG_VERBOSITY;
|
static int vncVerbose = DEFAULT_LOG_VERBOSITY;
|
||||||
|
|
||||||
|
int unixrelays[MAX_UNIX_RELAYS];
|
||||||
|
char unixrelaynames[MAX_UNIX_RELAYS][MAX_UNIX_RELAY_NAME_LEN];
|
||||||
|
struct sockaddr_un unixrelayclients[MAX_UNIX_RELAYS];
|
||||||
|
|
||||||
|
static unsigned addrelay(const char * const arg)
|
||||||
|
{
|
||||||
|
const char *ptr = strchr(arg, ':');
|
||||||
|
if (!ptr) {
|
||||||
|
ErrorF("Invalid unixrelay\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned namelen = ptr - arg;
|
||||||
|
if (namelen >= MAX_UNIX_RELAY_NAME_LEN) {
|
||||||
|
ErrorF("Unix relay name too long\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned i;
|
||||||
|
unsigned char found = 0;
|
||||||
|
for (i = 0; i < MAX_UNIX_RELAYS; i++) {
|
||||||
|
if (unixrelays[i] == -1) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
ErrorF("Too many unix relays\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(unixrelaynames[i], arg, namelen);
|
||||||
|
unixrelaynames[i][namelen] = '\0';
|
||||||
|
|
||||||
|
unixrelays[i] = socket(AF_UNIX, SOCK_DGRAM, 0);
|
||||||
|
if (unixrelays[i] < 0) {
|
||||||
|
ErrorF("Failed to create unix sock\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr++;
|
||||||
|
struct sockaddr_un sa;
|
||||||
|
if (strlen(ptr) >= sizeof(sa.sun_path)) {
|
||||||
|
ErrorF("Unix relay path too long\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sa.sun_family = AF_UNIX;
|
||||||
|
strcpy(sa.sun_path, ptr);
|
||||||
|
|
||||||
|
// SO_REUSEADDR doesn't exist for unix sockets, if the socket exists
|
||||||
|
// (from our previous run), we need to delete it first. Check it's a
|
||||||
|
// socket so we don't delete wrong files
|
||||||
|
struct stat st;
|
||||||
|
if (stat(ptr, &st) == 0) {
|
||||||
|
if (S_ISSOCK(st.st_mode))
|
||||||
|
unlink(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind(unixrelays[i], (struct sockaddr *) &sa, sizeof(struct sockaddr_un))) {
|
||||||
|
ErrorF("Failed to bind unix sock\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
char *extra_headers = NULL;
|
char *extra_headers = NULL;
|
||||||
unsigned extra_headers_len = 0;
|
unsigned extra_headers_len = 0;
|
||||||
|
|
||||||
@ -364,6 +434,7 @@ void ddxUseMsg(void)
|
|||||||
ErrorF("-inetd has been launched from inetd\n");
|
ErrorF("-inetd has been launched from inetd\n");
|
||||||
ErrorF("-http-header name=val append this header to all HTTP responses\n");
|
ErrorF("-http-header name=val append this header to all HTTP responses\n");
|
||||||
ErrorF("-noclipboard disable clipboard settings modification via vncconfig utility\n");
|
ErrorF("-noclipboard disable clipboard settings modification via vncconfig utility\n");
|
||||||
|
ErrorF("-unixrelay name:path create a local named unix relay socket\n");
|
||||||
ErrorF("-verbose [n] verbose startup messages\n");
|
ErrorF("-verbose [n] verbose startup messages\n");
|
||||||
ErrorF("-quiet minimal startup messages\n");
|
ErrorF("-quiet minimal startup messages\n");
|
||||||
ErrorF("-version show the server version\n");
|
ErrorF("-version show the server version\n");
|
||||||
@ -416,6 +487,13 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
|||||||
|
|
||||||
vfbInitializeDefaultScreens();
|
vfbInitializeDefaultScreens();
|
||||||
vfbInitializePixmapDepths();
|
vfbInitializePixmapDepths();
|
||||||
|
|
||||||
|
unsigned r;
|
||||||
|
for (r = 0; r < MAX_UNIX_RELAYS; r++) {
|
||||||
|
unixrelays[r] = -1;
|
||||||
|
unixrelaynames[r][0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
firstTime = FALSE;
|
firstTime = FALSE;
|
||||||
vncInitRFB();
|
vncInitRFB();
|
||||||
}
|
}
|
||||||
@ -668,6 +746,16 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strcasecmp(argv[i], "-unixrelay") == 0)
|
||||||
|
{
|
||||||
|
fail_unless_args(argc, i, 1);
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if (addrelay(argv[i]))
|
||||||
|
return 0;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(argv[i], "-verbose")) {
|
if (!strcmp(argv[i], "-verbose")) {
|
||||||
if (++i < argc && argv[i]) {
|
if (++i < argc && argv[i]) {
|
||||||
char *end;
|
char *end;
|
||||||
|
Loading…
Reference in New Issue
Block a user