# Server setup The server speaks TLS and needs a PKCS#12 identity (`identity.p12`) plus the PEM key/certificate used to build it. The files are read from the current working directory. ## Quick start From the project root: ```sh cargo run --bin server -- --init cargo run --bin server ``` `--init` creates a self-signed development identity and exits. The next command starts the server on `127.0.0.1:11525`. If `identity.p12` is missing at startup, the server now prints these same instructions instead of only the raw OS error. ## What `--init` creates | File | Purpose | | --- | --- | | `identity.p12` | PKCS#12 identity loaded by `native-tls`. Empty password. Uses PBE-SHA1-3DES and a SHA-1 MAC so the Windows SChannel backend can load it. | | `key.pem` | RSA private key used to build the identity. Not read at runtime. | | `cert.pem` | Public certificate, useful for inspection. | On Unix, `identity.p12` and `key.pem` are set to mode `0600`. All three are ignored by git (`*.p12`, `*.pem`, `*.key`). ## Manual setup If `openssl` is not installed or you want to control the certificate: ```sh openssl req -x509 -newkey rsa:2048 \ -keyout key.pem -out cert.pem \ -days 3650 -nodes -subj "/CN=localhost" openssl pkcs12 -export -out identity.p12 \ -inkey key.pem -in cert.pem -passout pass: ``` The password must be empty because the server calls `Identity::from_pkcs12(&data, "")`. ## Running ```sh # default: 127.0.0.1:11525 cargo run --bin server # listen on all interfaces cargo run --bin server -- -i 0.0.0.0 -p 11525 # show options cargo run --bin server -- --help ``` Then start the client in another terminal: ```sh cargo run --bin client ``` On first contact the client prints the SPKI fingerprint and pins it. If you regenerate the server identity, the client will reject the new key; run `forget-host` in the client if the change is intentional. Credentials are stored against the pinned fingerprint, not the address. Log in once through `127.0.0.1:11525` and connecting through the machine's LAN address will authenticate automatically, because both addresses present the same key. `forget-host` removes one address; the stored login is only dropped when the last address for that key is forgotten. ## Database The server creates `server.db` in the current directory on first use. It holds users, balances, and the per-game `plays` audit. The client keeps its own `client.db` for host fingerprints and stored credentials in `$XDG_DATA_HOME/zagan-bet/` (usually `~/.local/share/zagan-bet/`); pass `-d ` to keep it somewhere else. There are no schema migrations while the app is in alpha: a schema change means deleting both files. During development, delete both files to reset users, balances, history, and trust: ```sh rm -f server.db client.db ``` The `plays` schema is not auto-migrated from the old slots-only shape; a stale database must be removed. ## Windows `--init` shells out to `openssl`, so OpenSSL must be installed and on `PATH` (Git for Windows, WSL, or a standalone OpenSSL build). The generated files work the same way. `--init` uses SChannel-friendly PKCS#12 algorithms; if you build the identity by hand on Windows, use: ```sh openssl pkcs12 -export -out identity.p12 -inkey key.pem -in cert.pem \ -passout pass: -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -macalg sha1 ``` ## Security notes - This is a self-signed development identity with an empty PKCS#12 password. Treat `key.pem` and `identity.p12` as secrets and do not commit them. - The trust model is TOFU: clients pin the SPKI fingerprint on first contact. A changed key is a loud error, not an automatic re-trust. - For a public deployment, use a CA-issued certificate and protect the PKCS#12 with a password; the current server code expects an empty password. ## Troubleshooting | Symptom | Fix | | --- | --- | | `Failed to initialize TLS: Could not read TLS identity` | Run `cargo run --bin server -- --init`. | | `Address already in use` | Stop the other server or pass `-p `. | | Client says `HOST KEY CHANGED` | The server certificate changed. If intentional, run `forget-host` in the client. | | `openssl` not found | Install OpenSSL or use the manual commands on a machine that has it. |