From b019572e73be8f861626943ced1a9e48ebeba838 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Fri, 1 Jan 2010 12:02:30 +0800 Subject: [PATCH] Add support for viewers to select security types on demand Signed-off-by: Vic Lee Signed-off-by: Johannes Schindelin --- libvncclient/rfbproto.c | 59 ++++++++++++++++++++++++++++++++++++---- libvncclient/vncviewer.c | 3 ++ rfb/rfbclient.h | 5 ++++ 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c index d0e324d..83cfbf9 100644 --- a/libvncclient/rfbproto.c +++ b/libvncclient/rfbproto.c @@ -509,12 +509,30 @@ ReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth) if (tAuth[loop]==rfbVncAuth || tAuth[loop]==rfbNoAuth || tAuth[loop]==rfbMSLogon || (!subAuth && (tAuth[loop]==rfbTLS || tAuth[loop]==rfbVeNCrypt))) { - flag++; - authScheme=tAuth[loop]; - rfbClientLog("Selecting security type %d (%d/%d in the list)\n", authScheme, loop, count); - /* send back a single byte indicating which security type to use */ - if (!WriteToRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE; - + if (!subAuth && client->clientAuthSchemes) + { + int i; + for (i=0;client->clientAuthSchemes[i];i++) + { + if (client->clientAuthSchemes[i]==(uint32_t)tAuth[loop]) + { + flag++; + authScheme=tAuth[loop]; + break; + } + } + } + else + { + flag++; + authScheme=tAuth[loop]; + } + if (flag) + { + rfbClientLog("Selecting security type %d (%d/%d in the list)\n", authScheme, loop, count); + /* send back a single byte indicating which security type to use */ + if (!WriteToRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE; + } } } if (authScheme==0) @@ -718,6 +736,35 @@ HandleMSLogonAuth(rfbClient *client) return TRUE; } +/* + * SetClientAuthSchemes. + */ + +void +SetClientAuthSchemes(rfbClient* client,const uint32_t *authSchemes, int size) +{ + int i; + + if (client->clientAuthSchemes) + { + free(client->clientAuthSchemes); + client->clientAuthSchemes = NULL; + } + if (authSchemes) + { + if (size<0) + { + /* If size<0 we assume the passed-in list is also 0-terminate, so we + * calculate the size here */ + for (size=0;authSchemes[size];size++) ; + } + client->clientAuthSchemes = (uint32_t*)malloc(sizeof(uint32_t)*(size+1)); + for (i=0;iclientAuthSchemes[i] = authSchemes[i]; + client->clientAuthSchemes[size] = 0; + } +} + /* * InitialiseRFBConnection. */ diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c index 0361827..111a7f6 100644 --- a/libvncclient/vncviewer.c +++ b/libvncclient/vncviewer.c @@ -192,6 +192,7 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel, #endif client->sock = -1; client->listenSock = -1; + client->clientAuthSchemes = NULL; return client; } @@ -341,5 +342,7 @@ void rfbClientCleanup(rfbClient* client) { close(client->listenSock); free(client->desktopName); free(client->serverHost); + if (client->clientAuthSchemes) + free(client->clientAuthSchemes); free(client); } diff --git a/rfb/rfbclient.h b/rfb/rfbclient.h index d70ece1..a82ea22 100644 --- a/rfb/rfbclient.h +++ b/rfb/rfbclient.h @@ -305,6 +305,10 @@ typedef struct _rfbClient { * be bypassed. */ GetCredentialProc GetCredential; + + /* The 0-terminated security types supported by the client. + * Set by function SetClientAuthSchemes() */ + uint32_t *clientAuthSchemes; } rfbClient; /* cursor.c */ @@ -322,6 +326,7 @@ extern rfbBool rfbEnableClientLogging; typedef void (*rfbClientLogProc)(const char *format, ...); extern rfbClientLogProc rfbClientLog,rfbClientErr; extern rfbBool ConnectToRFBServer(rfbClient* client,const char *hostname, int port); +extern void SetClientAuthSchemes(rfbClient* client,const uint32_t *authSchemes, int size); extern rfbBool InitialiseRFBConnection(rfbClient* client); extern rfbBool SetFormatAndEncodings(rfbClient* client); extern rfbBool SendIncrementalFramebufferUpdateRequest(rfbClient* client);