3995c25
From 30b947df1b25cf741f6863b4c3f77e0016aa4898 Mon Sep 17 00:00:00 2001
Jonas Ådahl 604fea4
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Jonas Ådahl 604fea4
Date: Mon, 11 Jun 2018 23:50:05 +0200
Jonas Ådahl 604fea4
Subject: [PATCH 2/2] libvncserver: Add channel security handlers
Jonas Ådahl 604fea4
Jonas Ådahl 604fea4
Add another type of security handler that is meant to be used initially
Jonas Ådahl 604fea4
to set up a secure channel. Regular security handlers would be
Jonas Ådahl 604fea4
advertised and processed after any channel security have succeeded.
Jonas Ådahl 604fea4
Jonas Ådahl 604fea4
For example, this, together with the custom I/O functions allows a
Jonas Ådahl 604fea4
LibVNCServer user to implement TLS in combination with VNCAuth. This is
Jonas Ådahl 604fea4
done by adding a single channel security handler with the rfbTLS (18)
Jonas Ådahl 604fea4
with a handler that initiates a TLS session, and when a TLS session is
Jonas Ådahl 604fea4
initiated, the regular security handler list is sent.
Jonas Ådahl 604fea4
---
3995c25
 libvncserver/auth.c      | 164 ++++++++++++++++++++++++++++++---------
Jonas Ådahl 604fea4
 libvncserver/rfbserver.c |   1 +
Jonas Ådahl 604fea4
 rfb/rfb.h                |  15 +++-
3995c25
 3 files changed, 142 insertions(+), 38 deletions(-)
Jonas Ådahl 604fea4
Jonas Ådahl 604fea4
diff --git a/libvncserver/auth.c b/libvncserver/auth.c
3995c25
index 814a8142..55e0b3c9 100644
Jonas Ådahl 604fea4
--- a/libvncserver/auth.c
Jonas Ådahl 604fea4
+++ b/libvncserver/auth.c
Jonas Ådahl 604fea4
@@ -37,18 +37,17 @@ void rfbClientSendString(rfbClientPtr cl, const char *reason);
Jonas Ådahl 604fea4
  * Handle security types
Jonas Ådahl 604fea4
  */
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
+/* Channel security handlers to set up a secure channel, e.g. TLS. */
Jonas Ådahl 604fea4
+static rfbSecurityHandler* channelSecurityHandlers = NULL;
Jonas Ådahl 604fea4
+
Jonas Ådahl 604fea4
+/* Security handlers when channel security is established. */
Jonas Ådahl 604fea4
 static rfbSecurityHandler* securityHandlers = NULL;
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
-/*
Jonas Ådahl 604fea4
- * This method registers a list of new security types.  
Jonas Ådahl 604fea4
- * It avoids same security type getting registered multiple times. 
Jonas Ådahl 604fea4
- * The order is not preserved if multiple security types are
Jonas Ådahl 604fea4
- * registered at one-go.
Jonas Ådahl 604fea4
- */
Jonas Ådahl 604fea4
 void
Jonas Ådahl 604fea4
-rfbRegisterSecurityHandler(rfbSecurityHandler* handler)
Jonas Ådahl 604fea4
+rfbRegisterSecurityHandlerTo(rfbSecurityHandler* handler,
Jonas Ådahl 604fea4
+                             rfbSecurityHandler** handlerList)
Jonas Ådahl 604fea4
 {
Jonas Ådahl 604fea4
-	rfbSecurityHandler *head = securityHandlers, *next = NULL;
Jonas Ådahl 604fea4
+	rfbSecurityHandler *head = *handlerList, *next = NULL;
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
 	if(handler == NULL)
Jonas Ådahl 604fea4
 		return;
Jonas Ådahl 604fea4
@@ -57,39 +56,35 @@ rfbRegisterSecurityHandler(rfbSecurityHandler* handler)
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
 	while(head != NULL) {
Jonas Ådahl 604fea4
 		if(head == handler) {
Jonas Ådahl 604fea4
-			rfbRegisterSecurityHandler(next);
Jonas Ådahl 604fea4
+			rfbRegisterSecurityHandlerTo(next, handlerList);
Jonas Ådahl 604fea4
 			return;
Jonas Ådahl 604fea4
 		}
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
 		head = head->next;
Jonas Ådahl 604fea4
 	}
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
-	handler->next = securityHandlers;
Jonas Ådahl 604fea4
-	securityHandlers = handler;
Jonas Ådahl 604fea4
+	handler->next = *handlerList;
Jonas Ådahl 604fea4
+	*handlerList = handler;
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
-	rfbRegisterSecurityHandler(next);
Jonas Ådahl 604fea4
+	rfbRegisterSecurityHandlerTo(next, handlerList);
Jonas Ådahl 604fea4
 }
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
-/*
Jonas Ådahl 604fea4
- * This method unregisters a list of security types. 
Jonas Ådahl 604fea4
- * These security types won't be available for any new
Jonas Ådahl 604fea4
- * client connection. 
Jonas Ådahl 604fea4
- */
Jonas Ådahl 604fea4
-void
Jonas Ådahl 604fea4
-rfbUnregisterSecurityHandler(rfbSecurityHandler* handler)
Jonas Ådahl 604fea4
+static void
Jonas Ådahl 604fea4
+rfbUnregisterSecurityHandlerFrom(rfbSecurityHandler* handler,
Jonas Ådahl 604fea4
+                                 rfbSecurityHandler** handlerList)
Jonas Ådahl 604fea4
 {
Jonas Ådahl 604fea4
 	rfbSecurityHandler *cur = NULL, *pre = NULL;
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
 	if(handler == NULL)
Jonas Ådahl 604fea4
 		return;
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
-	if(securityHandlers == handler) {
Jonas Ådahl 604fea4
-		securityHandlers = securityHandlers->next;
Jonas Ådahl 604fea4
-		rfbUnregisterSecurityHandler(handler->next);
Jonas Ådahl 604fea4
+	if(*handlerList == handler) {
Jonas Ådahl 604fea4
+		*handlerList = (*handlerList)->next;
Jonas Ådahl 604fea4
+		rfbUnregisterSecurityHandlerFrom(handler->next, handlerList);
Jonas Ådahl 604fea4
 		return;
Jonas Ådahl 604fea4
 	}
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
-	cur = pre = securityHandlers;
Jonas Ådahl 604fea4
+	cur = pre = *handlerList;
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
 	while(cur) {
Jonas Ådahl 604fea4
 		if(cur == handler) {
Jonas Ådahl 604fea4
@@ -99,7 +94,50 @@ rfbUnregisterSecurityHandler(rfbSecurityHandler* handler)
Jonas Ådahl 604fea4
 		pre = cur;
Jonas Ådahl 604fea4
 		cur = cur->next;
Jonas Ådahl 604fea4
 	}
Jonas Ådahl 604fea4
-	rfbUnregisterSecurityHandler(handler->next);
Jonas Ådahl 604fea4
+	rfbUnregisterSecurityHandlerFrom(handler->next, handlerList);
Jonas Ådahl 604fea4
+}
Jonas Ådahl 604fea4
+
Jonas Ådahl 604fea4
+void
Jonas Ådahl 604fea4
+rfbRegisterChannelSecurityHandler(rfbSecurityHandler* handler)
Jonas Ådahl 604fea4
+{
Jonas Ådahl 604fea4
+    rfbRegisterSecurityHandlerTo(handler, &channelSecurityHandlers);
Jonas Ådahl 604fea4
+}
Jonas Ådahl 604fea4
+
Jonas Ådahl 604fea4
+/*
Jonas Ådahl 604fea4
+ * This method unregisters a list of security types.
Jonas Ådahl 604fea4
+ * These security types won't be available for any new
Jonas Ådahl 604fea4
+ * client connection.
Jonas Ådahl 604fea4
+ */
Jonas Ådahl 604fea4
+
Jonas Ådahl 604fea4
+void
Jonas Ådahl 604fea4
+rfbUnregisterChannelSecurityHandler(rfbSecurityHandler* handler)
Jonas Ådahl 604fea4
+{
Jonas Ådahl 604fea4
+    rfbUnregisterSecurityHandlerFrom(handler, &channelSecurityHandlers);
Jonas Ådahl 604fea4
+}
Jonas Ådahl 604fea4
+
Jonas Ådahl 604fea4
+/*
Jonas Ådahl 604fea4
+ * This method registers a list of new security types.
Jonas Ådahl 604fea4
+ * It avoids same security type getting registered multiple times.
Jonas Ådahl 604fea4
+ * The order is not preserved if multiple security types are
Jonas Ådahl 604fea4
+ * registered at one-go.
Jonas Ådahl 604fea4
+ */
Jonas Ådahl 604fea4
+
Jonas Ådahl 604fea4
+void
Jonas Ådahl 604fea4
+rfbRegisterSecurityHandler(rfbSecurityHandler* handler)
Jonas Ådahl 604fea4
+{
Jonas Ådahl 604fea4
+    rfbRegisterSecurityHandlerTo(handler, &securityHandlers);
Jonas Ådahl 604fea4
+}
Jonas Ådahl 604fea4
+
Jonas Ådahl 604fea4
+/*
Jonas Ådahl 604fea4
+ * This method unregisters a list of security types.
Jonas Ådahl 604fea4
+ * These security types won't be available for any new
Jonas Ådahl 604fea4
+ * client connection.
Jonas Ådahl 604fea4
+ */
Jonas Ådahl 604fea4
+
Jonas Ådahl 604fea4
+void
Jonas Ådahl 604fea4
+rfbUnregisterSecurityHandler(rfbSecurityHandler* handler)
Jonas Ådahl 604fea4
+{
Jonas Ådahl 604fea4
+    rfbUnregisterSecurityHandlerFrom(handler, &securityHandlers);
Jonas Ådahl 604fea4
 }
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
 /*
Jonas Ådahl 604fea4
@@ -197,9 +235,22 @@ static rfbSecurityHandler VncSecurityHandlerNone = {
Jonas Ådahl 604fea4
     NULL
Jonas Ådahl 604fea4
 };
Jonas Ådahl 604fea4
                         
Jonas Ådahl 604fea4
+static int32_t
Jonas Ådahl 604fea4
+determinePrimarySecurityType(rfbClientPtr cl)
Jonas Ådahl 604fea4
+{
Jonas Ådahl 604fea4
+    if (!cl->screen->authPasswdData || cl->reverseConnection) {
Jonas Ådahl 604fea4
+        /* chk if this condition is valid or not. */
Jonas Ådahl 604fea4
+        return rfbSecTypeNone;
Jonas Ådahl 604fea4
+    } else if (cl->screen->authPasswdData) {
Jonas Ådahl 604fea4
+        return rfbSecTypeVncAuth;
Jonas Ådahl 604fea4
+    } else {
Jonas Ådahl 604fea4
+        return rfbSecTypeInvalid;
Jonas Ådahl 604fea4
+    }
Jonas Ådahl 604fea4
+}
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
-static void
Jonas Ådahl 604fea4
-rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
Jonas Ådahl 604fea4
+void
Jonas Ådahl 604fea4
+rfbSendSecurityTypeList(rfbClientPtr cl,
Jonas Ådahl 604fea4
+                        enum rfbSecurityTag exclude)
Jonas Ådahl 604fea4
 {
Jonas Ådahl 604fea4
     /* The size of the message is the count of security types +1,
Jonas Ådahl 604fea4
      * since the first byte is the number of types. */
Jonas Ådahl 604fea4
@@ -207,9 +258,10 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
Jonas Ådahl 604fea4
     rfbSecurityHandler* handler;
Jonas Ådahl 604fea4
 #define MAX_SECURITY_TYPES 255
Jonas Ådahl 604fea4
     uint8_t buffer[MAX_SECURITY_TYPES+1];
Jonas Ådahl 604fea4
-
Jonas Ådahl 604fea4
+    int32_t primaryType;
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
     /* Fill in the list of security types in the client structure. (NOTE: Not really in the client structure) */
Jonas Ådahl 604fea4
+    primaryType = determinePrimarySecurityType(cl);
Jonas Ådahl 604fea4
     switch (primaryType) {
Jonas Ådahl 604fea4
     case rfbSecTypeNone:
Jonas Ådahl 604fea4
         rfbRegisterSecurityHandler(&VncSecurityHandlerNone);
Jonas Ådahl 604fea4
@@ -221,6 +273,9 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
     for (handler = securityHandlers;
Jonas Ådahl 604fea4
 	    handler && size<MAX_SECURITY_TYPES; handler = handler->next) {
Jonas Ådahl 604fea4
+	if (exclude && (handler->securityTags & exclude))
Jonas Ådahl 604fea4
+	    continue;
Jonas Ådahl 604fea4
+
Jonas Ådahl 604fea4
 	buffer[size] = handler->type;
Jonas Ådahl 604fea4
 	size++;
Jonas Ådahl 604fea4
     }
Jonas Ådahl 604fea4
@@ -249,7 +304,29 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
Jonas Ådahl 604fea4
     cl->state = RFB_SECURITY_TYPE;
Jonas Ådahl 604fea4
 }
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
+static void
Jonas Ådahl 604fea4
+rfbSendChannelSecurityTypeList(rfbClientPtr cl)
Jonas Ådahl 604fea4
+{
Jonas Ådahl 604fea4
+    int size = 1;
Jonas Ådahl 604fea4
+    rfbSecurityHandler* handler;
Jonas Ådahl 604fea4
+    uint8_t buffer[MAX_SECURITY_TYPES+1];
Jonas Ådahl 604fea4
+
Jonas Ådahl 604fea4
+    for (handler = channelSecurityHandlers;
Jonas Ådahl 604fea4
+	    handler && size<MAX_SECURITY_TYPES; handler = handler->next) {
Jonas Ådahl 604fea4
+	buffer[size] = handler->type;
Jonas Ådahl 604fea4
+	size++;
Jonas Ådahl 604fea4
+    }
Jonas Ådahl 604fea4
+    buffer[0] = (unsigned char)size-1;
Jonas Ådahl 604fea4
+
Jonas Ådahl 604fea4
+    if (rfbWriteExact(cl, (char *)buffer, size) < 0) {
Jonas Ådahl 604fea4
+	rfbLogPerror("rfbSendSecurityTypeList: write");
Jonas Ådahl 604fea4
+	rfbCloseClient(cl);
Jonas Ådahl 604fea4
+	return;
Jonas Ådahl 604fea4
+    }
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
+    /* Dispatch client input to rfbProcessClientChannelSecurityType. */
Jonas Ådahl 604fea4
+    cl->state = RFB_CHANNEL_SECURITY_TYPE;
Jonas Ådahl 604fea4
+}
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
 /*
Jonas Ådahl 604fea4
@@ -297,18 +374,19 @@ rfbSendSecurityType(rfbClientPtr cl, int32_t securityType)
Jonas Ådahl 604fea4
 void
Jonas Ådahl 604fea4
 rfbAuthNewClient(rfbClientPtr cl)
Jonas Ådahl 604fea4
 {
Jonas Ådahl 604fea4
-    int32_t securityType = rfbSecTypeInvalid;
Jonas Ådahl 604fea4
+    int32_t securityType;
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
-    if (!cl->screen->authPasswdData || cl->reverseConnection) {
Jonas Ådahl 604fea4
-	/* chk if this condition is valid or not. */
Jonas Ådahl 604fea4
-	securityType = rfbSecTypeNone;
Jonas Ådahl 604fea4
-    } else if (cl->screen->authPasswdData) {
Jonas Ådahl 604fea4
- 	    securityType = rfbSecTypeVncAuth;
Jonas Ådahl 604fea4
-    }
Jonas Ådahl 604fea4
+    securityType = determinePrimarySecurityType(cl);
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
     if (cl->protocolMajorVersion==3 && cl->protocolMinorVersion < 7)
Jonas Ådahl 604fea4
     {
Jonas Ådahl 604fea4
 	/* Make sure we use only RFB 3.3 compatible security types. */
Jonas Ådahl 604fea4
+	if (channelSecurityHandlers) {
Jonas Ådahl 604fea4
+	    rfbLog("VNC channel security enabled - RFB 3.3 client rejected\n");
Jonas Ådahl 604fea4
+	    rfbClientConnFailed(cl, "Your viewer cannot hnadler required "
Jonas Ådahl 604fea4
+				"security methods");
Jonas Ådahl 604fea4
+	    return;
Jonas Ådahl 604fea4
+	}
Jonas Ådahl 604fea4
 	if (securityType == rfbSecTypeInvalid) {
Jonas Ådahl 604fea4
 	    rfbLog("VNC authentication disabled - RFB 3.3 client rejected\n");
Jonas Ådahl 604fea4
 	    rfbClientConnFailed(cl, "Your viewer cannot handle required "
3995c25
@@ -316,9 +394,13 @@ rfbAuthNewClient(rfbClientPtr cl)
Jonas Ådahl 604fea4
 	    return;
Jonas Ådahl 604fea4
 	}
Jonas Ådahl 604fea4
 	rfbSendSecurityType(cl, securityType);
Jonas Ådahl 604fea4
+    } else if (channelSecurityHandlers) {
3995c25
+	rfbLog("Send channel security type list\n");
Jonas Ådahl 604fea4
+	rfbSendChannelSecurityTypeList(cl);
Jonas Ådahl 604fea4
     } else {
Jonas Ådahl 604fea4
 	/* Here it's ok when securityType is set to rfbSecTypeInvalid. */
Jonas Ådahl 604fea4
-	rfbSendSecurityTypeList(cl, securityType);
3995c25
+	rfbLog("Send channel security type 'none'\n");
Jonas Ådahl 604fea4
+	rfbSendSecurityTypeList(cl, RFB_SECURITY_TAG_NONE);
Jonas Ådahl 604fea4
     }
Jonas Ådahl 604fea4
 }
Jonas Ådahl 604fea4
 
3995c25
@@ -332,6 +414,7 @@ rfbProcessClientSecurityType(rfbClientPtr cl)
Jonas Ådahl 604fea4
     int n;
Jonas Ådahl 604fea4
     uint8_t chosenType;
Jonas Ådahl 604fea4
     rfbSecurityHandler* handler;
Jonas Ådahl 604fea4
+    rfbSecurityHandler* handlerListHead;
Jonas Ådahl 604fea4
     
Jonas Ådahl 604fea4
     /* Read the security type. */
Jonas Ådahl 604fea4
     n = rfbReadExact(cl, (char *)&chosenType, 1);
3995c25
@@ -344,8 +427,17 @@ rfbProcessClientSecurityType(rfbClientPtr cl)
Jonas Ådahl 604fea4
 	return;
Jonas Ådahl 604fea4
     }
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
+    switch (cl->state) {
Jonas Ådahl 604fea4
+    case RFB_CHANNEL_SECURITY_TYPE:
Jonas Ådahl 604fea4
+        handlerListHead = channelSecurityHandlers;
Jonas Ådahl 604fea4
+        break;
Jonas Ådahl 604fea4
+    case RFB_SECURITY_TYPE:
Jonas Ådahl 604fea4
+        handlerListHead = securityHandlers;
Jonas Ådahl 604fea4
+        break;
Jonas Ådahl 604fea4
+    }
Jonas Ådahl 604fea4
+
Jonas Ådahl 604fea4
     /* Make sure it was present in the list sent by the server. */
Jonas Ådahl 604fea4
-    for (handler = securityHandlers; handler; handler = handler->next) {
Jonas Ådahl 604fea4
+    for (handler = handlerListHead; handler; handler = handler->next) {
Jonas Ådahl 604fea4
 	if (chosenType == handler->type) {
Jonas Ådahl 604fea4
 	      rfbLog("rfbProcessClientSecurityType: executing handler for type %d\n", chosenType);
Jonas Ådahl 604fea4
 	      handler->handler(cl);
Jonas Ådahl 604fea4
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
3995c25
index cee87dbb..6efede61 100644
Jonas Ådahl 604fea4
--- a/libvncserver/rfbserver.c
Jonas Ådahl 604fea4
+++ b/libvncserver/rfbserver.c
3995c25
@@ -654,6 +654,7 @@ rfbProcessClientMessage(rfbClientPtr cl)
Jonas Ådahl 604fea4
     case RFB_PROTOCOL_VERSION:
Jonas Ådahl 604fea4
         rfbProcessClientProtocolVersion(cl);
Jonas Ådahl 604fea4
         return;
Jonas Ådahl 604fea4
+    case RFB_CHANNEL_SECURITY_TYPE:
Jonas Ådahl 604fea4
     case RFB_SECURITY_TYPE:
Jonas Ådahl 604fea4
         rfbProcessClientSecurityType(cl);
Jonas Ådahl 604fea4
         return;
Jonas Ådahl 604fea4
diff --git a/rfb/rfb.h b/rfb/rfb.h
3995c25
index 3c0b25a3..d136f884 100644
Jonas Ådahl 604fea4
--- a/rfb/rfb.h
Jonas Ådahl 604fea4
+++ b/rfb/rfb.h
3995c25
@@ -144,6 +144,11 @@ typedef struct {
Jonas Ådahl 604fea4
   } data; /**< there have to be count*3 entries */
Jonas Ådahl 604fea4
 } rfbColourMap;
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
+enum rfbSecurityTag {
Jonas Ådahl 604fea4
+    RFB_SECURITY_TAG_NONE = 0,
Jonas Ådahl 604fea4
+    RFB_SECURITY_TAG_CHANNEL = 1 << 0
Jonas Ådahl 604fea4
+};
Jonas Ådahl 604fea4
+
Jonas Ådahl 604fea4
 /**
Jonas Ådahl 604fea4
  * Security handling (RFB protocol version 3.7)
Jonas Ådahl 604fea4
  */
3995c25
@@ -152,6 +157,7 @@ typedef struct _rfbSecurity {
Jonas Ådahl 604fea4
 	uint8_t type;
Jonas Ådahl 604fea4
 	void (*handler)(struct _rfbClientRec* cl);
Jonas Ådahl 604fea4
 	struct _rfbSecurity* next;
Jonas Ådahl 604fea4
+	enum rfbSecurityTag securityTags;
Jonas Ådahl 604fea4
 } rfbSecurityHandler;
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
 /**
3995c25
@@ -480,7 +486,7 @@ typedef struct _rfbClientRec {
Jonas Ådahl 604fea4
                                 /** Possible client states: */
Jonas Ådahl 604fea4
     enum {
Jonas Ådahl 604fea4
         RFB_PROTOCOL_VERSION,   /**< establishing protocol version */
Jonas Ådahl 604fea4
-	RFB_SECURITY_TYPE,      /**< negotiating security (RFB v.3.7) */
Jonas Ådahl 604fea4
+        RFB_SECURITY_TYPE,      /**< negotiating security (RFB v.3.7) */
Jonas Ådahl 604fea4
         RFB_AUTHENTICATION,     /**< authenticating */
Jonas Ådahl 604fea4
         RFB_INITIALISATION,     /**< sending initialisation messages */
Jonas Ådahl 604fea4
         RFB_NORMAL,             /**< normal protocol messages */
3995c25
@@ -488,7 +494,9 @@ typedef struct _rfbClientRec {
Jonas Ådahl 604fea4
         /* Ephemeral internal-use states that will never be seen by software
Jonas Ådahl 604fea4
          * using LibVNCServer to provide services: */
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
-        RFB_INITIALISATION_SHARED /**< sending initialisation messages with implicit shared-flag already true */
Jonas Ådahl 604fea4
+        RFB_INITIALISATION_SHARED, /**< sending initialisation messages with implicit shared-flag already true */
Jonas Ådahl 604fea4
+
Jonas Ådahl 604fea4
+        RFB_CHANNEL_SECURITY_TYPE, /**< negotiating security (RFB v.3.7) */
Jonas Ådahl 604fea4
     } state;
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
     rfbBool reverseConnection;
3995c25
@@ -840,6 +848,9 @@ extern void rfbProcessClientSecurityType(rfbClientPtr cl);
Jonas Ådahl 604fea4
 extern void rfbAuthProcessClientMessage(rfbClientPtr cl);
Jonas Ådahl 604fea4
 extern void rfbRegisterSecurityHandler(rfbSecurityHandler* handler);
Jonas Ådahl 604fea4
 extern void rfbUnregisterSecurityHandler(rfbSecurityHandler* handler);
Jonas Ådahl 604fea4
+extern void rfbRegisterChannelSecurityHandler(rfbSecurityHandler* handler);
Jonas Ådahl 604fea4
+extern void rfbUnregisterChannelSecurityHandler(rfbSecurityHandler* handler);
Jonas Ådahl 604fea4
+extern void rfbSendSecurityTypeList(rfbClientPtr cl, enum rfbSecurityTag exclude);
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
 /* rre.c */
Jonas Ådahl 604fea4
 
Jonas Ådahl 604fea4
-- 
3995c25
2.25.4
Jonas Ådahl 604fea4