Branch: master

1d8b3c05 2015-01-12 23:48:26 Timothy Pearson
Add hooks to client library to ontain network and authentication status
M libvncclient/rfbproto.c
M libvncclient/sockets.c
M libvncclient/vncviewer.c
M rfb/rfbclient.h
M rfb/rfbproto.h
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 @@
 
       /* 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 @@
   }
 
   if (client->sock < 0) {
+    if (client->NetworkStatus)
+      client->NetworkStatus(client, rfbNetworkConnectionFailed);
     rfbClientLog("Unable to connect to VNC server\n");
     return FALSE;
   }
@@ -512,6 +516,9 @@
     if (!ReadFromRFBServer(client, (char *)&authResult, 4)) return FALSE;
 
     authResult = rfbClientSwap32IfLE(authResult);
+
+    if (client->AuthenticationResults)
+      client->AuthenticationResults(client, authResult);
 
     switch (authResult) {
     case rfbVncAuthOK:
@@ -643,13 +650,19 @@
     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 @@
       }
       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 @@
   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 @@
   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 @@
 
   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 @@
 	    return FALSE;
 	  }
 	} else {
+          if (client->NetworkStatus)
+            client->NetworkStatus(client, rfbNetworkConnectionClosed);
 	  if (errorMessageOnReadFailure) {
 	    rfbClientLog("VNC server closed connection\n");
 	  }
@@ -212,6 +214,8 @@
 	    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 @@
     }
   }
 
+  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 (*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 @@
 	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 @@
 
 #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