From fa98ec5afee7e5bc2ceba688df233d42ea712c28 Mon Sep 17 00:00:00 2001 From: Ian Chua Date: Thu, 24 Sep 2026 17:53:46 +0800 Subject: [PATCH] feat: add ssl and ca_cert for OrcaPrinterAgent --- src/slic3r/Utils/OrcaMqttConnection.cpp | 5 ++++- src/slic3r/Utils/OrcaMqttConnection.hpp | 1 + src/slic3r/Utils/OrcaPrinterAgent.cpp | 29 ++++++++++++++++++++----- src/slic3r/Utils/OrcaPrinterAgent.hpp | 2 ++ 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/slic3r/Utils/OrcaMqttConnection.cpp b/src/slic3r/Utils/OrcaMqttConnection.cpp index ef1044e468..396744655c 100644 --- a/src/slic3r/Utils/OrcaMqttConnection.cpp +++ b/src/slic3r/Utils/OrcaMqttConnection.cpp @@ -361,7 +361,10 @@ void OrcaMqttConnection::ws_handshake(Connection& conn, const Config& config, co auto& tls_stream = websocket.next_layer(); if (!SSL_set_tlsext_host_name(tls_stream.native_handle(), endpoint.host.c_str())) throw std::runtime_error("failed to set Orca Cloud TLS server name"); - conn.ssl_context.set_default_verify_paths(); + if (!config.ca_file.empty()) + conn.ssl_context.load_verify_file(config.ca_file); + else + conn.ssl_context.set_default_verify_paths(); Http::add_platform_root_certificates(conn.ssl_context.native_handle()); tls_stream.set_verify_mode(boost::asio::ssl::verify_peer); tls_stream.set_verify_callback(boost::asio::ssl::host_name_verification(endpoint.host)); diff --git a/src/slic3r/Utils/OrcaMqttConnection.hpp b/src/slic3r/Utils/OrcaMqttConnection.hpp index 8639dab0e3..dd62a72964 100644 --- a/src/slic3r/Utils/OrcaMqttConnection.hpp +++ b/src/slic3r/Utils/OrcaMqttConnection.hpp @@ -38,6 +38,7 @@ public: struct Config { std::string url; bool use_tls = false; + std::string ca_file; TokenProvider bearer_provider; // set => bearer on WS upgrade, CONNECT creds omitted std::string username; std::string password; diff --git a/src/slic3r/Utils/OrcaPrinterAgent.cpp b/src/slic3r/Utils/OrcaPrinterAgent.cpp index afdd16c4c1..6b1355eccc 100644 --- a/src/slic3r/Utils/OrcaPrinterAgent.cpp +++ b/src/slic3r/Utils/OrcaPrinterAgent.cpp @@ -1002,7 +1002,6 @@ int OrcaPrinterAgent::connect_printer(const PrinterConnectionParams& params) BOOST_LOG_TRIVIAL(trace) << "Orca diagnostic: connect_printer requested dev_id=" << params.dev_id << " dev_ip=" << params.host << " username=" << (params.username.empty() ? "" : params.username) << " password_present=" << (!params.password.empty()) << " use_ssl=" << params.use_ssl; - (void) params.use_ssl; // OrcaSonar LAN is plaintext ws:// if (params.dev_id.empty() || params.host.empty()) { BOOST_LOG_TRIVIAL(warning) << "Orca diagnostic: connect_printer rejected missing dev_id or dev_ip"; return BAMBU_NETWORK_ERR_INVALID_HANDLE; @@ -1016,8 +1015,9 @@ int OrcaPrinterAgent::connect_printer(const PrinterConnectionParams& params) const uint64_t gen = ++m_lan_generation; OrcaMqttConnection::Config cfg; - cfg.url = "ws://" + host + ":" + port + "/mqtt"; - cfg.use_tls = false; + cfg.url = (params.use_ssl ? "wss://" : "ws://") + host + ":" + port + "/mqtt"; + cfg.use_tls = params.use_ssl; + cfg.ca_file = params.ca_file; cfg.username = params.username.empty() ? std::string("orcasonar") : params.username; cfg.password = params.password; cfg.client_id = make_lan_client_id(params.dev_id); @@ -1034,6 +1034,8 @@ int OrcaPrinterAgent::connect_printer(const PrinterConnectionParams& params) previous_connection = m_current_connection; m_lan_dev_id = params.dev_id; m_lan_url = cfg.url; + m_lan_use_ssl = params.use_ssl; + m_lan_ca_file = params.ca_file; m_camera_stream_mode = CameraStreamMode::none; m_camera_url.clear(); m_current_connection = LAN; @@ -1107,6 +1109,8 @@ int OrcaPrinterAgent::disconnect_printer() doomed = std::move(lan_mqtt_connection); prev_dev = m_lan_dev_id; m_lan_dev_id.clear(); + m_lan_use_ssl = false; + m_lan_ca_file.clear(); if (m_current_connection == LAN) { m_current_connection = NONE; m_camera_stream_mode = CameraStreamMode::none; @@ -1446,9 +1450,17 @@ int OrcaPrinterAgent::start_send_gcode_to_sdcard(PrintParams params, return BAMBU_NETWORK_ERR_PRINT_SG_UPLOAD_FTP_FAILED; } + bool use_ssl = false; + std::string ca_file; + { + std::lock_guard lock(state_mutex); + use_ssl = m_lan_use_ssl; + ca_file = m_lan_ca_file; + } + std::string host, port, origin; if (parse_lan_endpoint(params.dev_ip, host, port)) - origin = "http://" + host; + origin = (use_ssl ? "https://" : "http://") + host; else origin = http_origin_from_lan_ws(lan_connection_target()); if (origin.empty()) { @@ -1469,7 +1481,11 @@ int OrcaPrinterAgent::start_send_gcode_to_sdcard(PrintParams params, std::string response_body; // check if printer has enough storage - Http::get(origin + "/server/files/directory?path=gcodes") + auto directory_http = Http::get(origin + "/server/files/directory?path=gcodes"); + directory_http.tls_verify(use_ssl); + if (!ca_file.empty()) + directory_http.ca_file(ca_file); + directory_http .on_complete([&](std::string body, unsigned status) { if (body.empty()) { http_status = 400; @@ -1506,6 +1522,9 @@ int OrcaPrinterAgent::start_send_gcode_to_sdcard(PrintParams params, } auto http = Http::post(origin + "/server/files/upload"); + http.tls_verify(use_ssl); + if (!ca_file.empty()) + http.ca_file(ca_file); if (!params.password.empty()) http.header("X-Api-Key", params.password); // trusted LAN facades may not require it; harmless when they do not http.form_add("root", "gcodes") diff --git a/src/slic3r/Utils/OrcaPrinterAgent.hpp b/src/slic3r/Utils/OrcaPrinterAgent.hpp index 3a32b2e3e3..d3ec5af1fe 100644 --- a/src/slic3r/Utils/OrcaPrinterAgent.hpp +++ b/src/slic3r/Utils/OrcaPrinterAgent.hpp @@ -191,6 +191,8 @@ private: std::string m_lan_dev_id; // guarded by state_mutex std::string m_lan_url; // guarded by state_mutex — the Config.url of the live LAN session + bool m_lan_use_ssl = false; // guarded by state_mutex + std::string m_lan_ca_file; // guarded by state_mutex CameraStreamMode m_camera_stream_mode = CameraStreamMode::none; // guarded by state_mutex std::string m_camera_url; // guarded by state_mutex