encryption stuff testing

This commit is contained in:
Bryan Gerlach
2026-01-10 19:10:26 -06:00
parent 52682fec1d
commit 38a4c64d3a
4 changed files with 164 additions and 120 deletions

View File

@@ -3,51 +3,19 @@ run-name: Custom Windows Client Generator
on:
workflow_dispatch:
inputs:
server:
description: 'Rendezvous Server'
payload:
description: 'The Fernet-encrypted JSON bundle'
required: true
default: ''
type: string
key:
description: 'Public Key'
wrapped_key:
description: 'The RSA-encrypted symmetric key'
required: true
default: ''
type: string
apiServer:
description: 'API Server'
required: true
default: ''
type: string
custom:
description: "Custom JSON"
required: true
default: ''
type: string
uuid:
description: "uuid of request"
required: true
default: ''
type: string
iconlink:
description: "icon link"
required: false
default: 'false'
type: string
logolink:
description: "logo link"
required: false
default: 'false'
type: string
appname:
description: "app name"
required: true
default: 'rustdesk'
type: string
filename:
description: "Filename"
required: true
default: 'rustdesk'
type: string
extras:
description: "extra inputs in json"
required: true
@@ -116,6 +84,47 @@ jobs:
}
# - { target: aarch64-pc-windows-msvc, os: windows-2022, arch: aarch64 }
steps:
- name: Install Cryptography
run: pip install cryptography
- name: Decrypt and Mask Inputs
env:
PRIVATE_KEY: ${{ secrets.RSA_PRIVATE_KEY }}
ENCRYPTED_DATA: ${{ github.event.inputs.payload }}
ENCRYPTED_KEY: ${{ github.event.inputs.wrapped_key }}
run: |
python - <<EOF
import os, json, base64
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
private_key = serialization.load_pem_private_key(
os.environ['PRIVATE_KEY'].encode(),
password=None
)
encrypted_key_bytes = base64.b64decode(os.environ['ENCRYPTED_KEY'])
session_key = private_key.decrypt(
encrypted_key_bytes,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
fernet = Fernet(session_key)
decrypted_json = fernet.decrypt(os.environ['ENCRYPTED_DATA'].encode()).decode('utf-8')
data = json.loads(decrypted_json)
with open(os.environ['GITHUB_ENV'], 'a') as f:
for key, value in data.items():
# This prevents the value from appearing in ANY logs
print(f"::add-mask::{value}")
f.write(f"{key}={value}\n")
EOF
- name: Export GitHub Actions cache environment variables
uses: actions/github-script@v6
with:
@@ -131,7 +140,7 @@ jobs:
- name: Set rdgen value
if: ${{ fromJson(inputs.extras).rdgen == 'false' }}
run: |
echo "STATUS_URL=${{ inputs.apiServer }}/api/updategh" >> $env:GITHUB_ENV
echo "STATUS_URL=${{ env.apiServer }}/api/updategh" >> $env:GITHUB_ENV
- name: Report Status
uses: fjogeleit/http-request-action@v1
@@ -140,7 +149,7 @@ jobs:
url: ${{ env.STATUS_URL }}
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "5% complete"}'
data: '{"uuid": "${{ env.uuid }}", "status": "5% complete"}'
- name: Checkout source code
if: ${{ env.VERSION != 'master' }}
@@ -175,34 +184,34 @@ jobs:
sed -i -e 's|2ded7f146437a761ffe6981e2f742038f85ca68d|08a471bb8ceccdd50483c81cdfa8b81b07b14b87|' ./flutter/pubspec.yaml
- name: change appname to custom
if: inputs.appname != 'rustdesk'
if: env.appname != 'rustdesk'
continue-on-error: true
shell: bash
run: |
# ./Cargo.toml
sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./Cargo.toml
sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./Cargo.toml
sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./Cargo.toml
sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./Cargo.toml
sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ env.appname }}"|' ./Cargo.toml
sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ env.appname }}"|' ./Cargo.toml
sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ env.appname }}"|' ./Cargo.toml
sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ env.appname }}.exe"|' ./Cargo.toml
# ./libs/portable/Cargo.toml
sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml
sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml
sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ inputs.appname }}"|' ./libs/portable/Cargo.toml
sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ inputs.appname }}.exe"|' ./libs/portable/Cargo.toml
sed -i -e 's|description = "RustDesk Remote Desktop"|description = "${{ env.appname }}"|' ./libs/portable/Cargo.toml
sed -i -e 's|ProductName = "RustDesk"|ProductName = "${{ env.appname }}"|' ./libs/portable/Cargo.toml
sed -i -e 's|FileDescription = "RustDesk Remote Desktop"|FileDescription = "${{ env.appname }}"|' ./libs/portable/Cargo.toml
sed -i -e 's|OriginalFilename = "rustdesk.exe"|OriginalFilename = "${{ env.appname }}.exe"|' ./libs/portable/Cargo.toml
# ./flutter/windows/runner/Runner.rc
sed -i -e 's|"RustDesk Remote Desktop"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc
sed -i -e 's|VALUE "InternalName", "rustdesk" "\0"|VALUE "InternalName", "${{ inputs.appname }}" "\0"|' ./flutter/windows/runner/Runner.rc
sed -i -e 's|"rustdesk.exe"|"${{ inputs.filename }}"|' ./flutter/windows/runner/Runner.rc
sed -i -e 's|"RustDesk"|"${{ inputs.appname }}"|' ./flutter/windows/runner/Runner.rc
sed -i -e 's|"RustDesk Remote Desktop"|"${{ env.appname }}"|' ./flutter/windows/runner/Runner.rc
sed -i -e 's|VALUE "InternalName", "rustdesk" "\0"|VALUE "InternalName", "${{ env.appname }}" "\0"|' ./flutter/windows/runner/Runner.rc
sed -i -e 's|"rustdesk.exe"|"${{ env.filename }}"|' ./flutter/windows/runner/Runner.rc
sed -i -e 's|"RustDesk"|"${{ env.appname }}"|' ./flutter/windows/runner/Runner.rc
# ./src/lang/en.rs
# change powered by rustdek to powered by compname
if [ ! -z "${{ fromJson(inputs.extras).compname }}" ]; then
find ./src/lang -name "*.rs" -exec sed -i '/powered_by_me/s|RustDesk|${{ fromJson(inputs.extras).compname }}|g' {} \;
if [ ! -z "${{ env.compname }}" ]; then
find ./src/lang -name "*.rs" -exec sed -i '/powered_by_me/s|RustDesk|${{ env.compname }}|g' {} \;
fi
find ./src/lang -name "*.rs" -exec sed -i -e 's|RustDesk|${{ inputs.appname }}|' {} \;
find ./src/lang -name "*.rs" -exec sed -i -e 's|RustDesk|${{ env.appname }}|' {} \;
- name: fix registry if appname has a space
if: contains(inputs.appname, ' ')
if: contains(env.appname, ' ')
continue-on-error: true
shell: bash
run: |
@@ -222,47 +231,47 @@ jobs:
sed -i -e 's|reg delete HKEY_CLASSES_ROOT\\\\{ext} /f|reg delete \\\"HKEY_CLASSES_ROOT\\\\{ext}\\\" /f|' ./src/platform/windows.rs
- name: change company name
if: fromJson(inputs.extras).compname != 'Purslane Ltd'
if: env.compname != 'Purslane Ltd'
continue-on-error: true
shell: bash
run: |
sed -i -e 's|Purslane Ltd|${{ fromJson(inputs.extras).compname }}|' ./flutter/lib/desktop/pages/desktop_setting_page.dart
sed -i -e 's|PURSLANE|${{ fromJson(inputs.extras).compname }}|' ./res/msi/preprocess.py
sed -i -e 's|Purslane Ltd|${{ fromJson(inputs.extras).compname }}|' ./res/msi/preprocess.py
sed -i -e 's|"Copyright © 2025 Purslane Ltd. All rights reserved."|"Copyright © 2025 ${{ fromJson(inputs.extras).compname }}. All rights reserved."|' ./flutter/windows/runner/Runner.rc
sed -i -e 's|Purslane Ltd|${{ fromJson(inputs.extras).compname }}|' ./flutter/windows/runner/Runner.rc
sed -i -e 's|Purslane Ltd|${{ fromJson(inputs.extras).compname }}|' ./Cargo.toml
sed -i -e 's|Purslane Ltd|${{ fromJson(inputs.extras).compname }}|' ./libs/portable/Cargo.toml
sed -i -e 's|Purslane Ltd|${{ env.compname }}|' ./flutter/lib/desktop/pages/desktop_setting_page.dart
sed -i -e 's|PURSLANE|${{ env.compname }}|' ./res/msi/preprocess.py
sed -i -e 's|Purslane Ltd|${{ env.compname }}|' ./res/msi/preprocess.py
sed -i -e 's|"Copyright © 2025 Purslane Ltd. All rights reserved."|"Copyright © 2025 ${{ env.compname }}. All rights reserved."|' ./flutter/windows/runner/Runner.rc
sed -i -e 's|Purslane Ltd|${{ env.compname }}|' ./flutter/windows/runner/Runner.rc
sed -i -e 's|Purslane Ltd|${{ env.compname }}|' ./Cargo.toml
sed -i -e 's|Purslane Ltd|${{ env.compname }}|' ./libs/portable/Cargo.toml
- name: change url to custom
if: fromJson(inputs.extras).urlLink != 'https://rustdesk.com'
if: env.urlLink != 'https://rustdesk.com'
continue-on-error: true
shell: bash
run: |
sed -i -e 's|Homepage: https://rustdesk.com|Homepage: ${{ fromJson(inputs.extras).urlLink }}|' ./build.py
sed -i -e "s|launchUrl(Uri.parse('https://rustdesk.com'));|launchUrl(Uri.parse('${{ fromJson(inputs.extras).urlLink }}'));|" ./flutter/lib/common.dart
sed -i -e "s|launchUrlString('https://rustdesk.com');|launchUrlString('${{ fromJson(inputs.extras).urlLink }}');|" ./flutter/lib/desktop/pages/desktop_setting_page.dart
sed -i -e "s|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ fromJson(inputs.extras).urlLink }}/privacy.html')|" ./flutter/lib/desktop/pages/desktop_setting_page.dart
sed -i -e "s|const url = 'https://rustdesk.com/';|const url = '${{ fromJson(inputs.extras).urlLink }}';|" ./flutter/lib/mobile/pages/settings_page.dart
sed -i -e "s|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ fromJson(inputs.extras).urlLink }}/privacy.html')|" ./flutter/lib/mobile/pages/settings_page.dart
sed -i -e "s|https://rustdesk.com/privacy.html|${{ fromJson(inputs.extras).urlLink }}/privacy.html|" ./flutter/lib/desktop/pages/install_page.dart
sed -i -e 's|Homepage: https://rustdesk.com|Homepage: ${{ env.urlLink }}|' ./build.py
sed -i -e "s|launchUrl(Uri.parse('https://rustdesk.com'));|launchUrl(Uri.parse('${{ env.urlLink }}'));|" ./flutter/lib/common.dart
sed -i -e "s|launchUrlString('https://rustdesk.com');|launchUrlString('${{ env.urlLink }}');|" ./flutter/lib/desktop/pages/desktop_setting_page.dart
sed -i -e "s|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ env.urlLink }}/privacy.html')|" ./flutter/lib/desktop/pages/desktop_setting_page.dart
sed -i -e "s|const url = 'https://rustdesk.com/';|const url = '${{ env.urlLink }}';|" ./flutter/lib/mobile/pages/settings_page.dart
sed -i -e "s|launchUrlString('https://rustdesk.com/privacy.html')|launchUrlString('${{ env.urlLink }}/privacy.html')|" ./flutter/lib/mobile/pages/settings_page.dart
sed -i -e "s|https://rustdesk.com/privacy.html|${{ env.urlLink }}/privacy.html|" ./flutter/lib/desktop/pages/install_page.dart
- name: change download link to custom
if: fromJson(inputs.extras).downloadLink != 'https://rustdesk.com/download'
if: env.downloadLink != 'https://rustdesk.com/download'
continue-on-error: true
shell: bash
run: |
sed -i -e 's|https://rustdesk.com/download|${{ fromJson(inputs.extras).downloadLink }}|' ./flutter/lib/desktop/pages/desktop_home_page.dart
sed -i -e 's|https://rustdesk.com/download|${{ fromJson(inputs.extras).downloadLink }}|' ./flutter/lib/mobile/pages/connection_page.dart
sed -i -e 's|https://rustdesk.com/download|${{ fromJson(inputs.extras).downloadLink }}|' ./src/ui/index.tis
sed -i -e 's|https://rustdesk.com/download|${{ env.downloadLink }}|' ./flutter/lib/desktop/pages/desktop_home_page.dart
sed -i -e 's|https://rustdesk.com/download|${{ env.downloadLink }}|' ./flutter/lib/mobile/pages/connection_page.dart
sed -i -e 's|https://rustdesk.com/download|${{ env.downloadLink }}|' ./src/ui/index.tis
- name: set server, key, and apiserver
continue-on-error: true
shell: bash
run: |
sed -i -e 's|rs-ny.rustdesk.com|${{ inputs.server }}|' ./libs/hbb_common/src/config.rs
sed -i -e 's|OeVuKk5nlHiXp+APNn0Y3pC1Iwpwn44JGqrQCsWqmBw=|${{ inputs.key }}|' ./libs/hbb_common/src/config.rs
sed -i -e 's|https://admin.rustdesk.com|${{ inputs.apiServer }}|' ./src/common.rs
sed -i -e 's|rs-ny.rustdesk.com|${{ env.server }}|' ./libs/hbb_common/src/config.rs
sed -i -e 's|OeVuKk5nlHiXp+APNn0Y3pC1Iwpwn44JGqrQCsWqmBw=|${{ env.key }}|' ./libs/hbb_common/src/config.rs
sed -i -e 's|https://admin.rustdesk.com|${{ env.apiServer }}|' ./src/common.rs
# ./flutter/pubspec.yaml
#sed -i '/intl:/a \ \ archive: ^3.6.1' ./flutter/pubspec.yaml
@@ -287,7 +296,7 @@ jobs:
url: ${{ env.STATUS_URL }}
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "10% complete"}'
data: '{"uuid": "${{ env.uuid }}", "status": "10% complete"}'
- name: Install flutter
uses: subosito/flutter-action@v2.12.0 #https://github.com/subosito/flutter-action/issues/277
@@ -325,7 +334,7 @@ jobs:
url: ${{ env.STATUS_URL }}
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "15% complete"}'
data: '{"uuid": "${{ env.uuid }}", "status": "15% complete"}'
- uses: Swatinem/rust-cache@v2
with:
@@ -338,7 +347,7 @@ jobs:
url: ${{ env.STATUS_URL }}
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "20% complete"}'
data: '{"uuid": "${{ env.uuid }}", "status": "20% complete"}'
- name: Setup vcpkg with Github Actions binary cache
uses: lukka/run-vcpkg@v11
@@ -368,10 +377,10 @@ jobs:
shell: bash
- name: magick stuff
if: ${{ inputs.iconlink != 'false' }}
if: ${{ env.iconlink != 'false' }}
continue-on-error: true
run: |
Invoke-WebRequest -Uri ${{ fromJson(inputs.iconlink).url }}/get_png?filename=${{ fromJson(inputs.iconlink).file }}"&"uuid=${{ fromJson(inputs.iconlink).uuid }} -OutFile ./res/iconx.png
Invoke-WebRequest -Uri ${{ fromJson(env.iconlink).url }}/get_png?filename=${{ fromJson(env.iconlink).file }}"&"uuid=${{ fromJson(env.iconlink).uuid }} -OutFile ./res/iconx.png
mv ./res/icon.ico ./res/icon.ico.bak
mv ./res/icon.png ./res/icon.png.bak
mv ./res/tray-icon.ico ./res/tray-icon.ico.bak
@@ -389,7 +398,7 @@ jobs:
- name: ui.rs icon
if: ${{ inputs.iconlink != 'false' }}
if: ${{ env.iconlink != 'false' }}
continue-on-error: true
shell: bash
run: |
@@ -444,10 +453,10 @@ jobs:
url: ${{ env.STATUS_URL }}
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "25% complete"}'
data: '{"uuid": "${{ env.uuid }}", "status": "25% complete"}'
- name: replace flutter icons
if: ${{ inputs.iconlink != 'false' }}
if: ${{ env.iconlink != 'false' }}
continue-on-error: true
run: |
cd ./flutter
@@ -463,7 +472,7 @@ jobs:
url: ${{ env.STATUS_URL }}
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "50% complete, this step takes about 5 minutes, be patient."}'
data: '{"uuid": "${{ env.uuid }}", "status": "50% complete, this step takes about 5 minutes, be patient."}'
- name: Build rustdesk
run: |
@@ -506,17 +515,17 @@ jobs:
}
- name: icon stuff
if: ${{ inputs.iconlink != 'false' }}
if: ${{ env.iconlink != 'false' }}
continue-on-error: true
run: |
mv ./rustdesk/data/flutter_assets/assets/icon.svg ./rustdesk/data/flutter_assets/assets/icon.svg.bak
magick ./res/icon.png ./rustdesk/data/flutter_assets/assets/icon.svg
- name: logo stuff
if: ${{ inputs.logolink != 'false' }}
if: ${{ env.logolink != 'false' }}
continue-on-error: true
run: |
Invoke-WebRequest -Uri ${{ fromJson(inputs.logolink).url }}/get_png?filename=${{ fromJson(inputs.logolink).file }}"&"uuid=${{ fromJson(inputs.logolink).uuid }} -OutFile ./rustdesk/data/flutter_assets/assets/logo.png
Invoke-WebRequest -Uri ${{ fromJson(env.logolink).url }}/get_png?filename=${{ fromJson(env.logolink).file }}"&"uuid=${{ fromJson(env.logolink).uuid }} -OutFile ./rustdesk/data/flutter_assets/assets/logo.png
- name: find Runner.res
# Windows: find Runner.res (compiled from ./flutter/windows/runner/Runner.rc), copy to ./Runner.res
@@ -548,7 +557,7 @@ jobs:
url: ${{ env.STATUS_URL }}
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "70% complete, this step takes about 5 minutes, be patient."}'
data: '{"uuid": "${{ env.uuid }}", "status": "70% complete, this step takes about 5 minutes, be patient."}'
- name: zip dlls
continue-on-error: true
@@ -587,11 +596,11 @@ jobs:
shell: bash
if: env.UPLOAD_ARTIFACT == 'true'
run: |
mv "./rustdesk/rustdesk.exe" "./rustdesk/${{ inputs.appname }}.exe" || echo "rustdesk.exe"
mv "./rustdesk/rustdesk.exe" "./rustdesk/${{ env.appname }}.exe" || echo "rustdesk.exe"
sed -i '/dpiAware/d' res/manifest.xml
pushd ./libs/portable
pip3 install -r requirements.txt
python3 ./generate.py -f ../../rustdesk/ -o . -e "../../rustdesk/${{ inputs.appname }}.exe"
python3 ./generate.py -f ../../rustdesk/ -o . -e "../../rustdesk/${{ env.appname }}.exe"
popd
mkdir -p ./SignOutput
mv ./target/release/rustdesk-portable-packer.exe "./SignOutput/rustdesk.exe"
@@ -603,8 +612,8 @@ jobs:
continue-on-error: true
if: env.UPLOAD_ARTIFACT == 'true'
run: |
$myappname = "${{ inputs.appname }}" -replace '\s','_'
cp "rustdesk/${{ inputs.appname }}.exe" "rustdesk/${myappname}.exe" -ErrorAction SilentlyContinue
$myappname = "${{ env.appname }}" -replace '\s','_'
cp "rustdesk/${{ env.appname }}.exe" "rustdesk/${myappname}.exe" -ErrorAction SilentlyContinue
pushd ./res/msi
python preprocess.py --app-name "$myappname" --arp -d ../../rustdesk
nuget restore msi.sln
@@ -620,7 +629,7 @@ jobs:
url: ${{ env.STATUS_URL }}
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "85% complete"}'
data: '{"uuid": "${{ env.uuid }}", "status": "85% complete"}'
- name: zip exe and msi
continue-on-error: true
@@ -652,26 +661,26 @@ jobs:
- name: rename rustdesk.exe to filename.exe
run: |
mv ./SignOutput/rustdesk.exe "./SignOutput/${{ inputs.filename }}.exe" || echo "rustdesk"
mv ./SignOutput/rustdesk.exe "./SignOutput/${{ env.filename }}.exe" || echo "rustdesk"
- name: rename rustdesk.msi to filename.msi
continue-on-error: true
run: |
mv ./SignOutput/rustdesk.msi "./SignOutput/${{ inputs.filename }}.msi" || echo "rustdesk"
mv ./SignOutput/rustdesk.msi "./SignOutput/${{ env.filename }}.msi" || echo "rustdesk"
- name: send file to rdgen server
if: ${{ fromJson(inputs.extras).rdgen == 'true' }}
shell: bash
run: |
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./SignOutput/${{ inputs.filename }}.exe" -F "uuid=${{ inputs.uuid }}" ${{ secrets.GENURL }}/save_custom_client
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./SignOutput/${{ inputs.filename }}.msi" -F "uuid=${{ inputs.uuid }}" ${{ secrets.GENURL }}/save_custom_client || true
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./SignOutput/${{ env.filename }}.exe" -F "uuid=${{ env.uuid }}" ${{ secrets.GENURL }}/save_custom_client
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./SignOutput/${{ env.filename }}.msi" -F "uuid=${{ env.uuid }}" ${{ secrets.GENURL }}/save_custom_client || true
- name: send file to api server
if: ${{ fromJson(inputs.extras).rdgen == 'false' }}
shell: bash
run: |
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./SignOutput/${{ inputs.filename }}.exe" ${{ inputs.apiServer }}/api/save_custom_client
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./SignOutput/${{ inputs.filename }}.msi" ${{ inputs.apiServer }}/api/save_custom_client || true
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./SignOutput/${{ env.filename }}.exe" ${{ env.apiServer }}/api/save_custom_client
curl -i -X POST -H "Content-Type: multipart/form-data" -H "Authorization: Bearer ${{ fromJson(inputs.extras).token }}" -F "file=@./SignOutput/${{ env.filename }}.msi" ${{ env.apiServer }}/api/save_custom_client || true
- name: Report Status
uses: fjogeleit/http-request-action@v1
@@ -679,7 +688,7 @@ jobs:
url: ${{ env.STATUS_URL }}
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "Success"}'
data: '{"uuid": "${{ env.uuid }}", "status": "Success"}'
- name: failed
if: failure()
@@ -688,7 +697,7 @@ jobs:
url: ${{ env.STATUS_URL }}
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation failed, try again"}'
data: '{"uuid": "${{ env.uuid }}", "status": "Generation failed, try again"}'
- name: failed
if: cancelled()
@@ -697,4 +706,4 @@ jobs:
url: ${{ env.STATUS_URL }}
method: 'POST'
customHeaders: '{"Content-Type": "application/json"}'
data: '{"uuid": "${{ inputs.uuid }}", "status": "Generation cancelled, try again"}'
data: '{"uuid": "${{ env.uuid }}", "status": "Generation cancelled, try again"}'

View File

@@ -8,6 +8,8 @@ services:
GHUSER: "github_username"
GHBEARER: "github_access_token"
GENURL: "accessible_url_of_server"
RSA_PUBLIC_KEY: ""
GHBRANCH: "master"
PROTOCOL: "https"
REPONAME: "rdgen"
ports:

View File

@@ -24,6 +24,8 @@ SECRET_KEY = os.environ.get('SECRET_KEY','django-insecure-!(t-!f#6g#sr%yfded9(xh
GHUSER = os.environ.get("GHUSER", '')
GHBEARER = os.environ.get("GHBEARER", '')
GENURL = os.environ.get("GENURL", '')
GHBRANCH = os.environ.get("GHBRANCH",'master')
RSA_PUBLIC_KEY = os.environ.get("RSA_PUBLIC_KEY",'')
PROTOCOL = os.environ.get("PROTOCOL", 'https')
REPONAME = os.environ.get("REPONAME", 'rdgen')

View File

@@ -15,6 +15,7 @@ from .forms import GenerateForm
from .models import GithubRun
from PIL import Image
from urllib.parse import quote
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
@@ -194,18 +195,18 @@ def generator_view(request):
#github limits inputs to 10, so lump extras into one with json
extras = {}
extras['genurl'] = _settings.GENURL
#extras['genurl'] = _settings.GENURL
#extras['runasadmin'] = runasadmin
extras['urlLink'] = urlLink
extras['downloadLink'] = downloadLink
#extras['urlLink'] = urlLink
#extras['downloadLink'] = downloadLink
extras['delayFix'] = 'true' if delayFix else 'false'
extras['version'] = version
extras['rdgen'] = 'true'
extras['cycleMonitor'] = 'true' if cycleMonitor else 'false'
extras['xOffline'] = 'true' if xOffline else 'false'
extras['removeNewVersionNotif'] = 'true' if removeNewVersionNotif else 'false'
extras['compname'] = compname
extras['androidappid'] = androidappid
#extras['compname'] = compname
#extras['androidappid'] = androidappid
extra_input = json.dumps(extras)
####from here run the github action, we need user, repo, access token.
@@ -223,19 +224,27 @@ def generator_view(request):
url = 'https://api.github.com/repos/'+_settings.GHUSER+'/'+_settings.REPONAME+'/actions/workflows/generator-windows.yml/dispatches'
#url = 'https://api.github.com/repos/'+_settings.GHUSER+'/rustdesk/actions/workflows/test.yml/dispatches'
sensitive_fields = {
"server": server,
"key": key,
"apiServer": apiServer,
"iconlink": iconlink,
"logolink": logolink,
"appname": appname,
"filename": filename,
"genurl": _settings.GENURL,
"urlLink": urlLink,
"downloadLink": downloadLink, "compname": compname, "androidappid": androidappid,
"uuid":myuuid
}
hybrid_result = encrypt_payload_hybrid(sensitive_fields, _settings.GH_PUBLIC_KEY)
data = {
"ref":"master",
"ref": _settings.GHBRANCH,
"inputs":{
"server":server,
"key":key,
"apiServer":apiServer,
"payload": hybrid_result["encrypted_data"],
"wrapped_key": hybrid_result["encrypted_key"],
"custom":encodedCustom,
"uuid":myuuid,
"iconlink":iconlink,
"logolink":logolink,
"appname":appname,
"extras":extra_input,
"filename":filename
"extras":extra_input
}
}
#print(data)
@@ -417,3 +426,25 @@ def save_custom_client(request):
f.write(chunk)
return HttpResponse("File saved successfully!")
def encrypt_payload_hybrid(data_dict, public_key_pem):
session_key = Fernet.generate_key()
fernet = Fernet(session_key)
json_data = json.dumps(data_dict).encode()
encrypted_data = fernet.encrypt(json_data)
public_key = serialization.load_pem_public_key(public_key_pem.encode())
encrypted_session_key = public_key.encrypt(
session_key,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
return {
"encrypted_data": base64.b64encode(encrypted_data).decode('utf-8'),
"encrypted_key": base64.b64encode(encrypted_session_key).decode('utf-8')
}