📄 vncclient.cpp
字号:
vnclog.Print(LL_INTINFO, VNCLOG("User specified or mslogon required"));
//int result=CheckUserGroupPasswordUni(user,plainmsPasswd,m_client->GetClientName());
//vnclog.Print(LL_INTINFO, VNCLOG("CheckUserGroupPasswordUni result=%i"), result);
//if (result==0) auth_ok = FALSE;
//if (result==2)
//{
// m_client->EnableKeyboard(false);
// m_client->EnablePointer(false);
//}
}
if (plainmsPasswd) free(plainmsPasswd);
plainmsPasswd=NULL;
}
else
{
vnclog.Print(LL_INTINFO, VNCLOG("password authentication"));
if (!m_socket->SendExact(challenge, sizeof(challenge)))
return FALSE;
// Read the response
if (!m_socket->ReadExact(response, sizeof(response)))
return FALSE;
memcpy(challenge2, challenge, 16);
// Encrypt the challenge bytes
vncEncryptBytes((BYTE *)&challenge, plain.c_str());
// Compare them to the response
for (int i=0; i<sizeof(challenge); i++)
{
if (challenge[i] != response[i])
{
auth_ok = FALSE;
break;
}
}
#ifdef _DEBUG
// Debug compilation: space is valid password
if(!auth_ok)
{
auth_ok = TRUE;
vncEncryptBytes((BYTE *)&challenge2, " ");
// Compare them to the response
for (int i=0; i<sizeof(challenge2); i++)
{
if (challenge2[i] != response[i])
{
auth_ok = FALSE;
break;
}
}
}
#endif
}
}
// Did the authentication work?
CARD32 authmsg;
if (!auth_ok)
{
vnclog.Print(LL_CONNERR, VNCLOG("authentication failed"));
//////////////////
// LOG it also in the event
//////////////////
//{
// typedef BOOL (*LogeventFn)(char *machine);
// LogeventFn Logevent = 0;
// char szCurrentDir[MAX_PATH];
// if (GetModuleFileName(NULL, szCurrentDir, MAX_PATH))
// {
// char* p = strrchr(szCurrentDir, '\\');
// *p = '\0';
// strcat (szCurrentDir,"\\logging.dll");
// }
// HMODULE hModule = LoadLibrary(szCurrentDir);
// if (hModule)
// {
// BOOL result=false;
// Logevent = (LogeventFn) GetProcAddress( hModule, "LOGFAILED" );
// Logevent((char *)m_client->GetClientName());
// FreeLibrary(hModule);
// }
//}
authmsg = Swap32IfLE(rfbVncAuthFailed);
m_socket->SendExact((char *)&authmsg, sizeof(authmsg));
return FALSE;
}
else
{
vnclog.Print(LL_CONNERR, VNCLOG("authentication succeeded"));
// Tell the client we're ok
authmsg = Swap32IfLE(rfbVncAuthOK);
//////////////////
// LOG it also in the event
//////////////////
//if (!m_ms_logon){
// typedef BOOL (*LogeventFn)(char *machine);
// LogeventFn Logevent = 0;
// char szCurrentDir[MAX_PATH];
// if (GetModuleFileName(NULL, szCurrentDir, MAX_PATH))
// {
// char* p = strrchr(szCurrentDir, '\\');
// *p = '\0';
// strcat (szCurrentDir,"\\logging.dll");
// }
// HMODULE hModule = LoadLibrary(szCurrentDir);
// if (hModule)
// {
// BOOL result=false;
// Logevent = (LogeventFn) GetProcAddress( hModule, "LOGLOGON" );
// Logevent((char *)m_client->GetClientName());
// FreeLibrary(hModule);
// }
//}
if (!m_socket->SendExact((char *)&authmsg, sizeof(authmsg)))
return FALSE;
}
}
// Read the client's initialisation message
rfbClientInitMsg client_ini;
if (!m_socket->ReadExact((char *)&client_ini, sz_rfbClientInitMsg))
return FALSE;
// If the client wishes to have exclusive access then remove other clients
if (m_server->ConnectPriority() == 2 ) //&& !m_shared )
{
if (m_server->AuthClientCount() > 0)
{
TeamviewerInfo::setLocalInfo(tvError, "MULTIPLE_CONNECTION_REJECTED");
vnclog.Print(LL_CLIENTS, VNCLOG("connections already exist - client rejected"));
return TRUE; // do not quit now, but later when tvError is processed
}
}
// let only the server decide and ignore the share flag that the clients send
//if (!client_ini.shared && !m_shared)
{
// Which client takes priority, existing or incoming?
if (m_server->ConnectPriority() == 0 && m_server->AuthClientCount() > 0)
{
// Incoming
vnclog.Print(LL_INTINFO, VNCLOG("non-shared connection - disconnecting old clients"));
m_server->KillAuthClients();
}
//else if (m_server->ConnectPriority() == 1)
//{
// // Existing
// if (m_server->AuthClientCount() > 0)
// {
// vnclog.Print(LL_CLIENTS, VNCLOG("connections already exist - client rejected"));
// return FALSE;
// }
//}
}
// Tell the server that this client is ok
return m_server->Authenticated(m_client->GetClientId());
}
void
ClearKeyState(BYTE key)
{
// This routine is used by the VNC client handler to clear the
// CAPSLOCK, NUMLOCK and SCROLL-LOCK states.
BYTE keyState[256];
GetKeyboardState((LPBYTE)&keyState);
if(keyState[key] & 1)
{
// Simulate the key being pressed
keybd_event(key, 0, KEYEVENTF_EXTENDEDKEY, 0);
// Simulate it being release
keybd_event(key, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
}
}
// TR@2003
void GetLocalName(char *buffer, int buflen)
{
BOOL noname;
DWORD buflen2 = buflen;
// Der lokale Name wird nicht mehr eingeblendet - f黨rt zur Verwirrung
buffer[0] = '\0';
/* if (GetComputerName(buffer, &buflen2))
{
// Make the name lowercase - deactivated TR@2003
//for (int x=0; x<strlen(buffer); x++)
//{
// buffer[x] = tolower(buffer[x]);
//}
}
else
{
strcpy(buffer, "");
}
if (strlen(buffer)>0)
noname=false;
else */
noname=true;
// We add the IP address(es) to the computer name, if local name was not available
if (!(strchr(buffer, '.') != NULL))
{
char szIP[256];
GetIPString(szIP, sizeof(szIP));
if (strlen(szIP) > 3 && szIP[0] != 'I' && szIP[0] != 'H')
{
if (!noname)
strncat(buffer, " (", buflen-strlen(buffer)-1);
strncat(buffer, szIP, buflen-strlen(buffer)-1);
if (!noname)
strncat(buffer, ")", buflen-strlen(buffer)-1);
}
}
}
// Modif sf@2002
// Get the local ip addresses as a human-readable string.
// If more than one, then with \n between them.
// If not available, then gets a message to that effect.
void GetIPString(char *buffer, int buflen)
{
char namebuf[256];
if (gethostname(namebuf, 256) != 0)
{
strncpy(buffer, "Host name unavailable", buflen);
return;
}
HOSTENT *ph = gethostbyname(namebuf);
if (!ph)
{
strncpy(buffer, "IP address unavailable", buflen);
return;
}
*buffer = '\0';
char digtxt[5];
for (int i = 0; ph->h_addr_list[i]; i++)
{
for (int j = 0; j < ph->h_length; j++)
{
sprintf(digtxt, "%d.", (unsigned char) ph->h_addr_list[i][j]);
strncat(buffer, digtxt, (buflen-1)-strlen(buffer));
}
buffer[strlen(buffer)-1] = '\0';
if (ph->h_addr_list[i+1] != 0)
strncat(buffer, ", ", (buflen-1)-strlen(buffer));
}
}
void
vncClientThread::run(void *arg)
{
// All this thread does is go into a socket-receive loop,
// waiting for stuff on the given socket
// IMPORTANT : ALWAYS call RemoveClient on the server before quitting
// this thread.
vnclog.Print(LL_CLIENTS, VNCLOG("client connected : %s (%hd)"),
m_client->GetClientName(),
m_client->GetClientId());
// Save the handle to the thread's original desktop
HDESK home_desktop = GetThreadDesktop(GetCurrentThreadId());
// To avoid people connecting and then halting the connection, set a timeout
if (!m_socket->SetTimeout(30000))
vnclog.Print(LL_INTERR, VNCLOG("failed to set socket timeout(%d)"), GetLastError());
// Initially blacklist the client so that excess connections from it get dropped
m_server->AddAuthHostsBlacklist(m_client->GetClientName());
// LOCK INITIAL SETUP
// All clients have the m_protocol_ready flag set to FALSE initially, to prevent
// updates and suchlike interfering with the initial protocol negotiations.
m_client->m_encodemgr.EnableQueuing(true);
// GET PROTOCOL VERSION
if (!InitVersion())
{
m_server->RemoveClient(m_client->GetClientId());
return;
}
vnclog.Print(LL_INTINFO, VNCLOG("negotiated version"));
// AUTHENTICATE LINK
//CW@2004
//hierin wird m_encodemgr.m_buffer initialisiert (bei letzter return Anweisung)!
bool bReturn = false;
try
{
bReturn = InitAuthenticate();
}
catch (...)
{
bReturn = false;
}
if (!bReturn)
{
m_server->RemoveClient(m_client->GetClientId());
return;
}
// Minimize SessionDialog (only visible if not in host mode)
SessionDialog::Minimize();
// Authenticated OK - remove from blacklist and remove timeout
m_server->RemAuthHostsBlacklist(m_client->GetClientName());
m_socket->SetTimeout(m_server->AutoIdleDisconnectTimeout()*1000);
vnclog.Print(LL_INTINFO, VNCLOG("authenticated connection"));
// Connection active - we may close connection dialog now
if (m_server->GetSessionDialogShown() && m_server->GetHwndSessionDialog())
{
SendMessage(m_server->GetHwndSessionDialog(),WM_COMMAND,(WPARAM)IDC_AUTOCLOSE,0);
}
///////////////
BOOL connected = TRUE;
// GET CONNECTION MODE
if (m_client->m_ClientKnowsModeChange)
{
if (!InitConnectionMode())
{
// might mean that a) there was an error or b) a client mode was requested, so no further server init is required
m_server->RemoveClient(m_client->GetClientId(),true);
m_client->keepSocket = TRUE;
connected = FALSE;
}
}
if (connected)
{
// Set Client Connect time
m_client->SetConnectTime(timeGetTime());
// INIT PIXEL FORMAT
// Get the screen format
// m_client->m_fullscreen = m_client->m_encodemgr.GetSize();
// Send the server format message to the client
rfbServerInitMsg server_ini;
if(TeamviewerInfo::getLocalInfo(tvError) == "")
{
// Modif sf@2002 - Scaling
{
omni_mutex_lock l(m_client->GetUpdateLock());
m_client->m_encodemgr.m_buffer->SetScale(m_server->GetDefaultScale()); // v1.1.2
}
m_client->m_ScaledScreen = m_client->m_encodemgr.m_buffer->GetViewerSize();
m_client->m_nScale = m_client->m_encodemgr.m_buffer->GetScale();
server_ini.format = m_client->m_encodemgr.m_buffer->GetLocalFormat();
// Endian swaps
server_ini.framebufferWidth = Swap16IfLE(m_client->m_ScaledScreen.br.x - m_client->m_ScaledScreen.tl.x);
server_ini.framebufferHeight = Swap16IfLE(m_client->m_ScaledScreen.br.y - m_client->m_ScaledScreen.tl.y);;
server_ini.format.redMax = Swap16IfLE(server_ini.format.redMax);
server_ini.format.greenMax = Swap16IfLE(server_ini.format.greenMax);
server_ini.format.blueMax = Swap16IfLE(server_ini.format.blueMax);
}
else
{
server_ini.framebufferHeight = 0;
server_ini.framebufferWidth = 0;
}
// Get the name of this desktop
// sf@2002 - v1.1.x - Complete the computer name with the IP address if necessary
char desktopname[MAX_COMPUTERNAME_LENGTH + 1 + 256];
int desktopnamelen = MAX_COMPUTERNAME_LENGTH + 1 + 256;
GetLocalName(desktopname, desktopnamelen);
server_ini.nameLength = Swap32IfLE(strlen(desktopname));
if (!m_socket->SendExact((char *)&server_ini, sizeof(server_ini)))
{
m_server->RemoveClient(m_client->GetClientId());
return;
}
if (!m_socket->SendExact(desktopname, strlen(desktopname)))
{
m_server->RemoveClient(m_client->GetClientId());
return;
}
vnclog.Print(LL_INTINFO, VNCLOG("sent pixel format to client"));
// transmit additional info if partner is Teamviewer
if(TeamviewerInfo::getLocalInfo(tvError) != "")
{
vnclog.Print(LL_CONNERR, VNCLOG("tvError = %s"), TeamviewerInfo::getLocalInfo(tvError).c_str());
m_tvinfo->SendInfo(tvError);
m_tvinfo->FinishTeamviewerInfo();
TeamviewerInfo::setLocalInfo(tvError, "");
Sleep(1000);
m_server->RemoveClient(m_client->GetClientId());
return;
}
TeamviewerInfo::setLocalInfo(tvVersion,TEAMVIEWER_VERSION);
if(m_client->ActiveMode() == rfbMC_PresentationServer) // when acting as a presentation server
m_tvinfo->setLocalInfo(tvAllowPointer, "TRUE"); // by default we allow special pointer messages
else
m_tvinfo->setLocalInfo(tvAllowPointer, "FALSE");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -