Files
pi-pm3/STAGE_COMPARISON.md
michael 4f35df1781 Initial commit - Phase 3/4
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 13:46:22 -08:00

8.1 KiB

Stage Comparison: Old stageDTPM3 vs New Split Stages

Date: 2025-11-26 Purpose: Identify differences between old working stageDTPM3 and new stagePM3 + stageDangerousPi split stages


Executive Summary

The new split stages are significantly more robust with:

  • Dynamic user detection (cloud-init compatible)
  • Dependency installation and verification
  • Python bindings for PM3
  • Cleaner build process
  • Modern nftables (vs old iptables)
  • Lightweight WiFi AP (vs bloated RaspAP)

CRITICAL ISSUE FOUND:

  • New PM3 script missing ARM cross-compiler (gcc-arm-none-eabi + libnewlib-dev)
  • This will cause firmware build to fail!

1. Proxmark3 Build Comparison

OLD: stageDTPM3/01-proxmark3/00-run-chroot.sh (9 lines)

#!/bin/bash -e

su - dt
git clone https://github.com/RfidResearchGroup/proxmark3
cd proxmark3
echo PLATFORM=PM3GENERIC > Makefile.platform
make clean && make
exit

Characteristics:

  • 🔴 No dependency installation (assumes they exist!)
  • 🔴 No error handling or verification
  • 🔴 Builds as 'dt' user (weird approach)
  • 🔴 No Python bindings
  • 🔴 No explicit installation location
  • 🔴 Installs later in ttyd stage via make install

NEW: stagePM3/01-proxmark3/00-run-chroot.sh (151 lines)

# Installs dependencies explicitly
apt-get install -y cmake python3-dev swig build-essential \
    libreadline-dev libusb-1.0-0-dev liblz4-dev libbz2-dev \
    libjansson-dev libc6-dev pkg-config git

# Clones to /tmp (cleaner)
cd /tmp
git clone https://github.com/RfidResearchGroup/proxmark3
cd proxmark3

# Builds firmware
echo PLATFORM=PM3GENERIC > Makefile.platform
make clean && make -j$(nproc)

# Applies qrcode fix for Python bindings
sed -i '/TARGET_SOURCES.*pm3rrg_rdv4_experimental/,/)/s|...|...|' \
    client/experimental_lib/CMakeLists.txt

# Builds Python bindings
cd client/experimental_lib
./00make_swig.sh
./01make_lib.sh

# Dynamic user detection
DEFAULT_USER=$(awk -F: '$3 >= 1000 && $3 < 65534 {print $1; exit}' /etc/passwd)

# Installs to ~/.pm3/proxmark3/
# Full verification with exit on error

Characteristics:

  • Explicit dependency installation
  • Comprehensive error handling
  • Python bindings support
  • Dynamic user detection (cloud-init compatible)
  • Organized installation to ~/.pm3/
  • Build verification steps
  • Creates version file for tracking

CRITICAL MISSING DEPENDENCIES: According to official Proxmark3 docs, Raspbian requires:

gcc-arm-none-eabi    ← MISSING! Required for firmware build
libnewlib-dev        ← MISSING! Required for ARM toolchain
ca-certificates      ← Missing (minor)
libssl-dev           ← Missing (minor)
libbluetooth-dev     ← Missing (if BLE features needed)
libgd-dev            ← Missing (for graphical features)

2. WiFi Access Point Comparison

OLD: stageDTPM3/02-Wireless-AP/00-run-chroot.sh (80 lines)

Approach: Full RaspAP installation

  • 🔴 Clones entire RaspAP PHP web interface
  • 🔴 Heavy dependencies (lighttpd + PHP + fastcgi)
  • 🔴 Complex sudoers configuration
  • 🔴 Multiple systemd services (raspapd.service, dhcpcd.service)
  • 🔴 Uses iptables (legacy)
  • 🔴 Hardcoded PHP 8.4 paths (brittle)

NEW: stageDangerousPi/01-Wireless-AP/00-run-chroot.sh (279 lines)

Approach: Minimal hostapd + dnsmasq

  • No PHP bloat (just hostapd + dnsmasq)
  • Modern nftables instead of iptables
  • Captive portal DNS redirect
  • Avahi mDNS for dangerous-pi.local
  • Better documented configuration files
  • Cleaner network setup

Verdict: New approach is significantly better - lightweight, modern, purpose-built for captive portal.


3. ttyd (Web Terminal) Comparison

OLD: stageDTPM3/03-ttyd/00-run-chroot.sh (73 lines)

# Hardcoded 'dt' user
USER_UID=$(id -u dt)
ExecStart=/usr/local/bin/ttyd ... -c dt:proxmark3 /usr/bin/bash

# Critical: Runs make install at end
cd /home/dt/proxmark3
make install

Key Point: This stage installs PM3 client to system paths via make install.

NEW: stageDangerousPi/02-ttyd/00-run-chroot.sh (87 lines)

# Dynamic user detection
DEFAULT_USER=$(awk -F: '$3 >= 1000 && $3 < 65534 {print $1; exit}' /etc/passwd)
USER_UID=$(id -u $DEFAULT_USER)
ExecStart=/usr/local/bin/ttyd ... -c $DEFAULT_USER:proxmark3 /usr/bin/bash

# Creates symlink instead of make install
if [ ! -f /usr/local/bin/pm3 ] && [ -f $DEFAULT_HOME/.pm3/proxmark3/client/proxmark3 ]; then
    ln -s $DEFAULT_HOME/.pm3/proxmark3/client/proxmark3 /usr/local/bin/pm3
fi

Key Point: No make install, just symlinks. PM3 already installed in previous stage.

Verdict: New approach is cleaner (install happens where build happens).


4. Dangerous Pi Application Comparison

OLD: stageDTPM3/04-dangerous-pi/

00-run.sh:

  • Tries to copy from parent directory (brittle path resolution)
  • DANGEROUS_PI_SRC="$(dirname "$(dirname "$(dirname "$(dirname "$0")")")")"

00-run-chroot.sh:

  • Hardcoded 'pi' user
  • No pip3 availability check
  • No cleanup at end

01-run-chroot.sh:

  • All commented out (no port conflict resolution)

NEW: stageDangerousPi/03-dangerous-pi/

00-run.sh:

  • Copies from files/ directory in stage (cleaner)
  • cp -r "${SCRIPT_DIR}/files/app" ...

00-run-chroot.sh:

  • Dynamic user detection
  • Checks for pip3, installs if missing
  • Handles both boot config locations (/boot/config.txt, /boot/firmware/config.txt)
  • Cleans apt cache at end (saves ~50MB)
  • User substitution in systemd service file

01-run-chroot.sh:

  • Actively disables ttyd-bash to free port 8000

Verdict: New approach is much more robust and production-ready.


5. Critical Differences Summary

Aspect OLD stageDTPM3 NEW Split Stages Winner
User handling Hardcoded 'dt'/'pi' Dynamic detection NEW
Dependencies Assumed/missing Explicit install NEW
PM3 build No ARM compiler! Has dependencies ⚠️ Neither complete
PM3 Python None Full support NEW
WiFi AP Bloated RaspAP Minimal hostapd NEW
Network stack iptables nftables NEW
Error handling None Comprehensive NEW
Image size Larger Smaller (cleanup) NEW
Maintainability Low High NEW
Cloud-init support No Yes NEW

6. Required Actions

URGENT: Fix PM3 Dependencies

Add missing ARM cross-compiler to stagePM3/01-proxmark3/00-run-chroot.sh:

apt-get install -y \
    cmake \
    python3-dev \
    swig \
    build-essential \
    libreadline-dev \
    libusb-1.0-0-dev \
    liblz4-dev \
    libbz2-dev \
    libjansson-dev \
    libc6-dev \
    pkg-config \
    git \
    gcc-arm-none-eabi \    # ADD THIS - ARM firmware compiler
    libnewlib-dev \        # ADD THIS - ARM C library
    ca-certificates \      # ADD THIS - SSL certs for git
    libssl-dev \           # ADD THIS - SSL support
    libbluetooth-dev \     # ADD THIS - Bluetooth support
    libgd-dev              # ADD THIS - Graphics support

Optional Improvements

  1. Consider keeping old stageDTPM3 as fallback until new stages proven
  2. Document port conflicts (Dangerous Pi 8000 vs ttyd-bash 8000)
  3. Add smoke tests to verify PM3 Python bindings work

7. Conclusion

The new split stages are superior in every way EXCEPT for one critical bug:

Missing ARM cross-compiler will cause firmware build to fail!

Recommendation:

  1. Fix the missing dependencies IMMEDIATELY
  2. Run pre-flight validation
  3. Test build with new dependencies
  4. Keep old stageDTPM3 as backup until successful build confirmed

Why old version might have worked:

  • Base image may have had gcc-arm-none-eabi pre-installed
  • Old stage didn't verify, just failed silently
  • OR: Old version was building client-only, not firmware

Next steps:

  1. Add missing dependencies to new PM3 script
  2. Re-run pre-flight validation
  3. Test build
  4. If successful, remove old stageDTPM3