Compare commits

..

5 Commits

Author SHA1 Message Date
Keagan McClelland
424afb3d1c adds actions copy (#240)
* adds actions copy

* punctuation

* punctuation

* removes superfluous language
2021-03-08 17:51:27 -07:00
Matt Hill
a056f6d318 fix instructions link (#239) 2021-03-08 17:25:24 -07:00
Keagan McClelland
5339b23ea6 0.2.10 version bump stuff (#238)
* agent -> 0.2.10

* appmgr -> 0.2.10

* updates to 0.2.10 for the UI

Co-authored-by: Aiden McClelland <me@drbonez.dev>
2021-03-08 16:38:24 -07:00
Aiden McClelland
bd61510c24 Hotfix/rewrite certs (#237)
* appmgr: rewrite full cert if missing

* rewrite if key missing
2021-03-08 16:25:05 -07:00
Keagan McClelland
91557c39e5 drops uniqueness requirement (#236) 2021-03-08 16:21:21 -07:00
16 changed files with 231 additions and 185 deletions

View File

@@ -1,9 +1,9 @@
# Values formatted like "_env:YESOD_ENV_VAR_NAME:default_value" can be overridden by the specified environment variable.
# See https://github.com/yesodweb/yesod/wiki/Configuration#overriding-configuration-values-with-environment-variables
static-dir: "_env:YESOD_STATIC_DIR:static"
host: "_env:YESOD_HOST:*4" # any IPv4 host
port: 5959 # NB: The port `yesod devel` uses is distinct from this value. Set the `yesod devel` port from the command line.
static-dir: "_env:YESOD_STATIC_DIR:static"
host: "_env:YESOD_HOST:*4" # any IPv4 host
port: 5959 # NB: The port `yesod devel` uses is distinct from this value. Set the `yesod devel` port from the command line.
ip-from-header: "_env:YESOD_IP_FROM_HEADER:false"
detailed-logging: "_env:DETAILED_LOGGING:false"
@@ -33,6 +33,5 @@ database:
database: "start9_agent.sqlite3"
poolsize: "_env:YESOD_SQLITE_POOLSIZE:10"
app-mgr-version-spec: "=0.2.9"
app-mgr-version-spec: "=0.2.10"
#analytics: UA-YOURCODE

View File

@@ -0,0 +1 @@
SELECT TRUE;

View File

@@ -1,117 +1,117 @@
name: ambassador-agent
version: 0.2.9
version: 0.2.10
default-extensions:
- NoImplicitPrelude
- BlockArguments
- ConstraintKinds
- DataKinds
- DeriveAnyClass
- DeriveFunctor
- DeriveGeneric
- DerivingStrategies
- EmptyCase
- FlexibleContexts
- FlexibleInstances
- GADTs
- GeneralizedNewtypeDeriving
- InstanceSigs
- KindSignatures
- LambdaCase
- MultiParamTypeClasses
- MultiWayIf
- NamedFieldPuns
- NumericUnderscores
- OverloadedStrings
- PolyKinds
- RankNTypes
- StandaloneDeriving
- StandaloneKindSignatures
- TupleSections
- TypeApplications
- TypeFamilies
- TypeOperators
- NoImplicitPrelude
- BlockArguments
- ConstraintKinds
- DataKinds
- DeriveAnyClass
- DeriveFunctor
- DeriveGeneric
- DerivingStrategies
- EmptyCase
- FlexibleContexts
- FlexibleInstances
- GADTs
- GeneralizedNewtypeDeriving
- InstanceSigs
- KindSignatures
- LambdaCase
- MultiParamTypeClasses
- MultiWayIf
- NamedFieldPuns
- NumericUnderscores
- OverloadedStrings
- PolyKinds
- RankNTypes
- StandaloneDeriving
- StandaloneKindSignatures
- TupleSections
- TypeApplications
- TypeFamilies
- TypeOperators
dependencies:
- base >=4.9.1.0 && <5
- aeson
- aeson-flatten
- attoparsec
- bytestring
- casing
- comonad
- conduit
- conduit-extra
- connection
- containers
- cryptonite
- cryptonite-conduit
- data-default
- directory
- errors
- exceptions
- exinst
- fast-logger
- file-embed
- filelock
- filepath
- fused-effects
- fused-effects-th
- git-embed
- http-api-data
- http-client
- http-client-tls
- http-conduit
- http-types
- interpolate
- iso8601-time
- json-rpc
- lens
- lens-aeson
- lifted-async
- lifted-base
- memory
- mime-types
- monad-control
- monad-logger
- network
- persistent
- persistent-sqlite
- persistent-template
- process
- process-extras
- protolude
- resourcet
- regex-compat # TODO: trim this dep
- shell-conduit
- singletons
- stm
- streaming
- streaming-bytestring
- streaming-conduit
- streaming-utils
- tar-conduit
- template-haskell
- text >=0.11 && <2.0
- time
- transformers
- transformers-base
- typed-process
- unix
- unliftio # TODO: trim this dep
- unliftio-core # TODO: trim this dep
- unordered-containers
- uuid
- wai
- wai-cors
- wai-extra
- warp
- yaml
- yesod
- yesod-auth
- yesod-core
- yesod-form
- yesod-persistent
- base >=4.9.1.0 && <5
- aeson
- aeson-flatten
- attoparsec
- bytestring
- casing
- comonad
- conduit
- conduit-extra
- connection
- containers
- cryptonite
- cryptonite-conduit
- data-default
- directory
- errors
- exceptions
- exinst
- fast-logger
- file-embed
- filelock
- filepath
- fused-effects
- fused-effects-th
- git-embed
- http-api-data
- http-client
- http-client-tls
- http-conduit
- http-types
- interpolate
- iso8601-time
- json-rpc
- lens
- lens-aeson
- lifted-async
- lifted-base
- memory
- mime-types
- monad-control
- monad-logger
- network
- persistent
- persistent-sqlite
- persistent-template
- process
- process-extras
- protolude
- resourcet
- regex-compat # TODO: trim this dep
- shell-conduit
- singletons
- stm
- streaming
- streaming-bytestring
- streaming-conduit
- streaming-utils
- tar-conduit
- template-haskell
- text >=0.11 && <2.0
- time
- transformers
- transformers-base
- typed-process
- unix
- unliftio # TODO: trim this dep
- unliftio-core # TODO: trim this dep
- unordered-containers
- uuid
- wai
- wai-cors
- wai-extra
- warp
- yaml
- yesod
- yesod-auth
- yesod-core
- yesod-form
- yesod-persistent
flags:
library-only:
@@ -129,56 +129,56 @@ flags:
library:
source-dirs: src
when:
- condition: (flag(dev)) || (flag(library-only))
then:
cpp-options: -DDEVELOPMENT
ghc-options:
- -Wall
- -Wunused-packages
- -fwarn-tabs
- -O0
- -fdefer-typed-holes
else:
ghc-options:
- -Wall
- -Wunused-packages
- -fwarn-tabs
- -O2
- -fdefer-typed-holes
- condition: (flag(disable-auth))
cpp-options: -DDISABLE_AUTH
- condition: (flag(dev)) || (flag(library-only))
then:
cpp-options: -DDEVELOPMENT
ghc-options:
- -Wall
- -Wunused-packages
- -fwarn-tabs
- -O0
- -fdefer-typed-holes
else:
ghc-options:
- -Wall
- -Wunused-packages
- -fwarn-tabs
- -O2
- -fdefer-typed-holes
- condition: (flag(disable-auth))
cpp-options: -DDISABLE_AUTH
tests:
agent-test:
source-dirs: test
main: Main.hs
ghc-options:
- -Wall
- -fdefer-typed-holes
- -Wall
- -fdefer-typed-holes
dependencies:
- ambassador-agent
- hspec >=2.0.0
- hspec-expectations
- hedgehog
- yesod-test
- random
- ambassador-agent
- hspec >=2.0.0
- hspec-expectations
- hedgehog
- yesod-test
- random
when:
- condition: false
other-modules: Paths_ambassador_agent
- condition: false
other-modules: Paths_ambassador_agent
executables:
agent:
source-dirs: app
main: main.hs
ghc-options:
- -Wall
- -threaded
- -rtsopts
- -with-rtsopts=-N
- -fdefer-typed-holes
- -Wall
- -threaded
- -rtsopts
- -with-rtsopts=-N
- -fdefer-typed-holes
dependencies:
- ambassador-agent
- ambassador-agent
when:
- buildable: false
condition: flag(library-only)
- condition: false
other-modules: Paths_ambassador_agent
- buildable: false
condition: flag(library-only)
- condition: false
other-modules: Paths_ambassador_agent

View File

@@ -97,12 +97,12 @@ parseKernelVersion = do
pure $ KernelVersion (Version (major', minor', patch', 0)) arch
synchronizer :: Synchronizer
synchronizer = sync_0_2_9
synchronizer = sync_0_2_10
{-# INLINE synchronizer #-}
sync_0_2_9 :: Synchronizer
sync_0_2_9 = Synchronizer
"0.2.9"
sync_0_2_10 :: Synchronizer
sync_0_2_10 = Synchronizer
"0.2.10"
[ syncCreateAgentTmp
, syncCreateSshDir
, syncRemoveAvahiSystemdDependency
@@ -125,6 +125,7 @@ sync_0_2_9 = Synchronizer
, syncConvertEcdsaCerts
, syncRestarterService
, syncInstallEject
, syncDropCertificateUniqueness
]
syncCreateAgentTmp :: SyncOp
@@ -595,6 +596,20 @@ syncUpgradeTor = SyncOp "Install Tor 0.3.5.12-1" check migrate False
shell "apt-get update"
shell "apt-get install -y tor=0.3.5.12-1"
syncDropCertificateUniqueness :: SyncOp
syncDropCertificateUniqueness = SyncOp "Eliminate OpenSSL unique_subject=yes" check migrate False
where
uni = "unique_subject = no\n"
check = do
base <- asks $ appFilesystemBase . appSettings
contentsRoot <- liftIO . BS.readFile . toS $ (rootCaDirectory <> "index.txt.attr") `relativeTo` base
contentsInt <- liftIO . BS.readFile . toS $ (intermediateCaDirectory <> "index.txt.attr") `relativeTo` base
pure $ uni /= contentsRoot || uni /= contentsInt
migrate = do
base <- asks $ appFilesystemBase . appSettings
liftIO $ BS.writeFile (toS $ (rootCaDirectory <> "index.txt.attr") `relativeTo` base) uni
liftIO $ BS.writeFile (toS $ (intermediateCaDirectory <> "index.txt.attr") `relativeTo` base) uni
failUpdate :: S9Error -> ExceptT Void (ReaderT AgentCtx IO) ()
failUpdate e = do
ref <- asks appIsUpdateFailed

2
appmgr/Cargo.lock generated
View File

@@ -41,7 +41,7 @@ checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1"
[[package]]
name = "appmgr"
version = "0.2.9"
version = "0.2.10"
dependencies = [
"async-trait",
"avahi-sys",

View File

@@ -2,7 +2,7 @@
authors = ["Aiden McClelland <me@drbonez.dev>"]
edition = "2018"
name = "appmgr"
version = "0.2.9"
version = "0.2.10"
[lib]
name = "appmgrlib"

View File

@@ -246,7 +246,14 @@ pub async fn write_lan_services(hidden_services: &ServicesMap) -> Result<(), Err
log::info!("Writing LAN certificates for {}", app_id);
let base_path = PersistencePath::from_ref("apps").join(&app_id);
let key_path = base_path.join("cert-local.key.pem").path();
if tokio::fs::metadata(&key_path).await.is_err() {
let conf_path = base_path.join("cert-local.csr.conf").path();
let req_path = base_path.join("cert-local.csr").path();
let cert_path = base_path.join("cert-local.crt.pem").path();
let fullchain_path = base_path.join("cert-local.fullchain.crt.pem");
if !fullchain_path.exists().await
|| tokio::fs::metadata(&key_path).await.is_err()
{
let mut fullchain_file = fullchain_path.write(None).await?;
tokio::process::Command::new("openssl")
.arg("ecparam")
.arg("-genkey")
@@ -257,9 +264,6 @@ pub async fn write_lan_services(hidden_services: &ServicesMap) -> Result<(), Err
.arg(&key_path)
.invoke("OpenSSL GenKey")
.await?;
}
let conf_path = base_path.join("cert-local.csr.conf").path();
if tokio::fs::metadata(&conf_path).await.is_err() {
tokio::fs::write(
&conf_path,
format!(
@@ -268,9 +272,6 @@ pub async fn write_lan_services(hidden_services: &ServicesMap) -> Result<(), Err
),
)
.await?;
}
let req_path = base_path.join("cert-local.csr").path();
if tokio::fs::metadata(&req_path).await.is_err() {
tokio::process::Command::new("openssl")
.arg("req")
.arg("-config")
@@ -287,9 +288,6 @@ pub async fn write_lan_services(hidden_services: &ServicesMap) -> Result<(), Err
.arg(&req_path)
.invoke("OpenSSL Req")
.await?;
}
let cert_path = base_path.join("cert-local.crt.pem").path();
if tokio::fs::metadata(&cert_path).await.is_err() {
tokio::process::Command::new("openssl")
.arg("ca")
.arg("-batch")
@@ -311,11 +309,7 @@ pub async fn write_lan_services(hidden_services: &ServicesMap) -> Result<(), Err
.arg(&cert_path)
.invoke("OpenSSL CA")
.await?;
}
let fullchain_path = base_path.join("cert-local.fullchain.crt.pem");
if !fullchain_path.exists().await {
log::info!("Writing fullchain to: {}", fullchain_path.path().display());
let mut fullchain_file = fullchain_path.write(None).await?;
tokio::io::copy(
&mut tokio::fs::File::open(&cert_path).await?,
&mut *fullchain_file,

View File

@@ -17,6 +17,7 @@ mod v0_1_4;
mod v0_1_5;
mod v0_2_0;
mod v0_2_1;
mod v0_2_10;
mod v0_2_2;
mod v0_2_3;
mod v0_2_4;
@@ -26,7 +27,7 @@ mod v0_2_7;
mod v0_2_8;
mod v0_2_9;
pub use v0_2_9::Version as Current;
pub use v0_2_10::Version as Current;
#[derive(serde::Serialize, serde::Deserialize)]
#[serde(untagged)]
@@ -48,6 +49,7 @@ enum Version {
V0_2_7(Wrapper<v0_2_7::Version>),
V0_2_8(Wrapper<v0_2_8::Version>),
V0_2_9(Wrapper<v0_2_9::Version>),
V0_2_10(Wrapper<v0_2_10::Version>),
Other(emver::Version),
}
@@ -159,6 +161,7 @@ pub async fn init() -> Result<(), failure::Error> {
Version::V0_2_7(v) => v.0.migrate_to(&Current::new()).await?,
Version::V0_2_8(v) => v.0.migrate_to(&Current::new()).await?,
Version::V0_2_9(v) => v.0.migrate_to(&Current::new()).await?,
Version::V0_2_10(v) => v.0.migrate_to(&Current::new()).await?,
Version::Other(_) => (),
// TODO find some way to automate this?
}
@@ -249,6 +252,7 @@ pub async fn self_update(requirement: emver::VersionRange) -> Result<(), Error>
Version::V0_2_7(v) => Current::new().migrate_to(&v.0).await?,
Version::V0_2_8(v) => Current::new().migrate_to(&v.0).await?,
Version::V0_2_9(v) => Current::new().migrate_to(&v.0).await?,
Version::V0_2_10(v) => Current::new().migrate_to(&v.0).await?,
Version::Other(_) => (),
// TODO find some way to automate this?
};

View File

@@ -0,0 +1,21 @@
use super::*;
const V0_2_10: emver::Version = emver::Version::new(0, 2, 10, 0);
pub struct Version;
#[async_trait]
impl VersionT for Version {
type Previous = v0_2_9::Version;
fn new() -> Self {
Version
}
fn semver(&self) -> &'static emver::Version {
&V0_2_10
}
async fn up(&self) -> Result<(), Error> {
Ok(())
}
async fn down(&self) -> Result<(), Error> {
Ok(())
}
}

View File

@@ -1,6 +1,6 @@
manifest-version: 0
app-id: start9-ambassador
app-version: 0.2.9
app-version: 0.2.10
uri-rewrites:
- =/api -> http://{{start9-ambassador}}:5959/authenticate
- /api/ -> http://{{start9-ambassador}}:5959/

2
ui/package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "embassy-ui",
"version": "0.2.9",
"version": "0.2.10",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "embassy-ui",
"version": "0.2.9",
"version": "0.2.10",
"description": "GUI for EmbassyOS",
"author": "Start9 Labs",
"homepage": "https://github.com/Start9Labs/embassy-ui",

View File

@@ -1,7 +1,7 @@
<ion-header>
<ion-toolbar>
<ion-title >
<ion-label style="font-size: 20px;" class="ion-text-wrap">Welcome to 0.2.9!</ion-label>
<ion-label style="font-size: 20px;" class="ion-text-wrap">Welcome to 0.2.10!</ion-label>
</ion-title>
</ion-toolbar>
</ion-header>
@@ -10,8 +10,12 @@
<div style="display: flex; flex-direction: column; justify-content: space-between; height: 100%">
<h2>Highlights</h2>
<p class="main-content">
0.2.9 introduces LAN support for services running on the Embassy. A service's LAN address (.local URL) can be accessed while connected to the same network.
0.2.10 introduces LAN support for services running on the Embassy. A service's LAN address (.local URL) can be accessed while connected to the same network.
This is useful for two reasons: (1) LAN connections are significantly faster than Tor, and (2) if the Tor network is experiencing connectivity issues, you will not be locked out of your services.
It also introduces support for services to define one-time actions that are exposed to the user. This
can be useful for password resets or other types of operations where doing it through the service UI would be
insecure or otherwise undesirable.
</p>
<div class="close-button">

View File

@@ -36,7 +36,7 @@
</ion-label>
</ion-item>
<ion-item>
<ion-button slot="start" fill="clear" color="primary">View Instructions</ion-button>
<ion-button slot="start" fill="clear" color="primary" (click)="viewInstructions()">View Instructions</ion-button>
</ion-item>
<ng-container *ngIf="!lanDisabled">

View File

@@ -12,8 +12,8 @@ import { ApiService } from 'src/app/services/api/api.service'
styleUrls: ['./lan.page.scss'],
})
export class LANPage {
torDocs = 'docs.privacy34kn4ez3y3nijweec6w4g54i3g54sdv7r5mr6soma3w4begyd.onion/user-manual/general/secure-lan'
lanDocs = 'docs.start9labs.com/user-manual/general/secure-lan'
torDocs = 'docs.privacy34kn4ez3y3nijweec6w4g54i3g54sdv7r5mr6soma3w4begyd.onion/user-manual/general/lan-setup'
lanDocs = 'docs.start9labs.com/user-manual/general/lan-setup'
lanAddress: string
fullDocumentationLink: string
@@ -60,6 +60,14 @@ export class LANPage {
})
}
viewInstructions (): void {
if (this.config.isConsulate) {
this.copyInstructions()
} else {
window.open(this.fullDocumentationLink, '_blank')
}
}
async copyLAN (): Promise <void> {
const message = await copyToClipboard(this.lanAddress).then(success => success ? 'copied to clipboard!' : 'failed to copy')
@@ -72,9 +80,9 @@ export class LANPage {
await toast.present()
}
async copyDocumentation (): Promise < void > {
async copyInstructions (): Promise < void > {
const message = await copyToClipboard(this.fullDocumentationLink).then(
success => success ? 'copied documentation link to clipboard!' : 'failed to copy',
success => success ? 'copied link to clipboard!' : 'failed to copy',
)
const toast = await this.toastCtrl.create({

View File

@@ -492,8 +492,8 @@ const mockApiNotifications: ReqRes.GetNotificationsRes = [
const mockApiServer: () => ReqRes.GetServerRes = () => ({
serverId: 'start9-mockxyzab',
name: 'Embassy:12345678',
versionInstalled: '0.2.9',
versionLatest: '0.2.10',
versionInstalled: '0.2.10',
versionLatest: '0.2.11',
status: ServerStatus.RUNNING,
alternativeRegistryUrl: 'beta-registry.start9labs.com',
welcomeAck: true,