mock-mfa-sms (1565B)
1 #!/bin/sh 2 # Development-only SMS challenger delivery helper. Challenger provides the 3 # address as a JSON object in $1 and the MFA message on standard input. 4 set -eu 5 6 if [ "$#" -ne 1 ]; then 7 echo "usage: mock-mfa-sms ADDRESS_JSON" >&2 8 exit 64 9 fi 10 11 # Challenger passes the complete address object to AUTH_COMMAND, for example 12 # {"CONTACT_PHONE":"+41700000006"}, rather than just the field value. 13 # Invalid input is left to the real helper so this wrapper does not change its 14 # normal error handling. 15 if ! phone_number=$( 16 printf '%s\n' "$1" | 17 jq -er \ 18 'if type == "object" and ((.CONTACT_PHONE | type) == "string") then .CONTACT_PHONE else empty end' \ 19 2>/dev/null 20 ); then 21 exec challenger-send-sms "$@" 22 fi 23 24 # Keep real deliveries real. Only the reserved staging phone numbers 25 # documented for MyTOPS development testing are captured locally. 26 case "$phone_number" in 27 +417000000[0-9][0-9]) 28 ;; 29 *) 30 exec challenger-send-sms "$@" 31 ;; 32 esac 33 34 message_dir=/var/www/mock-mfa 35 # Keep phone-number filenames readable while preventing a supplied number from 36 # escaping the message directory. 37 filename=$(LC_ALL=C printf '%s' "$phone_number" | tr -c '[:alnum:]@+._-' '_') 38 39 # Files must be readable by nginx through the challenger-mock-mfa group. Write 40 # atomically so the web server never exposes a partially-written MFA message. 41 umask 007 42 tmpfile=$(mktemp "$message_dir/.${filename}.XXXXXX") 43 trap 'rm -f "$tmpfile"' EXIT HUP INT TERM 44 chmod 0640 "$tmpfile" 45 cat >"$tmpfile" 46 mv -f "$tmpfile" "$message_dir/$filename.txt" 47 trap - EXIT HUP INT TERM