https://fedoraproject.org/wiki/Changes/WaylandRemoteDesktopepel9
parent
46d9c246b9
commit
604fea4679
@ -0,0 +1,195 @@
|
||||
From 0a98d629447964f1d5d922d5012ee0c2cbf10694 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Mon, 11 Jun 2018 23:47:02 +0200
|
||||
Subject: [PATCH 1/2] libvncserver: Add API to add custom I/O entry points
|
||||
|
||||
Add API to make it possible to channel RFB input and output through
|
||||
another layer, for example TLS. This is done by making it possible to
|
||||
override the default read/write/peek functions.
|
||||
---
|
||||
libvncserver/rfbserver.c | 4 +++
|
||||
libvncserver/sockets.c | 64 +++++++++++++++++++++++++++++++++++++---
|
||||
rfb/rfb.h | 17 +++++++++++
|
||||
3 files changed, 81 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
|
||||
index 7af6aed..fbedd9f 100644
|
||||
--- a/libvncserver/rfbserver.c
|
||||
+++ b/libvncserver/rfbserver.c
|
||||
@@ -322,6 +322,10 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
|
||||
|
||||
cl->screen = rfbScreen;
|
||||
cl->sock = sock;
|
||||
+ cl->readFromSocket = rfbDefaultReadFromSocket;
|
||||
+ cl->peekAtSocket = rfbDefaultPeekAtSocket;
|
||||
+ cl->hasPendingOnSocket = rfbDefaultHasPendingOnSocket;
|
||||
+ cl->writeToSocket = rfbDefaultWriteToSocket;
|
||||
cl->viewOnly = FALSE;
|
||||
/* setup pseudo scaling */
|
||||
cl->scaledScreen = rfbScreen;
|
||||
diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c
|
||||
index bbc3d90..27515f2 100644
|
||||
--- a/libvncserver/sockets.c
|
||||
+++ b/libvncserver/sockets.c
|
||||
@@ -589,6 +589,30 @@ rfbConnect(rfbScreenInfoPtr rfbScreen,
|
||||
return sock;
|
||||
}
|
||||
|
||||
+int
|
||||
+rfbDefaultReadFromSocket(rfbClientPtr cl, char *buf, int len)
|
||||
+{
|
||||
+ return read(cl->sock, buf, len);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+rfbReadFromSocket(rfbClientPtr cl, char *buf, int len)
|
||||
+{
|
||||
+ return cl->readFromSocket(cl, buf, len);
|
||||
+}
|
||||
+
|
||||
+rfbBool
|
||||
+rfbDefaultHasPendingOnSocket(rfbClientPtr cl)
|
||||
+{
|
||||
+ return FALSE;
|
||||
+}
|
||||
+
|
||||
+static rfbBool
|
||||
+rfbHasPendingOnSocket(rfbClientPtr cl)
|
||||
+{
|
||||
+ cl->hasPendingOnSocket(cl);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* ReadExact reads an exact number of bytes from a client. Returns 1 if
|
||||
* those bytes have been read, 0 if the other end has closed, or -1 if an error
|
||||
@@ -610,10 +634,10 @@ rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
|
||||
} else if (cl->sslctx) {
|
||||
n = rfbssl_read(cl, buf, len);
|
||||
} else {
|
||||
- n = read(sock, buf, len);
|
||||
+ n = rfbReadFromSocket(cl, buf, len);
|
||||
}
|
||||
#else
|
||||
- n = read(sock, buf, len);
|
||||
+ n = rfbReadFromSocket(cl, buf, len);
|
||||
#endif
|
||||
|
||||
if (n > 0) {
|
||||
@@ -645,6 +669,10 @@ rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
+
|
||||
+ if (rfbHasPendingOnSocket(cl))
|
||||
+ continue;
|
||||
+
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sock, &fds);
|
||||
tv.tv_sec = timeout / 1000;
|
||||
@@ -681,6 +709,18 @@ int rfbReadExact(rfbClientPtr cl,char* buf,int len)
|
||||
return(rfbReadExactTimeout(cl,buf,len,rfbMaxClientWait));
|
||||
}
|
||||
|
||||
+int
|
||||
+rfbDefaultPeekAtSocket(rfbClientPtr cl, char *buf, int len)
|
||||
+{
|
||||
+ return recv(cl->sock, buf, len, MSG_PEEK);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+rfbPeekAtSocket(rfbClientPtr cl, char *buf, int len)
|
||||
+{
|
||||
+ cl->peekAtSocket(cl, buf, len);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* PeekExact peeks at an exact number of bytes from a client. Returns 1 if
|
||||
* those bytes have been read, 0 if the other end has closed, or -1 if an
|
||||
@@ -701,7 +741,7 @@ rfbPeekExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
|
||||
n = rfbssl_peek(cl, buf, len);
|
||||
else
|
||||
#endif
|
||||
- n = recv(sock, buf, len, MSG_PEEK);
|
||||
+ n = rfbPeekAtSocket(cl, buf, len);
|
||||
|
||||
if (n == len) {
|
||||
|
||||
@@ -757,6 +797,22 @@ rfbPeekExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+int
|
||||
+rfbDefaultWriteToSocket(rfbClientPtr cl,
|
||||
+ const char *buf,
|
||||
+ int len)
|
||||
+{
|
||||
+ return write(cl->sock, buf, len);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+rfbWriteToSocket(rfbClientPtr cl,
|
||||
+ const char *buf,
|
||||
+ int len)
|
||||
+{
|
||||
+ return cl->writeToSocket(cl, buf, len);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* WriteExact writes an exact number of bytes to a client. Returns 1 if
|
||||
* those bytes have been written, or -1 if an error occurred (errno is set to
|
||||
@@ -801,7 +857,7 @@ rfbWriteExact(rfbClientPtr cl,
|
||||
n = rfbssl_write(cl, buf, len);
|
||||
else
|
||||
#endif
|
||||
- n = write(sock, buf, len);
|
||||
+ n = rfbWriteToSocket(cl, buf, len);
|
||||
|
||||
if (n > 0) {
|
||||
|
||||
diff --git a/rfb/rfb.h b/rfb/rfb.h
|
||||
index f982b40..ba9e898 100644
|
||||
--- a/rfb/rfb.h
|
||||
+++ b/rfb/rfb.h
|
||||
@@ -415,6 +415,14 @@ typedef struct sraRegion* sraRegionPtr;
|
||||
|
||||
typedef void (*ClientGoneHookPtr)(struct _rfbClientRec* cl);
|
||||
|
||||
+typedef int (*ClientReadFromSocket)(struct _rfbClientRec* cl,
|
||||
+ char *buf, int len);
|
||||
+typedef int (*ClientPeekAtSocket)(struct _rfbClientRec* cl,
|
||||
+ char *buf, int len);
|
||||
+typedef rfbBool (*ClientHasPendingOnSocket)(struct _rfbClientRec* cl);
|
||||
+typedef int (*ClientWriteToSocket)(struct _rfbClientRec* cl,
|
||||
+ const char *buf, int len);
|
||||
+
|
||||
typedef struct _rfbFileTransferData {
|
||||
int fd;
|
||||
int compressionEnabled;
|
||||
@@ -696,6 +704,11 @@ typedef struct _rfbClientRec {
|
||||
wsCtx *wsctx;
|
||||
char *wspath; /* Requests path component */
|
||||
#endif
|
||||
+
|
||||
+ ClientReadFromSocket readFromSocket; /* Read data from socket */
|
||||
+ ClientPeekAtSocket peekAtSocket; /* Peek at data from socket */
|
||||
+ ClientHasPendingOnSocket hasPendingOnSocket; /* Peek at data from socket */
|
||||
+ ClientWriteToSocket writeToSocket; /* Write data to socket */
|
||||
} rfbClientRec, *rfbClientPtr;
|
||||
|
||||
/**
|
||||
@@ -748,8 +761,12 @@ extern void rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen);
|
||||
extern void rfbCloseClient(rfbClientPtr cl);
|
||||
extern int rfbReadExact(rfbClientPtr cl, char *buf, int len);
|
||||
extern int rfbReadExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout);
|
||||
+extern int rfbDefaultReadFromSocket(rfbClientPtr cl, char *buf, int len);
|
||||
extern int rfbPeekExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout);
|
||||
+extern int rfbDefaultPeekAtSocket(rfbClientPtr cl, char *buf, int len);
|
||||
+extern rfbBool rfbDefaultHasPendingOnSocket(rfbClientPtr cl);
|
||||
extern int rfbWriteExact(rfbClientPtr cl, const char *buf, int len);
|
||||
+extern int rfbDefaultWriteToSocket(rfbClientPtr cl, const char *buf, int len);
|
||||
extern int rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec);
|
||||
extern int rfbConnect(rfbScreenInfoPtr rfbScreen, char* host, int port);
|
||||
extern int rfbConnectToTcpAddr(char* host, int port);
|
||||
--
|
||||
2.17.1
|
||||
|
@ -0,0 +1,366 @@
|
||||
From c343c1b43080bcb45dad285faa5cd8926bfb9811 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
|
||||
Date: Mon, 11 Jun 2018 23:50:05 +0200
|
||||
Subject: [PATCH 2/2] libvncserver: Add channel security handlers
|
||||
|
||||
Add another type of security handler that is meant to be used initially
|
||||
to set up a secure channel. Regular security handlers would be
|
||||
advertised and processed after any channel security have succeeded.
|
||||
|
||||
For example, this, together with the custom I/O functions allows a
|
||||
LibVNCServer user to implement TLS in combination with VNCAuth. This is
|
||||
done by adding a single channel security handler with the rfbTLS (18)
|
||||
with a handler that initiates a TLS session, and when a TLS session is
|
||||
initiated, the regular security handler list is sent.
|
||||
---
|
||||
libvncserver/auth.c | 162 ++++++++++++++++++++++++++++++---------
|
||||
libvncserver/rfbserver.c | 1 +
|
||||
rfb/rfb.h | 15 +++-
|
||||
3 files changed, 140 insertions(+), 38 deletions(-)
|
||||
|
||||
diff --git a/libvncserver/auth.c b/libvncserver/auth.c
|
||||
index 814a814..6581953 100644
|
||||
--- a/libvncserver/auth.c
|
||||
+++ b/libvncserver/auth.c
|
||||
@@ -37,18 +37,17 @@ void rfbClientSendString(rfbClientPtr cl, const char *reason);
|
||||
* Handle security types
|
||||
*/
|
||||
|
||||
+/* Channel security handlers to set up a secure channel, e.g. TLS. */
|
||||
+static rfbSecurityHandler* channelSecurityHandlers = NULL;
|
||||
+
|
||||
+/* Security handlers when channel security is established. */
|
||||
static rfbSecurityHandler* securityHandlers = NULL;
|
||||
|
||||
-/*
|
||||
- * This method registers a list of new security types.
|
||||
- * It avoids same security type getting registered multiple times.
|
||||
- * The order is not preserved if multiple security types are
|
||||
- * registered at one-go.
|
||||
- */
|
||||
void
|
||||
-rfbRegisterSecurityHandler(rfbSecurityHandler* handler)
|
||||
+rfbRegisterSecurityHandlerTo(rfbSecurityHandler* handler,
|
||||
+ rfbSecurityHandler** handlerList)
|
||||
{
|
||||
- rfbSecurityHandler *head = securityHandlers, *next = NULL;
|
||||
+ rfbSecurityHandler *head = *handlerList, *next = NULL;
|
||||
|
||||
if(handler == NULL)
|
||||
return;
|
||||
@@ -57,39 +56,35 @@ rfbRegisterSecurityHandler(rfbSecurityHandler* handler)
|
||||
|
||||
while(head != NULL) {
|
||||
if(head == handler) {
|
||||
- rfbRegisterSecurityHandler(next);
|
||||
+ rfbRegisterSecurityHandlerTo(next, handlerList);
|
||||
return;
|
||||
}
|
||||
|
||||
head = head->next;
|
||||
}
|
||||
|
||||
- handler->next = securityHandlers;
|
||||
- securityHandlers = handler;
|
||||
+ handler->next = *handlerList;
|
||||
+ *handlerList = handler;
|
||||
|
||||
- rfbRegisterSecurityHandler(next);
|
||||
+ rfbRegisterSecurityHandlerTo(next, handlerList);
|
||||
}
|
||||
|
||||
-/*
|
||||
- * This method unregisters a list of security types.
|
||||
- * These security types won't be available for any new
|
||||
- * client connection.
|
||||
- */
|
||||
-void
|
||||
-rfbUnregisterSecurityHandler(rfbSecurityHandler* handler)
|
||||
+static void
|
||||
+rfbUnregisterSecurityHandlerFrom(rfbSecurityHandler* handler,
|
||||
+ rfbSecurityHandler** handlerList)
|
||||
{
|
||||
rfbSecurityHandler *cur = NULL, *pre = NULL;
|
||||
|
||||
if(handler == NULL)
|
||||
return;
|
||||
|
||||
- if(securityHandlers == handler) {
|
||||
- securityHandlers = securityHandlers->next;
|
||||
- rfbUnregisterSecurityHandler(handler->next);
|
||||
+ if(*handlerList == handler) {
|
||||
+ *handlerList = (*handlerList)->next;
|
||||
+ rfbUnregisterSecurityHandlerFrom(handler->next, handlerList);
|
||||
return;
|
||||
}
|
||||
|
||||
- cur = pre = securityHandlers;
|
||||
+ cur = pre = *handlerList;
|
||||
|
||||
while(cur) {
|
||||
if(cur == handler) {
|
||||
@@ -99,7 +94,50 @@ rfbUnregisterSecurityHandler(rfbSecurityHandler* handler)
|
||||
pre = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
- rfbUnregisterSecurityHandler(handler->next);
|
||||
+ rfbUnregisterSecurityHandlerFrom(handler->next, handlerList);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+rfbRegisterChannelSecurityHandler(rfbSecurityHandler* handler)
|
||||
+{
|
||||
+ rfbRegisterSecurityHandlerTo(handler, &channelSecurityHandlers);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This method unregisters a list of security types.
|
||||
+ * These security types won't be available for any new
|
||||
+ * client connection.
|
||||
+ */
|
||||
+
|
||||
+void
|
||||
+rfbUnregisterChannelSecurityHandler(rfbSecurityHandler* handler)
|
||||
+{
|
||||
+ rfbUnregisterSecurityHandlerFrom(handler, &channelSecurityHandlers);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This method registers a list of new security types.
|
||||
+ * It avoids same security type getting registered multiple times.
|
||||
+ * The order is not preserved if multiple security types are
|
||||
+ * registered at one-go.
|
||||
+ */
|
||||
+
|
||||
+void
|
||||
+rfbRegisterSecurityHandler(rfbSecurityHandler* handler)
|
||||
+{
|
||||
+ rfbRegisterSecurityHandlerTo(handler, &securityHandlers);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This method unregisters a list of security types.
|
||||
+ * These security types won't be available for any new
|
||||
+ * client connection.
|
||||
+ */
|
||||
+
|
||||
+void
|
||||
+rfbUnregisterSecurityHandler(rfbSecurityHandler* handler)
|
||||
+{
|
||||
+ rfbUnregisterSecurityHandlerFrom(handler, &securityHandlers);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -197,9 +235,22 @@ static rfbSecurityHandler VncSecurityHandlerNone = {
|
||||
NULL
|
||||
};
|
||||
|
||||
+static int32_t
|
||||
+determinePrimarySecurityType(rfbClientPtr cl)
|
||||
+{
|
||||
+ if (!cl->screen->authPasswdData || cl->reverseConnection) {
|
||||
+ /* chk if this condition is valid or not. */
|
||||
+ return rfbSecTypeNone;
|
||||
+ } else if (cl->screen->authPasswdData) {
|
||||
+ return rfbSecTypeVncAuth;
|
||||
+ } else {
|
||||
+ return rfbSecTypeInvalid;
|
||||
+ }
|
||||
+}
|
||||
|
||||
-static void
|
||||
-rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
|
||||
+void
|
||||
+rfbSendSecurityTypeList(rfbClientPtr cl,
|
||||
+ enum rfbSecurityTag exclude)
|
||||
{
|
||||
/* The size of the message is the count of security types +1,
|
||||
* since the first byte is the number of types. */
|
||||
@@ -207,9 +258,10 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
|
||||
rfbSecurityHandler* handler;
|
||||
#define MAX_SECURITY_TYPES 255
|
||||
uint8_t buffer[MAX_SECURITY_TYPES+1];
|
||||
-
|
||||
+ int32_t primaryType;
|
||||
|
||||
/* Fill in the list of security types in the client structure. (NOTE: Not really in the client structure) */
|
||||
+ primaryType = determinePrimarySecurityType(cl);
|
||||
switch (primaryType) {
|
||||
case rfbSecTypeNone:
|
||||
rfbRegisterSecurityHandler(&VncSecurityHandlerNone);
|
||||
@@ -221,6 +273,9 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
|
||||
|
||||
for (handler = securityHandlers;
|
||||
handler && size<MAX_SECURITY_TYPES; handler = handler->next) {
|
||||
+ if (exclude && (handler->securityTags & exclude))
|
||||
+ continue;
|
||||
+
|
||||
buffer[size] = handler->type;
|
||||
size++;
|
||||
}
|
||||
@@ -249,7 +304,29 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
|
||||
cl->state = RFB_SECURITY_TYPE;
|
||||
}
|
||||
|
||||
+static void
|
||||
+rfbSendChannelSecurityTypeList(rfbClientPtr cl)
|
||||
+{
|
||||
+ int size = 1;
|
||||
+ rfbSecurityHandler* handler;
|
||||
+ uint8_t buffer[MAX_SECURITY_TYPES+1];
|
||||
+
|
||||
+ for (handler = channelSecurityHandlers;
|
||||
+ handler && size<MAX_SECURITY_TYPES; handler = handler->next) {
|
||||
+ buffer[size] = handler->type;
|
||||
+ size++;
|
||||
+ }
|
||||
+ buffer[0] = (unsigned char)size-1;
|
||||
+
|
||||
+ if (rfbWriteExact(cl, (char *)buffer, size) < 0) {
|
||||
+ rfbLogPerror("rfbSendSecurityTypeList: write");
|
||||
+ rfbCloseClient(cl);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
+ /* Dispatch client input to rfbProcessClientChannelSecurityType. */
|
||||
+ cl->state = RFB_CHANNEL_SECURITY_TYPE;
|
||||
+}
|
||||
|
||||
|
||||
/*
|
||||
@@ -297,18 +374,19 @@ rfbSendSecurityType(rfbClientPtr cl, int32_t securityType)
|
||||
void
|
||||
rfbAuthNewClient(rfbClientPtr cl)
|
||||
{
|
||||
- int32_t securityType = rfbSecTypeInvalid;
|
||||
+ int32_t securityType;
|
||||
|
||||
- if (!cl->screen->authPasswdData || cl->reverseConnection) {
|
||||
- /* chk if this condition is valid or not. */
|
||||
- securityType = rfbSecTypeNone;
|
||||
- } else if (cl->screen->authPasswdData) {
|
||||
- securityType = rfbSecTypeVncAuth;
|
||||
- }
|
||||
+ securityType = determinePrimarySecurityType(cl);
|
||||
|
||||
if (cl->protocolMajorVersion==3 && cl->protocolMinorVersion < 7)
|
||||
{
|
||||
/* Make sure we use only RFB 3.3 compatible security types. */
|
||||
+ if (channelSecurityHandlers) {
|
||||
+ rfbLog("VNC channel security enabled - RFB 3.3 client rejected\n");
|
||||
+ rfbClientConnFailed(cl, "Your viewer cannot hnadler required "
|
||||
+ "security methods");
|
||||
+ return;
|
||||
+ }
|
||||
if (securityType == rfbSecTypeInvalid) {
|
||||
rfbLog("VNC authentication disabled - RFB 3.3 client rejected\n");
|
||||
rfbClientConnFailed(cl, "Your viewer cannot handle required "
|
||||
@@ -316,9 +394,11 @@ rfbAuthNewClient(rfbClientPtr cl)
|
||||
return;
|
||||
}
|
||||
rfbSendSecurityType(cl, securityType);
|
||||
+ } else if (channelSecurityHandlers) {
|
||||
+ rfbSendChannelSecurityTypeList(cl);
|
||||
} else {
|
||||
/* Here it's ok when securityType is set to rfbSecTypeInvalid. */
|
||||
- rfbSendSecurityTypeList(cl, securityType);
|
||||
+ rfbSendSecurityTypeList(cl, RFB_SECURITY_TAG_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,6 +412,7 @@ rfbProcessClientSecurityType(rfbClientPtr cl)
|
||||
int n;
|
||||
uint8_t chosenType;
|
||||
rfbSecurityHandler* handler;
|
||||
+ rfbSecurityHandler* handlerListHead;
|
||||
|
||||
/* Read the security type. */
|
||||
n = rfbReadExact(cl, (char *)&chosenType, 1);
|
||||
@@ -344,8 +425,17 @@ rfbProcessClientSecurityType(rfbClientPtr cl)
|
||||
return;
|
||||
}
|
||||
|
||||
+ switch (cl->state) {
|
||||
+ case RFB_CHANNEL_SECURITY_TYPE:
|
||||
+ handlerListHead = channelSecurityHandlers;
|
||||
+ break;
|
||||
+ case RFB_SECURITY_TYPE:
|
||||
+ handlerListHead = securityHandlers;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
/* Make sure it was present in the list sent by the server. */
|
||||
- for (handler = securityHandlers; handler; handler = handler->next) {
|
||||
+ for (handler = handlerListHead; handler; handler = handler->next) {
|
||||
if (chosenType == handler->type) {
|
||||
rfbLog("rfbProcessClientSecurityType: executing handler for type %d\n", chosenType);
|
||||
handler->handler(cl);
|
||||
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
|
||||
index fbedd9f..1e8b3c1 100644
|
||||
--- a/libvncserver/rfbserver.c
|
||||
+++ b/libvncserver/rfbserver.c
|
||||
@@ -643,6 +643,7 @@ rfbProcessClientMessage(rfbClientPtr cl)
|
||||
case RFB_PROTOCOL_VERSION:
|
||||
rfbProcessClientProtocolVersion(cl);
|
||||
return;
|
||||
+ case RFB_CHANNEL_SECURITY_TYPE:
|
||||
case RFB_SECURITY_TYPE:
|
||||
rfbProcessClientSecurityType(cl);
|
||||
return;
|
||||
diff --git a/rfb/rfb.h b/rfb/rfb.h
|
||||
index ba9e898..be58d08 100644
|
||||
--- a/rfb/rfb.h
|
||||
+++ b/rfb/rfb.h
|
||||
@@ -182,6 +182,11 @@ typedef struct {
|
||||
} data; /**< there have to be count*3 entries */
|
||||
} rfbColourMap;
|
||||
|
||||
+enum rfbSecurityTag {
|
||||
+ RFB_SECURITY_TAG_NONE = 0,
|
||||
+ RFB_SECURITY_TAG_CHANNEL = 1 << 0
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* Security handling (RFB protocol version 3.7)
|
||||
*/
|
||||
@@ -190,6 +195,7 @@ typedef struct _rfbSecurity {
|
||||
uint8_t type;
|
||||
void (*handler)(struct _rfbClientRec* cl);
|
||||
struct _rfbSecurity* next;
|
||||
+ enum rfbSecurityTag securityTags;
|
||||
} rfbSecurityHandler;
|
||||
|
||||
/**
|
||||
@@ -506,7 +512,7 @@ typedef struct _rfbClientRec {
|
||||
/** Possible client states: */
|
||||
enum {
|
||||
RFB_PROTOCOL_VERSION, /**< establishing protocol version */
|
||||
- RFB_SECURITY_TYPE, /**< negotiating security (RFB v.3.7) */
|
||||
+ RFB_SECURITY_TYPE, /**< negotiating security (RFB v.3.7) */
|
||||
RFB_AUTHENTICATION, /**< authenticating */
|
||||
RFB_INITIALISATION, /**< sending initialisation messages */
|
||||
RFB_NORMAL, /**< normal protocol messages */
|
||||
@@ -514,7 +520,9 @@ typedef struct _rfbClientRec {
|
||||
/* Ephemeral internal-use states that will never be seen by software
|
||||
* using LibVNCServer to provide services: */
|
||||
|
||||
- RFB_INITIALISATION_SHARED /**< sending initialisation messages with implicit shared-flag already true */
|
||||
+ RFB_INITIALISATION_SHARED, /**< sending initialisation messages with implicit shared-flag already true */
|
||||
+
|
||||
+ RFB_CHANNEL_SECURITY_TYPE, /**< negotiating security (RFB v.3.7) */
|
||||
} state;
|
||||
|
||||
rfbBool reverseConnection;
|
||||
@@ -855,6 +863,9 @@ extern void rfbProcessClientSecurityType(rfbClientPtr cl);
|
||||
extern void rfbAuthProcessClientMessage(rfbClientPtr cl);
|
||||
extern void rfbRegisterSecurityHandler(rfbSecurityHandler* handler);
|
||||
extern void rfbUnregisterSecurityHandler(rfbSecurityHandler* handler);
|
||||
+extern void rfbRegisterChannelSecurityHandler(rfbSecurityHandler* handler);
|
||||
+extern void rfbUnregisterChannelSecurityHandler(rfbSecurityHandler* handler);
|
||||
+extern void rfbSendSecurityTypeList(rfbClientPtr cl, enum rfbSecurityTag exclude);
|
||||
|
||||
/* rre.c */
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
Loading…
Reference in new issue