test_anastasis_reducer_recovery_no_pay.sh (10065B)
1 #!/bin/bash 2 # This file is in the public domain. 3 4 set -eu 5 set -x 6 7 # Exit, with status code "skip" (no 'real' failure) 8 function exit_skip() { 9 echo " SKIP: $1" 10 exit 77 11 } 12 13 # Exit, with error message (hard failure) 14 function exit_fail() { 15 echo " FAIL: $1" 16 exit 1 17 } 18 19 # Cleanup to run whenever we exit 20 function cleanup() 21 { 22 for n in `jobs -p` 23 do 24 kill $n 2> /dev/null || true 25 done 26 rm -rf $CONF $R1FILE $R2FILE $B1FILE $B2FILE $TMP_DIR 27 wait 28 } 29 30 function sync_providers() { 31 infile=$1 32 outfile=$2 33 echo "Synchronizing providers" 34 # Sync with providers (up to 3 providers aren't synced here) 35 for x in 1 2 3; do 36 echo "Synchronizing providers (round $x)" 37 #anastasis-reducer sync_providers < $infile > $outfile 2> /dev/null || true 38 anastasis-reducer sync_providers < $infile > $outfile || true 39 CODE=$(jq -r -e ".code // 0" < $outfile) 40 # ANASTASIS_REDUCER_PROVIDERS_ALREADY_SYNCED 41 # FIXME: Temporary workaround for C reducer. See #7227. 42 if test "$CODE" = "8420"; then 43 # restore previous non-error state 44 cat $infile > $outfile 45 break 46 fi 47 # ANASTASIS_REDUCER_ACTION_INVALID 48 if test "$CODE" = "8400"; then 49 # restore previous non-error state 50 cat $infile > $outfile 51 break 52 fi 53 if test "$CODE" != "0"; then 54 exit_fail "Expected no error or 8420/8400, got $CODE" 55 fi 56 cat $outfile > $infile 57 done 58 echo "Providers synced." 59 } 60 61 62 CONF_1="test_anastasis_reducer_free_1.conf" 63 CONF_2="test_anastasis_reducer_free_2.conf" 64 CONF_3="test_anastasis_reducer_free_3.conf" 65 CONF_4="test_anastasis_reducer_free_4.conf" 66 67 68 # Configuration file will be edited, so we create one 69 # from the template. 70 CONF=$(mktemp test_reducerXXXXXX.conf) 71 cp test_reducer.conf "$CONF" 72 73 TMP_DIR=`mktemp -d keys-tmp-XXXXXX` 74 B1FILE=`mktemp test_reducer_stateB1XXXXXX` 75 B2FILE=`mktemp test_reducer_stateB2XXXXXX` 76 R1FILE=`mktemp test_reducer_stateR1XXXXXX` 77 R2FILE=`mktemp test_reducer_stateR2XXXXXX` 78 export B1FILE 79 export B2FILE 80 export R1FILE 81 export R2FILE 82 83 # Install cleanup handler (except for kill -9) 84 trap cleanup EXIT 85 86 # Check we can actually run 87 echo -n "Testing for jq" 88 jq -h > /dev/null || exit_skip "jq required" 89 echo " FOUND" 90 echo -n "Testing for anastasis-reducer ..." 91 anastasis-reducer -h > /dev/null || exit_skip "anastasis-reducer required" 92 echo " FOUND" 93 94 echo -n "Testing for anastasis-httpd" 95 anastasis-httpd -h >/dev/null </dev/null || exit_skip " MISSING" 96 echo " FOUND" 97 98 echo -n "Initialize anastasis database ..." 99 # Name of the Postgres database we will use for the script. 100 # Will be dropped, do NOT use anything that might be used 101 # elsewhere 102 TARGET_DB_1=`anastasis-config -c $CONF_1 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"` 103 TARGET_DB_2=`anastasis-config -c $CONF_2 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"` 104 TARGET_DB_3=`anastasis-config -c $CONF_3 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"` 105 TARGET_DB_4=`anastasis-config -c $CONF_4 -s stasis-postgres -o CONFIG | sed -e "s/^postgres:\/\/\///"` 106 107 dropdb $TARGET_DB_1 >/dev/null 2>/dev/null || true 108 createdb $TARGET_DB_1 || exit_skip "Could not create database $TARGET_DB_1" 109 anastasis-dbinit -c $CONF_1 2> anastasis-dbinit_1.log 110 dropdb $TARGET_DB_2 >/dev/null 2>/dev/null || true 111 createdb $TARGET_DB_2 || exit_skip "Could not create database $TARGET_DB_2" 112 anastasis-dbinit -c $CONF_2 2> anastasis-dbinit_2.log 113 dropdb $TARGET_DB_3 >/dev/null 2>/dev/null || true 114 createdb $TARGET_DB_3 || exit_skip "Could not create database $TARGET_DB_3" 115 anastasis-dbinit -c $CONF_3 2> anastasis-dbinit_3.log 116 dropdb $TARGET_DB_4 >/dev/null 2>/dev/null || true 117 createdb $TARGET_DB_4 || exit_skip "Could not create database $TARGET_DB_4" 118 anastasis-dbinit -c $CONF_4 2> anastasis-dbinit_4.log 119 120 echo " OK" 121 122 echo -n "Launching anastasis services ..." 123 PREFIX="" #valgrind 124 $PREFIX anastasis-httpd -L DEBUG -c $CONF_1 2> anastasis-httpd_1.log & 125 $PREFIX anastasis-httpd -L DEBUG -c $CONF_2 2> anastasis-httpd_2.log & 126 $PREFIX anastasis-httpd -L DEBUG -c $CONF_3 2> anastasis-httpd_3.log & 127 $PREFIX anastasis-httpd -L DEBUG -c $CONF_4 2> anastasis-httpd_4.log & 128 129 echo -n "Waiting for anastasis services ..." 130 131 # Wait for anastasis services to be available 132 for n in `seq 1 50` 133 do 134 echo -n "." 135 sleep 0.1 136 OK=0 137 # anastasis_01 138 wget --tries=1 --timeout=1 http://localhost:8086/ -o /dev/null -O /dev/null >/dev/null || continue 139 # anastasis_02 140 wget --tries=1 --timeout=1 http://localhost:8087/ -o /dev/null -O /dev/null >/dev/null || continue 141 # anastasis_03 142 wget --tries=1 --timeout=1 http://localhost:8088/ -o /dev/null -O /dev/null >/dev/null || continue 143 # anastasis_04 144 wget --tries=1 --timeout=1 http://localhost:8089/ -o /dev/null -O /dev/null >/dev/null || continue 145 OK=1 146 break 147 done 148 149 if [ 1 != $OK ] 150 then 151 exit_skip "Failed to launch anastasis services" 152 fi 153 echo "OK" 154 155 echo -n "Running backup logic ...," 156 anastasis-reducer -b > $B1FILE 157 echo -n "." 158 anastasis-reducer -a \ 159 '{"continent": "Demoworld"}' \ 160 select_continent < $B1FILE > $B2FILE 161 echo -n "." 162 anastasis-reducer -a \ 163 '{"country_code": "xx"}' \ 164 select_country < $B2FILE > $B1FILE 165 echo -n "." 166 anastasis-reducer -a \ 167 '{"identity_attributes": { 168 "full_name": "Max Musterman", 169 "sq_number": "4", 170 "birthdate": "2000-01-01"}}' \ 171 enter_user_attributes < $B1FILE > $B2FILE 172 cat $B2FILE > $B1FILE 173 echo -n "," 174 sync_providers $B1FILE $B2FILE 175 echo -n "," 176 # "91GPWWR" encodes "Hans" 177 anastasis-reducer -a \ 178 '{"authentication_method": { 179 "type": "question", 180 "instructions": "What is your name?", 181 "challenge": "91GPWWR" 182 } }' \ 183 add_authentication < $B2FILE > $B1FILE 184 echo -n "." 185 # "64S36" encodes "123" 186 anastasis-reducer -a \ 187 '{"authentication_method": { 188 "type": "question", 189 "instructions": "How old are you?", 190 "challenge": "64S36" 191 } }' \ 192 add_authentication < $B1FILE > $B2FILE 193 echo -n "." 194 # "9NGQ4WR" encodes "Mars" 195 anastasis-reducer -a \ 196 '{"authentication_method": { 197 "type": "question", 198 "instructions": "Where do you live?", 199 "challenge": "9NGQ4WR" 200 } }' \ 201 add_authentication < $B2FILE > $B1FILE 202 echo -n "." 203 # Finished adding authentication methods 204 anastasis-reducer \ 205 next < $B1FILE > $B2FILE 206 207 208 echo -n "," 209 # Finished policy review 210 anastasis-reducer \ 211 next < $B2FILE > $B1FILE 212 echo -n "." 213 214 # Note: 'secret' must here be a Crockford base32-encoded value 215 anastasis-reducer -a \ 216 '{"secret": { "value" : "VERYHARDT0GVESSSECRET", "mime" : "text/plain" }}' \ 217 enter_secret < $B1FILE > $B2FILE 218 anastasis-reducer next $B2FILE $B1FILE 219 echo " OK" 220 221 echo -n "Final backup checks ..." 222 STATE=`jq -r -e .backup_state < $B1FILE` 223 if test "$STATE" != "BACKUP_FINISHED" 224 then 225 exit_fail "Expected new state to be 'BACKUP_FINISHED', got '$STATE'" 226 fi 227 228 jq -r -e .core_secret < $B1FILE > /dev/null && exit_fail "'core_secret' was not cleared upon success" 229 230 echo " OK" 231 232 233 echo -n "Running recovery basic logic ..." 234 anastasis-reducer -r > $R1FILE 235 anastasis-reducer -a \ 236 '{"continent": "Demoworld"}' \ 237 select_continent < $R1FILE > $R2FILE 238 anastasis-reducer -a \ 239 '{"country_code": "xx" }' \ 240 select_country < $R2FILE > $R1FILE 241 anastasis-reducer -a '{"identity_attributes": { "full_name": "Max Musterman", "sq_number": "4", "birthdate": "2000-01-01" }}' enter_user_attributes < $R1FILE > $R2FILE 242 243 244 STATE=`jq -r -e .recovery_state < $R2FILE` 245 if test "$STATE" != "SECRET_SELECTING" 246 then 247 exit_fail "Expected new state to be 'SECRET_SELECTING', got '$STATE'" 248 fi 249 echo " OK" 250 251 echo -n "Adding provider (to ensure it is loaded)" 252 anastasis-reducer -a '{"provider_url" : "http://localhost:8086/" }' add_provider < $R2FILE > $R1FILE 253 echo " OK" 254 255 echo -n "Selecting secret to recover" 256 anastasis-reducer -a '{"attribute_mask": 0, "providers" : [ { "version": 1, "url" : "http://localhost:8086/" } ] }' select_version < $R1FILE > $R2FILE 257 258 STATE=`jq -r -e .recovery_state < $R2FILE` 259 if test "$STATE" != "CHALLENGE_SELECTING" 260 then 261 exit_fail "Expected new state to be 'CHALLENGE_SELECTING', got '$STATE'" 262 fi 263 echo " OK" 264 265 cat $R2FILE > $R1FILE 266 sync_providers $R1FILE $R2FILE 267 268 echo -n "Running challenge logic ..." 269 270 cat $R2FILE | jq . 271 272 UUID0=`jq -r -e .recovery_information.challenges[0].uuid < $R2FILE` 273 UUID1=`jq -r -e .recovery_information.challenges[1].uuid < $R2FILE` 274 UUID2=`jq -r -e .recovery_information.challenges[2].uuid < $R2FILE` 275 UUID0Q=`jq -r -e .recovery_information.challenges[0].instructions < $R2FILE` 276 UUID1Q=`jq -r -e .recovery_information.challenges[1].instructions < $R2FILE` 277 UUID2Q=`jq -r -e .recovery_information.challenges[2].instructions < $R2FILE` 278 279 if test "$UUID2Q" = 'How old are you?' 280 then 281 AGE_UUID=$UUID2 282 elif test "$UUID1Q" = 'How old are you?' 283 then 284 AGE_UUID=$UUID1 285 else 286 AGE_UUID=$UUID0 287 fi 288 289 if test "$UUID2Q" = 'What is your name?' 290 then 291 NAME_UUID=$UUID2 292 elif test "$UUID1Q" = 'What is your name?' 293 then 294 NAME_UUID=$UUID1 295 else 296 NAME_UUID=$UUID0 297 fi 298 299 anastasis-reducer -a \ 300 "$(jq -n ' 301 { 302 uuid: $UUID 303 }' \ 304 --arg UUID "$NAME_UUID" 305 )" \ 306 select_challenge < $R2FILE > $R1FILE 307 308 anastasis-reducer -a '{"answer": "Hans"}' \ 309 solve_challenge < $R1FILE > $R2FILE 310 311 anastasis-reducer -a \ 312 "$(jq -n ' 313 { 314 uuid: $UUID 315 }' \ 316 --arg UUID "$AGE_UUID" 317 )" \ 318 select_challenge < $R2FILE > $R1FILE 319 320 anastasis-reducer -a '{"answer": "123"}' \ 321 solve_challenge < $R1FILE > $R2FILE 322 323 echo " OK" 324 325 echo -n "Checking recovered secret ..." 326 # finally: check here that we recovered the secret... 327 328 STATE=`jq -r -e .recovery_state < $R2FILE` 329 if test "$STATE" != "RECOVERY_FINISHED" 330 then 331 jq -e . $R2FILE 332 exit_fail "Expected new state to be 'RECOVERY_FINISHED', got '$STATE'" 333 fi 334 335 SECRET=`jq -r -e .core_secret.value < $R2FILE` 336 if test "$SECRET" != "VERYHARDT0GVESSSECRET" 337 then 338 jq -e . $R2FILE 339 exit_fail "Expected recovered secret to be 'VERYHARDT0GVESSSECRET', got '$SECRET'" 340 fi 341 342 MIME=`jq -r -e .core_secret.mime < $R2FILE` 343 if test "$MIME" != "text/plain" 344 then 345 jq -e . $R2FILE 346 exit_fail "Expected recovered mime to be 'text/plain', got '$MIME'" 347 fi 348 349 echo " OK" 350 351 exit 0