Files
simple/start.sh
T
catarrh 295f5553fc pcsc: guide by PolicyKit actions, not a pcscd group
A headless/SSH box can show a world-writable /run/pcscd/pcscd.comm
(srw-rw-rw- root root) and still be denied: pcscd enforces its PolicyKit
policy, whose defaults allow only active local sessions.  The startup
report, the start.sh pre-flight and the README troubleshooting now name
the exact rule (99-pcscd-allow.rules, org.debian.pcsc-lite.access_pcsc
and access_card) and explain why the socket mode does not matter.  The
pcscd-group instruction is gone: there may be no such group, and it is
not the gate.  The group route stays only as a note for a pcscd built
without PolicyKit.

Tests: tests/test_pcsc_startup.py asserts the polkit action IDs, the
rule filename and the 0666-socket explanation.
1088 Python + 1075 frontend.
2026-10-25 00:50:24 +03:00

92 lines
3.6 KiB
Bash
Executable File

#!/usr/bin/env bash
set -e
# pysim-simple-server start script
# Starts the server, preferring the venv if it exists.
# Auto-detects PC/SC reader if available.
# Every run is mirrored to simple_lastrun.log (overwritten on each start) so the
# latest server output can be read without copy-pasting the console.
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
VENV_DIR="$SCRIPT_DIR/.venv"
# Console + log file. The log contains card keys and request payloads (test
# cards) - it is gitignored and must not be committed.
LOG_FILE="$SCRIPT_DIR/simple_lastrun.log"
exec > >(tee "$LOG_FILE") 2>&1
export PYTHONUNBUFFERED=1 # keep the log live: a piped stdout is block-buffered
# PC/SC pre-flight (v3.38.1): a user without access to pcscd must see the real
# cause - the server no longer falls back to /dev/ttyUSB0 silently. An
# explicit serial reader (-d/--device) keeps the serial path.
SERIAL=0
for arg in "$@"; do
case "$arg" in
-d|--device|--device=*|-d*) SERIAL=1 ;;
esac
done
READER_ARGS=""
if [ "$SERIAL" -eq 0 ]; then
PYTHON_BIN="$VENV_DIR/bin/python"
[ -x "$PYTHON_BIN" ] || PYTHON_BIN="$(command -v python3 || true)"
if [ -n "$PYTHON_BIN" ]; then
PCSC_ERR="$("$PYTHON_BIN" - <<'PY' 2>&1
import time
from smartcard.System import readers
last = None
for _ in range(3):
try:
readers()
raise SystemExit(0)
except SystemExit:
raise
except Exception as e:
last = e
hr = getattr(e, 'hresult', None)
if hr == 0x80100027 or 'access denied' in str(e).lower():
break # permissions do not fix themselves
time.sleep(1) # pcscd may still be starting (socket activation)
hr = getattr(last, 'hresult', -1)
msg = str(last) or 'PC/SC error'
print(msg + ((' (hresult=0x%08X)' % hr) if hr not in (None, -1) else ''))
raise SystemExit(1)
PY
)" || {
echo "Error: PC/SC is not accessible: ${PCSC_ERR:-unknown error}"
echo " The server will not fall back to a serial reader silently."
echo " - pcscd uses PolicyKit (the default allows only active local sessions,"
echo " so SSH/headless is denied even with a 0666 socket). Allow the user in"
echo " /etc/polkit-1/rules.d/99-pcscd-allow.rules: return polkit.Result.YES for"
echo " org.debian.pcsc-lite.access_pcsc and access_card, subject.user == \"$USER\";"
echo " then 'sudo systemctl restart polkit' (or log out/in);"
echo " - 'sudo systemctl start pcscd' if the service is not running;"
echo " - 'pcsc_scan' shows the same 'Access denied' error until the rule is active."
exit 2
}
READER_ARGS="-p 0"
fi
fi
SERVER=""
if [ -f "$VENV_DIR/bin/pysim-simple-server" ]; then
SERVER="$VENV_DIR/bin/pysim-simple-server"
elif command -v pysim-simple-server &> /dev/null; then
SERVER="pysim-simple-server"
elif [ -f "$SCRIPT_DIR/pysim_simple_server/__main__.py" ]; then
echo "Starting pysim-simple-server from source on http://127.0.0.1:8080"
echo "Log: simple_lastrun.log (overwritten on each start)."
cd "$SCRIPT_DIR" && python3 -m pysim_simple_server --http-port 8080 $READER_ARGS "$@"
exit $?
else
echo "Error: pysim-simple-server not installed."
echo "Run setup.sh first or install manually:"
echo " pip install pysim-simple-server"
exit 1
fi
echo "Starting pysim-simple-server on http://127.0.0.1:8080"
echo "Log: simple_lastrun.log (overwritten on each start)."
echo "Press Ctrl+C to stop."
echo "Extra arguments are passed to the server (e.g. ./start.sh --gsmtap)."
$SERVER --http-port 8080 $READER_ARGS "$@"