#!/bin/sh set -eu export BITMESSAGE_API_USER="${BITMESSAGE_API_USER:-bitmessage_api_user}" export BITMESSAGE_API_PASSWORD="${BITMESSAGE_API_PASSWORD:-bitmessage_api_password}" export BITMESSAGE_SEED_ADDRESSES="${BITMESSAGE_SEED_ADDRESSES:-0}" export BITMESSAGE_API_PORT="${BITMESSAGE_API_PORT:-8442}" export BITMESSAGE_TTL="${BITMESSAGE_TTL:-172800}" export BITMESSAGE_STOPRESENDINGAFTERXDAYS="${BITMESSAGE_STOPRESENDINGAFTERXDAYS:-30}" export BITMESSAGE_APIVARIANT="${BITMESSAGE_APIVARIANT:-legacy}" export BITMESSAGE_MAXTOTALCONNECTIONS="${BITMESSAGE_MAXTOTALCONNECTIONS:-200}" # Reject anything but a plain number: this value is written into keys.dat, and # unlike the credentials below it has no business containing characters that # esc() would have to neutralise. A typo here would otherwise land in the config # as a key the daemon silently ignores. case "$BITMESSAGE_MAXTOTALCONNECTIONS" in '' | *[!0-9]*) echo "BITMESSAGE_MAXTOTALCONNECTIONS must be a positive integer" >&2 exit 1 ;; esac if [ -z "${BITMESSAGE_SEED_PHRASE:-}" ] then BITMESSAGE_SEED_PHRASE="$(cat /dev/random | tr -dc "a-z" | head -c32)" export BITMESSAGE_SEED_PHRASE fi # Escape a value for use on the right-hand side of the sed expressions below. # There, a backslash starts an escape, "&" stands for the whole match, and "|" # ends the replacement because it is the delimiter. Unescaped, a password # containing "&" was silently rewritten into something else and one containing # "|" made sed fail outright. esc() { printf '%s' "$1" | sed -e 's/[\\&|]/\\&/g' } # this command must be run as root (for bind mounts to container) if [ -f keys.dat ] then chown bitmessage:bitmessage keys.dat chmod 600 keys.dat fi # maxtotalconnections is the only brake on a node whose P2P port (8444) is # published: it caps inbound sockets at the total minus maxoutboundconnections. # The substitution below is a no-op when the key is missing, which would ship a # node that looks capped and is not -- and the PyBitmessage clone in the # Dockerfile is unpinned, so the stock config is whatever upstream generates # today. Add the key rather than trust the substitution alone; line 1 is the # [bitmessagesettings] header the daemon reads it from. if ! grep -q "^maxtotalconnections = " keys.dat then gosu bitmessage sed -i "1a maxtotalconnections = $BITMESSAGE_MAXTOTALCONNECTIONS" keys.dat fi # Set config values. Every expression is anchored to the start of the line and # names its key in the replacement, so no backreference is involved and nothing # in another section can match. With set -e a failure here now stops the # container instead of leaving the daemon on its previous settings unnoticed -- # including the case of a bind mount with no keys.dat at all. gosu bitmessage sed -i \ -e "s|^apiinterface = .*|apiinterface = 0.0.0.0|" \ -e "s|^apivariant = .*|apivariant = $(esc "$BITMESSAGE_APIVARIANT")|" \ -e "s|^apiusername = .*|apiusername = $(esc "$BITMESSAGE_API_USER")|" \ -e "s|^apipassword = .*|apipassword = $(esc "$BITMESSAGE_API_PASSWORD")|" \ -e "s|^apiport = .*|apiport = $(esc "$BITMESSAGE_API_PORT")|" \ -e "s|^apienabled = .*|apienabled = True|" \ -e "s|^ttl = .*|ttl = $(esc "$BITMESSAGE_TTL")|" \ -e "s|^stopresendingafterxdays = .*|stopresendingafterxdays = $(esc "$BITMESSAGE_STOPRESENDINGAFTERXDAYS")|" \ -e "s|^maxtotalconnections = .*|maxtotalconnections = $BITMESSAGE_MAXTOTALCONNECTIONS|" \ -e "s|^udp = .*|udp = False|" keys.dat # generate address from seed if [ "$BITMESSAGE_SEED_ADDRESSES" -gt 0 ] then # Four attempts, not a bash {1..4}: this runs under dash, where brace # expansion is literal and the loop would have run once. The call is # idempotent (createDeterministicAddresses returns nothing for an address # that already exists), so these are retries while the API comes up. for i in 1 2 3 4 do sleep 15 gosu bitmessage /usr/bin/python /usr/local/bin/seed_addr_gen.py done & fi exec gosu bitmessage pybitmessage -d