Compare commits

..

9 Commits

Author SHA1 Message Date
Daniel García
ce9d93003c Merge pull request #2650 from BlackDex/mitigate-mobile-client-uploads
Mitigate attachment/send upload issues
2022-07-27 17:39:07 +02:00
BlackDex
abfa868423 Mitigate attachment/send upload issues
This PR attends to mitigate (not fix) #2644.
There seems to be an issue when uploading files either as attachment or
via send via the mobile (Android) client.

The binary data gets transfered correctly to Vaultwarden (Checked via
Wireshark), but the data is not parsed correctly for some reason.

Since the parsing is not done by Vaultwarden it self, i think we should
at least try to prevent saving the data and letting users think all
fine.

Further investigation is needed to actually fix this issue.
This is just a quick patch.
2022-07-27 17:12:04 +02:00
Daniel García
331f6c08fe Merge branch 'BlackDex-update-github-actions' into main 2022-07-22 16:00:45 +02:00
Daniel García
c0efd3d419 Merge branch 'update-github-actions' of https://github.com/BlackDex/vaultwarden into BlackDex-update-github-actions 2022-07-22 16:00:40 +02:00
Daniel García
1385d75972 Merge branch 'BlackDex-fix-2622-persistent-volume-check' into main 2022-07-22 16:00:28 +02:00
BlackDex
9a787dd105 Fix persistent folder check within containers
The previous persistent folder check worked by checking if a file
exists. If you used a bind-mount, then this file is not there. But when
using a docker/podman volume those files are copied, and caused the
container to not start.

This change checks the `/proc/self/mountinfo` for a specific patern to
see if the data folder is persistent or not.

Fixes #2622
2022-07-20 13:29:39 +02:00
BlackDex
0dcc435bb4 Update build workflow for CI
Because we want to support MSRV, we also need to run a CI for this.
This PR adds checks for the MSRV and rust-toolchain defined versions.

It will also run all cargo test, clippy and fmt checks no matter the outcome of the previous job.
This will help when there are multiple issues, like clippy errors and formatting.
Previously it would show only the first failed check and stopped.

It will also output a nice step summary with some details on which checks have failed.
Or it will output a success message.
2022-07-19 23:17:49 +02:00
Daniel García
f1a67663d1 Merge pull request #2624 from BlackDex/fix-2623-csp-icon-redirect
Fix issue with CSP and icon redirects
2022-07-18 00:40:59 +02:00
BlackDex
0f95bdc9bb Fix issue with CSP and icon redirects
When using anything else but the `internal` icon service it would
trigger an CSP block because the redirects were not allowed.

This PR fixes #2623 by dynamically adding the needed CSP strings.
This should also work with custom services.

For Google i needed to add an extra check because that does a redirect
it self to there gstatic.com domain.
2022-07-17 16:21:03 +02:00
24 changed files with 220 additions and 246 deletions

View File

@@ -20,6 +20,7 @@ on:
jobs:
build:
runs-on: ubuntu-20.04
# Make warnings errors, this is to prevent warnings slipping through.
# This is done globally to prevent rebuilds when the RUSTFLAGS env variable changes.
env:
@@ -28,118 +29,169 @@ jobs:
fail-fast: false
matrix:
channel:
- stable
target-triple:
- x86_64-unknown-linux-gnu
include:
- target-triple: x86_64-unknown-linux-gnu
host-triple: x86_64-unknown-linux-gnu
features: [sqlite,mysql,postgresql,enable_mimalloc] # Remember to update the `cargo test` to match the amount of features
channel: stable
os: ubuntu-20.04
ext: ""
- "rust-toolchain" # The version defined in rust-toolchain
- "1.59.0" # The supported MSRV
name: Build and Test ${{ matrix.channel }}
name: Building ${{ matrix.channel }}-${{ matrix.target-triple }}
runs-on: ${{ matrix.os }}
steps:
# Checkout the repo
- name: Checkout
- name: "Checkout"
uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3.0.2
# End Checkout the repo
# Install musl-tools when needed
- name: Install musl tools
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends musl-dev musl-tools cmake
if: matrix.target-triple == 'x86_64-unknown-linux-musl'
# End Install musl-tools when needed
# Install dependencies
- name: Install dependencies Ubuntu
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends openssl sqlite build-essential libmariadb-dev-compat libpq-dev libssl-dev pkgconf
if: startsWith( matrix.os, 'ubuntu' )
- name: "Install dependencies Ubuntu"
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends openssl sqlite build-essential libmariadb-dev-compat libpq-dev libssl-dev pkg-config
# End Install dependencies
# Enable Rust Caching
- uses: Swatinem/rust-cache@842ef286fff290e445b90b4002cc9807c3669641 # v1.3.0
# End Enable Rust Caching
# Uses the rust-toolchain file to determine version
- name: 'Install ${{ matrix.channel }}-${{ matrix.host-triple }} for target: ${{ matrix.target-triple }}'
- name: "Install rust-toolchain version"
uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f # v1.0.6
if: ${{ matrix.channel == 'rust-toolchain' }}
with:
profile: minimal
target: ${{ matrix.target-triple }}
components: clippy, rustfmt
# End Uses the rust-toolchain file to determine version
# Install the MSRV channel to be used
- name: "Install MSRV version"
uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f # v1.0.6
if: ${{ matrix.channel != 'rust-toolchain' }}
with:
profile: minimal
override: true
toolchain: ${{ matrix.channel }}
# End Install the MSRV channel to be used
# Enable Rust Caching
- uses: Swatinem/rust-cache@6720f05bc48b77f96918929a9019fb2203ff71f8 # v2.0.0
# End Enable Rust Caching
# Show environment
- name: "Show environment"
run: |
rustc -vV
cargo -vV
# End Show environment
# Run cargo tests (In release mode to speed up future builds)
# First test all features together, afterwards test them separately.
- name: "`cargo test --release --features ${{ join(matrix.features, ',') }} --target ${{ matrix.target-triple }}`"
- name: "test features: sqlite,mysql,postgresql,enable_mimalloc"
id: test_sqlite_mysql_postgresql_mimalloc
uses: actions-rs/cargo@844f36862e911db73fe0815f00a4a2602c279505 # v1.0.3
if: $${{ always() }}
with:
command: test
args: --release --features ${{ join(matrix.features, ',') }} --target ${{ matrix.target-triple }}
# Test single features
# 0: sqlite
- name: "`cargo test --release --features ${{ matrix.features[0] }} --target ${{ matrix.target-triple }}`"
args: --release --features sqlite,mysql,postgresql,enable_mimalloc
- name: "test features: sqlite,mysql,postgresql"
id: test_sqlite_mysql_postgresql
uses: actions-rs/cargo@844f36862e911db73fe0815f00a4a2602c279505 # v1.0.3
if: $${{ always() }}
with:
command: test
args: --release --features ${{ matrix.features[0] }} --target ${{ matrix.target-triple }}
if: ${{ matrix.features[0] != '' }}
# 1: mysql
- name: "`cargo test --release --features ${{ matrix.features[1] }} --target ${{ matrix.target-triple }}`"
args: --release --features sqlite,mysql,postgresql
- name: "test features: sqlite"
id: test_sqlite
uses: actions-rs/cargo@844f36862e911db73fe0815f00a4a2602c279505 # v1.0.3
if: $${{ always() }}
with:
command: test
args: --release --features ${{ matrix.features[1] }} --target ${{ matrix.target-triple }}
if: ${{ matrix.features[1] != '' }}
# 2: postgresql
- name: "`cargo test --release --features ${{ matrix.features[2] }} --target ${{ matrix.target-triple }}`"
args: --release --features sqlite
- name: "test features: mysql"
id: test_mysql
uses: actions-rs/cargo@844f36862e911db73fe0815f00a4a2602c279505 # v1.0.3
if: $${{ always() }}
with:
command: test
args: --release --features ${{ matrix.features[2] }} --target ${{ matrix.target-triple }}
if: ${{ matrix.features[2] != '' }}
args: --release --features mysql
- name: "test features: postgresql"
id: test_postgresql
uses: actions-rs/cargo@844f36862e911db73fe0815f00a4a2602c279505 # v1.0.3
if: $${{ always() }}
with:
command: test
args: --release --features postgresql
# End Run cargo tests
# Run cargo clippy, and fail on warnings (In release mode to speed up future builds)
- name: "`cargo clippy --release --features ${{ join(matrix.features, ',') }} --target ${{ matrix.target-triple }}`"
- name: "clippy features: sqlite,mysql,postgresql,enable_mimalloc"
id: clippy
uses: actions-rs/cargo@844f36862e911db73fe0815f00a4a2602c279505 # v1.0.3
if: ${{ always() && matrix.channel == 'rust-toolchain' }}
with:
command: clippy
args: --release --features ${{ join(matrix.features, ',') }} --target ${{ matrix.target-triple }} -- -D warnings
args: --release --features sqlite,mysql,postgresql,enable_mimalloc -- -D warnings
# End Run cargo clippy
# Run cargo fmt
- name: '`cargo fmt`'
# Run cargo fmt (Only run on rust-toolchain defined version)
- name: "check formatting"
id: formatting
uses: actions-rs/cargo@844f36862e911db73fe0815f00a4a2602c279505 # v1.0.3
if: ${{ always() && matrix.channel == 'rust-toolchain' }}
with:
command: fmt
args: --all -- --check
# End Run cargo fmt
# Build the binary
- name: "`cargo build --release --features ${{ join(matrix.features, ',') }} --target ${{ matrix.target-triple }}`"
# Check for any previous failures, if there are stop, else continue.
# This is useful so all test/clippy/fmt actions are done, and they can all be addressed
- name: "Some checks failed"
if: ${{ failure() }}
run: |
echo "### :x: Checks Failed!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "|Job|Status|" >> $GITHUB_STEP_SUMMARY
echo "|---|------|" >> $GITHUB_STEP_SUMMARY
echo "|test (sqlite,mysql,postgresql,enable_mimalloc)|${{ steps.test_sqlite_mysql_postgresql_mimalloc.outcome }}|" >> $GITHUB_STEP_SUMMARY
echo "|test (sqlite,mysql,postgresql)|${{ steps.test_sqlite_mysql_postgresql.outcome }}|" >> $GITHUB_STEP_SUMMARY
echo "|test (sqlite)|${{ steps.test_sqlite.outcome }}|" >> $GITHUB_STEP_SUMMARY
echo "|test (mysql)|${{ steps.test_mysql.outcome }}|" >> $GITHUB_STEP_SUMMARY
echo "|test (postgresql)|${{ steps.test_postgresql.outcome }}|" >> $GITHUB_STEP_SUMMARY
echo "|clippy (sqlite,mysql,postgresql,enable_mimalloc)|${{ steps.clippy.outcome }}|" >> $GITHUB_STEP_SUMMARY
echo "|fmt|${{ steps.formatting.outcome }}|" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Please check the failed jobs and fix where needed." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
exit 1
# Check for any previous failures, if there are stop, else continue.
# This is useful so all test/clippy/fmt actions are done, and they can all be addressed
- name: "All checks passed"
if: ${{ success() }}
run: |
echo "### :tada: Checks Passed!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Build the binary to upload to the artifacts
- name: "build features: sqlite,mysql,postgresql"
uses: actions-rs/cargo@844f36862e911db73fe0815f00a4a2602c279505 # v1.0.3
if: ${{ matrix.channel == 'rust-toolchain' }}
with:
command: build
args: --release --features ${{ join(matrix.features, ',') }} --target ${{ matrix.target-triple }}
args: --release --features sqlite,mysql,postgresql
# End Build the binary
# Upload artifact to Github Actions
- name: Upload artifact
- name: "Upload artifact"
uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
if: ${{ matrix.channel == 'rust-toolchain' }}
with:
name: vaultwarden-${{ matrix.target-triple }}${{ matrix.ext }}
path: target/${{ matrix.target-triple }}/release/vaultwarden${{ matrix.ext }}
name: vaultwarden
path: target/${{ matrix.target-triple }}/release/vaultwarden
# End Upload artifact to Github Actions

View File

@@ -181,14 +181,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN {{ mount_rust_cache -}} cargo build --features ${DB} --release{{ package_arch_target_param }}
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -250,7 +242,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
{% if package_arch_target is defined %}
COPY --from=build /app/target/{{ package_arch_target }}/release/vaultwarden .
{% else %}

View File

@@ -84,14 +84,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN cargo build --features ${DB} --release
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -124,7 +116,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -78,14 +78,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN cargo build --features ${DB} --release --target=x86_64-unknown-linux-musl
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -116,7 +108,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/x86_64-unknown-linux-musl/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -84,14 +84,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -124,7 +116,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -78,14 +78,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=x86_64-unknown-linux-musl
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -116,7 +108,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/x86_64-unknown-linux-musl/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -104,14 +104,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN cargo build --features ${DB} --release --target=aarch64-unknown-linux-gnu
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -148,7 +140,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/aarch64-unknown-linux-gnu/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -78,14 +78,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN cargo build --features ${DB} --release --target=aarch64-unknown-linux-musl
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -120,7 +112,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/aarch64-unknown-linux-musl/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -104,14 +104,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=aarch64-unknown-linux-gnu
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -148,7 +140,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/aarch64-unknown-linux-gnu/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -78,14 +78,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=aarch64-unknown-linux-musl
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -120,7 +112,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/aarch64-unknown-linux-musl/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -104,14 +104,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN cargo build --features ${DB} --release --target=arm-unknown-linux-gnueabi
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -153,7 +145,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/arm-unknown-linux-gnueabi/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -80,14 +80,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN cargo build --features ${DB} --release --target=arm-unknown-linux-musleabi
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -122,7 +114,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/arm-unknown-linux-musleabi/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -104,14 +104,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=arm-unknown-linux-gnueabi
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -153,7 +145,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/arm-unknown-linux-gnueabi/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -80,14 +80,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=arm-unknown-linux-musleabi
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -122,7 +114,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/arm-unknown-linux-musleabi/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -104,14 +104,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN cargo build --features ${DB} --release --target=armv7-unknown-linux-gnueabihf
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -148,7 +140,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/armv7-unknown-linux-gnueabihf/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -78,14 +78,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN cargo build --features ${DB} --release --target=armv7-unknown-linux-musleabihf
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -120,7 +112,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/armv7-unknown-linux-musleabihf/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -104,14 +104,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=armv7-unknown-linux-gnueabihf
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -148,7 +140,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/armv7-unknown-linux-gnueabihf/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -78,14 +78,6 @@ RUN touch src/main.rs
# hadolint ignore=DL3059
RUN --mount=type=cache,target=/root/.cargo/git --mount=type=cache,target=/root/.cargo/registry cargo build --features ${DB} --release --target=armv7-unknown-linux-musleabihf
# Create a special empty file which we check within the application.
# If this file exists, then we exit Vaultwarden to prevent data loss when someone forgets to use volumes.
# If you really really want to use volatile storage you can set the env `I_REALLY_WANT_VOLATILE_STORAGE=true`
# This file should disappear if a volume is mounted on-top of this using a docker volume.
# We run this in the build image and copy it over, because the runtime image could be missing some executables.
# hadolint ignore=DL3059
RUN touch /vaultwarden_docker_persistent_volume_check
######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
@@ -120,7 +112,6 @@ EXPOSE 3012
# and the binary from the "build" stage to the current stage
WORKDIR /
COPY --from=vault /web-vault ./web-vault
COPY --from=build /vaultwarden_docker_persistent_volume_check /data/vaultwarden_docker_persistent_volume_check
COPY --from=build /app/target/armv7-unknown-linux-musleabihf/release/vaultwarden .
COPY docker/healthcheck.sh /healthcheck.sh

View File

@@ -947,6 +947,17 @@ async fn save_attachment(
let mut data = data.into_inner();
// There seems to be a bug somewhere regarding uploading attachments using the Android Client (Maybe iOS too?)
// See: https://github.com/dani-garcia/vaultwarden/issues/2644
// Since all other clients seem to match TempFile::File and not TempFile::Buffered lets catch this and return an error for now.
// We need to figure out how to solve this, but for now it's better to not accept these attachments since they will be broken.
if let TempFile::Buffered {
content: _,
} = &data.data
{
err!("Error reading attachment data. Please try an other client.");
}
if let Some(size_limit) = size_limit {
if data.data.len() > size_limit {
err!("Attachment storage limit exceeded with this file");

View File

@@ -216,6 +216,17 @@ async fn post_send_file(data: Form<UploadData<'_>>, headers: Headers, conn: DbCo
err!("Send content is not a file");
}
// There seems to be a bug somewhere regarding uploading attachments using the Android Client (Maybe iOS too?)
// See: https://github.com/dani-garcia/vaultwarden/issues/2644
// Since all other clients seem to match TempFile::File and not TempFile::Buffered lets catch this and return an error for now.
// We need to figure out how to solve this, but for now it's better to not accept these attachments since they will be broken.
if let TempFile::Buffered {
content: _,
} = &data
{
err!("Error reading send file data. Please try an other client.");
}
let size = data.len();
if size > size_limit {
err!("Attachment storage limit exceeded with this file");

View File

@@ -30,10 +30,7 @@ use crate::{
pub fn routes() -> Vec<Route> {
match CONFIG.icon_service().as_str() {
"internal" => routes![icon_internal],
"bitwarden" => routes![icon_bitwarden],
"duckduckgo" => routes![icon_duckduckgo],
"google" => routes![icon_google],
_ => routes![icon_custom],
_ => routes![icon_external],
}
}
@@ -100,23 +97,8 @@ async fn icon_redirect(domain: &str, template: &str) -> Option<Redirect> {
}
#[get("/<domain>/icon.png")]
async fn icon_custom(domain: String) -> Option<Redirect> {
icon_redirect(&domain, &CONFIG.icon_service()).await
}
#[get("/<domain>/icon.png")]
async fn icon_bitwarden(domain: String) -> Option<Redirect> {
icon_redirect(&domain, "https://icons.bitwarden.net/{}/icon.png").await
}
#[get("/<domain>/icon.png")]
async fn icon_duckduckgo(domain: String) -> Option<Redirect> {
icon_redirect(&domain, "https://icons.duckduckgo.com/ip3/{}.ico").await
}
#[get("/<domain>/icon.png")]
async fn icon_google(domain: String) -> Option<Redirect> {
icon_redirect(&domain, "https://www.google.com/s2/favicons?domain={}&sz=32").await
async fn icon_external(domain: String) -> Option<Redirect> {
icon_redirect(&domain, &CONFIG._icon_service_url()).await
}
#[get("/<domain>/icon.png")]

View File

@@ -463,6 +463,10 @@ make_config! {
/// service is set, an icon request to Vaultwarden will return an HTTP redirect to the
/// corresponding icon at the external service.
icon_service: String, false, def, "internal".to_string();
/// Internal
_icon_service_url: String, false, gen, |c| generate_icon_service_url(&c.icon_service);
/// Internal
_icon_service_csp: String, false, gen, |c| generate_icon_service_csp(&c.icon_service, &c._icon_service_url);
/// Icon redirect code |> The HTTP status code to use for redirects to an external icon service.
/// The supported codes are 301 (legacy permanent), 302 (legacy temporary), 307 (temporary), and 308 (permanent).
/// Temporary redirects are useful while testing different icon services, but once a service
@@ -748,6 +752,34 @@ fn extract_url_path(url: &str) -> String {
}
}
/// Generate the correct URL for the icon service.
/// This will be used within icons.rs to call the external icon service.
fn generate_icon_service_url(icon_service: &str) -> String {
match icon_service {
"internal" => "".to_string(),
"bitwarden" => "https://icons.bitwarden.net/{}/icon.png".to_string(),
"duckduckgo" => "https://icons.duckduckgo.com/ip3/{}.ico".to_string(),
"google" => "https://www.google.com/s2/favicons?domain={}&sz=32".to_string(),
_ => icon_service.to_string(),
}
}
/// Generate the CSP string needed to allow redirected icon fetching
fn generate_icon_service_csp(icon_service: &str, icon_service_url: &str) -> String {
// We split on the first '{', since that is the variable delimiter for an icon service URL.
// Everything up until the first '{' should be fixed and can be used as an CSP string.
let csp_string = match icon_service_url.split_once('{') {
Some((c, _)) => c.to_string(),
None => "".to_string(),
};
// Because Google does a second redirect to there gstatic.com domain, we need to add an extra csp string.
match icon_service {
"google" => csp_string + " https://*.gstatic.com/favicon",
_ => csp_string,
}
}
/// Convert the old SMTP_SSL and SMTP_EXPLICIT_TLS options
fn smtp_convert_deprecated_ssl_options(smtp_ssl: Option<bool>, smtp_explicit_tls: Option<bool>) -> String {
if smtp_explicit_tls.is_some() || smtp_ssl.is_some() {

View File

@@ -61,6 +61,11 @@ use std::{
thread,
};
use tokio::{
fs::File,
io::{AsyncBufReadExt, BufReader},
};
#[macro_use]
mod error;
mod api;
@@ -89,7 +94,7 @@ async fn main() -> Result<(), Error> {
let extra_debug = matches!(level, LF::Trace | LF::Debug);
check_data_folder();
check_data_folder().await;
check_rsa_keys().unwrap_or_else(|_| {
error!("Error creating keys, exiting...");
exit(1);
@@ -286,7 +291,7 @@ fn create_dir(path: &str, description: &str) {
create_dir_all(path).expect(&err_msg);
}
fn check_data_folder() {
async fn check_data_folder() {
let data_folder = &CONFIG.data_folder();
let path = Path::new(data_folder);
if !path.exists() {
@@ -299,9 +304,10 @@ fn check_data_folder() {
exit(1);
}
let persistent_volume_check_file = format!("{data_folder}/vaultwarden_docker_persistent_volume_check");
let check_file = Path::new(&persistent_volume_check_file);
if check_file.exists() && std::env::var("I_REALLY_WANT_VOLATILE_STORAGE").is_err() {
if is_running_in_docker()
&& std::env::var("I_REALLY_WANT_VOLATILE_STORAGE").is_err()
&& !docker_data_folder_is_persistent(data_folder).await
{
error!(
"No persistent volume!\n\
########################################################################################\n\
@@ -314,6 +320,38 @@ fn check_data_folder() {
}
}
/// Detect when using Docker or Podman the DATA_FOLDER is either a bind-mount or a volume created manually.
/// If not created manually, then the data will not be persistent.
/// A none persistent volume in either Docker or Podman is represented by a 64 alphanumerical string.
/// If we detect this string, we will alert about not having a persistent self defined volume.
/// This probably means that someone forgot to add `-v /path/to/vaultwarden_data/:/data`
async fn docker_data_folder_is_persistent(data_folder: &str) -> bool {
if let Ok(mountinfo) = File::open("/proc/self/mountinfo").await {
// Since there can only be one mountpoint to the DATA_FOLDER
// We do a basic check for this mountpoint surrounded by a space.
let data_folder_match = if data_folder.starts_with('/') {
format!(" {data_folder} ")
} else {
format!(" /{data_folder} ")
};
let mut lines = BufReader::new(mountinfo).lines();
while let Some(line) = lines.next_line().await.unwrap_or_default() {
// Only execute a regex check if we find the base match
if line.contains(&data_folder_match) {
let re = regex::Regex::new(r"/volumes/[a-z0-9]{64}/_data /").unwrap();
if re.is_match(&line) {
return false;
}
// If we did found a match for the mountpoint, but not the regex, then still stop searching.
break;
}
}
}
// In all other cases, just assume a true.
// This is just an informative check to try and prevent data loss.
true
}
fn check_rsa_keys() -> Result<(), crate::error::Error> {
// If the RSA keys don't exist, try to create them
let priv_path = CONFIG.private_rsa_key();

View File

@@ -38,18 +38,18 @@ impl Fairing for AppHeaders {
let req_uri_path = req.uri().path();
// Check if we are requesting an admin page, if so, allow unsafe-inline for scripts.
// TODO: In the future maybe we need to see if we can generate a sha256 hash or have no scripts inline at all.
let admin_path = format!("{}/admin", CONFIG.domain_path());
let mut script_src = "";
if req_uri_path.starts_with(admin_path.as_str()) {
script_src = " 'unsafe-inline'";
}
// Do not send the Content-Security-Policy (CSP) Header and X-Frame-Options for the *-connector.html files.
// This can cause issues when some MFA requests needs to open a popup or page within the clients like WebAuthn, or Duo.
// This is the same behaviour as upstream Bitwarden.
if !req_uri_path.ends_with("connector.html") {
// Check if we are requesting an admin page, if so, allow unsafe-inline for scripts.
// TODO: In the future maybe we need to see if we can generate a sha256 hash or have no scripts inline at all.
let admin_path = format!("{}/admin", CONFIG.domain_path());
let mut script_src = "";
if req_uri_path.starts_with(admin_path.as_str()) {
script_src = " 'unsafe-inline'";
}
// # Frame Ancestors:
// Chrome Web Store: https://chrome.google.com/webstore/detail/bitwarden-free-password-m/nngceckbapebfimnlniiiahkandclblb
// Edge Add-ons: https://microsoftedge.microsoft.com/addons/detail/bitwarden-free-password/jbkfoedolllekgbhcbcoahefnbanhhlh?hl=en-US
@@ -65,13 +65,14 @@ impl Fairing for AppHeaders {
"default-src 'self'; \
script-src 'self'{script_src}; \
style-src 'self' 'unsafe-inline'; \
img-src 'self' data: https://haveibeenpwned.com/ https://www.gravatar.com; \
img-src 'self' data: https://haveibeenpwned.com/ https://www.gravatar.com {icon_service_csp}; \
child-src 'self' https://*.duosecurity.com https://*.duofederal.com; \
frame-src 'self' https://*.duosecurity.com https://*.duofederal.com; \
connect-src 'self' https://api.pwnedpasswords.com/range/ https://2fa.directory/api/ https://app.simplelogin.io/api/ https://app.anonaddy.com/api/ https://relay.firefox.com/api/; \
object-src 'self' blob:; \
frame-ancestors 'self' chrome-extension://nngceckbapebfimnlniiiahkandclblb chrome-extension://jbkfoedolllekgbhcbcoahefnbanhhlh moz-extension://* {};",
CONFIG.allowed_iframe_ancestors()
frame-ancestors 'self' chrome-extension://nngceckbapebfimnlniiiahkandclblb chrome-extension://jbkfoedolllekgbhcbcoahefnbanhhlh moz-extension://* {allowed_iframe_ancestors};",
icon_service_csp=CONFIG._icon_service_csp(),
allowed_iframe_ancestors=CONFIG.allowed_iframe_ancestors()
);
res.set_raw_header("Content-Security-Policy", csp);
res.set_raw_header("X-Frame-Options", "SAMEORIGIN");