mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-31 04:23:40 +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 model;
|
||||||
|
pub mod package;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|||||||
@@ -223,6 +223,15 @@ impl PackageDataEntry {
|
|||||||
Self::Updating { installed, .. } | Self::Installed { installed, .. } => Some(installed),
|
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 {
|
impl PackageDataEntryModel {
|
||||||
pub fn installed(self) -> OptionModel<InstalledPackageDataEntry> {
|
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,
|
Incoherent = 55,
|
||||||
InvalidBackupTargetId = 56,
|
InvalidBackupTargetId = 56,
|
||||||
ProductKeyMismatch = 57,
|
ProductKeyMismatch = 57,
|
||||||
|
LanPortConflict = 58,
|
||||||
}
|
}
|
||||||
impl ErrorKind {
|
impl ErrorKind {
|
||||||
pub fn as_str(&self) -> &'static str {
|
pub fn as_str(&self) -> &'static str {
|
||||||
@@ -125,6 +126,7 @@ impl ErrorKind {
|
|||||||
Incoherent => "Incoherent",
|
Incoherent => "Incoherent",
|
||||||
InvalidBackupTargetId => "Invalid Backup Target ID",
|
InvalidBackupTargetId => "Invalid Backup Target ID",
|
||||||
ProductKeyMismatch => "Incompatible Product Keys",
|
ProductKeyMismatch => "Incompatible Product Keys",
|
||||||
|
LanPortConflict => "Incompatible LAN port configuration",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ use std::time::{Duration, Instant};
|
|||||||
|
|
||||||
use color_eyre::eyre::eyre;
|
use color_eyre::eyre::eyre;
|
||||||
use emver::VersionRange;
|
use emver::VersionRange;
|
||||||
use futures::future::BoxFuture;
|
use futures::future::{self, BoxFuture};
|
||||||
use futures::{FutureExt, StreamExt, TryStreamExt};
|
use futures::{stream, FutureExt, StreamExt, TryStreamExt};
|
||||||
use http::header::CONTENT_LENGTH;
|
use http::header::CONTENT_LENGTH;
|
||||||
use http::{Request, Response, StatusCode};
|
use http::{Request, Response, StatusCode};
|
||||||
use hyper::Body;
|
use hyper::Body;
|
||||||
@@ -43,7 +43,7 @@ use crate::s9pk::manifest::{Manifest, PackageId};
|
|||||||
use crate::s9pk::reader::S9pkReader;
|
use crate::s9pk::reader::S9pkReader;
|
||||||
use crate::status::{MainStatus, Status};
|
use crate::status::{MainStatus, Status};
|
||||||
use crate::util::io::{copy_and_shutdown, response_to_reader};
|
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::util::{display_none, AsyncFileExt, Version};
|
||||||
use crate::version::{Current, VersionT};
|
use crate::version::{Current, VersionT};
|
||||||
use crate::volume::asset_dir;
|
use crate::volume::asset_dir;
|
||||||
@@ -124,6 +124,7 @@ pub async fn install(
|
|||||||
.json()
|
.json()
|
||||||
.await
|
.await
|
||||||
.with_kind(crate::ErrorKind::Registry)?;
|
.with_kind(crate::ErrorKind::Registry)?;
|
||||||
|
|
||||||
let s9pk = s9pk
|
let s9pk = s9pk
|
||||||
.error_for_status()
|
.error_for_status()
|
||||||
.with_kind(crate::ErrorKind::Registry)?;
|
.with_kind(crate::ErrorKind::Registry)?;
|
||||||
@@ -651,6 +652,51 @@ pub async fn download_install_s9pk(
|
|||||||
let version = &temp_manifest.version;
|
let version = &temp_manifest.version;
|
||||||
|
|
||||||
if let Err(e) = async {
|
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
|
let pkg_archive_dir = ctx
|
||||||
.datadir
|
.datadir
|
||||||
.join(PKG_ARCHIVE_DIR)
|
.join(PKG_ARCHIVE_DIR)
|
||||||
@@ -1345,3 +1391,20 @@ pub fn load_images<'a, P: AsRef<Path> + 'a + Send + Sync>(
|
|||||||
}
|
}
|
||||||
.boxed()
|
.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