Commit a60ee2ee authored by steven_carr's avatar steven_carr

RFB 3.8 clients are well informed

parent 6bd995ec
...@@ -369,6 +369,47 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port) ...@@ -369,6 +369,47 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port)
extern void rfbClientEncryptBytes(unsigned char* bytes, char* passwd); extern void rfbClientEncryptBytes(unsigned char* bytes, char* passwd);
rfbBool
rfbHandleAuthResult(rfbClient* client)
{
uint32_t authResult=0, reasonLen=0;
char *reason=NULL;
if (!ReadFromRFBServer(client, (char *)&authResult, 4)) return FALSE;
authResult = rfbClientSwap32IfLE(authResult);
switch (authResult) {
case rfbVncAuthOK:
rfbClientLog("VNC authentication succeeded\n");
return TRUE;
break;
case rfbVncAuthFailed:
if (client->major==3 && client->minor>7)
{
/* 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;
}
rfbClientLog("VNC authentication failed\n");
return FALSE;
case rfbVncAuthTooMany:
rfbClientLog("VNC authentication failed - too many tries\n");
return FALSE;
}
rfbClientLog("Unknown VNC authentication result: %d\n",
(int)authResult);
return FALSE;
}
/* /*
* InitialiseRFBConnection. * InitialiseRFBConnection.
*/ */
...@@ -378,7 +419,7 @@ InitialiseRFBConnection(rfbClient* client) ...@@ -378,7 +419,7 @@ InitialiseRFBConnection(rfbClient* client)
{ {
rfbProtocolVersionMsg pv; rfbProtocolVersionMsg pv;
int major,minor; int major,minor;
uint32_t authScheme, reasonLen, authResult; uint32_t authScheme, reasonLen;
char *reason; char *reason;
uint8_t challenge[CHALLENGESIZE]; uint8_t challenge[CHALLENGESIZE];
char *passwd=NULL; char *passwd=NULL;
...@@ -453,9 +494,10 @@ InitialiseRFBConnection(rfbClient* client) ...@@ -453,9 +494,10 @@ InitialiseRFBConnection(rfbClient* client)
/* we have an error following */ /* we have an error following */
if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE; if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
reasonLen = rfbClientSwap32IfLE(reasonLen); reasonLen = rfbClientSwap32IfLE(reasonLen);
reason = malloc(reasonLen); reason = malloc(reasonLen+1);
if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; } if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
rfbClientLog("VNC connection failed: %.*s\n",(int)reasonLen, reason); reason[reasonLen]=0;
rfbClientLog("VNC connection failed: %s\n",reason);
free(reason); free(reason);
return FALSE; return FALSE;
} }
...@@ -473,6 +515,7 @@ InitialiseRFBConnection(rfbClient* client) ...@@ -473,6 +515,7 @@ InitialiseRFBConnection(rfbClient* client)
rfbClientLog("Selecting security type %d (%d/%d in the list)\n", authScheme, loop, count); 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 */ /* send back a single byte indicating which security type to use */
if (!WriteToRFBServer(client, (char *)&tAuth, 1)) return FALSE; if (!WriteToRFBServer(client, (char *)&tAuth, 1)) return FALSE;
} }
} }
} }
...@@ -490,16 +533,21 @@ InitialiseRFBConnection(rfbClient* client) ...@@ -490,16 +533,21 @@ InitialiseRFBConnection(rfbClient* client)
if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE; if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
reasonLen = rfbClientSwap32IfLE(reasonLen); reasonLen = rfbClientSwap32IfLE(reasonLen);
reason = malloc(reasonLen); reason = malloc(reasonLen+1);
if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; } if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
reason[reasonLen]=0;
rfbClientLog("VNC connection failed: %.*s\n",(int)reasonLen, reason); rfbClientLog("VNC connection failed: %s\n", reason);
free(reason); free(reason);
return FALSE; return FALSE;
case rfbNoAuth: case rfbNoAuth:
rfbClientLog("No authentication needed\n"); rfbClientLog("No authentication needed\n");
/* 3.8 and upwards sends a Security Result for rfbNoAuth */
if (client->major==3 && client->minor > 7)
if (!rfbHandleAuthResult(client)) return FALSE;
break; break;
case rfbVncAuth: case rfbVncAuth:
...@@ -528,36 +576,8 @@ InitialiseRFBConnection(rfbClient* client) ...@@ -528,36 +576,8 @@ InitialiseRFBConnection(rfbClient* client)
if (!WriteToRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE; if (!WriteToRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
} }
if (!ReadFromRFBServer(client, (char *)&authResult, 4)) return FALSE; /* Handle the SecurityResult message */
if (!rfbHandleAuthResult(client)) return FALSE;
authResult = rfbClientSwap32IfLE(authResult);
switch (authResult) {
case rfbVncAuthOK:
rfbClientLog("VNC authentication succeeded\n");
break;
case rfbVncAuthFailed:
if (client->major==3 && client->minor>7)
{
/* we have an error following */
if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
reasonLen = rfbClientSwap32IfLE(reasonLen);
reason = malloc(reasonLen);
if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
rfbClientLog("VNC connection failed: %.*s\n",(int)reasonLen, reason);
free(reason);
return FALSE;
}
rfbClientLog("VNC authentication failed\n");
return FALSE;
case rfbVncAuthTooMany:
rfbClientLog("VNC authentication failed - too many tries\n");
return FALSE;
default:
rfbClientLog("Unknown VNC authentication result: %d\n",
(int)authResult);
return FALSE;
}
break; break;
default: default:
......
...@@ -29,6 +29,10 @@ ...@@ -29,6 +29,10 @@
#include <rfb/rfb.h> #include <rfb/rfb.h>
/* RFB 3.8 clients are well informed */
void rfbClientSendString(rfbClientPtr cl, char *reason);
/* /*
* Handle security types * Handle security types
*/ */
...@@ -207,7 +211,7 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType) ...@@ -207,7 +211,7 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
/* The execution should never reach here */ /* The execution should never reach here */
char* reason = "No authentication mode is registered!"; char* reason = "No authentication mode is registered!";
rfbClientConnFailed(cl, reason); rfbClientSendString(cl, reason);
return; return;
} }
...@@ -352,7 +356,7 @@ rfbAuthProcessClientMessage(rfbClientPtr cl) ...@@ -352,7 +356,7 @@ rfbAuthProcessClientMessage(rfbClientPtr cl)
} }
/* support RFB 3.8 clients, they expect a reason *why* it was disconnected */ /* support RFB 3.8 clients, they expect a reason *why* it was disconnected */
if (cl->protocolMinorVersion > 7) { if (cl->protocolMinorVersion > 7) {
rfbClientConnFailed(cl, "password check failed!"); rfbClientSendString(cl, "password check failed!");
} }
else else
rfbCloseClient(cl); rfbCloseClient(cl);
......
...@@ -587,7 +587,6 @@ rfbProcessClientProtocolVersion(rfbClientPtr cl) ...@@ -587,7 +587,6 @@ rfbProcessClientProtocolVersion(rfbClientPtr cl)
{ {
rfbProtocolVersionMsg pv; rfbProtocolVersionMsg pv;
int n, major_, minor_; int n, major_, minor_;
char failureReason[256];
if ((n = rfbReadExact(cl, pv, sz_rfbProtocolVersionMsg)) <= 0) { if ((n = rfbReadExact(cl, pv, sz_rfbProtocolVersionMsg)) <= 0) {
if (n == 0) if (n == 0)
...@@ -612,14 +611,10 @@ rfbProcessClientProtocolVersion(rfbClientPtr cl) ...@@ -612,14 +611,10 @@ rfbProcessClientProtocolVersion(rfbClientPtr cl)
rfbLog("Client Protocol Version %d.%d\n", major_, minor_); rfbLog("Client Protocol Version %d.%d\n", major_, minor_);
if (major_ != rfbProtocolMajorVersion) { if (major_ != rfbProtocolMajorVersion) {
/* Major version mismatch - send a ConnFailed message */ rfbErr("RFB protocol version mismatch - server %d.%d, client %d.%d",
rfbErr("Major version mismatch\n");
sprintf(failureReason,
"RFB protocol version mismatch - server %d.%d, client %d.%d",
cl->screen->protocolMajorVersion, cl->screen->protocolMinorVersion, cl->screen->protocolMajorVersion, cl->screen->protocolMinorVersion,
major_,minor_); major_,minor_);
rfbClientConnFailed(cl, failureReason); rfbCloseClient(cl);
return; return;
} }
...@@ -641,6 +636,25 @@ rfbProcessClientProtocolVersion(rfbClientPtr cl) ...@@ -641,6 +636,25 @@ rfbProcessClientProtocolVersion(rfbClientPtr cl)
} }
void
rfbClientSendString(rfbClientPtr cl, char *reason)
{
char *buf;
int len = strlen(reason);
rfbLog("rfbClientSendString(\"%s\")\n", reason);
buf = (char *)malloc(4 + len);
((uint32_t *)buf)[0] = Swap32IfLE(len);
memcpy(buf + 4, reason, len);
if (rfbWriteExact(cl, buf, 4 + len) < 0)
rfbLogPerror("rfbClientSendString: write");
free(buf);
rfbCloseClient(cl);
}
/* /*
* rfbClientConnFailed is called when a client connection has failed either * rfbClientConnFailed is called when a client connection has failed either
* because it talks the wrong protocol or it has failed authentication. * because it talks the wrong protocol or it has failed authentication.
...@@ -653,6 +667,8 @@ rfbClientConnFailed(rfbClientPtr cl, ...@@ -653,6 +667,8 @@ rfbClientConnFailed(rfbClientPtr cl,
char *buf; char *buf;
int len = strlen(reason); int len = strlen(reason);
rfbLog("rfbClientConnFailed(\"%s\")\n", reason);
buf = (char *)malloc(8 + len); buf = (char *)malloc(8 + len);
((uint32_t *)buf)[0] = Swap32IfLE(rfbConnFailed); ((uint32_t *)buf)[0] = Swap32IfLE(rfbConnFailed);
((uint32_t *)buf)[1] = Swap32IfLE(len); ((uint32_t *)buf)[1] = Swap32IfLE(len);
...@@ -661,6 +677,7 @@ rfbClientConnFailed(rfbClientPtr cl, ...@@ -661,6 +677,7 @@ rfbClientConnFailed(rfbClientPtr cl,
if (rfbWriteExact(cl, buf, 8 + len) < 0) if (rfbWriteExact(cl, buf, 8 + len) < 0)
rfbLogPerror("rfbClientConnFailed: write"); rfbLogPerror("rfbClientConnFailed: write");
free(buf); free(buf);
rfbCloseClient(cl); rfbCloseClient(cl);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment