Checksums - Allow anyone to confirm source and delivered code (#467)
* Checksums - Allow anyone to confirm source and delivered code For now this only has the initial step on making CSP stricter so we can use it to parse through used files. Very much WIP for now, but now it should just be a matter of writing up concise docs on how to go through the process, after generating and publishing the checksums via CI as well. Related to #331 * Lint! * Add more instructions and CI to build checksums. * Fix typo and lint * Remove CSP package dependency, build it manually. Update commands in docs, fix web extension release. * Tweak docs and webpack. CI still isn't producing a matching checksum, though. * Tweak docs for web checksums, add debugging in the checksum action, make it faster, temporarily. * Fix web checksum, add checksums and instructions for everything else Closes #467 * Fix tauri release + macos sha256sum * Remove .app checksum, since it's a directory and checksum'ing the .tar.gz seems strange. * Properly indent + fix sha256sum results (and windows line endings problem) * Include PWA for release, add instructions to change filenames when checksum fails. * Include _everything_ in the CSP now, and tweak the verification script and checksum build to also include everything, now. Still requires changes in the way to verify a published web app, where I'll have to write a script to parse through the whole CSP now. * Add TypeScript (Deno) script to parse through CSP and download matched files. Also update docs. * Tweak web checksum examples. * Remove content hashes from font files. * Try sorting files before adding to CSP, to enforce consistency.
This commit is contained in:
parent
ea05def083
commit
8e2036f297
|
@ -81,7 +81,7 @@ jobs:
|
|||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: "v${{ env.PL_VENDOR_VERSION }}"
|
||||
file: packages/extension/dist/web-ext-artifacts/padloc-${{ env.PL_VENDOR_VERSION }}.${{ env.RELEASE_BUILD }}-an+fx.xpi
|
||||
file: packages/extension/dist/web-ext-artifacts/padloc-${{ env.PL_VENDOR_VERSION }}.${{ env.RELEASE_BUILD }}.xpi
|
||||
asset_name: padloc-web-extension-${{ env.PL_VENDOR_VERSION }}.${{ env.RELEASE_BUILD }}.xpi
|
||||
prerelease: true
|
||||
- name: Pack for Chrome Extension
|
||||
|
@ -112,6 +112,30 @@ jobs:
|
|||
file: packages/extension/padloc-signed.crx
|
||||
asset_name: padloc-web-extension-${{ env.PL_VENDOR_VERSION }}.${{ env.RELEASE_BUILD }}.crx
|
||||
prerelease: true
|
||||
- name: Generate checksum (xpi)
|
||||
run: |
|
||||
cd packages/extension/dist/web-ext-artifacts
|
||||
sha256sum padloc*.xpi > sha256sum-xpi.txt
|
||||
- name: Upload checksum (xpi)
|
||||
uses: svenstaro/upload-release-action@2.2.1
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: "v${{ env.PL_VENDOR_VERSION }}"
|
||||
file: packages/extension/dist/web-ext-artifacts/sha256sum-xpi.txt
|
||||
asset_name: sha256sum-xpi.txt
|
||||
prerelease: true
|
||||
- name: Generate checksum (crx)
|
||||
run: |
|
||||
cd packages/extension
|
||||
sha256sum padloc-signed.crx > sha256sum-crx.txt
|
||||
- name: Upload checksum (crx)
|
||||
uses: svenstaro/upload-release-action@2.2.1
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: "v${{ env.PL_VENDOR_VERSION }}"
|
||||
file: packages/extension/sha256sum-crx.txt
|
||||
asset_name: sha256sum-crx.txt
|
||||
prerelease: true
|
||||
|
||||
release_tauri:
|
||||
name: "Release Tauri apps"
|
||||
|
@ -143,11 +167,15 @@ jobs:
|
|||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y webkit2gtk-4.0
|
||||
- name: Install coreutils
|
||||
if: matrix.platform == 'macos-latest'
|
||||
run: |
|
||||
brew install coreutils
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
npm i -g npm@8.2.0
|
||||
npm ci
|
||||
- uses: tauri-apps/tauri-action@v0.2.0
|
||||
- uses: tauri-apps/tauri-action@v0.3.1
|
||||
env:
|
||||
PL_SERVER_URL: ${{ secrets.PL_SERVER_URL }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
@ -162,6 +190,62 @@ jobs:
|
|||
with:
|
||||
releaseId: ${{ env.RELEASE_ID }}
|
||||
projectPath: packages/tauri
|
||||
- name: Generate checksum (AppImage)
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
run: |
|
||||
cd packages/tauri/src-tauri/target/release/bundle/appimage
|
||||
sha256sum padloc*.AppImage > sha256sum-appimage.txt
|
||||
- name: Upload checksum (AppImage)
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
uses: svenstaro/upload-release-action@2.2.1
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: "v${{ env.PL_VENDOR_VERSION }}"
|
||||
file: packages/tauri/src-tauri/target/release/bundle/appimage/sha256sum-appimage.txt
|
||||
asset_name: sha256sum-tauri-appimage.txt
|
||||
prerelease: true
|
||||
- name: Generate checksum (deb)
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
run: |
|
||||
cd packages/tauri/src-tauri/target/release/bundle/deb
|
||||
sha256sum *.deb > sha256sum-deb.txt
|
||||
- name: Upload checksum (deb)
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
uses: svenstaro/upload-release-action@2.2.1
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: "v${{ env.PL_VENDOR_VERSION }}"
|
||||
file: packages/tauri/src-tauri/target/release/bundle/deb/sha256sum-deb.txt
|
||||
asset_name: sha256sum-tauri-deb.txt
|
||||
prerelease: true
|
||||
- name: Generate checksum (dmg)
|
||||
if: matrix.platform == 'macos-latest'
|
||||
run: |
|
||||
cd packages/tauri/src-tauri/target/release/bundle/dmg
|
||||
sha256sum *.dmg > sha256sum-dmg.txt
|
||||
- name: Upload checksum (dmg)
|
||||
if: matrix.platform == 'macos-latest'
|
||||
uses: svenstaro/upload-release-action@2.2.1
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: "v${{ env.PL_VENDOR_VERSION }}"
|
||||
file: packages/tauri/src-tauri/target/release/bundle/dmg/sha256sum-dmg.txt
|
||||
asset_name: sha256sum-tauri-dmg.txt
|
||||
prerelease: true
|
||||
- name: Generate checksum (msi)
|
||||
if: matrix.platform == 'windows-latest'
|
||||
run: |
|
||||
cd packages/tauri/src-tauri/target/release/bundle/msi
|
||||
sha256sum *.msi > sha256sum-msi.txt
|
||||
- name: Upload checksum (msi)
|
||||
if: matrix.platform == 'windows-latest'
|
||||
uses: svenstaro/upload-release-action@2.2.1
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: "v${{ env.PL_VENDOR_VERSION }}"
|
||||
file: packages/tauri/src-tauri/target/release/bundle/msi/sha256sum-msi.txt
|
||||
asset_name: sha256sum-tauri-msi.txt
|
||||
prerelease: true
|
||||
|
||||
release_electron:
|
||||
name: "Release Electron apps"
|
||||
|
@ -182,6 +266,10 @@ jobs:
|
|||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
- name: Install coreutils
|
||||
if: matrix.platform == 'macos-latest'
|
||||
run: |
|
||||
brew install coreutils
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
npm i -g npm@8.2.0
|
||||
|
@ -197,6 +285,48 @@ jobs:
|
|||
PL_MACOS_NOTARIZE_PASSWORD: ${{ secrets.PL_MACOS_NOTARIZE_PASSWORD }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
EP_PRE_RELEASE: true
|
||||
- name: Generate checksum (AppImage)
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
run: |
|
||||
cd packages/electron/dist
|
||||
sha256sum *.AppImage > sha256sum-appimage.txt
|
||||
- name: Upload checksum (AppImage)
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
uses: svenstaro/upload-release-action@2.2.1
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: "v${{ env.PL_VENDOR_VERSION }}"
|
||||
file: packages/electron/dist/sha256sum-appimage.txt
|
||||
asset_name: sha256sum-electron-appimage.txt
|
||||
prerelease: true
|
||||
- name: Generate checksum (dmg)
|
||||
if: matrix.platform == 'macos-latest'
|
||||
run: |
|
||||
cd packages/electron/dist
|
||||
sha256sum *.dmg > sha256sum-dmg.txt
|
||||
- name: Upload checksum (dmg)
|
||||
if: matrix.platform == 'macos-latest'
|
||||
uses: svenstaro/upload-release-action@2.2.1
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: "v${{ env.PL_VENDOR_VERSION }}"
|
||||
file: packages/electron/dist/sha256sum-dmg.txt
|
||||
asset_name: sha256sum-electron-dmg.txt
|
||||
prerelease: true
|
||||
- name: Generate checksum (exe)
|
||||
if: matrix.platform == 'windows-latest'
|
||||
run: |
|
||||
cd packages/electron/dist
|
||||
sha256sum *.exe > sha256sum-exe.txt
|
||||
- name: Upload checksum (exe)
|
||||
if: matrix.platform == 'windows-latest'
|
||||
uses: svenstaro/upload-release-action@2.2.1
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: "v${{ env.PL_VENDOR_VERSION }}"
|
||||
file: packages/electron/dist/sha256sum-exe.txt
|
||||
asset_name: sha256sum-electron-exe.txt
|
||||
prerelease: true
|
||||
|
||||
release_cordova:
|
||||
name: "Release Cordova apps"
|
||||
|
@ -230,6 +360,10 @@ jobs:
|
|||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
- name: Install coreutils
|
||||
if: matrix.platform == 'macos-latest'
|
||||
run: |
|
||||
brew install coreutils
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
npm i -g npm@8.2.0
|
||||
|
@ -315,6 +449,34 @@ jobs:
|
|||
file: packages/cordova/platforms/ios/build/device/Padloc.ipa
|
||||
asset_name: padloc-${{ env.PL_VENDOR_VERSION }}.ipa
|
||||
prerelease: true
|
||||
- name: Generate checksum (apk)
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
run: |
|
||||
cd packages/cordova/platforms/android/app/build/outputs/apk/release
|
||||
sha256sum app-release.apk > sha256sum-apk.txt
|
||||
- name: Upload checksum (apk)
|
||||
if: matrix.platform == 'ubuntu-latest'
|
||||
uses: svenstaro/upload-release-action@2.2.1
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: "v${{ env.PL_VENDOR_VERSION }}"
|
||||
file: packages/cordova/platforms/android/app/build/outputs/apk/release/sha256sum-apk.txt
|
||||
asset_name: sha256sum-apk.txt
|
||||
prerelease: true
|
||||
- name: Generate checksum (ipa)
|
||||
if: matrix.platform == 'macos-latest'
|
||||
run: |
|
||||
cd packages/cordova/platforms/ios/build/device
|
||||
sha256sum Padloc.ipa > sha256sum-ipa.txt
|
||||
- name: Upload checksum (ipa)
|
||||
if: matrix.platform == 'macos-latest'
|
||||
uses: svenstaro/upload-release-action@2.2.1
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: "v${{ env.PL_VENDOR_VERSION }}"
|
||||
file: packages/cordova/platforms/ios/build/device/sha256sum-ipa.txt
|
||||
asset_name: sha256sum-ipa.txt
|
||||
prerelease: true
|
||||
- name: Delete android-upload-key.keystore
|
||||
if: matrix.platform == 'ubuntu-latest' && always()
|
||||
run: rm -f ./packages/cordova/android-upload-key.keystore
|
||||
|
@ -323,3 +485,60 @@ jobs:
|
|||
run: |
|
||||
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
|
||||
rm -f ~/Library/MobileDevice/Provisioning\ Profiles/build_pp.mobileprovision
|
||||
|
||||
release_web_checksums:
|
||||
name: "Release web checksums"
|
||||
environment: ${{ github.event.inputs.environment || 'Beta' }}
|
||||
needs: create_release_tag
|
||||
env:
|
||||
RELEASE_ID: ${{ needs.create_release_tag.outputs.release_id }}
|
||||
PL_VENDOR_VERSION: ${{ github.event.inputs.vendor_version || '0.0.1' }}
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version-file: ".nvmrc"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
npm i -g npm@8.2.0
|
||||
npm ci
|
||||
- name: Build
|
||||
run: |
|
||||
npm run pwa:build
|
||||
env:
|
||||
PL_PWA_URL: ${{ secrets.PL_PWA_URL }}
|
||||
PL_SERVER_URL: ${{ secrets.PL_SERVER_URL }}
|
||||
- name: Generate pwa.tar.gz
|
||||
run: |
|
||||
cd packages/pwa/dist
|
||||
tar -czf ../pwa.tar.gz *
|
||||
- name: Upload pwa.tar.gz
|
||||
uses: svenstaro/upload-release-action@2.2.1
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: "v${{ env.PL_VENDOR_VERSION }}"
|
||||
file: packages/pwa/pwa.tar.gz
|
||||
asset_name: padloc-pwa-${{ env.PL_VENDOR_VERSION }}.${{ env.RELEASE_BUILD }}.tar.gz
|
||||
prerelease: true
|
||||
- name: Generate checksums
|
||||
run: |
|
||||
cd packages/pwa/dist
|
||||
find . -type f ! -name "sha256sums-web.txt" -exec sha256sum {} > sha256sums-web.txt \;
|
||||
- name: Upload checksums
|
||||
uses: svenstaro/upload-release-action@2.2.1
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: "v${{ env.PL_VENDOR_VERSION }}"
|
||||
file: packages/pwa/dist/sha256sums-web.txt
|
||||
asset_name: sha256sums-web.txt
|
||||
prerelease: true
|
||||
- name: Upload CSP parser
|
||||
uses: svenstaro/upload-release-action@2.2.1
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: "v${{ env.PL_VENDOR_VERSION }}"
|
||||
file: docs/checksums/web/parse-csp.ts
|
||||
asset_name: parse-csp.ts
|
||||
prerelease: true
|
||||
|
|
|
@ -4,5 +4,9 @@
|
|||
"*.svg": "html"
|
||||
},
|
||||
"prettier.prettierPath": "./node_modules/prettier",
|
||||
"files.insertFinalNewline": true
|
||||
"files.insertFinalNewline": true,
|
||||
"deno.enable": false,
|
||||
"deno.lint": true,
|
||||
"deno.unstable": true,
|
||||
"deno.enablePaths": ["./docs/checksums/web"]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# Checksums
|
||||
|
||||
We use file checksums (SHA-256) to verify the source code you see matches the
|
||||
code served by our app. These are instructions for you to verify that too, so
|
||||
you don't have to trust us.
|
||||
|
||||
**NOTE:** These commands are meant for Linux and should also work on macOS. For
|
||||
Windows systems, we suggest you run them via WSL2.
|
||||
|
||||
In here you can find ways to verify the checksums for the different platforms:
|
||||
|
||||
- [Web](web)
|
||||
- [Firefox](firefox)
|
||||
- [Chrome](chrome)
|
||||
- [Android](android)
|
||||
- [iOS](ios)
|
||||
- [Linux](linux)
|
||||
- [macOS](macos)
|
||||
- [Windows](windows)
|
|
@ -0,0 +1,61 @@
|
|||
# Checksums (Android)
|
||||
|
||||
We use file checksums (SHA-256) to verify the source code you see matches the
|
||||
code served by our app. These are instructions for you to verify that too, so
|
||||
you don't have to trust us.
|
||||
|
||||
**NOTE:** These commands are meant for Linux and should also work on macOS. For
|
||||
Windows systems, we suggest you run them via WSL2.
|
||||
|
||||
## Verify checksums against source code
|
||||
|
||||
Unfortunately, because we sign our Android builds, it's not really possible to
|
||||
locally build the exact same file unless you had access to our certificates and
|
||||
keys. You can still
|
||||
[see how we build them here](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/publish-release.yml#L201),
|
||||
and
|
||||
[see how to build unsigned ones yourself](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/build-cordova.yml),
|
||||
though.
|
||||
|
||||
## Verify what you're using has the same source code
|
||||
|
||||
1. Download the apk file.
|
||||
|
||||
You can do that from
|
||||
[our releases page](https://github.com/padloc/padloc/releases) or from the
|
||||
store you've downloaded it from, to make sure that wasn't tampered with in
|
||||
the process of uploading there.
|
||||
|
||||
2. Download the latest `sha256sum-apk.txt` checksum file:
|
||||
|
||||
```bash
|
||||
wget https://github.com/padloc/padloc/releases/latest/download/sha256sum-apk.txt
|
||||
```
|
||||
|
||||
3. Verify checksum matches:
|
||||
|
||||
```bash
|
||||
sha256sum -c sha256sum-apk.txt
|
||||
```
|
||||
|
||||
You should see the `.apk` filename with an `OK` next to it for matching
|
||||
checksums. You'll get a warning at the end of the script if something didn't
|
||||
match.
|
||||
|
||||
> **NOTE:** If there's a warning about failing to find a file, your `.apk`
|
||||
> file probably doesn't match what `sha256sum-apk.txt` expects, so you can
|
||||
> change your `.apk` file's name to `app-release.apk` (or whatever's in the
|
||||
> file) for it to be found.
|
||||
|
||||
Here's an illustrative example of success:
|
||||
|
||||
```txt
|
||||
./app-release.apk: OK
|
||||
```
|
||||
|
||||
And one with a tampered file:
|
||||
|
||||
```txt
|
||||
./app-release.apk: FAILED
|
||||
sha256sum: WARNING: 1 computed checksum did NOT match
|
||||
```
|
|
@ -0,0 +1,61 @@
|
|||
# Checksums (Chrome)
|
||||
|
||||
We use file checksums (SHA-256) to verify the source code you see matches the
|
||||
code served by our app. These are instructions for you to verify that too, so
|
||||
you don't have to trust us.
|
||||
|
||||
**NOTE:** These commands are meant for Linux and should also work on macOS. For
|
||||
Windows systems, we suggest you run them via WSL2.
|
||||
|
||||
## Verify checksums against source code
|
||||
|
||||
Unfortunately, because we sign our Chrome builds, it's not really possible to
|
||||
locally build the exact same file unless you had access to our certificates and
|
||||
keys. You can still
|
||||
[see how we build them here](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/publish-release.yml#L54),
|
||||
and
|
||||
[see how to build unsigned ones yourself](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/build-web-extension.yml),
|
||||
though.
|
||||
|
||||
## Verify what you're using has the same source code
|
||||
|
||||
1. Download the crx file.
|
||||
|
||||
You can do that from
|
||||
[our releases page](https://github.com/padloc/padloc/releases) or from the
|
||||
store you've downloaded it from, to make sure that wasn't tampered with in
|
||||
the process of uploading there.
|
||||
|
||||
2. Download the latest `sha256sum-crx.txt` checksum file:
|
||||
|
||||
```bash
|
||||
wget https://github.com/padloc/padloc/releases/latest/download/sha256sum-crx.txt
|
||||
```
|
||||
|
||||
3. Verify checksum matches:
|
||||
|
||||
```bash
|
||||
sha256sum -c sha256sum-crx.txt
|
||||
```
|
||||
|
||||
You should see the `.xpi` filename with an `OK` next to it for matching
|
||||
checksums. You'll get a warning at the end of the script if something didn't
|
||||
match.
|
||||
|
||||
> **NOTE:** If there's a warning about failing to find a file, your `.crx`
|
||||
> file probably doesn't match what `sha256sum-crx.txt` expects, so you can
|
||||
> change your `.crx` file's name to `padloc-signed.crx` (or whatever's in
|
||||
> the file) for it to be found.
|
||||
|
||||
Here's an illustrative example of success:
|
||||
|
||||
```txt
|
||||
./padloc-signed.crx: OK
|
||||
```
|
||||
|
||||
And one with a tampered file:
|
||||
|
||||
```txt
|
||||
./padloc-signed.crx: FAILED
|
||||
sha256sum: WARNING: 1 computed checksum did NOT match
|
||||
```
|
|
@ -0,0 +1,61 @@
|
|||
# Checksums (Firefox)
|
||||
|
||||
We use file checksums (SHA-256) to verify the source code you see matches the
|
||||
code served by our app. These are instructions for you to verify that too, so
|
||||
you don't have to trust us.
|
||||
|
||||
**NOTE:** These commands are meant for Linux and should also work on macOS. For
|
||||
Windows systems, we suggest you run them via WSL2.
|
||||
|
||||
## Verify checksums against source code
|
||||
|
||||
Unfortunately, because we sign our Firefox builds, it's not really possible to
|
||||
locally build the exact same file unless you had access to our certificates and
|
||||
keys. You can still
|
||||
[see how we build them here](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/publish-release.yml#L54),
|
||||
and
|
||||
[see how to build unsigned ones yourself](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/build-web-extension.yml),
|
||||
though.
|
||||
|
||||
## Verify what you're using has the same source code
|
||||
|
||||
1. Download the xpi file.
|
||||
|
||||
You can do that from
|
||||
[our releases page](https://github.com/padloc/padloc/releases) or from the
|
||||
store you've downloaded it from, to make sure that wasn't tampered with in
|
||||
the process of uploading there.
|
||||
|
||||
2. Download the latest `sha256sum-xpi.txt` checksum file:
|
||||
|
||||
```bash
|
||||
wget https://github.com/padloc/padloc/releases/latest/download/sha256sum-xpi.txt
|
||||
```
|
||||
|
||||
3. Verify checksum matches:
|
||||
|
||||
```bash
|
||||
sha256sum -c sha256sum-xpi.txt
|
||||
```
|
||||
|
||||
You should see the `.xpi` filename with an `OK` next to it for matching
|
||||
checksums. You'll get a warning at the end of the script if something didn't
|
||||
match.
|
||||
|
||||
> **NOTE:** If there's a warning about failing to find a file, your `.xpi`
|
||||
> file probably doesn't match what `sha256sum-xpi.txt` expects, so you can
|
||||
> change your `.xpi` file's name to `padloc-4.0.0.55.xpi` (or whatever's in
|
||||
> the file) for it to be found.
|
||||
|
||||
Here's an illustrative example of success:
|
||||
|
||||
```txt
|
||||
./padloc-4.0.0.55.xpi: OK
|
||||
```
|
||||
|
||||
And one with a tampered file:
|
||||
|
||||
```txt
|
||||
./padloc-4.0.0.55.xpi: FAILED
|
||||
sha256sum: WARNING: 1 computed checksum did NOT match
|
||||
```
|
|
@ -0,0 +1,61 @@
|
|||
# Checksums (iOS)
|
||||
|
||||
We use file checksums (SHA-256) to verify the source code you see matches the
|
||||
code served by our app. These are instructions for you to verify that too, so
|
||||
you don't have to trust us.
|
||||
|
||||
**NOTE:** These commands are meant for Linux and should also work on macOS. For
|
||||
Windows systems, we suggest you run them via WSL2.
|
||||
|
||||
## Verify checksums against source code
|
||||
|
||||
Unfortunately, because we sign our iOS builds, it's not really possible to
|
||||
locally build the exact same file unless you had access to our certificates and
|
||||
keys. You can still
|
||||
[see how we build them here](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/publish-release.yml#L201),
|
||||
and
|
||||
[see how to build unsigned ones yourself](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/build-cordova.yml),
|
||||
though.
|
||||
|
||||
## Verify what you're using has the same source code
|
||||
|
||||
1. Download the ipa file.
|
||||
|
||||
You can do that from
|
||||
[our releases page](https://github.com/padloc/padloc/releases) or from the
|
||||
store you've downloaded it from, to make sure that wasn't tampered with in
|
||||
the process of uploading there.
|
||||
|
||||
2. Download the latest `sha256sum-ipa.txt` checksum file:
|
||||
|
||||
```bash
|
||||
wget https://github.com/padloc/padloc/releases/latest/download/sha256sum-ipa.txt
|
||||
```
|
||||
|
||||
3. Verify checksum matches:
|
||||
|
||||
```bash
|
||||
sha256sum -c sha256sum-ipa.txt
|
||||
```
|
||||
|
||||
You should see the `.ipa` filename with an `OK` next to it for matching
|
||||
checksums. You'll get a warning at the end of the script if something didn't
|
||||
match.
|
||||
|
||||
> **NOTE:** If there's a warning about failing to find a file, your `.ipa`
|
||||
> file probably doesn't match what `sha256sum-ipa.txt` expects, so you can
|
||||
> change your `.ipa` file's name to `Padloc.ipa` (or whatever's in the file)
|
||||
> for it to be found.
|
||||
|
||||
Here's an illustrative example of success:
|
||||
|
||||
```txt
|
||||
./Padloc.ipa: OK
|
||||
```
|
||||
|
||||
And one with a tampered file:
|
||||
|
||||
```txt
|
||||
./Padloc.ipa: FAILED
|
||||
sha256sum: WARNING: 1 computed checksum did NOT match
|
||||
```
|
|
@ -0,0 +1,72 @@
|
|||
# Checksums (Linux)
|
||||
|
||||
We use file checksums (SHA-256) to verify the source code you see matches the
|
||||
code served by our app. These are instructions for you to verify that too, so
|
||||
you don't have to trust us.
|
||||
|
||||
**NOTE:** These commands are meant for Linux and should also work on macOS. For
|
||||
Windows systems, we suggest you run them via WSL2.
|
||||
|
||||
## Verify checksums against source code
|
||||
|
||||
Unfortunately, because we sign our Linux builds (both via Electron and Tauri),
|
||||
it's not really possible to locally build the exact same file unless you had
|
||||
access to our certificates and keys. You can still see how we build them here
|
||||
([via Electron](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/publish-release.yml#L166)
|
||||
and
|
||||
[via Tauri](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/publish-release.yml#L116)),
|
||||
and see how to build unsigned ones yourself
|
||||
([via Electron](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/build-electron.yml)
|
||||
and
|
||||
[via Tauri](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/build-tauri.yml))
|
||||
, though.
|
||||
|
||||
## Verify what you're using has the same source code
|
||||
|
||||
1. Download the Electron or Tauri AppImage or deb file.
|
||||
|
||||
You can do that from
|
||||
[our releases page](https://github.com/padloc/padloc/releases) or from the
|
||||
store you've downloaded it from, to make sure that wasn't tampered with in
|
||||
the process of uploading there.
|
||||
|
||||
2. Download the latest `sha256sum-[tauri/electron]-[appimage/deb].txt` checksum
|
||||
file:
|
||||
|
||||
**NOTE**: Pick one of the options above, from `tauri` or `electron`, and
|
||||
from `appimage` or `deb`, depending on what's available for that platform.
|
||||
You can see what's available in the releases page. For the examples below,
|
||||
we'll use `tauri` and `appimage`.
|
||||
|
||||
```bash
|
||||
wget https://github.com/padloc/padloc/releases/latest/download/sha256sum-tauri-appimage.txt
|
||||
```
|
||||
|
||||
3. Verify checksum matches:
|
||||
|
||||
```bash
|
||||
sha256sum -c sha256sum-tauri-appimage.txt
|
||||
```
|
||||
|
||||
You should see the `.AppImage` filename with an `OK` next to it for matching
|
||||
checksums. You'll get a warning at the end of the script if something didn't
|
||||
match.
|
||||
|
||||
> **NOTE:** If there's a warning about failing to find a file, your
|
||||
> `.AppImage` file probably doesn't match what
|
||||
> `sha256sum-tauri-appimage.txt` expects, so you can change your `.AppImage`
|
||||
> file's name to `padloc_4.0.0_amd64.AppImage` (or whatever's in the file)
|
||||
> for it to be found.
|
||||
|
||||
Here's an illustrative example of success:
|
||||
|
||||
```txt
|
||||
./padloc_4.0.0_amd64.AppImage: OK
|
||||
```
|
||||
|
||||
And one with a tampered file:
|
||||
|
||||
```txt
|
||||
./padloc_4.0.0_amd64.AppImage: FAILED
|
||||
sha256sum: WARNING: 1 computed checksum did NOT match
|
||||
```
|
|
@ -0,0 +1,68 @@
|
|||
# Checksums (macOS)
|
||||
|
||||
We use file checksums (SHA-256) to verify the source code you see matches the
|
||||
code served by our app. These are instructions for you to verify that too, so
|
||||
you don't have to trust us.
|
||||
|
||||
**NOTE:** These commands are meant for Linux and should also work on macOS. For
|
||||
Windows systems, we suggest you run them via WSL2.
|
||||
|
||||
## Verify checksums against source code
|
||||
|
||||
Unfortunately, because we sign our macOS builds (both via Electron and Tauri),
|
||||
it's not really possible to locally build the exact same file unless you had
|
||||
access to our certificates and keys. You can still see how we build them here
|
||||
([via Electron](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/publish-release.yml#L166)
|
||||
and
|
||||
[via Tauri](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/publish-release.yml#L116)),
|
||||
and see how to build unsigned ones yourself
|
||||
([via Electron](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/build-electron.yml)
|
||||
and
|
||||
[via Tauri](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/build-tauri.yml))
|
||||
, though.
|
||||
|
||||
## Verify what you're using has the same source code
|
||||
|
||||
1. Download the Electron or Tauri dmg or app file.
|
||||
|
||||
You can do that from
|
||||
[our releases page](https://github.com/padloc/padloc/releases) or from the store
|
||||
you've downloaded it from, to make sure that wasn't tampered with in the process
|
||||
of uploading there.
|
||||
|
||||
2. Download the latest `sha256sum-[tauri/electron]-dmg.txt` checksum file:
|
||||
|
||||
**NOTE**: Pick one of the options above, from `tauri` or `electron`. For the
|
||||
examples below, we'll use `tauri`.
|
||||
|
||||
```bash
|
||||
wget https://github.com/padloc/padloc/releases/latest/download/sha256sum-tauri-dmg.txt
|
||||
```
|
||||
|
||||
3. Verify checksum matches:
|
||||
|
||||
```bash
|
||||
sha256sum -c sha256sum-tauri-dmg.txt
|
||||
```
|
||||
|
||||
You should see the `.dmg` filename with an `OK` next to it for matching
|
||||
checksums. You'll get a warning at the end of the script if something didn't
|
||||
match.
|
||||
|
||||
> **NOTE:** If there's a warning about failing to find a file, your `.dmg`
|
||||
> file probably doesn't match what `sha256sum-tauri-dmg.txt` expects, so you
|
||||
> can change your `.dmg` file's name to `Padloc_4.0.0_x64.dmg` (or
|
||||
> whatever's in the file) for it to be found.
|
||||
|
||||
Here's an illustrative example of success:
|
||||
|
||||
```txt
|
||||
./Padloc_4.0.0_x64.dmg: OK
|
||||
```
|
||||
|
||||
And one with a tampered file:
|
||||
|
||||
```txt
|
||||
./Padloc_4.0.0_x64.dmg: FAILED
|
||||
sha256sum: WARNING: 1 computed checksum did NOT match
|
||||
```
|
|
@ -0,0 +1,196 @@
|
|||
# Checksums (Web)
|
||||
|
||||
We use file checksums (SHA-256) to verify the source code you see matches the
|
||||
code served by our app. These are instructions for you to verify that too, so
|
||||
you don't have to trust us.
|
||||
|
||||
**NOTE:** These commands are meant for Linux and should also work on macOS. For
|
||||
Windows systems, we suggest you run them via WSL2.
|
||||
|
||||
## Verify checksums against source code
|
||||
|
||||
1. Clone repo and install dependencies:
|
||||
|
||||
```bash
|
||||
git clone git@github.com:padloc/padloc.git && \
|
||||
cd padloc && \
|
||||
git pull origin/v4 && \
|
||||
npm install
|
||||
```
|
||||
|
||||
2. Build code (replace `beta.padloc.app` with whatever domain you're trying to
|
||||
check, if not padloc's production):
|
||||
|
||||
```bash
|
||||
PL_PWA_URL=https://beta.padloc.app \
|
||||
PL_SERVER_URL=$PL_PWA_URL/server/ \
|
||||
npm run pwa:build
|
||||
```
|
||||
|
||||
3. Download the latest `sha256sums-web.txt` checksum file:
|
||||
|
||||
```bash
|
||||
cd packages/pwa/dist && \
|
||||
wget https://github.com/padloc/padloc/releases/latest/download/sha256sums-web.txt
|
||||
```
|
||||
|
||||
4. Verify checksums match:
|
||||
|
||||
```bash
|
||||
sha256sum -c sha256sums-web.txt
|
||||
```
|
||||
|
||||
You should see all filenames with an `OK` next to them for matching
|
||||
checksums. You'll get a warning at the end of the script if something didn't
|
||||
match.
|
||||
|
||||
Here's an illustrative example of success:
|
||||
|
||||
```txt
|
||||
./main.js: OK
|
||||
./9c5a939648cf4e10869c369c7262c0b2.woff2: OK
|
||||
./0ce7bb41cbc2ad09a21b7b5222628111.svg: OK
|
||||
./zxcvbn.chunk.js: OK
|
||||
./manifest.623e2268f17398ec7f19225e281e4056.json: OK
|
||||
./ua-parser.chunk.js: OK
|
||||
./locale_res_wordlists_pt_json.chunk.js: OK
|
||||
./locale_res_wordlists_en_json.chunk.js: OK
|
||||
./sw.js.map: OK
|
||||
./app_src_elements_app_ts.chunk.js.map: OK
|
||||
./index.html: OK
|
||||
./ua-parser.chunk.js.map: OK
|
||||
./6d964ac2439b4e11afd25d1d47df88b6.woff2: OK
|
||||
./56435da2448caaff95b05759954ec6ee.woff2: OK
|
||||
./icon_192x192.8dfb7236c7e6b6591567173b18eaa144.png: OK
|
||||
./vendors-app_node_modules_autosize_src_autosize_js-app_node_modules_dompurify_dist_purify_js-a-10f8da.chunk.js.map: OK
|
||||
./app_src_elements_app_ts.chunk.js: OK
|
||||
./sw.js: OK
|
||||
./main.js.map: OK
|
||||
./icon_384x384.971e45062e4d601a3014dc16ee3ed27b.png: OK
|
||||
./locale_res_translations_fr_json.chunk.js: OK
|
||||
./c94db5f3862667362c6815c9b1ec8acf.woff2: OK
|
||||
./icon_256x256.9a47fba2857d94939047064f37cd075f.png: OK
|
||||
./locale_res_translations_pl_json.chunk.js: OK
|
||||
./locale_res_translations_es_json.chunk.js: OK
|
||||
./locale_res_translations_de_json.chunk.js: OK
|
||||
./zxcvbn.chunk.js.map: OK
|
||||
./locale_res_translations_ru_json.chunk.js: OK
|
||||
./papaparse.chunk.js.map: OK
|
||||
./5d40dd64e2278fe436ba68ac7f1195a4.woff2: OK
|
||||
./jsqr.chunk.js.map: OK
|
||||
./1bbee3bd1bc00c4dce2a7c7046930ae6.woff2: OK
|
||||
./app_src_lib_1pux-parser_ts.chunk.js.map: OK
|
||||
./vendors-app_node_modules_date-fns_esm_sub_index_js.chunk.js: OK
|
||||
./locale_res_wordlists_de_json.chunk.js: OK
|
||||
./favicon.png: OK
|
||||
./icon_128x128.f620784d1682c9fbb033d3b018e7d998.png: OK
|
||||
./vendors-app_node_modules_autosize_src_autosize_js-app_node_modules_dompurify_dist_purify_js-a-10f8da.chunk.js: OK
|
||||
./app_src_lib_1pux-parser_ts.chunk.js: OK
|
||||
./papaparse.chunk.js: OK
|
||||
./icon_512x512.e3175643e8fe0d95175a493da5201480.png: OK
|
||||
./4a9ab29a10089191088de2b7c02c78e7.woff2: OK
|
||||
./locale_res_wordlists_es_json.chunk.js: OK
|
||||
./locale_res_translations__template_json.chunk.js: OK
|
||||
./vendors-app_node_modules_date-fns_esm_sub_index_js.chunk.js.map: OK
|
||||
./locale_res_wordlists_fr_json.chunk.js: OK
|
||||
./icon_96x96.eda9f98be1c35dabab77f9d2ab7be538.png: OK
|
||||
./5ce2631c76a09ec2ab1d619e3b1eda91.woff2: OK
|
||||
./jsqr.chunk.js: OK
|
||||
./b1fac335d3804d9dadf795e093048b40.woff2: OK
|
||||
./03e3c10d4a52fe7b56918f851766d886.woff2: OK
|
||||
./date-fns.chunk.js.map: OK
|
||||
./date-fns.chunk.js: OK
|
||||
```
|
||||
|
||||
And one with a tampered `main.js` file:
|
||||
|
||||
```txt
|
||||
./main.js: FAILED
|
||||
./9c5a939648cf4e10869c369c7262c0b2.woff2: OK
|
||||
./0ce7bb41cbc2ad09a21b7b5222628111.svg: OK
|
||||
./zxcvbn.chunk.js: OK
|
||||
./manifest.623e2268f17398ec7f19225e281e4056.json: OK
|
||||
./ua-parser.chunk.js: OK
|
||||
./locale_res_wordlists_pt_json.chunk.js: OK
|
||||
./locale_res_wordlists_en_json.chunk.js: OK
|
||||
./sw.js.map: OK
|
||||
./app_src_elements_app_ts.chunk.js.map: OK
|
||||
./index.html: OK
|
||||
./ua-parser.chunk.js.map: OK
|
||||
./6d964ac2439b4e11afd25d1d47df88b6.woff2: OK
|
||||
./56435da2448caaff95b05759954ec6ee.woff2: OK
|
||||
./icon_192x192.8dfb7236c7e6b6591567173b18eaa144.png: OK
|
||||
./vendors-app_node_modules_autosize_src_autosize_js-app_node_modules_dompurify_dist_purify_js-a-10f8da.chunk.js.map: OK
|
||||
./app_src_elements_app_ts.chunk.js: OK
|
||||
./sw.js: OK
|
||||
./main.js.map: OK
|
||||
./icon_384x384.971e45062e4d601a3014dc16ee3ed27b.png: OK
|
||||
./locale_res_translations_fr_json.chunk.js: OK
|
||||
./c94db5f3862667362c6815c9b1ec8acf.woff2: OK
|
||||
./icon_256x256.9a47fba2857d94939047064f37cd075f.png: OK
|
||||
./locale_res_translations_pl_json.chunk.js: OK
|
||||
./locale_res_translations_es_json.chunk.js: OK
|
||||
./locale_res_translations_de_json.chunk.js: OK
|
||||
./zxcvbn.chunk.js.map: OK
|
||||
./locale_res_translations_ru_json.chunk.js: OK
|
||||
./papaparse.chunk.js.map: OK
|
||||
./5d40dd64e2278fe436ba68ac7f1195a4.woff2: OK
|
||||
./jsqr.chunk.js.map: OK
|
||||
./1bbee3bd1bc00c4dce2a7c7046930ae6.woff2: OK
|
||||
./app_src_lib_1pux-parser_ts.chunk.js.map: OK
|
||||
./vendors-app_node_modules_date-fns_esm_sub_index_js.chunk.js: OK
|
||||
./locale_res_wordlists_de_json.chunk.js: OK
|
||||
./favicon.png: OK
|
||||
./icon_128x128.f620784d1682c9fbb033d3b018e7d998.png: OK
|
||||
./vendors-app_node_modules_autosize_src_autosize_js-app_node_modules_dompurify_dist_purify_js-a-10f8da.chunk.js: OK
|
||||
./app_src_lib_1pux-parser_ts.chunk.js: OK
|
||||
./papaparse.chunk.js: OK
|
||||
./icon_512x512.e3175643e8fe0d95175a493da5201480.png: OK
|
||||
./4a9ab29a10089191088de2b7c02c78e7.woff2: OK
|
||||
./locale_res_wordlists_es_json.chunk.js: OK
|
||||
./locale_res_translations__template_json.chunk.js: OK
|
||||
./vendors-app_node_modules_date-fns_esm_sub_index_js.chunk.js.map: OK
|
||||
./locale_res_wordlists_fr_json.chunk.js: OK
|
||||
./icon_96x96.eda9f98be1c35dabab77f9d2ab7be538.png: OK
|
||||
./5ce2631c76a09ec2ab1d619e3b1eda91.woff2: OK
|
||||
./jsqr.chunk.js: OK
|
||||
./b1fac335d3804d9dadf795e093048b40.woff2: OK
|
||||
./03e3c10d4a52fe7b56918f851766d886.woff2: OK
|
||||
./date-fns.chunk.js.map: OK
|
||||
./date-fns.chunk.js: OK
|
||||
sha256sum: WARNING: 1 computed checksum did NOT match
|
||||
```
|
||||
|
||||
## Verify what you're using has the same source code
|
||||
|
||||
1. Download a website (replace `beta.padloc.app` with whatever domain you're
|
||||
trying to check), and all the relevant files:
|
||||
|
||||
```bash
|
||||
HOST_TO_CHECK=beta.padloc.app && \
|
||||
wget -r -p -U Mozilla https://$HOST_TO_CHECK && \
|
||||
cd $HOST_TO_CHECK && \
|
||||
wget https://github.com/padloc/padloc/releases/latest/download/parse-csp.ts && \
|
||||
deno run --allow-read=index.html --allow-net=$HOST_TO_CHECK --allow-write=. parse-csp.ts
|
||||
```
|
||||
|
||||
The bash script above downloads a full website into a directory with its
|
||||
hostname, then parses the `Content-Security-Policy` meta tag to get the list
|
||||
of all the used/necessary files (using [`Deno`](https://deno.land), after
|
||||
downloading the [`parse-csp.ts`](parse-csp.ts) file from this repo). This
|
||||
will change with each build of Padloc, so the script needs to be dynamic.
|
||||
|
||||
2. Download the latest `sha256sums-web.txt` checksum file:
|
||||
|
||||
```bash
|
||||
wget https://github.com/padloc/padloc/releases/latest/download/sha256sums-web.txt
|
||||
```
|
||||
|
||||
3. Verify checksums match:
|
||||
|
||||
```bash
|
||||
sha256sum -c sha256sums-web.txt
|
||||
```
|
||||
|
||||
You can see step 4 from the `Verify checksums against source code` section
|
||||
above, for expected outputs.
|
|
@ -0,0 +1,79 @@
|
|||
import { writableStreamFromWriter } from "https://deno.land/std@0.143.0/streams/mod.ts";
|
||||
|
||||
const indexFileName = "index.html";
|
||||
|
||||
const html = await Deno.readTextFile(`./${indexFileName}`);
|
||||
|
||||
const regExp = /(?:<meta http-equiv="Content-Security-Policy" content=")([^">]+)">/gi;
|
||||
|
||||
const matches = regExp.exec(html);
|
||||
|
||||
if (!matches || !matches[1]) {
|
||||
console.error("Could not find CSP meta tag. Please make sure you've downloaded a correct index.html file.");
|
||||
Deno.exit(1);
|
||||
}
|
||||
|
||||
console.log("Found CSP meta tag. Parsing rules...");
|
||||
|
||||
const cspString = matches[1];
|
||||
|
||||
const filesInCsp = new Set<string>();
|
||||
|
||||
const cspRuleStrings = cspString.split(";").map((cspRule) => cspRule.trim());
|
||||
|
||||
// Parse all rules appropriately, with the files per rule
|
||||
for (const cspRuleString of cspRuleStrings) {
|
||||
const cspParts = cspRuleString.split(" ");
|
||||
|
||||
if (cspParts.length === 0) {
|
||||
console.error("Found invalid CSP rule. Please make sure you've downloaded a correct index.html file.");
|
||||
Deno.exit(1);
|
||||
}
|
||||
|
||||
// Skip empty set (we get one at the end)
|
||||
if (cspParts.length === 1 && cspParts[0] === "") {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove the rule name
|
||||
cspParts.shift();
|
||||
|
||||
for (const cspPart of cspParts) {
|
||||
if (cspPart.startsWith("https://")) {
|
||||
// Confirm we're downloading a file and not a server URL, for example
|
||||
const urlParts = cspPart.split("/");
|
||||
const fileName = urlParts.pop() || "";
|
||||
const fileExtension = fileName.split(".").pop();
|
||||
|
||||
if (urlParts.length > 2 && fileName && fileExtension) {
|
||||
filesInCsp.add(cspPart);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Parsed all the rules. Downloading files...");
|
||||
|
||||
// Download all files, in parallel
|
||||
await Promise.all(
|
||||
Array.from(filesInCsp).map(async (fileUrl) => {
|
||||
try {
|
||||
const fileName = fileUrl.split("/").pop() || "";
|
||||
const response = await fetch(fileUrl);
|
||||
// Stream instead of waiting for the response to finish before saving, as it's faster, even if the files should be small
|
||||
if (response.body) {
|
||||
const file = await Deno.open(`./${fileName}`, { write: true, create: true });
|
||||
const writableStream = writableStreamFromWriter(file);
|
||||
await response.body.pipeTo(writableStream);
|
||||
} else {
|
||||
throw new Error("Failed to fetch file");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Failed to download "${fileUrl}": ${error}`);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
console.log(
|
||||
"Finished downloading files. You can now download the latest checksum and run the sha256sum command to verify them."
|
||||
);
|
|
@ -0,0 +1,72 @@
|
|||
# Checksums (Windows)
|
||||
|
||||
We use file checksums (SHA-256) to verify the source code you see matches the
|
||||
code served by our app. These are instructions for you to verify that too, so
|
||||
you don't have to trust us.
|
||||
|
||||
**NOTE:** These commands are meant for Linux and should also work on macOS. For
|
||||
Windows systems, we suggest you run them via WSL2.
|
||||
|
||||
## Verify checksums against source code
|
||||
|
||||
Unfortunately, because we sign our Windows builds (both via Electron and Tauri),
|
||||
it's not really possible to locally build the exact same file unless you had
|
||||
access to our certificates and keys. You can still see how we build them here
|
||||
([via Electron](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/publish-release.yml#L166)
|
||||
and
|
||||
[via Tauri](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/publish-release.yml#L116)),
|
||||
and see how to build unsigned ones yourself
|
||||
([via Electron](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/build-electron.yml)
|
||||
and
|
||||
[via Tauri](https://github.com/padloc/padloc/blob/ea05def083df89823d7c15c7bbeb6ef1a1b40383/.github/workflows/build-tauri.yml))
|
||||
, though.
|
||||
|
||||
## Verify what you're using has the same source code
|
||||
|
||||
1. Download the Electron or Tauri exe or msi file.
|
||||
|
||||
You can do that from
|
||||
[our releases page](https://github.com/padloc/padloc/releases) or from the
|
||||
store you've downloaded it from, to make sure that wasn't tampered with in
|
||||
the process of uploading there.
|
||||
|
||||
2. Download the latest `sha256sum-[tauri/electron]-[exe/msi].txt` checksum file:
|
||||
|
||||
**NOTE**: Pick one of the options above, from `tauri` or `electron`, and
|
||||
from `exe` or `msi`, depending on what's available for that platform. You
|
||||
can see what's available in the releases page. For the examples below, we'll
|
||||
use `tauri` and `msi`.
|
||||
|
||||
```bash
|
||||
wget https://github.com/padloc/padloc/releases/latest/download/sha256sum-tauri-msi.txt
|
||||
```
|
||||
|
||||
3. Verify checksum matches:
|
||||
|
||||
```bash
|
||||
# replaces windows line-endings with unix
|
||||
sed -i.bak 's/\r$//' sha256sum-tauri-msi.txt && \
|
||||
sha256sum -c sha256sum-tauri-msi.txt
|
||||
```
|
||||
|
||||
You should then see the `.msi` filename with an `OK` next to it for matching
|
||||
checksums. You'll get a warning at the end of the script if something didn't
|
||||
match.
|
||||
|
||||
> **NOTE:** If there's a warning about failing to find a file, your `.msi`
|
||||
> file probably doesn't match what `sha256sum-tauri-msi.txt` expects, so you
|
||||
> can change your `.msi` file's name to `Padloc_4.0.0_x64_en-US.msi` (or
|
||||
> whatever's in the file) for it to be found.
|
||||
|
||||
Here's an illustrative example of success:
|
||||
|
||||
```txt
|
||||
./Padloc_4.0.0_x64_en-US.msi: OK
|
||||
```
|
||||
|
||||
And one with a tampered file:
|
||||
|
||||
```txt
|
||||
./Padloc_4.0.0_x64_en-US.msi: FAILED
|
||||
sha256sum: WARNING: 1 computed checksum did NOT match
|
||||
```
|
File diff suppressed because it is too large
Load Diff
|
@ -9,6 +9,7 @@ const sharp = require("sharp");
|
|||
|
||||
const out = process.env.PL_PWA_DIR || resolve(__dirname, "dist");
|
||||
const serverUrl = process.env.PL_SERVER_URL || `http://0.0.0.0:${process.env.PL_SERVER_PORT || 3000}`;
|
||||
const pwaUrl = process.env.PL_PWA_URL || `http://localhost:${process.env.PL_PWA_PORT || 8080}`;
|
||||
const rootDir = resolve(__dirname, "../..");
|
||||
const assetsDir = resolve(rootDir, process.env.PL_ASSETS_DIR || "assets");
|
||||
|
||||
|
@ -54,6 +55,7 @@ module.exports = {
|
|||
plugins: [
|
||||
new EnvironmentPlugin({
|
||||
PL_APP_NAME: name,
|
||||
PL_PWA_URL: pwaUrl,
|
||||
PL_SERVER_URL: serverUrl,
|
||||
PL_BILLING_ENABLED: null,
|
||||
PL_BILLING_DISABLE_PAYMENT: null,
|
||||
|
@ -66,13 +68,96 @@ module.exports = {
|
|||
PL_TERMS_OF_SERVICE: terms_of_service,
|
||||
}),
|
||||
new CleanWebpackPlugin(),
|
||||
{
|
||||
apply(compiler) {
|
||||
compiler.hooks.compilation.tap("Store Built Files for CSP", (compilation) => {
|
||||
HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(
|
||||
"Store Built Files for CSP",
|
||||
(data, callback) => {
|
||||
const isBuildingLocally = pwaUrl.startsWith("http://localhost");
|
||||
const fileExtensionsToCspRule = new Map([
|
||||
["js", "script-src"],
|
||||
["map", "script-src"],
|
||||
["woff2", "font-src"],
|
||||
["svg", "img-src"],
|
||||
["png", "img-src"],
|
||||
]);
|
||||
const builtFilesForCsp = new Map([
|
||||
["script-src", []],
|
||||
["font-src", []],
|
||||
[
|
||||
"img-src",
|
||||
[
|
||||
"favicon.png",
|
||||
// TODO: These should be dynamically added (from the manifest), but it's not available at this point
|
||||
"icon_512x512.e3175643e8fe0d95175a493da5201480.png",
|
||||
"icon_384x384.971e45062e4d601a3014dc16ee3ed27b.png",
|
||||
"icon_256x256.9a47fba2857d94939047064f37cd075f.png",
|
||||
"icon_192x192.8dfb7236c7e6b6591567173b18eaa144.png",
|
||||
"icon_128x128.f620784d1682c9fbb033d3b018e7d998.png",
|
||||
"icon_96x96.eda9f98be1c35dabab77f9d2ab7be538.png",
|
||||
],
|
||||
],
|
||||
// TODO: This should to be dynamically added, but it's not available at this point
|
||||
["manifest-src", ["manifest.623e2268f17398ec7f19225e281e4056.json"]],
|
||||
]);
|
||||
|
||||
// Add the root PWA URL of webpack-dev-server to script-src when building locally, otherwise server hot reloading won't work
|
||||
if (isBuildingLocally) {
|
||||
builtFilesForCsp.get("script-src").push("");
|
||||
}
|
||||
|
||||
const assets = compilation.getAssets();
|
||||
|
||||
for (const asset of assets) {
|
||||
const fileExtension = asset.name.split(".").pop();
|
||||
|
||||
if (!fileExtensionsToCspRule.has(fileExtension)) {
|
||||
throw new Error(`No CSP rule found for ".${fileExtension}"! (${asset.name})`);
|
||||
}
|
||||
|
||||
const cspRule = fileExtensionsToCspRule.get(fileExtension);
|
||||
|
||||
if (!builtFilesForCsp.has(cspRule)) {
|
||||
throw new Error(`No CSP rule found for "${cspRule}"! (${fileExtension})`);
|
||||
}
|
||||
|
||||
builtFilesForCsp.get(cspRule).push(asset.name);
|
||||
}
|
||||
|
||||
// Manually add the files in for the CSP meta tag
|
||||
for (const cspRule of builtFilesForCsp.keys()) {
|
||||
// Sort all files first
|
||||
const files = builtFilesForCsp.get(cspRule);
|
||||
files.sort();
|
||||
|
||||
data.html = data.html.replace(
|
||||
`[REPLACE_${cspRule.replace("-src", "").toUpperCase()}]`,
|
||||
`${files.map((file) => `${pwaUrl}/${file}`).join(" ")}`
|
||||
);
|
||||
}
|
||||
|
||||
// Add the websocket URL + PWA URL of webpack-dev-server to connect-src when building locally, or nothing otherwise
|
||||
let connectReplacement = isBuildingLocally
|
||||
? `ws://localhost:${process.env.PL_PWA_PORT || 8080}/ws ${pwaUrl}`
|
||||
: "";
|
||||
data.html = data.html.replace("[REPLACE_CONNECT]", connectReplacement);
|
||||
|
||||
callback(null, data);
|
||||
}
|
||||
);
|
||||
|
||||
return true;
|
||||
});
|
||||
},
|
||||
},
|
||||
new HtmlWebpackPlugin({
|
||||
title: name,
|
||||
template: resolve(__dirname, "src/index.html"),
|
||||
meta: {
|
||||
"Content-Security-Policy": {
|
||||
"http-equiv": "Content-Security-Policy",
|
||||
content: `default-src 'self' ${serverUrl} https://api.pwnedpasswords.com blob:; style-src 'self' 'unsafe-inline'; object-src 'self' blob:; frame-src 'self'; img-src 'self' blob: data: https:;`,
|
||||
content: `default-src 'none'; base-uri 'none'; script-src blob: [REPLACE_SCRIPT]; connect-src ${serverUrl} https://api.pwnedpasswords.com [REPLACE_CONNECT]; style-src 'unsafe-inline'; font-src [REPLACE_FONT]; object-src blob:; frame-src 'none'; img-src [REPLACE_IMG] blob: data: https://icons.duckduckgo.com; manifest-src [REPLACE_MANIFEST]; worker-src ${pwaUrl}/sw.js;`,
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
|
|
@ -22,5 +22,6 @@
|
|||
"esModuleInterop": true,
|
||||
"allowJs": true,
|
||||
"useUnknownInCatchVariables": false
|
||||
}
|
||||
},
|
||||
"exclude": ["docs"]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue