Add anonymous TLS support in libvncclient

Signed-off-by: Vic Lee <llyzs@163.com>
pull/1/head
Vic Lee 14 years ago committed by Johannes Schindelin
parent 0c061f2a27
commit 58a8df6ff2

@ -667,6 +667,22 @@ if test ! -z "$MINGW"; then
fi
AC_SUBST(WSOCKLIB)
# Checks for GnuTLS
AH_TEMPLATE(WITH_CLIENT_TLS, [Enable support for gnutls in libvncclient])
AC_ARG_WITH(gnutls,
[ --without-gnutls disable support for gnutls],,)
AC_ARG_WITH(client-tls,
[ --without-client-tls disable support for gnutls in libvncclient],,)
if test "x$with_gnutls" != "xno"; then
PKG_CHECK_MODULES(GNUTLS, gnutls >= 2.8.0)
CFLAGS="$CFLAGS $GNUTLS_CFLAGS"
LIBS="$LIBS $GNUTLS_LIBS"
if test "x$with_client_tls" != "xno"; then
AC_DEFINE(WITH_CLIENT_TLS)
fi
fi
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h sys/timeb.h syslog.h unistd.h])

@ -1,12 +1,12 @@
INCLUDES = -I$(top_srcdir)
libvncclient_la_SOURCES=cursor.c listen.c rfbproto.c sockets.c vncviewer.c minilzo.c
libvncclient_la_SOURCES=cursor.c listen.c rfbproto.c sockets.c vncviewer.c minilzo.c tls.c
noinst_HEADERS=lzoconf.h minilzo.h
noinst_HEADERS=lzoconf.h minilzo.h tls.h
rfbproto.o: rfbproto.c corre.c hextile.c rre.c tight.c zlib.c zrle.c ultra.c
EXTRA_DIST=corre.c hextile.c rre.c tight.c zlib.c zrle.c ultra.c
EXTRA_DIST=corre.c hextile.c rre.c tight.c zlib.c zrle.c ultra.c tls.c
$(libvncclient_la_OBJECTS): ../rfb/rfbclient.h

@ -53,6 +53,7 @@
#include <time.h>
#include "minilzo.h"
#include "tls.h"
/*
* rfbClientLog prints a time-stamped message to the log file (stderr).
@ -454,6 +455,119 @@ rfbHandleAuthResult(rfbClient* client)
return FALSE;
}
static void
ReadReason(rfbClient* client)
{
uint32_t reasonLen;
char *reason;
/* we have an error following */
if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return;
reasonLen = rfbClientSwap32IfLE(reasonLen);
reason = malloc(reasonLen+1);
if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return; }
reason[reasonLen]=0;
rfbClientLog("VNC connection failed: %s\n",reason);
free(reason);
}
static rfbBool
ReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth)
{
uint8_t count=0;
uint8_t loop=0;
uint8_t flag=0;
uint8_t tAuth[256];
char buf1[500],buf2[10];
uint32_t authScheme;
if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE;
if (count==0)
{
rfbClientLog("List of security types is ZERO, expecting an error to follow\n");
ReadReason(client);
return FALSE;
}
if (count>sizeof(tAuth))
{
rfbClientLog("%d security types are too many; maximum is %d\n", count, sizeof(tAuth));
return FALSE;
}
rfbClientLog("We have %d security types to read\n", count);
authScheme=0;
/* now, we have a list of available security types to read ( uint8_t[] ) */
for (loop=0;loop<count;loop++)
{
if (!ReadFromRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE;
rfbClientLog("%d) Received security type %d\n", loop, tAuth[loop]);
if (flag) continue;
if (tAuth[loop]==rfbVncAuth || tAuth[loop]==rfbNoAuth ||
(!subAuth && tAuth[loop]==rfbTLS))
{
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 (authScheme==0)
{
memset(buf1, 0, sizeof(buf1));
for (loop=0;loop<count;loop++)
{
if (strlen(buf1)>=sizeof(buf1)-1) break;
snprintf(buf2, sizeof(buf2), (loop>0 ? ", %d" : "%d"), (int)tAuth[loop]);
strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1);
}
rfbClientLog("Unknown authentication scheme from VNC server: %s\n",
buf1);
return FALSE;
}
*result = authScheme;
return TRUE;
}
static rfbBool
HandleVncAuth(rfbClient *client)
{
uint8_t challenge[CHALLENGESIZE];
char *passwd=NULL;
int i;
if (!ReadFromRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
if (client->serverPort!=-1) { /* if not playing a vncrec file */
if (client->GetPassword)
passwd = client->GetPassword(client);
if ((!passwd) || (strlen(passwd) == 0)) {
rfbClientLog("Reading password failed\n");
return FALSE;
}
if (strlen(passwd) > 8) {
passwd[8] = '\0';
}
rfbClientEncryptBytes(challenge, passwd);
/* Lose the password from memory */
for (i = strlen(passwd); i >= 0; i--) {
passwd[i] = '\0';
}
free(passwd);
if (!WriteToRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
}
/* Handle the SecurityResult message */
if (!rfbHandleAuthResult(client)) return FALSE;
return TRUE;
}
/*
* InitialiseRFBConnection.
@ -464,11 +578,8 @@ InitialiseRFBConnection(rfbClient* client)
{
rfbProtocolVersionMsg pv;
int major,minor;
uint32_t authScheme, reasonLen;
char *reason;
uint8_t challenge[CHALLENGESIZE];
char *passwd=NULL;
int i;
uint32_t authScheme;
uint32_t subAuthScheme;
rfbClientInitMsg ci;
/* if the connection is immediately closed, don't report anything, so
@ -528,64 +639,7 @@ InitialiseRFBConnection(rfbClient* client)
/* 3.7 and onwards sends a # of security types first */
if (client->major==3 && client->minor > 6)
{
uint8_t count=0;
uint8_t loop=0;
uint8_t flag=0;
uint8_t tAuth[256];
char buf1[500],buf2[10];
if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE;
if (count==0)
{
rfbClientLog("List of security types is ZERO, expecting an error to follow\n");
/* we have an error following */
if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
reasonLen = rfbClientSwap32IfLE(reasonLen);
reason = malloc(reasonLen+1);
if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
reason[reasonLen]=0;
rfbClientLog("VNC connection failed: %s\n",reason);
free(reason);
return FALSE;
}
if (count>sizeof(tAuth))
{
rfbClientLog("%d security types are too many; maximum is %d\n", count, sizeof(tAuth));
return FALSE;
}
rfbClientLog("We have %d security types to read\n", count);
authScheme=0;
/* now, we have a list of available security types to read ( uint8_t[] ) */
for (loop=0;loop<count;loop++)
{
if (!ReadFromRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE;
rfbClientLog("%d) Received security type %d\n", loop, tAuth[loop]);
if ((flag==0) && ((tAuth[loop]==rfbVncAuth) || (tAuth[loop]==rfbNoAuth)))
{
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 (authScheme==0)
{
memset(buf1, 0, sizeof(buf1));
for (loop=0;loop<count;loop++)
{
if (strlen(buf1)>=sizeof(buf1)-1) break;
snprintf(buf2, sizeof(buf2), (loop>0 ? ", %d" : "%d"), (int)tAuth[loop]);
strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1);
}
rfbClientLog("Unknown authentication scheme from VNC server: %s\n",
buf1);
return FALSE;
}
if (!ReadSupportedSecurityType(client, &authScheme, FALSE)) return FALSE;
}
else
{
@ -594,19 +648,12 @@ InitialiseRFBConnection(rfbClient* client)
}
rfbClientLog("Selected Security Scheme %d\n", authScheme);
client->authScheme = authScheme;
switch (authScheme) {
case rfbConnFailed:
if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
reasonLen = rfbClientSwap32IfLE(reasonLen);
reason = malloc(reasonLen+1);
if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
reason[reasonLen]=0;
rfbClientLog("VNC connection failed: %s\n", reason);
free(reason);
ReadReason(client);
return FALSE;
case rfbNoAuth:
@ -619,33 +666,38 @@ InitialiseRFBConnection(rfbClient* client)
break;
case rfbVncAuth:
if (!ReadFromRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
if (!HandleVncAuth(client)) return FALSE;
break;
if (client->serverPort!=-1) { /* if not playing a vncrec file */
if (client->GetPassword)
passwd = client->GetPassword(client);
case rfbTLS:
if (!HandleAnonTLSAuth(client)) return FALSE;
/* After the TLS session is established, sub auth types are expected.
* Note that all following reading/writing are through the TLS session from here.
*/
if (!ReadSupportedSecurityType(client, &subAuthScheme, TRUE)) return FALSE;
client->subAuthScheme = subAuthScheme;
if ((!passwd) || (strlen(passwd) == 0)) {
rfbClientLog("Reading password failed\n");
switch (subAuthScheme) {
case rfbConnFailed:
ReadReason(client);
return FALSE;
}
if (strlen(passwd) > 8) {
passwd[8] = '\0';
}
rfbClientEncryptBytes(challenge, passwd);
case rfbNoAuth:
rfbClientLog("No sub authentication needed\n");
if (!rfbHandleAuthResult(client)) return FALSE;
break;
/* Lose the password from memory */
for (i = strlen(passwd); i >= 0; i--) {
passwd[i] = '\0';
}
free(passwd);
case rfbVncAuth:
if (!HandleVncAuth(client)) return FALSE;
break;
if (!WriteToRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
default:
rfbClientLog("Unknown sub authentication scheme from VNC server: %d\n",
(int)subAuthScheme);
return FALSE;
}
/* Handle the SecurityResult message */
if (!rfbHandleAuthResult(client)) return FALSE;
break;
default:

@ -43,6 +43,7 @@
#include <arpa/inet.h>
#include <netdb.h>
#endif
#include "tls.h"
void PrintInHex(char *buf, int len);
@ -127,7 +128,16 @@ ReadFromRFBServer(rfbClient* client, char *out, unsigned int n)
if (n <= RFB_BUF_SIZE) {
while (client->buffered < n) {
int i = read(client->sock, client->buf + client->buffered, RFB_BUF_SIZE - client->buffered);
int i;
#ifdef LIBVNCSERVER_WITH_CLIENT_TLS
if (client->tlsSession) {
i = ReadFromTLS(client, client->buf + client->buffered, RFB_BUF_SIZE - client->buffered);
} else {
#endif
i = read(client->sock, client->buf + client->buffered, RFB_BUF_SIZE - client->buffered);
#ifdef LIBVNCSERVER_WITH_CLIENT_TLS
}
#endif
if (i <= 0) {
if (i < 0) {
#ifdef WIN32
@ -159,7 +169,16 @@ ReadFromRFBServer(rfbClient* client, char *out, unsigned int n)
} else {
while (n > 0) {
int i = read(client->sock, out, n);
int i;
#ifdef LIBVNCSERVER_WITH_CLIENT_TLS
if (client->tlsSession) {
i = ReadFromTLS(client, out, n);
} else {
#endif
i = read(client->sock, out, n);
#ifdef LIBVNCSERVER_WITH_CLIENT_TLS
}
#endif
if (i <= 0) {
if (i < 0) {
#ifdef WIN32
@ -213,6 +232,16 @@ WriteToRFBServer(rfbClient* client, char *buf, int n)
if (client->serverPort==-1)
return TRUE; /* vncrec playing */
#ifdef LIBVNCSERVER_WITH_CLIENT_TLS
if (client->tlsSession) {
/* WriteToTLS() will guarantee either everything is written, or error/eof returns */
i = WriteToTLS(client, buf, n);
if (i <= 0) return FALSE;
return TRUE;
}
#endif
while (i < n) {
j = write(client->sock, buf + i, (n - i));
if (j <= 0) {

@ -0,0 +1,275 @@
/*
* Copyright (C) 2009 Vic Lee.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include <rfb/rfbclient.h>
#include <errno.h>
#include "tls.h"
#ifdef LIBVNCSERVER_WITH_CLIENT_TLS
static const int rfbCertTypePriority[] = { GNUTLS_CRT_X509, 0 };
static const int rfbProtoPriority[]= { GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 };
static const int rfbKXPriority[] = {GNUTLS_KX_DHE_DSS, GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0};
static const int rfbKXAnon[] = {GNUTLS_KX_ANON_DH, 0};
#define DH_BITS 1024
static gnutls_dh_params_t rfbDHParams;
static rfbBool rfbTLSInitialized = FALSE;
static rfbBool
InitializeTLS(void)
{
int ret;
if (rfbTLSInitialized) return TRUE;
if ((ret = gnutls_global_init()) < 0 ||
(ret = gnutls_dh_params_init(&rfbDHParams)) < 0 ||
(ret = gnutls_dh_params_generate2(rfbDHParams, DH_BITS)) < 0)
{
rfbClientLog("Failed to initialized GnuTLS: %s.\n", gnutls_strerror(ret));
return FALSE;
}
rfbClientLog("GnuTLS initialized.\n");
rfbTLSInitialized = TRUE;
return TRUE;
}
static ssize_t
PushTLS(gnutls_transport_ptr_t transport, const void *data, size_t len)
{
rfbClient *client = (rfbClient*)transport;
int ret;
while (1)
{
ret = write(client->sock, data, len);
if (ret < 0)
{
if (errno == EINTR) continue;
return -1;
}
return ret;
}
}
static ssize_t
PullTLS(gnutls_transport_ptr_t transport, void *data, size_t len)
{
rfbClient *client = (rfbClient*)transport;
int ret;
while (1)
{
ret = read(client->sock, data, len);
if (ret < 0)
{
if (errno == EINTR) continue;
return -1;
}
return ret;
}
}
static rfbBool
InitializeTLSSession(rfbClient* client, rfbBool anonTLS)
{
int ret;
if (client->tlsSession) return TRUE;
if ((ret = gnutls_init(&client->tlsSession, GNUTLS_CLIENT)) < 0)
{
rfbClientLog("Failed to initialized TLS session: %s.\n", gnutls_strerror(ret));
return FALSE;
}
if ((ret = gnutls_set_default_priority(client->tlsSession)) < 0 ||
(ret = gnutls_kx_set_priority(client->tlsSession, anonTLS ? rfbKXAnon : rfbKXPriority)) < 0 ||
(ret = gnutls_certificate_type_set_priority(client->tlsSession, rfbCertTypePriority)) < 0 ||
(ret = gnutls_protocol_set_priority(client->tlsSession, rfbProtoPriority)) < 0)
{
FreeTLS(client);
rfbClientLog("Failed to set TLS priority: %s.\n", gnutls_strerror(ret));
return FALSE;
}
gnutls_transport_set_ptr(client->tlsSession, (gnutls_transport_ptr_t)client);
gnutls_transport_set_push_function(client->tlsSession, PushTLS);
gnutls_transport_set_pull_function(client->tlsSession, PullTLS);
rfbClientLog("TLS session initialized.\n");
return TRUE;
}
static rfbBool
SetTLSAnonCredential(rfbClient* client)
{
gnutls_anon_client_credentials anonCred;
int ret;
if ((ret = gnutls_anon_allocate_client_credentials(&anonCred)) < 0 ||
(ret = gnutls_credentials_set(client->tlsSession, GNUTLS_CRD_ANON, anonCred)) < 0)
{
FreeTLS(client);
rfbClientLog("Failed to create anonymous credentials: %s", gnutls_strerror(ret));
return FALSE;
}
rfbClientLog("TLS anonymous credential created.\n");
return TRUE;
}
static rfbBool
HandshakeTLS(rfbClient* client)
{
int timeout = 15;
int ret;
while (timeout > 0 && (ret = gnutls_handshake(client->tlsSession)) < 0)
{
if (!gnutls_error_is_fatal(ret))
{
rfbClientLog("TLS handshake blocking.\n");
sleep(1);
timeout--;
continue;
}
rfbClientLog("TLS handshake failed: %s.\n", gnutls_strerror(ret));
FreeTLS(client);
return FALSE;
}
if (timeout <= 0)
{
rfbClientLog("TLS handshake timeout.\n");
FreeTLS(client);
return FALSE;
}
rfbClientLog("TLS handshake done.\n");
return TRUE;
}
#endif
rfbBool
HandleAnonTLSAuth(rfbClient* client)
{
#ifdef LIBVNCSERVER_WITH_CLIENT_TLS
if (!InitializeTLS() || !InitializeTLSSession(client, TRUE)) return FALSE;
if (!SetTLSAnonCredential(client)) return FALSE;
if (!HandshakeTLS(client)) return FALSE;
return TRUE;
#else
rfbClientLog("TLS is not supported.\n");
return FALSE;
#endif
}
rfbBool
HandleVeNCryptAuth(rfbClient* client)
{
#ifdef LIBVNCSERVER_WITH_CLIENT_TLS
int ret;
if (!InitializeTLS() || !InitializeTLSSession(client, FALSE)) return FALSE;
/* TODO: read VeNCrypt version, etc */
/* TODO: call GetCredential and set to TLS session */
if (!HandshakeTLS(client)) return FALSE;
/* TODO: validate certificate */
return TRUE;
#else
rfbClientLog("TLS is not supported.\n");
return FALSE;
#endif
}
int
ReadFromTLS(rfbClient* client, char *out, unsigned int n)
{
#ifdef LIBVNCSERVER_WITH_CLIENT_TLS
ssize_t ret;
ret = gnutls_record_recv(client->tlsSession, out, n);
if (ret >= 0) return ret;
if (ret == GNUTLS_E_REHANDSHAKE || ret == GNUTLS_E_AGAIN)
{
errno = EAGAIN;
} else
{
rfbClientLog("Error reading from TLS: %s.\n", gnutls_strerror(ret));
errno = EINTR;
}
return -1;
#else
rfbClientLog("TLS is not supported.\n");
errno = EINTR;
return -1;
#endif
}
int
WriteToTLS(rfbClient* client, char *buf, unsigned int n)
{
#ifdef LIBVNCSERVER_WITH_CLIENT_TLS
unsigned int offset = 0;
ssize_t ret;
while (offset < n)
{
ret = gnutls_record_send(client->tlsSession, buf+offset, (size_t)(n-offset));
if (ret == 0) continue;
if (ret < 0)
{
if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) continue;
rfbClientLog("Error writing to TLS: %s.\n", gnutls_strerror(ret));
return -1;
}
offset += (unsigned int)ret;
}
return offset;
#else
rfbClientLog("TLS is not supported.\n");
errno = EINTR;
return -1;
#endif
}
void FreeTLS(rfbClient* client)
{
#ifdef LIBVNCSERVER_WITH_CLIENT_TLS
if (client->tlsSession)
{
gnutls_deinit(client->tlsSession);
client->tlsSession = NULL;
}
#endif
}

@ -0,0 +1,51 @@
#ifndef TLS_H
#define TLS_H
/*
* Copyright (C) 2009 Vic Lee.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
/* Handle Anonymous TLS Authentication (18) with the server.
* After authentication, client->tlsSession will be set.
*/
rfbBool HandleAnonTLSAuth(rfbClient* client);
/* Handle VeNCrypt Authentication (19) with the server.
* The callback function GetX509Credential will be called.
* After authentication, client->tlsSession will be set.
*/
rfbBool HandleVeNCryptAuth(rfbClient* client);
/* Read desired bytes from TLS session.
* It's a wrapper function over gnutls_record_recv() and return values
* are same as read(), that is, >0 for actual bytes read, 0 for EOF,
* or EAGAIN, EINTR.
* This should be a non-blocking call. Blocking is handled in sockets.c.
*/
int ReadFromTLS(rfbClient* client, char *out, unsigned int n);
/* Write desired bytes to TLS session.
* It's a wrapper function over gnutls_record_send() and it will be
* blocking call, until all bytes are written or error returned.
*/
int WriteToTLS(rfbClient* client, char *buf, unsigned int n);
/* Free TLS resources */
void FreeTLS(rfbClient* client);
#endif /* TLS_H */

@ -30,6 +30,7 @@
#include <string.h>
#include <time.h>
#include <rfb/rfbclient.h>
#include "tls.h"
static void Dummy(rfbClient* client) {
}
@ -179,6 +180,13 @@ rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,
client->CurrentKeyboardLedState = 0;
client->HandleKeyboardLedState = (HandleKeyboardLedStateProc)DummyPoint;
client->authScheme = 0;
client->subAuthScheme = 0;
client->GetCredential = NULL;
#ifdef LIBVNCSERVER_WITH_CLIENT_TLS
client->tlsSession = NULL;
#endif
return client;
}
@ -318,6 +326,7 @@ void rfbClientCleanup(rfbClient* client) {
#endif
#endif
FreeTLS(client);
if (client->sock > 0)
close(client->sock);
free(client->desktopName);

@ -33,6 +33,9 @@
#include <unistd.h>
#include <rfb/rfbproto.h>
#include <rfb/keysym.h>
#ifdef LIBVNCSERVER_WITH_CLIENT_TLS
#include <gnutls/gnutls.h>
#endif
#define rfbClientSwap16IfLE(s) \
(*(char *)&client->endianTest ? ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) : (s))
@ -98,6 +101,24 @@ typedef struct {
int scaleSetting; /* 0 means no scale set, else 1/scaleSetting */
} AppData;
/* For GetCredentialProc callback function to return */
typedef union _rfbCredential
{
/* VeNCrypt */
struct
{
char *x509CACertFile;
char *x509CACrlFile;
char *x509ClientCertFile;
char *x509ClientKeyFile;
} x509Credential;
/* MSLogon */
struct
{
char *username;
char *password;
} userCredential;
} rfbCredential;
struct _rfbClient;
@ -108,6 +129,7 @@ typedef void (*SoftCursorLockAreaProc)(struct _rfbClient* client, int x, int y,
typedef void (*SoftCursorUnlockScreenProc)(struct _rfbClient* client);
typedef void (*GotFrameBufferUpdateProc)(struct _rfbClient* client, int x, int y, int w, int h);
typedef char* (*GetPasswordProc)(struct _rfbClient* client);
typedef rfbCredential* (*GetCredentialProc)(struct _rfbClient* client, uint8_t securityType);
typedef rfbBool (*MallocFrameBufferProc)(struct _rfbClient* client);
typedef void (*GotXCutTextProc)(struct _rfbClient* client, const char *text, int textlen);
typedef void (*BellProc)(struct _rfbClient* client);
@ -249,6 +271,22 @@ typedef struct _rfbClient {
/* negotiated protocol version */
int major, minor;
/* The selected security types */
uint32_t authScheme, subAuthScheme;
#ifdef LIBVNCSERVER_WITH_CLIENT_TLS
/* The TLS session for Anonymous TLS and VeNCrypt */
gnutls_session_t tlsSession;
#endif
/* To support security types that requires user input (except VNC password
* authentication), for example VeNCrypt and MSLogon, this callback function
* must be set before the authentication. Otherwise, it implicates that the
* caller application does not support it and related security types should
* be bypassed.
*/
GetCredentialProc GetCredential;
} rfbClient;
/* cursor.c */

@ -264,6 +264,7 @@ typedef char rfbProtocolVersionMsg[13]; /* allow extra byte for null */
#define rfbTight 16
#define rfbUltra 17
#define rfbTLS 18
#define rfbVeNCrypt 19
/*
* rfbConnFailed: For some reason the connection failed (e.g. the server

Loading…
Cancel
Save