bool Auth::basicServer(std::shared_ptr<BaseLib::RPC::RPCHeader>& binaryHeader) { if(!_initialized) throw AuthException("Not initialized."); if(!binaryHeader) throw AuthException("Header is nullptr."); if(binaryHeader->authorization.empty()) { sendBasicUnauthorized(true); throw AuthException("No header field \"Authorization\""); } std::pair<std::string, std::string> authData = BaseLib::HelperFunctions::splitLast(binaryHeader->authorization, ' '); BaseLib::HelperFunctions::toLower(authData.first); if(authData.first != "basic") { sendBasicUnauthorized(true); throw AuthException("Authorization type is not basic but: " + authData.first); } std::string decodedData; BaseLib::Base64::decode(authData.second, decodedData); std::pair<std::string, std::string> credentials = BaseLib::HelperFunctions::splitLast(decodedData, ':'); BaseLib::HelperFunctions::toLower(credentials.first); if(std::find(_validUsers.begin(), _validUsers.end(), credentials.first) == _validUsers.end()) { sendBasicUnauthorized(true); throw AuthException("User name " + credentials.first + " is not in the list of valid users in /etc/homegear/rpcservers.conf."); } if(User::verify(credentials.first, credentials.second)) return true; sendBasicUnauthorized(true); return false; }
void RfbInitializer::doVncAuth() { UINT8 challenge[16]; srand((unsigned)time(0)); for (int i = 0; i < sizeof(challenge); i++) { challenge[i] = rand() & 0xff; } m_output->writeFully(challenge, sizeof(challenge)); UINT8 response[16]; m_input->readFully(response, sizeof(response)); checkForBan(); ServerConfig *srvConf = Configurator::getInstance()->getServerConfig(); if ( srvConf->shouldReloadConfigOnClientAuth() ) { Configurator::getInstance()->reloadConfig(); srvConf = Configurator::getInstance()->getServerConfig(); } bool hasPrim = srvConf->hasPrimaryPassword(); bool hasRdly = srvConf->hasReadOnlyPassword(); if (!hasPrim && !hasRdly) { throw AuthException(_T("Server is not configured properly")); } if (hasPrim) { UINT8 crypPrimPass[8]; srvConf->getPrimaryPassword(crypPrimPass); VncPassCrypt passCrypt; passCrypt.updatePlain(crypPrimPass); if (passCrypt.challengeAndResponseIsValid(challenge, response)) { return; } } if (hasRdly) { UINT8 crypReadOnlyPass[8]; srvConf->getReadOnlyPassword(crypReadOnlyPass); VncPassCrypt passCrypt; passCrypt.updatePlain(crypReadOnlyPass); if (passCrypt.challengeAndResponseIsValid(challenge, response)) { m_viewOnlyAuth = true; return; } } m_extAuthListener->onAuthFailed(m_client); throw AuthException(_T("Authentication failed")); }
bool Auth::sessionServer(BaseLib::WebSocket& webSocket) { if(!_initialized) throw AuthException("Not initialized."); if(webSocket.getContent().empty()) { sendWebSocketUnauthorized(webSocket, "No data received."); return false; } BaseLib::PVariable variable; try { variable = _jsonDecoder->decode(webSocket.getContent()); } catch(BaseLib::RPC::JsonDecoderException& ex) { sendWebSocketUnauthorized(webSocket, "Error decoding json (is packet in json format?)."); return false; } if(variable->type != BaseLib::VariableType::tStruct) { sendWebSocketUnauthorized(webSocket, "Received data is no json object."); return false; } if(variable->structValue->find("user") != variable->structValue->end() && GD::scriptEngineServer->checkSessionId(variable->structValue->at("user")->stringValue)) { sendWebSocketAuthorized(webSocket); return true; } else { sendWebSocketUnauthorized(webSocket, "No session id specified."); return false; } }
void RemoteViewerCore::authenticate() { m_logWriter.detail(_T("Negotiating about security type...")); int authenticationType = negotiateAboutSecurityType(); m_logWriter.info(_T("Authentication type accepted: %s (%d)"), getAuthenticationTypeName(authenticationType).getString(), authenticationType); if (authenticationType != 0) { m_logWriter.detail(_T("Authentication...")); if (m_authHandlers.find(authenticationType) != m_authHandlers.end()) { m_authHandlers[authenticationType]->authenticate(m_input, m_output); } else { // Security type is added automatic, but not by user. if (authenticationType != SecurityDefs::NONE) { m_logWriter.error(_T("Isn't exist authentication handler for selected security type %d"), authenticationType); throw AuthException(_T("Isn't exist authentication handler ") _T("for selected type of authentication")); } } } // get authentication result, if version 3.8 or authentication isn't None if (m_minor >= 8 || authenticationType != SecurityDefs::NONE) { UINT32 authResult = 0; if (authenticationType) { authResult = m_input->readUInt32(); m_logWriter.detail(_T("Auth result is %d"), authResult); } static const UINT32 AUTH_RESULT_OK = 0; if (!authenticationType || authResult != AUTH_RESULT_OK) { // if version 3.3 or 3.7 then server connection closed m_logWriter.message(_T("Authentication failure")); if (m_minor < 8) { throw AuthException(_T("Authentication failure")); } // if version 3.8 then try read reasonAuth. StringStorage reasonAuth; m_input->readUTF8(&reasonAuth); StringStorage errorMessage = _T("Authentication reason: "); errorMessage.appendString(reasonAuth.getString()); m_logWriter.message(_T("%s"), errorMessage.getString()); throw AuthException(errorMessage.getString()); } } }
void RfbInitializer::doVncAuth() { UINT8 challenge[16]; srand((unsigned)time(0)); for (int i = 0; i < sizeof(challenge); i++) { challenge[i] = rand() & 0xff; } m_output->writeFully(challenge, sizeof(challenge)); UINT8 response[16]; m_input->readFully(response, sizeof(response)); // Checking for a ban after auth. checkForBan(); // Comparing the challenge with the response. ServerConfig *srvConf = Configurator::getInstance()->getServerConfig(); bool hasPrim = srvConf->hasPrimaryPassword(); bool hasRdly = srvConf->hasReadOnlyPassword(); if (!hasPrim && !hasRdly) { throw AuthException(_T("Server is not configured properly")); } if (hasPrim) { UINT8 crypPrimPass[8]; srvConf->getPrimaryPassword(crypPrimPass); VncPassCrypt passCrypt; passCrypt.updatePlain(crypPrimPass); if (passCrypt.challengeAndResponseIsValid(challenge, response)) { return; } } if (hasRdly) { UINT8 crypReadOnlyPass[8]; srvConf->getReadOnlyPassword(crypReadOnlyPass); VncPassCrypt passCrypt; passCrypt.updatePlain(crypReadOnlyPass); if (passCrypt.challengeAndResponseIsValid(challenge, response)) { m_viewOnlyAuth = true; return; } } // At this time we are sure that the client was typed an incorectly password. m_extAuthListener->onAuthFailed(m_client); throw AuthException(_T("Authentication failed")); }
void RfbInitializer::doVncAuth() { UINT8 challenge[16]; srand((unsigned)time(0)); for (int i = 0; i < sizeof(challenge); i++) { challenge[i] = rand() & 0xff; } m_output->writeFully(challenge, sizeof(challenge)); UINT8 response[16]; m_input->readFully(response, sizeof(response)); // Checking for a ban after auth. checkForBan(); // Comparing the challenge with the response. ServerConfig *srvConf = Configurator::getInstance()->getServerConfig(); bool hasPrim = srvConf->hasPrimaryPassword(); if (!hasPrim) { throw AuthException(_T("Server is not configured properly")); } if (hasPrim) { UINT8 primPass[8]; srvConf->getPrimaryPassword(primPass); VncPassCrypt passCrypt; passCrypt.setPlain(primPass); if (passCrypt.challengeAndResponseIsValid(challenge, response)) { return; } } // At this time we are sure that the client was typed an incorectly password. m_extAuthListener->onAuthFailed(m_client); StringStorage clientAddressStorage; m_client->getPeerHost(&clientAddressStorage); StringStorage errMess; errMess.format(_T("Authentication failed from %s"), clientAddressStorage.getString()); throw AuthException(errMess.getString()); }
void Auth::sendBasicUnauthorized(bool binary) { if(binary) { if(_basicUnauthBinaryHeader.empty()) { BaseLib::PVariable error = BaseLib::Variable::createError(-32603, "Unauthorized"); _rpcEncoder->encodeResponse(error, _basicUnauthBinaryHeader); } try { _socket->proofwrite(_basicUnauthBinaryHeader); } catch(const BaseLib::SocketOperationException& ex) { throw AuthException("Authorization failed because of socket exception: " + ex.what()); } } else { if(_basicUnauthHTTPHeader.empty()) { std::string header; header.append("HTTP/1.1 401 Unauthorized\r\n"); header.append("Connection: Close\r\n"); std::string content("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\"><html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"><title>Unauthorized</title></head><body>Unauthorized</body></html>"); header.append("Content-Length: " + std::to_string(content.size()) + "\r\n\r\n"); header.append(content); _basicUnauthHTTPHeader.insert(_basicUnauthHTTPHeader.begin(), header.begin(), header.end()); } try { _socket->proofwrite(_basicUnauthHTTPHeader); } catch(const BaseLib::SocketOperationException& ex) { throw AuthException("Authorization failed because of socket exception: " + ex.what()); } } }
std::pair<std::string, std::string> Auth::basicClient() { if(!_initialized) throw AuthException("Not initialized."); if(_basicAuthString.second.empty()) { _basicAuthString.first = "Authorization"; std::string credentials = _userName + ":" + _password; std::string encodedData; BaseLib::Base64::encode(credentials, encodedData); _basicAuthString.second = "Basic " + encodedData; } return _basicAuthString; }
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")); } } }
bool Auth::basicServer(BaseLib::WebSocket& webSocket) { if(!_initialized) throw AuthException("Not initialized."); if(webSocket.getContent()->empty()) { sendWebSocketUnauthorized(webSocket, "No data received."); return false; } std::shared_ptr<BaseLib::RPC::Variable> variable; try { variable = _jsonDecoder->decode(*webSocket.getContent()); } catch(BaseLib::RPC::JsonDecoderException& ex) { sendWebSocketUnauthorized(webSocket, "Error decoding json (is packet in json format?)."); return false; } if(variable->type != BaseLib::RPC::VariableType::rpcStruct) { sendWebSocketUnauthorized(webSocket, "Received data is no json object."); return false; } #ifdef SCRIPTENGINE if(variable->structValue->find("user") == variable->structValue->end() || variable->structValue->find("password") == variable->structValue->end()) { if(variable->structValue->find("user") != variable->structValue->end() && GD::scriptEngine.checkSessionId(variable->structValue->at("user")->stringValue)) { sendWebSocketAuthorized(webSocket); return true; } else { sendWebSocketUnauthorized(webSocket, "Either \"user\" or \"password\" is not specified."); return false; } } #else sendWebSocketUnauthorized(webSocket, "Either \"user\" or \"password\" is not specified."); return false; #endif if(User::verify(variable->structValue->at("user")->stringValue, variable->structValue->at("password")->stringValue)) { sendWebSocketAuthorized(webSocket); return true; } sendWebSocketUnauthorized(webSocket, "Wrong user name or password."); return false; }
bool Auth::basicServer(BaseLib::WebSocket& webSocket) { if(!_initialized) throw AuthException("Not initialized."); if(webSocket.getContent()->empty()) { sendWebSocketUnauthorized(webSocket, "No data received."); return false; } BaseLib::PVariable variable; try { variable = _jsonDecoder->decode(*webSocket.getContent()); } catch(BaseLib::RPC::JsonDecoderException& ex) { sendWebSocketUnauthorized(webSocket, "Error decoding json (is packet in json format?)."); return false; } if(variable->type != BaseLib::VariableType::tStruct) { sendWebSocketUnauthorized(webSocket, "Received data is no json object."); return false; } if(variable->structValue->find("user") == variable->structValue->end() || variable->structValue->find("password") == variable->structValue->end()) { sendWebSocketUnauthorized(webSocket, "Either \"user\" or \"password\" is not specified."); return false; } if(User::verify(variable->structValue->at("user")->stringValue, variable->structValue->at("password")->stringValue)) { sendWebSocketAuthorized(webSocket); return true; } sendWebSocketUnauthorized(webSocket, "Wrong user name or password."); return false; }
void RfbInitializer::checkForBan() { if (m_extAuthListener->onCheckForBan(m_client)) { throw AuthException(_T("Your connection has been rejected")); } }
bool Auth::basicServer(BaseLib::HTTP& httpPacket) { if(!_initialized) throw AuthException("Not initialized."); _http.reset(); uint32_t bufferLength = 1024; char buffer[bufferLength + 1]; if(httpPacket.getHeader()->authorization.empty()) { if(_basicAuthHTTPHeader.empty()) { _basicAuthHTTPHeader.append("HTTP/1.1 401 Authorization Required\r\n"); _basicAuthHTTPHeader.append("WWW-Authenticate: Basic realm=\"Authentication Required\"\r\n"); _basicAuthHTTPHeader.append("Connection: Keep-Alive\r\n"); std::string content("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\"><html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"><title>Authorization Required</title></head><body>Authorization Required</body></html>"); _basicAuthHTTPHeader.append("Content-Length: " + std::to_string(content.size()) + "\r\n\r\n"); _basicAuthHTTPHeader.append(content); } std::shared_ptr<std::vector<char>> data(new std::vector<char>()); data->insert(data->begin(), _basicAuthHTTPHeader.begin(), _basicAuthHTTPHeader.end()); try { _socket->proofwrite(data); int32_t bytesRead = _socket->proofread(buffer, bufferLength); //Some clients send only one byte in the first packet if(bytesRead == 1) bytesRead += _socket->proofread(&buffer[1], bufferLength - 1); buffer[bytesRead] = '\0'; try { _http.process(buffer, bufferLength); } catch(BaseLib::HTTPException& ex) { throw AuthException("Authorization failed because of HTTP exception: " + ex.what()); } } catch(const BaseLib::SocketOperationException& ex) { throw AuthException("Authorization failed because of socket exception: " + ex.what()); } } else _http = httpPacket; if(_http.getHeader()->authorization.empty()) { sendBasicUnauthorized(false); throw AuthException("No header field \"Authorization\""); } std::pair<std::string, std::string> authData = BaseLib::HelperFunctions::splitLast(_http.getHeader()->authorization, ' '); BaseLib::HelperFunctions::toLower(authData.first); if(authData.first != "basic") { sendBasicUnauthorized(false); throw AuthException("Authorization type is not basic but: " + authData.first); } std::string decodedData; BaseLib::Base64::decode(authData.second, decodedData); std::pair<std::string, std::string> credentials = BaseLib::HelperFunctions::splitLast(decodedData, ':'); BaseLib::HelperFunctions::toLower(credentials.first); if(std::find(_validUsers.begin(), _validUsers.end(), credentials.first) == _validUsers.end()) { sendBasicUnauthorized(false); throw AuthException("User name " + credentials.first + " is not in the list of valid users in /etc/homegear/rpcservers.conf."); } if(User::verify(credentials.first, credentials.second)) return true; sendBasicUnauthorized(false); return false; }