📄 vncserver.cpp
字号:
// NOTIFICATION HANDLING!// Connect/disconnect notificationBOOLvncServer::AddNotify(HWND hwnd){ omni_mutex_lock l(m_clientsLock); // Add the window handle to the list m_notifyList.push_front(hwnd); return TRUE;}BOOLvncServer::RemNotify(HWND hwnd){ omni_mutex_lock l(m_clientsLock); // Remove the window handle from the list vncNotifyList::iterator i; for (i=m_notifyList.begin(); i!=m_notifyList.end(); i++) { if ((*i) == hwnd) { // Found the handle, so remove it m_notifyList.erase(i); return TRUE; } } return FALSE;}// Send a notification messagevoidvncServer::DoNotify(UINT message, WPARAM wparam, LPARAM lparam){ omni_mutex_lock l(m_clientsLock); // Send the given message to all the notification windows vncNotifyList::iterator i; for (i=m_notifyList.begin(); i!=m_notifyList.end(); i++) { PostMessage((*i), message, wparam, lparam); }}voidvncServer::UpdateMouse(){ vncClientList::iterator i; omni_mutex_lock l(m_clientsLock); // Post this mouse update to all the connected clients for (i = m_authClients.begin(); i != m_authClients.end(); i++) { // Post the update GetClient(*i)->UpdateMouse(); }}voidvncServer::UpdateClipText(const char* text){ vncClientList::iterator i; omni_mutex_lock l(m_clientsLock); // Post this update to all the connected clients for (i = m_authClients.begin(); i != m_authClients.end(); i++) { // Post the update GetClient(*i)->UpdateClipText(text); }}voidvncServer::UpdatePalette(){ vncClientList::iterator i; omni_mutex_lock l(m_clientsLock); // Post this update to all the connected clients for (i = m_authClients.begin(); i != m_authClients.end(); i++) { // Post the update GetClient(*i)->UpdatePalette(); }}voidvncServer::UpdateLocalFormat(){ vncClientList::iterator i; omni_mutex_lock l(m_clientsLock); // Post this update to all the connected clients for (i = m_authClients.begin(); i != m_authClients.end(); i++) { // Post the update GetClient(*i)->UpdateLocalFormat(); }}voidvncServer::UpdateLocalClipText(LPSTR text){ omni_mutex_lock l(m_desktopLock); if (m_desktop != NULL) m_desktop->SetClipText(text);}// Name and port number handlingvoidvncServer::SetName(const char * name){ // Set the name of the desktop if (m_name != NULL) { free(m_name); m_name = NULL; } m_name = strdup(name);}voidvncServer::SetPort(const UINT port){ if (m_port != port) { ///////////////////////////////// // Adjust the listen socket // Set the port number to use m_port = port; // If there is already a listening socket then close and re-open it... BOOL socketon = SockConnected(); SockConnect(FALSE); if (socketon) SockConnect(TRUE); }}UINTvncServer::GetPort(){ return m_port;}voidvncServer::SetPassword(const char *passwd){ memcpy(m_password, passwd, MAXPWLEN);}voidvncServer::GetPassword(char *passwd){ memcpy(passwd, m_password, MAXPWLEN);}// Remote input handlingvoidvncServer::EnableRemoteInputs(BOOL enable){ m_enable_remote_inputs = enable;}BOOL vncServer::RemoteInputsEnabled(){ return m_enable_remote_inputs;}// Local input handlingvoidvncServer::DisableLocalInputs(BOOL disable){ m_disable_local_inputs = disable;}BOOL vncServer::LocalInputsDisabled(){ return m_disable_local_inputs;}// Socket connection handlingBOOLvncServer::SockConnect(BOOL On){ // Are we being asked to switch socket connects on or off? if (On) { // Is there a listening socket? if (m_socketConn == NULL) { m_socketConn = new vncSockConnect(); if (m_socketConn == NULL) return FALSE; // Are we to use automatic port selection? if (m_autoportselect) { BOOL ok = FALSE; // Yes, so cycle through the ports, looking for a free one! for (int i=0; i < 99; i++) { m_port = DISPLAY_TO_PORT(i); vnclog.Print(LL_CLIENTS, VNCLOG("trying port number %d\n"), m_port); // Attempt to connect to the port VSocket tempsock; if (tempsock.Create()) { if (!tempsock.Connect("localhost", m_port)) { // Couldn't connect, so this port is probably usable! if (m_socketConn->Init(this, m_port)) { ok = TRUE; break; } } } } if (!ok) { delete m_socketConn; m_socketConn = NULL; return FALSE; } } else { // No autoportselect if (!m_socketConn->Init(this, m_port)) { delete m_socketConn; m_socketConn = NULL; return FALSE; } } // Now let's start the HTTP connection stuff EnableHTTPConnect(m_enableHttpConn); } } else { // *** JNW - Trying to fix up a lock-up when the listening socket closes KillAuthClients(); KillUnauthClients(); WaitUntilAuthEmpty(); WaitUntilUnauthEmpty(); // Is there a listening socket? if (m_socketConn != NULL) { // Close the socket delete m_socketConn; m_socketConn = NULL; } // Is there an HTTP socket active? EnableHTTPConnect(m_enableHttpConn); } return TRUE;}BOOLvncServer::SockConnected(){ return m_socketConn != NULL;}BOOLvncServer::EnableHTTPConnect(BOOL enable) { m_enableHttpConn = enable; if (enable && m_socketConn) { if (m_httpConn == NULL) { m_httpConn = new vncHTTPConnect; if (m_httpConn != NULL) { // Start up the HTTP server if (!m_httpConn->Init(this, PORT_TO_DISPLAY(m_port) + HTTP_PORT_OFFSET)) { delete m_httpConn; m_httpConn = NULL; return FALSE; } } } } else { if (m_httpConn != NULL) { // Close the socket delete m_httpConn; m_httpConn = NULL; } } return TRUE;}BOOLvncServer::SetLoopbackOnly(BOOL loopbackOnly){ if (loopbackOnly != m_loopbackOnly) { m_loopbackOnly = loopbackOnly; BOOL socketConn = SockConnected(); SockConnect(FALSE); SockConnect(socketConn); } return TRUE;}BOOLvncServer::LoopbackOnly(){ return m_loopbackOnly;}// CORBA connection handlingBOOLvncServer::CORBAConnect(BOOL On){ // Are we being asked to switch CORBA connects on or off? if (On) { // Is there a CORBA object? if (m_corbaConn == NULL) { m_corbaConn = new vncCorbaConnect(); } if (m_corbaConn == NULL) return FALSE; if (!m_corbaConn->Init(this)) { delete m_corbaConn; m_corbaConn = NULL; return FALSE; } } else { // Is there a listening socket? if (m_corbaConn != NULL) { // Close the socket delete m_corbaConn; m_corbaConn = NULL; } } return TRUE;}BOOLvncServer::CORBAConnected(){ return m_corbaConn != NULL;}voidvncServer::GetScreenInfo(int &width, int &height, int &depth){ rfbServerInitMsg scrinfo; omni_mutex_lock l(m_desktopLock); vnclog.Print(LL_INTINFO, VNCLOG("GetScreenInfo called\n")); // Is a desktop object currently active? if (m_desktop == NULL) { vncDesktop desktop; // No, so create a dummy desktop and interrogate it if (!desktop.Init(this)) { scrinfo.framebufferWidth = 0; scrinfo.framebufferHeight = 0; scrinfo.format.bitsPerPixel = 0; } else { desktop.FillDisplayInfo(&scrinfo); } } else { m_desktop->FillDisplayInfo(&scrinfo); } // Get the info from the scrinfo structure width = scrinfo.framebufferWidth; height = scrinfo.framebufferHeight; depth = scrinfo.format.bitsPerPixel;}voidvncServer::SetAuthHosts(const char*hostlist) { omni_mutex_lock l(m_clientsLock); if (hostlist == 0) { vnclog.Print(LL_INTINFO, VNCLOG("authhosts cleared\n")); m_auth_hosts = 0; return; } vnclog.Print(LL_INTINFO, VNCLOG("authhosts set to \"%s\"\n"), hostlist); if (m_auth_hosts != 0) free(m_auth_hosts); m_auth_hosts = strdup(hostlist);}char*vncServer::AuthHosts() { omni_mutex_lock l(m_clientsLock); if (m_auth_hosts == 0) return strdup(""); else return strdup(m_auth_hosts);}inline BOOLMatchStringToTemplate(const char *addr, UINT addrlen, const char *filtstr, UINT filtlen) { if (filtlen == 0) return 1; if (addrlen < filtlen) return 0; for (int x = 0; x < filtlen; x++) { if (addr[x] != filtstr[x]) return 0; } if ((addrlen > filtlen) && (addr[filtlen] != '.')) return 0; return 1;}vncServer::AcceptQueryRejectvncServer::VerifyHost(const char *hostname) { omni_mutex_lock l(m_clientsLock); // -=- Is the specified host blacklisted? vncServer::BlacklistEntry *current = m_blacklist; vncServer::BlacklistEntry *previous = 0; SYSTEMTIME systime; FILETIME ftime; LARGE_INTEGER now; // Get the current time as a 64-bit value GetSystemTime(&systime); SystemTimeToFileTime(&systime, &ftime); now.LowPart=ftime.dwLowDateTime;now.HighPart=ftime.dwHighDateTime; now.QuadPart /= 10000000; // Convert it into seconds while (current) { // Has the blacklist entry timed out? if ((now.QuadPart - current->_lastRefTime.QuadPart) > 0) { // Yes. Is it a "blocked" entry? if (current->_blocked) { // Yes, so unblock it & re-set the reference time current->_blocked = FALSE; current->_lastRefTime.QuadPart = now.QuadPart + 10; } else { // No, so remove it if (previous) previous->_next = current->_next; else m_blacklist = current->_next; vncServer::BlacklistEntry *next = current->_next; free(current->_machineName); delete current; current = next; continue; } } // Is this the entry we're interested in? if ((strcmp(current->_machineName, hostname) == 0) && (current->_blocked)) { // Machine is blocked, so just reject it return vncServer::aqrReject; } previous = current; current = current->_next; } // Has a hostname been specified? if (hostname == 0) { vnclog.Print(LL_INTWARN, VNCLOG("verify failed - null hostname\n")); return vncServer::aqrReject; } // Set the state machine into the correct mode & process the filter enum vh_Mode {vh_ExpectDelimiter, vh_ExpectIncludeExclude, vh_ExpectPattern}; vh_Mode machineMode = vh_ExpectIncludeExclude; vncServer::AcceptQueryReject verifiedHost = vncServer::aqrAccept; vncServer::AcceptQueryReject patternType = vncServer::aqrReject; UINT authHostsPos = 0; UINT patternStart = 0; UINT hostNameLen = strlen(hostname); // Run through the auth hosts string until we hit the end if (m_auth_hosts) { while (1) { // Which mode are we in? switch (machineMode) { // ExpectIncludeExclude - we should see a + or -. case vh_ExpectIncludeExclude: if (m_auth_hosts[authHostsPos] == '+') { patternType = vncServer::aqrAccept; patternStart = authHostsPos+1; machineMode = vh_ExpectPattern; } else if (m_auth_hosts[authHostsPos] == '-') { patternType = vncServer::aqrReject; patternStart = authHostsPos+1; machineMode = vh_ExpectPattern; } else if (m_auth_hosts[authHostsPos] == '?') { patternType = vncServer::aqrQuery; patternStart = authHostsPos+1; machineMode = vh_ExpectPattern; } else if (m_auth_hosts[authHostsPos] != '\0') { vnclog.Print(LL_INTWARN, VNCLOG("verify host - malformed AuthHosts string\n")); machineMode = vh_ExpectDelimiter; } break; // ExpectPattern - we expect to see a valid pattern case vh_ExpectPattern: // ExpectDelimiter - we're scanning for the next ':', skipping a pattern case vh_ExpectDelimiter: if ((m_auth_hosts[authHostsPos] == ':') || (m_auth_hosts[authHostsPos] == '\0')) { if (machineMode == vh_ExpectPattern) { if (patternStart == 0) { vnclog.Print(LL_INTWARN, VNCLOG("verify host - pattern processing failed!\n")); } else { // Process the match if (MatchStringToTemplate(hostname, hostNameLen, &(m_auth_hosts[patternStart]), authHostsPos-patternStart)) { // The hostname matched - apply the include/exclude rule verifiedHost = patternType; } } } // We now expect another + or - machineMode = vh_ExpectIncludeExclude; } break; } // Have we hit the end of the pattern string? if (m_auth_hosts[authHostsPos] == '\0') break; authHostsPos++; } } // Based on the server's QuerySetting, adjust the verification result switch (verifiedHost) { case vncServer::aqrAccept: if (QuerySetting() >= 3) verifiedHost = vncServer::aqrQuery; break; case vncServer::aqrQuery: if (QuerySetting() <= 1) verifiedHost = vncServer::aqrAccept; else if (QuerySetting() == 4) verifiedHost = vncServer::aqrReject; break; case vncServer::aqrReject: if (QuerySetting() == 0) verifiedHost = vncServer::aqrQuery; break; }; return verifiedHost;}voidvncServer::AddAuthHostsBlacklist(const char *machine) { omni_mutex_lock l(m_clientsLock); // -=- Is the specified host blacklisted? vncServer::BlacklistEntry *current = m_blacklist; // Get the current time as a 64-bit value SYSTEMTIME systime; FILETIME ftime; LARGE_INTEGER now; GetSystemTime(&systime); SystemTimeToFileTime(&systime, &ftime); now.LowPart=ftime.dwLowDateTime;now.HighPart=ftime.dwHighDateTime; now.QuadPart /= 10000000; // Convert it into seconds while (current) { // Is this the entry we're interested in? if (strcmp(current->_machineName, machine) == 0) { // If the host is already blocked then ignore if (current->_blocked) return; // Set the RefTime & failureCount current->_lastRefTime.QuadPart = now.QuadPart + 10; current->_failureCount++; if (current->_failureCount > 5) current->_blocked = TRUE; return; } current = current->_next; } // Didn't find the entry current = new vncServer::BlacklistEntry; current->_blocked = FALSE; current->_failureCount = 0; current->_lastRefTime.QuadPart = now.QuadPart + 10; current->_machineName = strdup(machine); current->_next = m_blacklist; m_blacklist = current;}voidvncServer::RemAuthHostsBlacklist(const char *machine) { omni_mutex_lock l(m_clientsLock); // -=- Is the specified host blacklisted? vncServer::BlacklistEntry *current = m_blacklist; vncServer::BlacklistEntry *previous = 0; while (current) { // Is this the entry we're interested in? if (strcmp(current->_machineName, machine) == 0) { if (previous) previous->_next = current->_next; else m_blacklist = current->_next; vncServer::BlacklistEntry *next = current->_next; free (current->_machineName); delete current; current = next; continue; } previous = current; current = current->_next; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -