From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id EBB94671C8 for ; Mon, 9 Nov 2020 10:35:39 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id D794414FB3 for ; Mon, 9 Nov 2020 10:35:39 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [212.186.127.180]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 935E514FAA for ; Mon, 9 Nov 2020 10:35:38 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 6374543C8E for ; Mon, 9 Nov 2020 10:35:38 +0100 (CET) From: Stefan Reiter To: pbs-devel@lists.proxmox.com Date: Mon, 9 Nov 2020 10:35:28 +0100 Message-Id: <20201109093528.27812-1-s.reiter@proxmox.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.036 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pbs-devel] [PATCH proxmox-backup] apt: allow changelog retrieval from enterprise repo X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Nov 2020 09:35:40 -0000 If a package is or will be installed from the enterprise repo, retrieve the changelog from there as well (securely via HTTPS and authenticated with the subcription key). Extends the get_string method to take additional headers, in this case used for 'Authorization'. Hyper does not have built-in basic auth support AFAICT but it's simple enough to just build the header manually. Take the opportunity and also set the User-Agent sensibly for GET requests, just like for POST. Signed-off-by: Stefan Reiter --- Note: If you configure the enterprise repo together with pbstest/staging, the latter will take precedence, i.e. for testing this only configure the enterprise repo, otherwise the old code path will be taken for packages found in both. src/api2/node/apt.rs | 30 ++++++++++++++++++++++++++++-- src/tools/apt.rs | 9 +++++++-- src/tools/http.rs | 18 ++++++++++++++++-- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/api2/node/apt.rs b/src/api2/node/apt.rs index 05c6b7ee..cb1e454a 100644 --- a/src/api2/node/apt.rs +++ b/src/api2/node/apt.rs @@ -1,12 +1,13 @@ use anyhow::{Error, bail, format_err}; use serde_json::{json, Value}; +use std::collections::HashMap; use proxmox::list_subdirs_api_method; use proxmox::api::{api, RpcEnvironment, RpcEnvironmentType, Permission}; use proxmox::api::router::{Router, SubdirMap}; use crate::server::WorkerTask; -use crate::tools::{apt, http}; +use crate::tools::{apt, http, subscription}; use crate::config::acl::{PRIV_SYS_AUDIT, PRIV_SYS_MODIFY}; use crate::api2::types::{Authid, APTUpdateInfo, NODE_SCHEMA, UPID_SCHEMA}; @@ -202,9 +203,34 @@ fn apt_get_changelog( let changelog_url = &pkg_info[0].change_log_url; // FIXME: use 'apt-get changelog' for proxmox packages as well, once repo supports it if changelog_url.starts_with("http://download.proxmox.com/") { - let changelog = crate::tools::runtime::block_on(http::get_string(changelog_url)) + let changelog = crate::tools::runtime::block_on(http::get_string(changelog_url, None)) .map_err(|err| format_err!("Error downloading changelog from '{}': {}", changelog_url, err))?; return Ok(json!(changelog)); + + } else if changelog_url.starts_with("https://enterprise.proxmox.com/") { + let sub = match subscription::read_subscription()? { + Some(sub) => sub, + None => bail!("cannot retrieve changelog from enterprise repo: no subscription info found") + }; + let (key, id) = match sub.key { + Some(key) => { + match sub.serverid { + Some(id) => (key, id), + None => + bail!("cannot retrieve changelog from enterprise repo: no server id found") + } + }, + None => bail!("cannot retrieve changelog from enterprise repo: no subscription key found") + }; + + let mut auth_header = HashMap::new(); + auth_header.insert("Authorization".to_owned(), + format!("Basic {}", base64::encode(format!("{}:{}", key, id)))); + + let changelog = crate::tools::runtime::block_on(http::get_string(changelog_url, Some(&auth_header))) + .map_err(|err| format_err!("Error downloading changelog from '{}': {}", changelog_url, err))?; + return Ok(json!(changelog)); + } else { let mut command = std::process::Command::new("apt-get"); command.arg("changelog"); diff --git a/src/tools/apt.rs b/src/tools/apt.rs index 5800e0a2..3dbc5e23 100644 --- a/src/tools/apt.rs +++ b/src/tools/apt.rs @@ -128,8 +128,13 @@ fn get_changelog_url( None => bail!("incompatible filename, doesn't match regex") }; - return Ok(format!("http://download.proxmox.com/{}/{}_{}.changelog", - base, package, version)); + if component == "pbs-enterprise" { + return Ok(format!("https://enterprise.proxmox.com/{}/{}_{}.changelog", + base, package, version)); + } else { + return Ok(format!("http://download.proxmox.com/{}/{}_{}.changelog", + base, package, version)); + } } bail!("unknown origin ({}) or component ({})", origin, component) diff --git a/src/tools/http.rs b/src/tools/http.rs index 168bb107..d8603fe5 100644 --- a/src/tools/http.rs +++ b/src/tools/http.rs @@ -2,6 +2,7 @@ use anyhow::{Error, format_err, bail}; use lazy_static::lazy_static; use std::task::{Context, Poll}; use std::os::unix::io::AsRawFd; +use std::collections::HashMap; use hyper::{Uri, Body}; use hyper::client::{Client, HttpConnector}; @@ -26,8 +27,21 @@ lazy_static! { }; } -pub async fn get_string(uri: &str) -> Result { - let res = HTTP_CLIENT.get(uri.parse()?).await?; +pub async fn get_string(uri: &str, extra_headers: Option<&HashMap>) -> Result { + let mut request = Request::builder() + .method("GET") + .uri(uri) + .header("User-Agent", "proxmox-backup-client/1.0"); + + if let Some(hs) = extra_headers { + for (h, v) in hs.iter() { + request = request.header(h, v); + } + } + + let request = request.body(Body::empty())?; + + let res = HTTP_CLIENT.request(request).await?; let status = res.status(); if !status.is_success() { -- 2.20.1