diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c index aa74c23..8ac0028 100644 --- a/libvncclient/rfbproto.c +++ b/libvncclient/rfbproto.c @@ -431,6 +431,8 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port) /* serverHost is a hostname */ if (!StringToIPAddr(hostname, &host)) { + if (client->NetworkStatus) + client->NetworkStatus(client, rfbNetworkNameResolutionFailed); rfbClientLog("Couldn't convert '%s' to host address\n", hostname); return FALSE; } @@ -439,6 +441,8 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port) } if (client->sock < 0) { + if (client->NetworkStatus) + client->NetworkStatus(client, rfbNetworkConnectionFailed); rfbClientLog("Unable to connect to VNC server\n"); return FALSE; } @@ -513,6 +517,9 @@ rfbHandleAuthResult(rfbClient* client) authResult = rfbClientSwap32IfLE(authResult); + if (client->AuthenticationResults) + client->AuthenticationResults(client, authResult); + switch (authResult) { case rfbVncAuthOK: rfbClientLog("VNC authentication succeeded\n"); @@ -643,13 +650,19 @@ HandleVncAuth(rfbClient *client) char *passwd=NULL; int i; - if (!ReadFromRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE; + if (!ReadFromRFBServer(client, (char *)challenge, CHALLENGESIZE)) { + if (client->AuthenticationResults) + client->AuthenticationResults(client, rfbVncAuthFailed); + return FALSE; + } if (client->serverPort!=-1) { /* if not playing a vncrec file */ if (client->GetPassword) passwd = client->GetPassword(client); if ((!passwd) || (strlen(passwd) == 0)) { + if (client->AuthenticationResults) + client->AuthenticationResults(client, rfbVncAuthFailed); rfbClientLog("Reading password failed\n"); return FALSE; } @@ -665,7 +678,11 @@ HandleVncAuth(rfbClient *client) } free(passwd); - if (!WriteToRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE; + if (!WriteToRFBServer(client, (char *)challenge, CHALLENGESIZE)) { + if (client->AuthenticationResults) + client->AuthenticationResults(client, rfbVncAuthFailed); + return FALSE; + } } /* Handle the SecurityResult message */ @@ -1080,7 +1097,11 @@ InitialiseRFBConnection(rfbClient* client) if (client->listenSpecified) errorMessageOnReadFailure = FALSE; - if (!ReadFromRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE; + if (!ReadFromRFBServer(client, pv, sz_rfbProtocolVersionMsg)) { + if (client->NetworkStatus) + client->NetworkStatus(client, rfbNetworkRFBServerNotValid); + return FALSE; + } pv[sz_rfbProtocolVersionMsg]=0; errorMessageOnReadFailure = TRUE; @@ -1088,6 +1109,8 @@ InitialiseRFBConnection(rfbClient* client) pv[sz_rfbProtocolVersionMsg] = 0; if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) { + if (client->NetworkStatus) + client->NetworkStatus(client, rfbNetworkRFBServerNotValid); rfbClientLog("Not a valid VNC server (%s)\n",pv); return FALSE; } @@ -1133,17 +1156,29 @@ InitialiseRFBConnection(rfbClient* client) sprintf(pv,rfbProtocolVersionFormat,client->major,client->minor); - if (!WriteToRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE; + if (!WriteToRFBServer(client, pv, sz_rfbProtocolVersionMsg)) { + if (client->NetworkStatus) + client->NetworkStatus(client, rfbNetworkRFBProtocolFailure); + return FALSE; + } /* 3.7 and onwards sends a # of security types first */ if (client->major==3 && client->minor > 6) { - if (!ReadSupportedSecurityType(client, &authScheme, FALSE)) return FALSE; + if (!ReadSupportedSecurityType(client, &authScheme, FALSE)) { + if (client->NetworkStatus) + client->NetworkStatus(client, rfbNetworkRFBProtocolFailure); + return FALSE; + } } else { - if (!ReadFromRFBServer(client, (char *)&authScheme, 4)) return FALSE; + if (!ReadFromRFBServer(client, (char *)&authScheme, 4)) { + if (client->NetworkStatus) + client->NetworkStatus(client, rfbNetworkRFBProtocolFailure); + return FALSE; + } authScheme = rfbClientSwap32IfLE(authScheme); } diff --git a/libvncclient/sockets.c b/libvncclient/sockets.c index e32c60e..225450c 100644 --- a/libvncclient/sockets.c +++ b/libvncclient/sockets.c @@ -173,6 +173,8 @@ ReadFromRFBServer(rfbClient* client, char *out, unsigned int n) return FALSE; } } else { + if (client->NetworkStatus) + client->NetworkStatus(client, rfbNetworkConnectionClosed); if (errorMessageOnReadFailure) { rfbClientLog("VNC server closed connection\n"); } @@ -212,6 +214,8 @@ ReadFromRFBServer(rfbClient* client, char *out, unsigned int n) return FALSE; } } else { + if (client->NetworkStatus) + client->NetworkStatus(client, rfbNetworkConnectionClosed); if (errorMessageOnReadFailure) { rfbClientLog("VNC server closed connection\n"); } diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c index b12116c..22bf0e4 100644 --- a/libvncclient/vncviewer.c +++ b/libvncclient/vncviewer.c @@ -250,11 +250,17 @@ static rfbBool rfbInitConnection(rfbClient* client) } } + if (client->NetworkStatus) + client->NetworkStatus(client, rfbNetworkConnectionSuccess); + /* Initialise the VNC connection, including reading the password */ if (!InitialiseRFBConnection(client)) return FALSE; + if (client->NetworkStatus) + client->NetworkStatus(client, rfbNetworkRFBConnectionSuccess); + client->width=client->si.framebufferWidth; client->height=client->si.framebufferHeight; if (!client->MallocFrameBuffer(client)) diff --git a/rfb/rfbclient.h b/rfb/rfbclient.h index aedb4f4..f3700ae 100644 --- a/rfb/rfbclient.h +++ b/rfb/rfbclient.h @@ -169,6 +169,8 @@ typedef void (*SoftCursorUnlockScreenProc)(struct _rfbClient* client); typedef void (*GotFrameBufferUpdateProc)(struct _rfbClient* client, int x, int y, int w, int h); typedef void (*FinishedFrameBufferUpdateProc)(struct _rfbClient* client); typedef char* (*GetPasswordProc)(struct _rfbClient* client); +typedef void (*AuthenticationResultsProc)(struct _rfbClient* client, uint32_t authResult); +typedef void (*NetworkStatusProc)(struct _rfbClient* client, uint32_t errorCode); typedef rfbCredential* (*GetCredentialProc)(struct _rfbClient* client, int credentialType); typedef rfbBool (*MallocFrameBufferProc)(struct _rfbClient* client); typedef void (*GotXCutTextProc)(struct _rfbClient* client, const char *text, int textlen); @@ -292,6 +294,8 @@ typedef struct _rfbClient { GotFrameBufferUpdateProc GotFrameBufferUpdate; /** the pointer returned by GetPassword will be freed after use! */ GetPasswordProc GetPassword; + AuthenticationResultsProc AuthenticationResults; + NetworkStatusProc NetworkStatus; MallocFrameBufferProc MallocFrameBuffer; GotXCutTextProc GotXCutText; BellProc Bell; diff --git a/rfb/rfbproto.h b/rfb/rfbproto.h index 4baae6d..4d6a1e6 100644 --- a/rfb/rfbproto.h +++ b/rfb/rfbproto.h @@ -126,6 +126,14 @@ typedef uint32_t in_addr_t; #define MAX_ENCODINGS 21 +#define rfbNetworkConnectionSuccess 0 +#define rfbNetworkRFBConnectionSuccess 1 +#define rfbNetworkConnectionClosed 2 +#define rfbNetworkConnectionFailed 3 +#define rfbNetworkNameResolutionFailed 4 +#define rfbNetworkRFBServerNotValid 5 +#define rfbNetworkRFBProtocolFailure 6 + /***************************************************************************** * * Structures used in several messages