mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
prevents packages from producing conflicting ssl configs (#1195)
* prevents packages from producing conflicting ssl configs * remove commented code commits missing file fix builds
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
pub mod model;
|
||||
pub mod package;
|
||||
pub mod util;
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
@@ -223,6 +223,15 @@ impl PackageDataEntry {
|
||||
Self::Updating { installed, .. } | Self::Installed { installed, .. } => Some(installed),
|
||||
}
|
||||
}
|
||||
pub fn manifest(self) -> Manifest {
|
||||
match self {
|
||||
PackageDataEntry::Installing { manifest, .. } => manifest,
|
||||
PackageDataEntry::Updating { manifest, .. } => manifest,
|
||||
PackageDataEntry::Restoring { manifest, .. } => manifest,
|
||||
PackageDataEntry::Removing { manifest, .. } => manifest,
|
||||
PackageDataEntry::Installed { manifest, .. } => manifest,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl PackageDataEntryModel {
|
||||
pub fn installed(self) -> OptionModel<InstalledPackageDataEntry> {
|
||||
|
||||
25
backend/src/db/package.rs
Normal file
25
backend/src/db/package.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
use patch_db::DbHandle;
|
||||
|
||||
use crate::s9pk::manifest::{Manifest, PackageId};
|
||||
use crate::Error;
|
||||
|
||||
pub async fn get_packages<Db: DbHandle>(db: &mut Db) -> Result<Vec<PackageId>, Error> {
|
||||
let packages = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.get(db, false)
|
||||
.await?;
|
||||
Ok(packages.0.keys().cloned().collect())
|
||||
}
|
||||
|
||||
pub async fn get_manifest<Db: DbHandle>(
|
||||
db: &mut Db,
|
||||
pkg: &PackageId,
|
||||
) -> Result<Option<Manifest>, Error> {
|
||||
let mpde = crate::db::DatabaseModel::new()
|
||||
.package_data()
|
||||
.idx_model(pkg)
|
||||
.get(db, false)
|
||||
.await?
|
||||
.into_owned();
|
||||
Ok(mpde.map(|pde| pde.manifest()))
|
||||
}
|
||||
@@ -63,6 +63,7 @@ pub enum ErrorKind {
|
||||
Incoherent = 55,
|
||||
InvalidBackupTargetId = 56,
|
||||
ProductKeyMismatch = 57,
|
||||
LanPortConflict = 58,
|
||||
}
|
||||
impl ErrorKind {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
@@ -125,6 +126,7 @@ impl ErrorKind {
|
||||
Incoherent => "Incoherent",
|
||||
InvalidBackupTargetId => "Invalid Backup Target ID",
|
||||
ProductKeyMismatch => "Incompatible Product Keys",
|
||||
LanPortConflict => "Incompatible LAN port configuration",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ use std::time::{Duration, Instant};
|
||||
|
||||
use color_eyre::eyre::eyre;
|
||||
use emver::VersionRange;
|
||||
use futures::future::BoxFuture;
|
||||
use futures::{FutureExt, StreamExt, TryStreamExt};
|
||||
use futures::future::{self, BoxFuture};
|
||||
use futures::{stream, FutureExt, StreamExt, TryStreamExt};
|
||||
use http::header::CONTENT_LENGTH;
|
||||
use http::{Request, Response, StatusCode};
|
||||
use hyper::Body;
|
||||
@@ -43,7 +43,7 @@ use crate::s9pk::manifest::{Manifest, PackageId};
|
||||
use crate::s9pk::reader::S9pkReader;
|
||||
use crate::status::{MainStatus, Status};
|
||||
use crate::util::io::{copy_and_shutdown, response_to_reader};
|
||||
use crate::util::serde::{display_serializable, IoFormat};
|
||||
use crate::util::serde::{display_serializable, IoFormat, Port};
|
||||
use crate::util::{display_none, AsyncFileExt, Version};
|
||||
use crate::version::{Current, VersionT};
|
||||
use crate::volume::asset_dir;
|
||||
@@ -124,6 +124,7 @@ pub async fn install(
|
||||
.json()
|
||||
.await
|
||||
.with_kind(crate::ErrorKind::Registry)?;
|
||||
|
||||
let s9pk = s9pk
|
||||
.error_for_status()
|
||||
.with_kind(crate::ErrorKind::Registry)?;
|
||||
@@ -651,6 +652,51 @@ pub async fn download_install_s9pk(
|
||||
let version = &temp_manifest.version;
|
||||
|
||||
if let Err(e) = async {
|
||||
let mut db_handle = ctx.db.handle();
|
||||
let mut tx = db_handle.begin().await?;
|
||||
// Build set of existing manifests
|
||||
let mut manifests = Vec::new();
|
||||
for pkg in crate::db::package::get_packages(&mut tx).await? {
|
||||
match crate::db::package::get_manifest(&mut tx, &pkg).await? {
|
||||
Some(m) => {
|
||||
manifests.push(m);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
// Build map of current port -> ssl mappings
|
||||
let port_map = ssl_port_status(&manifests);
|
||||
tracing::info!("SSL Port Map: {:?}", &port_map);
|
||||
|
||||
// if any of the requested interface lan configs conflict with current state, fail the install
|
||||
for (_id, iface) in &temp_manifest.interfaces.0 {
|
||||
if let Some(cfg) = &iface.lan_config {
|
||||
for (p, lan) in cfg {
|
||||
if p.0 == 80 && lan.ssl || p.0 == 443 && !lan.ssl {
|
||||
return Err(Error::new(
|
||||
eyre!("SSL Conflict with EmbassyOS"),
|
||||
ErrorKind::LanPortConflict,
|
||||
));
|
||||
}
|
||||
match port_map.get(&p) {
|
||||
Some((ssl, pkg)) => {
|
||||
if *ssl != lan.ssl {
|
||||
return Err(Error::new(
|
||||
eyre!("SSL Conflict with package: {}", pkg),
|
||||
ErrorKind::LanPortConflict,
|
||||
));
|
||||
}
|
||||
}
|
||||
None => {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tx.save().await?;
|
||||
drop(db_handle);
|
||||
|
||||
let pkg_archive_dir = ctx
|
||||
.datadir
|
||||
.join(PKG_ARCHIVE_DIR)
|
||||
@@ -1345,3 +1391,20 @@ pub fn load_images<'a, P: AsRef<Path> + 'a + Send + Sync>(
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn ssl_port_status(manifests: &Vec<Manifest>) -> BTreeMap<Port, (bool, PackageId)> {
|
||||
let mut ret = BTreeMap::new();
|
||||
for m in manifests {
|
||||
for (_id, iface) in &m.interfaces.0 {
|
||||
match &iface.lan_config {
|
||||
None => {}
|
||||
Some(cfg) => {
|
||||
for (p, lan) in cfg {
|
||||
ret.insert(p.clone(), (lan.ssl, m.id.clone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user