From e7fae5d4b0905eb77d40b32f653a994ba96fb12f Mon Sep 17 00:00:00 2001 From: Seb Aebischer Date: Mon, 29 Jan 2018 16:45:58 +0000 Subject: [PATCH 01/15] Read timeouts in fsmpico This commit is a transfer of GitLab branch 88-read-timeouts-in-fsm. --- src/fsmpico.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/fsmpico.c b/src/fsmpico.c index 667170c..a9bea76 100644 --- a/src/fsmpico.c +++ b/src/fsmpico.c @@ -69,6 +69,8 @@ // Defines +#define READ_TIMEOUT (5000) +#define CONTINUOUS_TIMEOUT_LEEWAY (1000) #define RECONNECT_DELAY (10000) // Structure definitions @@ -111,6 +113,8 @@ struct _FsmPico { FSMPICOSTATE state; AuthFsmComms * comms; void * user_data; + + int reauthDelay; }; // Function prototypes @@ -165,6 +169,8 @@ FsmPico * fsmpico_new() { fsmpico->comms->sessionEnded = FsmSessionEndedNull; fsmpico->comms->statusUpdate = FsmStatusUpdateNull; + fsmpico->reauthDelay = 0; + return fsmpico; } @@ -364,6 +370,8 @@ void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length) { createMessagePicoAuth(fsmpico, message, fsmpico->extraData); fsmpico->comms->write(buffer_get_buffer(message), buffer_get_pos(message), fsmpico->user_data); stateTransition(fsmpico, FSMPICOSTATE_STATUS); + // set a timeout for waiting for the status message + fsmpico->comms->setTimeout(READ_TIMEOUT, fsmpico->user_data); } break; case FSMPICOSTATE_STATUS: @@ -390,6 +398,7 @@ void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length) { result = readMessageServiceReauth(fsmpico, dataread, &timeout); if (result) { stateTransition(fsmpico, FSMPICOSTATE_PICOREAUTH); + fsmpico->reauthDelay = timeout; LOG(LOG_DEBUG, "Timeout set to: %d", timeout); // Wait for timeout fsmpico->comms->setTimeout(timeout, fsmpico->user_data); @@ -425,6 +434,8 @@ void fsmpico_connected(FsmPico * fsmpico) { createMessageStart(fsmpico, message); fsmpico->comms->write(buffer_get_buffer(message), buffer_get_pos(message), fsmpico->user_data); stateTransition(fsmpico, FSMPICOSTATE_SERVICEAUTH); + // set a timeout for waiting for the service auth message + fsmpico->comms->setTimeout(READ_TIMEOUT, fsmpico->user_data); break; case FSMPICOSTATE_CONTSTARTPICO: fsmpico->currentState = REAUTHSTATE_CONTINUE; @@ -489,7 +500,7 @@ void fsmpico_timeout(FsmPico * fsmpico) { message = buffer_new(0); switch (fsmpico->state) { - case FSMPICOSTATE_CONTSTARTPICO: + case FSMPICOSTATE_CONTSTARTPICO: LOG(LOG_DEBUG, "Reconnecting for continuous authentication"); fsmpico->comms->reconnect(fsmpico->user_data); break; @@ -497,10 +508,26 @@ void fsmpico_timeout(FsmPico * fsmpico) { createMessagePicoReauth(fsmpico, message, extraData); fsmpico->comms->write(buffer_get_buffer(message), buffer_get_pos(message), fsmpico->user_data); stateTransition(fsmpico, FSMPICOSTATE_SERVICEREAUTH); + // set a timeout for awaiting a response + fsmpico->comms->setTimeout(fsmpico->reauthDelay + CONTINUOUS_TIMEOUT_LEEWAY, fsmpico->user_data); break; - default: + case FSMPICOSTATE_SERVICEAUTH: + case FSMPICOSTATE_STATUS: + case FSMPICOSTATE_SERVICEREAUTH: + // gave up waiting for a reply to a sent message, enter error state + stateTransition(fsmpico, FSMPICOSTATE_ERROR); + fsmpico->comms->error(fsmpico->user_data); + break; + case FSMPICOSTATE_INVALID: + case FSMPICOSTATE_ERROR: + // in these states, the state machine is stopped, so ignore it (but log) LOG(LOG_DEBUG, "Timer fired during an invalid state"); break; + default: + // in any other state, we're not expecting a timeout and this is an error + stateTransition(fsmpico, FSMPICOSTATE_ERROR); + fsmpico->comms->error(fsmpico->user_data); + break; } buffer_delete(extraData); From bbe200a4808ed76a8d53659f8783a655abe55488 Mon Sep 17 00:00:00 2001 From: Claudio Dettoni Date: Wed, 31 Jan 2018 13:53:20 +0000 Subject: [PATCH 02/15] Fix test according to new timeouts --- tests/test_fsm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_fsm.c b/tests/test_fsm.c index a0cabfe..a7207bf 100644 --- a/tests/test_fsm.c +++ b/tests/test_fsm.c @@ -461,10 +461,15 @@ START_TEST (fsm_pico_test) { } int expectedTimeouts[] = { + 5000, // Read timeout for ServiceAuthMessage + 5000, // Read timeout for StatusMessage 10000, //Reconnect delay 9000, // Continuous timeout + 11000, // Read timeout for ServiceReauthMessage 9000, // Continuous timeout + 11000, // Read timeout for ServiceReauthMessage 9000, // Continuous timeout + 11000, // Read timeout for ServiceReauthMessage 9000 // Continuous timeout }; From 6ed4f4ce69eda9092342e76fb4f061ab57db5e6b Mon Sep 17 00:00:00 2001 From: Claudio Dettoni Date: Thu, 1 Feb 2018 16:00:16 +0000 Subject: [PATCH 03/15] Adding extra data to service reauth message I added the functionality of having an extra data to the service reauth message in a similar fashion as the pico reauth message It was implemented in a way that previous messages still work, so it is not breaking compatibility --- include/pico/messageservicereauth.h | 2 + src/messageservicereauth.c | 29 ++++ tests/Makefile.am | 2 +- tests/Makefile.in | 24 +++- tests/test_messages.c | 199 ++++++++++++++++++++++++++++ 5 files changed, 251 insertions(+), 5 deletions(-) create mode 100644 tests/test_messages.c diff --git a/include/pico/messageservicereauth.h b/include/pico/messageservicereauth.h index 698140f..56b0dc2 100644 --- a/include/pico/messageservicereauth.h +++ b/include/pico/messageservicereauth.h @@ -68,6 +68,8 @@ typedef struct _MessageServiceReAuth MessageServiceReAuth; MessageServiceReAuth * messageservicereauth_new(); void messageservicereauth_delete(MessageServiceReAuth * messageservicereauth); void messageservicereauth_set(MessageServiceReAuth * messageservicereauth, Buffer * sharedKey, long int timeout, REAUTHSTATE reauthState, SequenceNumber const * sequenceNum); +void messageservicereauth_set_extra_data(MessageServiceReAuth * messageservicereauth, Buffer * extraData); +const Buffer * messageservicereauth_get_extra_data(MessageServiceReAuth * messageservicereauth); void messageservicereauth_serialize(MessageServiceReAuth * messageservicereauth, Buffer * buffer); bool messageservicereauth_deserialize(MessageServiceReAuth * messageservicereauth, Buffer const * buffer); int messageservicereauth_get_timeout(MessageServiceReAuth * messageservicereauth); diff --git a/src/messageservicereauth.c b/src/messageservicereauth.c index b12acb1..e51a4b3 100644 --- a/src/messageservicereauth.c +++ b/src/messageservicereauth.c @@ -83,6 +83,7 @@ struct _MessageServiceReAuth { Buffer * iv; Buffer * encryptedData; + Buffer * extraData; }; // Function prototypes @@ -108,6 +109,7 @@ MessageServiceReAuth * messageservicereauth_new() { messageservicereauth->iv = buffer_new(0); messageservicereauth->encryptedData = buffer_new(0); + messageservicereauth->extraData = buffer_new(0); return messageservicereauth; } @@ -134,6 +136,8 @@ void messageservicereauth_delete(MessageServiceReAuth * messageservicereauth) { buffer_delete(messageservicereauth->encryptedData); } + buffer_delete(messageservicereauth->extraData); + FREE(messageservicereauth); } } @@ -163,6 +167,15 @@ void messageservicereauth_set(MessageServiceReAuth * messageservicereauth, Buffe } } +void messageservicereauth_set_extra_data(MessageServiceReAuth * messageservicereauth, Buffer * extraData) { + buffer_clear(messageservicereauth->extraData); + buffer_append_buffer(messageservicereauth->extraData, extraData); +} + +const Buffer * messageservicereauth_get_extra_data(MessageServiceReAuth * messageservicereauth) { + return messageservicereauth->extraData; +} + /** * Serialize the Status data in JSON format. * @@ -196,6 +209,9 @@ void messageservicereauth_serialize(MessageServiceReAuth * messageservicereauth, // Sequence number buffer_append_lengthprepend(toEncrypt, sequencenumber_get_raw_bytes(messageservicereauth->sequenceNum), SEQUENCE_NUMBER_LENGTH); + + // Extra data + buffer_append_buffer_lengthprepend(toEncrypt, messageservicereauth->extraData); iv = buffer_new(CRYPTOSUPPORT_IV_SIZE); cryptosupport_generate_iv(iv); @@ -349,6 +365,19 @@ bool messageservicereauth_deserialize(MessageServiceReAuth * messageservicereaut LOG(LOG_ERR, "Error deserializing decrypted length-prepended challenge sequence number data\n"); result = false; } + + // length | char extraData[length] (optional) + buffer_clear(bytes); + next = buffer_copy_lengthprepend(cleartext, start, bytes); + length = buffer_get_pos(bytes); + if (next > start) { + buffer_clear(messageservicereauth->extraData); + buffer_append_buffer(messageservicereauth->extraData, bytes); + start = next; + } + else { + LOG(LOG_DEBUG, "Service reauth message without extra data\n"); + } } if (result) { diff --git a/tests/Makefile.am b/tests/Makefile.am index a50c036..810e3a6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = subdir-objects -TESTS = test_base64 test_buffer test_cryptosupport test_sigmaverifier test_channel test_json test_users test_auth test_displayqr test_continuous test_beacons test_fsm +TESTS = test_base64 test_buffer test_cryptosupport test_sigmaverifier test_channel test_json test_users test_auth test_displayqr test_continuous test_beacons test_fsm test_messages noinst_LTLIBRARIES = lib_mockbt.la lib_mockbt_la_SOURCES = \ diff --git a/tests/Makefile.in b/tests/Makefile.in index be791c9..8a084ca 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -93,7 +93,7 @@ TESTS = test_base64$(EXEEXT) test_buffer$(EXEEXT) \ test_channel$(EXEEXT) test_json$(EXEEXT) test_users$(EXEEXT) \ test_auth$(EXEEXT) test_displayqr$(EXEEXT) \ test_continuous$(EXEEXT) test_beacons$(EXEEXT) \ - test_fsm$(EXEEXT) + test_fsm$(EXEEXT) test_messages$(EXEEXT) check_PROGRAMS = $(am__EXEEXT_1) subdir = tests ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -125,7 +125,7 @@ am__EXEEXT_1 = test_base64$(EXEEXT) test_buffer$(EXEEXT) \ test_channel$(EXEEXT) test_json$(EXEEXT) test_users$(EXEEXT) \ test_auth$(EXEEXT) test_displayqr$(EXEEXT) \ test_continuous$(EXEEXT) test_beacons$(EXEEXT) \ - test_fsm$(EXEEXT) + test_fsm$(EXEEXT) test_messages$(EXEEXT) test_auth_SOURCES = test_auth.c test_auth_OBJECTS = test_auth.$(OBJEXT) test_auth_LDADD = $(LDADD) @@ -166,6 +166,10 @@ test_json_SOURCES = test_json.c test_json_OBJECTS = test_json.$(OBJEXT) test_json_LDADD = $(LDADD) test_json_DEPENDENCIES = ../libpico.la .libs/lib_mockbt.la +test_messages_SOURCES = test_messages.c +test_messages_OBJECTS = test_messages.$(OBJEXT) +test_messages_LDADD = $(LDADD) +test_messages_DEPENDENCIES = ../libpico.la .libs/lib_mockbt.la test_sigmaverifier_SOURCES = test_sigmaverifier.c test_sigmaverifier_OBJECTS = test_sigmaverifier.$(OBJEXT) test_sigmaverifier_LDADD = $(LDADD) @@ -211,11 +215,11 @@ am__v_CCLD_1 = SOURCES = $(lib_mockbt_la_SOURCES) test_auth.c test_base64.c \ test_beacons.c test_buffer.c test_channel.c test_continuous.c \ test_cryptosupport.c test_displayqr.c test_fsm.c test_json.c \ - test_sigmaverifier.c test_users.c + test_messages.c test_sigmaverifier.c test_users.c DIST_SOURCES = $(lib_mockbt_la_SOURCES) test_auth.c test_base64.c \ test_beacons.c test_buffer.c test_channel.c test_continuous.c \ test_cryptosupport.c test_displayqr.c test_fsm.c test_json.c \ - test_sigmaverifier.c test_users.c + test_messages.c test_sigmaverifier.c test_users.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -686,6 +690,10 @@ test_json$(EXEEXT): $(test_json_OBJECTS) $(test_json_DEPENDENCIES) $(EXTRA_test_ @rm -f test_json$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_json_OBJECTS) $(test_json_LDADD) $(LIBS) +test_messages$(EXEEXT): $(test_messages_OBJECTS) $(test_messages_DEPENDENCIES) $(EXTRA_test_messages_DEPENDENCIES) + @rm -f test_messages$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_messages_OBJECTS) $(test_messages_LDADD) $(LIBS) + test_sigmaverifier$(EXEEXT): $(test_sigmaverifier_OBJECTS) $(test_sigmaverifier_DEPENDENCIES) $(EXTRA_test_sigmaverifier_DEPENDENCIES) @rm -f test_sigmaverifier$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_sigmaverifier_OBJECTS) $(test_sigmaverifier_LDADD) $(LIBS) @@ -712,6 +720,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_displayqr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fsm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_json.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_messages.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_sigmaverifier.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_users.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@mockbt/$(DEPDIR)/lib_mockbt_la-mockbt.Plo@am__quote@ @@ -1031,6 +1040,13 @@ test_fsm.log: test_fsm$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +test_messages.log: test_messages$(EXEEXT) + @p='test_messages$(EXEEXT)'; \ + b='test_messages'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ diff --git a/tests/test_messages.c b/tests/test_messages.c new file mode 100644 index 0000000..f6ee917 --- /dev/null +++ b/tests/test_messages.c @@ -0,0 +1,199 @@ +/** + * @file + * @author Claudio Dettoni + * @version $(VERSION) + * + * @section LICENSE + * + * (C) Copyright Cambridge Authentication Ltd, 2018 + * + * This file is part of libpico. + * + * Libpico is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * Libpico is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with libpico. If not, see + * . + * + * + * @brief Unit tests for the message + */ + +#include +#include "pico/messagepicoreauth.h" +#include "pico/messageservicereauth.h" + +// Defines + +// Structure definitions + +// Function prototypes + +// Function definitions + +START_TEST (test_messagepicoreauth) { + MessagePicoReAuth * msg; + Buffer * sharedKey; + SequenceNumber* sequenceNumber; + SequenceNumber* sequenceNumberCopy; + SequenceNumber* sequenceNumberRecovered; + Buffer * extraData; + Buffer * json; + + sharedKey = buffer_new(0); + buffer_append(sharedKey, "\x00\x01\x02\x03\x04\x05", 6); + sequenceNumber = sequencenumber_new(); + sequenceNumberCopy = sequencenumber_new(); + sequenceNumberRecovered = sequencenumber_new(); + sequencenumber_random(sequenceNumber); + sequencenumber_copy(sequenceNumberCopy, sequenceNumber); + extraData = buffer_new(0); + buffer_append(extraData, "Extra", 5); + json = buffer_new(0); + + msg = messagepicoreauth_new(); + messagepicoreauth_set(msg, sharedKey, sequenceNumber); + messagepicoreauth_set_reauthstate(msg, REAUTHSTATE_PAUSE); + messagepicoreauth_serialize(msg, extraData, json); + + ck_assert(buffer_get_pos(json) > 0); + messagepicoreauth_delete(msg); + + msg = messagepicoreauth_new(); + messagepicoreauth_set(msg, sharedKey, NULL); + messagepicoreauth_deserialize(msg, json); + + ck_assert_str_eq(buffer_get_buffer(messagepicoreauth_get_extra_data(msg)), "Extra"); + ck_assert(messagepicoreauth_get_reauthstate(msg) == REAUTHSTATE_PAUSE); + messagepicoreauth_get_sequencenum(msg, sequenceNumberRecovered); + ck_assert(sequencenumber_equals(sequenceNumberRecovered, sequenceNumberCopy)); + + buffer_delete(sharedKey); + sequencenumber_delete(sequenceNumber); + sequencenumber_delete(sequenceNumberCopy); + sequencenumber_delete(sequenceNumberRecovered); + messagepicoreauth_delete(msg); + buffer_delete(json); + buffer_delete(extraData); +} +END_TEST + +START_TEST (test_messageservicereauth) { + MessageServiceReAuth * msg; + Buffer * sharedKey; + SequenceNumber* sequenceNumber; + SequenceNumber* sequenceNumberCopy; + SequenceNumber* sequenceNumberRecovered; + Buffer * extraData; + Buffer * json; + + sharedKey = buffer_new(0); + buffer_append(sharedKey, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16); + sequenceNumber = sequencenumber_new(); + sequenceNumberCopy = sequencenumber_new(); + sequenceNumberRecovered = sequencenumber_new(); + sequencenumber_random(sequenceNumber); + sequencenumber_copy(sequenceNumberCopy, sequenceNumber); + extraData = buffer_new(0); + buffer_append(extraData, "Extra", 5); + json = buffer_new(0); + + msg = messageservicereauth_new(); + messageservicereauth_set(msg, sharedKey, 123, REAUTHSTATE_STOP, sequenceNumber); + messageservicereauth_set_extra_data(msg, extraData); + messageservicereauth_serialize(msg, json); + + buffer_print(json); + + ck_assert(buffer_get_pos(json) > 0); + messageservicereauth_delete(msg); + + msg = messageservicereauth_new(); + messageservicereauth_set(msg, sharedKey, 0, REAUTHSTATE_INVALID, NULL); + messageservicereauth_deserialize(msg, json); + + ck_assert(messageservicereauth_get_reauthstate(msg) == REAUTHSTATE_STOP); + ck_assert(messageservicereauth_get_timeout(msg) == 123); + messageservicereauth_get_sequencenum(msg, sequenceNumberRecovered); + ck_assert(sequencenumber_equals(sequenceNumberRecovered, sequenceNumberCopy)); + ck_assert_str_eq(buffer_get_buffer(messageservicereauth_get_extra_data(msg)), "Extra"); + + buffer_delete(sharedKey); + sequencenumber_delete(sequenceNumber); + sequencenumber_delete(sequenceNumberRecovered); + sequencenumber_delete(sequenceNumberCopy); + messageservicereauth_delete(msg); + buffer_delete(json); + buffer_delete(extraData); +} +END_TEST + +START_TEST (test_deserialize_messageservicereauth_without_extra_data) { + MessageServiceReAuth * msg; + Buffer * sharedKey; + SequenceNumber* sequenceNumberExpected; + SequenceNumber* sequenceNumberRecovered; + Buffer * expectedNumberBuf; + Buffer * json; + + sequenceNumberRecovered = sequencenumber_new(); + sequenceNumberExpected = sequencenumber_new(); + sharedKey = buffer_new(0); + buffer_append(sharedKey, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16); + json = buffer_new(0); + buffer_append_string(json, "{\"iv\":\"YlGac7bdxNNWcToeNw3Xsg==\",\"encryptedData\":\"uFmElztl5yBtd79Cp651v5OX9YmIQ3BQ7N8tjhf/ShYNCu0fuLolmdqhog+pH2swMTh/jxXaajV0\",\"sessionId\":0}"); + expectedNumberBuf = buffer_new(0); + buffer_append(expectedNumberBuf, "\x3c\x3e\xbe\x5b\xf7\xd9\x08\xa1\xde\x02\x77\x51\xf4\xdf\x86\x46\x6c\x4a\xde\x6e\x48\x67\x83\xa6\x64\xaf\xda\x56\x0d\x9e\x69\xde", 32); + sequencenumber_transfer_from_buffer(sequenceNumberExpected, expectedNumberBuf); + + msg = messageservicereauth_new(); + messageservicereauth_set(msg, sharedKey, 0, REAUTHSTATE_INVALID, NULL); + ck_assert(messageservicereauth_deserialize(msg, json)); + + ck_assert(messageservicereauth_get_reauthstate(msg) == REAUTHSTATE_STOP); + ck_assert(messageservicereauth_get_timeout(msg) == 123); + messageservicereauth_get_sequencenum(msg, sequenceNumberRecovered); + sequencenumber_print(sequenceNumberRecovered); + sequencenumber_print(sequenceNumberExpected); + ck_assert(sequencenumber_equals(sequenceNumberRecovered, sequenceNumberExpected)); + + buffer_delete(sharedKey); + buffer_delete(expectedNumberBuf); + sequencenumber_delete(sequenceNumberRecovered); + sequencenumber_delete(sequenceNumberExpected); + messageservicereauth_delete(msg); + buffer_delete(json); +} +END_TEST + +int main (void) { + int number_failed; + Suite * s; + SRunner *sr; + TCase * tc; + + s = suite_create("Libpico"); + + // Base64 test case + tc = tcase_create("Messages"); + tcase_add_test(tc, test_messagepicoreauth); + tcase_add_test(tc, test_messageservicereauth); + tcase_add_test(tc, test_deserialize_messageservicereauth_without_extra_data); + suite_add_tcase(s, tc); + sr = srunner_create(s); + + srunner_run_all(sr, CK_NORMAL); + number_failed = srunner_ntests_failed(sr); + srunner_free(sr); + + return (number_failed == 0) ? 0 : -1; +} + From a5c4a3c770aa19b837db576487eff8f31d62edb0 Mon Sep 17 00:00:00 2001 From: Claudio Dettoni Date: Thu, 1 Feb 2018 17:43:46 +0000 Subject: [PATCH 04/15] Adding extraData to fsmpico This was in a similar way to what already existed on fsmservice --- include/pico/fsmpico.h | 2 + include/pico/messageservicereauth.h | 2 +- src/fsmpico.c | 81 +++++++++++++++++++++++------ src/fsmservice.c | 14 +++-- src/messageservicereauth.c | 2 +- 5 files changed, 80 insertions(+), 21 deletions(-) diff --git a/include/pico/fsmpico.h b/include/pico/fsmpico.h index 96d7f0e..f8d7026 100644 --- a/include/pico/fsmpico.h +++ b/include/pico/fsmpico.h @@ -103,6 +103,8 @@ FsmPico * fsmpico_new(); void fsmpico_delete(FsmPico * fsmpico); void fsmpico_set_functions(FsmPico * fsmpico, FsmWrite write, FsmSetTimeout setTimeout, FsmError error, FsmReconnect reconnect, FsmDisconnect disconnect, FsmAuthenticated authenticated, FsmSessionEnded sessionEnded, FsmStatusUpdate statusUpdate); void fsmpico_set_userdata(FsmPico * fsmpico, void * user_data); +Buffer const * fsmpico_get_received_extra_data(FsmPico * fsmpico); +void fsmpico_set_outbound_extra_data(FsmPico * fsmpico, Buffer const * extraData); // Use these functions to control the authentication process void fsmpico_start(FsmPico * fsmpico, Buffer const * extraData, EC_KEY * serviceIdPubKey, EC_KEY * clientIdPubKey, EVP_PKEY * clientIdPrivKey); diff --git a/include/pico/messageservicereauth.h b/include/pico/messageservicereauth.h index 56b0dc2..bb32131 100644 --- a/include/pico/messageservicereauth.h +++ b/include/pico/messageservicereauth.h @@ -68,7 +68,7 @@ typedef struct _MessageServiceReAuth MessageServiceReAuth; MessageServiceReAuth * messageservicereauth_new(); void messageservicereauth_delete(MessageServiceReAuth * messageservicereauth); void messageservicereauth_set(MessageServiceReAuth * messageservicereauth, Buffer * sharedKey, long int timeout, REAUTHSTATE reauthState, SequenceNumber const * sequenceNum); -void messageservicereauth_set_extra_data(MessageServiceReAuth * messageservicereauth, Buffer * extraData); +void messageservicereauth_set_extra_data(MessageServiceReAuth * messageservicereauth, const Buffer * extraData); const Buffer * messageservicereauth_get_extra_data(MessageServiceReAuth * messageservicereauth); void messageservicereauth_serialize(MessageServiceReAuth * messageservicereauth, Buffer * buffer); bool messageservicereauth_deserialize(MessageServiceReAuth * messageservicereauth, Buffer const * buffer); diff --git a/src/fsmpico.c b/src/fsmpico.c index fac4ae7..1ae071c 100644 --- a/src/fsmpico.c +++ b/src/fsmpico.c @@ -111,6 +111,7 @@ struct _FsmPico { Buffer * sharedKey; Shared * shared; Buffer * extraData; + Buffer * returnedExtraData; FSMPICOSTATE state; AuthFsmComms * comms; @@ -126,7 +127,7 @@ static bool readMessageServiceAuth(FsmPico * fsmpico, Buffer const * message); static void createMessagePicoAuth(FsmPico * fsmpico, Buffer * message, Buffer const * sendExtraData); static bool readMessageStatus(FsmPico * fsmpico, Buffer const * message, Buffer * returnedExtraData, char *status); static void createMessagePicoReauth(FsmPico * fsmpico, Buffer * message, Buffer const * sendExtraData); -static bool readMessageServiceReauth(FsmPico * fsmpico, Buffer const * message, int * timeout); +static bool readMessageServiceReauth(FsmPico * fsmpico, Buffer const * message, int * timeout, Buffer * returnedExtraData); static void stateTransition(FsmPico* fsmpico, FSMPICOSTATE newState); static void FsmWriteNull(char const * data, size_t length, void * user_data); @@ -152,6 +153,7 @@ FsmPico * fsmpico_new() { fsmpico->shared = shared_new(); fsmpico->extraData = buffer_new(0); + fsmpico->returnedExtraData = buffer_new(0); fsmpico->currentState = REAUTHSTATE_INVALID; fsmpico->picoSeqNumber = sequencenumber_new(); @@ -202,6 +204,9 @@ void fsmpico_delete(FsmPico * fsmpico) { buffer_delete(fsmpico->sharedKey); fsmpico->sharedKey = NULL; } + + buffer_delete(fsmpico->extraData); + buffer_delete(fsmpico->returnedExtraData); FREE(fsmpico->comms); @@ -352,13 +357,11 @@ void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length) { LOG(LOG_DEBUG, "Read"); bool result; - Buffer * receivedExtraData; int timeout; Buffer * message; Buffer * dataread; char status; - receivedExtraData = buffer_new(0); message = buffer_new(0); dataread = buffer_new(length); buffer_append(dataread, data, length); @@ -377,7 +380,7 @@ void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length) { } break; case FSMPICOSTATE_STATUS: - result = readMessageStatus(fsmpico, dataread, receivedExtraData, &status); + result = readMessageStatus(fsmpico, dataread, fsmpico->returnedExtraData, &status); if (result) { fsmpico->comms->authenticated((int) status, fsmpico->user_data); fsmpico->comms->disconnect(fsmpico->user_data); @@ -397,7 +400,7 @@ void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length) { break; case FSMPICOSTATE_CONTSTARTSERVICE: case FSMPICOSTATE_SERVICEREAUTH: - result = readMessageServiceReauth(fsmpico, dataread, &timeout); + result = readMessageServiceReauth(fsmpico, dataread, &timeout, fsmpico->returnedExtraData); if (result) { stateTransition(fsmpico, FSMPICOSTATE_PICOREAUTH); fsmpico->reauthDelay = timeout; @@ -412,7 +415,6 @@ void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length) { break; } - buffer_delete(receivedExtraData); buffer_delete(message); buffer_delete(dataread); } @@ -423,12 +425,10 @@ void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length) { * @param fsmpico The object to apply to. */ void fsmpico_connected(FsmPico * fsmpico) { - Buffer * extraData; Buffer * message; LOG(LOG_DEBUG, "Connected"); - extraData = buffer_new(0); message = buffer_new(0); switch (fsmpico->state) { @@ -444,7 +444,7 @@ void fsmpico_connected(FsmPico * fsmpico) { buffer_clear(fsmpico->sharedKey); buffer_append_buffer(fsmpico->sharedKey, shared_get_shared_key(fsmpico->shared)); sequencenumber_random(fsmpico->picoSeqNumber); - createMessagePicoReauth(fsmpico, message, extraData); + createMessagePicoReauth(fsmpico, message, fsmpico->extraData); fsmpico->comms->write(buffer_get_buffer(message), buffer_get_pos(message), fsmpico->user_data); stateTransition(fsmpico, FSMPICOSTATE_CONTSTARTSERVICE); break; @@ -454,7 +454,6 @@ void fsmpico_connected(FsmPico * fsmpico) { break; } - buffer_delete(extraData); buffer_delete(message); } @@ -493,12 +492,10 @@ void fsmpico_disconnected(FsmPico * fsmpico) { * @param fsmpico The object to apply to. */ void fsmpico_timeout(FsmPico * fsmpico) { - Buffer * extraData; Buffer * message; LOG(LOG_DEBUG, "Timeout"); - extraData = buffer_new(0); message = buffer_new(0); switch (fsmpico->state) { @@ -507,7 +504,7 @@ void fsmpico_timeout(FsmPico * fsmpico) { fsmpico->comms->reconnect(fsmpico->user_data); break; case FSMPICOSTATE_PICOREAUTH: - createMessagePicoReauth(fsmpico, message, extraData); + createMessagePicoReauth(fsmpico, message, fsmpico->extraData); fsmpico->comms->write(buffer_get_buffer(message), buffer_get_pos(message), fsmpico->user_data); stateTransition(fsmpico, FSMPICOSTATE_SERVICEREAUTH); // set a timeout for awaiting a response @@ -532,10 +529,57 @@ void fsmpico_timeout(FsmPico * fsmpico) { break; } - buffer_delete(extraData); buffer_delete(message); } +/** + * Get the latest extra data that was sent by the Service. This is updated when + * the service sends either a ServiceAuth or PicoReauth message. The value is reset + * for each of these messages, and so the previous value will be wiped when + * either of these messages is received (even if the Pico doesn't send any + * extra data). + * + * To be alerted to any fresh data that arrives, the simplest approach is to + * set up an FsmStatusUpdate callback and check for any data recevied on either + * of the following two events: + * + * 1. FSMPICOSTATE_STATUS + * 2. FSMPICOSTATE_SERVICEREAUTH + * + * Then make a call using this function to check whether any new data + * has arrived (in which case, the returned buffer will be non-empty). + * + * @param fsmpico The object to get the extra data from. + * @return The latest extra data received from the Service, or an empty buffer. + */ +Buffer const * fsmpico_get_received_extra_data(FsmPico * fsmpico) { + return fsmpico->returnedExtraData; +} + +/** + * + * Set the extra data that will be sent to the Service. The data is sent in the + * Status and ServiceReauth messages. As such, to ensure it's set prior to each + * of these messages being sent, it's safe to set the new extra data when an + * update notifcation is triggered for either of the following events: + * + * 1. FSMPICOSTATE_STATUS + * 2. FSMPICOSTATE_SERVICEREAUTH + * + * These two events are those that immediately proceed the arrival of a + * Status or ServiceReauth message. + * + * @param fsmpico The object to set the extra data. + * @return The next extra data to be sent to the Service. + */ +void fsmpico_set_outbound_extra_data(FsmPico * fsmpico, Buffer const * extraData) { + // Record the extra data + buffer_clear(fsmpico->extraData); + if (extraData != NULL) { + buffer_append_buffer(fsmpico->extraData, extraData); + } +} + void stateTransition(FsmPico* fsmpico, FSMPICOSTATE newState) { fsmpico->state = newState; @@ -666,8 +710,10 @@ static void createMessagePicoReauth(FsmPico * fsmpico, Buffer * message, Buffer * @param fsmpico The object to apply to. * @param message The message data to interpret. * @param timeout A pointer to an integer to return the timeout value in. + * @param returnedExtraData A buffer to store any extra data that was extracted + * from the message. */ -static bool readMessageServiceReauth(FsmPico * fsmpico, Buffer const * message, int * timeout) { +static bool readMessageServiceReauth(FsmPico * fsmpico, Buffer const * message, int * timeout, Buffer * returnedExtraData) { MessageServiceReAuth * messageservicereauth; bool result; bool sequencenumber_match; @@ -700,6 +746,11 @@ static bool readMessageServiceReauth(FsmPico * fsmpico, Buffer const * message, } } + if (result && returnedExtraData != NULL) { + buffer_clear(returnedExtraData); + buffer_append_buffer(returnedExtraData, messageservicereauth_get_extra_data(messageservicereauth)); + } + if (result && sequencenumber_match) { sequencenumber_increment(fsmpico->serviceSeqNumber); } diff --git a/src/fsmservice.c b/src/fsmservice.c index 757559a..689248f 100644 --- a/src/fsmservice.c +++ b/src/fsmservice.c @@ -131,7 +131,7 @@ static void createMessageServiceAuth(FsmService * fsmservice, Buffer * message); static bool readMessagePicoAuth(FsmService * fsmservice, Buffer /* const */ * message, Buffer * returnedExtraData); static void createMessageStatus(FsmService * fsmservice, Buffer * message, Buffer const * sendExtraData, signed char status); static bool readMessagePicoReauth(FsmService * fsmservice, Buffer /* const */ * message, Buffer * returnedExtraData); -static void createMessageServiceReauth(FsmService * fsmservice, Buffer * message, int timeout); +static void createMessageServiceReauth(FsmService * fsmservice, Buffer * message, int timeout, const Buffer * extraData); static bool fsmservice_check_user(FsmService * fsmservice, Buffer * user, Buffer * symmetrickey); static void FsmWriteNull(char const * data, size_t length, void * user_data); @@ -562,7 +562,7 @@ void fsmservice_timeout(FsmService * fsmservice) { fsmservice->comms->sessionEnded(fsmservice->user_data); break; case FSMSERVICESTATE_SERVICEREAUTH: - createMessageServiceReauth(fsmservice, message, fsmservice->currentTimeout); + createMessageServiceReauth(fsmservice, message, fsmservice->currentTimeout, fsmservice->extraData); fsmservice->comms->write(buffer_get_buffer(message), buffer_get_pos(message), fsmservice->user_data); fsmservice->state = FSMSERVICESTATE_PICOREAUTH; fsmservice->comms->statusUpdate(fsmservice->state, fsmservice->user_data); @@ -746,14 +746,18 @@ static bool readMessagePicoReauth(FsmService * fsmservice, Buffer * message, Buf * @param fsmservice The object to apply to. * @param message A buffer to store the resulting message in. * @param timeout The timeout in milliseconds to send to the Pico. + * @param extraData [optional] application data to be included in the message */ -static void createMessageServiceReauth(FsmService * fsmservice, Buffer * message, int timeout) { +static void createMessageServiceReauth(FsmService * fsmservice, Buffer * message, int timeout, const Buffer * extraData) { MessageServiceReAuth * messageservicereauth; LOG(LOG_DEBUG, "Send MessageServiceReauth"); messageservicereauth = messageservicereauth_new(); messageservicereauth_set(messageservicereauth, fsmservice->sharedKey, timeout, fsmservice->currentState, fsmservice->serviceSeqNumber); + if (extraData != NULL) { + messageservicereauth_set_extra_data(messageservicereauth, extraData); + } messageservicereauth_serialize(messageservicereauth, message); // Increment the sequence number ready for the next message @@ -1004,7 +1008,9 @@ Buffer const * fsmservice_get_received_extra_data(FsmService * fsmservice) { void fsmservice_set_outbound_extra_data(FsmService * fsmservice, Buffer const * extraData) { // Record the extra data buffer_clear(fsmservice->extraData); - buffer_append_buffer(fsmservice->extraData, extraData); + if (extraData != NULL) { + buffer_append_buffer(fsmservice->extraData, extraData); + } } /** @} addtogroup Protocol */ diff --git a/src/messageservicereauth.c b/src/messageservicereauth.c index e51a4b3..c1bfa09 100644 --- a/src/messageservicereauth.c +++ b/src/messageservicereauth.c @@ -167,7 +167,7 @@ void messageservicereauth_set(MessageServiceReAuth * messageservicereauth, Buffe } } -void messageservicereauth_set_extra_data(MessageServiceReAuth * messageservicereauth, Buffer * extraData) { +void messageservicereauth_set_extra_data(MessageServiceReAuth * messageservicereauth, const Buffer * extraData) { buffer_clear(messageservicereauth->extraData); buffer_append_buffer(messageservicereauth->extraData, extraData); } From 11e443b5800ca69302fab2ceb5a3863f739c7970 Mon Sep 17 00:00:00 2001 From: Claudio Dettoni Date: Thu, 1 Feb 2018 17:45:25 +0000 Subject: [PATCH 05/15] Adding ability send send the reauth message at any time --- include/pico/fsmpico.h | 1 + include/pico/fsmservice.h | 1 + src/fsmpico.c | 50 ++++++++++++++++++++++++++++++++++++++ src/fsmservice.c | 51 +++++++++++++++++++++++++++++++++++++++ tests/test_fsm.c | 50 +++++++++++++++++++++++++++++++++++++- 5 files changed, 152 insertions(+), 1 deletion(-) diff --git a/include/pico/fsmpico.h b/include/pico/fsmpico.h index f8d7026..096c058 100644 --- a/include/pico/fsmpico.h +++ b/include/pico/fsmpico.h @@ -110,6 +110,7 @@ void fsmpico_set_outbound_extra_data(FsmPico * fsmpico, Buffer const * extraData void fsmpico_start(FsmPico * fsmpico, Buffer const * extraData, EC_KEY * serviceIdPubKey, EC_KEY * clientIdPubKey, EVP_PKEY * clientIdPrivKey); void fsmpico_stop(FsmPico * fsmpico); FSMPICOSTATE fsmpico_get_state(FsmPico * fsmpico); +void fsmpico_send_extra_data(FsmPico * fsmpico); // Call these functions when an event occurs void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length); diff --git a/include/pico/fsmservice.h b/include/pico/fsmservice.h index 7b3e96f..9369494 100644 --- a/include/pico/fsmservice.h +++ b/include/pico/fsmservice.h @@ -120,6 +120,7 @@ DLL_PUBLIC void fsmservice_set_outbound_extra_data(FsmService * fsmservice, Buff DLL_PUBLIC void fsmservice_start(FsmService * fsmservice, Shared * shared, Users const * users, Buffer const * extraData); DLL_PUBLIC void fsmservice_stop(FsmService * fsmservice); DLL_PUBLIC FSMSERVICESTATE fsmservice_get_state(FsmService * fsmservice); +DLL_PUBLIC void fsmservice_send_extra_data(FsmService * fsmpico); // Call these functions when an event occurs DLL_PUBLIC void fsmservice_read(FsmService * fsmservice, char const * data, size_t length); diff --git a/src/fsmpico.c b/src/fsmpico.c index 1ae071c..bddf67e 100644 --- a/src/fsmpico.c +++ b/src/fsmpico.c @@ -409,6 +409,16 @@ void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length) { fsmpico->comms->setTimeout(MAX((timeout - CONTAUTH_LEEWAY), 0), fsmpico->user_data); } break; + case FSMPICOSTATE_PICOREAUTH: + result = readMessageServiceReauth(fsmpico, dataread, &timeout, fsmpico->returnedExtraData); + if (result) { + stateTransition(fsmpico, FSMPICOSTATE_PICOREAUTH); + fsmpico->reauthDelay = timeout; + LOG(LOG_DEBUG, "Timeout set to: %d", timeout); + // Update reauthDelay but keep the previous timeout + // TODO assert we are waiting for a timeout? + } + break; default: stateTransition(fsmpico, FSMPICOSTATE_ERROR); fsmpico->comms->error(fsmpico->user_data); @@ -580,6 +590,46 @@ void fsmpico_set_outbound_extra_data(FsmPico * fsmpico, Buffer const * extraData } } +/** + * This functions should be called after fsmpico_set_outbound_extra_data + * if the application using FsmPico wants that data to be sent immediately. + * This functions only works after continuous authentication has been + * established. + * + * @param fsmpico The object to containing the state + * @param buffer Data to be sent + * + */ +void fsmpico_send_extra_data(FsmPico* fsmpico) { + Buffer * message; + + LOG(LOG_DEBUG, "fsmpico_send_extra_data"); + + message = buffer_new(0); + + switch (fsmpico->state) { + case FSMPICOSTATE_PICOREAUTH: + createMessagePicoReauth(fsmpico, message, fsmpico->extraData); + fsmpico->comms->write(buffer_get_buffer(message), buffer_get_pos(message), fsmpico->user_data); + stateTransition(fsmpico, FSMPICOSTATE_SERVICEREAUTH); + // set a timeout for awaiting a response + fsmpico->comms->setTimeout(fsmpico->reauthDelay + CONTINUOUS_TIMEOUT_LEEWAY, fsmpico->user_data); + break; + case FSMPICOSTATE_SERVICEREAUTH: + createMessagePicoReauth(fsmpico, message, fsmpico->extraData); + fsmpico->comms->write(buffer_get_buffer(message), buffer_get_pos(message), fsmpico->user_data); + stateTransition(fsmpico, FSMPICOSTATE_SERVICEREAUTH); + // Keep the previous timeout waiting for service + // TODO assert we are waiting for a timeout? + break; + default: + LOG(LOG_DEBUG, "Sending data during an invalid state"); + break; + } + + buffer_delete(message); + +} void stateTransition(FsmPico* fsmpico, FSMPICOSTATE newState) { fsmpico->state = newState; diff --git a/src/fsmservice.c b/src/fsmservice.c index 689248f..e1dd9f3 100644 --- a/src/fsmservice.c +++ b/src/fsmservice.c @@ -453,6 +453,14 @@ void fsmservice_read(FsmService * fsmservice, char const * data, size_t length) fsmservice->comms->error(fsmservice->user_data); } break; + case FSMSERVICESTATE_SERVICEREAUTH: + result = readMessagePicoReauth(fsmservice, dataread, fsmservice->returnedExtraData); + if (result) { + // Keep same state + fsmservice->comms->statusUpdate(fsmservice->state, fsmservice->user_data); + // TODO assert we are waiting for a timeout? + } + break; default: fsmservice->state = FSMSERVICESTATE_ERROR; fsmservice->comms->error(fsmservice->user_data); @@ -1013,5 +1021,48 @@ void fsmservice_set_outbound_extra_data(FsmService * fsmservice, Buffer const * } } +/** + * This functions should be called after fsmservice_set_outbound_extra_data when the application + * want to send the data immediately + * This functions only works after continuous authentication has been + * established. + * + * @param fsmservice The object containing the state + * + */ +void fsmservice_send_extra_data(FsmService* fsmservice) { + Buffer * message; + + LOG(LOG_DEBUG, "fsmservice_send_extra_data"); + + message = buffer_new(0); + + switch (fsmservice->state) { + case FSMSERVICESTATE_PICOREAUTH: + createMessageServiceReauth(fsmservice, message, fsmservice->currentTimeout, fsmservice->extraData); + fsmservice->comms->write(buffer_get_buffer(message), buffer_get_pos(message), fsmservice->user_data); + fsmservice->state = FSMSERVICESTATE_PICOREAUTH; + fsmservice->comms->statusUpdate(fsmservice->state, fsmservice->user_data); + // Keep the previous timeout waiting for service + // TODO assert we are waiting for a timeout? + break; + case FSMSERVICESTATE_SERVICEREAUTH: + createMessageServiceReauth(fsmservice, message, fsmservice->currentTimeout, fsmservice->extraData); + fsmservice->comms->write(buffer_get_buffer(message), buffer_get_pos(message), fsmservice->user_data); + fsmservice->state = FSMSERVICESTATE_PICOREAUTH; + fsmservice->comms->statusUpdate(fsmservice->state, fsmservice->user_data); + // set a timeout for awaiting a response + fsmservice->comms->setTimeout(fsmservice->currentTimeout, fsmservice->user_data); + break; + default: + LOG(LOG_DEBUG, "Sending data during an invalid state"); + break; + } + + buffer_delete(message); + +} + + /** @} addtogroup Protocol */ diff --git a/tests/test_fsm.c b/tests/test_fsm.c index a7207bf..dbe1392 100644 --- a/tests/test_fsm.c +++ b/tests/test_fsm.c @@ -239,6 +239,7 @@ START_TEST (fsm_fsm_test) { Node* queue = NULL; currentTime = 0; int cycles = 0; + int cyclesService = 0; Shared * picoShared = shared_new(); shared_load_or_generate_pico_keys(picoShared, "testpicokey.pub", "testpicokey.priv"); @@ -291,12 +292,57 @@ START_TEST (fsm_fsm_test) { } void picoStatusUpdate(FSMPICOSTATE state, void * user_data) { + Buffer * extraData; + extraData = buffer_new(0); + // Using this variable, otherwise send_extra_data will call status_update + // and we will have a stack overflow + static bool sendingReply = false; + if (state == FSMPICOSTATE_PICOREAUTH) { cycles++; if (cycles > 3) { queue = push_stop(queue, pico, NULL, currentTime); } } + if (state == FSMPICOSTATE_SERVICEREAUTH && !sendingReply) { + if (cycles == 2) { + sendingReply = true; + ck_assert_str_eq(buffer_get_buffer(fsmpico_get_received_extra_data(pico)), "EXTRA!!"); + buffer_append_string(extraData, "Extra reply"); + fsmpico_set_outbound_extra_data(pico, extraData); + fsmpico_send_extra_data(pico); + fsmpico_set_outbound_extra_data(pico, NULL); + } else { + ck_assert_str_eq(buffer_get_buffer(fsmpico_get_received_extra_data(pico)), ""); + } + } + + buffer_delete(extraData); + } + + void serviceStatusUpdate(FSMSERVICESTATE state, void * user_data) { + Buffer * extraData; + extraData = buffer_new(0); + + if (state == FSMSERVICESTATE_SERVICEREAUTH) { + cyclesService++; + if (cyclesService == 2) { + buffer_append_string(extraData, "EXTRA!!"); + fsmservice_set_outbound_extra_data(serv, extraData); + fsmservice_send_extra_data(serv); + fsmservice_set_outbound_extra_data(serv, NULL); + } + } + + if (state == FSMSERVICESTATE_SERVICEREAUTH) { + if (cyclesService == 4) { + ck_assert_str_eq(buffer_get_buffer(fsmservice_get_received_extra_data(serv)), "Extra reply"); + } else { + ck_assert_str_eq(buffer_get_buffer(fsmservice_get_received_extra_data(serv)), ""); + } + } + + buffer_delete(extraData); } void serviceAuthenticated(int status, void * user_data) { @@ -309,9 +355,11 @@ START_TEST (fsm_fsm_test) { ck_assert(buffer_equals(receivedSymKey, symmetricKey)); ck_assert(!strcmp(buffer_get_buffer(user), "Donald")); ck_assert(!strcmp(buffer_get_buffer(extraData), "p@ssword")); + + fsmpico_set_outbound_extra_data(pico, NULL); } - fsmservice_set_functions(serv, serviceWrite, serviceSetTimeout, NULL, NULL, serviceDisconnect, serviceAuthenticated, NULL, NULL); + fsmservice_set_functions(serv, serviceWrite, serviceSetTimeout, NULL, NULL, serviceDisconnect, serviceAuthenticated, NULL, serviceStatusUpdate); fsmservice_set_continuous(serv, true); fsmpico_set_functions(pico, picoWrite, picoSetTimeout, NULL, picoReconnect, picoDisconnect, NULL, NULL, picoStatusUpdate); From 3d290abcabdd715c54aa12bbbdd0601f3988a847 Mon Sep 17 00:00:00 2001 From: Seb Aebischer Date: Fri, 2 Feb 2018 17:35:42 +0000 Subject: [PATCH 06/15] Reply to ServiceReauth immediately Remove the timeout between reading a ServiceReauth message and sending the PicoReauth message. --- src/fsmpico.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/src/fsmpico.c b/src/fsmpico.c index a9bea76..8ebf85e 100644 --- a/src/fsmpico.c +++ b/src/fsmpico.c @@ -354,12 +354,14 @@ void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length) { int timeout; Buffer * message; Buffer * dataread; + Buffer * extraDataToSend; char status; receivedExtraData = buffer_new(0); message = buffer_new(0); dataread = buffer_new(length); buffer_append(dataread, data, length); + extraDataToSend = buffer_new(0); // TODO: If the reads fail, should move to an error state switch (fsmpico->state) { @@ -399,9 +401,12 @@ void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length) { if (result) { stateTransition(fsmpico, FSMPICOSTATE_PICOREAUTH); fsmpico->reauthDelay = timeout; - LOG(LOG_DEBUG, "Timeout set to: %d", timeout); - // Wait for timeout - fsmpico->comms->setTimeout(timeout, fsmpico->user_data); + // reply with the PicoReauth message + createMessagePicoReauth(fsmpico, message, extraDataToSend); + fsmpico->comms->write(buffer_get_buffer(message), buffer_get_pos(message), fsmpico->user_data); + stateTransition(fsmpico, FSMPICOSTATE_SERVICEREAUTH); + // set a timeout for awaiting a response + fsmpico->comms->setTimeout(fsmpico->reauthDelay + CONTINUOUS_TIMEOUT_LEEWAY, fsmpico->user_data); } break; default: @@ -413,6 +418,7 @@ void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length) { buffer_delete(receivedExtraData); buffer_delete(message); buffer_delete(dataread); + buffer_delete(extraDataToSend); } /** @@ -491,26 +497,13 @@ void fsmpico_disconnected(FsmPico * fsmpico) { * @param fsmpico The object to apply to. */ void fsmpico_timeout(FsmPico * fsmpico) { - Buffer * extraData; - Buffer * message; - LOG(LOG_DEBUG, "Timeout"); - extraData = buffer_new(0); - message = buffer_new(0); - switch (fsmpico->state) { case FSMPICOSTATE_CONTSTARTPICO: LOG(LOG_DEBUG, "Reconnecting for continuous authentication"); fsmpico->comms->reconnect(fsmpico->user_data); break; - case FSMPICOSTATE_PICOREAUTH: - createMessagePicoReauth(fsmpico, message, extraData); - fsmpico->comms->write(buffer_get_buffer(message), buffer_get_pos(message), fsmpico->user_data); - stateTransition(fsmpico, FSMPICOSTATE_SERVICEREAUTH); - // set a timeout for awaiting a response - fsmpico->comms->setTimeout(fsmpico->reauthDelay + CONTINUOUS_TIMEOUT_LEEWAY, fsmpico->user_data); - break; case FSMPICOSTATE_SERVICEAUTH: case FSMPICOSTATE_STATUS: case FSMPICOSTATE_SERVICEREAUTH: @@ -529,9 +522,6 @@ void fsmpico_timeout(FsmPico * fsmpico) { fsmpico->comms->error(fsmpico->user_data); break; } - - buffer_delete(extraData); - buffer_delete(message); } From b5ce68f0d3c92789acbfaddda77a6d93a4f9d03e Mon Sep 17 00:00:00 2001 From: Claudio Dettoni Date: Mon, 12 Feb 2018 15:40:12 +0000 Subject: [PATCH 07/15] Improve messageservicereauth destructor --- src/messageservicereauth.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/messageservicereauth.c b/src/messageservicereauth.c index 09a7090..5597a29 100644 --- a/src/messageservicereauth.c +++ b/src/messageservicereauth.c @@ -123,20 +123,28 @@ void messageservicereauth_delete(MessageServiceReAuth * messageservicereauth) { if (messageservicereauth) { if (messageservicereauth->sharedKey) { buffer_delete(messageservicereauth->sharedKey); + messageservicereauth->sharedKey = NULL; } if (messageservicereauth->sequenceNum) { sequencenumber_delete(messageservicereauth->sequenceNum); + messageservicereauth->sequenceNum = NULL; } if (messageservicereauth->iv) { buffer_delete(messageservicereauth->iv); + messageservicereauth->iv = NULL; } + if (messageservicereauth->encryptedData) { buffer_delete(messageservicereauth->encryptedData); + messageservicereauth->encryptedData = NULL; + } + + if (messageservicereauth->extraData) { + buffer_delete(messageservicereauth->extraData); + messageservicereauth->extraData = NULL; } - - buffer_delete(messageservicereauth->extraData); FREE(messageservicereauth); } From 17a052e448c7a247b9f03d179041f5c3027f205c Mon Sep 17 00:00:00 2001 From: David Llewellyn-Jones Date: Tue, 13 Feb 2018 20:43:02 +0000 Subject: [PATCH 08/15] Update serial service/pico continuous functions to support extradata --- include/pico/continuous.h | 20 +++++----- include/pico/messageservicereauth.h | 4 +- src/continuous.c | 61 ++++++++++++++++++++--------- tests/test_continuous.c | 26 ++++++------ tests/test_fsm.c | 27 +++++++------ 5 files changed, 82 insertions(+), 56 deletions(-) diff --git a/include/pico/continuous.h b/include/pico/continuous.h index 9f88c53..d236657 100644 --- a/include/pico/continuous.h +++ b/include/pico/continuous.h @@ -72,16 +72,16 @@ DLL_PUBLIC void continuous_set_service_sequence_number(Continuous * continuous, DLL_PUBLIC REAUTHSTATE continuous_get_state(Continuous * continuous); DLL_PUBLIC bool continuous_start(Continuous * continuous, Shared * shared, Users * authorizedUsers, Buffer * returnedStoredData, QrCallbackFunction qrCallback, void * data, Buffer * localSymmetricKey); -DLL_PUBLIC bool continuous_cycle_start(Continuous * continuous); -DLL_PUBLIC bool continuous_cycle_start_pico(Continuous * continuous, Buffer * extraData); +DLL_PUBLIC bool continuous_cycle_start(Continuous * continuous, Buffer const * extraData, Buffer * returnedStoredData); +DLL_PUBLIC bool continuous_cycle_start_pico(Continuous * continuous, Buffer const * extraData, Buffer * returnedStoredData); DLL_PUBLIC bool continuous_read_pico_reauth(Continuous * continuous, SequenceNumber * sequenceNumber, Buffer * returnedStoredData); -DLL_PUBLIC bool continuous_write_pico_reauth(Continuous * continuous, Buffer * extraData); -DLL_PUBLIC bool continuous_read_service_reauth(Continuous * continuous, SequenceNumber * sequenceNumber, int * timeout); -DLL_PUBLIC bool continuous_write_service_reauth(Continuous * continuous); -DLL_PUBLIC bool continuous_update_state(Continuous * continuous, REAUTHSTATE new_state); -DLL_PUBLIC bool continuous_reauth(Continuous * continuous, Buffer * returnedStoredData); -DLL_PUBLIC bool continuous_reauth_pico(Continuous * continuous, Buffer * extraData, int * timeout); -DLL_PUBLIC bool continuous_continue(Continuous * continuous, Buffer * returnedStoredData); +DLL_PUBLIC bool continuous_write_pico_reauth(Continuous * continuous, Buffer const * extraData); +DLL_PUBLIC bool continuous_read_service_reauth(Continuous * continuous, SequenceNumber * sequenceNumber, int * timeout, Buffer * returnedStoredData); +DLL_PUBLIC bool continuous_write_service_reauth(Continuous * continuous, Buffer const * extraData); +DLL_PUBLIC bool continuous_update_state(Continuous * continuous, REAUTHSTATE new_state, Buffer const * extraData); +DLL_PUBLIC bool continuous_reauth(Continuous * continuous, Buffer const * extraData, Buffer * returnedStoredData); +DLL_PUBLIC bool continuous_reauth_pico(Continuous * continuous, Buffer const * extraData, int * timeout, Buffer * returnedStoredData); +DLL_PUBLIC bool continuous_continue(Continuous * continuous, Buffer const * extraData, Buffer * returnedStoredData); DLL_PUBLIC bool continuous_finish(Continuous * continuous); DLL_PUBLIC void continuous_set_custom_timeout(Continuous * continuous, int timeout_active, int timeout_paused); @@ -92,7 +92,7 @@ DLL_PUBLIC void continuous_get_shared_key(Continuous * continuous, Buffer * shar DLL_PUBLIC void continuous_set_channel(Continuous * continuous, RVPChannel * channel); DLL_PUBLIC RVPChannel * continuous_get_channel(Continuous * continuous); -DLL_PUBLIC bool continuous_continue_pico(Continuous * continuous, Buffer * extraData, int * timeout); +DLL_PUBLIC bool continuous_continue_pico(Continuous * continuous, Buffer const * extraData, int * timeout, Buffer * returnedStoredData); // Function definitions diff --git a/include/pico/messageservicereauth.h b/include/pico/messageservicereauth.h index bb32131..2f5f830 100644 --- a/include/pico/messageservicereauth.h +++ b/include/pico/messageservicereauth.h @@ -68,8 +68,8 @@ typedef struct _MessageServiceReAuth MessageServiceReAuth; MessageServiceReAuth * messageservicereauth_new(); void messageservicereauth_delete(MessageServiceReAuth * messageservicereauth); void messageservicereauth_set(MessageServiceReAuth * messageservicereauth, Buffer * sharedKey, long int timeout, REAUTHSTATE reauthState, SequenceNumber const * sequenceNum); -void messageservicereauth_set_extra_data(MessageServiceReAuth * messageservicereauth, const Buffer * extraData); -const Buffer * messageservicereauth_get_extra_data(MessageServiceReAuth * messageservicereauth); +void messageservicereauth_set_extra_data(MessageServiceReAuth * messageservicereauth, Buffer const * extraData); +Buffer const * messageservicereauth_get_extra_data(MessageServiceReAuth * messageservicereauth); void messageservicereauth_serialize(MessageServiceReAuth * messageservicereauth, Buffer * buffer); bool messageservicereauth_deserialize(MessageServiceReAuth * messageservicereauth, Buffer const * buffer); int messageservicereauth_get_timeout(MessageServiceReAuth * messageservicereauth); diff --git a/src/continuous.c b/src/continuous.c index eac8b90..3a3064d 100644 --- a/src/continuous.c +++ b/src/continuous.c @@ -409,9 +409,12 @@ bool continuous_start(Continuous * continuous, Shared * shared, Users * authoriz * call to continuous_continue(). * * @param continuous The continuous prover object. + * @param extraData The extra data to send to the Pico, or NULL for none + * @param returnedStoredData A buffer to store the extra data sent back by the + * Pico * @return true if everything was successfully set up. */ -bool continuous_cycle_start(Continuous * continuous) { +bool continuous_cycle_start(Continuous * continuous, Buffer const * extraData, Buffer * returnedStoredData) { bool result; SequenceNumber * sequenceNum; REAUTHSTATE receivedState = REAUTHSTATE_INVALID; @@ -423,7 +426,7 @@ bool continuous_cycle_start(Continuous * continuous) { if (result) { LOG(LOG_INFO, "First read, allowing default timeout"); channel_set_timeout(continuous->channel, DEFAULT_CONTINUOUS_TIMEOUT_ACTIVE); - result = continuous_read_pico_reauth(continuous, sequenceNum, NULL); + result = continuous_read_pico_reauth(continuous, sequenceNum, returnedStoredData); receivedState = continuous->currentState; } @@ -436,7 +439,7 @@ bool continuous_cycle_start(Continuous * continuous) { sequencenumber_increment(sequenceNum); continuous_set_pico_sequence_number(continuous, sequenceNum); continuous_set_current_state(continuous, receivedState); - result = continuous_write_service_reauth(continuous); + result = continuous_write_service_reauth(continuous, extraData); } sequencenumber_delete(sequenceNum); @@ -451,9 +454,12 @@ bool continuous_cycle_start(Continuous * continuous) { * call to continuous_continue_pico(). * * @param continuous The continuous prover object. + * @param extraData The extra data to send to the service, or NULL for none + * @param returnedStoredData A buffer to store the extra data sent back by the + * service * @return true if everything was successfully set up. */ -bool continuous_cycle_start_pico(Continuous * continuous, Buffer * extraData) { +bool continuous_cycle_start_pico(Continuous * continuous, Buffer const * extraData, Buffer * returnedStoredData) { bool result; SequenceNumber * sequenceNum; @@ -471,7 +477,7 @@ bool continuous_cycle_start_pico(Continuous * continuous, Buffer * extraData) { if (result) { sequenceNum = sequencenumber_new(); - result = continuous_read_service_reauth(continuous, sequenceNum, NULL); + result = continuous_read_service_reauth(continuous, sequenceNum, NULL, returnedStoredData); // Increment and store the sequence number received from the Service sequencenumber_increment(sequenceNum); @@ -568,7 +574,7 @@ bool continuous_read_pico_reauth(Continuous * continuous, SequenceNumber * seque * @param extraData The extra data to send to the service (or NULL for none). * @return True if we could send the message correctly */ -bool continuous_write_pico_reauth(Continuous * continuous, Buffer * extraData) { +bool continuous_write_pico_reauth(Continuous * continuous, Buffer const * extraData) { bool result; Buffer * buffer; MessagePicoReAuth * messagepicoreauth; @@ -620,12 +626,13 @@ bool continuous_write_pico_reauth(Continuous * continuous, Buffer * extraData) { * @param returnedStoredData A buffer to store any returned extraData into. * @return True if the message was read correctly. */ -bool continuous_read_service_reauth(Continuous * continuous, SequenceNumber * sequenceNumber, int * timeout) { +bool continuous_read_service_reauth(Continuous * continuous, SequenceNumber * sequenceNumber, int * timeout, Buffer * returnedStoredData) { bool result; bool sequencenumber_match; Buffer * buffer; MessageServiceReAuth * messageservicereauth; SequenceNumber * sequenceNum; + Buffer const * extraData; buffer = buffer_new(0); sequenceNum = sequencenumber_new(); @@ -672,6 +679,12 @@ bool continuous_read_service_reauth(Continuous * continuous, SequenceNumber * se if (result && sequencenumber_match) { sequencenumber_increment(continuous->serviceSeqNumber); + + if (returnedStoredData != NULL) { + extraData = messageservicereauth_get_extra_data(messageservicereauth); + buffer_clear(returnedStoredData); + buffer_append_buffer(returnedStoredData, extraData); + } } else { continuous_set_current_state(continuous, REAUTHSTATE_ERROR); } @@ -689,9 +702,10 @@ bool continuous_read_service_reauth(Continuous * continuous, SequenceNumber * se * If successful, the sequence number will be incremented. * * @param continuous The continuous structure holding the context. + * @param extraData The extra data to send to the Pico, or NULL for none * @return True if we could send the message correctly. */ -bool continuous_write_service_reauth(Continuous * continuous) { +bool continuous_write_service_reauth(Continuous * continuous, Buffer const * extraData) { bool result; Buffer * buffer; MessageServiceReAuth * messageservicereauth; @@ -703,6 +717,9 @@ bool continuous_write_service_reauth(Continuous * continuous) { // {"encryptedData":"B64-ENC","iv":"B64","sessionId":0} messageservicereauth = messageservicereauth_new(); messageservicereauth_set(messageservicereauth, continuous->sharedKey, continuous->currentTimeout, continuous->currentState, continuous->serviceSeqNumber); + if (extraData != NULL) { + messageservicereauth_set_extra_data(messageservicereauth, extraData); + } messageservicereauth_serialize(messageservicereauth, buffer); @@ -736,16 +753,17 @@ bool continuous_write_service_reauth(Continuous * continuous) { * @param continuous The continuous structure holding the context. * @param newState The new state to attempt to transition to (if different * from the current state). + * @param extraData The extra data to send with the new state, or NULL for none * @return True if we could send the message correctly. */ -bool continuous_update_state(Continuous * continuous, REAUTHSTATE newState) { +bool continuous_update_state(Continuous * continuous, REAUTHSTATE newState, Buffer const * extraData) { bool result = true; newState = continuous_transition(continuous->currentState, newState); if (continuous->currentState != newState) { continuous_set_current_state(continuous, newState); - result = continuous_write_service_reauth(continuous); + result = continuous_write_service_reauth(continuous, extraData); } return result; @@ -758,11 +776,12 @@ bool continuous_update_state(Continuous * continuous, REAUTHSTATE newState) { * It will return the current status, as returned by Pico. * * @param continuous The continuous prover object. + * @param extraData The extra data to send to the Pico, or NULL for none * @param returnedStoredData If not NULL, is appended with a string * containing data returned from Pico. * @return True if the authentication was successful. */ -bool continuous_reauth(Continuous * continuous, Buffer * returnedStoredData) { +bool continuous_reauth(Continuous * continuous, Buffer const * extraData, Buffer * returnedStoredData) { bool result; LOG(LOG_INFO, "Starting read %d", continuous->currentTimeout); @@ -774,7 +793,7 @@ bool continuous_reauth(Continuous * continuous, Buffer * returnedStoredData) { } if (result) { - result = continuous_write_service_reauth(continuous); + result = continuous_write_service_reauth(continuous, extraData); } return result; @@ -786,12 +805,18 @@ bool continuous_reauth(Continuous * continuous, Buffer * returnedStoredData) { * * It will return the current status, as returned by the service. * + * The timeout should be used as a deadline within which the Pico must + * respond to the service. If the service doesn't hear back within this time, + * it will assume the Pico is no longer coninuously communicating with it. + * * @param continuous The continuous prover object. + * @param extraData The extra data to send to the Pico, or NULL for none + * @param timeout An integer to store the timeout returned by the service * @param returnedStoredData If not NULL, is appended with a string * containing data returned from Pico. * @return True if the authentication was successful. */ -bool continuous_reauth_pico(Continuous * continuous, Buffer * extraData, int * timeout) { +bool continuous_reauth_pico(Continuous * continuous, Buffer const * extraData, int * timeout, Buffer * returnedStoredData) { bool result; result = continuous_write_pico_reauth(continuous, extraData); @@ -801,7 +826,7 @@ bool continuous_reauth_pico(Continuous * continuous, Buffer * extraData, int * t } if (result) { - result = continuous_read_service_reauth(continuous, NULL, timeout); + result = continuous_read_service_reauth(continuous, NULL, timeout, returnedStoredData); } return result; @@ -819,11 +844,11 @@ bool continuous_reauth_pico(Continuous * continuous, Buffer * extraData, int * t * containing data returned from Pico. * @return true if authentication completed successfully, false o/w. */ -bool continuous_continue(Continuous * continuous, Buffer * returnedStoredData) { +bool continuous_continue(Continuous * continuous, Buffer const * extraData, Buffer * returnedStoredData) { bool result; REAUTHSTATE receivedState = REAUTHSTATE_INVALID; - result = continuous_reauth(continuous, returnedStoredData); + result = continuous_reauth(continuous, extraData, returnedStoredData); if (result) { receivedState = continuous->currentState; } @@ -862,11 +887,11 @@ bool continuous_finish(Continuous * continuous) { * (set in messageservicereauth.h to 10000ms = 10s). * @return true if authentication completed successfully. false o/w. */ -bool continuous_continue_pico(Continuous * continuous, Buffer * extraData, int * timeout) { +bool continuous_continue_pico(Continuous * continuous, Buffer const * extraData, int * timeout, Buffer * returnedStoredData) { bool result; REAUTHSTATE receivedState = REAUTHSTATE_INVALID; - result = continuous_reauth_pico(continuous, extraData, timeout); + result = continuous_reauth_pico(continuous, extraData, timeout, returnedStoredData); if (result) { receivedState = continuous->currentState; diff --git a/tests/test_continuous.c b/tests/test_continuous.c index 617a0bc..4f1f219 100644 --- a/tests/test_continuous.c +++ b/tests/test_continuous.c @@ -84,23 +84,23 @@ void * pico_main(void * thread_data) { continuous_set_shared_key(continuous, sharedkey); continuous_set_custom_timeout_leeway(continuous, 500); - continuous_cycle_start_pico(continuous, NULL); + continuous_cycle_start_pico(continuous, NULL, NULL); - continuous_reauth_pico(continuous, NULL, NULL); + continuous_reauth_pico(continuous, NULL, NULL, NULL); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_CONTINUE); - bool result = continuous_continue_pico(continuous, NULL, NULL); + bool result = continuous_continue_pico(continuous, NULL, NULL, NULL); ck_assert(result); - continuous_reauth_pico(continuous, NULL, &timeout); + continuous_reauth_pico(continuous, NULL, &timeout, NULL); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_PAUSE); ck_assert_int_eq(timeout, 1500); - continuous_reauth_pico(continuous, NULL, &timeout); + continuous_reauth_pico(continuous, NULL, &timeout, NULL); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_CONTINUE); ck_assert_int_eq(timeout, 1500); - continuous_reauth_pico(continuous, NULL, &timeout); + continuous_reauth_pico(continuous, NULL, &timeout, NULL); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_STOP); ck_assert_int_eq(timeout, 0); @@ -141,26 +141,26 @@ START_TEST (continuous_test) { pthread_t pico_td; pthread_create(&pico_td, NULL, pico_main, &thread_data); - continuous_set_custom_timeout(continuous, 2000, 2000); - bool result = continuous_cycle_start(continuous); + continuous_set_custom_timeout(continuous, 2000, 2000); + bool result = continuous_cycle_start(continuous, NULL, NULL); ck_assert(result); - continuous_reauth(continuous, NULL); + continuous_reauth(continuous, NULL, NULL); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_CONTINUE); - result = continuous_continue(continuous, NULL); + result = continuous_continue(continuous, NULL, NULL); ck_assert(result); continuous_read_pico_reauth(continuous, NULL, NULL); - continuous_update_state(continuous, REAUTHSTATE_PAUSE); + continuous_update_state(continuous, REAUTHSTATE_PAUSE, NULL); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_PAUSE); continuous_read_pico_reauth(continuous, NULL, NULL); - continuous_update_state(continuous, REAUTHSTATE_CONTINUE); + continuous_update_state(continuous, REAUTHSTATE_CONTINUE, NULL); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_CONTINUE); continuous_read_pico_reauth(continuous, NULL, NULL); - continuous_update_state(continuous, REAUTHSTATE_STOP); + continuous_update_state(continuous, REAUTHSTATE_STOP, NULL); continuous_finish(continuous); diff --git a/tests/test_fsm.c b/tests/test_fsm.c index 6a01a5c..314b18f 100644 --- a/tests/test_fsm.c +++ b/tests/test_fsm.c @@ -512,17 +512,18 @@ START_TEST (fsm_pico_test) { 5000, // Read timeout for ServiceAuthMessage 5000, // Read timeout for StatusMessage 10000, //Reconnect delay - 9000, // Continuous timeout + 11000, // Continuous timeout 11000, // Read timeout for ServiceReauthMessage - 9000, // Continuous timeout + 11000, // Continuous timeout 11000, // Read timeout for ServiceReauthMessage - 9000, // Continuous timeout + 11000, // Continuous timeout 11000, // Read timeout for ServiceReauthMessage - 9000 // Continuous timeout + 11000 // Continuous timeout }; void picoSetTimeout(int timeout, void * user_data) { static int i = 0; + fprintf(stderr, "Timeout: %d, expected: %d\n", timeout, expectedTimeouts[i]); ck_assert_int_eq(expectedTimeouts[i++], timeout); push_timeout(&queue, pico, NULL, currentTime, timeout); } @@ -578,19 +579,19 @@ START_TEST (fsm_pico_test) { continuous_set_channel(continuous, channel); continuous_set_shared_key(continuous, shared_get_shared_key(servShared)); - result = continuous_cycle_start(continuous); + result = continuous_cycle_start(continuous, NULL, NULL); ck_assert(result); - result = continuous_continue(continuous, NULL); + result = continuous_continue(continuous, NULL, NULL); ck_assert(result); - result = continuous_continue(continuous, NULL); + result = continuous_continue(continuous, NULL, NULL); ck_assert(result); - result = continuous_continue(continuous, NULL); + result = continuous_continue(continuous, NULL, NULL); ck_assert(result); - result = continuous_continue(continuous, NULL); + result = continuous_continue(continuous, NULL, NULL); ck_assert(!result); ck_assert(cycles == 4); @@ -748,17 +749,17 @@ START_TEST (fsm_service_test) { continuous_set_channel(continuous, channel); continuous_set_shared_key(continuous, shared_get_shared_key(servShared)); - result = continuous_cycle_start_pico(continuous, NULL); + result = continuous_cycle_start_pico(continuous, NULL, NULL); ck_assert(result); int timeout = 0; - result = continuous_reauth_pico(continuous, NULL, &timeout); + result = continuous_reauth_pico(continuous, NULL, &timeout, NULL); ck_assert(result); - result = continuous_reauth_pico(continuous, NULL, &timeout); + result = continuous_reauth_pico(continuous, NULL, &timeout, NULL); ck_assert(result); - result = continuous_reauth_pico(continuous, NULL, &timeout); + result = continuous_reauth_pico(continuous, NULL, &timeout, NULL); ck_assert(result); // Wait for the other thread to complete the cycles before stopping the loop From 7fbb3920d5f7bb5e596717d1e9ae875197684df5 Mon Sep 17 00:00:00 2001 From: David Llewellyn-Jones Date: Tue, 13 Feb 2018 20:47:09 +0000 Subject: [PATCH 09/15] Update documentation --- src/continuous.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/continuous.c b/src/continuous.c index 3a3064d..e7eb346 100644 --- a/src/continuous.c +++ b/src/continuous.c @@ -840,7 +840,9 @@ bool continuous_reauth_pico(Continuous * continuous, Buffer const * extraData, i * successfully (e.g. someone tried unsuccessfully to imitate the Pico). * * @param continuous The continuous prover object. - * @param returnedStoredData If not NULL, is appended with a string + * @param extraData The extra data to send to the Pico, or NULL for none + * @param returnedStoredData A buffer to store the extra data sent back by the + * Pico * containing data returned from Pico. * @return true if authentication completed successfully, false o/w. */ @@ -881,10 +883,12 @@ bool continuous_finish(Continuous * continuous) { * the Server). * * @param continuous The continuous prover object. - * @param extraData If not NULL, is sent to the server. + * @param extraData The extra data to send to the service, or NULL for none * @param timeout returns the timeout value sent by the server, measured in * milliseconds. The server value defaults toCONTINUOUS_TIMEOUT_ACTIVE * (set in messageservicereauth.h to 10000ms = 10s). + * @param returnedStoredData A buffer to store the extra data sent back by the + * service * @return true if authentication completed successfully. false o/w. */ bool continuous_continue_pico(Continuous * continuous, Buffer const * extraData, int * timeout, Buffer * returnedStoredData) { From 7bcd05893522626b2862e63dee99c2ef1ae027c8 Mon Sep 17 00:00:00 2001 From: David Llewellyn-Jones Date: Thu, 15 Feb 2018 22:00:57 +0000 Subject: [PATCH 10/15] Update unit tests to check extradata sending --- include/pico/continuous.h | 6 +- src/continuous.c | 30 +++++--- tests/test_continuous.c | 149 +++++++++++++++++++++++++++++++++----- 3 files changed, 154 insertions(+), 31 deletions(-) diff --git a/include/pico/continuous.h b/include/pico/continuous.h index d236657..b25f287 100644 --- a/include/pico/continuous.h +++ b/include/pico/continuous.h @@ -76,11 +76,11 @@ DLL_PUBLIC bool continuous_cycle_start(Continuous * continuous, Buffer const * e DLL_PUBLIC bool continuous_cycle_start_pico(Continuous * continuous, Buffer const * extraData, Buffer * returnedStoredData); DLL_PUBLIC bool continuous_read_pico_reauth(Continuous * continuous, SequenceNumber * sequenceNumber, Buffer * returnedStoredData); DLL_PUBLIC bool continuous_write_pico_reauth(Continuous * continuous, Buffer const * extraData); -DLL_PUBLIC bool continuous_read_service_reauth(Continuous * continuous, SequenceNumber * sequenceNumber, int * timeout, Buffer * returnedStoredData); +DLL_PUBLIC bool continuous_read_service_reauth(Continuous * continuous, SequenceNumber * sequenceNumber, Buffer * returnedStoredData, int * timeout); DLL_PUBLIC bool continuous_write_service_reauth(Continuous * continuous, Buffer const * extraData); DLL_PUBLIC bool continuous_update_state(Continuous * continuous, REAUTHSTATE new_state, Buffer const * extraData); DLL_PUBLIC bool continuous_reauth(Continuous * continuous, Buffer const * extraData, Buffer * returnedStoredData); -DLL_PUBLIC bool continuous_reauth_pico(Continuous * continuous, Buffer const * extraData, int * timeout, Buffer * returnedStoredData); +DLL_PUBLIC bool continuous_reauth_pico(Continuous * continuous, Buffer const * extraData, Buffer * returnedStoredData, int * timeout); DLL_PUBLIC bool continuous_continue(Continuous * continuous, Buffer const * extraData, Buffer * returnedStoredData); DLL_PUBLIC bool continuous_finish(Continuous * continuous); @@ -92,7 +92,7 @@ DLL_PUBLIC void continuous_get_shared_key(Continuous * continuous, Buffer * shar DLL_PUBLIC void continuous_set_channel(Continuous * continuous, RVPChannel * channel); DLL_PUBLIC RVPChannel * continuous_get_channel(Continuous * continuous); -DLL_PUBLIC bool continuous_continue_pico(Continuous * continuous, Buffer const * extraData, int * timeout, Buffer * returnedStoredData); +DLL_PUBLIC bool continuous_continue_pico(Continuous * continuous, Buffer const * extraData, Buffer * returnedStoredData, int * timeout); // Function definitions diff --git a/src/continuous.c b/src/continuous.c index e7eb346..94d24e5 100644 --- a/src/continuous.c +++ b/src/continuous.c @@ -477,7 +477,7 @@ bool continuous_cycle_start_pico(Continuous * continuous, Buffer const * extraDa if (result) { sequenceNum = sequencenumber_new(); - result = continuous_read_service_reauth(continuous, sequenceNum, NULL, returnedStoredData); + result = continuous_read_service_reauth(continuous, sequenceNum, returnedStoredData, NULL); // Increment and store the sequence number received from the Service sequencenumber_increment(sequenceNum); @@ -514,6 +514,7 @@ bool continuous_read_pico_reauth(Continuous * continuous, SequenceNumber * seque Buffer * buffer; MessagePicoReAuth * messagepicoreauth; SequenceNumber * sequenceNum; + Buffer const * extraData; buffer = buffer_new(0); sequenceNum = sequencenumber_new(); @@ -526,9 +527,10 @@ bool continuous_read_pico_reauth(Continuous * continuous, SequenceNumber * seque result = channel_read(continuous->channel, buffer); LOG(LOG_INFO, "PicoReauth received\n"); + messagepicoreauth = messagepicoreauth_new(); + if (result) { // Deserialize the message - messagepicoreauth = messagepicoreauth_new(); messagepicoreauth_set(messagepicoreauth, continuous->sharedKey, NULL); result = messagepicoreauth_deserialize(messagepicoreauth, buffer); } @@ -536,7 +538,6 @@ bool continuous_read_pico_reauth(Continuous * continuous, SequenceNumber * seque if (result) { messagepicoreauth_get_sequencenum(messagepicoreauth, sequenceNum); continuous_set_current_state(continuous, messagepicoreauth_get_reauthstate(messagepicoreauth)); - messagepicoreauth_delete(messagepicoreauth); if (sequenceNumber != NULL) { // This is an initialisation message, so store the receied sequence @@ -554,12 +555,20 @@ bool continuous_read_pico_reauth(Continuous * continuous, SequenceNumber * seque if (result && sequencenumber_match) { sequencenumber_increment(continuous->picoSeqNumber); + + if (returnedStoredData != NULL) { + extraData = messagepicoreauth_get_extra_data(messagepicoreauth); + buffer_clear(returnedStoredData); + buffer_append_buffer(returnedStoredData, extraData); + } + } else { continuous_set_current_state(continuous, REAUTHSTATE_ERROR); } buffer_delete(buffer); sequencenumber_delete(sequenceNum); + messagepicoreauth_delete(messagepicoreauth); return result; } @@ -626,7 +635,7 @@ bool continuous_write_pico_reauth(Continuous * continuous, Buffer const * extraD * @param returnedStoredData A buffer to store any returned extraData into. * @return True if the message was read correctly. */ -bool continuous_read_service_reauth(Continuous * continuous, SequenceNumber * sequenceNumber, int * timeout, Buffer * returnedStoredData) { +bool continuous_read_service_reauth(Continuous * continuous, SequenceNumber * sequenceNumber, Buffer * returnedStoredData, int * timeout) { bool result; bool sequencenumber_match; Buffer * buffer; @@ -648,9 +657,10 @@ bool continuous_read_service_reauth(Continuous * continuous, SequenceNumber * se result = channel_read(continuous->channel, buffer); LOG(LOG_INFO, "ServiceReauth received\n"); + messageservicereauth = messageservicereauth_new(); + if (result) { // Deserialize the message - messageservicereauth = messageservicereauth_new(); messageservicereauth_set(messageservicereauth, continuous->sharedKey, 0, REAUTHSTATE_CONTINUE, NULL); result = messageservicereauth_deserialize(messageservicereauth, buffer); } @@ -661,7 +671,6 @@ bool continuous_read_service_reauth(Continuous * continuous, SequenceNumber * se if (timeout != NULL) { *timeout = MAX(messageservicereauth_get_timeout(messageservicereauth) - continuous->timeoutLeeway, 0); } - messageservicereauth_delete(messageservicereauth); if (sequenceNumber != NULL) { // This is an initialisation message, so store the receied sequence @@ -691,6 +700,7 @@ bool continuous_read_service_reauth(Continuous * continuous, SequenceNumber * se buffer_delete(buffer); sequencenumber_delete(sequenceNum); + messageservicereauth_delete(messageservicereauth); return result; } @@ -816,7 +826,7 @@ bool continuous_reauth(Continuous * continuous, Buffer const * extraData, Buffer * containing data returned from Pico. * @return True if the authentication was successful. */ -bool continuous_reauth_pico(Continuous * continuous, Buffer const * extraData, int * timeout, Buffer * returnedStoredData) { +bool continuous_reauth_pico(Continuous * continuous, Buffer const * extraData, Buffer * returnedStoredData, int * timeout) { bool result; result = continuous_write_pico_reauth(continuous, extraData); @@ -826,7 +836,7 @@ bool continuous_reauth_pico(Continuous * continuous, Buffer const * extraData, i } if (result) { - result = continuous_read_service_reauth(continuous, NULL, timeout, returnedStoredData); + result = continuous_read_service_reauth(continuous, NULL, returnedStoredData, timeout); } return result; @@ -891,11 +901,11 @@ bool continuous_finish(Continuous * continuous) { * service * @return true if authentication completed successfully. false o/w. */ -bool continuous_continue_pico(Continuous * continuous, Buffer const * extraData, int * timeout, Buffer * returnedStoredData) { +bool continuous_continue_pico(Continuous * continuous, Buffer const * extraData, Buffer * returnedStoredData, int * timeout) { bool result; REAUTHSTATE receivedState = REAUTHSTATE_INVALID; - result = continuous_reauth_pico(continuous, extraData, timeout, returnedStoredData); + result = continuous_reauth_pico(continuous, extraData, returnedStoredData, timeout); if (result) { receivedState = continuous->currentState; diff --git a/tests/test_continuous.c b/tests/test_continuous.c index 4f1f219..58eae19 100644 --- a/tests/test_continuous.c +++ b/tests/test_continuous.c @@ -47,6 +47,77 @@ typedef struct { // Function definitions +static char const * const pico_data[] = {"one", "two", NULL, "four", NULL, "six", "seven"}; +static char const * const service_data[] = {"ten", "eleven", NULL, NULL, "fourteen", "fifteen", "sixteen"}; +static int pico_data_pos_sent; +static int pico_data_pos_received; +static int service_data_pos_sent; +static int service_data_pos_received; + +Buffer const * pico_update_extradata(Buffer * extraData) { + Buffer const * extraDataOrNull; + + ck_assert(pico_data_pos_sent < 7); + buffer_clear(extraData); + if (pico_data[pico_data_pos_sent] != NULL) { + buffer_append_string(extraData, pico_data[pico_data_pos_sent]); + extraDataOrNull = extraData; + } + else { + extraDataOrNull = NULL; + } + pico_data_pos_sent++; + + return extraDataOrNull; +} + +void pico_check_extradata(Buffer const * returnedStoredData) { + char const * data; + + data = buffer_get_buffer(returnedStoredData); + + ck_assert(pico_data_pos_received < 7); + if (service_data[pico_data_pos_received] != NULL) { + ck_assert_str_eq(data, service_data[pico_data_pos_received]); + } + else { + ck_assert_str_eq(data, ""); + } + pico_data_pos_received++; +} + +Buffer const * service_update_extradata(Buffer * extraData) { + Buffer const * extraDataOrNull; + + ck_assert(service_data_pos_sent < 7); + buffer_clear(extraData); + if (service_data[service_data_pos_sent] != NULL) { + buffer_append_string(extraData, service_data[service_data_pos_sent]); + extraDataOrNull = extraData; + } + else { + extraDataOrNull = NULL; + } + service_data_pos_sent++; + + return extraDataOrNull; +} + +void service_check_extradata(Buffer const * returnedStoredData) { + char const * data; + + data = buffer_get_buffer(returnedStoredData); + + ck_assert(service_data_pos_received < 7); + if (pico_data[service_data_pos_received] != NULL) { + ck_assert_str_eq(data, pico_data[service_data_pos_received]); + } + else { + ck_assert_str_eq(data, ""); + } + service_data_pos_received++; +} + START_TEST (continuous_constructor_test) { RVPChannel * channel = channel_new(); Continuous * continuous = continuous_new(); @@ -74,7 +145,16 @@ END_TEST void * pico_main(void * thread_data) { sleep(0.5); PicoThreadData * data = (PicoThreadData*) thread_data; - int timeout; + int timeout; + Buffer * extraData; + Buffer * returnedStoredData; + Buffer const * extraDataOrNull; + + extraData = buffer_new(0); + returnedStoredData = buffer_new(0); + + pico_data_pos_sent = 0; + pico_data_pos_received = 0; Buffer * sharedkey = buffer_new(0); buffer_append(sharedkey, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16); @@ -84,25 +164,37 @@ void * pico_main(void * thread_data) { continuous_set_shared_key(continuous, sharedkey); continuous_set_custom_timeout_leeway(continuous, 500); - continuous_cycle_start_pico(continuous, NULL, NULL); + extraDataOrNull = pico_update_extradata(extraData); + continuous_cycle_start_pico(continuous, extraDataOrNull, returnedStoredData); + pico_check_extradata(returnedStoredData); - continuous_reauth_pico(continuous, NULL, NULL, NULL); + extraDataOrNull = pico_update_extradata(extraData); + continuous_reauth_pico(continuous, extraDataOrNull, returnedStoredData, NULL); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_CONTINUE); + pico_check_extradata(returnedStoredData); - bool result = continuous_continue_pico(continuous, NULL, NULL, NULL); + extraDataOrNull = pico_update_extradata(extraData); + bool result = continuous_continue_pico(continuous, extraDataOrNull, returnedStoredData, NULL); ck_assert(result); + pico_check_extradata(returnedStoredData); - continuous_reauth_pico(continuous, NULL, &timeout, NULL); + extraDataOrNull = pico_update_extradata(extraData); + continuous_reauth_pico(continuous, extraDataOrNull, returnedStoredData, &timeout); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_PAUSE); ck_assert_int_eq(timeout, 1500); + pico_check_extradata(returnedStoredData); - continuous_reauth_pico(continuous, NULL, &timeout, NULL); + extraDataOrNull = pico_update_extradata(extraData); + continuous_reauth_pico(continuous, extraDataOrNull, returnedStoredData, &timeout); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_CONTINUE); ck_assert_int_eq(timeout, 1500); + pico_check_extradata(returnedStoredData); - continuous_reauth_pico(continuous, NULL, &timeout, NULL); + extraDataOrNull = pico_update_extradata(extraData); + continuous_reauth_pico(continuous, extraDataOrNull, returnedStoredData, &timeout); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_STOP); - ck_assert_int_eq(timeout, 0); + ck_assert_int_eq(timeout, 0); + pico_check_extradata(returnedStoredData); continuous_finish(continuous); @@ -120,15 +212,24 @@ void get_allocated_channel_name(char const * channel_url_const, char * out) { free(channel_url); } - START_TEST (continuous_test) { PicoThreadData thread_data; RVPChannel * channel = channel_new(); Continuous * continuous = continuous_new(); Buffer * channel_buffer = buffer_new(0); Buffer * sharedkey = buffer_new(0); + Buffer * extraData; + Buffer * returnedStoredData; + Buffer const * extraDataOrNull; + buffer_append(sharedkey, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16); + extraData = buffer_new(0); + returnedStoredData = buffer_new(0); + + service_data_pos_sent = 0; + service_data_pos_received = 0; + ck_assert(channel != NULL); continuous_set_channel(continuous, channel); continuous_set_shared_key(continuous, sharedkey); @@ -141,26 +242,38 @@ START_TEST (continuous_test) { pthread_t pico_td; pthread_create(&pico_td, NULL, pico_main, &thread_data); + extraDataOrNull = service_update_extradata(extraData); continuous_set_custom_timeout(continuous, 2000, 2000); - bool result = continuous_cycle_start(continuous, NULL, NULL); + bool result = continuous_cycle_start(continuous, extraDataOrNull, returnedStoredData); ck_assert(result); + service_check_extradata(returnedStoredData); - continuous_reauth(continuous, NULL, NULL); + extraDataOrNull = service_update_extradata(extraData); + continuous_reauth(continuous, extraDataOrNull, returnedStoredData); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_CONTINUE); + service_check_extradata(returnedStoredData); - result = continuous_continue(continuous, NULL, NULL); + extraDataOrNull = service_update_extradata(extraData); + result = continuous_continue(continuous, extraDataOrNull, returnedStoredData); ck_assert(result); + service_check_extradata(returnedStoredData); - continuous_read_pico_reauth(continuous, NULL, NULL); - continuous_update_state(continuous, REAUTHSTATE_PAUSE, NULL); + extraDataOrNull = service_update_extradata(extraData); + continuous_read_pico_reauth(continuous, NULL, returnedStoredData); + continuous_update_state(continuous, REAUTHSTATE_PAUSE, extraDataOrNull); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_PAUSE); + service_check_extradata(returnedStoredData); - continuous_read_pico_reauth(continuous, NULL, NULL); - continuous_update_state(continuous, REAUTHSTATE_CONTINUE, NULL); + extraDataOrNull = service_update_extradata(extraData); + continuous_read_pico_reauth(continuous, NULL, returnedStoredData); + continuous_update_state(continuous, REAUTHSTATE_CONTINUE, extraDataOrNull); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_CONTINUE); + service_check_extradata(returnedStoredData); - continuous_read_pico_reauth(continuous, NULL, NULL); - continuous_update_state(continuous, REAUTHSTATE_STOP, NULL); + extraDataOrNull = service_update_extradata(extraData); + continuous_read_pico_reauth(continuous, NULL, returnedStoredData); + continuous_update_state(continuous, REAUTHSTATE_STOP, extraDataOrNull); + service_check_extradata(returnedStoredData); continuous_finish(continuous); From 54c4bf1f7c9ad3c3367d80a535da8ef16ad1708e Mon Sep 17 00:00:00 2001 From: David Llewellyn-Jones Date: Fri, 16 Feb 2018 17:30:37 +0000 Subject: [PATCH 11/15] Avoid the use of global variables This is more important than it looks because the tests may be run in parallel. --- tests/test_continuous.c | 110 +++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 52 deletions(-) diff --git a/tests/test_continuous.c b/tests/test_continuous.c index 58eae19..04c5781 100644 --- a/tests/test_continuous.c +++ b/tests/test_continuous.c @@ -49,73 +49,69 @@ typedef struct { static char const * const pico_data[] = {"one", "two", NULL, "four", NULL, "six", "seven"}; static char const * const service_data[] = {"ten", "eleven", NULL, NULL, "fourteen", "fifteen", "sixteen"}; -static int pico_data_pos_sent; -static int pico_data_pos_received; -static int service_data_pos_sent; -static int service_data_pos_received; -Buffer const * pico_update_extradata(Buffer * extraData) { +Buffer const * pico_update_extradata(Buffer * extraData, int * pico_sent) { Buffer const * extraDataOrNull; - ck_assert(pico_data_pos_sent < 7); + ck_assert(*pico_sent < 7); buffer_clear(extraData); - if (pico_data[pico_data_pos_sent] != NULL) { - buffer_append_string(extraData, pico_data[pico_data_pos_sent]); + if (pico_data[*pico_sent] != NULL) { + buffer_append_string(extraData, pico_data[*pico_sent]); extraDataOrNull = extraData; } else { extraDataOrNull = NULL; } - pico_data_pos_sent++; + (*pico_sent)++; return extraDataOrNull; } -void pico_check_extradata(Buffer const * returnedStoredData) { +void pico_check_extradata(Buffer const * returnedStoredData, int * pico_received) { char const * data; data = buffer_get_buffer(returnedStoredData); - ck_assert(pico_data_pos_received < 7); - if (service_data[pico_data_pos_received] != NULL) { - ck_assert_str_eq(data, service_data[pico_data_pos_received]); + ck_assert(*pico_received < 7); + if (service_data[*pico_received] != NULL) { + ck_assert_str_eq(data, service_data[*pico_received]); } else { ck_assert_str_eq(data, ""); } - pico_data_pos_received++; + (*pico_received)++; } -Buffer const * service_update_extradata(Buffer * extraData) { +Buffer const * service_update_extradata(Buffer * extraData, int * service_sent) { Buffer const * extraDataOrNull; - ck_assert(service_data_pos_sent < 7); + ck_assert(*service_sent < 7); buffer_clear(extraData); - if (service_data[service_data_pos_sent] != NULL) { - buffer_append_string(extraData, service_data[service_data_pos_sent]); + if (service_data[*service_sent] != NULL) { + buffer_append_string(extraData, service_data[*service_sent]); extraDataOrNull = extraData; } else { extraDataOrNull = NULL; } - service_data_pos_sent++; + (*service_sent)++; return extraDataOrNull; } -void service_check_extradata(Buffer const * returnedStoredData) { +void service_check_extradata(Buffer const * returnedStoredData, int * service_received) { char const * data; data = buffer_get_buffer(returnedStoredData); - ck_assert(service_data_pos_received < 7); - if (pico_data[service_data_pos_received] != NULL) { - ck_assert_str_eq(data, pico_data[service_data_pos_received]); + ck_assert(*service_received < 7); + if (pico_data[*service_received] != NULL) { + ck_assert_str_eq(data, pico_data[*service_received]); } else { ck_assert_str_eq(data, ""); } - service_data_pos_received++; + (*service_received)++; } START_TEST (continuous_constructor_test) { @@ -149,12 +145,14 @@ void * pico_main(void * thread_data) { Buffer * extraData; Buffer * returnedStoredData; Buffer const * extraDataOrNull; + int pico_sent; + int pico_received; extraData = buffer_new(0); returnedStoredData = buffer_new(0); - pico_data_pos_sent = 0; - pico_data_pos_received = 0; + pico_sent = 0; + pico_received = 0; Buffer * sharedkey = buffer_new(0); buffer_append(sharedkey, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16); @@ -164,40 +162,43 @@ void * pico_main(void * thread_data) { continuous_set_shared_key(continuous, sharedkey); continuous_set_custom_timeout_leeway(continuous, 500); - extraDataOrNull = pico_update_extradata(extraData); + extraDataOrNull = pico_update_extradata(extraData, & pico_sent); continuous_cycle_start_pico(continuous, extraDataOrNull, returnedStoredData); - pico_check_extradata(returnedStoredData); + pico_check_extradata(returnedStoredData, & pico_received); - extraDataOrNull = pico_update_extradata(extraData); + extraDataOrNull = pico_update_extradata(extraData, & pico_sent); continuous_reauth_pico(continuous, extraDataOrNull, returnedStoredData, NULL); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_CONTINUE); - pico_check_extradata(returnedStoredData); + pico_check_extradata(returnedStoredData, & pico_received); - extraDataOrNull = pico_update_extradata(extraData); + extraDataOrNull = pico_update_extradata(extraData, & pico_sent); bool result = continuous_continue_pico(continuous, extraDataOrNull, returnedStoredData, NULL); ck_assert(result); - pico_check_extradata(returnedStoredData); + pico_check_extradata(returnedStoredData, & pico_received); - extraDataOrNull = pico_update_extradata(extraData); + extraDataOrNull = pico_update_extradata(extraData, & pico_sent); continuous_reauth_pico(continuous, extraDataOrNull, returnedStoredData, &timeout); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_PAUSE); ck_assert_int_eq(timeout, 1500); - pico_check_extradata(returnedStoredData); + pico_check_extradata(returnedStoredData, & pico_received); - extraDataOrNull = pico_update_extradata(extraData); + extraDataOrNull = pico_update_extradata(extraData, & pico_sent); continuous_reauth_pico(continuous, extraDataOrNull, returnedStoredData, &timeout); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_CONTINUE); ck_assert_int_eq(timeout, 1500); - pico_check_extradata(returnedStoredData); + pico_check_extradata(returnedStoredData, & pico_received); - extraDataOrNull = pico_update_extradata(extraData); + extraDataOrNull = pico_update_extradata(extraData, & pico_sent); continuous_reauth_pico(continuous, extraDataOrNull, returnedStoredData, &timeout); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_STOP); ck_assert_int_eq(timeout, 0); - pico_check_extradata(returnedStoredData); + pico_check_extradata(returnedStoredData, & pico_received); continuous_finish(continuous); + buffer_delete(extraData); + buffer_delete(returnedStoredData); + return NULL; } @@ -221,14 +222,16 @@ START_TEST (continuous_test) { Buffer * extraData; Buffer * returnedStoredData; Buffer const * extraDataOrNull; + int service_sent; + int service_received; buffer_append(sharedkey, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16); extraData = buffer_new(0); returnedStoredData = buffer_new(0); - service_data_pos_sent = 0; - service_data_pos_received = 0; + service_sent = 0; + service_received = 0; ck_assert(channel != NULL); continuous_set_channel(continuous, channel); @@ -242,38 +245,38 @@ START_TEST (continuous_test) { pthread_t pico_td; pthread_create(&pico_td, NULL, pico_main, &thread_data); - extraDataOrNull = service_update_extradata(extraData); + extraDataOrNull = service_update_extradata(extraData, & service_sent); continuous_set_custom_timeout(continuous, 2000, 2000); bool result = continuous_cycle_start(continuous, extraDataOrNull, returnedStoredData); ck_assert(result); - service_check_extradata(returnedStoredData); + service_check_extradata(returnedStoredData, & service_received); - extraDataOrNull = service_update_extradata(extraData); + extraDataOrNull = service_update_extradata(extraData, & service_sent); continuous_reauth(continuous, extraDataOrNull, returnedStoredData); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_CONTINUE); - service_check_extradata(returnedStoredData); + service_check_extradata(returnedStoredData, & service_received); - extraDataOrNull = service_update_extradata(extraData); + extraDataOrNull = service_update_extradata(extraData, & service_sent); result = continuous_continue(continuous, extraDataOrNull, returnedStoredData); ck_assert(result); - service_check_extradata(returnedStoredData); + service_check_extradata(returnedStoredData, & service_received); - extraDataOrNull = service_update_extradata(extraData); + extraDataOrNull = service_update_extradata(extraData, & service_sent); continuous_read_pico_reauth(continuous, NULL, returnedStoredData); continuous_update_state(continuous, REAUTHSTATE_PAUSE, extraDataOrNull); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_PAUSE); - service_check_extradata(returnedStoredData); + service_check_extradata(returnedStoredData, & service_received); - extraDataOrNull = service_update_extradata(extraData); + extraDataOrNull = service_update_extradata(extraData, & service_sent); continuous_read_pico_reauth(continuous, NULL, returnedStoredData); continuous_update_state(continuous, REAUTHSTATE_CONTINUE, extraDataOrNull); ck_assert(continuous_get_state(continuous) == REAUTHSTATE_CONTINUE); - service_check_extradata(returnedStoredData); + service_check_extradata(returnedStoredData, & service_received); - extraDataOrNull = service_update_extradata(extraData); + extraDataOrNull = service_update_extradata(extraData, & service_sent); continuous_read_pico_reauth(continuous, NULL, returnedStoredData); continuous_update_state(continuous, REAUTHSTATE_STOP, extraDataOrNull); - service_check_extradata(returnedStoredData); + service_check_extradata(returnedStoredData, & service_received); continuous_finish(continuous); @@ -282,6 +285,9 @@ START_TEST (continuous_test) { buffer_delete(channel_buffer); channel_delete(channel); continuous_delete(continuous); + + buffer_delete(extraData); + buffer_delete(returnedStoredData); } END_TEST From 4f853ab8103e56ac4caa074e9f86ed534a5a2a73 Mon Sep 17 00:00:00 2001 From: David Llewellyn-Jones Date: Fri, 16 Feb 2018 17:48:04 +0000 Subject: [PATCH 12/15] Add extradata to one test --- tests/test_fsm.c | 128 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 117 insertions(+), 11 deletions(-) diff --git a/tests/test_fsm.c b/tests/test_fsm.c index 314b18f..b57f355 100644 --- a/tests/test_fsm.c +++ b/tests/test_fsm.c @@ -82,6 +82,80 @@ pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER; // Function definitions +static char const * const pico_data[] = {"one", "two", NULL, "four", NULL, "six", "seven"}; +static char const * const service_data[] = {"ten", "eleven", NULL, NULL, "fourteen", "fifteen", "sixteen"}; +//static int pico_sent; +//static int pico_received; + +Buffer const * pico_update_extradata(Buffer * extraData, int * pico_sent) { + Buffer const * extraDataOrNull; + + ck_assert(*pico_sent < 7); + buffer_clear(extraData); + if (pico_data[*pico_sent] != NULL) { + buffer_append_string(extraData, pico_data[*pico_sent]); + extraDataOrNull = extraData; + } + else { + extraDataOrNull = NULL; + } + (*pico_sent)++; + + return extraDataOrNull; +} + +void pico_check_extradata(Buffer const * returnedStoredData, int * pico_received) { + char const * data; + + data = buffer_get_buffer(returnedStoredData); + + fprintf(stderr, "Received: %s, expected: %s\n", data, ((service_data[*pico_received] != NULL )? service_data[*pico_received] : "NULL")); + + ck_assert(*pico_received < 7); + if (service_data[*pico_received] != NULL) { + ck_assert_str_eq(data, service_data[*pico_received]); + } + else { + ck_assert_str_eq(data, ""); + } + (*pico_received)++; +} + +Buffer const * service_update_extradata(Buffer * extraData, int * service_sent) { + Buffer const * extraDataOrNull; + + ck_assert(*service_sent < 7); + buffer_clear(extraData); + if (service_data[*service_sent] != NULL) { + buffer_append_string(extraData, service_data[*service_sent]); + extraDataOrNull = extraData; + } + else { + extraDataOrNull = NULL; + } + (*service_sent)++; + + fprintf(stderr, "Sending: %s\n", ((extraDataOrNull != NULL )? buffer_get_buffer(extraDataOrNull) : "NULL")); + + return extraDataOrNull; +} + +void service_check_extradata(Buffer const * returnedStoredData, int * service_received) { + char const * data; + + data = buffer_get_buffer(returnedStoredData); + + ck_assert(*service_received < 7); + if (pico_data[*service_received] != NULL) { + ck_assert_str_eq(data, pico_data[*service_received]); + } + else { + ck_assert_str_eq(data, ""); + } + (*service_received)++; +} + + void push_event(Queue* queue, Event event) { bool isService = event.service != NULL; bool isPico = event.pico != NULL; @@ -338,7 +412,7 @@ START_TEST (fsm_fsm_test) { fsmservice_set_outbound_extra_data(serv, NULL); } } - + if (state == FSMSERVICESTATE_SERVICEREAUTH) { if (cyclesService == 4) { ck_assert_str_eq(buffer_get_buffer(fsmservice_get_received_extra_data(serv)), "Extra reply"); @@ -545,7 +619,6 @@ START_TEST (fsm_pico_test) { global_data_len = -1; pthread_mutex_unlock(&global_data_mutex); sem_post(&read_semaphore); - } } } @@ -626,7 +699,19 @@ START_TEST (fsm_service_test) { sem_t read_semaphore; sem_t authenticated_semaphore; sem_t stop_semaphore; + Buffer * extraData; + Buffer * returnedStoredData; + int service_sent; + int service_received; + + extraData = buffer_new(0); + returnedStoredData = buffer_new(0); + service_sent = 0; + service_received = 0; + //pico_sent = 0; + //pico_received = 0; + char global_data[1024]; int global_data_len = 0; pthread_mutex_t global_data_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -717,6 +802,10 @@ START_TEST (fsm_service_test) { } void serviceStatusUpdate(int state, void * user_data) { + Buffer * extraData; + Buffer const * extraDataOrNull; + extraData = buffer_new(0); + if (state == FSMSERVICESTATE_PICOREAUTH) { cycles++; if (cycles > 3) { @@ -724,6 +813,17 @@ START_TEST (fsm_service_test) { sem_post(&stop_semaphore); } } + + if (state == FSMSERVICESTATE_SERVICEREAUTH) { + extraDataOrNull = service_update_extradata(extraData, & service_sent); + fsmservice_set_outbound_extra_data(serv, extraDataOrNull); + } + + if (state == FSMSERVICESTATE_SERVICEREAUTH) { + ck_assert_str_eq(buffer_get_buffer(fsmservice_get_received_extra_data(serv)), "LESS!!"); + } + + buffer_delete(extraData); } fsmservice_set_functions(serv, serviceWrite, serviceSetTimeout, NULL, NULL, serviceDisconnect, serviceAuthenticated, NULL, serviceStatusUpdate); @@ -736,31 +836,35 @@ START_TEST (fsm_service_test) { RVPChannel * channel = channel_new(); channel_set_functions(channel, NULL, channelOpen, channelClose, channelWrite, channelRead, NULL, NULL, NULL); - Buffer * returnedExtraData = buffer_new(0); channel_open(channel); - bool result = sigmaprover(picoShared, channel, picoExtraData, returnedExtraData); + bool result = sigmaprover(picoShared, channel, picoExtraData, returnedStoredData); ck_assert(result); - + sem_wait(&authenticated_semaphore); ck_assert(calledAuthenticated); - ck_assert(!strcmp(buffer_get_buffer(returnedExtraData), "SERVICE EXTRA")); Continuous * continuous = continuous_new(); continuous_set_channel(continuous, channel); continuous_set_shared_key(continuous, shared_get_shared_key(servShared)); - result = continuous_cycle_start_pico(continuous, NULL, NULL); + buffer_clear(extraData); + buffer_append_string(extraData, "LESS!!"); + result = continuous_cycle_start_pico(continuous, extraData, returnedStoredData); ck_assert(result); + pico_check_extradata(returnedStoredData, & service_received); int timeout = 0; - result = continuous_reauth_pico(continuous, NULL, &timeout, NULL); + result = continuous_reauth_pico(continuous, extraData, returnedStoredData, &timeout); ck_assert(result); + pico_check_extradata(returnedStoredData, & service_received); - result = continuous_reauth_pico(continuous, NULL, &timeout, NULL); + result = continuous_reauth_pico(continuous, extraData, returnedStoredData, &timeout); ck_assert(result); + pico_check_extradata(returnedStoredData, & service_received); - result = continuous_reauth_pico(continuous, NULL, &timeout, NULL); + result = continuous_reauth_pico(continuous, extraData, returnedStoredData, &timeout); ck_assert(result); + pico_check_extradata(returnedStoredData, & service_received); // Wait for the other thread to complete the cycles before stopping the loop sem_wait(&stop_semaphore); @@ -775,7 +879,6 @@ START_TEST (fsm_service_test) { ck_assert_int_eq(cycles, 4); - buffer_delete(returnedExtraData); channel_delete(channel); fsmservice_delete(serv); @@ -784,6 +887,9 @@ START_TEST (fsm_service_test) { buffer_delete(picoExtraData); users_delete(users); buffer_delete(symmetricKey); + + buffer_delete(extraData); + buffer_delete(returnedStoredData); } END_TEST From db383c41ebad01577847508a377bc8dceb25dbcc Mon Sep 17 00:00:00 2001 From: David Llewellyn-Jones Date: Fri, 16 Feb 2018 18:58:08 +0000 Subject: [PATCH 13/15] Fix intermittent test failure; add pico->service extradata check --- tests/test_fsm.c | 74 ++++++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/tests/test_fsm.c b/tests/test_fsm.c index b57f355..475f6fd 100644 --- a/tests/test_fsm.c +++ b/tests/test_fsm.c @@ -43,6 +43,11 @@ #include // Defines + +#define CONT_CYCLE_MAX (3) + +// Structure definitions + typedef enum { READ, CONNECTED, @@ -54,7 +59,6 @@ typedef enum { STOP_LOOP } EVENT_TYPE; -// Structure definitions typedef struct { EVENT_TYPE type; FsmService* service; @@ -84,8 +88,6 @@ pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER; // Function definitions static char const * const pico_data[] = {"one", "two", NULL, "four", NULL, "six", "seven"}; static char const * const service_data[] = {"ten", "eleven", NULL, NULL, "fourteen", "fifteen", "sixteen"}; -//static int pico_sent; -//static int pico_received; Buffer const * pico_update_extradata(Buffer * extraData, int * pico_sent) { Buffer const * extraDataOrNull; @@ -575,11 +577,13 @@ START_TEST (fsm_pico_test) { } void picoWrite(char const * data, size_t length, void * user_data) { - pthread_mutex_lock(&global_data_mutex); - memcpy(global_data, data, length); - global_data_len = length; - pthread_mutex_unlock(&global_data_mutex); - sem_post(&read_semaphore); + if (cycles <= CONT_CYCLE_MAX) { + pthread_mutex_lock(&global_data_mutex); + memcpy(global_data, data, length); + global_data_len = length; + pthread_mutex_unlock(&global_data_mutex); + sem_post(&read_semaphore); + } } int expectedTimeouts[] = { @@ -612,7 +616,7 @@ START_TEST (fsm_pico_test) { void picoStatusUpdate(FSMPICOSTATE state, void * user_data) { if (state == FSMPICOSTATE_PICOREAUTH) { cycles++; - if (cycles > 3) { + if (cycles > CONT_CYCLE_MAX) { push_stop(&queue, pico, NULL, currentTime); pthread_mutex_lock(&global_data_mutex); @@ -667,7 +671,7 @@ START_TEST (fsm_pico_test) { result = continuous_continue(continuous, NULL, NULL); ck_assert(!result); - ck_assert(cycles == 4); + ck_assert(cycles == (CONT_CYCLE_MAX + 1)); Event e; e.type = STOP_LOOP; @@ -701,16 +705,19 @@ START_TEST (fsm_service_test) { sem_t stop_semaphore; Buffer * extraData; Buffer * returnedStoredData; + Buffer const * extraDataOrNull; int service_sent; int service_received; + int pico_sent; + int pico_received; extraData = buffer_new(0); returnedStoredData = buffer_new(0); service_sent = 0; service_received = 0; - //pico_sent = 0; - //pico_received = 0; + pico_sent = 0; + pico_received = 0; char global_data[1024]; int global_data_len = 0; @@ -771,13 +778,15 @@ START_TEST (fsm_service_test) { pthread_mutex_unlock(&global_data_mutex); return ret; } - + void serviceWrite(char const * data, size_t length, void * user_data) { - pthread_mutex_lock(&global_data_mutex); - memcpy(global_data, data, length); - global_data_len = length; - pthread_mutex_unlock(&global_data_mutex); - sem_post(&read_semaphore); + if (cycles <= CONT_CYCLE_MAX) { + pthread_mutex_lock(&global_data_mutex); + memcpy(global_data, data, length); + global_data_len = length; + pthread_mutex_unlock(&global_data_mutex); + sem_post(&read_semaphore); + } } void serviceSetTimeout(int timeout, void * user_data) { @@ -808,7 +817,7 @@ START_TEST (fsm_service_test) { if (state == FSMSERVICESTATE_PICOREAUTH) { cycles++; - if (cycles > 3) { + if (cycles > CONT_CYCLE_MAX) { push_stop(&queue, NULL, serv, currentTime); sem_post(&stop_semaphore); } @@ -820,7 +829,7 @@ START_TEST (fsm_service_test) { } if (state == FSMSERVICESTATE_SERVICEREAUTH) { - ck_assert_str_eq(buffer_get_buffer(fsmservice_get_received_extra_data(serv)), "LESS!!"); + service_check_extradata(fsmservice_get_received_extra_data(serv), & service_received); } buffer_delete(extraData); @@ -847,24 +856,27 @@ START_TEST (fsm_service_test) { continuous_set_channel(continuous, channel); continuous_set_shared_key(continuous, shared_get_shared_key(servShared)); - buffer_clear(extraData); - buffer_append_string(extraData, "LESS!!"); - result = continuous_cycle_start_pico(continuous, extraData, returnedStoredData); + + extraDataOrNull = pico_update_extradata(extraData, & pico_sent); + result = continuous_cycle_start_pico(continuous, extraDataOrNull, returnedStoredData); ck_assert(result); - pico_check_extradata(returnedStoredData, & service_received); + pico_check_extradata(returnedStoredData, & pico_received); int timeout = 0; - result = continuous_reauth_pico(continuous, extraData, returnedStoredData, &timeout); + extraDataOrNull = pico_update_extradata(extraData, & pico_sent); + result = continuous_reauth_pico(continuous, extraDataOrNull, returnedStoredData, &timeout); ck_assert(result); - pico_check_extradata(returnedStoredData, & service_received); + pico_check_extradata(returnedStoredData, & pico_received); - result = continuous_reauth_pico(continuous, extraData, returnedStoredData, &timeout); + extraDataOrNull = pico_update_extradata(extraData, & pico_sent); + result = continuous_reauth_pico(continuous, extraDataOrNull, returnedStoredData, &timeout); ck_assert(result); - pico_check_extradata(returnedStoredData, & service_received); + pico_check_extradata(returnedStoredData, & pico_received); - result = continuous_reauth_pico(continuous, extraData, returnedStoredData, &timeout); + extraDataOrNull = pico_update_extradata(extraData, & pico_sent); + result = continuous_reauth_pico(continuous, extraDataOrNull, returnedStoredData, &timeout); ck_assert(result); - pico_check_extradata(returnedStoredData, & service_received); + pico_check_extradata(returnedStoredData, & pico_received); // Wait for the other thread to complete the cycles before stopping the loop sem_wait(&stop_semaphore); @@ -877,7 +889,7 @@ START_TEST (fsm_service_test) { push_event(&queue, e); pthread_join(prover_td, NULL); - ck_assert_int_eq(cycles, 4); + ck_assert_int_eq(cycles, (CONT_CYCLE_MAX + 1)); channel_delete(channel); From b721edbe8fc82c08da8f7f90d8e7109e10c372c9 Mon Sep 17 00:00:00 2001 From: David Llewellyn-Jones Date: Fri, 16 Feb 2018 20:49:15 +0000 Subject: [PATCH 14/15] Fix bug preventing Pico sending extradata during continuous --- src/fsmpico.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/fsmpico.c b/src/fsmpico.c index 2c2c2ad..5b4919e 100644 --- a/src/fsmpico.c +++ b/src/fsmpico.c @@ -376,13 +376,11 @@ void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length) { int timeout; Buffer * message; Buffer * dataread; - Buffer * extraDataToSend; char status; message = buffer_new(0); dataread = buffer_new(length); buffer_append(dataread, data, length); - extraDataToSend = buffer_new(0); // TODO: If the reads fail, should move to an error state switch (fsmpico->state) { @@ -402,7 +400,7 @@ void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length) { if (result) { fsmpico->comms->authenticated((int) status, fsmpico->user_data); fsmpico->comms->disconnect(fsmpico->user_data); - + switch (status) { case MESSAGESTATUS_OK_DONE: stateTransition(fsmpico, FSMPICOSTATE_FIN); @@ -423,7 +421,7 @@ void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length) { stateTransition(fsmpico, FSMPICOSTATE_PICOREAUTH); fsmpico->reauthDelay = timeout; // reply with the PicoReauth message - createMessagePicoReauth(fsmpico, message, extraDataToSend); + createMessagePicoReauth(fsmpico, message, fsmpico->extraData); fsmpico->comms->write(buffer_get_buffer(message), buffer_get_pos(message), fsmpico->user_data); stateTransition(fsmpico, FSMPICOSTATE_SERVICEREAUTH); // set a timeout for awaiting a response @@ -447,7 +445,6 @@ void fsmpico_read(FsmPico * fsmpico, char const * data, size_t length) { buffer_delete(message); buffer_delete(dataread); - buffer_delete(extraDataToSend); } /** @@ -562,7 +559,7 @@ void fsmpico_timeout(FsmPico * fsmpico) { * of the following two events: * * 1. FSMPICOSTATE_STATUS - * 2. FSMPICOSTATE_SERVICEREAUTH + * 2. FSMPICOSTATE_PICOREAUTH * * Then make a call using this function to check whether any new data * has arrived (in which case, the returned buffer will be non-empty). @@ -582,7 +579,7 @@ Buffer const * fsmpico_get_received_extra_data(FsmPico * fsmpico) { * update notifcation is triggered for either of the following events: * * 1. FSMPICOSTATE_STATUS - * 2. FSMPICOSTATE_SERVICEREAUTH + * 2. FSMPICOSTATE_PICOREAUTH * * These two events are those that immediately proceed the arrival of a * Status or ServiceReauth message. From b86a47692999f7904853b7a1ff0be2618779390c Mon Sep 17 00:00:00 2001 From: David Llewellyn-Jones Date: Fri, 16 Feb 2018 20:49:59 +0000 Subject: [PATCH 15/15] Add extradata sending to FSM tests --- tests/test_fsm.c | 70 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 12 deletions(-) diff --git a/tests/test_fsm.c b/tests/test_fsm.c index 475f6fd..85d7773 100644 --- a/tests/test_fsm.c +++ b/tests/test_fsm.c @@ -103,6 +103,8 @@ Buffer const * pico_update_extradata(Buffer * extraData, int * pico_sent) { } (*pico_sent)++; + //fprintf(stderr, "Pico sending: %s\n", ((extraDataOrNull != NULL )? buffer_get_buffer(extraDataOrNull) : "NULL")); + return extraDataOrNull; } @@ -111,7 +113,7 @@ void pico_check_extradata(Buffer const * returnedStoredData, int * pico_received data = buffer_get_buffer(returnedStoredData); - fprintf(stderr, "Received: %s, expected: %s\n", data, ((service_data[*pico_received] != NULL )? service_data[*pico_received] : "NULL")); + //fprintf(stderr, "Pico received: %s, expected: %s\n", data, ((service_data[*pico_received] != NULL )? service_data[*pico_received] : "NULL")); ck_assert(*pico_received < 7); if (service_data[*pico_received] != NULL) { @@ -137,7 +139,7 @@ Buffer const * service_update_extradata(Buffer * extraData, int * service_sent) } (*service_sent)++; - fprintf(stderr, "Sending: %s\n", ((extraDataOrNull != NULL )? buffer_get_buffer(extraDataOrNull) : "NULL")); + //fprintf(stderr, "Service sending: %s\n", ((extraDataOrNull != NULL )? buffer_get_buffer(extraDataOrNull) : "NULL")); return extraDataOrNull; } @@ -147,6 +149,8 @@ void service_check_extradata(Buffer const * returnedStoredData, int * service_re data = buffer_get_buffer(returnedStoredData); + //fprintf(stderr, "Service received: %s, expected: %s\n", data, ((pico_data[*service_received] != NULL )? pico_data[*service_received] : "NULL")); + ck_assert(*service_received < 7); if (pico_data[*service_received] != NULL) { ck_assert_str_eq(data, pico_data[*service_received]); @@ -385,7 +389,7 @@ START_TEST (fsm_fsm_test) { push_stop(&queue, pico, NULL, currentTime); } } - if (state == FSMPICOSTATE_SERVICEREAUTH && !sendingReply) { + if (state == FSMPICOSTATE_PICOREAUTH && !sendingReply) { if (cycles == 2) { sendingReply = true; ck_assert_str_eq(buffer_get_buffer(fsmpico_get_received_extra_data(pico)), "EXTRA!!"); @@ -416,7 +420,7 @@ START_TEST (fsm_fsm_test) { } if (state == FSMSERVICESTATE_SERVICEREAUTH) { - if (cyclesService == 4) { + if (cyclesService == 3) { ck_assert_str_eq(buffer_get_buffer(fsmservice_get_received_extra_data(serv)), "Extra reply"); } else { ck_assert_str_eq(buffer_get_buffer(fsmservice_get_received_extra_data(serv)), ""); @@ -515,7 +519,22 @@ START_TEST (fsm_pico_test) { currentTime = 0; sem_t read_semaphore; sem_t connect_semaphore; - + Buffer * extraData; + Buffer * returnedStoredData; + Buffer const * extraDataOrNull; + int service_sent; + int service_received; + int pico_sent; + int pico_received; + + extraData = buffer_new(0); + returnedStoredData = buffer_new(0); + + service_sent = 0; + service_received = 0; + pico_sent = 0; + pico_received = 0; + char global_data[1024]; int global_data_len = 0; pthread_mutex_t global_data_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -601,7 +620,6 @@ START_TEST (fsm_pico_test) { void picoSetTimeout(int timeout, void * user_data) { static int i = 0; - fprintf(stderr, "Timeout: %d, expected: %d\n", timeout, expectedTimeouts[i]); ck_assert_int_eq(expectedTimeouts[i++], timeout); push_timeout(&queue, pico, NULL, currentTime, timeout); } @@ -614,6 +632,10 @@ START_TEST (fsm_pico_test) { } void picoStatusUpdate(FSMPICOSTATE state, void * user_data) { + Buffer * extraData; + Buffer const * extraDataOrNull; + extraData = buffer_new(0); + if (state == FSMPICOSTATE_PICOREAUTH) { cycles++; if (cycles > CONT_CYCLE_MAX) { @@ -625,6 +647,17 @@ START_TEST (fsm_pico_test) { sem_post(&read_semaphore); } } + + if ((state == FSMPICOSTATE_PICOREAUTH) || (state == FSMPICOSTATE_STATUS)) { + extraDataOrNull = pico_update_extradata(extraData, & pico_sent); + fsmpico_set_outbound_extra_data(pico, extraDataOrNull); + } + + if (state == FSMPICOSTATE_PICOREAUTH) { + pico_check_extradata(fsmpico_get_received_extra_data(pico), & pico_received); + } + + buffer_delete(extraData); } fsmpico_set_functions(pico, picoWrite, picoSetTimeout, NULL, picoReconnect, picoDisconnect, NULL, NULL, picoStatusUpdate); @@ -655,21 +688,31 @@ START_TEST (fsm_pico_test) { Continuous * continuous = continuous_new(); continuous_set_channel(continuous, channel); continuous_set_shared_key(continuous, shared_get_shared_key(servShared)); - - result = continuous_cycle_start(continuous, NULL, NULL); + + extraDataOrNull = service_update_extradata(extraData, & service_sent); + result = continuous_cycle_start(continuous, extraDataOrNull, returnedStoredData); ck_assert(result); + service_check_extradata(returnedStoredData, & service_received); - result = continuous_continue(continuous, NULL, NULL); + extraDataOrNull = service_update_extradata(extraData, & service_sent); + result = continuous_continue(continuous, extraDataOrNull, returnedStoredData); ck_assert(result); + service_check_extradata(returnedStoredData, & service_received); - result = continuous_continue(continuous, NULL, NULL); + extraDataOrNull = service_update_extradata(extraData, & service_sent); + result = continuous_continue(continuous, extraDataOrNull, returnedStoredData); ck_assert(result); + //service_check_extradata(returnedStoredData, & service_received); - result = continuous_continue(continuous, NULL, NULL); + extraDataOrNull = service_update_extradata(extraData, & service_sent); + result = continuous_continue(continuous, extraDataOrNull, returnedStoredData); ck_assert(result); + //service_check_extradata(returnedStoredData, & service_received); - result = continuous_continue(continuous, NULL, NULL); + extraDataOrNull = service_update_extradata(extraData, & service_sent); + result = continuous_continue(continuous, extraDataOrNull, returnedStoredData); ck_assert(!result); + //service_check_extradata(returnedStoredData, & service_received); ck_assert(cycles == (CONT_CYCLE_MAX + 1)); @@ -693,6 +736,9 @@ START_TEST (fsm_pico_test) { buffer_delete(picoIdDer); users_delete(users); buffer_delete(symmetricKey); + + buffer_delete(extraData); + buffer_delete(returnedStoredData); } END_TEST