From 5f9a07d7e1613dbccd5a27e845dbb8a7f2a27b2e Mon Sep 17 00:00:00 2001 From: Tobias Junghans Date: Tue, 6 Nov 2018 14:22:56 +0100 Subject: [PATCH] LibVNCClient: add support for custom auth handlers This allows to register custom authentication handlers in order to support additional security types. --- client_examples/backchannel.c | 4 +++- libvncclient/rfbproto.c | 29 +++++++++++++++++++++++++++++ rfb/rfbclient.h | 3 +++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/client_examples/backchannel.c b/client_examples/backchannel.c index 04d154e..a7db9a0 100644 --- a/client_examples/backchannel.c +++ b/client_examples/backchannel.c @@ -71,7 +71,9 @@ static rfbClientProtocolExtension backChannel = { backChannelEncodings, /* encodings */ NULL, /* handleEncoding */ handleBackChannelMessage, /* handleMessage */ - NULL /* next extension */ + NULL, /* next extension */ + NULL, /* securityTypes */ + NULL /* handleAuthentication */ }; int diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c index ac2a983..fbe579c 100644 --- a/libvncclient/rfbproto.c +++ b/libvncclient/rfbproto.c @@ -474,9 +474,11 @@ ReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth) uint8_t count=0; uint8_t loop=0; uint8_t flag=0; + rfbBool extAuthHandler; uint8_t tAuth[256]; char buf1[500],buf2[10]; uint32_t authScheme; + rfbClientProtocolExtension* e; if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE; @@ -495,7 +497,18 @@ ReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth) if (!ReadFromRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE; rfbClientLog("%d) Received security type %d\n", loop, tAuth[loop]); if (flag) continue; + extAuthHandler=FALSE; + for (e = rfbClientExtensions; e; e = e->next) { + if (!e->handleAuthentication) continue; + uint32_t const* secType; + for (secType = e->securityTypes; secType && *secType; secType++) { + if (tAuth[loop]==*secType) { + extAuthHandler=TRUE; + } + } + } if (tAuth[loop]==rfbVncAuth || tAuth[loop]==rfbNoAuth || + extAuthHandler || #if defined(LIBVNCSERVER_HAVE_GNUTLS) || defined(LIBVNCSERVER_HAVE_LIBSSL) tAuth[loop]==rfbVeNCrypt || #endif @@ -1176,6 +1189,22 @@ InitialiseRFBConnection(rfbClient* client) break; default: + { + rfbBool authHandled=FALSE; + rfbClientProtocolExtension* e; + for (e = rfbClientExtensions; e; e = e->next) { + uint32_t const* secType; + if (!e->handleAuthentication) continue; + for (secType = e->securityTypes; secType && *secType; secType++) { + if (authScheme==*secType) { + if (!e->handleAuthentication(client, authScheme)) return FALSE; + if (!rfbHandleAuthResult(client)) return FALSE; + authHandled=TRUE; + } + } + } + if (authHandled) break; + } rfbClientLog("Unknown authentication scheme from VNC server: %d\n", (int)authScheme); return FALSE; diff --git a/rfb/rfbclient.h b/rfb/rfbclient.h index 87f4eaa..1a80f0d 100644 --- a/rfb/rfbclient.h +++ b/rfb/rfbclient.h @@ -620,6 +620,9 @@ typedef struct _rfbClientProtocolExtension { rfbBool (*handleMessage)(rfbClient* cl, rfbServerToClientMsg* message); struct _rfbClientProtocolExtension* next; + uint32_t const* securityTypes; + /** returns TRUE if it handled the authentication */ + rfbBool (*handleAuthentication)(rfbClient* cl, uint32_t authScheme); } rfbClientProtocolExtension; void rfbClientRegisterExtension(rfbClientProtocolExtension* e);