From 7396149ab1a5bd045b4252f3bb183a535c8797ba Mon Sep 17 00:00:00 2001 From: Maufeat Date: Mon, 26 Jan 2026 01:30:53 +0100 Subject: [PATCH] [bsd, ssl] force ssl verify option to be 0 and other fixes (#3386) JackBox games broke again, this makes it work again. Forces Verify Option to be 0 Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3386 Reviewed-by: crueter Reviewed-by: MaranBr Co-authored-by: Maufeat Co-committed-by: Maufeat --- src/core/hle/service/sockets/bsd.cpp | 13 +++++-- src/core/hle/service/sockets/sockets.h | 5 ++- .../hle/service/sockets/sockets_translate.cpp | 13 +++++-- src/core/hle/service/ssl/ssl.cpp | 9 ++++- src/core/hle/service/ssl/ssl_backend.h | 4 ++ .../hle/service/ssl/ssl_backend_openssl.cpp | 38 ++++++++++++++----- .../hle/service/ssl/ssl_backend_schannel.cpp | 22 ++++++++--- .../ssl/ssl_backend_securetransport.cpp | 19 ++++++++++ src/core/internal_network/network.cpp | 10 ++++- src/core/internal_network/network.h | 3 +- 10 files changed, 110 insertions(+), 26 deletions(-) diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index d4932fc4ee..fd758d4915 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project @@ -643,7 +643,14 @@ Errno BSD::ConnectImpl(s32 fd, std::span addr) { UNIMPLEMENTED_IF(addr.size() != sizeof(SockAddrIn)); auto addr_in = GetValue(addr); - return Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in))); + const Errno result = Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in))); + + if (result == Errno::ISCONN) { + LOG_DEBUG(Service, "returned ISCONN - socket already connected"); + return Errno::SUCCESS; + } + + return result; } Errno BSD::GetPeerNameImpl(s32 fd, std::vector& write_buffer) { @@ -750,7 +757,7 @@ Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span(SocketLevel::SOCKET)) { - UNIMPLEMENTED_MSG("Unknown setsockopt level"); + LOG_WARNING(Service, "(STUBBED) setsockopt with level={}, optname={}", level, optname); return Errno::SUCCESS; } diff --git a/src/core/hle/service/sockets/sockets.h b/src/core/hle/service/sockets/sockets.h index 0093347eb8..b72bf53c16 100644 --- a/src/core/hle/service/sockets/sockets.h +++ b/src/core/hle/service/sockets/sockets.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project @@ -29,6 +29,7 @@ enum class Errno : u32 { TIMEDOUT = 110, CONNREFUSED = 111, INPROGRESS = 115, + ISCONN = 106, }; enum class GetAddrInfoError : s32 { @@ -71,6 +72,8 @@ enum class Protocol : u32 { }; enum class SocketLevel : u32 { + IP = 0, + TCP = 6, SOCKET = 0xffff, // i.e. SOL_SOCKET }; diff --git a/src/core/hle/service/sockets/sockets_translate.cpp b/src/core/hle/service/sockets/sockets_translate.cpp index 21bb3e7764..9d82d347eb 100644 --- a/src/core/hle/service/sockets/sockets_translate.cpp +++ b/src/core/hle/service/sockets/sockets_translate.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -5,6 +8,7 @@ #include "common/assert.h" #include "common/common_types.h" +#include "common/logging/log.h" #include "core/hle/service/sockets/sockets.h" #include "core/hle/service/sockets/sockets_translate.h" #include "core/internal_network/network.h" @@ -37,6 +41,8 @@ Errno Translate(Network::Errno value) { return Errno::CONNRESET; case Network::Errno::INPROGRESS: return Errno::INPROGRESS; + case Network::Errno::ISCONN: + return Errno::ISCONN; default: UNIMPLEMENTED_MSG("Unimplemented errno={}", value); return Errno::SUCCESS; @@ -259,9 +265,10 @@ PollEvents Translate(Network::PollEvents flags) { } Network::SockAddrIn Translate(SockAddrIn value) { - // Note: 6 is incorrect, but can be passed by homebrew (because libnx sets - // sin_len to 6 when deserializing getaddrinfo results). - ASSERT(value.len == 0 || value.len == sizeof(value) || value.len == 6); + if (value.len != 0 && value.len != sizeof(value) && value.len != 6) { + LOG_WARNING(Service, "Unexpected SockAddrIn len={}, expected 0, {}, or 6", + value.len, sizeof(value)); + } return { .family = Translate(static_cast(value.family)), diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp index 5a1ae0dbc9..b66c686b2a 100644 --- a/src/core/hle/service/ssl/ssl.cpp +++ b/src/core/hle/service/ssl/ssl.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project @@ -116,6 +116,8 @@ public: RegisterHandlers(functions); + backend->SetVerifyOption(verify_option); + shared_data->connection_count++; } @@ -150,6 +152,7 @@ private: std::shared_ptr socket; std::vector next_alpn_proto; bool did_handshake = false; + u32 verify_option = 0; Result SetSocketDescriptorImpl(s32* out_fd, s32 fd) { LOG_DEBUG(Service_SSL, "called, fd={}", fd); @@ -190,7 +193,9 @@ private: Result SetVerifyOptionImpl(u32 option) { ASSERT(!did_handshake); - LOG_WARNING(Service_SSL, "(STUBBED) called. option={}", option); + LOG_DEBUG(Service_SSL, "called. option={} (forcing 0)", option); + verify_option = 0; + backend->SetVerifyOption(0); return ResultSuccess; } diff --git a/src/core/hle/service/ssl/ssl_backend.h b/src/core/hle/service/ssl/ssl_backend.h index a2ec8e6947..a3127342a2 100644 --- a/src/core/hle/service/ssl/ssl_backend.h +++ b/src/core/hle/service/ssl/ssl_backend.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -34,6 +37,7 @@ public: virtual ~SSLConnectionBackend() {} virtual void SetSocket(std::shared_ptr socket) = 0; virtual Result SetHostName(const std::string& hostname) = 0; + virtual void SetVerifyOption(u32 option) = 0; virtual Result DoHandshake() = 0; virtual Result Read(size_t* out_size, std::span data) = 0; virtual Result Write(size_t* out_size, std::span data) = 0; diff --git a/src/core/hle/service/ssl/ssl_backend_openssl.cpp b/src/core/hle/service/ssl/ssl_backend_openssl.cpp index 02d0b8fba7..f0e05266ba 100644 --- a/src/core/hle/service/ssl/ssl_backend_openssl.cpp +++ b/src/core/hle/service/ssl/ssl_backend_openssl.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project @@ -158,9 +158,11 @@ public: } Result SetHostName(const std::string& hostname) override { - if (!SSL_set1_host(ssl, hostname.c_str())) { // hostname for verification - LOG_ERROR(Service_SSL, "SSL_set1_host({}) failed", hostname); - return CheckOpenSSLErrors(); + if (!skip_cert_verification) { + if (!SSL_set1_host(ssl, hostname.c_str())) { + LOG_ERROR(Service_SSL, "SSL_set1_host({}) failed", hostname); + return CheckOpenSSLErrors(); + } } if (!SSL_set_tlsext_host_name(ssl, hostname.c_str())) { // hostname for SNI LOG_ERROR(Service_SSL, "SSL_set_tlsext_host_name({}) failed", hostname); @@ -169,15 +171,32 @@ public: return ResultSuccess; } + void SetVerifyOption(u32 option) override { + skip_cert_verification = (option == 0); + LOG_WARNING(Service_SSL, "option={} skip_verification={}", option, + skip_cert_verification); + if (skip_cert_verification) { + SSL_set_verify(ssl, SSL_VERIFY_NONE, nullptr); + SSL_set1_host(ssl, nullptr); + SSL_set_hostflags(ssl, 0); + } else { + SSL_set_verify(ssl, SSL_VERIFY_PEER, nullptr); + } + } + Result DoHandshake() override { SSL_set_verify_result(ssl, X509_V_OK); const int ret = SSL_do_handshake(ssl); - const long verify_result = SSL_get_verify_result(ssl); - if (verify_result != X509_V_OK) { - LOG_ERROR(Service_SSL, "SSL cert verification failed because: {}", - X509_verify_cert_error_string(verify_result)); - return CheckOpenSSLErrors(); + + if (!skip_cert_verification) { + const long verify_result = SSL_get_verify_result(ssl); + if (verify_result != X509_V_OK) { + LOG_ERROR(Service_SSL, "SSL cert verification failed because: {}", + X509_verify_cert_error_string(verify_result)); + return CheckOpenSSLErrors(); + } } + if (ret <= 0) { const int ssl_err = SSL_get_error(ssl, ret); if (ssl_err == SSL_ERROR_ZERO_RETURN || @@ -328,6 +347,7 @@ public: SSL* ssl = nullptr; BIO* bio = nullptr; bool got_read_eof = false; + bool skip_cert_verification = false; std::shared_ptr socket; }; diff --git a/src/core/hle/service/ssl/ssl_backend_schannel.cpp b/src/core/hle/service/ssl/ssl_backend_schannel.cpp index cbc88753bc..2b68f29eaf 100644 --- a/src/core/hle/service/ssl/ssl_backend_schannel.cpp +++ b/src/core/hle/service/ssl/ssl_backend_schannel.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project @@ -89,6 +89,12 @@ public: return ResultSuccess; } + void SetVerifyOption(u32 option) override { + skip_cert_verification = (option == 0); + LOG_WARNING(Service_SSL, "option={} skip_verification={}", option, + skip_cert_verification); + } + Result DoHandshake() override { while (1) { Result r; @@ -175,10 +181,15 @@ public: } Result CallInitializeSecurityContext() { - const unsigned long req = ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONFIDENTIALITY | - ISC_REQ_INTEGRITY | ISC_REQ_REPLAY_DETECT | - ISC_REQ_SEQUENCE_DETECT | ISC_REQ_STREAM | - ISC_REQ_USE_SUPPLIED_CREDS; + unsigned long req = ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONFIDENTIALITY | + ISC_REQ_INTEGRITY | ISC_REQ_REPLAY_DETECT | + ISC_REQ_SEQUENCE_DETECT | ISC_REQ_STREAM | + ISC_REQ_USE_SUPPLIED_CREDS; + + if (skip_cert_verification) { + req |= ISC_REQ_MANUAL_CRED_VALIDATION; + } + unsigned long attr; // https://learn.microsoft.com/en-us/windows/win32/secauthn/initializesecuritycontext--schannel std::array input_buffers{{ @@ -536,6 +547,7 @@ public: std::vector cleartext_write_buf; bool got_read_eof = false; + bool skip_cert_verification = false; size_t read_buf_fill_size = 0; }; diff --git a/src/core/hle/service/ssl/ssl_backend_securetransport.cpp b/src/core/hle/service/ssl/ssl_backend_securetransport.cpp index c48914f640..65f81be631 100644 --- a/src/core/hle/service/ssl/ssl_backend_securetransport.cpp +++ b/src/core/hle/service/ssl/ssl_backend_securetransport.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -98,8 +101,23 @@ public: return ResultSuccess; } + void SetVerifyOption(u32 option) override { + skip_cert_verification = (option == 0); + LOG_WARNING(Service_SSL, "option={} skip_verification={}", option, + skip_cert_verification); + if (skip_cert_verification) { + SSLSetSessionOption(context, kSSLSessionOptionBreakOnServerAuth, true); + } + } + Result DoHandshake() override { OSStatus status = SSLHandshake(context); + + if (skip_cert_verification && status == errSSLServerAuthCompleted) { + LOG_DEBUG(Service_SSL, "Skipping certificate verification as requested"); + status = SSLHandshake(context); + } + return HandleReturn("SSLHandshake", 0, status); } @@ -201,6 +219,7 @@ public: private: CFReleaser context = nullptr; bool got_read_eof = false; + bool skip_cert_verification = false; std::shared_ptr socket; }; diff --git a/src/core/internal_network/network.cpp b/src/core/internal_network/network.cpp index 35f2157761..f16da5a3d8 100644 --- a/src/core/internal_network/network.cpp +++ b/src/core/internal_network/network.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project @@ -157,6 +157,8 @@ Errno TranslateNativeError(int e, CallType call_type = CallType::Other) { return Errno::TIMEDOUT; case WSAEINPROGRESS: return Errno::INPROGRESS; + case WSAEISCONN: + return Errno::ISCONN; default: UNIMPLEMENTED_MSG("Unimplemented errno={}", e); return Errno::OTHER; @@ -296,6 +298,8 @@ Errno TranslateNativeError(int e, CallType call_type = CallType::Other) { return Errno::TIMEDOUT; case EINPROGRESS: return Errno::INPROGRESS; + case EISCONN: + return Errno::ISCONN; default: UNIMPLEMENTED_MSG("Unimplemented errno={} ({})", e, strerror(e)); return Errno::OTHER; @@ -872,7 +876,9 @@ std::pair Socket::SendTo(u32 flags, std::span message, Errno Socket::Close() { [[maybe_unused]] const int result = closesocket(fd); - ASSERT(result == 0); + if (result != 0) { + LOG_WARNING(Network, "closesocket failed, socket may already be closed"); + } fd = INVALID_SOCKET; return Errno::SUCCESS; diff --git a/src/core/internal_network/network.h b/src/core/internal_network/network.h index 5df28911f8..ce259c0e66 100644 --- a/src/core/internal_network/network.h +++ b/src/core/internal_network/network.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project @@ -48,6 +48,7 @@ enum class Errno { TIMEDOUT, MSGSIZE, INPROGRESS, + ISCONN, OTHER, };