Commit 29990f00 authored by Vic Lee's avatar Vic Lee Committed by Johannes Schindelin

Add MSLogon security type

Signed-off-by: 's avatarVic Lee <llyzs@163.com>
Signed-off-by: 's avatarJohannes Schindelin <johannes.schindelin@gmx.de>
parent 95ae56c8
...@@ -414,6 +414,7 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port) ...@@ -414,6 +414,7 @@ ConnectToRFBServer(rfbClient* client,const char *hostname, int port)
} }
extern void rfbClientEncryptBytes(unsigned char* bytes, char* passwd); extern void rfbClientEncryptBytes(unsigned char* bytes, char* passwd);
extern void rfbClientEncryptBytes2(unsigned char *where, const int length, unsigned char *key);
rfbBool rfbBool
rfbHandleAuthResult(rfbClient* client) rfbHandleAuthResult(rfbClient* client)
...@@ -503,7 +504,7 @@ ReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth) ...@@ -503,7 +504,7 @@ ReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth)
if (!ReadFromRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE; if (!ReadFromRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE;
rfbClientLog("%d) Received security type %d\n", loop, tAuth[loop]); rfbClientLog("%d) Received security type %d\n", loop, tAuth[loop]);
if (flag) continue; if (flag) continue;
if (tAuth[loop]==rfbVncAuth || tAuth[loop]==rfbNoAuth || if (tAuth[loop]==rfbVncAuth || tAuth[loop]==rfbNoAuth || tAuth[loop]==rfbMSLogon ||
(!subAuth && (tAuth[loop]==rfbTLS || tAuth[loop]==rfbVeNCrypt))) (!subAuth && (tAuth[loop]==rfbTLS || tAuth[loop]==rfbVeNCrypt)))
{ {
flag++; flag++;
...@@ -569,6 +570,14 @@ HandleVncAuth(rfbClient *client) ...@@ -569,6 +570,14 @@ HandleVncAuth(rfbClient *client)
return TRUE; return TRUE;
} }
static void
FreeUserCredential(rfbCredential *cred)
{
if (cred->userCredential.username) free(cred->userCredential.username);
if (cred->userCredential.password) free(cred->userCredential.password);
free(cred);
}
static rfbBool static rfbBool
HandlePlainAuth(rfbClient *client) HandlePlainAuth(rfbClient *client)
{ {
...@@ -592,20 +601,114 @@ HandlePlainAuth(rfbClient *client) ...@@ -592,20 +601,114 @@ HandlePlainAuth(rfbClient *client)
ulensw = rfbClientSwap32IfLE(ulen); ulensw = rfbClientSwap32IfLE(ulen);
plen = (cred->userCredential.password ? strlen(cred->userCredential.password) : 0); plen = (cred->userCredential.password ? strlen(cred->userCredential.password) : 0);
plensw = rfbClientSwap32IfLE(plen); plensw = rfbClientSwap32IfLE(plen);
if (!WriteToRFBServer(client, (char *)&ulensw, 4)) return FALSE; if (!WriteToRFBServer(client, (char *)&ulensw, 4) ||
if (!WriteToRFBServer(client, (char *)&plensw, 4)) return FALSE; !WriteToRFBServer(client, (char *)&plensw, 4))
{
FreeUserCredential(cred);
return FALSE;
}
if (ulen > 0) if (ulen > 0)
{ {
if (!WriteToRFBServer(client, cred->userCredential.username, ulen)) return FALSE; if (!WriteToRFBServer(client, cred->userCredential.username, ulen))
{
FreeUserCredential(cred);
return FALSE;
}
} }
if (plen > 0) if (plen > 0)
{ {
if (!WriteToRFBServer(client, cred->userCredential.password, plen)) return FALSE; if (!WriteToRFBServer(client, cred->userCredential.password, plen))
{
FreeUserCredential(cred);
return FALSE;
}
} }
if (cred->userCredential.username) free(cred->userCredential.username); FreeUserCredential(cred);
if (cred->userCredential.password) free(cred->userCredential.password);
free(cred); /* Handle the SecurityResult message */
if (!rfbHandleAuthResult(client)) return FALSE;
return TRUE;
}
/* Simple 64bit big integer arithmetic implementation */
/* (x + y) % m, works even if (x + y) > 64bit */
#define rfbAddM64(x,y,m) ((x+y)%m+(x+y<x?(((uint64_t)-1)%m+1)%m:0))
/* (x * y) % m */
static uint64_t
rfbMulM64(uint64_t x, uint64_t y, uint64_t m)
{
uint64_t r;
for(r=0;x>0;x>>=1)
{
if (x&1) r=rfbAddM64(r,y,m);
y=rfbAddM64(y,y,m);
}
return r;
}
/* (x ^ y) % m */
static uint64_t
rfbPowM64(uint64_t b, uint64_t e, uint64_t m)
{
uint64_t r;
for(r=1;e>0;e>>=1)
{
if(e&1) r=rfbMulM64(r,b,m);
b=rfbMulM64(b,b,m);
}
return r;
}
static rfbBool
HandleMSLogonAuth(rfbClient *client)
{
uint64_t gen, mod, resp, priv, pub, key;
uint8_t username[256], password[64];
rfbCredential *cred;
if (!ReadFromRFBServer(client, (char *)&gen, 8)) return FALSE;
if (!ReadFromRFBServer(client, (char *)&mod, 8)) return FALSE;
if (!ReadFromRFBServer(client, (char *)&resp, 8)) return FALSE;
gen = rfbClientSwap64IfLE(gen);
mod = rfbClientSwap64IfLE(mod);
resp = rfbClientSwap64IfLE(resp);
if (!client->GetCredential)
{
rfbClientLog("GetCredential callback is not set.\n");
return FALSE;
}
rfbClientLog("WARNING! MSLogon security type has very low password encryption! "\
"Use it only with SSH tunnel or trusted network.\n");
cred = client->GetCredential(client, rfbCredentialTypeUser);
if (!cred)
{
rfbClientLog("Reading credential failed\n");
return FALSE;
}
memset(username, 0, sizeof(username));
strncpy((char *)username, cred->userCredential.username, sizeof(username));
memset(password, 0, sizeof(password));
strncpy((char *)password, cred->userCredential.password, sizeof(password));
FreeUserCredential(cred);
srand(time(NULL));
priv = ((uint64_t)rand())<<32;
priv |= (uint64_t)rand();
pub = rfbPowM64(gen, priv, mod);
key = rfbPowM64(resp, priv, mod);
pub = rfbClientSwap64IfLE(pub);
key = rfbClientSwap64IfLE(key);
rfbClientEncryptBytes2(username, sizeof(username), (unsigned char *)&key);
rfbClientEncryptBytes2(password, sizeof(password), (unsigned char *)&key);
if (!WriteToRFBServer(client, (char *)&pub, 8)) return FALSE;
if (!WriteToRFBServer(client, (char *)username, sizeof(username))) return FALSE;
if (!WriteToRFBServer(client, (char *)password, sizeof(password))) return FALSE;
/* Handle the SecurityResult message */ /* Handle the SecurityResult message */
if (!rfbHandleAuthResult(client)) return FALSE; if (!rfbHandleAuthResult(client)) return FALSE;
...@@ -713,6 +816,10 @@ InitialiseRFBConnection(rfbClient* client) ...@@ -713,6 +816,10 @@ InitialiseRFBConnection(rfbClient* client)
if (!HandleVncAuth(client)) return FALSE; if (!HandleVncAuth(client)) return FALSE;
break; break;
case rfbMSLogon:
if (!HandleMSLogonAuth(client)) return FALSE;
break;
case rfbTLS: case rfbTLS:
if (!HandleAnonTLSAuth(client)) return FALSE; if (!HandleAnonTLSAuth(client)) return FALSE;
/* After the TLS session is established, sub auth types are expected. /* After the TLS session is established, sub auth types are expected.
...@@ -1889,6 +1996,7 @@ PrintPixelFormat(rfbPixelFormat *format) ...@@ -1889,6 +1996,7 @@ PrintPixelFormat(rfbPixelFormat *format)
/* avoid name clashes with LibVNCServer */ /* avoid name clashes with LibVNCServer */
#define rfbEncryptBytes rfbClientEncryptBytes #define rfbEncryptBytes rfbClientEncryptBytes
#define rfbEncryptBytes2 rfbClientEncryptBytes2
#define rfbDes rfbClientDes #define rfbDes rfbClientDes
#define rfbDesKey rfbClientDesKey #define rfbDesKey rfbClientDesKey
#define rfbUseKey rfbClientUseKey #define rfbUseKey rfbClientUseKey
......
...@@ -191,3 +191,18 @@ rfbEncryptBytes(unsigned char *bytes, char *passwd) ...@@ -191,3 +191,18 @@ rfbEncryptBytes(unsigned char *bytes, char *passwd)
rfbDes(bytes+i, bytes+i); rfbDes(bytes+i, bytes+i);
} }
} }
void
rfbEncryptBytes2(unsigned char *where, const int length, unsigned char *key) {
int i, j;
rfbDesKey(key, EN0);
for (i = 0; i< 8; i++)
where[i] ^= key[i];
rfbDes(where, where);
for (i = 8; i < length; i += 8) {
for (j = 0; j < 8; j++)
where[i + j] ^= where[i + j - 8];
rfbDes(where + i, where + i);
}
}
...@@ -46,6 +46,16 @@ ...@@ -46,6 +46,16 @@
(((l) & 0x0000ff00) << 8) | \ (((l) & 0x0000ff00) << 8) | \
(((l) & 0x000000ff) << 24)) : (l)) (((l) & 0x000000ff) << 24)) : (l))
#define rfbClientSwap64IfLE(l) \
(*(char *)&client->endianTest ? ((((l) & 0xff00000000000000ULL) >> 56) | \
(((l) & 0x00ff000000000000ULL) >> 40) | \
(((l) & 0x0000ff0000000000ULL) >> 24) | \
(((l) & 0x000000ff00000000ULL) >> 8) | \
(((l) & 0x00000000ff000000ULL) << 8) | \
(((l) & 0x0000000000ff0000ULL) << 24) | \
(((l) & 0x000000000000ff00ULL) << 40) | \
(((l) & 0x00000000000000ffULL) << 56)) : (l))
#define FLASH_PORT_OFFSET 5400 #define FLASH_PORT_OFFSET 5400
#define LISTEN_PORT_OFFSET 5500 #define LISTEN_PORT_OFFSET 5500
#define TUNNEL_PORT_OFFSET 5500 #define TUNNEL_PORT_OFFSET 5500
......
...@@ -265,6 +265,7 @@ typedef char rfbProtocolVersionMsg[13]; /* allow extra byte for null */ ...@@ -265,6 +265,7 @@ typedef char rfbProtocolVersionMsg[13]; /* allow extra byte for null */
#define rfbUltra 17 #define rfbUltra 17
#define rfbTLS 18 #define rfbTLS 18
#define rfbVeNCrypt 19 #define rfbVeNCrypt 19
#define rfbMSLogon 0xfffffffa
#define rfbVeNCryptPlain 256 #define rfbVeNCryptPlain 256
#define rfbVeNCryptTLSNone 257 #define rfbVeNCryptTLSNone 257
......
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