add config setting to allow protections around package uploads to specific registries

This commit is contained in:
Lucy Cifferello
2023-04-11 20:22:14 -06:00
parent e4756f481d
commit d599a90e8b
4 changed files with 27 additions and 18 deletions

View File

@@ -39,6 +39,7 @@ marketplace-name: "_env:MARKETPLACE_NAME:CHANGE ME"
max-eos-version: "_env:MAX_VERSION:0.3.4.0" max-eos-version: "_env:MAX_VERSION:0.3.4.0"
min-eos-version: "_env:MIN_VERSION:0.3.4.0" min-eos-version: "_env:MIN_VERSION:0.3.4.0"
run-migration: "_env:RUN_MIGRATION:false" run-migration: "_env:RUN_MIGRATION:false"
blacklist: "_env:BLACKLIST:ADD ME"
database: database:
database: "_env:PG_DATABASE:start9_registry" database: "_env:PG_DATABASE:start9_registry"

View File

@@ -144,11 +144,13 @@ import Yesod (
import Yesod.Auth (YesodAuth (maybeAuthId)) import Yesod.Auth (YesodAuth (maybeAuthId))
import Yesod.Core.Types (JSONResponse (JSONResponse)) import Yesod.Core.Types (JSONResponse (JSONResponse))
import Database.Persist.Sql (runSqlPool) import Database.Persist.Sql (runSqlPool)
import Data.List (elem)
postPkgUploadR :: Handler () postPkgUploadR :: Handler ()
postPkgUploadR = do postPkgUploadR = do
resourcesTemp <- getsYesod $ (</> "temp") . resourcesDir . appSettings resourcesTemp <- getsYesod $ (</> "temp") . resourcesDir . appSettings
blacklist <- getsYesod $ blacklist . appSettings
createDirectoryIfMissing True resourcesTemp createDirectoryIfMissing True resourcesTemp
withTempDirectory resourcesTemp "newpkg" $ \dir -> do withTempDirectory resourcesTemp "newpkg" $ \dir -> do
let path = dir </> "temp" <.> "s9pk" let path = dir </> "temp" <.> "s9pk"
@@ -159,22 +161,25 @@ postPkgUploadR = do
when (isNothing res) $ do when (isNothing res) $ do
$logError "Failed to extract package" $logError "Failed to extract package"
sendResponseText status500 "Failed to extract package" sendResponseText status500 "Failed to extract package"
PackageManifest{..} <- PackageManifest{..} <- do
liftIO (decodeFileStrict (dir </> "manifest.json")) liftIO (decodeFileStrict (dir </> "manifest.json"))
`orThrow` sendResponseText status500 "Failed to parse manifest.json" `orThrow` sendResponseText status500 "Failed to parse manifest.json"
renameFile path (dir </> (toS . unPkgId) packageManifestId <.> "s9pk") if (elem packageManifestId blacklist)
let targetPath = pkgRepoFileRoot </> show packageManifestId </> show packageManifestVersion then sendResponseText status500 "Package does not belong on this registry."
removePathForcibly targetPath else do
createDirectoryIfMissing True targetPath renameFile path (dir </> (toS . unPkgId) packageManifestId <.> "s9pk")
renameDirectory dir targetPath let targetPath = pkgRepoFileRoot </> show packageManifestId </> show packageManifestVersion
maybeAuthId >>= \case removePathForcibly targetPath
Nothing -> do createDirectoryIfMissing True targetPath
$logError renameDirectory dir targetPath
"The Impossible has happened, an unauthenticated user has managed to upload a pacakge to this registry" maybeAuthId >>= \case
pure () Nothing -> do
Just name -> do $logError
now <- liftIO getCurrentTime "The Impossible has happened, an unauthenticated user has managed to upload a pacakge to this registry"
runDB $ insert_ (Upload (AdminKey name) (PkgRecordKey packageManifestId) packageManifestVersion now) pure ()
Just name -> do
now <- liftIO getCurrentTime
runDB $ insert_ (Upload (AdminKey name) (PkgRecordKey packageManifestId) packageManifestVersion now)
where where
retry m = runMaybeT . asum $ replicate 3 (MaybeT $ hush <$> try @_ @SomeException m) retry m = runMaybeT . asum $ replicate 3 (MaybeT $ hush <$> try @_ @SomeException m)

View File

@@ -23,7 +23,7 @@ import Database.Queries (
getDependencyVersions, getDependencyVersions,
getPkgDataSource, getPkgDataSource,
getPkgDependencyData, getPkgDependencyData,
serviceQuerySource, fetchLatestApp, serviceQuerySource,
) )
import Foundation (Handler, Route (InstructionsR, LicenseR), RegistryCtx (appSettings)) import Foundation (Handler, Route (InstructionsR, LicenseR), RegistryCtx (appSettings))
import Handler.Package.Api (DependencyRes (..), PackageListRes (..), PackageRes (..)) import Handler.Package.Api (DependencyRes (..), PackageListRes (..), PackageRes (..))

View File

@@ -56,6 +56,7 @@ import Lib.PkgRepository ( EosRepo(EosRepo, eosRepoFileRo
) )
import Lib.Types.Emver ( Version ) import Lib.Types.Emver ( Version )
import Orphans.Emver ( ) import Orphans.Emver ( )
import Lib.Types.Core (PkgId)
-- | Runtime settings to configure this application. These settings can be -- | Runtime settings to configure this application. These settings can be
-- loaded from various sources: defaults, environment variables, config files, -- loaded from various sources: defaults, environment variables, config files,
-- theoretically even a database. -- theoretically even a database.
@@ -75,12 +76,12 @@ data AppSettings = AppSettings
-- ^ Should all log messages be displayed? -- ^ Should all log messages be displayed?
, errorLogRoot :: !FilePath , errorLogRoot :: !FilePath
, marketplaceName :: !Text , marketplaceName :: !Text
, maxOsVersion :: !Version , maxOsVersion :: !Version
, minOsVersion :: !Version , minOsVersion :: !Version
, registryHostname :: !Text , registryHostname :: !Text
, registryVersion :: !Version , registryVersion :: !Version
, resourcesDir :: !FilePath , resourcesDir :: !FilePath
, needsMigration :: !Bool , needsMigration :: !Bool
, sslAuto :: !Bool , sslAuto :: !Bool
, sslCertLocation :: !FilePath , sslCertLocation :: !FilePath
, sslCsrLocation :: !FilePath , sslCsrLocation :: !FilePath
@@ -88,6 +89,7 @@ data AppSettings = AppSettings
, sslPath :: !FilePath , sslPath :: !FilePath
, staticBinDir :: !FilePath , staticBinDir :: !FilePath
, torPort :: !AppPort , torPort :: !AppPort
, blacklist :: ![PkgId]
} }
instance Has PkgRepo AppSettings where instance Has PkgRepo AppSettings where
extract = liftA2 PkgRepo ((</> "apps") . resourcesDir) staticBinDir extract = liftA2 PkgRepo ((</> "apps") . resourcesDir) staticBinDir
@@ -120,6 +122,7 @@ instance FromJSON AppSettings where
sslPath <- o .: "ssl-path" sslPath <- o .: "ssl-path"
staticBinDir <- o .: "static-bin-dir" staticBinDir <- o .: "static-bin-dir"
torPort <- o .: "tor-port" torPort <- o .: "tor-port"
blacklist <- o .: "blacklist"
let sslKeyLocation = sslPath </> "key.pem" let sslKeyLocation = sslPath </> "key.pem"
let sslCsrLocation = sslPath </> "certificate.csr" let sslCsrLocation = sslPath </> "certificate.csr"