void RfbServer::onAcceptConnection(SocketIPv4 *socket) { try { // Get incoming connection address and convert it to string. SocketAddressIPv4 peerAddr; socket->getPeerAddr(&peerAddr); StringStorage peerIpString; peerAddr.toString(&peerIpString); m_log->message(_T("Incoming rfb connection from %s"), peerIpString.getString()); struct sockaddr_in addr_in = peerAddr.getSockAddr(); // Check access control rules for the IP address of the peer. // FIXME: Check loopback-related rules separately, report differently. ServerConfig *config = Configurator::getInstance()->getServerConfig(); IpAccessRule::ActionType action = config->getActionByAddress((unsigned long)addr_in.sin_addr.S_un.S_addr); if (action == IpAccessRule::ACTION_TYPE_DENY) { m_log->message(_T("Connection rejected due to access control rules")); delete socket; return; } // Access granted, add new RFB client. One more check will follow later in // RfbClientManager::onCheckAccessControl(). socket->enableNaggleAlgorithm(false); m_clientManager->addNewConnection(socket, &m_viewPort, false, false); } catch (Exception &ex) { m_log->error(_T("Failed to process incoming rfb connection with following reason: \"%s\""), ex.getMessage()); } }
void RfbInitializer::checkForLoopback() { SocketAddressIPv4 sockAddr; m_client->getSocketAddr(&sockAddr); struct sockaddr_in addrIn = sockAddr.getSockAddr(); bool isLoopback = (unsigned long)addrIn.sin_addr.S_un.S_addr == 16777343; ServerConfig *srvConf = Configurator::getInstance()->getServerConfig(); if (isLoopback && !srvConf->isLoopbackConnectionsAllowed()) { throw Exception(_T("Sorry, loopback connections are not enabled")); } if (srvConf->isOnlyLoopbackConnectionsAllowed() && !isLoopback) { throw Exception(_T("Your connection has been rejected")); } }
void SocketIPv4::connect(const SocketAddressIPv4 &addr) { struct sockaddr_in targetSockAddr = addr.getSockAddr(); if (::connect(m_socket, (const sockaddr *)&targetSockAddr, addr.getAddrLen()) == SOCKET_ERROR) { throw SocketException(); } AutoLock l(&m_mutex); if (m_peerAddr) { delete m_peerAddr; } m_peerAddr = new SocketAddressIPv4(*(struct sockaddr_in *)&targetSockAddr); m_isBound = false; }
void SocketIPv4::bind(const SocketAddressIPv4 &addr) { struct sockaddr_in bindSockaddr = addr.getSockAddr(); if (::bind(m_socket, (const sockaddr *)&bindSockaddr, addr.getAddrLen()) == SOCKET_ERROR) { throw SocketException(); } AutoLock l(&m_mutex); if (m_localAddr) { delete m_localAddr; } m_localAddr = new SocketAddressIPv4(*(struct sockaddr_in*)&bindSockaddr); m_isBound = true; }
void RfbClientManager::onCheckAccessControl(RfbClient *client) { SocketAddressIPv4 peerAddr; try { client->getSocketAddr(&peerAddr); } catch (...) { throw AuthException(_T("Failed to get IP address of the RFB client")); } struct sockaddr_in addr_in = peerAddr.getSockAddr(); ServerConfig *config = Configurator::getInstance()->getServerConfig(); IpAccessRule::ActionType action; if (!client->isOutgoing()) { action = config->getActionByAddress((unsigned long)addr_in.sin_addr.S_un.S_addr); } else { action = IpAccessRule::ACTION_TYPE_ALLOW; } // Promt user to know what to do with incmoing connection. if (action == IpAccessRule::ACTION_TYPE_QUERY) { StringStorage peerHost; peerAddr.toString(&peerHost); int queryRetVal = QueryConnectionApplication::execute(peerHost.getString(), config->isDefaultActionAccept(), config->getQueryTimeout()); if (queryRetVal == 1) { throw AuthException(_T("Connection has been rejected")); } } }