diff options
Diffstat (limited to 'src/reducer/anastasis_api_recovery_redux.c')
-rw-r--r-- | src/reducer/anastasis_api_recovery_redux.c | 165 |
1 files changed, 164 insertions, 1 deletions
diff --git a/src/reducer/anastasis_api_recovery_redux.c b/src/reducer/anastasis_api_recovery_redux.c index fab3c24..95632cc 100644 --- a/src/reducer/anastasis_api_recovery_redux.c +++ b/src/reducer/anastasis_api_recovery_redux.c | |||
@@ -151,6 +151,13 @@ struct SelectChallengeContext | |||
151 | * Payment secret, if we are in the "pay" state. | 151 | * Payment secret, if we are in the "pay" state. |
152 | */ | 152 | */ |
153 | struct ANASTASIS_PaymentSecretP ps; | 153 | struct ANASTASIS_PaymentSecretP ps; |
154 | |||
155 | /** | ||
156 | * Application asked us to only poll for existing | ||
157 | * asynchronous challenges, and not to being a | ||
158 | * new one. | ||
159 | */ | ||
160 | bool poll_only; | ||
154 | }; | 161 | }; |
155 | 162 | ||
156 | 163 | ||
@@ -741,7 +748,6 @@ solve_challenge_cb (void *cls, | |||
741 | &ps), | 748 | &ps), |
742 | GNUNET_JSON_spec_end () | 749 | GNUNET_JSON_spec_end () |
743 | }; | 750 | }; |
744 | |||
745 | json_t *challenge; | 751 | json_t *challenge; |
746 | 752 | ||
747 | if (NULL == ri) | 753 | if (NULL == ri) |
@@ -769,6 +775,80 @@ solve_challenge_cb (void *cls, | |||
769 | return; | 775 | return; |
770 | } | 776 | } |
771 | 777 | ||
778 | /* resume all async, unsolved challenges */ | ||
779 | { | ||
780 | bool poll_started = false; | ||
781 | |||
782 | for (unsigned int i = 0; i<ri->cs_len; i++) | ||
783 | { | ||
784 | struct ANASTASIS_Challenge *ci = ri->cs[i]; | ||
785 | const struct ANASTASIS_ChallengeDetails *cd; | ||
786 | json_t *challenge; | ||
787 | json_t *pin; | ||
788 | |||
789 | cd = ANASTASIS_challenge_get_details (ci); | ||
790 | if (cd->solved || | ||
791 | (! cd->async) ) | ||
792 | continue; | ||
793 | |||
794 | challenge = find_challenge_in_ri (sctx->state, | ||
795 | &cd->uuid); | ||
796 | if (NULL == challenge) | ||
797 | { | ||
798 | GNUNET_break_op (0); | ||
799 | ANASTASIS_redux_fail_ (sctx->cb, | ||
800 | sctx->cb_cls, | ||
801 | TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, | ||
802 | "challenge not found"); | ||
803 | sctx_free (sctx); | ||
804 | return; | ||
805 | } | ||
806 | pin = json_object_get (challenge, | ||
807 | "answer-pin"); | ||
808 | if (! json_is_integer (pin)) | ||
809 | { | ||
810 | GNUNET_break_op (0); | ||
811 | ANASTASIS_redux_fail_ (sctx->cb, | ||
812 | sctx->cb_cls, | ||
813 | TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, | ||
814 | "async challenge 'answer-pin' not found"); | ||
815 | sctx_free (sctx); | ||
816 | return; | ||
817 | } | ||
818 | if (GNUNET_OK != | ||
819 | ANASTASIS_challenge_answer2 (ci, | ||
820 | psp, | ||
821 | timeout, | ||
822 | json_integer_value (pin), | ||
823 | &answer_feedback_cb, | ||
824 | sctx)) | ||
825 | { | ||
826 | ANASTASIS_redux_fail_ (sctx->cb, | ||
827 | sctx->cb_cls, | ||
828 | TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, | ||
829 | "Failed to begin answering asynchronous challenge"); | ||
830 | sctx_free (sctx); | ||
831 | return; | ||
832 | } | ||
833 | poll_started = true; | ||
834 | } | ||
835 | |||
836 | if (sctx->poll_only) | ||
837 | { | ||
838 | if (! poll_started) | ||
839 | { | ||
840 | GNUNET_break_op (0); | ||
841 | ANASTASIS_redux_fail_ (sctx->cb, | ||
842 | sctx->cb_cls, | ||
843 | TALER_EC_ANASTASIS_REDUCER_ACTION_INVALID, | ||
844 | "no challenge available for polling"); | ||
845 | return; | ||
846 | } | ||
847 | /* only polling, do not start new challenges */ | ||
848 | return; | ||
849 | } | ||
850 | } /* end resuming async challenges */ | ||
851 | |||
772 | /* Check if we got a payment_secret */ | 852 | /* Check if we got a payment_secret */ |
773 | challenge = find_challenge_in_ri (sctx->state, | 853 | challenge = find_challenge_in_ri (sctx->state, |
774 | &sctx->uuid); | 854 | &sctx->uuid); |
@@ -823,6 +903,7 @@ solve_challenge_cb (void *cls, | |||
823 | psp = &ps; | 903 | psp = &ps; |
824 | } | 904 | } |
825 | 905 | ||
906 | /* start or solve selected challenge */ | ||
826 | for (unsigned int i = 0; i<ri->cs_len; i++) | 907 | for (unsigned int i = 0; i<ri->cs_len; i++) |
827 | { | 908 | { |
828 | struct ANASTASIS_Challenge *ci = ri->cs[i]; | 909 | struct ANASTASIS_Challenge *ci = ri->cs[i]; |
@@ -830,6 +911,8 @@ solve_challenge_cb (void *cls, | |||
830 | int ret; | 911 | int ret; |
831 | 912 | ||
832 | cd = ANASTASIS_challenge_get_details (ci); | 913 | cd = ANASTASIS_challenge_get_details (ci); |
914 | if (cd->async) | ||
915 | continue; /* handled above */ | ||
833 | if (0 != | 916 | if (0 != |
834 | GNUNET_memcmp (&sctx->uuid, | 917 | GNUNET_memcmp (&sctx->uuid, |
835 | &cd->uuid)) | 918 | &cd->uuid)) |
@@ -883,6 +966,12 @@ solve_challenge_cb (void *cls, | |||
883 | { | 966 | { |
884 | uint64_t ianswer = json_integer_value (pin); | 967 | uint64_t ianswer = json_integer_value (pin); |
885 | 968 | ||
969 | /* persist answer, in case async processing | ||
970 | happens via poll */ | ||
971 | GNUNET_assert (0 == | ||
972 | json_object_set (challenge, | ||
973 | "answer-pin", | ||
974 | pin)); | ||
886 | ret = ANASTASIS_challenge_answer2 (ci, | 975 | ret = ANASTASIS_challenge_answer2 (ci, |
887 | psp, | 976 | psp, |
888 | timeout, | 977 | timeout, |
@@ -1153,6 +1242,75 @@ solve_challenge (json_t *state, | |||
1153 | 1242 | ||
1154 | 1243 | ||
1155 | /** | 1244 | /** |
1245 | * The user asked for us to poll on pending | ||
1246 | * asynchronous challenges to see if they have | ||
1247 | * now completed / been satisfied. | ||
1248 | * | ||
1249 | * @param[in] state we are in | ||
1250 | * @param arguments our arguments with the solution | ||
1251 | * @param cb functiont o call with the new state | ||
1252 | * @param cb_cls closure for @a cb | ||
1253 | * @return handle to cancel challenge selection step | ||
1254 | */ | ||
1255 | static struct ANASTASIS_ReduxAction * | ||
1256 | poll_challenges (json_t *state, | ||
1257 | const json_t *arguments, | ||
1258 | ANASTASIS_ActionCallback cb, | ||
1259 | void *cb_cls) | ||
1260 | { | ||
1261 | struct SelectChallengeContext *sctx | ||
1262 | = GNUNET_new (struct SelectChallengeContext); | ||
1263 | json_t *rd; | ||
1264 | |||
1265 | if (NULL == arguments) | ||
1266 | { | ||
1267 | ANASTASIS_redux_fail_ (cb, | ||
1268 | cb_cls, | ||
1269 | TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID, | ||
1270 | "arguments missing"); | ||
1271 | return NULL; | ||
1272 | } | ||
1273 | rd = json_object_get (state, | ||
1274 | "recovery_document"); | ||
1275 | if (NULL == rd) | ||
1276 | { | ||
1277 | GNUNET_break_op (0); | ||
1278 | ANASTASIS_redux_fail_ (cb, | ||
1279 | cb_cls, | ||
1280 | TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, | ||
1281 | "poll_challenges"); | ||
1282 | return NULL; | ||
1283 | } | ||
1284 | sctx->poll_only = true; | ||
1285 | sctx->cb = cb; | ||
1286 | sctx->cb_cls = cb_cls; | ||
1287 | sctx->state = json_incref (state); | ||
1288 | sctx->args = json_incref ((json_t*) arguments); | ||
1289 | sctx->r = ANASTASIS_recovery_deserialize (ANASTASIS_REDUX_ctx_, | ||
1290 | rd, | ||
1291 | &solve_challenge_cb, | ||
1292 | sctx, | ||
1293 | &core_secret_cb, | ||
1294 | sctx); | ||
1295 | if (NULL == sctx->r) | ||
1296 | { | ||
1297 | json_decref (sctx->state); | ||
1298 | json_decref (sctx->args); | ||
1299 | GNUNET_free (sctx); | ||
1300 | GNUNET_break_op (0); | ||
1301 | ANASTASIS_redux_fail_ (cb, | ||
1302 | cb_cls, | ||
1303 | TALER_EC_ANASTASIS_REDUCER_STATE_INVALID, | ||
1304 | "'recovery_document' invalid"); | ||
1305 | return NULL; | ||
1306 | } | ||
1307 | sctx->ra.cleanup = &sctx_free; | ||
1308 | sctx->ra.cleanup_cls = sctx; | ||
1309 | return &sctx->ra; | ||
1310 | } | ||
1311 | |||
1312 | |||
1313 | /** | ||
1156 | * The user selected a challenge to be solved. Handle the payment | 1314 | * The user selected a challenge to be solved. Handle the payment |
1157 | * process. | 1315 | * process. |
1158 | * | 1316 | * |
@@ -1712,6 +1870,11 @@ ANASTASIS_recovery_action_ (json_t *state, | |||
1712 | }, | 1870 | }, |
1713 | { | 1871 | { |
1714 | ANASTASIS_RECOVERY_STATE_CHALLENGE_SELECTING, | 1872 | ANASTASIS_RECOVERY_STATE_CHALLENGE_SELECTING, |
1873 | "poll", | ||
1874 | &poll_challenges | ||
1875 | }, | ||
1876 | { | ||
1877 | ANASTASIS_RECOVERY_STATE_CHALLENGE_SELECTING, | ||
1715 | "back", | 1878 | "back", |
1716 | &ANASTASIS_back_generic_decrement_ | 1879 | &ANASTASIS_back_generic_decrement_ |
1717 | }, | 1880 | }, |