# netexec SlackBuild — Design

Date: 2026-06-26
Maintainer: danix <danix@danix.xyz>

## Goal

Package [NetExec](https://github.com/Pennyw0rth/NetExec) (the `nxc` network
execution / post-exploitation tool) as a SlackBuild for Slackware, following
SBo conventions where applicable.

NetExec is a Poetry-managed Python project with a large dependency tree (~30
direct deps, 4 sourced from git: impacket, certipy-ad, oscrypto, pynfsclient)
plus a heavy transitive tree (cryptography, pypykatz, lsassy, dploot,
aardwolf, etc).

## Platform constraint

NetExec requires Python `>=3.10,<4.0`.

- Slackware **-current** ships Python 3.12.13 → supported.
- Slackware **-stable** ships Python 3.9 → **not supported** (below 3.10, and
  the venv's compiled extensions are tied to the build-time Python minor
  version regardless).

**netexec is -current only.** The package table marks `Tested -stable` as
not-applicable / no.

## Why not the distro pattern

Kali (native `python3-*` packages) and Arch (`python-*` packages) both resolve
the dep tree through their package managers, leaning on hundreds of
distro-maintained Python packages. Slackware/SBo does not maintain that
ecosystem; reproducing it would mean authoring ~40 new SBo packages, and the
git-sourced deps do not fit the SBo `.info` model. Not viable for a single
maintainer.

## Approach: self-contained venv from a vendored wheels tarball

One package. A virtualenv is built at install prefix `/opt/netexec`, with
netexec and its full dependency tree pip-installed into it from a **pinned,
vendored wheels tarball** (no network at build time). This mirrors the
existing feroxbuster vendored-crates pattern: freeze the dependency set once,
host it, build offline and reproducibly.

## Repo layout

```
netexec/
├── netexec.SlackBuild
├── netexec.info
├── README
├── slack-desc
└── requirements.txt        # pinned, hashed lockfile (vendored)
```

## Sources (two, like feroxbuster)

- `netexec-<ver>.tar.gz` — upstream source tarball (GitHub release archive).
  `DOWNLOAD`.
- `netexec-wheels-<ver>.tar.gz` — vendored wheels, hosted on
  packages.danix.xyz. `DOWNLOAD_x86_64` + `MD5SUM_x86_64`.

x86_64-only wheels: several deps ship platform-specific compiled wheels
(cryptography, pypykatz crypto). Other arches → exit with an error, matching
the `.deb`/`.rpm` repack precedent in CLAUDE.md.

## `.info`

```
PRGNAM="netexec"
VERSION="<ver>"
HOMEPAGE="https://github.com/Pennyw0rth/NetExec"
DOWNLOAD="<github source tarball url>"
MD5SUM="<source md5>"
DOWNLOAD_x86_64="https://packages.danix.xyz/.../netexec-wheels-<ver>.tar.gz"
MD5SUM_x86_64="<wheels md5>"
REQUIRES=""
MAINTAINER="danix"
EMAIL="danix@danix.xyz"
```

`REQUIRES=""` — Python 3.12 is in the -current base.

## Build flow (netexec.SlackBuild)

1. `set -e`; honor `$TMP`/`$BUILD`/`$TAG`/`$OUTPUT` defaults.
2. Arch detection: non-x86_64 → error out.
3. Unpack source tarball → `$PRGNAM-$VERSION` (provides README/LICENSE/docs).
4. Unpack wheels tarball → `$TMP/wheels`.
5. `python3 -m venv $PKG/opt/netexec`.
6. `$PKG/opt/netexec/bin/pip install --no-index --find-links=$TMP/wheels netexec==$VERSION`
   (installs netexec + full tree from local wheels, zero network).
7. Relocate the venv: sed the `$PKG` prefix out of `bin/*` shebangs and
   `pyvenv.cfg` so it resolves at the installed `/opt/netexec`, not the build
   `$PKG/opt/netexec`.
8. Strip compiled `.so` extension modules in the venv (cryptography etc) per
   guidelines.
9. Create `/usr/bin/{nxc,netexec,nxcdb}` symlinks → `/opt/netexec/bin/<x>`.
10. Docs → `/usr/doc/netexec-$VERSION/` (README, LICENSE).
11. `find -L` chown/chmod cleanup; `makepkg -l y -c n`.

## Prerequisite: wheels tarball (external tool)

The vendored wheels tarball is generated by a **generic, reusable** helper
that lives in its own repo (`~/Programming/GIT/mkwheels`), out of scope for
this repo. It is a prerequisite the maintainer runs once per version, not part
of the SlackBuild. This spec only depends on its output (the tarball + the
`requirements.txt` it emits).

The reproducible vendor recipe (mirrors mksboarchive and the Rust vendor
recipe):

- Create a clean venv.
- `pip download <pkg>==<ver> -d wheels/` — resolves the full tree including git
  deps, building sdists to wheels.
- Pin exact resolved versions + hashes into `requirements.txt`.
- Tar `wheels/` → `<pkg>-wheels-<ver>.tar.gz` with `SOURCE_DATE_EPOCH` pinned
  to the release tag commit date (feroxbuster pattern).
- Print the md5. Maintainer uploads to packages.danix.xyz.

The tool is generic over `<pkg>`/`<ver>` so it serves any future Python SBo,
not just netexec. Its own design/implementation is tracked in its own repo.

## Risks / notes

- **Git deps** (impacket, certipy-ad, oscrypto, pynfsclient) are unversioned
  git refs upstream. `pip download` resolves them to built wheels; the wheels
  tarball **freezes** them, so once built the package is reproducible. The
  lockfile records resolved versions.
- **venv relocation**: venvs are not relocatable by default; the shebang /
  `pyvenv.cfg` sed step (build flow step 7) handles it. Verify on build.
- **Python minor-version tie**: compiled extensions bind to the build-time
  Python minor. If -current bumps Python (e.g. 3.12 → 3.13) the venv must be
  rebuilt. Note this in the README. SBo-acceptable; common for Python packages.

## Out of scope (YAGNI)

- Packaging any dependency as its own SBo package.
- -stable support (Python 3.9 is too old).
- Non-x86_64 arches.
