• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!
  • 2026 staff recruitment is open! Check it out and consider applying!

TFS 1.X+ Server does not open tls/ssl problem

2057623

Member
Joined
Jan 16, 2012
Messages
135
Reaction score
15
Hey guys, I have a Baiak Thunger 1.3x server, I compiled the source code and everything is ok. When I try to open it, it won't open. This appears

> Loading configurations
> Establishing connection to the database...
MySQL Error Message: TLS/SSL error: SSL is required, but the server does not support it
ERROR: Failed to connect to database.

This is the first time I've been messing with otserv and I see something with SSL. I use Xampp 3.3.0 PHP 8.1. I installed the normal Myacc site. I went to open the server and it won't open. It looks like this. In config.lua, it's already configured correctly.

mysqlHost = "localhost"
mysqlUser = "root"
mysqlPass = ""
mysqlDatabase = "otserv"
mysqlPort = 3306
mysqlSock = ""
passwordType = "sha1"
sqlType = "mysql"

I have already tried changing the mysqlhost to 127.0.0.1 but without any success. If anyone can help me out, please let me know.
 
you are using custom server... as far as i know tfs is not using tls/ssl for db connection
 
Disable SSL requirement in MySQL:
Open the my.cnf or my.ini file.
Add the following under the [mysqld] section:
LUA:
require_secure_transport = OFF
Save and restart MySQL.
Disable SSL in config.lua:
Code:
mysqlHost = "localhost"
mysqlUser = "root"
mysqlPass = ""
mysqlDatabase = "otserv"
mysqlPort = 3306
mysqlSock = ""
passwordType = "sha1"
sqlType = "mysql"
Add the line:
Code:
mysqlFlags = "CLIENT_SSL=0"
Restart the server and check the connection.

Test the connection directly from the terminal:
LUA:
mysql -u root -p --host=localhost --ssl-mode=DISABLED
If the connection succeeds, the issue is likely with the otserv configuration.

Let me know if it helped, I'm learning myself. We'll figure it out :D
 
Last edited:
Disable SSL requirement in MySQL:
Open the my.cnf or my.ini file.
Add the following under the [mysqld] section:
LUA:
require_secure_transport = OFF
Save and restart MySQL.
Disable SSL in config.lua:
Code:
mysqlHost = "localhost"
mysqlUser = "root"
mysqlPass = ""
mysqlDatabase = "otserv"
mysqlPort = 3306
mysqlSock = ""
passwordType = "sha1"
sqlType = "mysql"
Add the line:
Code:
mysqlFlags = "CLIENT_SSL=0"
Restart the server and check the connection.

Test the connection directly from the terminal:
LUA:
mysql -u root -p --host=localhost --ssl-mode=DISABLED
If the connection succeeds, the issue is likely with the otserv configuration.

Let me know if it helped, I'm learning myself. We'll figure it out :D
i having same problem, i tried to use this solution but dind't worked, ssl certificate already off but still having a mysql connection error.

1730231056846.webp
 

Attachments

  • 1730231100059.webp
    1730231100059.webp
    35.2 KB · Views: 29 · VirusTotal
Last edited:
Hey guys, I have a Baiak Thunger 1.3x server, I compiled the source code and everything is ok. When I try to open it, it won't open. This appears


MySQL Error Message: TLS/SSL error: SSL is required, but the server does not support it


This is the first time I've been messing with otserv and I see something with SSL. I use Xampp 3.3.0 PHP 8.1. I installed the normal Myacc site. I went to open the server and it won't open. It looks like this. In config.lua, it's already configured correctly.

mysqlHost = "localhost"
mysqlUser = "root"
mysqlPass = ""
mysqlDatabase = "otserv"
mysqlPort = 3306
mysqlSock = ""
passwordType = "sha1"
sqlType = "mysql"

I have already tried changing the mysqlhost to 127.0.0.1 but without any success. If anyone can help me out, please let me know.

Add more mysql_options for new version +3.5.x libmariadb from vcpkg.
It seems like they enabled it without specifying the ssl setting.
That's really annoying. security standards maybe.

In database.cpp, bool Database::connect()
after
C++:
mysql_options(handle, MYSQL_OPT_RECONNECT, &reconnect);
add
C++:
my_bool ssl_enforce = 0;
my_bool ssl_verify = 0;
unsigned int ssl_mode = 0;
mysql_options(handle, MYSQL_OPT_SSL_ENFORCE, &ssl_enforce);
mysql_options(handle, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &ssl_verify);
mysql_options(handle, MYSQL_OPT_SSL_ENFORCE, &ssl_mode);
mysql_ssl_set(handle, nullptr, nullptr, nullptr, nullptr, nullptr);
 
Last edited:
Add more mysql_options for new version +3.5.x libmariadb from vcpkg.
It seems like they enabled it without specifying the ssl setting.
That's really annoying. security standards maybe.

In database.cpp, bool Database::connect()
after
C++:
mysql_options(handle, MYSQL_OPT_RECONNECT, &reconnect);
add
C++:
my_bool ssl_enforce = 0;
my_bool ssl_verify = 0;
unsigned int ssl_mode = 0;
mysql_options(handle, MYSQL_OPT_SSL_ENFORCE, &ssl_enforce);
mysql_options(handle, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &ssl_verify);
mysql_options(handle, MYSQL_OPT_SSL_ENFORCE, &ssl_mode);
mysql_ssl_set(handle, nullptr, nullptr, nullptr, nullptr, nullptr);
TFS 1.6+ has the same problem on Linux Ubuntu, if you compile engine using vcpkg.
To fix it, above this line:
add:
C++:
    bool ssl_enforce = false;
    bool ssl_verify = false;
and above this if:
add:
C++:
    mysql_options(handle.get(), MYSQL_OPT_SSL_ENFORCE, &ssl_enforce);
    mysql_options(handle.get(), MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &ssl_verify);
    mysql_ssl_set(handle.get(), nullptr, nullptr, nullptr, nullptr, nullptr);

EDIT:
I will test if it works fine on Windows and make PR.
 
Last edited:
LUA:
// Copyright 2023 The Forgotten Server Authors. All rights reserved.
// Use of this source code is governed by the GPL-2.0 License that can be found in the LICENSE file.

#include "otpch.h"

#include "database.h"

#include "configmanager.h"

#include <mysql/errmsg.h>

static tfs::detail::Mysql_ptr connectToDatabase(const bool retryIfError)
{
    bool isFirstAttemptToConnect = true;

retry:
    if (!isFirstAttemptToConnect) {
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    isFirstAttemptToConnect = false;



    tfs::detail::Mysql_ptr handle{mysql_init(nullptr)};
    if (!handle) {
        std::cout << "\nFailed to initialize MySQL connection handle." << std::endl;
        if (retryIfError) goto retry;
        return nullptr;
    }

    // ✅ Configure SSL [I]depois[/I] de mysql_init, [I]antes[/I] de mysql_real_connect
    bool ssl_enforce = false;
    bool ssl_verify = false;
    mysql_options(handle.get(), MYSQL_OPT_SSL_ENFORCE, &ssl_enforce);
    mysql_options(handle.get(), MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &ssl_verify);
    mysql_ssl_set(handle.get(), nullptr, nullptr, nullptr, nullptr, nullptr);
    
    // connects to database
    if (!mysql_real_connect(handle.get(), getString(ConfigManager::MYSQL_HOST).c_str(),
                            getString(ConfigManager::MYSQL_USER).c_str(), getString(ConfigManager::MYSQL_PASS).c_str(),
                            getString(ConfigManager::MYSQL_DB).c_str(), getNumber(ConfigManager::SQL_PORT),
                            getString(ConfigManager::MYSQL_SOCK).c_str(), 0)) {
        std::cout << std::endl << "MySQL Error Message: " << mysql_error(handle.get()) << std::endl;
        goto error;
    }
    return handle;

error:
    if (retryIfError) {
        goto retry;
    }
    return nullptr;
}

static bool isLostConnectionError(const unsigned error)
{
    return error == CR_SERVER_LOST || error == CR_SERVER_GONE_ERROR || error == CR_CONN_HOST_ERROR ||
           error == 1053 /[I]ER_SERVER_SHUTDOWN[/I]/ || error == CR_CONNECTION_ERROR;
}

static bool executeQuery(tfs::detail::Mysql_ptr& handle, std::string_view query, const bool retryIfLostConnection)
{
    while (mysql_real_query(handle.get(), query.data(), query.length()) != 0) {
        std::cout << "[Error - mysql_real_query] Query: " << query.substr(0, 256) << std::endl
                  << "Message: " << mysql_error(handle.get()) << std::endl;
        const unsigned error = mysql_errno(handle.get());
        if (!isLostConnectionError(error) || !retryIfLostConnection) {
            return false;
        }
        handle = connectToDatabase(true);
    }
    return true;
}

bool Database::connect()
{
    auto newHandle = connectToDatabase(false);
    if (!newHandle) {
        return false;
    }

    handle = std::move(newHandle);
    DBResult_ptr result = storeQuery("SHOW VARIABLES LIKE 'max_allowed_packet'");
    if (result) {
        maxPacketSize = result->getNumber<uint64_t>("Value");
    }
    return true;
}

bool Database::beginTransaction()
{
    databaseLock.lock();
    const bool result = executeQuery("START TRANSACTION");
    retryQueries = !result;
    if (!result) {
        databaseLock.unlock();
    }
    return result;
}

bool Database::rollback()
{
    const bool result = executeQuery("ROLLBACK");
    retryQueries = true;
    databaseLock.unlock();
    return result;
}

bool Database::commit()
{
    const bool result = executeQuery("COMMIT");
    retryQueries = true;
    databaseLock.unlock();
    return result;
}

bool Database::executeQuery(const std::string& query)
{
    std::lock_guard<std::recursive_mutex> lockGuard(databaseLock);
    return ::executeQuery(handle, query, retryQueries);
}

DBResult_ptr Database::storeQuery(std::string_view query)
{
    std::lock_guard<std::recursive_mutex> lockGuard(databaseLock);

retry:
    if (!::executeQuery(handle, query, retryQueries) && !retryQueries) {
        return nullptr;
    }

    // we should call that every time as someone would call executeQuery('SELECT...')
    // as it is described in MySQL manual: "it doesn't hurt" :P
    tfs::detail::MysqlResult_ptr res{mysql_store_result(handle.get())};
    if (!res) {
        std::cout << "[Error - mysql_store_result] Query: " << query << std::endl
                  << "Message: " << mysql_error(handle.get()) << std::endl;
        const unsigned error = mysql_errno(handle.get());
        if (!isLostConnectionError(error) || !retryQueries) {
            return nullptr;
        }
        goto retry;
    }

    // retrieving results of query
    DBResult_ptr result = std::make_shared<DBResult>(std::move(res));
    if (!result->hasNext()) {
        return nullptr;
    }
    return result;
}

std::string Database::escapeBlob(const char* s, uint32_t length) const
{
    // the worst case is 2n + 1
    size_t maxLength = (length * 2) + 1;

    std::string escaped;
    escaped.reserve(maxLength + 2);
    escaped.push_back('\'');

    if (length != 0) {
        char* output = new char[maxLength];
        mysql_real_escape_string(handle.get(), output, s, length);
        escaped.append(output);
        delete[] output;
    }

    escaped.push_back('\'');
    return escaped;
}

DBResult::DBResult(tfs::detail::MysqlResult_ptr&& res) : handle{std::move(res)}
{
    size_t i = 0;

    MYSQL_FIELD* field = mysql_fetch_field(handle.get());
    while (field) {
        listNames[field->name] = i++;
        field = mysql_fetch_field(handle.get());
    }

    row = mysql_fetch_row(handle.get());
}

std::string_view DBResult::getString(std::string_view column) const
{
    auto it = listNames.find(column);
    if (it == listNames.end()) {
        std::cout << "[Error - DBResult::getString] Column '" << column << "' does not exist in result set."
                  << std::endl;
        retornar {};
    }

    se (!linha[it->segundo]) {
        retornar {};
    }

    tamanho automático = mysql_fetch_lengths(handle.get())[it->second];
    retornar {row[it->second], size};
}

bool DBResult:: hasNext() const {return row; }

bool DBResult::próximo()
{
    linha = mysql_fetch_row(handle.get());
    linha de retorno;
}

DBInsert::DBInsert(std:::string query): query(std:::move(query)) { this->length = this->query.length(); }

bool DBInsert::addRow(const std::string& row)
{
    // adiciona nova linha ao buffer
    const size_t rowLength = row.length();
    comprimento += comprimento da linha;
    se (comprimento > Banco de dados::getInstance().getMaxPacketSize()&&!executar()) {
        retornar falso;
    }

    se (valores.vazio()) {
        valores.reserva(comprimento da linha + 2);
        valores.push_back('(');
        valores.append(linha);
        valores.push_back(')');
    } caso contrário {
        valores.reserve(values.length() + rowLength + 3);
        valores.push_back(',');
        valores.push_back('(');
        valores.append(linha);
        valores.push_back(')');
    }
    retornar verdadeiro;
}

bool DBInsert::addRow(std::ostringstream& row)
{
    bool ret = addRow(row.str());
    row.str(std::string());
    retornar ret;
}

bool DBInsert::executar()
{
    se (valores.vazio()) {
        retornar verdadeiro;
    }

    // executa buffer
    bool res = Banco de dados::getInstance().executeQuery(consulta + valores);
    valores.claro();
    comprimento = consulta.comprimento();
    devolver res;
}
[/CÓDIGO]
 
Add more mysql_options for new version +3.5.x libmariadb from vcpkg.
It seems like they enabled it without specifying the ssl setting.
That's really annoying. security standards maybe.

In database.cpp, bool Database::connect()
after
C++:
mysql_options(handle, MYSQL_OPT_RECONNECT, &reconnect);
add
C++:
my_bool ssl_enforce = 0;
my_bool ssl_verify = 0;
unsigned int ssl_mode = 0;
mysql_options(handle, MYSQL_OPT_SSL_ENFORCE, &ssl_enforce);
mysql_options(handle, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &ssl_verify);
mysql_options(handle, MYSQL_OPT_SSL_ENFORCE, &ssl_mode);
mysql_ssl_set(handle, nullptr, nullptr, nullptr, nullptr, nullptr);
It worked for me!

Thanks!
 
Back
Top