public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pbs-devel] [PATCH proxmox-backup 1/3] refactor CertInfo to tools
@ 2020-07-10  8:51 Dominik Csapak
  2020-07-10  8:51 ` [pbs-devel] [PATCH proxmox-backup 2/3] api2/node/status: add fingerprint Dominik Csapak
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Dominik Csapak @ 2020-07-10  8:51 UTC (permalink / raw)
  To: pbs-devel

we want to reuse some of the functionality elsewhere

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/bin/proxmox_backup_manager/cert.rs | 29 ++---------
 src/tools.rs                           |  1 +
 src/tools/cert.rs                      | 67 ++++++++++++++++++++++++++
 3 files changed, 73 insertions(+), 24 deletions(-)
 create mode 100644 src/tools/cert.rs

diff --git a/src/bin/proxmox_backup_manager/cert.rs b/src/bin/proxmox_backup_manager/cert.rs
index f5f725a..845c8ed 100644
--- a/src/bin/proxmox_backup_manager/cert.rs
+++ b/src/bin/proxmox_backup_manager/cert.rs
@@ -1,32 +1,18 @@
-use std::path::PathBuf;
-
 use anyhow::{bail, Error};
 
 use proxmox::api::{api, cli::*};
 
 use proxmox_backup::config;
-use proxmox_backup::configdir;
 use proxmox_backup::auth_helpers::*;
-
-fn x509name_to_string(name: &openssl::x509::X509NameRef) -> Result<String, Error> {
-    let mut parts = Vec::new();
-    for entry in name.entries() {
-        parts.push(format!("{} = {}", entry.object().nid().short_name()?, entry.data().as_utf8()?));
-    }
-    Ok(parts.join(", "))
-}
+use proxmox_backup::tools::cert::CertInfo;
 
 #[api]
 /// Display node certificate information.
 fn cert_info() -> Result<(), Error> {
 
-    let cert_path = PathBuf::from(configdir!("/proxy.pem"));
+    let cert = CertInfo::new()?;
 
-    let cert_pem = proxmox::tools::fs::file_get_contents(&cert_path)?;
-
-    let cert = openssl::x509::X509::from_pem(&cert_pem)?;
-
-    println!("Subject: {}", x509name_to_string(cert.subject_name())?);
+    println!("Subject: {}", cert.subject_name()?);
 
     if let Some(san) = cert.subject_alt_names() {
         for name in san.iter() {
@@ -42,17 +28,12 @@ fn cert_info() -> Result<(), Error> {
         }
     }
 
-    println!("Issuer: {}", x509name_to_string(cert.issuer_name())?);
+    println!("Issuer: {}", cert.issuer_name()?);
     println!("Validity:");
     println!("    Not Before: {}", cert.not_before());
     println!("    Not After : {}", cert.not_after());
 
-    let fp = cert.digest(openssl::hash::MessageDigest::sha256())?;
-    let fp_string = proxmox::tools::digest_to_hex(&fp);
-    let fp_string = fp_string.as_bytes().chunks(2).map(|v| std::str::from_utf8(v).unwrap())
-        .collect::<Vec<&str>>().join(":");
-
-    println!("Fingerprint (sha256): {}", fp_string);
+    println!("Fingerprint (sha256): {}", cert.fingerprint()?);
 
     let pubkey = cert.public_key()?;
     println!("Public key type: {}", openssl::nid::Nid::from_raw(pubkey.id().as_raw()).long_name()?);
diff --git a/src/tools.rs b/src/tools.rs
index 75c8d9f..4bfc35c 100644
--- a/src/tools.rs
+++ b/src/tools.rs
@@ -23,6 +23,7 @@ pub use proxmox::tools::fd::Fd;
 pub mod acl;
 pub mod async_io;
 pub mod borrow;
+pub mod cert;
 pub mod daemon;
 pub mod disks;
 pub mod fs;
diff --git a/src/tools/cert.rs b/src/tools/cert.rs
new file mode 100644
index 0000000..0c7e9e5
--- /dev/null
+++ b/src/tools/cert.rs
@@ -0,0 +1,67 @@
+use std::path::PathBuf;
+
+use anyhow::Error;
+use openssl::x509::{X509, GeneralName};
+use openssl::stack::Stack;
+use openssl::pkey::{Public, PKey};
+
+use crate::configdir;
+
+pub struct CertInfo {
+    x509: X509,
+}
+
+fn x509name_to_string(name: &openssl::x509::X509NameRef) -> Result<String, Error> {
+    let mut parts = Vec::new();
+    for entry in name.entries() {
+        parts.push(format!("{} = {}", entry.object().nid().short_name()?, entry.data().as_utf8()?));
+    }
+    Ok(parts.join(", "))
+}
+
+impl CertInfo {
+    pub fn new() -> Result<Self, Error> {
+        Self::from_path(PathBuf::from(configdir!("/proxy.pem")))
+    }
+
+    pub fn from_path(path: PathBuf) -> Result<Self, Error> {
+        let cert_pem = proxmox::tools::fs::file_get_contents(&path)?;
+        let x509 = openssl::x509::X509::from_pem(&cert_pem)?;
+        Ok(Self{
+            x509
+        })
+    }
+
+    pub fn subject_alt_names(&self) -> Option<Stack<GeneralName>> {
+        self.x509.subject_alt_names()
+    }
+
+    pub fn subject_name(&self) -> Result<String, Error> {
+        Ok(x509name_to_string(self.x509.subject_name())?)
+    }
+
+    pub fn issuer_name(&self) -> Result<String, Error> {
+        Ok(x509name_to_string(self.x509.issuer_name())?)
+    }
+
+    pub fn fingerprint(&self) -> Result<String, Error> {
+        let fp = self.x509.digest(openssl::hash::MessageDigest::sha256())?;
+        let fp_string = proxmox::tools::digest_to_hex(&fp);
+        let fp_string = fp_string.as_bytes().chunks(2).map(|v| std::str::from_utf8(v).unwrap())
+            .collect::<Vec<&str>>().join(":");
+        Ok(fp_string)
+    }
+
+    pub fn public_key(&self) -> Result<PKey<Public>, Error> {
+        let pubkey = self.x509.public_key()?;
+        Ok(pubkey)
+    }
+
+    pub fn not_before(&self) -> &openssl::asn1::Asn1TimeRef {
+        self.x509.not_before()
+    }
+
+    pub fn not_after(&self) -> &openssl::asn1::Asn1TimeRef {
+        self.x509.not_after()
+    }
+}
-- 
2.20.1





^ permalink raw reply	[flat|nested] 4+ messages in thread

* [pbs-devel] [PATCH proxmox-backup 2/3] api2/node/status: add fingerprint
  2020-07-10  8:51 [pbs-devel] [PATCH proxmox-backup 1/3] refactor CertInfo to tools Dominik Csapak
@ 2020-07-10  8:51 ` Dominik Csapak
  2020-07-10  8:51 ` [pbs-devel] [PATCH proxmox-backup 3/3] ui: add show fingerprint button to dashboard Dominik Csapak
  2020-07-10  9:10 ` [pbs-devel] applied: [PATCH proxmox-backup 1/3] refactor CertInfo to tools Dietmar Maurer
  2 siblings, 0 replies; 4+ messages in thread
From: Dominik Csapak @ 2020-07-10  8:51 UTC (permalink / raw)
  To: pbs-devel

and rename get_usage to get_status (since its not usage only anymore)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/api2/node/status.rs | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/api2/node/status.rs b/src/api2/node/status.rs
index 970c136..14d4b58 100644
--- a/src/api2/node/status.rs
+++ b/src/api2/node/status.rs
@@ -10,6 +10,7 @@ use proxmox::api::{api, ApiMethod, Router, RpcEnvironment, Permission};
 
 use crate::api2::types::*;
 use crate::config::acl::{PRIV_SYS_AUDIT, PRIV_SYS_POWER_MANAGEMENT};
+use crate::tools::cert::CertInfo;
 
 #[api(
     input: {
@@ -46,14 +47,24 @@ use crate::config::acl::{PRIV_SYS_AUDIT, PRIV_SYS_POWER_MANAGEMENT};
                 description: "Total CPU usage since last query.",
                 optional: true,
             },
-        }
+            info: {
+                type: Object,
+                description: "contains node information",
+                properties: {
+                    fingerprint: {
+                        description: "The SSL Fingerprint",
+                        type: String,
+                    },
+                },
+            },
+        },
     },
     access: {
         permission: &Permission::Privilege(&["system", "status"], PRIV_SYS_AUDIT, false),
     },
 )]
 /// Read node memory, CPU and (root) disk usage
-fn get_usage(
+fn get_status(
     _param: Value,
     _info: &ApiMethod,
     _rpcenv: &mut dyn RpcEnvironment,
@@ -63,6 +74,10 @@ fn get_usage(
     let kstat: procfs::ProcFsStat = procfs::read_proc_stat()?;
     let disk_usage = crate::tools::disks::disk_usage(Path::new("/"))?;
 
+    // get fingerprint
+    let cert = CertInfo::new()?;
+    let fp = cert.fingerprint()?;
+
     Ok(json!({
         "memory": {
             "total": meminfo.memtotal,
@@ -74,7 +89,10 @@ fn get_usage(
             "total": disk_usage.total,
             "used": disk_usage.used,
             "free": disk_usage.avail,
-        }
+        },
+        "info": {
+            "fingerprint": fp,
+        },
     }))
 }
 
@@ -122,5 +140,5 @@ fn reboot_or_shutdown(command: NodePowerCommand) -> Result<(), Error> {
 }
 
 pub const ROUTER: Router = Router::new()
-    .get(&API_METHOD_GET_USAGE)
+    .get(&API_METHOD_GET_STATUS)
     .post(&API_METHOD_REBOOT_OR_SHUTDOWN);
-- 
2.20.1





^ permalink raw reply	[flat|nested] 4+ messages in thread

* [pbs-devel] [PATCH proxmox-backup 3/3] ui: add show fingerprint button to dashboard
  2020-07-10  8:51 [pbs-devel] [PATCH proxmox-backup 1/3] refactor CertInfo to tools Dominik Csapak
  2020-07-10  8:51 ` [pbs-devel] [PATCH proxmox-backup 2/3] api2/node/status: add fingerprint Dominik Csapak
@ 2020-07-10  8:51 ` Dominik Csapak
  2020-07-10  9:10 ` [pbs-devel] applied: [PATCH proxmox-backup 1/3] refactor CertInfo to tools Dietmar Maurer
  2 siblings, 0 replies; 4+ messages in thread
From: Dominik Csapak @ 2020-07-10  8:51 UTC (permalink / raw)
  To: pbs-devel

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 www/Dashboard.js | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/www/Dashboard.js b/www/Dashboard.js
index 10d4261..9ac30b2 100644
--- a/www/Dashboard.js
+++ b/www/Dashboard.js
@@ -76,6 +76,7 @@ Ext.define('PBS.Dashboard', {
 	    let viewmodel = me.getViewModel();
 
 	    let res = records[0].data;
+	    viewmodel.set('fingerprint', res.info.fingerprint || Proxmox.Utils.unknownText);
 
 	    let cpu = res.cpu,
 	        mem = res.memory,
@@ -91,6 +92,34 @@ Ext.define('PBS.Dashboard', {
 	    hdPanel.updateValue(root.used / root.total);
 	},
 
+	showFingerPrint: function() {
+	    let me = this;
+	    let vm = me.getViewModel();
+	    let fingerprint = vm.get('fingerprint');
+	    Ext.create('Ext.window.Window', {
+		modal: true,
+		width: 600,
+		title: gettext('Fingerprint'),
+		layout: 'form',
+		bodyPadding: '10 0',
+		items: [
+		    {
+			xtype: 'textfield',
+			value: fingerprint,
+			editable: false,
+		    },
+		],
+		buttons: [
+		    {
+			text: gettext("OK"),
+			handler: function() {
+			    this.up('window').close();
+			},
+		    },
+		],
+	    }).show();
+	},
+
 	updateTasks: function(store, records, success) {
 	    if (!success) return;
 	    let me = this;
@@ -134,11 +163,16 @@ Ext.define('PBS.Dashboard', {
 	    timespan: 300, // in seconds
 	    hours: 12, // in hours
 	    error_shown: false,
+	    fingerprint: "",
 	    'bytes_in': 0,
 	    'bytes_out': 0,
 	    'avg_ptime': 0.0
 	},
 
+	formulas: {
+	    disableFPButton: (get) => get('fingerprint') === "",
+	},
+
 	stores: {
 	    usage: {
 		storeid: 'dash-usage',
@@ -211,6 +245,16 @@ Ext.define('PBS.Dashboard', {
 	    iconCls: 'fa fa-tasks',
 	    title: gettext('Server Resources'),
 	    bodyPadding: '0 20 0 20',
+	    tools: [
+		{
+		    xtype: 'button',
+		    text: gettext('Show Fingerprint'),
+		    handler: 'showFingerPrint',
+		    bind: {
+			disabled: '{disableFPButton}',
+		    },
+		},
+	    ],
 	    layout: {
 		type: 'hbox',
 		align: 'center'
-- 
2.20.1





^ permalink raw reply	[flat|nested] 4+ messages in thread

* [pbs-devel] applied: [PATCH proxmox-backup 1/3] refactor CertInfo to tools
  2020-07-10  8:51 [pbs-devel] [PATCH proxmox-backup 1/3] refactor CertInfo to tools Dominik Csapak
  2020-07-10  8:51 ` [pbs-devel] [PATCH proxmox-backup 2/3] api2/node/status: add fingerprint Dominik Csapak
  2020-07-10  8:51 ` [pbs-devel] [PATCH proxmox-backup 3/3] ui: add show fingerprint button to dashboard Dominik Csapak
@ 2020-07-10  9:10 ` Dietmar Maurer
  2 siblings, 0 replies; 4+ messages in thread
From: Dietmar Maurer @ 2020-07-10  9:10 UTC (permalink / raw)
  To: Proxmox Backup Server development discussion, Dominik Csapak

applied all 3 patches

> On 07/10/2020 10:51 AM Dominik Csapak <d.csapak@proxmox.com> wrote:
> 
>  
> we want to reuse some of the functionality elsewhere
> 
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
>  src/bin/proxmox_backup_manager/cert.rs | 29 ++---------
>  src/tools.rs                           |  1 +
>  src/tools/cert.rs                      | 67 ++++++++++++++++++++++++++
>  3 files changed, 73 insertions(+), 24 deletions(-)
>  create mode 100644 src/tools/cert.rs
> 
> diff --git a/src/bin/proxmox_backup_manager/cert.rs b/src/bin/proxmox_backup_manager/cert.rs
> index f5f725a..845c8ed 100644
> --- a/src/bin/proxmox_backup_manager/cert.rs
> +++ b/src/bin/proxmox_backup_manager/cert.rs
> @@ -1,32 +1,18 @@
> -use std::path::PathBuf;
> -
>  use anyhow::{bail, Error};
>  
>  use proxmox::api::{api, cli::*};
>  
>  use proxmox_backup::config;
> -use proxmox_backup::configdir;
>  use proxmox_backup::auth_helpers::*;
> -
> -fn x509name_to_string(name: &openssl::x509::X509NameRef) -> Result<String, Error> {
> -    let mut parts = Vec::new();
> -    for entry in name.entries() {
> -        parts.push(format!("{} = {}", entry.object().nid().short_name()?, entry.data().as_utf8()?));
> -    }
> -    Ok(parts.join(", "))
> -}
> +use proxmox_backup::tools::cert::CertInfo;
>  
>  #[api]
>  /// Display node certificate information.
>  fn cert_info() -> Result<(), Error> {
>  
> -    let cert_path = PathBuf::from(configdir!("/proxy.pem"));
> +    let cert = CertInfo::new()?;
>  
> -    let cert_pem = proxmox::tools::fs::file_get_contents(&cert_path)?;
> -
> -    let cert = openssl::x509::X509::from_pem(&cert_pem)?;
> -
> -    println!("Subject: {}", x509name_to_string(cert.subject_name())?);
> +    println!("Subject: {}", cert.subject_name()?);
>  
>      if let Some(san) = cert.subject_alt_names() {
>          for name in san.iter() {
> @@ -42,17 +28,12 @@ fn cert_info() -> Result<(), Error> {
>          }
>      }
>  
> -    println!("Issuer: {}", x509name_to_string(cert.issuer_name())?);
> +    println!("Issuer: {}", cert.issuer_name()?);
>      println!("Validity:");
>      println!("    Not Before: {}", cert.not_before());
>      println!("    Not After : {}", cert.not_after());
>  
> -    let fp = cert.digest(openssl::hash::MessageDigest::sha256())?;
> -    let fp_string = proxmox::tools::digest_to_hex(&fp);
> -    let fp_string = fp_string.as_bytes().chunks(2).map(|v| std::str::from_utf8(v).unwrap())
> -        .collect::<Vec<&str>>().join(":");
> -
> -    println!("Fingerprint (sha256): {}", fp_string);
> +    println!("Fingerprint (sha256): {}", cert.fingerprint()?);
>  
>      let pubkey = cert.public_key()?;
>      println!("Public key type: {}", openssl::nid::Nid::from_raw(pubkey.id().as_raw()).long_name()?);
> diff --git a/src/tools.rs b/src/tools.rs
> index 75c8d9f..4bfc35c 100644
> --- a/src/tools.rs
> +++ b/src/tools.rs
> @@ -23,6 +23,7 @@ pub use proxmox::tools::fd::Fd;
>  pub mod acl;
>  pub mod async_io;
>  pub mod borrow;
> +pub mod cert;
>  pub mod daemon;
>  pub mod disks;
>  pub mod fs;
> diff --git a/src/tools/cert.rs b/src/tools/cert.rs
> new file mode 100644
> index 0000000..0c7e9e5
> --- /dev/null
> +++ b/src/tools/cert.rs
> @@ -0,0 +1,67 @@
> +use std::path::PathBuf;
> +
> +use anyhow::Error;
> +use openssl::x509::{X509, GeneralName};
> +use openssl::stack::Stack;
> +use openssl::pkey::{Public, PKey};
> +
> +use crate::configdir;
> +
> +pub struct CertInfo {
> +    x509: X509,
> +}
> +
> +fn x509name_to_string(name: &openssl::x509::X509NameRef) -> Result<String, Error> {
> +    let mut parts = Vec::new();
> +    for entry in name.entries() {
> +        parts.push(format!("{} = {}", entry.object().nid().short_name()?, entry.data().as_utf8()?));
> +    }
> +    Ok(parts.join(", "))
> +}
> +
> +impl CertInfo {
> +    pub fn new() -> Result<Self, Error> {
> +        Self::from_path(PathBuf::from(configdir!("/proxy.pem")))
> +    }
> +
> +    pub fn from_path(path: PathBuf) -> Result<Self, Error> {
> +        let cert_pem = proxmox::tools::fs::file_get_contents(&path)?;
> +        let x509 = openssl::x509::X509::from_pem(&cert_pem)?;
> +        Ok(Self{
> +            x509
> +        })
> +    }
> +
> +    pub fn subject_alt_names(&self) -> Option<Stack<GeneralName>> {
> +        self.x509.subject_alt_names()
> +    }
> +
> +    pub fn subject_name(&self) -> Result<String, Error> {
> +        Ok(x509name_to_string(self.x509.subject_name())?)
> +    }
> +
> +    pub fn issuer_name(&self) -> Result<String, Error> {
> +        Ok(x509name_to_string(self.x509.issuer_name())?)
> +    }
> +
> +    pub fn fingerprint(&self) -> Result<String, Error> {
> +        let fp = self.x509.digest(openssl::hash::MessageDigest::sha256())?;
> +        let fp_string = proxmox::tools::digest_to_hex(&fp);
> +        let fp_string = fp_string.as_bytes().chunks(2).map(|v| std::str::from_utf8(v).unwrap())
> +            .collect::<Vec<&str>>().join(":");
> +        Ok(fp_string)
> +    }
> +
> +    pub fn public_key(&self) -> Result<PKey<Public>, Error> {
> +        let pubkey = self.x509.public_key()?;
> +        Ok(pubkey)
> +    }
> +
> +    pub fn not_before(&self) -> &openssl::asn1::Asn1TimeRef {
> +        self.x509.not_before()
> +    }
> +
> +    pub fn not_after(&self) -> &openssl::asn1::Asn1TimeRef {
> +        self.x509.not_after()
> +    }
> +}
> -- 
> 2.20.1
> 
> 
> 
> _______________________________________________
> pbs-devel mailing list
> pbs-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-07-10  9:11 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-10  8:51 [pbs-devel] [PATCH proxmox-backup 1/3] refactor CertInfo to tools Dominik Csapak
2020-07-10  8:51 ` [pbs-devel] [PATCH proxmox-backup 2/3] api2/node/status: add fingerprint Dominik Csapak
2020-07-10  8:51 ` [pbs-devel] [PATCH proxmox-backup 3/3] ui: add show fingerprint button to dashboard Dominik Csapak
2020-07-10  9:10 ` [pbs-devel] applied: [PATCH proxmox-backup 1/3] refactor CertInfo to tools Dietmar Maurer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal