KEYSYNC: adapted to new update_identity behaviour + fixed some memory leak.
authorEdouard Tisserant <edouard@pep-project.org>
Fri, 07 Oct 2016 13:55:23 +0200
changeset 12568bc2e3636021
parent 1255 1f3c6fa1a46e
child 1257 0c12d65fe859
KEYSYNC: adapted to new update_identity behaviour + fixed some memory leak.
src/sync_fsm.c
src/sync_impl.c
sync/gen_statemachine.ysl2
     1.1 --- a/src/sync_fsm.c	Fri Oct 07 11:29:56 2016 +0200
     1.2 +++ b/src/sync_fsm.c	Fri Oct 07 13:55:23 2016 +0200
     1.3 @@ -15,8 +15,10 @@
     1.4  
     1.5      switch (state) {
     1.6          case InitState:
     1.7 +            printf("State : InitState\n");
     1.8              switch (event) {
     1.9                  case Init:
    1.10 +                printf("Event : Init\n");
    1.11                      cond_result = storedGroupKeys(session);
    1.12                      if (cond_result < 0)
    1.13                          return cond_result;
    1.14 @@ -30,9 +32,11 @@
    1.15              break;
    1.16          
    1.17          case Sole:
    1.18 +            printf("State : Sole\n");
    1.19              switch (event) {
    1.20 -                case Init: break;
    1.21 +                case Init: printf("Event : Init\n"); break;
    1.22                  case KeyGen:
    1.23 +                printf("Event : KeyGen\n");
    1.24                      status = sendBeacon(session, state, NULL, NULL);
    1.25                      if (status == PEP_OUT_OF_MEMORY)
    1.26                          return (int) invalid_out_of_memory;
    1.27 @@ -40,6 +44,7 @@
    1.28                          return (int) invalid_action;
    1.29                      break;
    1.30                  case CannotDecrypt:
    1.31 +                printf("Event : CannotDecrypt\n");
    1.32                      status = sendBeacon(session, state, NULL, NULL);
    1.33                      if (status == PEP_OUT_OF_MEMORY)
    1.34                          return (int) invalid_out_of_memory;
    1.35 @@ -47,6 +52,7 @@
    1.36                          return (int) invalid_action;
    1.37                      break;
    1.38                  case Beacon:
    1.39 +                printf("Event : Beacon\n");
    1.40                      status = sendHandshakeRequest(session, state, partner, NULL);
    1.41                      if (status == PEP_OUT_OF_MEMORY)
    1.42                          return (int) invalid_out_of_memory;
    1.43 @@ -54,6 +60,7 @@
    1.44                          return (int) invalid_action;
    1.45                      break;
    1.46                  case HandshakeRequest:
    1.47 +                printf("Event : HandshakeRequest\n");
    1.48                      status = sendHandshakeRequest(session, state, partner, NULL);
    1.49                      if (status == PEP_OUT_OF_MEMORY)
    1.50                          return (int) invalid_out_of_memory;
    1.51 @@ -66,8 +73,10 @@
    1.52              break;
    1.53          
    1.54          case HandshakingSole:
    1.55 +            printf("State : HandshakingSole\n");
    1.56              switch (event) {
    1.57                  case Init:
    1.58 +                printf("Event : Init\n");
    1.59                      status = showHandshake(session, state, partner, NULL);
    1.60                      if (status == PEP_OUT_OF_MEMORY)
    1.61                          return (int) invalid_out_of_memory;
    1.62 @@ -75,6 +84,7 @@
    1.63                          return (int) invalid_action;
    1.64                      break;
    1.65                  case HandshakeRejected:
    1.66 +                printf("Event : HandshakeRejected\n");
    1.67                      status = rejectHandshake(session, state, partner, NULL);
    1.68                      if (status == PEP_OUT_OF_MEMORY)
    1.69                          return (int) invalid_out_of_memory;
    1.70 @@ -82,6 +92,7 @@
    1.71                          return (int) invalid_action;
    1.72                      return Sole;
    1.73                  case HandshakeAccepted:
    1.74 +                printf("Event : HandshakeAccepted\n");
    1.75                      status = acceptHandshake(session, state, partner, NULL);
    1.76                      if (status == PEP_OUT_OF_MEMORY)
    1.77                          return (int) invalid_out_of_memory;
    1.78 @@ -105,9 +116,11 @@
    1.79              break;
    1.80          
    1.81          case WaitForGroupKeysSole:
    1.82 +            printf("State : WaitForGroupKeysSole\n");
    1.83              switch (event) {
    1.84 -                case Init: break;
    1.85 +                case Init: printf("Event : Init\n"); break;
    1.86                  case GroupKeys:
    1.87 +                printf("Event : GroupKeys\n");
    1.88                      status = storeGroupKeys(session, state, partner, extra /*keys*/);
    1.89                      if (status == PEP_OUT_OF_MEMORY)
    1.90                          return (int) invalid_out_of_memory;
    1.91 @@ -115,8 +128,10 @@
    1.92                          return (int) invalid_action;
    1.93                      return Grouped;
    1.94                  case Cancel:
    1.95 +                printf("Event : Cancel\n");
    1.96                      return Sole;
    1.97                  case Reject:
    1.98 +                printf("Event : Reject\n");
    1.99                      status = rejectHandshake(session, state, partner, NULL);
   1.100                      if (status == PEP_OUT_OF_MEMORY)
   1.101                          return (int) invalid_out_of_memory;
   1.102 @@ -129,9 +144,11 @@
   1.103              break;
   1.104          
   1.105          case Grouped:
   1.106 +            printf("State : Grouped\n");
   1.107              switch (event) {
   1.108 -                case Init: break;
   1.109 +                case Init: printf("Event : Init\n"); break;
   1.110                  case KeyGen:
   1.111 +                printf("Event : KeyGen\n");
   1.112                      status = sendGroupKeys(session, state, NULL, NULL);
   1.113                      if (status == PEP_OUT_OF_MEMORY)
   1.114                          return (int) invalid_out_of_memory;
   1.115 @@ -139,6 +156,7 @@
   1.116                          return (int) invalid_action;
   1.117                      break;
   1.118                  case Beacon:
   1.119 +                printf("Event : Beacon\n");
   1.120                      status = sendHandshakeRequest(session, state, partner, NULL);
   1.121                      if (status == PEP_OUT_OF_MEMORY)
   1.122                          return (int) invalid_out_of_memory;
   1.123 @@ -146,6 +164,7 @@
   1.124                          return (int) invalid_action;
   1.125                      break;
   1.126                  case HandshakeRequest:
   1.127 +                printf("Event : HandshakeRequest\n");
   1.128                      status = sendHandshakeRequest(session, state, partner, NULL);
   1.129                      if (status == PEP_OUT_OF_MEMORY)
   1.130                          return (int) invalid_out_of_memory;
   1.131 @@ -153,6 +172,7 @@
   1.132                          return (int) invalid_action;
   1.133                      return HandshakingGrouped;
   1.134                  case GroupKeys:
   1.135 +                printf("Event : GroupKeys\n");
   1.136                      status = storeGroupKeys(session, state, partner, extra /*keys*/);
   1.137                      if (status == PEP_OUT_OF_MEMORY)
   1.138                          return (int) invalid_out_of_memory;
   1.139 @@ -165,8 +185,10 @@
   1.140              break;
   1.141          
   1.142          case HandshakingGrouped:
   1.143 +            printf("State : HandshakingGrouped\n");
   1.144              switch (event) {
   1.145                  case Init:
   1.146 +                printf("Event : Init\n");
   1.147                      status = showHandshake(session, state, partner, NULL);
   1.148                      if (status == PEP_OUT_OF_MEMORY)
   1.149                          return (int) invalid_out_of_memory;
   1.150 @@ -174,6 +196,7 @@
   1.151                          return (int) invalid_action;
   1.152                      break;
   1.153                  case HandshakeRejected:
   1.154 +                printf("Event : HandshakeRejected\n");
   1.155                      status = rejectHandshake(session, state, partner, NULL);
   1.156                      if (status == PEP_OUT_OF_MEMORY)
   1.157                          return (int) invalid_out_of_memory;
   1.158 @@ -181,6 +204,7 @@
   1.159                          return (int) invalid_action;
   1.160                      return Grouped;
   1.161                  case HandshakeAccepted:
   1.162 +                printf("Event : HandshakeAccepted\n");
   1.163                      status = acceptHandshake(session, state, partner, NULL);
   1.164                      if (status == PEP_OUT_OF_MEMORY)
   1.165                          return (int) invalid_out_of_memory;
     2.1 --- a/src/sync_impl.c	Fri Oct 07 11:29:56 2016 +0200
     2.2 +++ b/src/sync_impl.c	Fri Oct 07 13:55:23 2016 +0200
     2.3 @@ -60,6 +60,7 @@
     2.4                      ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
     2.5                      goto error;
     2.6                  }
     2.7 +
     2.8                  event = HandshakeRequest;
     2.9                  break;
    2.10  
    2.11 @@ -94,6 +95,45 @@
    2.12          event = sync_msg->u.event.event;
    2.13      }
    2.14  
    2.15 +    // partner identity must be explicitely added DB to later
    2.16 +    // be able to communicate securely with it.
    2.17 +    if(partner){
    2.18 +        // prevent attacks spoofing virtual user IDs 
    2.19 +        if((strncmp("TOFU_", partner->user_id, 6) == 0 &&
    2.20 +           strlen(partner->user_id) == strlen(partner->address) + 6 &&
    2.21 +           strcmp(partner->user_id + 6, partner->address)) ||
    2.22 +        // prevent attacks spoofing own IDs 
    2.23 +           (strcmp(PEP_OWN_USERID, partner->user_id) == 0)){
    2.24 +            status = PEP_SYNC_ILLEGAL_MESSAGE;
    2.25 +            goto error;
    2.26 +        }
    2.27 +
    2.28 +        // partner ID are UUID bound to session lifespan
    2.29 +        // and therefore partner identities are not supposed
    2.30 +        // to mutate over time, but just disapear.
    2.31 +        // it is then safe to accept given identity if not 
    2.32 +        // already pre-existing
    2.33 +        pEp_identity *stored_identity = NULL;
    2.34 +        status = get_identity(session,
    2.35 +                              partner->address,
    2.36 +                              partner->user_id,
    2.37 +                              &stored_identity);
    2.38 +
    2.39 +        if (!stored_identity) {
    2.40 +            // add partner to DB
    2.41 +            status = set_identity(session, partner);
    2.42 +            assert(status == PEP_STATUS_OK);
    2.43 +            if (status != PEP_STATUS_OK) {
    2.44 +                goto error;
    2.45 +            }
    2.46 +        }
    2.47 +        else if (status == PEP_STATUS_OK) {
    2.48 +            free_identity(stored_identity);
    2.49 +        } 
    2.50 +        else
    2.51 +            goto error;
    2.52 +    }
    2.53 +
    2.54      status = fsm_DeviceState_inject(session, event, partner, extra);
    2.55  
    2.56      free_identity(partner);
    2.57 @@ -202,7 +242,7 @@
    2.58                  time_t now = time(NULL);
    2.59                  if(expiry != 0 && now != 0 && expiry < now){
    2.60                      expired = true;
    2.61 -                    goto flush;
    2.62 +                    goto free_all;
    2.63                  }
    2.64  
    2.65                  int32_t value = (int32_t) msg->header.sequence;
    2.66 @@ -218,7 +258,7 @@
    2.67                                          (const char *)msg->payload.choice.handshakeRequest.partner.user_id->buf,
    2.68                                          msg->payload.choice.handshakeRequest.partner.user_id->size) != 0){
    2.69                                  discarded = true;
    2.70 -                                goto flush;
    2.71 +                                goto free_all;
    2.72                              }
    2.73                              break;
    2.74                          // accepting GroupKeys needs encryption and trust
    2.75 @@ -233,7 +273,7 @@
    2.76                                          (const char *)msg->payload.choice.groupKeys.partner.user_id->buf,
    2.77                                          msg->payload.choice.groupKeys.partner.user_id->size) != 0)){
    2.78                                  discarded = true;
    2.79 -                                goto flush;
    2.80 +                                goto free_all;
    2.81                              }
    2.82  
    2.83                              // otherwise, when group keys are sent from a 
    2.84 @@ -251,7 +291,7 @@
    2.85                                                                 src->from->username);
    2.86                              if (_from == NULL){
    2.87                                  status = PEP_OUT_OF_MEMORY;
    2.88 -                                goto flush;
    2.89 +                                goto free_all;
    2.90                              }
    2.91                              PEP_rating this_user_id_rating = PEP_rating_undefined;
    2.92                              identity_rating(session, _from, &this_user_id_rating);
    2.93 @@ -259,7 +299,7 @@
    2.94  
    2.95                              if (this_user_id_rating < PEP_rating_trusted ) {
    2.96                                  discarded = true;
    2.97 -                                goto flush;
    2.98 +                                goto free_all;
    2.99                              }
   2.100                              break;
   2.101                          default:
   2.102 @@ -271,7 +311,7 @@
   2.103                      sync_msg_t *sync_msg = malloc(sizeof(sync_msg_t));
   2.104                      if(sync_msg == NULL){
   2.105                          status = PEP_OUT_OF_MEMORY;
   2.106 -                        goto flush;
   2.107 +                        goto free_all;
   2.108                      }
   2.109                      sync_msg->is_a_message = true;
   2.110                      sync_msg->u.message = msg;
   2.111 @@ -280,17 +320,20 @@
   2.112                          if (status == PEP_SYNC_NO_INJECT_CALLBACK){
   2.113                              free(sync_msg);
   2.114                          }
   2.115 -                        goto flush;
   2.116 +                        goto free_all;
   2.117                      }
   2.118 +                    // don't message now that it is in the queue
   2.119 +                    goto free_userid;
   2.120                  }
   2.121                  else if (status == PEP_OWN_SEQUENCE) {
   2.122                      status = PEP_STATUS_OK;
   2.123                      discarded = true;
   2.124 -                    goto flush;
   2.125 +                    goto free_all;
   2.126                  }
   2.127  
   2.128 -            flush:
   2.129 +            free_all:
   2.130                  ASN_STRUCT_FREE(asn_DEF_DeviceGroup_Protocol, msg);
   2.131 +            free_userid:
   2.132                  free(user_id);
   2.133  
   2.134                  if (status != PEP_STATUS_OK)
     3.1 --- a/sync/gen_statemachine.ysl2	Fri Oct 07 11:29:56 2016 +0200
     3.2 +++ b/sync/gen_statemachine.ysl2	Fri Oct 07 13:55:23 2016 +0200
     3.3 @@ -207,8 +207,9 @@
     3.4      template "state"
     3.5      ||
     3.6      case «@name»:
     3.7 +        printf("State : «@name»\\\\n");
     3.8          switch (event) {
     3.9 -        `` if "not(event[@name='Init'])" |>> case Init: break;
    3.10 +        `` if "not(event[@name='Init'])" |>> case Init: printf("Event : Init\\\\n"); break;
    3.11          `` apply "event", 2
    3.12              default:
    3.13                  return («../@name»_state) invalid_event;
    3.14 @@ -220,6 +221,7 @@
    3.15      template "event"
    3.16      ||
    3.17      case «@name»:
    3.18 +    printf("Event : «@name»\\\\n");
    3.19      `` apply "action|transition|condition";
    3.20      `` if "name(*[position()=last()]) != 'transition'" |> break;
    3.21      ||