diff options
Diffstat (limited to 'src/backend/anastasis-httpd_truth.c')
-rw-r--r-- | src/backend/anastasis-httpd_truth.c | 154 |
1 files changed, 82 insertions, 72 deletions
diff --git a/src/backend/anastasis-httpd_truth.c b/src/backend/anastasis-httpd_truth.c index 8fb1aee..0b0d22f 100644 --- a/src/backend/anastasis-httpd_truth.c +++ b/src/backend/anastasis-httpd_truth.c | |||
@@ -1383,7 +1383,6 @@ AH_handler_truth_get ( | |||
1383 | enum ANASTASIS_DB_CodeStatus cs; | 1383 | enum ANASTASIS_DB_CodeStatus cs; |
1384 | bool satisfied; | 1384 | bool satisfied; |
1385 | 1385 | ||
1386 | GNUNET_free (decrypted_truth); | ||
1387 | GNUNET_free (truth_mime); | 1386 | GNUNET_free (truth_mime); |
1388 | cs = db->verify_challenge_code (db->cls, | 1387 | cs = db->verify_challenge_code (db->cls, |
1389 | &gc->truth_uuid, | 1388 | &gc->truth_uuid, |
@@ -1394,6 +1393,7 @@ AH_handler_truth_get ( | |||
1394 | case ANASTASIS_DB_CODE_STATUS_CHALLENGE_CODE_MISMATCH: | 1393 | case ANASTASIS_DB_CODE_STATUS_CHALLENGE_CODE_MISMATCH: |
1395 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1394 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1396 | "Provided response does not match our stored challenge\n"); | 1395 | "Provided response does not match our stored challenge\n"); |
1396 | GNUNET_free (decrypted_truth); | ||
1397 | return TALER_MHD_reply_with_error (connection, | 1397 | return TALER_MHD_reply_with_error (connection, |
1398 | MHD_HTTP_FORBIDDEN, | 1398 | MHD_HTTP_FORBIDDEN, |
1399 | TALER_EC_ANASTASIS_TRUTH_CHALLENGE_FAILED, | 1399 | TALER_EC_ANASTASIS_TRUTH_CHALLENGE_FAILED, |
@@ -1401,6 +1401,7 @@ AH_handler_truth_get ( | |||
1401 | case ANASTASIS_DB_CODE_STATUS_HARD_ERROR: | 1401 | case ANASTASIS_DB_CODE_STATUS_HARD_ERROR: |
1402 | case ANASTASIS_DB_CODE_STATUS_SOFT_ERROR: | 1402 | case ANASTASIS_DB_CODE_STATUS_SOFT_ERROR: |
1403 | GNUNET_break (0); | 1403 | GNUNET_break (0); |
1404 | GNUNET_free (decrypted_truth); | ||
1404 | return TALER_MHD_reply_with_error (gc->connection, | 1405 | return TALER_MHD_reply_with_error (gc->connection, |
1405 | MHD_HTTP_INTERNAL_SERVER_ERROR, | 1406 | MHD_HTTP_INTERNAL_SERVER_ERROR, |
1406 | TALER_EC_GENERIC_DB_FETCH_FAILED, | 1407 | TALER_EC_GENERIC_DB_FETCH_FAILED, |
@@ -1409,91 +1410,100 @@ AH_handler_truth_get ( | |||
1409 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1410 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1410 | "No challenge known (challenge is invalidated after %u requests)\n", | 1411 | "No challenge known (challenge is invalidated after %u requests)\n", |
1411 | INITIAL_RETRY_COUNTER); | 1412 | INITIAL_RETRY_COUNTER); |
1413 | GNUNET_free (decrypted_truth); | ||
1412 | return TALER_MHD_reply_with_error (connection, | 1414 | return TALER_MHD_reply_with_error (connection, |
1413 | MHD_HTTP_TOO_MANY_REQUESTS, | 1415 | MHD_HTTP_TOO_MANY_REQUESTS, |
1414 | TALER_EC_ANASTASIS_TRUTH_RATE_LIMITED, | 1416 | TALER_EC_ANASTASIS_TRUTH_RATE_LIMITED, |
1415 | NULL); | 1417 | NULL); |
1416 | case ANASTASIS_DB_CODE_STATUS_VALID_CODE_STORED: | 1418 | case ANASTASIS_DB_CODE_STATUS_VALID_CODE_STORED: |
1417 | // FIXME: if ! satisfied don't do this... | 1419 | if (satisfied) |
1418 | return return_key_share (&gc->truth_uuid, | 1420 | { |
1419 | connection); | 1421 | GNUNET_free (decrypted_truth); |
1420 | } | 1422 | return return_key_share (&gc->truth_uuid, |
1421 | GNUNET_break (0); | 1423 | connection); |
1422 | return MHD_NO; | 1424 | } |
1423 | } | 1425 | /* continue with authorization plugin below */ |
1424 | |||
1425 | /* Not security question and no answer: use plugin to check if | ||
1426 | decrypted truth is a valid challenge! */ | ||
1427 | { | ||
1428 | enum GNUNET_GenericReturnValue ret; | ||
1429 | |||
1430 | ret = gc->authorization->validate (gc->authorization->cls, | ||
1431 | connection, | ||
1432 | truth_mime, | ||
1433 | decrypted_truth, | ||
1434 | decrypted_truth_size); | ||
1435 | GNUNET_free (truth_mime); | ||
1436 | switch (ret) | ||
1437 | { | ||
1438 | case GNUNET_OK: | ||
1439 | /* data valid, continued below */ | ||
1440 | break; | 1426 | break; |
1441 | case GNUNET_NO: | 1427 | default: |
1442 | /* data invalid, reply was queued */ | 1428 | GNUNET_break (0); |
1443 | GNUNET_free (decrypted_truth); | ||
1444 | return MHD_YES; | ||
1445 | case GNUNET_SYSERR: | ||
1446 | /* data invalid, reply was NOT queued */ | ||
1447 | GNUNET_free (decrypted_truth); | ||
1448 | return MHD_NO; | 1429 | return MHD_NO; |
1449 | } | 1430 | } |
1450 | } | 1431 | } |
1451 | 1432 | else | |
1452 | /* Setup challenge and begin authorization process */ | ||
1453 | { | 1433 | { |
1454 | struct GNUNET_TIME_Absolute transmission_date; | 1434 | /* Not security question and no answer: use plugin to check if |
1455 | enum GNUNET_DB_QueryStatus qs; | 1435 | decrypted truth is a valid challenge! */ |
1456 | |||
1457 | qs = db->create_challenge_code (db->cls, | ||
1458 | &gc->truth_uuid, | ||
1459 | gc->authorization->code_rotation_period, | ||
1460 | gc->authorization->code_validity_period, | ||
1461 | INITIAL_RETRY_COUNTER, | ||
1462 | &transmission_date, | ||
1463 | &gc->code); | ||
1464 | switch (qs) | ||
1465 | { | 1436 | { |
1466 | case GNUNET_DB_STATUS_HARD_ERROR: | 1437 | enum GNUNET_GenericReturnValue ret; |
1467 | case GNUNET_DB_STATUS_SOFT_ERROR: | 1438 | |
1468 | GNUNET_break (0); | 1439 | ret = gc->authorization->validate (gc->authorization->cls, |
1469 | GNUNET_free (decrypted_truth); | 1440 | connection, |
1470 | return TALER_MHD_reply_with_error (gc->connection, | 1441 | truth_mime, |
1471 | MHD_HTTP_INTERNAL_SERVER_ERROR, | 1442 | decrypted_truth, |
1472 | TALER_EC_GENERIC_DB_FETCH_FAILED, | 1443 | decrypted_truth_size); |
1473 | "store_challenge_code"); | 1444 | GNUNET_free (truth_mime); |
1474 | case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: | 1445 | switch (ret) |
1475 | /* 0 == retry_counter of existing challenge => rate limit exceeded */ | 1446 | { |
1476 | GNUNET_free (decrypted_truth); | 1447 | case GNUNET_OK: |
1477 | return TALER_MHD_reply_with_error (connection, | 1448 | /* data valid, continued below */ |
1478 | MHD_HTTP_TOO_MANY_REQUESTS, | 1449 | break; |
1479 | TALER_EC_ANASTASIS_TRUTH_RATE_LIMITED, | 1450 | case GNUNET_NO: |
1480 | NULL); | 1451 | /* data invalid, reply was queued */ |
1481 | case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: | 1452 | GNUNET_free (decrypted_truth); |
1482 | /* challenge code was stored successfully*/ | 1453 | return MHD_YES; |
1483 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1454 | case GNUNET_SYSERR: |
1484 | "Created fresh challenge\n"); | 1455 | /* data invalid, reply was NOT queued */ |
1485 | break; | 1456 | GNUNET_free (decrypted_truth); |
1457 | return MHD_NO; | ||
1458 | } | ||
1486 | } | 1459 | } |
1487 | 1460 | ||
1488 | if (GNUNET_TIME_absolute_get_duration (transmission_date).rel_value_us < | 1461 | /* Setup challenge and begin authorization process */ |
1489 | gc->authorization->code_retransmission_frequency.rel_value_us) | ||
1490 | { | 1462 | { |
1491 | /* Too early for a retransmission! */ | 1463 | struct GNUNET_TIME_Absolute transmission_date; |
1492 | GNUNET_free (decrypted_truth); | 1464 | enum GNUNET_DB_QueryStatus qs; |
1493 | return TALER_MHD_reply_with_error (gc->connection, | 1465 | |
1494 | MHD_HTTP_ALREADY_REPORTED, | 1466 | qs = db->create_challenge_code (db->cls, |
1495 | TALER_EC_ANASTASIS_TRUTH_CHALLENGE_ACTIVE, | 1467 | &gc->truth_uuid, |
1496 | NULL); | 1468 | gc->authorization->code_rotation_period, |
1469 | gc->authorization->code_validity_period, | ||
1470 | INITIAL_RETRY_COUNTER, | ||
1471 | &transmission_date, | ||
1472 | &gc->code); | ||
1473 | switch (qs) | ||
1474 | { | ||
1475 | case GNUNET_DB_STATUS_HARD_ERROR: | ||
1476 | case GNUNET_DB_STATUS_SOFT_ERROR: | ||
1477 | GNUNET_break (0); | ||
1478 | GNUNET_free (decrypted_truth); | ||
1479 | return TALER_MHD_reply_with_error (gc->connection, | ||
1480 | MHD_HTTP_INTERNAL_SERVER_ERROR, | ||
1481 | TALER_EC_GENERIC_DB_FETCH_FAILED, | ||
1482 | "store_challenge_code"); | ||
1483 | case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: | ||
1484 | /* 0 == retry_counter of existing challenge => rate limit exceeded */ | ||
1485 | GNUNET_free (decrypted_truth); | ||
1486 | return TALER_MHD_reply_with_error (connection, | ||
1487 | MHD_HTTP_TOO_MANY_REQUESTS, | ||
1488 | TALER_EC_ANASTASIS_TRUTH_RATE_LIMITED, | ||
1489 | NULL); | ||
1490 | case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: | ||
1491 | /* challenge code was stored successfully*/ | ||
1492 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1493 | "Created fresh challenge\n"); | ||
1494 | break; | ||
1495 | } | ||
1496 | |||
1497 | if (GNUNET_TIME_absolute_get_duration (transmission_date).rel_value_us < | ||
1498 | gc->authorization->code_retransmission_frequency.rel_value_us) | ||
1499 | { | ||
1500 | /* Too early for a retransmission! */ | ||
1501 | GNUNET_free (decrypted_truth); | ||
1502 | return TALER_MHD_reply_with_error (gc->connection, | ||
1503 | MHD_HTTP_ALREADY_REPORTED, | ||
1504 | TALER_EC_ANASTASIS_TRUTH_CHALLENGE_ACTIVE, | ||
1505 | NULL); | ||
1506 | } | ||
1497 | } | 1507 | } |
1498 | } | 1508 | } |
1499 | 1509 | ||