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)
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.
*/
......@@ -378,7 +419,7 @@ InitialiseRFBConnection(rfbClient* client)
{
rfbProtocolVersionMsg pv;
int major,minor;
uint32_t authScheme, reasonLen, authResult;
uint32_t authScheme, reasonLen;
char *reason;
uint8_t challenge[CHALLENGESIZE];
char *passwd=NULL;
......@@ -453,9 +494,10 @@ InitialiseRFBConnection(rfbClient* client)
/* we have an error following */
if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
reasonLen = rfbClientSwap32IfLE(reasonLen);
reason = malloc(reasonLen);
reason = malloc(reasonLen+1);
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);
return FALSE;
}
......@@ -473,6 +515,7 @@ InitialiseRFBConnection(rfbClient* client)
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, 1)) return FALSE;
}
}
}
......@@ -490,16 +533,21 @@ InitialiseRFBConnection(rfbClient* client)
if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
reasonLen = rfbClientSwap32IfLE(reasonLen);
reason = malloc(reasonLen);
reason = malloc(reasonLen+1);
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);
return FALSE;
case rfbNoAuth:
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;
case rfbVncAuth:
......@@ -528,36 +576,8 @@ InitialiseRFBConnection(rfbClient* client)
if (!WriteToRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
}
if (!ReadFromRFBServer(client, (char *)&authResult, 4)) 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;
}
/* Handle the SecurityResult message */
if (!rfbHandleAuthResult(client)) return FALSE;
break;
default:
......
......@@ -29,6 +29,10 @@
#include <rfb/rfb.h>
/* RFB 3.8 clients are well informed */
void rfbClientSendString(rfbClientPtr cl, char *reason);
/*
* Handle security types
*/
......@@ -207,7 +211,7 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
/* The execution should never reach here */
char* reason = "No authentication mode is registered!";
rfbClientConnFailed(cl, reason);
rfbClientSendString(cl, reason);
return;
}
......@@ -352,7 +356,7 @@ rfbAuthProcessClientMessage(rfbClientPtr cl)
}
/* support RFB 3.8 clients, they expect a reason *why* it was disconnected */
if (cl->protocolMinorVersion > 7) {
rfbClientConnFailed(cl, "password check failed!");
rfbClientSendString(cl, "password check failed!");
}
else
rfbCloseClient(cl);
......
......@@ -587,7 +587,6 @@ rfbProcessClientProtocolVersion(rfbClientPtr cl)
{
rfbProtocolVersionMsg pv;
int n, major_, minor_;
char failureReason[256];
if ((n = rfbReadExact(cl, pv, sz_rfbProtocolVersionMsg)) <= 0) {
if (n == 0)
......@@ -612,14 +611,10 @@ rfbProcessClientProtocolVersion(rfbClientPtr cl)
rfbLog("Client Protocol Version %d.%d\n", major_, minor_);
if (major_ != rfbProtocolMajorVersion) {
/* Major version mismatch - send a ConnFailed message */
rfbErr("Major version mismatch\n");
sprintf(failureReason,
"RFB protocol version mismatch - server %d.%d, client %d.%d",
rfbErr("RFB protocol version mismatch - server %d.%d, client %d.%d",
cl->screen->protocolMajorVersion, cl->screen->protocolMinorVersion,
major_,minor_);
rfbClientConnFailed(cl, failureReason);
rfbCloseClient(cl);
return;
}
......@@ -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
* because it talks the wrong protocol or it has failed authentication.
......@@ -653,6 +667,8 @@ rfbClientConnFailed(rfbClientPtr cl,
char *buf;
int len = strlen(reason);
rfbLog("rfbClientConnFailed(\"%s\")\n", reason);
buf = (char *)malloc(8 + len);
((uint32_t *)buf)[0] = Swap32IfLE(rfbConnFailed);
((uint32_t *)buf)[1] = Swap32IfLE(len);
......@@ -661,6 +677,7 @@ rfbClientConnFailed(rfbClientPtr cl,
if (rfbWriteExact(cl, buf, 8 + len) < 0)
rfbLogPerror("rfbClientConnFailed: write");
free(buf);
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