diff --git a/git-teaspeak b/git-teaspeak index 401d248..50c0265 160000 --- a/git-teaspeak +++ b/git-teaspeak @@ -1 +1 @@ -Subproject commit 401d248244b1d0dc82726d9baaeb375cb37f6f91 +Subproject commit 50c0265be2f44dff2225d8e8a9c29514c95263c2 diff --git a/server/src/client/query/QueryClient.cpp b/server/src/client/query/QueryClient.cpp index 548b2e8..9a38a84 100644 --- a/server/src/client/query/QueryClient.cpp +++ b/server/src/client/query/QueryClient.cpp @@ -362,13 +362,14 @@ void QueryClient::handle_event_read(int fd, short, void *ptr_client) { auto client = (QueryClient*) ptr_client; auto length = read(fd, buffer, kReadBufferLength); - if(length <= 0){ - if(errno == EINTR || errno == EAGAIN) { + if(length <= 0) { + /* error handling */ + if(length == -1 && errno == EAGAIN) { /* Nothing to read */ return; } - if(length == 0 && errno == 0) { + if(length == 0) { logMessage(LOG_QUERY, "{} Connection closed. Client disconnected.", client->getLoggingPrefix()); } else { logMessage(LOG_QUERY, "{} Failed to received message ({}/{}). Closing connection.", client->getLoggingPrefix(), errno, strerror(errno)); diff --git a/server/src/client/voice/CryptSetupHandler.cpp b/server/src/client/voice/CryptSetupHandler.cpp index 44e24c7..c1f4307 100644 --- a/server/src/client/voice/CryptSetupHandler.cpp +++ b/server/src/client/voice/CryptSetupHandler.cpp @@ -111,7 +111,6 @@ CryptSetupHandler::CommandResult CryptSetupHandler::handleCommandClientInitIv(co client->properties()[property::CLIENT_TYPE_EXACT] = ClientType::CLIENT_TEASPEAK; } - /* normal TeamSpeak handling */ this->seed_client = base64::decode(cmd.value("alpha")); if(this->seed_client.length() != 10) { return ts::command_result{error::parameter_invalid, "alpha"}; @@ -122,30 +121,31 @@ CryptSetupHandler::CommandResult CryptSetupHandler::handleCommandClientInitIv(co bool ot = cmd.has_key("ot") && cmd.value_as("ot"); { - this->remote_key = std::shared_ptr(new ecc_key{}, [](ecc_key* key){ - if(!key) return; - ecc_free(key); - delete key; - }); - - auto state = ecc_import((const unsigned char *) clientOmega.data(), clientOmega.length(), &*this->remote_key); + auto remote_key_{new ecc_key{}}; + auto state = ecc_import((const unsigned char *) clientOmega.data(), clientOmega.length(), remote_key_); if(state != CRYPT_OK) { - this->remote_key = nullptr; + delete remote_key_; return ts::command_result{error::client_could_not_validate_identity}; } + this->remote_key = std::shared_ptr{remote_key_, [](ecc_key* key) { + if(!key) { + return; + } + + /* We can only call ecc_free if we've really initialized the remote key */ + ecc_free(key); + delete key; + }}; + client->properties()[property::CLIENT_UNIQUE_IDENTIFIER] = base64::encode(digest::sha1(cmd.value("omega"))); } this->new_protocol = !use_teaspeak && ot && config::experimental_31 && (this->client_protocol_time_ >= 173265950ULL || this->client_protocol_time_ == (uint32_t) 5680278000ULL); - { - size_t server_seed_length = this->new_protocol ? 54 : 10; - - char beta[server_seed_length]; - generate_random((uint8_t *) beta, server_seed_length); - - this->seed_server = std::string{beta, server_seed_length}; + this->seed_server.resize(this->new_protocol ? 54 : 10); + for(auto& byte : this->seed_server) { + byte = (uint8_t) rand(); } auto server_public_key = client->getServer()->publicServerKey(); @@ -164,7 +164,7 @@ CryptSetupHandler::CommandResult CryptSetupHandler::handleCommandClientInitIv(co auto crypto_chain = this->chain_data->chain->exportChain(); auto crypto_chain_hash = digest::sha256(crypto_chain); - size_t sign_buffer_size{128}; + size_t sign_buffer_size{512}; char sign_buffer[sign_buffer_size]; prng_state prng_state{}; diff --git a/server/src/client/voice/VoiceClient.cpp b/server/src/client/voice/VoiceClient.cpp index f70d144..69c579a 100644 --- a/server/src/client/voice/VoiceClient.cpp +++ b/server/src/client/voice/VoiceClient.cpp @@ -490,7 +490,6 @@ void VoiceClient::send_video_unsupported_message() { std::string message{kUnsupportedMessage}; if(auto index{message.find("%web-url%")}; index != std::string::npos) { /* TODO: generate connect url */ - //this->server->getWebServer()-> message.replace(index, 9, "https://web.teaspeak.de"); } notify.put_unchecked(0, "msg", message); diff --git a/server/src/client/web/WSWebClient.cpp b/server/src/client/web/WSWebClient.cpp index c4b36af..0bcc727 100644 --- a/server/src/client/web/WSWebClient.cpp +++ b/server/src/client/web/WSWebClient.cpp @@ -70,19 +70,22 @@ void WebClient::handleMessageRead(int fd, short, void *ptr_client) { uint8_t buffer[buffer_length]; auto length = recv(fd, buffer, buffer_length, MSG_NOSIGNAL | MSG_DONTWAIT); - if(length <= 0){ - if(errno == EINTR || errno == EAGAIN) - ; - else { - debugMessage(client->getServerId(), "[{}] Failed to read message (length {}, errno {}, message: {}). Closing connection.", client->getLoggingPrefix(), length, errno, strerror(errno)); - - { - lock_guard lock(client->event_mutex); - if(client->readEvent) - event_del_noblock(client->readEvent); - } - client->close_connection(system_clock::now()); /* direct close, but from another thread */ + if(length <= 0) { + /* error handling "slow path" */ + if(length == 0 && errno == EAGAIN) { + /* We've currently no data queued */ + return; } + + debugMessage(client->getServerId(), "[{}] Failed to read message (length {}, errno {}, message: {}). Closing connection.", client->getLoggingPrefix(), length, errno, strerror(errno)); + + { + lock_guard lock{client->event_mutex}; + if(client->readEvent) { + event_del_noblock(client->readEvent); + } + } + client->close_connection(system_clock::now()); /* direct close, but from another thread */ return; } diff --git a/server/src/lincense/TeamSpeakLicense.cpp b/server/src/lincense/TeamSpeakLicense.cpp index 8bb53e4..740f466 100644 --- a/server/src/lincense/TeamSpeakLicense.cpp +++ b/server/src/lincense/TeamSpeakLicense.cpp @@ -141,9 +141,11 @@ bool TeamSpeakLicense::load(std::string& error) { } std::shared_ptr TeamSpeakLicense::license(bool copy) { - if(!copy || !this->data) return this->data; + if(!copy || !this->data) { + return this->data; + } - auto result = make_shared(); + auto result = std::make_shared(); result->chain = this->data->chain->copy(); result->root_index = this->data->root_index; diff --git a/server/src/server/VoiceServerSocket.cpp b/server/src/server/VoiceServerSocket.cpp index 5bf1adf..cc715fb 100644 --- a/server/src/server/VoiceServerSocket.cpp +++ b/server/src/server/VoiceServerSocket.cpp @@ -118,6 +118,8 @@ bool VoiceServerSocket::activate(std::string &error) { this->network_events.emplace_back(std::move(events)); } + network_loop->free_use_list(read_use_list); + network_loop->free_use_list(write_use_list); if(this->network_events.empty()) { error = "failed to register any network events"; goto bind_failed; @@ -410,10 +412,15 @@ void VoiceServerSocket::network_event_read(int, short, void *ptr_network_events) logCritical(socket->server_id, "Could not receive datagram packet! Code: {} Reason: {}", errno, strerror(errno)); break; } else if(bytes_read == 0){ - //This should never happen + /* We received a dara gram with zero length? Well, how the hell sends us such? */ break; } + if(bytes_read < 8) { + /* every packet must be at least 8 bytes long... */ + continue; + } + if(*(uint64_t*) raw_read_buffer == TS3INIT.integral) { //Handle ddos protection... /* TODO: Don't pass the raw buffer instead pass the protocol::ClientPacketParser and ClientPacketParser mus allow the INIT packet */ diff --git a/shared b/shared index f008d3a..bc8f314 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit f008d3a711307307a85bac837d124baf99d9e8ac +Subproject commit bc8f314623ac341631ceb847ededcadb33926639