⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vncclient.cpp

📁 teamviewer source code vc++
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		// Update the client palette if necessary

		if (send_palette) { 
			m_client->SendPalette();
		}

		// Send updates to the client - this implicitly clears
		// the supplied update tracker
		if (m_client->SendUpdate(update)) {
			updates_sent++;
			clipregion.clear();
		}

		yield();

		if (!m_active)
			break;

		//Pushprotokoll
		if (m_client->m_thread && m_client->m_thread->m_autopush) // Ab 1.85 Pushprotokoll
		{
			rfb::Rect update;
			update.tl.x = (m_client->m_SWOffsetx) * m_client->m_nScale;
			update.tl.y = (m_client->m_SWOffsety) * m_client->m_nScale;
			update.br.x = m_client->m_ScaledScreen.br.x - m_client->m_ScaledScreen.tl.x;
			update.br.y = m_client->m_ScaledScreen.br.y - m_client->m_ScaledScreen.tl.y;
			rfb::Region2D update_rgn = update;
			//omni_mutex_lock l(m_client->GetUpdateLock());
			m_client->m_incr_rgn = m_client->m_incr_rgn.union_(update_rgn);

			m_client->m_encodemgr.m_buffer->m_desktop->TriggerUpdate();
			m_client->TriggerUpdateThread();
		}
		if(m_client->m_encodemgr.m_buffer &&
			m_client->m_encodemgr.m_buffer->m_desktop &&
			m_client->m_encodemgr.m_buffer->m_desktop->m_stop_input_while_sw)
			m_client->m_encodemgr.m_buffer->m_desktop->m_stop_input_while_sw = false;
	}
#ifndef _DEBUG
	}
	catch(...)
	{
		vnclog.Print(LL_INTERR, VNCLOG("ClientUpdateThread.CATCH"));
	}
#endif

	vnclog.Print(LL_INTINFO, VNCLOG("stopping update thread"));
	
	vnclog.Print(LL_INTERR, VNCLOG("client sent %lu updates"), updates_sent);
	return 0;
}

vncClientThread::~vncClientThread()
{
	// If we have a client object then delete it
	if (m_client != NULL)
		delete m_client;

	if (m_tvinfo != NULL)
		delete m_tvinfo;
}

BOOL
vncClientThread::Init(vncClient *client, vncServer *server, VSocket *socket, BOOL auth, BOOL shared)
{
	// Save the server pointer and window handle
	m_server = server;
	m_socket = socket;
	m_client = client;
	m_auth = auth;
	m_shared = shared;
	m_autopush = false;
	
	m_tvinfo = new TeamviewerInfo(TI_VNCCLIENT, this);

	// Start the thread
	start();

	return TRUE;
}

BOOL
vncClientThread::InitConnectionMode()
{
	rfbModeChangeMsg mcm;

	if (!m_socket->ReadExact((char *)&mcm, sz_rfbModeChangeMsg))
		return false;
	if ( !(mcm.newmode & rfbMC_Servermodes)) 
	{ 
		// a client connection was requested, so directly switch to client mode
		VNCviewerApp32 *app = VNCviewerApp32::Instance();

		// connect with existing socket
		app->NewConnection((SOCKET)m_socket->sock,mcm.newmode);					

		// Keep the socket
		m_client->keepSocket=TRUE;

		return false;
	}
	else
	{
		// set server mode
		m_client->SetActiveMode(mcm.newmode);
		
		// some special settings for different modes
		switch (mcm.newmode)
		{
			case rfbMC_PresentationServer:
				m_client->EnablePointer(FALSE);
				m_client->EnableKeyboard(FALSE);
				break;
		}

		return true;
	}
}

BOOL
vncClientThread::InitVersion()
{
	rfbProtocolVersionMsg protocol_ver;
	protocol_ver[12] = 0;
	if (strcmp(m_client->ProtocolVersionMsg,"0.0.0.0") == 0)
	{
		// Generate the server's protocol version
		rfbProtocolVersionMsg protocolMsg;
		sprintf((char *)protocolMsg,
			rfbProtocolVersionFormat,
			rfbProtocolMajorVersion,
			rfbProtocolMinorVersion + (m_server->MSLogonRequired() ? 0 : 2)); // 4: mslogon+FT,
																			  // 6: VNClogon+FT
		// Send the protocol message
		m_socket->SetTimeout(0);
		if (!m_socket->SendExact((char *)&protocolMsg, sz_rfbProtocolVersionMsg))
			return FALSE;

		// Now, get the client's protocol version
		if (!m_socket->ReadExact((char *)&protocol_ver, sz_rfbProtocolVersionMsg))
		{
			return FALSE;
		}
	}
	else memcpy(protocol_ver,m_client->ProtocolVersionMsg,sz_rfbProtocolVersionMsg);

	// Check viewer's the protocol version
	int major, minor;
	sscanf((char *)&protocol_ver, rfbProtocolVersionFormat, &major, &minor);
	if (strncmp (protocol_ver,"TV ",3)==0)	//TeamViewer 3
	{
		PostMessage(menu->GetHWND(),WM_REQUEST_UPDATE_TEAMVIEWER,0,0);
		//throw QuietException("Connection failed - incompatible TeamViewer version!\r\n");
		return FALSE;
	}
	
	
	if (major != rfbProtocolMajorVersion)
		return FALSE;

	// TODO: Maybe change this UltraVNC specific minor value because
	// TightVNC viewer uses minor = 5 ...
	// For now:
	// UltraViewer always sends minor = 4 (sf@2005: or 6, as it returns the minor version received from the server)
	// UltraServer sends minor = 4 or minor = 6
	// m_ms_logon = false; // For all non-UltraVNC logon compatible viewers

	//TR@2004: roVNC client=14, server=14 or 16
	m_ms_logon = m_server->MSLogonRequired();
	if ((minor == 4) || (minor == 6) || (minor == 14) || (minor == 16) || (minor%200 == 34) || (minor%200 == 36))
		m_client->SetUltraViewer(true); 
	else 
		m_client->SetUltraViewer(false);

	// Old TeamViewers aren't accepted any more
	if ((minor == rfbProtocolMinorVersion) || (minor == rfbProtocolMinorVersion+2)) 
	{
		m_client->m_ClientKnowsModeChange = true;
		m_tvinfo->partnerIsTeamviewer = true;
	}

	vnclog.Print(LL_INTINFO, VNCLOG("m_ms_logon set to %s"), m_ms_logon ? "true" : "false");


	return TRUE;
}

BOOL
vncClientThread::InitAuthenticate()
{
	vnclog.Print(LL_INTINFO, VNCLOG("Entered InitAuthenticate"));
	// Retrieve the local password
	char password[MAXPWLEN];
	char passwordMs[MAXMSPWLEN];
	m_server->GetPassword(password);


	string plain;
	if(strlen(SessionDialog::quickSupportPassword) > 0)
	{
		plain = string(SessionDialog::quickSupportPassword);
	}
	else
	if(m_server->GetServerMode())
	{
		vncPasswd::ToText vncPassword(password);
		plain=vncPassword;
	}
	else
	{
		plain=m_server->SessionPassword();
	}
	vncServer::AcceptQueryReject verified=vncServer::aqrAccept;
	
	// If necessary, query the connection with a timed dialog
	char username[UNLEN+1];
	if (!vncService::CurrentUser(username, sizeof(username))) return false;
	
	// Staudenmeyer@2005:
	//if(m_server->GetIncomingConnections()==ConnectionViewerOpened && !sessionDialogShown)
	//{
	//	return false;
	//}

	if (strcmp(username, "") != 0)
		if (verified == vncServer::aqrQuery) {
			vncAcceptDialog *acceptDlg = new vncAcceptDialog(m_client, m_server->QueryTimeout(),m_server->QueryAccept(), m_socket->GetPeerName());
	
			if (acceptDlg == NULL) 
				{
					if (m_server->QueryAccept()==1) 
					{
						verified = vncServer::aqrAccept;
					}
					else 
					{
						// No end dialog if Accept = no
						verified = vncServer::aqrReject;
					}
				}
			else 
				{
					if ( !(acceptDlg->DoDialog()) ) verified = vncServer::aqrReject;

				}
		}

	if (verified == vncServer::aqrReject) {
		CARD32 auth_val = Swap32IfLE(rfbConnFailed);

		char *errmsg = sz_IDS_CONNECTION_REJECTED;
		CARD32 errlen = Swap32IfLE(strlen(errmsg));
		if (!m_socket->SendExact((char *)&auth_val, sizeof(auth_val)))
			return FALSE;
		if (!m_socket->SendExact((char *)&errlen, sizeof(errlen)))
			return FALSE;
		m_socket->SendExact(errmsg, strlen(errmsg));
		return FALSE;
	}

	// By default we disallow passwordless workstations
	// TR@2004: We require either password or query window
	if ((plain.length() == 0) && m_server->AuthRequired() && m_server->QuerySetting()!=4)
	{
		vnclog.Print(LL_CONNERR, VNCLOG("no password specified for server - client rejected"));

		// Send an error message to the client
		CARD32 auth_val = Swap32IfLE(rfbConnFailed);
		char *errmsg =
			"This server does not have a valid password enabled.  "
			"Until a password is set, incoming connections cannot be accepted.";
		CARD32 errlen = Swap32IfLE(strlen(errmsg));

		if (!m_socket->SendExact((char *)&auth_val, sizeof(auth_val)))
			return FALSE;
		if (!m_socket->SendExact((char *)&errlen, sizeof(errlen)))
			return FALSE;
		m_socket->SendExact(errmsg, strlen(errmsg));

		return FALSE;
	}

	// By default we filter out local loop connections, because they're pointless
	if (!m_server->LoopbackOk())
	{
		char *localname = strdup(m_socket->GetSockName());
		char *remotename = strdup(m_socket->GetPeerName());

		// Check that the local & remote names are different!
		if ((localname != NULL) && (remotename != NULL))
		{
			BOOL ok = strcmp(localname, remotename) != 0;

			if (!ok)
			{
				vnclog.Print(LL_CONNERR, VNCLOG("loopback connection attempted - client rejected"));
				
				// Send an error message to the client
				CARD32 auth_val = Swap32IfLE(rfbConnFailed);
				char *errmsg = "Local loop-back connections are disabled.";
				CARD32 errlen = Swap32IfLE(strlen(errmsg));

				m_socket->SendExact((char *)&auth_val, sizeof(auth_val));
				m_socket->SendExact((char *)&errlen, sizeof(errlen));
				m_socket->SendExact(errmsg, strlen(errmsg));
				if (localname != NULL)
					free(localname);
				if (remotename != NULL)
					free(remotename);
				return FALSE;
			}
		}
		if (localname != NULL)
			free(localname);

		if (remotename != NULL)
			free(remotename);
	}
	else
	{
		char *localname = strdup(m_socket->GetSockName());
		char *remotename = strdup(m_socket->GetPeerName());

		// Check that the local & remote names are different!
		if ((localname != NULL) && (remotename != NULL))
		{
			BOOL ok = strcmp(localname, remotename) != 0;

			if (!ok)
			{
				vnclog.Print(LL_CONNERR, VNCLOG("loopback connection attempted - client accepted"));
				m_client->m_IsLoopback=true;
			}
		}
		if (localname != NULL)
			free(localname);

		if (remotename != NULL)
			free(remotename);
	}

	// Authenticate the connection, if required
	if (m_auth || (plain.length() == 0))// || !m_server->GetServerMode())
	{
		// Send no-auth-required message
		CARD32 auth_val = Swap32IfLE(rfbNoAuth);
		if (!m_socket->SendExact((char *)&auth_val, sizeof(auth_val)))
			return FALSE;
	}
	else
	{
		// Send auth-required message
		CARD32 auth_val = Swap32IfLE(rfbVncAuth);
		if (!m_socket->SendExact((char *)&auth_val, sizeof(auth_val)))
			return FALSE;

		BOOL auth_ok = TRUE;
		{
			/*
			// sf@2002 - DSMPlugin
			// Use Plugin only from this point for the moment
			if (m_server->GetDSMPluginPointer()->IsEnabled())
			{
				m_socket->EnableUsePlugin(true);
				// TODO: Make a more secured challenge (with time stamp)
			}
			*/

			// Now create a 16-byte challenge
			char challenge[16];
			char challenge2[16];
			char challengems[64];
			char response[16];
			char responsems[64];
			char *plainmsPasswd;
			char user[256];
			char domain[256];
			vncRandomBytes((BYTE *)&challenge);
			vncRandomBytesMs((BYTE *)&challengems);

			// Send the challenge to the client
			// m_ms_logon = false;
			if (m_ms_logon)
			{
				vnclog.Print(LL_INTINFO, VNCLOG("MS-Logon authentication"));
				if (!m_socket->SendExact(challengems, sizeof(challengems)))
					return FALSE;
				if (!m_socket->SendExact(challenge, sizeof(challenge)))
						return FALSE;
				if (!m_socket->ReadExact(user, sizeof(char)*256))
					return FALSE;
				if (!m_socket->ReadExact(domain, sizeof(char)*256))
					return FALSE;
				// Read the response
				if (!m_socket->ReadExact(responsems, sizeof(responsems)))
					return FALSE;
				if (!m_socket->ReadExact(response, sizeof(response)))
						return FALSE;
				
				// TODO: Improve this... 
				for (int i = 0; i < 32 ;i++)
				{
					passwordMs[i] = challengems[i]^responsems[i];
				}

				// REM: Instead of the fixedkey, we could use VNC password
				// -> the user needs to enter the VNC password on viewer's side.
				plainmsPasswd = vncDecryptPasswdMs((char *)passwordMs);

				// We let it as is right now for testing purpose.
				if (strlen(user) == 0 && !m_server->MSLogonRequired())
				{
					vnclog.Print(LL_INTINFO, VNCLOG("No user specified, mslogon not required"));
					vncEncryptBytes((BYTE *)&challenge, plain.c_str());
					//vncEncryptBytes((BYTE *)&challenge, plain);
	
					// Compare them to the response
					for (int i=0; i<sizeof(challenge); i++)
					{
						if (challenge[i] != response[i])
						{
							auth_ok = FALSE;
							break;
						}
					}
				}
				else 
				{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -