error handling in state machine keysync
authorVolker Birk <vb@pep.foundation>
Mon, 01 Aug 2016 12:32:04 +0200
branchkeysync
changeset 959c1c463ecf30c
parent 958 cef602982909
child 964 ef02296c41ca
error handling in state machine
src/pgp_gpg.c
src/sync_actions.c
src/sync_fsm.c
src/sync_fsm.h
sync/gen_statemachine.ysl2
     1.1 --- a/src/pgp_gpg.c	Mon Aug 01 12:03:00 2016 +0200
     1.2 +++ b/src/pgp_gpg.c	Mon Aug 01 12:32:04 2016 +0200
     1.3 @@ -1978,6 +1978,8 @@
     1.4      assert(fpr);
     1.5      assert(created);
     1.6  
     1.7 +    *created = 0;
     1.8 +
     1.9      status = find_single_key(session, fpr, &key);
    1.10      if (status != PEP_STATUS_OK)
    1.11          return status;
     2.1 --- a/src/sync_actions.c	Mon Aug 01 12:03:00 2016 +0200
     2.2 +++ b/src/sync_actions.c	Mon Aug 01 12:32:04 2016 +0200
     2.3 @@ -24,11 +24,11 @@
     2.4      return 0;
     2.5  }
     2.6  
     2.7 -bool storedGroupKeys(PEP_SESSION session)
     2.8 +int storedGroupKeys(PEP_SESSION session)
     2.9  {
    2.10      assert(session);
    2.11      if (!session)
    2.12 -        return false;
    2.13 +        return -1; // error
    2.14  
    2.15      bool gc = false;
    2.16      int int_result = sqlite3_exec(
    2.17 @@ -39,34 +39,55 @@
    2.18          NULL
    2.19      );
    2.20      assert(int_result == SQLITE_OK);
    2.21 -    return gc;
    2.22 +    if (int_result != SQLITE_OK)
    2.23 +        return -1; // error
    2.24 +
    2.25 +    if (gc)
    2.26 +        return 1;
    2.27 +    else
    2.28 +        return 0;
    2.29  }
    2.30  
    2.31 -bool keyElectionWon(PEP_SESSION session, Identity partner)
    2.32 +int keyElectionWon(PEP_SESSION session, Identity partner)
    2.33  {
    2.34      assert(session);
    2.35      assert(partner);
    2.36      if (!(session && partner))
    2.37 -        return false;
    2.38 +        return -1; // error
    2.39  
    2.40      // an already existing group always wins
    2.41  
    2.42      if (storedGroupKeys(session)) {
    2.43          assert(!(partner->flags & PEP_idf_devicegroup));
    2.44 -        return true;
    2.45 +        return 1;
    2.46      }
    2.47  
    2.48      if (partner->flags & PEP_idf_devicegroup)
    2.49 -        return false;
    2.50 +        return 0;
    2.51  
    2.52      Identity me = NULL;
    2.53      PEP_STATUS status = get_identity(session, partner->address, PEP_OWN_USERID,
    2.54              &me);
    2.55      if (status != PEP_STATUS_OK)
    2.56 -        return false;
    2.57 +        return -1; // error
    2.58  
    2.59 -    bool result = false;
    2.60 +    int result = -1; // error state has to be overwritten
    2.61  
    2.62 +    time_t own_created;
    2.63 +    time_t partners_created;
    2.64 +
    2.65 +    status = key_created(session, me->fpr, &own_created);
    2.66 +    if (status != PEP_STATUS_OK)
    2.67 +        goto the_end;
    2.68 +
    2.69 +    status = key_created(session, partner->fpr, &partners_created);
    2.70 +    if (status != PEP_STATUS_OK)
    2.71 +        goto the_end;
    2.72 +
    2.73 +    if (own_created > partners_created)
    2.74 +        result = 0;
    2.75 +    else
    2.76 +        result = 1;
    2.77  
    2.78  the_end:
    2.79      free_identity(me);
     3.1 --- a/src/sync_fsm.c	Mon Aug 01 12:03:00 2016 +0200
     3.2 +++ b/src/sync_fsm.c	Mon Aug 01 12:32:04 2016 +0200
     3.3 @@ -10,11 +10,18 @@
     3.4          void *extra
     3.5      )
     3.6  {
     3.7 +    int cond_result = -1;
     3.8 +    PEP_STATUS status = PEP_STATUS_OK;
     3.9 +
    3.10      switch (state) {
    3.11          case InitState:
    3.12              switch (event) {
    3.13                  case Init:
    3.14 -                    if (storedGroupKeys(session)) {
    3.15 +                    cond_result = storedGroupKeys(session);
    3.16 +                    assert(cond_result == 0 || cond_result == 1);
    3.17 +                    if (cond_result == -1)
    3.18 +                        return invalid_condition;
    3.19 +                    if (cond_result) {
    3.20                          return Grouped;
    3.21                      }
    3.22                      return Sole;
    3.23 @@ -26,16 +33,24 @@
    3.24          case Sole:
    3.25              switch (event) {
    3.26                  case KeyGen:
    3.27 -                    sendBeacon(session, state, NULL, NULL);
    3.28 +                    status = sendBeacon(session, state, NULL, NULL);
    3.29 +                    if (status != PEP_STATUS_OK)
    3.30 +                        return invalid_action;
    3.31                      break;
    3.32                  case CannotDecrypt:
    3.33 -                    sendBeacon(session, state, NULL, NULL);
    3.34 +                    status = sendBeacon(session, state, NULL, NULL);
    3.35 +                    if (status != PEP_STATUS_OK)
    3.36 +                        return invalid_action;
    3.37                      break;
    3.38                  case Beacon:
    3.39 -                    sendHandshakeRequest(session, state, partner, NULL);
    3.40 +                    status = sendHandshakeRequest(session, state, partner, NULL);
    3.41 +                    if (status != PEP_STATUS_OK)
    3.42 +                        return invalid_action;
    3.43                      break;
    3.44                  case HandshakeRequest:
    3.45 -                    sendHandshakeRequest(session, state, partner, NULL);
    3.46 +                    status = sendHandshakeRequest(session, state, partner, NULL);
    3.47 +                    if (status != PEP_STATUS_OK)
    3.48 +                        return invalid_action;
    3.49                      return HandshakingSole;
    3.50                  default:
    3.51                      return (DeviceState_state) invalid_event;
    3.52 @@ -45,13 +60,21 @@
    3.53          case HandshakingSole:
    3.54              switch (event) {
    3.55                  case Init:
    3.56 -                    showHandshake(session, state, partner, NULL);
    3.57 +                    status = showHandshake(session, state, partner, NULL);
    3.58 +                    if (status != PEP_STATUS_OK)
    3.59 +                        return invalid_action;
    3.60                      break;
    3.61                  case HandshakeRejected:
    3.62 -                    reject(session, state, partner, NULL);
    3.63 +                    status = reject(session, state, partner, NULL);
    3.64 +                    if (status != PEP_STATUS_OK)
    3.65 +                        return invalid_action;
    3.66                      return Sole;
    3.67                  case HandshakeAccepted:
    3.68 -                    if (keyElectionWon(session, partner)) {
    3.69 +                    cond_result = keyElectionWon(session, partner);
    3.70 +                    assert(cond_result == 0 || cond_result == 1);
    3.71 +                    if (cond_result == -1)
    3.72 +                        return invalid_condition;
    3.73 +                    if (cond_result) {
    3.74                          return Grouped;
    3.75                      }
    3.76                      return WaitForGroupKeys;
    3.77 @@ -63,12 +86,16 @@
    3.78          case WaitForGroupKeys:
    3.79              switch (event) {
    3.80                  case GroupKeys:
    3.81 -                    storeGroupKeys(session, state, partner, NULL);
    3.82 +                    status = storeGroupKeys(session, state, partner, NULL);
    3.83 +                    if (status != PEP_STATUS_OK)
    3.84 +                        return invalid_action;
    3.85                      return Grouped;
    3.86                  case Cancel:
    3.87                      return Sole;
    3.88                  case Reject:
    3.89 -                    reject(session, state, partner, NULL);
    3.90 +                    status = reject(session, state, partner, NULL);
    3.91 +                    if (status != PEP_STATUS_OK)
    3.92 +                        return invalid_action;
    3.93                      return Sole;
    3.94                  default:
    3.95                      return (DeviceState_state) invalid_event;
    3.96 @@ -78,19 +105,29 @@
    3.97          case Grouped:
    3.98              switch (event) {
    3.99                  case KeyGen:
   3.100 -                    sendGroupKeys(session, state, NULL, NULL);
   3.101 +                    status = sendGroupKeys(session, state, NULL, NULL);
   3.102 +                    if (status != PEP_STATUS_OK)
   3.103 +                        return invalid_action;
   3.104                      break;
   3.105                  case HandshakeRequest:
   3.106 -                    sendHandshakeRequest(session, state, partner, NULL);
   3.107 -                    showHandshake(session, state, partner, NULL);
   3.108 +                    status = sendHandshakeRequest(session, state, partner, NULL);
   3.109 +                    if (status != PEP_STATUS_OK)
   3.110 +                        return invalid_action;
   3.111 +                    status = showHandshake(session, state, partner, NULL);
   3.112 +                    if (status != PEP_STATUS_OK)
   3.113 +                        return invalid_action;
   3.114                      break;
   3.115                  case HandshakeRejected:
   3.116 -                    reject(session, state, partner, NULL);
   3.117 +                    status = reject(session, state, partner, NULL);
   3.118 +                    if (status != PEP_STATUS_OK)
   3.119 +                        return invalid_action;
   3.120                      break;
   3.121                  case Hand:
   3.122                      break;
   3.123                  case Reject:
   3.124 -                    reject(session, state, NULL, NULL);
   3.125 +                    status = reject(session, state, NULL, NULL);
   3.126 +                    if (status != PEP_STATUS_OK)
   3.127 +                        return invalid_action;
   3.128                      break;
   3.129                  default:
   3.130                      return (DeviceState_state) invalid_event;
     4.1 --- a/src/sync_fsm.h	Mon Aug 01 12:03:00 2016 +0200
     4.2 +++ b/src/sync_fsm.h	Mon Aug 01 12:32:04 2016 +0200
     4.3 @@ -20,13 +20,15 @@
     4.4  
     4.5  typedef enum _fsm_error {
     4.6      invalid_state = -2,
     4.7 -    invalid_event = -3
     4.8 +    invalid_event = -3,
     4.9 +    invalid_condition = -4,
    4.10 +    invalid_action = -5
    4.11  } fsm_error;
    4.12  
    4.13  // conditions
    4.14  
    4.15 -bool storedGroupKeys(PEP_SESSION session);
    4.16 -bool keyElectionWon(PEP_SESSION session, Identity partner);
    4.17 +int storedGroupKeys(PEP_SESSION session);
    4.18 +int keyElectionWon(PEP_SESSION session, Identity partner);
    4.19  
    4.20  // states
    4.21  
     5.1 --- a/sync/gen_statemachine.ysl2	Mon Aug 01 12:03:00 2016 +0200
     5.2 +++ b/sync/gen_statemachine.ysl2	Mon Aug 01 12:32:04 2016 +0200
     5.3 @@ -46,12 +46,14 @@
     5.4  
     5.5          typedef enum _fsm_error {
     5.6              invalid_state = -2,
     5.7 -            invalid_event = -3
     5.8 +            invalid_event = -3,
     5.9 +            invalid_condition = -4,
    5.10 +            invalid_action = -5
    5.11          } fsm_error;
    5.12  
    5.13          // conditions
    5.14  
    5.15 -        `` for "func:distinctName(condition)" | bool «@name»(PEP_SESSION session`apply "parm", 0`);
    5.16 +        `` for "func:distinctName(condition)" | int «@name»(PEP_SESSION session`apply "parm", 0`);
    5.17  
    5.18          // states
    5.19  
    5.20 @@ -148,6 +150,9 @@
    5.21                  void *extra
    5.22              )
    5.23          {
    5.24 +            int cond_result = -1;
    5.25 +            PEP_STATUS status = PEP_STATUS_OK;
    5.26 +
    5.27              switch (state) {
    5.28              `` apply "state", 2
    5.29                  default:
    5.30 @@ -181,16 +186,22 @@
    5.31  
    5.32      template "action" {
    5.33          indent(0);
    5.34 -        > «@name»(session, state, 
    5.35 +        > status = «@name»(session, state, 
    5.36          choose {
    5.37              when "parm" > «name(parm/*)»
    5.38              otherwise > NULL
    5.39          }
    5.40          > , NULL);\n
    5.41 +        | if (status != PEP_STATUS_OK)
    5.42 +        |> return invalid_action;
    5.43      }
    5.44  
    5.45      template "condition" {
    5.46 -        | if («@name»(session`apply "parm", 0`)) {
    5.47 +        | cond_result = «@name»(session`apply "parm", 0`);
    5.48 +        | assert(cond_result == 0 || cond_result == 1);
    5.49 +        | if (cond_result == -1)
    5.50 +        |> return invalid_condition;
    5.51 +        | if (cond_result) {
    5.52          apply "action|transition|condition";
    5.53          | }
    5.54      }