Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
df570bd
ci: unbreak GitHub Actions build
bwdiehl Sep 14, 2026
6cd382a
ci: move first-party and docker actions to node24 majors
bwdiehl Sep 14, 2026
8494e36
ci: replace third-party uploader with actions/upload-artifact@v7
bwdiehl Sep 14, 2026
a266861
buildenv: fix two of three corecrypto build failures (does NOT close …
bwdiehl Sep 14, 2026
b885501
anisette: make Linux anisette failures legible, and fix two real bugs
bwdiehl Sep 14, 2026
301eb8b
daemon: warn at startup when no anisette server is configured, and ad…
bwdiehl Sep 14, 2026
6be911b
REVIVAL.md: record the actual deployment target
bwdiehl Sep 14, 2026
d674cd1
REVIVAL.md: fix TODO numbering
bwdiehl Sep 14, 2026
8674780
REVIVAL.md: network topology resolved -- VM is bridged, same segment …
bwdiehl Sep 14, 2026
60c2c56
REVIVAL.md: multicast confirmed, and mDNS advertisement fails silently
bwdiehl Sep 14, 2026
04e928a
dnssd: detect and report mDNS advertisement failure instead of silent…
bwdiehl Sep 14, 2026
cc011dd
REVIVAL.md: fill in the commit SHA for the dnssd fix
bwdiehl Sep 14, 2026
ebfbc5b
gitignore: ignore macOS .DS_Store and AppleDouble files
bwdiehl Sep 14, 2026
fa1a0a0
REVIVAL.md: record two future goals -- self-contained deploy, and a w…
bwdiehl Sep 14, 2026
6663597
REVIVAL.md: correct the refresh-path analysis -- #131 is bootstrap-on…
bwdiehl Sep 14, 2026
d094368
REVIVAL.md: record the full deployment research -- prereqs and silent…
bwdiehl Sep 14, 2026
0e8090b
ldid: fix the iOS 26 hash-agility truncation (issue #131)
bwdiehl Sep 14, 2026
ca2022c
REVIVAL.md: correct the #131 commit SHA
bwdiehl Sep 14, 2026
04dd7ee
Clear the last two bootstrap blockers: GSA client-info, and argv parsing
bwdiehl Sep 14, 2026
907e7fe
REVIVAL.md: record the bootstrap-blocker commit SHA
bwdiehl Sep 14, 2026
790973d
buildenv: fix corecrypto layer 3, and add BOOTSTRAP.md
bwdiehl Sep 14, 2026
dbb9977
REVIVAL.md: corecrypto fully builds -- #111 closed
bwdiehl Sep 14, 2026
cd137ba
BOOTSTRAP.md: do not enable usbmuxd on Ubuntu -- it is udev-activated
bwdiehl Sep 14, 2026
bbb3c03
BOOTSTRAP.md: install jq, which the Phase 2 anisette checks use
bwdiehl Sep 14, 2026
6bad8a9
BOOTSTRAP.md: how to get the binary onto the VM, and what belongs in …
bwdiehl Sep 14, 2026
fe5cda3
BOOTSTRAP.md: Safari auto-expands the artifact, and how to verify the…
bwdiehl Sep 14, 2026
061af4c
argv: register --help as a long option
bwdiehl Sep 14, 2026
957f903
REVIVAL.md: record bootstrap progress -- phases 0, 1 and 3 complete
bwdiehl Sep 14, 2026
b49d922
BOOTSTRAP.md: the anisette persistence check could report success on …
bwdiehl Sep 14, 2026
3cd30ac
Phase 2: a Portainer stack for anisette, and the volume path the docs…
bwdiehl Sep 14, 2026
2fd4a92
REVIVAL.md: anisette deployed and verified; the GSA sanitizer is load…
bwdiehl Sep 14, 2026
9fbf8b7
BOOTSTRAP.md: make the Phase 4 command paste-safe, and keep the passw…
bwdiehl Sep 14, 2026
118e9fb
altsign: report a non-200 from Apple's auth endpoint instead of "inva…
bwdiehl Sep 14, 2026
4f40fdd
argv: accept credentials from the environment, not only from argv
bwdiehl Sep 14, 2026
1fe89a3
Containerise AltServer: image, combined stack, and a publish workflow
bwdiehl Sep 14, 2026
6e2d81d
REVIVAL.md: PR #135's GSA client-info block is CONFIRMED against real…
bwdiehl Sep 14, 2026
5b4fe84
web: status dashboard -- slice 1 of the setup portal
bwdiehl Sep 14, 2026
af35345
web: pairing wizard, and a draft confirmation for upstream PR #135
bwdiehl Sep 14, 2026
725677d
README: correct the parts that were actively wrong, document what is …
bwdiehl Sep 14, 2026
3f29bcb
web: pairing wizard detects an existing backup instead of nagging
bwdiehl Sep 14, 2026
eb053f1
altsign: give every GrandSlam request its own connection (the 429 fix)
bwdiehl Sep 14, 2026
24fbae9
docs: zero-credential probe for the GrandSlam connection-reuse theory
bwdiehl Sep 14, 2026
1b9b8d5
docs: the probe must skip TLS validation, as AltServer does
bwdiehl Sep 14, 2026
887d459
REVIVAL.md: connection-reuse cause PROVEN, at zero cost to the Apple ID
bwdiehl Sep 14, 2026
38bddab
ci: do not cancel sibling build legs when one fails
bwdiehl Sep 14, 2026
7f2032e
deploy: named volumes, so the stack needs no host prep at all
bwdiehl Sep 14, 2026
215885a
image: fetch the current AltStore IPA automatically on start
bwdiehl Sep 14, 2026
5e41eee
web: install flow with 2FA entry -- slice 3, the setup portal is comp…
bwdiehl Sep 14, 2026
023755c
ci: build amd64 only on branch pushes, all four on tags
bwdiehl Sep 14, 2026
663cfaf
deploy: run the web UI as a stack service, reachable at http://<host>…
bwdiehl Sep 14, 2026
f6e98de
README: rewrite for the current state of the fork
bwdiehl Sep 14, 2026
9baa62b
web: serve concurrently, and make install errors visible
bwdiehl Sep 14, 2026
d7e3da5
web: auto-populate the device UDID on the install page
bwdiehl Sep 14, 2026
a79aab5
web: fix two status checks that were reporting nonsense
bwdiehl Sep 14, 2026
70b646e
deploy: mDNS from a container needs AppArmor rules -- ship a tested p…
bwdiehl Sep 14, 2026
45486e5
REVIVAL.md: bring the log up to date through the AppArmor finding
bwdiehl Sep 14, 2026
501e40f
web: fix a JavaScript syntax error that broke every page script
bwdiehl Sep 14, 2026
f7f3130
ci: rebuild the image when web/, the entrypoint or the submodule change
bwdiehl Sep 14, 2026
503225f
REVIVAL.md: record the stale-image and JS-escape findings
bwdiehl Sep 14, 2026
cfda5b2
Add two CI guards for the failures that reported success
bwdiehl Sep 14, 2026
e21b261
Add netmuxd: wireless device transport for unattended refresh
bwdiehl Sep 14, 2026
3cefd9e
Bump runtime base to trixie: netmuxd needs glibc 2.38
bwdiehl Sep 14, 2026
06f0314
REVIVAL.md: record the refresh-path investigation
bwdiehl Sep 14, 2026
3616c91
Fix duplicate depends_on key, and guard against the class
bwdiehl Sep 14, 2026
033cb73
Fix wireless refresh: parse usbmux network addresses in both sockaddr…
bwdiehl Sep 15, 2026
55bf6be
Rebuild the image when libraries/ changes, and derive that rule from …
bwdiehl Sep 15, 2026
25cc99e
Require a bare filter entry for submodules that are themselves compil…
bwdiehl Sep 15, 2026
ef5deec
Wireless refresh confirmed working on the deployed stack
bwdiehl Sep 15, 2026
b7da4ea
Fix a reachability check that could never pass, and put nav tabs on e…
bwdiehl Sep 15, 2026
dbd1df2
Drop the 4-hourly scheduled build
bwdiehl Sep 15, 2026
9eca755
Merge pull request #2 from Ben-Diehlci/bd/revival
Ben-Diehlci Sep 15, 2026
b4767eb
REVIVAL.md: record the post-merge repository audit as a tracked check…
bwdiehl Sep 15, 2026
9b6d0c0
Redact the anisette identifiers the install page was printing, and sc…
bwdiehl Sep 15, 2026
e6f3d2d
Repair the commit SHAs the history rewrite invalidated
bwdiehl Sep 15, 2026
ccb2489
REVIVAL.md: record where credentials actually live, on the server not…
bwdiehl Sep 15, 2026
9cd0399
gitignore: refuse the file classes that would leak credentials or ide…
bwdiehl Sep 15, 2026
2f07f58
Rewrite BOOTSTRAP.md as a guide someone else can actually follow
bwdiehl Sep 15, 2026
5db98d1
Close the remaining audit items, and tidy the repository layout
bwdiehl Sep 15, 2026
5702f8a
REVIVAL.md: close the wireless-refresh TODO, which was confirmed two …
bwdiehl Sep 15, 2026
e991c23
Make rewrite_altserver_source.py fail loudly, the last rewriter that …
bwdiehl Sep 15, 2026
326bbc6
Build the sub-make once, give Linux recovery advice, and ship a crede…
bwdiehl Sep 15, 2026
94493ed
credential-hygiene: fix a double-counted grep result, and label skipp…
bwdiehl Sep 15, 2026
eccd51b
buildenv: push to the repo owner's namespace, not a hardcoded one
bwdiehl Sep 15, 2026
adce684
buildenv: build amd64 first, so a QEMU failure does not cost the imag…
bwdiehl Sep 15, 2026
b1ec101
Build against this fork's own toolchain images, not another account's
bwdiehl Sep 15, 2026
39b2263
Stop credentials reaching docker logs, and bound the logs that remain
bwdiehl Sep 15, 2026
104a98c
credential-hygiene: stop counting redacted lines as leaks
bwdiehl Sep 15, 2026
2c7109f
stack: select the AppArmor profile by variable instead of by editing …
bwdiehl Sep 15, 2026
14e3bde
apparmor: verify the profile loaded against the kernel, not against a…
bwdiehl Sep 15, 2026
27b0d33
tests: use synthetic fixtures -- the old ones were a real anisette id…
bwdiehl Sep 15, 2026
c94b31f
web: look for the phone on both transports, not just USB
bwdiehl Sep 15, 2026
fbcd9ca
web: live log view on the status page, for watching a refresh happen
bwdiehl Sep 15, 2026
e1dfbd9
apparmor: allow Avahi SIGNALS, which carry a unique sender name
bwdiehl Sep 16, 2026
b116faa
web: run the status checks in parallel, not in series
bwdiehl Sep 16, 2026
40a8b4d
Remove the last two real values: a profile UUID and the device mDNS name
bwdiehl Sep 16, 2026
0512e57
README: lead with what it does, not with a changelog
bwdiehl Sep 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.git
build/
*.o
.DS_Store
._*
__pycache__/
*.pyc
docs/
166 changes: 140 additions & 26 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,104 @@ on:
workflow_dispatch:
inputs:
sync_upstream:
description: 'Also check upstream_repo for new commits and sync if it changed'
required: false
type: boolean
default: false
all_arches:
description: 'Build every architecture, not just amd64'
required: false
type: boolean
default: false
debug_enabled:
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
required: false
default: false
repository_dispatch:

schedule:
- cron: "0 */4 * * *" # min hour day week year
# NO schedule. This used to run `cron: "0 */4 * * *"` -- 6 times a day, ~180 runs a month --
# watching the upstream_repo submodule, which is rileytestut/AltServer-Windows, NOT this repo's
# upstream (NyaMisty/AltServer-Linux). AltServer-Windows has not moved since 071b1dd on
# 2022-04-25, so every one of those runs found nothing.
#
# Removed for a second and better reason than noise. When it DID find a commit it ran
# `git submodule update --remote -- upstream_repo` and built all four architectures from that
# newer source WITHOUT committing it, so a published artifact could come from code no commit in
# this repo describes. The build rewrites those sources textually
# (makefiles/rewrite_altserver_source.py), and that rewriter has no match guards at all, so an
# upstream move could change what the binary does with nothing failing -- see the TODO in
# REVIVAL.md. An unattended job is the worst place for that.
#
# Nothing is lost: the same check still runs on demand via the `sync_upstream` input above. The
# `github.event_name == 'schedule'` conditions in the check and matrix_setup jobs are left in
# place, so restoring the cron here is the only edit needed to bring the old behaviour back.


env:
REGISTRY: ghcr.io

jobs:
# Two guards for failures that were invisible while everything reported success. They live HERE,
# in the workflow with no paths: filter, because one of them detects a broken paths: filter --
# a guard inside build_image.yml would be skipped by exactly the bug it is meant to catch.
#
# Fast and dependency-free, so they gate nothing and cost nothing.
guards:
runs-on: ubuntu-latest
name: "Guards"
permissions:
contents: read
steps:
- uses: actions/checkout@v7

# An omitted paths: entry meant five commits of web fixes never reached a published image,
# while CI stayed green and the deployment kept serving the old code.
- name: Everything copied into the image triggers a rebuild
run: python3 tests/check_workflow_paths.py

# A literal newline inside a JS string literal once killed an entire <script> block. The
# Python was well tested; nothing ever parsed what the browser actually runs.
- name: Generated pages emit valid JavaScript
run: python3 tests/check_page_js.py

# A duplicate mapping key shipped because yaml.safe_load keeps the last one instead of
# erroring, so the stack only broke at deploy time inside Portainer.
- name: Compose files load the way Docker loads them
run: |
python3 -m pip install --quiet --disable-pip-version-check pyyaml
python3 tests/check_compose.py

# A usbmux network address is a raw sockaddr in the layout of whichever host produced it, and
# the vendored parser understood only the BSD one -- so every Wi-Fi refresh failed as a device
# fault while the phone sat plainly visible in the device list. Needs the real submodule
# source, because the guard also proves the rewriter still matches it.
- name: Fetch the libimobiledevice submodule
run: git submodule update --init --depth 1 libraries/libimobiledevice

- name: usbmux network addresses parse in both sockaddr layouts
run: python3 tests/check_conn_data_layout.py

# installer.py's docstring promised every line was filtered while it printed the anisette
# MachineID, one-time password and local user ID in full, into a page served over plain HTTP.
# This feeds it real captured output and fails if any secret value survives.
- name: Install-log redaction actually redacts
run: python3 tests/check_redaction.py

check:
runs-on: ubuntu-latest
name: "Check Upstream Updates"
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v7
with:
fetch-depth: 0
submodules: recursive

- name: Check If Need Checking
id: needCheck
if: ${{ github.event_name == 'schedule' || ( github.event_name == 'workflow_dispatch' && github.event.inputs.sync_upstream ) }}
if: ${{ github.event_name == 'schedule' || ( github.event_name == 'workflow_dispatch' && inputs.sync_upstream ) }}
run: |
echo "needCheck=1" >> $GITHUB_ENV

Expand All @@ -54,31 +123,69 @@ jobs:
git submodule update --init
if [[ "$current_upstream" != "$new_upstream" ]]; then
echo "Upstream got new commits, go updating!"
echo "::set-output name=updated::1"
echo "updated=1" >> $GITHUB_OUTPUT
else
echo "Upstream no change~"
echo "::set-output name=updated::0"
echo "updated=0" >> $GITHUB_OUTPUT
fi
else
echo "Needn't to check changes, directly return~"
echo "::set-output name=updated::0"
echo "updated=0" >> $GITHUB_OUTPUT
fi

- uses: gautamkrishnar/keepalive-workflow@master
with:
commit_message: "[proj] keepalive-workflow auto commit"
outputs:
updated: ${{ steps.check.outputs.updated }}

# Decides which architectures to build. amd64 alone for ordinary branch pushes, which is what
# day-to-day iteration actually consumes; the full set for tags (the release job needs all four),
# for the scheduled upstream-sync run, and on demand via the all_arches input.
#
# The emulated legs (armv7, aarch64, i386 run under QEMU on x86 runners) take several times
# longer than amd64, so paying for them on every push is pure latency for no benefit -- but
# dropping them entirely would make this fork useless on a Raspberry Pi, which is much of the
# point of AltServer-Linux.
matrix_setup:
runs-on: ubuntu-latest
name: "Select architectures"
permissions:
contents: read
outputs:
matrix: ${{ steps.pick.outputs.matrix }}
steps:
- name: Pick architectures
id: pick
run: |
AMD64='{"arch":"amd64","builder":"ghcr.io/ben-diehlci/altserver_builder_alpine_amd64"}'
AARCH64='{"arch":"aarch64","builder":"ghcr.io/ben-diehlci/altserver_builder_alpine_aarch64"}'
ARMV7='{"arch":"armv7","builder":"ghcr.io/ben-diehlci/altserver_builder_alpine_armv7"}'
I386='{"arch":"i386","builder":"ghcr.io/ben-diehlci/altserver_builder_alpine_i386"}'

if [[ "${{ github.ref }}" == refs/tags/* ]] \
|| [[ "${{ github.event_name }}" == "schedule" ]] \
|| [[ "${{ inputs.all_arches }}" == "true" ]]; then
echo "Building ALL architectures"
echo "matrix={\"include\":[$ARMV7,$AARCH64,$AMD64,$I386]}" >> "$GITHUB_OUTPUT"
else
echo "Branch push: building amd64 only. Use the all_arches input, or push a tag, for the full set."
echo "matrix={\"include\":[$AMD64]}" >> "$GITHUB_OUTPUT"
fi

build:
needs: [check]
needs: [check, matrix_setup]
strategy:
matrix:
builder: [ghcr.io/nyamisty/altserver_builder_alpine_armv7, ghcr.io/nyamisty/altserver_builder_alpine_aarch64, ghcr.io/nyamisty/altserver_builder_alpine_amd64, ghcr.io/nyamisty/altserver_builder_alpine_i386]
# Do not cancel the other legs when one fails: the emulated architectures are the most
# likely to break, and killing a good amd64 build because armv7 died wastes the useful one.
fail-fast: false
# Computed by matrix_setup above. Each leg carries a short `arch` label because
# actions/upload-artifact rejects '/' and ':' in artifact names, so the image reference
# cannot be used as the name.
matrix: ${{ fromJSON(needs.matrix_setup.outputs.matrix) }}
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v7
with:
fetch-depth: 0
submodules: recursive
Expand All @@ -88,9 +195,9 @@ jobs:
git submodule update --remote -- upstream_repo
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v4
- name: Log in to the Container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
Expand All @@ -106,21 +213,24 @@ jobs:
sudo rm -rf build
git clean -fdX
- name: Upload to github artifact
uses: NyaMisty/upload-artifact-as-is@master
uses: actions/upload-artifact@v7
with:
name: AltServer-${{ matrix.arch }}
path: /tmp/build_output

release:
runs-on: ubuntu-latest
if: ${{ startsWith(github.ref, 'refs/tags/') }}
needs: [build]
name: "release"
permissions:
contents: write
steps:
- name: "Create artifact directory"
run: |
mkdir -p build_output
- name: "Download all artifacts"
uses: actions/download-artifact@v2
uses: actions/download-artifact@v8
with:
path: build_output
- name: "Rearrange artifacts"
Expand All @@ -131,7 +241,8 @@ jobs:
ls build_release
if [ "$(ls -A build_release)" ]; then exit 0; else exit 1; fi
- name: Release
uses: softprops/action-gh-release@v1
# Pinned to a commit, not the v3 tag: a tag is mutable, and this job publishes releases.
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3
with:
files: build_release/*
env:
Expand All @@ -141,9 +252,11 @@ jobs:
runs-on: ubuntu-latest
needs: [check, build]
if: ${{ needs.check.outputs.updated == '1' }}
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v7
with:
fetch-depth: 0
submodules: recursive
Expand All @@ -153,9 +266,10 @@ jobs:
git config --local user.name "github-actions[bot]"
git submodule update --remote -- upstream_repo
git commit -m "[server] Sync Upstream Repo commit" upstream_repo
# Plain git push rather than a third-party action. ad-m/github-push-action@master was
# unpinned -- a floating branch ref from another account, running in a job that holds
# `contents: write` and is handed GITHUB_TOKEN. Whatever that branch pointed at on the day
# would have run with permission to rewrite this repo. actions/checkout already persists
# credentials, so nothing is gained by delegating the push.
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ github.ref }}

run: git push origin HEAD:${{ github.ref }}
13 changes: 7 additions & 6 deletions .github/workflows/build_docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,30 @@ env:
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v7
with:
ref: master # set the branch to merge to
fetch-depth: 0
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v4
#-
# uses: docker/setup-buildx-action@v1
# uses: docker/setup-buildx-action@v4
# id: buildx
# with:
# install: true
-
name: Available platforms
run: echo ${{ steps.buildx.outputs.platforms }}
- name: Log in to the Container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build & Push Dockers
run: cd ./buildenv && bash ./build_docker.sh

Loading