Skip to content

packaging: include amuleweb on Windows + alc / alcc / cas / wxcas on every platform - #785

Merged
mrjimenez merged 1 commit into
amule-project:masterfrom
got3nks:fix/packaging-include-utility-binaries
May 31, 2026
Merged

packaging: include amuleweb on Windows + alc / alcc / cas / wxcas on every platform#785
mrjimenez merged 1 commit into
amule-project:masterfrom
got3nks:fix/packaging-include-utility-binaries

Conversation

@got3nks

@got3nks got3nks commented May 31, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #781. ngosang reported that the GHA-built packages omit the four src/utils/ utility binaries (alc, alcc, cas, wxcas) on every platform, and amuleweb specifically on Windows. They're all light, fully in-tree, and don't need any deps the packaging environment isn't already pulling in for amule itself (libgd is present on Windows via the existing pacman list, on macOS via brew, on Linux AppImage via apt, and on Flatpak as a build module).

Changes

File Change
packaging/windows/build.sh Add BUILD_WEBSERVER, BUILD_CAS, BUILD_WXCAS, BUILD_ALC, BUILD_ALCC to the cmake configure. cmake --install already drops everything into bin\.
packaging/macos/build.sh Same four BUILD_* (WEBSERVER was already there). Replace the flat src/<bin> lookup in the .app-bundle copy loop with explicit paths since the utility tools live deeper in src/utils/<tool>/[src/]<tool>.
packaging/linux/appimage/build.sh Same four BUILD_*. Extend EXTRA_BINS so linuxdeploy bundles their .so deps.
packaging/linux/appimage/AppRun Extend the argv[0]-dispatch case so a symlink to cas / wxcas / alc / alcc invokes the right binary.
packaging/linux/flatpak/org.amule.aMule.yaml.in Same four BUILD_* to config-opts. libgd is already in the manifest.

Test plan

  • cmake configure on macOS accepts all the new flags
  • alc, alcc, cas, wxcas all build and link on macOS
  • Windows + Linux artifact verification on the next packaging run (triggered against this branch on the fork)
  • Field check by @ngosang that the artifacts now contain all ten binaries

Targets all ten of the binaries he listed: amule, amuled, amulegui, amuleweb, amulecmd, ed2k, alc, alcc, wxcas, cas.

           on every platform (amule-project#781)

ngosang flagged that the GHA-built packages on every platform omit
the four src/utils/ binaries (alc, alcc, cas, wxcas), and that
Windows specifically also omits amuleweb. They're all light, fully
in-tree, and don't require any deps the packaging environment isn't
already pulling in (libgd is installed for amule itself on Windows
GHA via pacman, on macOS via brew, on Linux AppImage via apt, and
on Flatpak as a build module).

Wire them up across every packaging recipe:

  packaging/windows/build.sh -- add BUILD_WEBSERVER, BUILD_CAS,
    BUILD_WXCAS, BUILD_ALC, BUILD_ALCC to the cmake configure.
    `cmake --install` already drops everything into bin\, so no
    further changes needed.

  packaging/macos/build.sh -- add the same four BUILD_* (BUILD_WEBSERVER
    was already there).  Replace the flat 'src/<bin>' lookup in the
    .app-bundle copy loop with explicit paths, since the utility
    tools live deeper in src/utils/<tool>/[src/]<tool>.

  packaging/linux/appimage/build.sh -- add the four BUILD_*.  Extend
    EXTRA_BINS so linuxdeploy bundles their .so deps.

  packaging/linux/appimage/AppRun -- extend the argv[0]-dispatch
    case so a symlink / rename to cas / wxcas / alc / alcc invokes
    the right binary.

  packaging/linux/flatpak/org.amule.aMule.yaml.in -- add the four
    BUILD_* to config-opts.  libgd is already in the manifest.

Verified locally on macOS: cmake configure clean with all flags,
all four utility tools build and link.  Windows and Linux are
artifact-side verification on the next packaging run.
Comment thread packaging/macos/build.sh
# path list rather than the previous flat src/<bin> assumption.
echo "==> Copying auxiliary binaries into aMule.app"
local bin_paths=(
src/amuled

@ngosang ngosang May 31, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@got3nks amulegui is not need here?

@mrjimenez
mrjimenez merged commit cf09aaa into amule-project:master May 31, 2026
7 checks passed
@got3nks

got3nks commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

Ran the full verification across both packaging runs to confirm the 10-binary lineup ships on every flavour. Downloaded every artefact from runs 26717127681 (master post-merge) and 26720270704 (post-merge + #794 macOS path fix) and inspected the bin layouts:

Platform aMule aMuled aMuleGUI amulecmd amuleweb ed2k alc alcc cas wxcas
Windows portable x64
Windows portable arm64
Windows installer x64
Windows installer arm64
AppImage x86_64
AppImage aarch64
Flatpak x86_64
Flatpak aarch64
macOS Universal2 (with #794) ✓ (own aMuleGUI.app)

Notes from the inspection:

  • Windows installer (NSIS .exe) content was confirmed identical to the portable .zip — installer.nsi uses File /r "${INSTROOT}\*.*" over the same cmake --install tree, so it carries the full ten binaries by construction.
  • AppImages were verified by extracting the squashfs payload and listing usr/bin/ (offset-anchored unsquashfs on both x86_64 and aarch64).
  • Flatpaks were installed via flatpak install --user --bundle (cross-arch worked for the x86_64 bundle on an aarch64 host) and listed under ~/.local/share/flatpak/app/org.amule.aMule/<arch>/master/active/files/bin/.
  • macOS aMule.app/Contents/MacOS/ showed nine binaries on the first run (missing amuleweb) because bin_paths pointed at src/amuleweb while cmake builds it at src/webserver/src/amuleweb — fixed in fix(packaging/macos): correct amuleweb build path so it ships in the .dmg #794, verified clean on the second run.

Closes the verification ask in your review. Once #794 merges, every release artefact ships the full amule + amuled + amulegui + amulecmd + amuleweb + ed2k + alc + alcc + cas + wxcas lineup.

mrjimenez pushed a commit that referenced this pull request May 31, 2026
….dmg

The bin_paths copy loop in packaging/macos/build.sh listed
`src/amuleweb`, but cmake builds amuleweb at
`src/webserver/src/amuleweb` (its CMakeLists.txt lives under
src/webserver/src/, see src/CMakeLists.txt subdirectory handling).
The `[[ -x "${src}" ]]` guard in the copy loop silently skipped
the missing path on every macOS build, so the dmg has been
shipping without amuleweb.

Pre-#785 this affected the simpler `for bin in amuled amulecmd
amuleweb ed2k` loop with the same broken path. #785 made the
array explicit for the four utility binaries (cas / wxcas / alc
/ alcc) which live under src/utils/<tool>, but kept amuleweb at
the old wrong path, so the regression-from-omission persisted.

Verified empty against run 26717127681 artefacts: macOS Universal2
dmg + per-arch macos-app-{x86_64,arm64} all missing amuleweb
while every other build flavour (Windows portable / installer,
AppImage, Flatpak) shipped the full ten-binary lineup. Build
log confirms amuleweb itself builds fine on macOS — only the
copy step misses it.
@got3nks
got3nks deleted the fix/packaging-include-utility-binaries branch June 3, 2026 14:16
got3nks added a commit to got3nks/amule that referenced this pull request Jun 4, 2026
…ndex

Adds 55+ merged PRs to the 3.0.0 changelog since the last update
(amule-project#747, 2026-05-27). Narrative additions cover:

- Packaging: expanded the top list to include the macOS per-arch .app
  bundles and the Windows NSIS installer alongside the existing
  AppImage / Flatpak / .dmg / .zip entries. New bullets for amule-project#785
  (alc/alcc/cas/wxcas everywhere + Windows amuleweb), amule-project#794 (.dmg
  amuleweb path), amule-project#789 (<OS>-<arch> artifact naming), amule-project#780 / amule-project#796
  (Windows DPI + comctl32 manifest), amule-project#784 (FHS share/amule paths).

- Bug Fixes & Stability: post-amule-project#744 fixes including EC notification
  leak (amule-project#797), big-library scaling (amule-project#736, amule-project#840 superseding amule-project#728),
  amulegui ghost entries (amule-project#810, amule-project#819, amule-project#841, amule-project#824, amule-project#830, amule-project#760),
  PartFile early hash (amule-project#762), server protocol fixes (amule-project#835, amule-project#788,
  amule-project#721, amule-project#787), crypto stream UB (amule-project#779), UAF prevention (amule-project#756),
  Kad rotation (amule-project#795, amule-project#799/amule-project#805), GTK warning silencing (amule-project#833,
  amule-project#826/amule-project#836), and the clang-tidy worklist (amule-project#770, amule-project#772-amule-project#774).

- Translations: late-cycle wave covering French/Turkish manpages
  (amule-project#753/amule-project#754/amule-project#776), Galician (amule-project#763), Slovenian (amule-project#771), pt-BR
  (amule-project#768/amule-project#775/amule-project#812), French (amule-project#811), plus man-page tooling for
  date+version drift (amule-project#802).

- Contributors: added ngosang for UX feedback on the late-3.0
  cycle (amule-project#817/amule-project#818/amule-project#821/amule-project#828/amule-project#844) and ongoing work on the
  user-facing manual at amule-org.github.io.

- Merged PRs flat index: extended with amule-project#746-amule-project#845 + amule-project#841.
got3nks added a commit to got3nks/amule that referenced this pull request Jun 4, 2026
…ndex

Adds 55+ merged PRs to the 3.0.0 changelog since the last update
(amule-project#747, 2026-05-27). Narrative additions cover:

- Packaging: expanded the top list to include the macOS per-arch .app
  bundles and the Windows NSIS installer alongside the existing
  AppImage / Flatpak / .dmg / .zip entries. New bullets for amule-project#785
  (alc/alcc/cas/wxcas everywhere + Windows amuleweb), amule-project#794 (.dmg
  amuleweb path), amule-project#789 (<OS>-<arch> artifact naming), amule-project#780 / amule-project#796
  (Windows DPI + comctl32 manifest), amule-project#784 (FHS share/amule paths).

- Bug Fixes & Stability: post-amule-project#744 fixes including EC notification
  leak (amule-project#797), big-library scaling (amule-project#736, amule-project#840 superseding amule-project#728),
  amulegui ghost entries (amule-project#810, amule-project#819, amule-project#841, amule-project#824, amule-project#830, amule-project#760),
  PartFile early hash (amule-project#762), server protocol fixes (amule-project#835, amule-project#788,
  amule-project#721, amule-project#787), crypto stream UB (amule-project#779), UAF prevention (amule-project#756),
  Kad rotation (amule-project#795, amule-project#799/amule-project#805), GTK warning silencing (amule-project#833,
  amule-project#826/amule-project#836), and the clang-tidy worklist (amule-project#770, amule-project#772-amule-project#774).

- Translations: late-cycle wave covering French/Turkish manpages
  (amule-project#753/amule-project#754/amule-project#776), Galician (amule-project#763), Slovenian (amule-project#771), pt-BR
  (amule-project#768/amule-project#775/amule-project#812), French (amule-project#811), plus man-page tooling for
  date+version drift (amule-project#802).

- Contributors: added ngosang for UX feedback on the late-3.0
  cycle (amule-project#817/amule-project#818/amule-project#821/amule-project#828/amule-project#844) and ongoing work on the
  user-facing manual at amule-org.github.io.

- Merged PRs flat index: extended with amule-project#746-amule-project#845 + amule-project#841.
mrjimenez pushed a commit that referenced this pull request Jun 4, 2026
Adds 55+ merged PRs to the 3.0.0 changelog since the last update
(#747, 2026-05-27). Narrative additions cover:

- Packaging: expanded the top list to include the macOS per-arch .app
  bundles and the Windows NSIS installer alongside the existing
  AppImage / Flatpak / .dmg / .zip entries. New bullets for #785
  (alc/alcc/cas/wxcas everywhere + Windows amuleweb), #794 (.dmg
  amuleweb path), #789 (<OS>-<arch> artifact naming), #780 / #796
  (Windows DPI + comctl32 manifest), #784 (FHS share/amule paths).

- Bug Fixes & Stability: post-#744 fixes including EC notification
  leak (#797), big-library scaling (#736, #840 superseding #728),
  amulegui ghost entries (#810, #819, #841, #824, #830, #760),
  PartFile early hash (#762), server protocol fixes (#835, #788,
  #721, #787), crypto stream UB (#779), UAF prevention (#756),
  Kad rotation (#795, #799/#805), GTK warning silencing (#833,
  #826/#836), and the clang-tidy worklist (#770, #772-#774).

- Translations: late-cycle wave covering French/Turkish manpages
  (#753/#754/#776), Galician (#763), Slovenian (#771), pt-BR
  (#768/#775/#812), French (#811), plus man-page tooling for
  date+version drift (#802).

- Contributors: added ngosang for UX feedback on the late-3.0
  cycle (#817/#818/#821/#828/#844) and ongoing work on the
  user-facing manual at amule-org.github.io.

- Merged PRs flat index: extended with #746-#845 + #841.
mrjimenez pushed a commit to mrjimenez/amule that referenced this pull request Aug 5, 2026
…mule-project#785)

* feat(ec): X25519 and key-confirmation primitives for forward secrecy

Groundwork only: the primitives and their wire tags, with no handshake
wired to them yet, so this changes no behaviour on its own.

The session key is currently derived from the EC credential, which is what
makes an active man in the middle useless -- it cannot derive the key -- but
also means there is no forward secrecy: a credential learned later decrypts
a recording made earlier. An ephemeral X25519 exchange fixes that, and moves
the defence against a relay from 'cannot derive the key' to 'cannot produce
the confirmation'.

GenerateX25519KeyPair / X25519Agree wrap Crypto++'s x25519. Agree validates
the peer key, and an all-zero shared secret is refused on top of that rather
than trusting one library's notion of a degenerate point, since it would key
every such session identically.

ConfirmTag is built from the existing HKDF rather than a second primitive:
extract-then-expand with the credential as keying material is a MAC over the
handshake transcript, which is all a confirmation needs. ConstantTimeEquals
goes with it -- an early-returning compare leaks how much of a guessed tag
was right, turning forgery into a per-byte search.

Four tags reserved for the exchange. No new capability tag: encryption has
never shipped, so anything advertising EC_TAG_CAN_AEAD is new enough to do
X25519, and a peer offering the cipher list without a public key will be
treated as malformed rather than old.

* feat(ec): forward secrecy for External Connect via ephemeral X25519

The session key was derived from the EC credential. That made an active man
in the middle useless -- it cannot derive the key -- but it also meant a
credential learned later decrypts a recording made earlier. The key outlived
the session it protected.

Both ends now exchange an ephemeral X25519 public key alongside the nonces
they already exchange, and the channel is keyed from the resulting shared
secret alone. The private halves are wiped as soon as they have produced it,
so once a session ends there is nothing left that could reopen it -- not in
memory, not on disk, and nothing an operator could be compelled to hand over.

Removing the credential from the key removes what stopped a relay, since a
raw exchange authenticates nobody: an attacker can complete one exchange with
each side and sit in the middle. The confirmation tags replace that defence.
Each side proves it knows the credential over the exact handshake it saw --
both nonces, both public keys, the offered ciphers and the chosen one -- and a
relay necessarily runs a different exchange on each leg, so its two
transcripts differ and at least one check fails. This is the shape TLS uses
for PSK with DHE, and it is the same structure a future scrypt verifier
needs, so that change lands on top rather than replacing this.

Failure is closed throughout. A missing, malformed or wrong tag is an
authentication failure on either side, never a fallback to the old
password-derived key or to clear -- a downgrade a middlebox could force by
dropping one tag is not much better than no defence. The transcript binds
the cipher list, so the existing downgrade protection is unchanged.

BuildTranscript is one shared function rather than the same concatenation
written out on each side: the two ends must agree byte for byte or every
session fails, and two copies of that is what drifts when a field is added.
Its cipher list is length-prefixed so no two handshakes can flatten to the
same bytes.

No new capability negotiation. Encryption has never shipped, so anything
advertising EC_TAG_CAN_AEAD is new enough to do X25519, and an offer without
a public key is treated as malformed rather than as an older peer. A client
that does not offer encryption at all is unaffected and still connects in
clear, so older clients keep working.

Verified against a daemon with RequireEncryption on: amulecmd completes the
handshake and `show Shared` and `show DL` -- the cached-blob sealing path --
return in full. Then, by deliberately breaking one thing at a time and
confirming each is refused: a corrupted client tag, an omitted client tag, a
corrupted daemon tag, a substituted daemon public key (the relay case, caught
by the confirmation), and a diverged shared secret with an intact transcript
(caught by the AEAD tag, which is why the key is bound and not only
confirmed). A client offering no encryption still connects in clear against a
permissive daemon.

* docs(ec): document the key exchange and confirmation in the EC protocol

Section 1.3 still described the previous design, where the channel key came
from the password. Anyone implementing against it would have built something
the daemon now refuses.

Covers the two new key tags and the two confirmation tags, the transcript the
confirmations are computed over, and why a peer offering the cipher list
without a public key is treated as malformed rather than as an older client.

* harden EC AEAD: reject post-handshake cleartext, client-side require, wipe key material

Follow-up hardening on the forward-secrecy handshake, from an adversarial
review of the AEAD path:

- Reject a cleartext packet on a session that negotiated encryption. The
  per-packet EC_FLAG_ENCRYPTED classification let a clear packet be
  processed after the handshake, so an on-path attacker could inject an
  unauthenticated command with the session's authority. ReadPacket now
  records how each packet arrived and both dispatches drop the connection
  on a clear packet once keys exist. RequireEncryption did not cover this,
  since it only gates the handshake.

- Require encryption on the client unless the user opted out. m_canAEAD is
  the opt-out: when the client offers AEAD but the core does not negotiate
  it, refuse rather than send the credential and later commands in clear,
  with a message that names the likely cause. An older core still connects
  in clear, but only when the user turns encryption off.

- Refuse a keyless AEAD offer on the daemon even when RequireEncryption is
  off: a peer that offers encryption is new enough to send a key, so a
  keyless offer is malformed, not an older client.

- Wipe key material with a non-elidable secure wipe (CryptoPP
  SecureWipeBuffer) instead of std::fill / memset, on every path: the
  ephemeral private key, the shared secret (including the failure paths the
  old code left it on), the HKDF output, the session keys, and the
  credential copies.

- Validate the daemon's nonce and public-key length on the client at
  receipt, the way the daemon validates the client's.

- Guard the confirm-tag reads with a new CECTag::IsCustom(), so a mistyped
  tag cannot trip GetTagData()'s debug assert.

- Add a SecureWipe unit test; fix a stale comment claiming ChaCha20 is
  compiled in conditionally.

New user-facing strings are added here; the po catalogs are regenerated
separately.

* fix(ec): enforce require-encryption on the synchronous connect path too

The client-side require-encryption check was added to ProcessAuthPacket,
but the synchronous ConnectToCore path (amulecmd, amuleweb) ignored its
return value, so a client that offered AEAD would still send the
credential and later commands in clear when the core did not negotiate
encryption. Check the return the way the async OnPacketReceived path
already does, and abort before sending AUTH_PASSWD.

Verified against a daemon patched to not negotiate AEAD: amulecmd refuses
with the "core did not negotiate an encrypted connection" message instead
of connecting in clear, and still connects encrypted against a normal
daemon.

* i18n: regenerate catalogs for the EC encryption strings

New user-facing strings from the forward-secrecy handshake and its
hardening: the require-encryption refusal on the client, the malformed
offer refusal on the daemon, and the two authentication-failure messages.
mrjimenez pushed a commit to mrjimenez/amule that referenced this pull request Aug 5, 2026
amule-project#797)

The two encryption checks added in amule-project#785 end a login attempt by setting
m_server_reply, closing the socket and returning false -- but they return
before the tail of ProcessAuthPacket, which is the only place that fires
wxEVT_EC_CONNECTION. Nothing else covers for them: plain CloseSocket
deliberately does not dispatch OnLost, precisely because ProcessAuthPacket
is documented as notifying for itself (see the note on CloseAndDispatchLost
in ECSocket.h), and CAsioSocketImpl::Close suppresses the asio-side lost
path as well.

So amulegui never learned the attempt had ended. It waited out its
connect-timeout watchdog and then reported "Unable to reach <host>:<port>
... check that aMule is running with External Connections enabled" -- wrong
in every particular: the host is reachable, aMule is running, and EC is
enabled. The accurate message, telling the user the core did not negotiate
encryption and how to turn it off, sat unread in m_server_reply.

This is the normal upgrade order -- amulegui updated before the daemon --
so it is what a user hits first.

Route all three terminal paths through one NotifyConnectionResult helper.
The mid-handshake EC_SALT_RECEIVED return still does not notify, which is
correct: that attempt has not ended.

Verified against a real pre-amule-project#785 core.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Include all aMule binaries in the release packages

3 participants