]> git.proxmox.com Git - proxmox-backup.git/blobdiff - src/config.rs
unbreak build
[proxmox-backup.git] / src / config.rs
index f8cd22cc8cdd163b6134406fbd21e6afa04221c3..c2ac6da10fef2b7a589f214f92b14196f22d8f95 100644 (file)
@@ -3,13 +3,26 @@
 //! This library contains helper to read, parse and write the
 //! configuration files.
 
-use failure::*;
+use anyhow::{bail, format_err, Error};
+use std::path::PathBuf;
+use nix::sys::stat::Mode;
+use openssl::rsa::{Rsa};
+use openssl::x509::{X509Builder};
+use openssl::pkey::PKey;
 
-use proxmox::tools::try_block;
+use proxmox::tools::fs::{CreateOptions, replace_file};
+use proxmox::try_block;
 
 use crate::buildcfg;
 
+pub mod acl;
+pub mod cached_user_info;
 pub mod datastore;
+pub mod jobstate;
+pub mod network;
+pub mod remote;
+pub mod sync;
+pub mod user;
 
 /// Check configuration directory permissions
 ///
@@ -18,7 +31,10 @@ pub mod datastore;
 /// * nobody else can read (mode 0700)
 pub fn check_configdir_permissions() -> Result<(), Error> {
     let cfgdir = buildcfg::CONFIGDIR;
-    let (backup_uid, backup_gid) = crate::tools::getpwnam_ugid("backup")?;
+
+    let backup_user = crate::backup::backup_user()?;
+    let backup_uid = backup_user.uid.as_raw();
+    let backup_gid = backup_user.gid.as_raw();
 
     try_block!({
         let stat = nix::sys::stat::stat(cfgdir)?;
@@ -46,10 +62,7 @@ pub fn check_configdir_permissions() -> Result<(), Error> {
 }
 
 pub fn create_configdir() -> Result<(), Error> {
-    use nix::sys::stat::Mode;
-
     let cfgdir = buildcfg::CONFIGDIR;
-    let (backup_uid, backup_gid) = crate::tools::getpwnam_ugid("backup")?;
 
     match nix::unistd::mkdir(cfgdir, Mode::from_bits_truncate(0o700)) {
         Ok(()) => {}
@@ -64,19 +77,129 @@ pub fn create_configdir() -> Result<(), Error> {
         ),
     }
 
-    try_block!({
-        let uid = nix::unistd::Uid::from_raw(backup_uid);
-        let gid = nix::unistd::Gid::from_raw(backup_gid);
+    let backup_user = crate::backup::backup_user()?;
 
-        nix::unistd::chown(cfgdir, Some(uid), Some(gid))?;
+    nix::unistd::chown(cfgdir, Some(backup_user.uid), Some(backup_user.gid))
+        .map_err(|err| {
+            format_err!(
+                "unable to set configuration directory '{}' permissions - {}",
+                cfgdir,
+                err
+            )
+        })
+}
 
-        Ok(())
-    })
-    .map_err(|err: Error| {
-        format_err!(
-            "unable to set configuration directory '{}' permissions - {}",
-            cfgdir,
-            err
-        )
-    })
+/// Update self signed node certificate.
+pub fn update_self_signed_cert(force: bool) -> Result<(), Error> {
+
+    let backup_user = crate::backup::backup_user()?;
+
+    create_configdir()?;
+
+    let key_path = PathBuf::from(configdir!("/proxy.key"));
+    let cert_path = PathBuf::from(configdir!("/proxy.pem"));
+
+    if key_path.exists() && cert_path.exists() && !force { return Ok(()); }
+
+    let rsa = Rsa::generate(4096).unwrap();
+
+    let priv_pem = rsa.private_key_to_pem()?;
+
+    replace_file(
+        &key_path,
+        &priv_pem,
+        CreateOptions::new()
+            .perm(Mode::from_bits_truncate(0o0640))
+            .owner(nix::unistd::ROOT)
+            .group(backup_user.gid),
+    )?;
+
+    let mut x509 = X509Builder::new()?;
+
+    x509.set_version(2)?;
+
+    let today = openssl::asn1::Asn1Time::days_from_now(0)?;
+    x509.set_not_before(&today)?;
+    let expire = openssl::asn1::Asn1Time::days_from_now(365*1000)?;
+    x509.set_not_after(&expire)?;
+
+    let nodename = proxmox::tools::nodename();
+    let mut fqdn = nodename.to_owned();
+
+    let resolv_conf = crate::api2::node::dns::read_etc_resolv_conf()?;
+    if let Some(search) = resolv_conf["search"].as_str() {
+        fqdn.push('.');
+        fqdn.push_str(search);
+    }
+
+    // we try to generate an unique 'subject' to avoid browser problems
+    //(reused serial numbers, ..)
+    let uuid = proxmox::tools::uuid::Uuid::generate();
+
+    let mut subject_name = openssl::x509::X509NameBuilder::new()?;
+    subject_name.append_entry_by_text("O", "Proxmox Backup Server")?;
+    subject_name.append_entry_by_text("OU", &format!("{:X}", uuid))?;
+    subject_name.append_entry_by_text("CN", &fqdn)?;
+    let subject_name = subject_name.build();
+
+    x509.set_subject_name(&subject_name)?;
+    x509.set_issuer_name(&subject_name)?;
+
+    let bc = openssl::x509::extension::BasicConstraints::new(); // CA = false
+    let bc = bc.build()?;
+    x509.append_extension(bc)?;
+
+    let usage = openssl::x509::extension::ExtendedKeyUsage::new()
+        .server_auth()
+        .build()?;
+    x509.append_extension(usage)?;
+
+    let context = x509.x509v3_context(None, None);
+
+    let mut alt_names = openssl::x509::extension::SubjectAlternativeName::new();
+
+    alt_names.ip("127.0.0.1");
+    alt_names.ip("::1");
+
+    alt_names.dns("localhost");
+
+    if nodename != "localhost" { alt_names.dns(nodename); }
+    if nodename != fqdn { alt_names.dns(&fqdn); }
+
+    let alt_names = alt_names.build(&context)?;
+
+    x509.append_extension(alt_names)?;
+
+    let pub_pem = rsa.public_key_to_pem()?;
+    let pubkey = PKey::public_key_from_pem(&pub_pem)?;
+
+    x509.set_pubkey(&pubkey)?;
+
+    let context = x509.x509v3_context(None, None);
+    let ext = openssl::x509::extension::SubjectKeyIdentifier::new().build(&context)?;
+    x509.append_extension(ext)?;
+
+    let context = x509.x509v3_context(None, None);
+    let ext = openssl::x509::extension::AuthorityKeyIdentifier::new()
+        .keyid(true)
+        .build(&context)?;
+    x509.append_extension(ext)?;
+
+    let privkey = PKey::from_rsa(rsa)?;
+
+    x509.sign(&privkey, openssl::hash::MessageDigest::sha256())?;
+
+    let x509 = x509.build();
+    let cert_pem = x509.to_pem()?;
+
+    replace_file(
+        &cert_path,
+        &cert_pem,
+        CreateOptions::new()
+            .perm(Mode::from_bits_truncate(0o0640))
+            .owner(nix::unistd::ROOT)
+            .group(backup_user.gid),
+    )?;
+
+    Ok(())
 }