aboutsummaryrefslogtreecommitdiffstats
path: root/CLAUDE.md
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-02-17 11:07:37 +0100
committerThomas Vanbesien <tvanbesi@proton.me>2026-02-17 11:07:37 +0100
commita54421dd976fd8081e96c11c2621076876c9986b (patch)
treea7614934364bc692dd94ee13a3ec6d242521194b /CLAUDE.md
parentd1e229c80a6e51ccc5b21d001271c41d6cda30bf (diff)
downloadBobinkCOpcUa-a54421dd976fd8081e96c11c2621076876c9986b.tar.gz
BobinkCOpcUa-a54421dd976fd8081e96c11c2621076876c9986b.zip
Replace CLI arguments with config-file parser and add integration tests
Introduce a reusable key=value config parser (config.h/c) and convert all three programs to read their settings from config files instead of positional command-line arguments. Add example config files in config/ and 6 CTest integration tests covering None/Basic256Sha256/Aes128 with anonymous and user authentication. Remove the now-obsolete launch.sh.
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md128
1 files changed, 85 insertions, 43 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index 4a6af57..4135924 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -61,77 +61,119 @@ Existing certs live in `certs/`. Only regenerate if missing.
## Running
-All three programs run from the project root. Start them in order in separate terminals:
+Each program takes a single argument: a configuration file. Example config files are in `config/`. Start programs in order in separate terminals from the project root:
**1. Local Discovery Server (LDS)**
```sh
-build/ServerLDS 4840 "urn:bobink.ServerLDS" \
- certs/ServerLDS_cert.der certs/ServerLDS_key.der \
- 60 \
- user user password \
- certs/ServerRegisterClient_cert.der certs/ClientFindServers_cert.der
+build/ServerLDS config/server_lds.conf
```
-Args: `<port> <applicationUri> <cert> <key> <cleanup-timeout-seconds> <auth-mode> [<username> <password>] [trustlist...]`
-
-The trustlist must include the client certs that will connect over encrypted channels: `ServerRegisterClient_cert.der` (used by `ServerRegister`) and `ClientFindServers_cert.der` (used by `ClientFindServers`). Cleanup timeout must be > 10.
-
**2. Register Server**
```sh
-build/ServerRegister 4841 "urn:bobink.ServerRegister" \
- certs/ServerRegister_cert.der certs/ServerRegister_key.der \
- certs/ServerRegisterClient_cert.der certs/ServerRegisterClient_key.der \
- "opc.tcp://localhost:4840" 10 \
- SignAndEncrypt Aes128_Sha256_RsaOaep \
- user user password \
- user user password \
- certs/ServerLDS_cert.der certs/ClientFindServers_cert.der
+build/ServerRegister config/server_register.conf
```
-Args: `<port> <applicationUri> <server-cert> <server-key> <client-cert> <client-key> <discovery-endpoint> <register-interval-seconds> <security-mode> <security-policy> <server-auth-mode> [<server-user> <server-pass>] <client-auth-mode> [<client-user> <client-pass>] [trustlist...]`
-
-Uses separate server/client certificate pairs. The client cert+key are for the secure channel to the LDS. Re-registers periodically at the given interval. Server auth mode controls what clients connecting to this server need; client auth mode controls how this server authenticates to the LDS. Trustlist should include the LDS cert and any client certs that will query this server's endpoints (e.g. `ClientFindServers_cert.der`).
-
**3. Find Servers Client**
```sh
-build/ClientFindServers "opc.tcp://localhost:4840" \
- "urn:bobink.ClientFindServers" \
- certs/ClientFindServers_cert.der certs/ClientFindServers_key.der \
- SignAndEncrypt Aes128_Sha256_RsaOaep \
- user user password \
- certs/ServerLDS_cert.der certs/ServerRegister_cert.der
+build/ClientFindServers config/client_find_servers.conf
```
-Args: `<discovery-server-endpoint> <applicationUri> <cert> <key> <security-mode> <security-policy> <auth-mode> [<username> <password>] [trustlist...]`
+## Configuration Files
+
+Config files use a simple `key = value` format, one entry per line. Lines starting with `#` are comments. Blank lines are ignored. Repeated keys are used for list values (e.g. multiple `trustList` entries).
+
+### ServerLDS Keys
+
+| Key | Required | Description |
+|-----|----------|-------------|
+| `port` | yes | Server port number |
+| `applicationUri` | yes | OPC UA application URI |
+| `certificate` | yes | Path to server certificate (.der) |
+| `privateKey` | yes | Path to server private key (.der) |
+| `cleanupTimeout` | yes | Seconds before stale registrations are removed (must be > 10) |
+| `authMode` | yes | `anonymous` or `user` |
+| `username` | if user | Username for authentication |
+| `password` | if user | Password for authentication |
+| `trustList` | no | Trusted certificate path (repeat for multiple) |
+
+### ServerRegister Keys
+
+| Key | Required | Description |
+|-----|----------|-------------|
+| `port` | yes | Server port number |
+| `applicationUri` | yes | OPC UA application URI |
+| `serverCertificate` | yes | Path to server certificate (.der) |
+| `serverPrivateKey` | yes | Path to server private key (.der) |
+| `clientCertificate` | yes | Path to client certificate for LDS connection (.der) |
+| `clientPrivateKey` | yes | Path to client private key for LDS connection (.der) |
+| `discoveryEndpoint` | yes | LDS endpoint URL (e.g. `opc.tcp://localhost:4840`) |
+| `registerInterval` | yes | Seconds between re-registrations |
+| `securityMode` | yes | `None`, `Sign`, or `SignAndEncrypt` |
+| `securityPolicy` | yes | `None`, `Basic256Sha256`, `Aes256_Sha256_RsaPss`, `Aes128_Sha256_RsaOaep`, or `ECC_nistP256` |
+| `serverAuthMode` | yes | Auth for clients connecting to this server: `anonymous` or `user` |
+| `serverUsername` | if user | Server-side username |
+| `serverPassword` | if user | Server-side password |
+| `clientAuthMode` | yes | Auth for LDS connection: `anonymous` or `user` |
+| `clientUsername` | if user | Client-side username (for LDS) |
+| `clientPassword` | if user | Client-side password (for LDS) |
+| `trustList` | no | Trusted certificate path (repeat for multiple) |
+
+### ClientFindServers Keys
+
+| Key | Required | Description |
+|-----|----------|-------------|
+| `discoveryEndpoint` | yes | LDS endpoint URL (e.g. `opc.tcp://localhost:4840`) |
+| `applicationUri` | yes | OPC UA application URI |
+| `certificate` | yes | Path to client certificate (.der) |
+| `privateKey` | yes | Path to client private key (.der) |
+| `securityMode` | yes | `None`, `Sign`, or `SignAndEncrypt` |
+| `securityPolicy` | yes | `None`, `Basic256Sha256`, `Aes256_Sha256_RsaPss`, `Aes128_Sha256_RsaOaep`, or `ECC_nistP256` |
+| `authMode` | yes | `anonymous` or `user` |
+| `username` | if user | Username for session auth |
+| `password` | if user | Password for session auth |
+| `trustList` | no | Trusted certificate path (repeat for multiple) |
+
+## Testing
+
+Integration tests use CTest and cover 6 combinations of security mode/policy and authentication:
+
+| Test | Security | Auth |
+|------|----------|------|
+| `none_anon` | None / None | anonymous |
+| `none_user` | None / None | user |
+| `basic256sha256_anon` | SignAndEncrypt / Basic256Sha256 | anonymous |
+| `basic256sha256_user` | SignAndEncrypt / Basic256Sha256 | user |
+| `aes128_anon` | SignAndEncrypt / Aes128_Sha256_RsaOaep | anonymous |
+| `aes128_user` | SignAndEncrypt / Aes128_Sha256_RsaOaep | user |
+
+Run all tests:
-Queries the LDS and prints all registered servers and their endpoints. Auth mode controls how the client authenticates when reading server time. The trustlist should include the certs of all servers whose endpoints will be queried.
-
-**Security and auth options** (for both ServerRegister and ClientFindServers):
+```sh
+ctest --test-dir build --output-on-failure
+```
-| Security modes | Security policies |
-|----------------|-------------------|
-| `None` | `None` |
-| `Sign` | `Basic256Sha256` |
-| `SignAndEncrypt` | `Aes256_Sha256_RsaPss` |
-| | `Aes128_Sha256_RsaOaep` |
-| | `ECC_nistP256` |
+Each test starts ServerLDS (port 14840) and ServerRegister (port 14841), runs ClientFindServers, then validates:
+1. Client exits with code 0
+2. FindServers output contains `urn:bobink.ServerRegister`
+3. Client read the current time (`date is:`)
+4. Endpoint listing contains the expected security policy
-| Auth modes | Description |
-|------------|-------------|
-| `anonymous` | No session credentials |
-| `user` | Username/password (requires two extra args) |
+To add a new test case: create a directory under `tests/` with 3 config files (`server_lds.conf`, `server_register.conf`, `client_find_servers.conf`), then add a `"name;ExpectedPolicy"` entry to the `INTEGRATION_TESTS` list in `CMakeLists.txt`.
## Project Structure
| Path | Purpose |
|------|---------|
| `src/common.h` / `src/common.c` | Shared helpers: `loadFile()`, `createSecureServer()`, `createSecureClientConfig()`, `parseSecurityMode()`, `resolveSecurityPolicyUri()` |
+| `src/config.h` / `src/config.c` | Config file parser: `configLoad()`, `configGet()`, `configRequire()`, `configRequireInt()`, `configGetAll()`, `configFree()` |
| `src/server_lds.c` | Local Discovery Server |
| `src/server_register.c` | Server that registers with LDS |
| `src/client_find_servers.c` | Client that queries LDS and displays endpoints |
+| `config/` | Example configuration files for all three programs |
+| `tests/` | Integration tests: `run_test.sh` helper and per-test config directories |
| `certs/` | TLS certificates for server, client, and LDS |
| `tools/` | Helper scripts |
| `cmake/BuildDeps.cmake` | Configures, builds, and installs open62541 |