Skip to content

install.sh: --password, --psk, --transport, --pool, --upstream-port, --http-port (#141) - #145

Merged
compot-dev merged 6 commits into
masterfrom
installer-options
Oct 28, 2026
Merged

compot-dev merged 6 commits into
masterfrom
installer-options

Conversation

@compot-dev

Copy link
Copy Markdown
Collaborator

Closes #141.

Options

Option What it sets Without it
--psk <key> psk= in a new camex.conf (hex:, base64: or a passphrase, checked) a random hex: key
--transport udp|tcp --transport tcp in a new /etc/default/camex; the printed client command has it udp
--pool <network>/<prefix> auto_pool= (/8 to /30, the network of the given address) and local_cidr=, the first address 10.200.0.0/24
--password <password> (with --domain) the start page's password a random one
--http-port <port> (with --domain) nginx's listen lines, HTTP_PORT of the sync service, the addresses printed 80
--upstream-port <port> (with --domain) UPSTREAM_PORT of the sync service 80

Settings made once, as the files they go to: on a rerun a different value is not applied, and the installer says which line to edit where (a new password: remove /etc/camex/nginx-password). The sync service's ports are kept from the installed unit when the option is not given.

nginx on another port

The start page's links were //<ID>.<domain>/: on port 85 they would lead to 80. camex --status --format nginx-index --http-port <port> puts the port in them (none for 80); camex-nginx-sync passes HTTP_PORT (only when it is not 80, for older camex) and --check asks nginx on that port.

Tests

  • docker/test-e2e-install.sh section 8, a second host: every option at once (a TCP server on 5900, the pool 10.60.0.0/22 from 10.60.1.7/22, a passphrase psk, a password with a ':' and a blank, nginx on 85, cameras on 8080): camex.conf, the TCP server, the printed command, nginx's listen lines, the service's ports, the page on 85 with the password, --check on 85; a rerun with other values that changes none of them and says what to edit; --password without --domain refused.
  • tests/test_nginxmap.c: the links with :85, none with 80.
  • Locally, as in CI: native build and unit tests, the musl builds of the four targets with the unit tests under qemu, every docker/test-e2e-*.sh, smoke, tun-provider, the kernel module on three images, the Android APK. Windows and macOS: CI.

Version 3.12.0.

…--http-port (#141)

Settings made once, as the files they go to: on a rerun a different value
is not applied; the installer says which line to edit where. --pool takes
a network and prefix (/8 to /30), the server at its first address.
--http-port is nginx's port: the listen lines of the server blocks, the
start page's links (camex --status --format nginx-index --http-port), the
sync service's HTTP_PORT (the links and what --check asks) and the
addresses printed. --password, --http-port and --upstream-port need
--domain. e2e: every option on a new host, a rerun with others.
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (1) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Reruns can miss active server overrides 📎 Requirement gap ≡ Correctness
Description
The rerun checks for --port and --psk compare only the values in camex.conf, not command-line
overrides in CAMEX_ARGS. When the service has either override, the running server can keep a
different port or key without the installer reporting the conflict or identifying the effective
setting to edit.
Code

install.sh[R462-465]

+if [ -n "$PORT_OPT" ] && [ "$(conf_server port)" != "$PORT_OPT" ]; then
+    say "kept port= of $CONF, not --port $PORT_OPT: edit it there, then" \
+        "systemctl restart camex (the clients need the same)"
+fi
Evidence
The changed rerun checks read port and psk only from camex.conf, while the service executes
CAMEX_ARGS and the installer itself recognizes that those arguments can override the
configuration. Therefore an existing command-line override can remain active without being detected
or reported.

Reruns preserve existing settings and explain conflicts
install.sh[462-467]
install.sh[651-654]
examples/camex.service[20-21]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Rerun conflict checks compare `--port` and `--psk` only with `camex.conf`, even though `CAMEX_ARGS` can override those values when the service starts. This can hide a conflict and leave the running server using a different setting than the installer reports.
## Fix Focus Areas
- install.sh[462-467]
- install.sh[651-654]
- examples/camex.service[20-21]
## Recommended Fix
Parse the effective `CAMEX_ARGS` values for port and PSK before comparing rerun options, giving command-line overrides precedence over `camex.conf`. If an override differs, report the actual value and tell the operator to edit `/etc/default/camex`; otherwise compare against the configuration file and retain the existing edit guidance.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Reruns hide a changed server port ✓ Resolved
Description
The installer keeps an existing camex.conf but provides no comparison or edit guidance when a
rerun supplies a different --port. That leaves the configured server port unchanged while the user
receives no instruction to edit port= in /etc/camex/camex.conf, unlike the other settings
handled in this block.
Code

install.sh[R460-463]

+# Settings made once: a different value is said, not applied
+if [ -n "$PSK_OPT" ] && [ "$(conf_server psk)" != "$PSK_OPT" ]; then
+    say "kept psk= of $CONF, not --psk: edit it there (the clients need the same)"
+fi
Evidence
The rerun guidance added in install.sh compares only psk= and auto_pool= after preserving the
existing configuration; it never checks PORT or tells the user how to change the existing port=
setting.

Preserve existing settings on installer reruns
install.sh[460-466]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A rerun with a different `--port` silently preserves the existing server port without telling the user which setting to edit, violating the installer's settings-once guidance.
## Fix Focus Areas
- install.sh[460-466]
## Recommended Fix
When `/etc/camex/camex.conf` already exists, compare the requested `PORT` with the existing `port=` value and print a keep-and-edit message when they differ, identifying `/etc/camex/camex.conf` and its `port=` line. Keep the existing value unchanged.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Bad keys can leave the server down ✓ Resolved
Description
The --psk check in install.sh validates base64: keys by text length alone and does not reject
passphrases of 128 characters or more or all-zero hex: keys. When one of these values is written
unchanged to camex.conf, camex can reject it during option copying or key parsing, causing
camex.service to fail after installation.
Code

install.sh[R252-255]

+        hex:*) printf '%s\n' "${PSK_OPT#hex:}" | grep -qxE '[0-9a-fA-F]{64}' ||
+                   die "--psk: hex: needs 64 hex digits" ;;
+        base64:*) [ ${#PSK_OPT} -eq 51 ] || die "--psk: base64: needs 44 characters" ;;
+    esac
Evidence
The installer accepts a base64: value based on its total length of 51 characters and writes the
supplied PSK unchanged, while camex checks Base64 contents and decoded length and rejects all-zero
raw keys. Separately, copy_option rejects values whose length is at least the destination size,
and the psk destination is char[128]; these daemon-side checks cover values the installer
permits, so global-key initialization can fail at startup.

Installer options and fresh-install defaults
install.sh[252-255]
src/keys.c[323-326]
src/util.c[314-328]
src/config.h[35-35]
src/keys.h[32-40]
src/config.c[352-354]
install.sh[246-255]
install.sh[415-430]
src/keys.c[61-113]
src/keys.c[295-326]
src/camex.c[738-765]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The installer can write `--psk` values to `camex.conf` that camex rejects when loading the configuration: malformed or incorrectly decoded Base64 keys, all-zero raw keys, and passphrases of 128 characters or more.
## Fix Focus Areas
- install.sh[246-256]
- install.sh[415-430]
- src/keys.c[323-326]
## Recommended Fix
Before writing `camex.conf`, reject PSKs of 128 characters or more and leading or trailing whitespace, which camex trims. Validate `base64:` payloads against camex’s decoding rules, including characters, padding, and a decoded length of 32 bytes; reject all-zero decoded raw keys for both Base64 and hex encodings. Report invalid values with a clear installer error.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View action required (1)
4. Reruns overwrite existing web ports ✓ Resolved
Description
install.sh selects supplied HTTP_PORT and UPSTREAM_PORT values before reading the installed
sync-service unit, then writes those values into the replacement unit even though an existing nginx
configuration is kept. On a rerun with a different --http-port, nginx retains its old listen port
while generated links, printed addresses and --check use the new one; a different
--upstream-port also changes the port used for subsequently generated camera routes, without
keep-and-edit guidance.
Code

install.sh[R579-585]

+    # Its ports: the option, else what the installed service has (#141)
+    for v in HTTP_PORT UPSTREAM_PORT; do
+        eval "val=\$$v"
+        [ -n "$val" ] || val=$(sed -n "s/^Environment=$v=\([0-9]*\)\$/\1/p" \
+                               "$UNITS/camex-nginx-sync.service" 2>/dev/null | tail -n 1)
+        [ -n "$val" ] && [ "$val" != 80 ] &&
+            sed -i "/^Environment=INDEX=/a Environment=$v=$val" "$TMP/sync.service"
Evidence
The existing nginx configuration is kept at install.sh lines 511–514, but the service-generation
loop at lines 579–588 takes a supplied port before consulting the installed unit and writes the
selected value into the replacement service. The sync script uses HTTP_PORT for index links and
its --check probe, and passes the upstream setting into nginx-map generation. The cited e2e rerun
checks the keep message but not the resulting service setting, so it does not catch the mismatch.

Non-destructive installer reruns with edit guidance
install.sh[579-585]
install.sh[509-517]
install.sh[579-588]
examples/camex-nginx-sync.sh[203-208]
examples/camex-nginx-sync.sh[337-342]
install.sh[509-514]
install.sh[579-587]
examples/camex-nginx-sync.sh[338-348]
examples/camex-nginx-sync.sh[361-367]
examples/camex-nginx-sync.sh[126-133]
install.sh[49-54]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Rerunning the installer with a different `--http-port` or `--upstream-port` changes the sync-service setting despite those settings already being installed. For HTTP, the existing nginx listen lines remain unchanged while links, printed addresses and `--check` use the newly requested port.
## Fix Focus Areas
- install.sh[511-514]
- install.sh[579-588]
## Recommended Fix
When the sync-service unit already exists, read and retain its installed `HTTP_PORT` and `UPSTREAM_PORT` values instead of applying differing command-line options; use the options when first creating the unit. Keep the service HTTP port and printed addresses consistent with an existing nginx configuration, and print guidance to edit the kept configuration or service when a requested value is not applied. Add an e2e rerun check that a service containing `Environment=HTTP_PORT=85` retains it after `--http-port 86`, rather than checking only the message.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

5. Custom nginx listeners get wrong links ✓ Resolved
Description
install.sh extracts NGINX_PORT only when the number immediately follows listen, so it misses
an existing directive such as listen 0.0.0.0:85;. On a rerun that keeps such a file, the sync
service and printed addresses fall back to port 80, causing the start page to link to the wrong port
and --check to probe it.
Code

install.sh[R540-541]

+        NGINX_PORT=$(sed -n 's/^[[:space:]]*listen[[:space:]]\{1,\}\([0-9]\{1,5\}\)[[:space:];].*/\1/p' \
+                     "$NGINX_CONF" | head -n 1)
Evidence
The new extraction requires digits immediately after listen; failure leaves NGINX_PORT empty.
The service-generation path then substitutes 80, and that value feeds both the printed URLs and the
sync script's index generation and probe.

install.sh[535-544]
install.sh[610-630]
install.sh[713-717]
examples/camex-nginx-sync.sh[203-207]
examples/camex-nginx-sync.sh[333-341]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A retained nginx configuration with an address-qualified `listen` directive is treated as though it listens on port 80, producing incorrect links and checks.
## Fix Focus Areas
- install.sh[538-544]
- install.sh[613-630]
## Recommended Fix
Extract the port from supported address-qualified as well as bare nginx `listen` directives before setting the sync service's HTTP port. Add a rerun test using an address-qualified listener.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Rerun on an HTTPS-first nginx file breaks links ✓ Resolved
Description
For a kept nginx file, the new NGINX_PORT sed takes the port from whatever listen line comes
first, and an ssl one such as listen 443 ssl; counts too, since the pattern accepts a space
after the digits. That value goes into HTTP_PORT of the sync service. So when a block lists
listen 443 ssl; before (or instead of) listen 80; — an HTTPS-only setup, or the file after
certbot's redirect edit — a plain rerun of install.sh, with no --http-port, makes the start page
link to http://.:443/. It also makes --check probe http://127.0.0.1:443/ and prints addresses
with :443, where the links used to be //./ and worked.
Code

install.sh[R540-541]

+        NGINX_PORT=$(sed -n 's/^[[:space:]]*listen[[:space:]]\{1,\}\([0-9]\{1,5\}\)[[:space:];].*/\1/p' \
+                     "$NGINX_CONF" | head -n 1)
Evidence
Lines 540-541 take the first listen  line and accept a following space or ;, so `listen 443
ssl; gives 443. Lines 613-629 copy NGINX_PORT into Environment=HTTP_PORT` whenever it is not 80,
and set WEB_PORT from it for the printed addresses. In the sync script, a non-80 HTTP_PORT is passed
as --http-port (index_build) and used in probe's http://127.0.0.1:$HTTP_PORT/.
nginx_index_format then writes http:// links with that port. The docs tell users to add `listen
443 ssl` lines, and the sync script already expects a certbot redirect on the HTTP port, so HTTPS
listen lines are expected in this file.

install.sh[536-545]
install.sh[610-630]
examples/camex-nginx-sync.sh[200-210]
examples/camex-nginx-sync.sh[333-345]
docs/nginx.md[252-255]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
For a kept nginx file, install.sh takes nginx's HTTP port from the first `listen` line, and that line can be `listen 443 ssl;`. The sync service then gets HTTP_PORT=443: the start page links say `http://...:443/`, `--check` probes plain HTTP on 443, and the printed addresses carry `:443`.
## Fix Focus Areas
- install.sh[538-544]
## Recommended Fix
Only count plain HTTP listen lines: skip any line that contains `ssl` (or `quic`/`http2 ssl`), e.g. `grep -vE '[[:space:]]ssl([[:space:];]|$)'` before the sed. Also accept an `addr:port` form if you want. When no plain HTTP listen line is found, fall back to 80, or leave HTTP_PORT unset.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. Quoted passwords fail the page check ✓ Resolved
Description
install.sh accepts a double quote in --password and writes it unchanged, but the sync script
later inserts that password into a double-quoted curl configuration value without escaping it. A
password such as foo"bar works for nginx authentication, while the installer's --check cannot
verify the protected start page.
Code

install.sh[R563-564]

+        if [ -n "$PASSWORD" ]; then
+            (umask 077; printf '%s\n' "$PASSWORD" > "$PASSWORD_FILE")
Evidence
The installer rejects newlines but not quotes, stores the supplied password, and hashes that file
for nginx. The sync check reads the same file and interpolates its contents into user = "camex:%s"
before passing the resulting file to curl.

install.sh[278-281]
install.sh[563-580]
examples/camex-nginx-sync.sh[484-507]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A user-supplied password containing a double quote is valid for nginx but produces a malformed credential in the sync script's curl configuration.
## Fix Focus Areas
- install.sh[563-564]
- examples/camex-nginx-sync.sh[484-495]
## Recommended Fix
Escape the password according to curl's configuration-file quoting rules before writing the `user` setting, while preserving the password used by nginx.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View review recommended (8)
8. Custom-port checks fail after unit loss ✓ Resolved
Description
install.sh retains an existing nginx configuration but defaults the replacement sync service to
port 80 when its prior unit is absent and --http-port is omitted. If the retained configuration
listens only on a custom port, the rebuilt service generates links without that port and --check
probes port 80 instead of nginx's listener.
Code

install.sh[618]

+            val=${opt:-80}
Evidence
The installer keeps the nginx file, independently chooses 80 for a missing unit, and installs a
service without a custom HTTP_PORT. The sync script then uses its default of 80 both for index
generation and for the local nginx probe.

install.sh[535-553]
install.sh[605-624]
examples/camex-nginx-sync.sh[24-27]
examples/camex-nginx-sync.sh[203-207]
examples/camex-nginx-sync.sh[337-341]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Recreating a missing sync service defaults its HTTP port to 80 even when the retained nginx configuration listens on a different port.
## Fix Focus Areas
- install.sh[535-540]
- install.sh[605-623]
## Recommended Fix
When the unit is missing and no port was supplied, determine the applicable port from the retained nginx configuration or require an explicit port rather than silently creating a mismatched service.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


9. A regenerated nginx file and the sync service disagree on the port ✓ Resolved
Description
The sync-service loop takes HTTP_PORT from the installed camex-nginx-sync.service whenever that
unit exists. The nginx file, though, is regenerated with --http-port (or with 80) whenever
$NGINX_CONF is missing. Suppose a host was installed before with --domain, and the user removes
the nginx file and reruns with --http-port 85: nginx now listens on 85, while the service keeps
HTTP_PORT=80. The start page then links to port 80, --check probes port 80 and fails, the
printed addresses use port 80, and the message tells the user to edit listen lines that already say
85.
Code

install.sh[R609-612]

+        if [ -f "$UNITS/camex-nginx-sync.service" ]; then
+            val=$(sed -n "s/^Environment=$v=\([0-9]*\)\$/\1/p" \
+                  "$UNITS/camex-nginx-sync.service" | tail -n 1)
+            val=${val:-80}
Evidence
Lines 536-555 make a new nginx file with --http-port when $NGINX_CONF is missing, so that choice
depends only on the nginx file. Lines 607-622 choose HTTP_PORT for the service, the links and
WEB_PORT only from the existing unit when there is one, and ignore whether the nginx file was just
made. probe in camex-nginx-sync.sh then queries 127.0.0.1:$HTTP_PORT.

install.sh[536-555]
install.sh[605-623]
examples/camex-nginx-sync.sh[332-342]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
When nginx's file is regenerated in a rerun, it gets `--http-port` (or 80), but the sync service's `HTTP_PORT` is kept from the old unit. nginx and the links / `--check` then point at different ports.
## Fix Focus Areas
- install.sh[536-555]
- install.sh[605-623]
## Recommended Fix
Record whether `$NGINX_CONF` was created in this run (e.g. `NGINX_NEW=1` in the else branch). In the HTTP_PORT iteration of the loop, when `NGINX_NEW` is set, use `${HTTP_PORT:-80}` (the port just written to the listen lines) instead of the installed unit's value. Alternatively, read the port from the `listen` line of the kept or new nginx file.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


10. TCP servers can get a UDP client command ✓ Resolved
Description
install.sh recognizes TCP in existing arguments only when -R and tcp are separated by a space,
so its transport check and printed command miss the valid -Rtcp form. When that form is retained
from an older unit, the server runs over TCP, but the installer can report that UDP was kept and
prints a client command without --transport tcp.
Code

install.sh[R687-689]

+case " $ARGS " in *" --transport tcp "*|*" -R tcp "*|*" --transport=tcp "*) PROTO=tcp ;; esac
+TOPT=
+[ "$PROTO" = tcp ] && TOPT=" --transport tcp"
Evidence
The command-line parser accepts -R with a required tcp argument. The installer's new transport
check and output matching require a separator after -R, although it preserves older unit arguments
in /etc/default/camex.

src/main.c[124-130]
src/main.c[252-263]
install.sh[471-498]
install.sh[683-695]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A valid attached short transport argument, `-Rtcp`, is not recognized when the installer checks the effective server transport or prints the client command.
## Fix Focus Areas
- install.sh[491-498]
- install.sh[683-693]
## Recommended Fix
Parse the effective transport from `CAMEX_ARGS` in one place and recognize both separated and attached short-option forms. Use that result for the kept-setting message and the printed client command, and test an older unit containing `-Rtcp`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


11. Passphrases with a backslash get mangled ✓ Resolved
Description
install.sh accepts backslashes in --psk, assigns the passphrase to PSK unchanged, then writes
psk=$PSK and prints the client command with echo. When run under dash, as with `curl … | sudo
sh on Debian and Ubuntu, escapes such as \c and \n` can truncate or split both outputs, leaving
the daemon with a different key from the one supplied to clients and causing reruns to report `kept
psk= … not --psk`; the printed start-page password is affected too.
Code

install.sh[R435-437]

+    if [ -n "$PSK_OPT" ]; then
+        PSK=$PSK_OPT
+    else
Evidence
The --psk validation at install.sh lines 255–276 permits backslashes, and the supplied passphrase
reaches echo "psk=$PSK" at line 452. The printed client command at line 694 and start-page
password at line 700 also use echo. Dash interprets backslash sequences in echo, so the daemon
reads a changed psk= value and derives its authentication key from that value. Previously, the
generated hex: key contained no backslashes.

install.sh[441-456]
install.sh[683-701]
install.sh[255-276]
install.sh[255-275]
install.sh[435-452]
src/config.c[541-545]
src/crypto.c[82-103]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The installer permits backslashes in a user-supplied `--psk` but uses `echo` to write it to the configuration and print it in the client command. Under dash, backslash escapes can change those values; the printed start-page password has the same problem.
## Fix Focus Areas
- install.sh[435-456]
- install.sh[683-700]
## Recommended Fix
Write the configuration line with `printf 'psk=%s\n' "$PSK"`. Use `printf '%s\n' "..."` for the printed client command and start-page password so backslashes are preserved. Add a test with a passphrase containing a backslash escape.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


12. Camera mapping regressions go untested ✓ Resolved
Description
The new end-to-end assertion checks only that the sync service contains UPSTREAM_PORT=8080 and
never inspects the generated nginx map for the camera port. A broken map-generation path could
therefore pass the fresh-install test, and the rerun command also omits a changed upstream-port
value.
Code

docker/test-e2e-install.sh[R335-339]

+o 'grep -qE "^[[:space:]]*listen[[:space:]]+85;" /etc/nginx/conf.d/camex-nginx.conf &&
+   ! grep -qE "^[[:space:]]*listen[[:space:]]+80;" /etc/nginx/conf.d/camex-nginx.conf &&
+   grep -qx "Environment=HTTP_PORT=85" /etc/systemd/system/camex-nginx-sync.service &&
+   grep -qx "Environment=UPSTREAM_PORT=8080" /etc/systemd/system/camex-nginx-sync.service'
+check $? "nginx listens on 85; the sync service has HTTP_PORT and UPSTREAM_PORT"
Evidence
The fresh-install test checks nginx listen lines and the sync-service environment, but contains no
assertion against the generated map. The rerun changes transport, pool, PSK, password, and HTTP port
only, so it does not verify non-destructive behavior for the upstream-port option.

End-to-end coverage for options and reruns
docker/test-e2e-install.sh[335-339]
docker/test-e2e-install.sh[348-357]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The option test verifies the installed service environment but does not verify that the generated nginx map routes cameras through the requested upstream port, and the rerun does not exercise changing that option.
## Fix Focus Areas
- docker/test-e2e-install.sh[335-339]
- docker/test-e2e-install.sh[348-357]
## Recommended Fix
After the first sync, inspect the generated nginx map and assert that camera upstreams use port 8080, then include a different `--upstream-port` in the rerun and assert that the installer preserves the original value and reports the edit location.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


13. Space-padded keys block client access ✓ Resolved
Description
install.sh accepts leading or trailing whitespace in passphrase-form --psk values and writes it
into camex.conf. The config parser strips that whitespace before deriving the server key, so
clients using the supplied passphrase derive a different key; a whitespace-only value instead makes
the config invalid.
Code

install.sh[R248-255]

+if [ -n "$PSK_OPT" ]; then
+    case "$PSK_OPT" in
+        *"
+"*) die "--psk: one line" ;;
+        hex:*) printf '%s\n' "${PSK_OPT#hex:}" | grep -qxE '[0-9a-fA-F]{64}' ||
+                   die "--psk: hex: needs 64 hex digits" ;;
+        base64:*) [ ${#PSK_OPT} -eq 51 ] || die "--psk: base64: needs 44 characters" ;;
+    esac
Evidence
Only newline and raw-key prefixes receive checks in the installer. The config parser trims the value
and rejects it if trimming leaves it empty.

install.sh[246-255]
install.sh[415-430]
src/config.c[469-480]
src/util.c[133-154]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The daemon trims whitespace from configured PSKs, but the installer accepts whitespace-bearing passphrases as supplied.
## Fix Focus Areas
- install.sh[246-255]
- install.sh[415-430]
## Recommended Fix
Reject supplied PSKs whose leading or trailing whitespace would be removed by the configuration parser, including whitespace-only values, before creating the config.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


14. HTTPS start pages link to the wrong port ✓ Resolved
Description
nginx_index_format adds the configured HTTP port to protocol-relative device links regardless of
the scheme used to open the start page. If nginx serves HTTPS on 443 and HTTP on a custom port such
as 85, an HTTPS visitor follows https://:85/ even though that port is configured for HTTP.
Code

src/nginxmap.c[R656-657]

+                       "class=\"bulb\"></span></td><td><a href=\"//%s%s/\">",
+                       d->host, port);
Evidence
The generated link keeps the current scheme while appending the HTTP port. The nginx example and TLS
instructions place HTTPS on 443, separate from the custom HTTP listen port.

src/nginxmap.c[653-657]
src/nginxmap.c[901-907]
examples/nginx-camex.conf[14-18]
docs/nginx.md[251-258]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Protocol-relative links force HTTPS visitors onto the custom HTTP port instead of the HTTPS listener.
## Fix Focus Areas
- src/nginxmap.c[653-657]
- src/nginxmap.c[901-907]
## Recommended Fix
Generate links that select the appropriate port for the page's scheme: the configured HTTP port for HTTP and the HTTPS listener for HTTPS. Cover both schemes in link-generation tests.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


15. Empty supplied options silently use defaults ✓ Resolved
Description
install.sh uses an empty string both for an omitted option and for an explicitly supplied empty
value. For example, --psk '' bypasses validation and generates a random key, while --password ''
generates a random password instead of rejecting the supplied value.
Code

install.sh[R215-220]

+        --transport) [ $# -ge 2 ] || usage; TRANSPORT=$2; shift 2 ;;
+        --psk)       [ $# -ge 2 ] || usage; PSK_OPT=$2; shift 2 ;;
+        --pool)      [ $# -ge 2 ] || usage; POOL=$2; shift 2 ;;
+        --password)  [ $# -ge 2 ] || usage; PASSWORD=$2; shift 2 ;;
+        --http-port) [ $# -ge 2 ] || usage; HTTP_PORT=$2; shift 2 ;;
+        --upstream-port) [ $# -ge 2 ] || usage; UPSTREAM_PORT=$2; shift 2 ;;
Evidence
Parsing stores the argument without a presence flag. Later nonempty-string tests skip PSK validation
and select the random-generation branches for both PSK and password.

install.sh[212-220]
install.sh[246-259]
install.sh[415-420]
install.sh[535-541]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
An explicitly empty option value is treated as though the option was omitted.
## Fix Focus Areas
- install.sh[212-220]
- install.sh[246-259]
- install.sh[415-420]
- install.sh[535-541]
## Recommended Fix
Track whether each option was supplied separately from its value, and reject empty values for options that require a nonempty key, password or setting.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

16. TCP reruns can falsely warn of UDP ✓ Resolved
Description
The transport check in install.sh recognizes only one separator before tcp, although the service
splits CAMEX_ARGS on arbitrary whitespace. If retained arguments contain --transport  tcp and a
rerun supplies --transport tcp, the server remains on TCP but the installer says it kept UDP and
directs the operator to edit the arguments.
Code

install.sh[R499-500]

+    grep -qE -- '(--transport[ =]|-R ?)tcp' "$DEFAULTS" && have=tcp
+    [ "$have" = "$TRANSPORT" ] ||
Evidence
The new grep does not match two spaces after --transport, while the service and the installer's
later argument inspection both split that text into a valid transport option and value. The mismatch
affects the new kept-transport message, not the server's actual transport.

install.sh[496-502]
examples/camex.service[16-17]
install.sh[658-685]
src/main.c[103-103]
src/main.c[249-259]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The rerun transport diagnostic can report UDP for a valid TCP argument containing multiple whitespace characters.
## Fix Focus Areas
- install.sh[496-502]
- install.sh[658-685]
## Recommended Fix
Determine the retained transport from shell-split arguments, as the printed-command path does, rather than matching a narrow whitespace pattern. Test a retained `CAMEX_ARGS` value with multiple spaces before `tcp`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


17. Windows build warns about an unused port parameter ✓ Resolved
Description
The Windows stub of control_nginx_index gained an http_port parameter but has no
(void)http_port; beside (void)path; and (void)domain;. Because -Wextra is enabled, the
Windows build now prints an unused-parameter warning that it did not print before.
Code

src/control.c[1580]

+int control_nginx_index(const char *path, const char *domain, int http_port)
Evidence
The stub casts the other two parameters to void but not the new one, and src/Makefile builds with
-Wall -Wextra.

src/control.c[1580-1586]
src/Makefile[41-41]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Windows stub of control_nginx_index leaves the new http_port parameter unused, which triggers a -Wextra warning.
## Fix Focus Areas
- src/control.c[1580-1586]
## Recommended Fix
Add `(void)http_port;` after `(void)domain;`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


18. --transport tcp is silently dropped with an old unit ✓ Resolved
Description
When /etc/default/camex is new but the installed camex.service has its own CAMEX_ARGS (args
not empty and without SERVER_PUBLIC_KEY), --transport tcp is only appended in the default
branch, so it is ignored. No "kept the server's transport" message is printed in this case, so the
user gets a UDP server without being told.
Code

install.sh[R457-458]

+            args="--mode server --config $CONF --server-key-file $KEY"
+            [ "$TRANSPORT" = tcp ] && args="$args --transport tcp" ;;
Evidence
The case "$args" only adds --transport tcp in the ''|*SERVER_PUBLIC_KEY* branch. The mismatch
warning is only in the else branch, for an existing $DEFAULTS.

install.sh[450-477]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`--transport` is ignored without a message when an older unit's CAMEX_ARGS are moved into a new /etc/default/camex.
## Fix Focus Areas
- install.sh[450-477]
## Recommended Fix
After writing $DEFAULTS, run the same transport comparison as in the `else` branch whenever TRANSPORT is set, so a mismatch is reported in both paths.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can turn on the rule miner and Qodo learns your standards from review history

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Add installer options for server and nginx configuration

✨ Enhancement 🧪 Tests 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Add installer options for transport, pool, pre-shared key, password, and nginx ports.
• Carry custom HTTP ports through start-page links, sync checks, and printed addresses.
• Document the options and test a fresh installation and rerun.
Diagram

graph TD
  O["Installer options"] --> I["install.sh"] --> C[("camex.conf")]
  I --> U["Systemd unit"] --> S["Nginx sync"] --> X["camex status"] --> P["Start page"]
  I --> N["Nginx config"]
  C --> X
  S --> N
  N --> P
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Resolve effective ports from installed settings on reruns
  • ➕ Keeps the sync service, start-page links, and nginx listener aligned when a new option is ignored by an existing nginx configuration.
  • ➖ Requires a reliable way to identify the effective port in an existing nginx configuration.

Recommendation: Keep the installer’s first-install configuration approach, but resolve or preserve the effective HTTP port before rewriting the sync unit. As written, a rerun with a different --http-port keeps nginx’s listen lines while replacing the unit’s HTTP_PORT, contrary to the stated settings-made-once behavior.

Files changed (15) +314 / -48

Enhancement (7) +177 / -33
camex-nginx-sync.shUse the configured nginx port for links and checks +11/-6

Use the configured nginx port for links and checks

• Passes nondefault HTTP_PORT values to nginx-index generation and probes nginx on that port. Manual --check runs can read HTTP_PORT from the installed service.

examples/camex-nginx-sync.sh

install.shConfigure server and nginx settings from new options +137/-18

Configure server and nginx settings from new options

• Validates and applies transport, pool, key, password, and port options to newly created configuration. Reports conflicting persisted values on reruns and includes the effective transport and web port in printed connection instructions.

install.sh

camex.hStore the nginx index HTTP port +1/-0

Store the nginx index HTTP port

• Adds a configuration field for the port used in generated start-page links.

src/camex.h

control.cForward HTTP port to index generation +3/-3

Forward HTTP port to index generation

• Extends the nginx-index control entry point to pass the requested port to the HTML formatter.

src/control.c

control.hDeclare the port-aware index entry point +1/-1

Declare the port-aware index entry point

• Updates the control API declaration to accept an HTTP port.

src/control.h

main.cParse --http-port for nginx-index output +19/-1

Parse --http-port for nginx-index output

• Adds a long option with port-range validation and passes its value to the nginx-index control path.

src/main.c

nginxmap.hDescribe and declare port-aware page formatting +5/-4

Describe and declare port-aware page formatting

• Updates the formatter signature and documents when device links include an HTTP port.

src/nginxmap.h

Bug fix (1) +13 / -7
nginxmap.cInclude nondefault ports in device links +13/-7

Include nondefault ports in device links

• Adds a port suffix to live-device links on the start page when the requested HTTP port is neither 80 nor unset.

src/nginxmap.c

Tests (2) +76 / -1
test-e2e-install.shExercise custom options on a second host +57/-0

Exercise custom options on a second host

• Adds a container-based installation covering TCP, pool, keys, password, and HTTP and upstream ports. Checks selected outputs, a rerun with different values, and rejection of a password without a domain.

docker/test-e2e-install.sh

test_nginxmap.cTest device links with default and custom ports +19/-1

Test device links with default and custom ports

• Verifies that links include :85 for a custom HTTP port and omit a suffix for port 80.

tests/test_nginxmap.c

Documentation (4) +47 / -6
CHANGELOG.mdRecord the 3.12.0 installer release +22/-0

Record the 3.12.0 installer release

• Documents the new installer options, port-aware start page and sync checks, and test coverage.

CHANGELOG.md

install.mdDocument installer options and rerun behavior +23/-6

Document installer options and rerun behavior

• Expands the options table, adds a custom-port installation example, and explains how to change a previously created password.

docs/install.md

nginx.mdDocument the sync service HTTP_PORT setting +1/-0

Document the sync service HTTP_PORT setting

• Describes how HTTP_PORT controls start-page links and the port used by sync checks.

docs/nginx.md

usage.mdDocument the nginx-index HTTP port option +1/-0

Document the nginx-index HTTP port option

• Adds --http-port to the status-format reference and explains its effect on device links.

docs/usage.md

Other (1) +1 / -1
version.hBump the version to 3.12.0 +1/-1

Bump the version to 3.12.0

• Sets the compiled version for this release.

src/version.h

@compot-dev

Copy link
Copy Markdown
Collaborator Author

/agentic_review

Comment thread install.sh Outdated
Comment thread install.sh Outdated
Comment thread docker/test-e2e-install.sh
Comment thread install.sh
Comment thread src/nginxmap.c Outdated
Comment thread install.sh
Comment thread install.sh
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 3f52922

… sync service made once, empty values refused, links with a port say http

- --psk: below 128 characters, no blank at its ends, hex:/base64: 32 bytes
  and not all zero (base64 decoded).
- A rerun keeps the installed service's HTTP_PORT and UPSTREAM_PORT and says
  what to edit when the option differs.
- --domain/--port/--transport/--psk/--pool/--password/--http-port/
  --upstream-port with an empty value are refused.
- --transport is compared also when an older unit's arguments were moved.
- With --http-port the start page's links are http://<ID>.<domain>:<port>/.
- e2e: a TCP client on the second host, its map entry on 8080 and its link on
  :85; bad psk values; a rerun with another --upstream-port.
@compot-dev

Copy link
Copy Markdown
Collaborator Author

/review

Comment thread install.sh
Comment thread install.sh Outdated
Comment thread install.sh
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 2fde749

…rintf for the psk and the password

- A rerun with another --port keeps port= of camex.conf and says to edit
  it there.
- The transport of camex.service is read as camex reads it: -R tcp, -Rtcp,
  --transport tcp, --transport=tcp; so are -f, -S, -k and -p with their
  value attached.
- psk= of camex.conf, the printed client command and the start page's
  password are written with printf: dash's echo reads \c and \n in them.
- e2e: a psk and a password with a backslash, -Rtcp in /etc/default/camex
  and another --port on the rerun.
@compot-dev

Copy link
Copy Markdown
Collaborator Author

/review

Comment thread install.sh
Comment thread install.sh
Comment thread install.sh
Comment thread install.sh Outdated
Comment thread src/control.c
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 32fbe1a

…the password, the Windows stub

- HTTP_PORT of camex-nginx-sync.service is the first listen port of
  nginx's file, kept or just made: a file made again with --http-port, or
  a service made again without it, agree with nginx.
- camex-nginx-sync --check escapes \ and " of the password in curl's
  quoted value.
- control_nginx_index()'s Windows stub: http_port unused (-Wextra).
- e2e: a quote in the password (--check opens the start page with it);
  nginx's file made again on --http-port 87; the sync service made again.
@compot-dev

Copy link
Copy Markdown
Collaborator Author

/review

Comment thread install.sh Outdated
Comment thread install.sh Outdated
Comment thread install.sh Outdated
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit f79085b

…n HTTP listen port, --psk counted in bytes

- read_args(): CAMEX_ARGS split as the shell splits it, for the transport
  check on a rerun and for the summary (--transport   tcp is TCP).
- nginx's port: the first listen line without ssl or quic, <port>,
  <address>:<port> or [::]:<port>.
- --psk below 128 bytes, as camex counts it (UTF-8 letters are more).
- e2e: listen 0.0.0.0:87; --transport with more blanks in CAMEX_ARGS; a
  psk of 64 two-byte letters refused.
@compot-dev

Copy link
Copy Markdown
Collaborator Author

/review

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 2341c9e

@compot-dev
compot-dev merged commit cd697e5 into master Oct 28, 2026
18 checks passed
@compot-dev
compot-dev deleted the installer-options branch October 28, 2026 08:12
compot-dev added a commit that referenced this pull request Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

install.sh: --password, --psk, --transport, --pool, --upstream-port, --http-port

1 participant