aboutsummaryrefslogtreecommitdiff
path: root/src/backend/anastasis-httpd_truth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/anastasis-httpd_truth.c')
-rw-r--r--src/backend/anastasis-httpd_truth.c154
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