From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <pdm-devel-bounces@lists.proxmox.com> Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 94FDE1FF1CD for <inbox@lore.proxmox.com>; Fri, 16 May 2025 15:36:20 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 42756DAAD; Fri, 16 May 2025 15:36:45 +0200 (CEST) From: Dominik Csapak <d.csapak@proxmox.com> To: pdm-devel@lists.proxmox.com Date: Fri, 16 May 2025 15:35:53 +0200 Message-Id: <20250516133611.3499075-4-d.csapak@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250516133611.3499075-1-d.csapak@proxmox.com> References: <20250516133611.3499075-1-d.csapak@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.021 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [connection.rs] Subject: [pdm-devel] [PATCH datacenter-manager 03/21] server: connection: add probe_tls_connection helper X-BeenThere: pdm-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Datacenter Manager development discussion <pdm-devel.lists.proxmox.com> List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pdm-devel>, <mailto:pdm-devel-request@lists.proxmox.com?subject=unsubscribe> List-Archive: <http://lists.proxmox.com/pipermail/pdm-devel/> List-Post: <mailto:pdm-devel@lists.proxmox.com> List-Help: <mailto:pdm-devel-request@lists.proxmox.com?subject=help> List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel>, <mailto:pdm-devel-request@lists.proxmox.com?subject=subscribe> Reply-To: Proxmox Datacenter Manager development discussion <pdm-devel@lists.proxmox.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pdm-devel-bounces@lists.proxmox.com Sender: "pdm-devel" <pdm-devel-bounces@lists.proxmox.com> this is intended to help us probe a remote/host before using it to check whether the tls connection is working fine, or it returns the certificate information so we can show it to the user. Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> --- server/src/connection.rs | 79 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/server/src/connection.rs b/server/src/connection.rs index 0be9033..c7b2558 100644 --- a/server/src/connection.rs +++ b/server/src/connection.rs @@ -15,8 +15,10 @@ use std::time::{Duration, SystemTime}; use anyhow::{bail, format_err, Error}; use http::uri::Authority; use http::Method; +use openssl::x509::X509StoreContextRef; use serde::Serialize; +use proxmox_acme_api::CertificateInfo; use proxmox_client::{Client, HttpApiClient, HttpApiResponse, HttpApiResponseStream, TlsOptions}; use pdm_api_types::remotes::{NodeUrl, Remote, RemoteType}; @@ -799,3 +801,80 @@ impl HttpApiClient for MultiClient { try_request! { self, method, path_and_query, params, streaming_request } } } + +/// Checks TLS connection to the given remote +/// +/// Returns `Ok(None)` if connecting with the given parameters works +/// Returns `Ok(Some(cert))` if no fingerprint was given and some certificate could not be validated +/// Returns `Err(err)` if some other error occurred +/// +/// # Example +/// +/// ``` +/// use server::connection::probe_tls_connection; +/// use pdm_api_types::remotes::RemoteType; +/// +/// # async fn function() { +/// let result = probe_tls_connection(RemoteType::Pve, "192.168.2.100".to_string(), None).await; +/// match result { +/// Ok(None) => { /* everything ok */ }, +/// Ok(Some(cert)) => { /* do something with cert */ }, +/// Err(err) => { /* do something with error */ }, +/// } +/// # } +/// ``` +pub async fn probe_tls_connection( + remote_type: RemoteType, + hostname: String, + fingerprint: Option<String>, +) -> Result<Option<CertificateInfo>, Error> { + let host_port: Authority = hostname.parse()?; + + let uri: http::uri::Uri = format!( + "https://{}:{}", + host_port.host(), + host_port.port_u16().unwrap_or(remote_type.default_port()) + ) + .parse()?; + + // to save the invalid cert we find + let invalid_cert = Arc::new(StdMutex::new(None)); + + let options = if let Some(fp) = &fingerprint { + TlsOptions::parse_fingerprint(fp)? + } else { + TlsOptions::Callback(Box::new({ + let invalid_cert = invalid_cert.clone(); + move |valid: bool, chain: &mut X509StoreContextRef| { + if let Some(cert) = chain.current_cert() { + if !valid { + let cert = cert.to_pem().map(|pem| CertificateInfo::from_pem("", &pem)); + *invalid_cert.lock().unwrap() = Some(cert); + } + } + true + } + })) + }; + let client = proxmox_client::Client::with_options(uri, options, Default::default())?; + + // set fake auth info. we don't need any, but the proxmox client will return unauthenticated if + // none is set. + client.set_authentication(proxmox_client::Token { + userid: "".to_string(), + value: "".to_string(), + prefix: "".to_string(), + perl_compat: false, + }); + + client.request(Method::GET, "/", None::<()>).await?; + + let cert = invalid_cert.lock().unwrap().take(); + if let Some(cert) = cert { + let cert = cert?; + let cert = cert?; + Ok(Some(cert)) + } else { + Ok(None) + } +} -- 2.39.5 _______________________________________________ pdm-devel mailing list pdm-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel