ENGINE-140: merged
authorEdouard Tisserant <edouard@pep-project.org>
Thu, 10 Nov 2016 21:10:24 +0100
changeset 1370274b7141afb6
parent 1365 9e45d9a7583b
parent 1369 9df1ba0ecf18
child 1381 f84211f27e5b
ENGINE-140: merged
src/keymanagement.c
src/keymanagement.h
src/pEpEngine.c
src/pEpEngine.h
src/pEp_internal.h
src/sync_impl.c
     1.1 --- a/src/keymanagement.c	Wed Nov 09 15:28:45 2016 +0100
     1.2 +++ b/src/keymanagement.c	Thu Nov 10 21:10:24 2016 +0100
     1.3 @@ -442,6 +442,8 @@
     1.4          }
     1.5  
     1.6          identity->flags = stored_identity->flags;
     1.7 +
     1.8 +        free_identity(stored_identity);
     1.9      }
    1.10      else if (!EMPTYSTR(identity->fpr))
    1.11      {
    1.12 @@ -848,3 +850,68 @@
    1.13      return status;
    1.14  }
    1.15  
    1.16 +DYNAMIC_API PEP_STATUS keys_retrieve_by_flag(
    1.17 +        PEP_SESSION session,
    1.18 +        keypair_flags_t flags,
    1.19 +        stringlist_t **keylist
    1.20 +      )
    1.21 +{
    1.22 +    PEP_STATUS status = PEP_STATUS_OK;
    1.23 +    
    1.24 +    assert(session && keylist);
    1.25 +    if (!(session && keylist))
    1.26 +        return PEP_ILLEGAL_VALUE;
    1.27 +    
    1.28 +    *keylist = NULL;
    1.29 +    stringlist_t *_keylist = NULL;
    1.30 +    
    1.31 +    sqlite3_reset(session->keys_retrieve_by_flag);
    1.32 +    sqlite3_bind_int(session->keys_retrieve_by_flag, 1, flags);
    1.33 +    
    1.34 +    int result;
    1.35 +    char *fpr = NULL;
    1.36 +    
    1.37 +    stringlist_t *_bl = _keylist;
    1.38 +    do {
    1.39 +        result = sqlite3_step(session->keys_retrieve_by_flag);
    1.40 +        switch (result) {
    1.41 +            case SQLITE_ROW:
    1.42 +                fpr = strdup((const char *) sqlite3_column_text(session->keys_retrieve_by_flag, 0));
    1.43 +                if(fpr == NULL)
    1.44 +                    goto enomem;
    1.45 +
    1.46 +                _bl = stringlist_add(_bl, fpr);
    1.47 +                if (_bl == NULL) {
    1.48 +                    free(fpr);
    1.49 +                    goto enomem;
    1.50 +                }
    1.51 +                if (_keylist == NULL)
    1.52 +                    _keylist = _bl;
    1.53 +                
    1.54 +                break;
    1.55 +                
    1.56 +            case SQLITE_DONE:
    1.57 +                break;
    1.58 +                
    1.59 +            default:
    1.60 +                status = PEP_UNKNOWN_ERROR;
    1.61 +                result = SQLITE_DONE;
    1.62 +        }
    1.63 +    } while (result != SQLITE_DONE);
    1.64 +    
    1.65 +    sqlite3_reset(session->keys_retrieve_by_flag);
    1.66 +    if (status == PEP_STATUS_OK)
    1.67 +        *keylist = _keylist;
    1.68 +    else
    1.69 +        free_stringlist(_keylist);
    1.70 +    
    1.71 +    goto the_end;
    1.72 +    
    1.73 +enomem:
    1.74 +    free_stringlist(_keylist);
    1.75 +    status = PEP_OUT_OF_MEMORY;
    1.76 +    
    1.77 +the_end:
    1.78 +    return status;
    1.79 +}
    1.80 +
     2.1 --- a/src/keymanagement.h	Wed Nov 09 15:28:45 2016 +0100
     2.2 +++ b/src/keymanagement.h	Thu Nov 10 21:10:24 2016 +0100
     2.3 @@ -189,6 +189,21 @@
     2.4          identity_list **own_identities
     2.5      );
     2.6  
     2.7 +// keys_retrieve_by_flag() - retrieve all flagged keypair fingerprints 
     2.8 +//
     2.9 +//  parameters:
    2.10 +//      session (in)            session to use
    2.11 +//      flags                   flags to compare pgp keypair's flags to
    2.12 +//      keylist (out)           list of fingerprints
    2.13 +//
    2.14 +//  caveat:
    2.15 +//      the ownership of the list goes to the caller
    2.16 +DYNAMIC_API PEP_STATUS keys_retrieve_by_flag(
    2.17 +        PEP_SESSION session,
    2.18 +        keypair_flags_t flags,
    2.19 +        stringlist_t **keylist
    2.20 +      );
    2.21 +
    2.22  #ifdef __cplusplus
    2.23  }
    2.24  #endif
     3.1 --- a/src/message_api.c	Wed Nov 09 15:28:45 2016 +0100
     3.2 +++ b/src/message_api.c	Thu Nov 10 21:10:24 2016 +0100
     3.3 @@ -1410,13 +1410,13 @@
     3.4                  remove_attached_keys(src);
     3.5              if(session->inject_sync_msg){
     3.6                  status = receive_DeviceState_msg(session, src, *rating, *keylist);
     3.7 -                if (status == PEP_MESSAGE_CONSUMED || 
     3.8 -                    status == PEP_MESSAGE_DISCARDED) {
     3.9 +                if (status == PEP_MESSAGE_CONSUME || 
    3.10 +                    status == PEP_MESSAGE_IGNORE) {
    3.11                      free_message(msg);
    3.12                      msg = NULL;
    3.13 -                    *flags |= (status == PEP_MESSAGE_DISCARDED) ?
    3.14 -                                PEP_decrypt_flag_discarded :
    3.15 -                                PEP_decrypt_flag_consumed;
    3.16 +                    *flags |= (status == PEP_MESSAGE_IGNORE) ?
    3.17 +                                PEP_decrypt_flag_ignore :
    3.18 +                                PEP_decrypt_flag_consume;
    3.19                  }
    3.20                  else if (status != PEP_STATUS_OK) {
    3.21                      return status;
    3.22 @@ -1697,13 +1697,13 @@
    3.23              remove_attached_keys(msg);
    3.24          if (*rating >= PEP_rating_reliable && session->inject_sync_msg) {
    3.25              status = receive_DeviceState_msg(session, msg, *rating, _keylist);
    3.26 -            if (status == PEP_MESSAGE_CONSUMED || 
    3.27 -                status == PEP_MESSAGE_DISCARDED) {
    3.28 +            if (status == PEP_MESSAGE_CONSUME || 
    3.29 +                status == PEP_MESSAGE_IGNORE) {
    3.30                  free_message(msg);
    3.31                  msg = NULL;
    3.32 -                *flags |= (status == PEP_MESSAGE_DISCARDED) ?
    3.33 -                            PEP_decrypt_flag_discarded :
    3.34 -                            PEP_decrypt_flag_consumed;
    3.35 +                *flags |= (status == PEP_MESSAGE_IGNORE) ?
    3.36 +                            PEP_decrypt_flag_ignore :
    3.37 +                            PEP_decrypt_flag_consume;
    3.38  
    3.39                  status = decrypt_status;
    3.40              }
     4.1 --- a/src/message_api.h	Wed Nov 09 15:28:45 2016 +0100
     4.2 +++ b/src/message_api.h	Thu Nov 10 21:10:24 2016 +0100
     4.3 @@ -158,8 +158,8 @@
     4.4  
     4.5  typedef enum _PEP_decrypt_flags {
     4.6      PEP_decrypt_flag_own_private_key = 0x1,
     4.7 -    PEP_decrypt_flag_consumed = 0x2,
     4.8 -    PEP_decrypt_flag_discarded = 0x4
     4.9 +    PEP_decrypt_flag_consume = 0x2,
    4.10 +    PEP_decrypt_flag_ignore = 0x4
    4.11  } PEP_decrypt_flags; 
    4.12  
    4.13  typedef unsigned int PEP_decrypt_flags_t;
     5.1 --- a/src/pEpEngine.c	Wed Nov 09 15:28:45 2016 +0100
     5.2 +++ b/src/pEpEngine.c	Thu Nov 10 21:10:24 2016 +0100
     5.3 @@ -52,6 +52,7 @@
     5.4      // Own keys
     5.5      static const char *sql_own_key_is_listed;
     5.6      static const char *sql_own_identities_retrieve;
     5.7 +    static const char *sql_keys_retrieve_by_flag;
     5.8  
     5.9      // Sequence
    5.10      static const char *sql_sequence_value1;
    5.11 @@ -331,8 +332,8 @@
    5.12          sql_get_device_group = "select device_group from person "
    5.13                                 "where id = '" PEP_OWN_USERID "';";
    5.14  
    5.15 -        sql_set_pgp_keypair = "insert or replace into pgp_keypair (fpr) "
    5.16 -                              "values (upper(replace(?1,' ',''))) ;";
    5.17 +        sql_set_pgp_keypair = "insert or replace into pgp_keypair (fpr, flags) "
    5.18 +                              "values (upper(replace(?1,' ','')), ?2) ;";
    5.19  
    5.20          sql_set_identity = "insert or replace into identity (address, main_key_id, "
    5.21                             "user_id, flags) values (?1, upper(replace(?2,' ','')),"
    5.22 @@ -380,8 +381,7 @@
    5.23                  
    5.24          // Own keys
    5.25          
    5.26 -        sql_own_key_is_listed =
    5.27 -                                "select count(*) from ("
    5.28 +        sql_own_key_is_listed = "select count(*) from ("
    5.29                                  " select main_key_id from person "
    5.30                                  "   where main_key_id = upper(replace(?1,' ',''))"
    5.31                                  "    and id = '" PEP_OWN_USERID "' "
    5.32 @@ -390,7 +390,8 @@
    5.33                                  "   where main_key_id = upper(replace(?1,' ',''))"
    5.34                                  "    and user_id = '" PEP_OWN_USERID "' );";
    5.35  
    5.36 -        sql_own_identities_retrieve =  "select address, fpr, username, "
    5.37 +        sql_own_identities_retrieve =  
    5.38 +                            "select address, fpr, username, "
    5.39                              "   lang, identity.flags | pgp_keypair.flags"
    5.40                              "   from identity"
    5.41                              "   join person on id = identity.user_id"
    5.42 @@ -399,6 +400,10 @@
    5.43                              "       and pgp_keypair_fpr = identity.main_key_id"
    5.44                              "   where identity.user_id = '" PEP_OWN_USERID "';";
    5.45          
    5.46 +        sql_keys_retrieve_by_flag =  
    5.47 +                            "select fpr from pgp_keypair"
    5.48 +                            "  where (flags & ?1) = ?1;";
    5.49 +
    5.50          sql_sequence_value1 = "insert or replace into sequences (name, value, own) "
    5.51                                "values (?1, "
    5.52                                "(select coalesce((select value + 1 from sequences "
    5.53 @@ -526,6 +531,11 @@
    5.54              &_session->own_identities_retrieve, NULL);
    5.55      assert(int_result == SQLITE_OK);
    5.56   
    5.57 +    int_result = sqlite3_prepare_v2(_session->db, sql_keys_retrieve_by_flag,
    5.58 +            (int)strlen(sql_keys_retrieve_by_flag),
    5.59 +            &_session->keys_retrieve_by_flag, NULL);
    5.60 +    assert(int_result == SQLITE_OK);
    5.61 + 
    5.62      // Sequence
    5.63  
    5.64      int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value1,
    5.65 @@ -652,6 +662,8 @@
    5.66                  sqlite3_finalize(session->own_key_is_listed);
    5.67              if (session->own_identities_retrieve)
    5.68                  sqlite3_finalize(session->own_identities_retrieve);
    5.69 +            if (session->keys_retrieve_by_flag)
    5.70 +                sqlite3_finalize(session->keys_retrieve_by_flag);
    5.71              if (session->sequence_value1)
    5.72                  sqlite3_finalize(session->sequence_value1);
    5.73              if (session->sequence_value2)
    5.74 @@ -1124,6 +1136,9 @@
    5.75      sqlite3_reset(session->set_pgp_keypair);
    5.76      sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
    5.77              SQLITE_STATIC);
    5.78 +    sqlite3_bind_int(session->set_pgp_keypair, 2, 
    5.79 +                     strcmp(identity->user_id, PEP_OWN_USERID) == 0 ?
    5.80 +                        PEP_kpf_own_key : 0);
    5.81      result = sqlite3_step(session->set_pgp_keypair);
    5.82      sqlite3_reset(session->set_pgp_keypair);
    5.83      if (result != SQLITE_DONE) {
     6.1 --- a/src/pEpEngine.h	Wed Nov 09 15:28:45 2016 +0100
     6.2 +++ b/src/pEpEngine.h	Thu Nov 10 21:10:24 2016 +0100
     6.3 @@ -92,8 +92,8 @@
     6.4      PEP_STATEMACHINE_INHIBITED_EVENT                = 0x0986,
     6.5  
     6.6      PEP_COMMIT_FAILED                               = 0xff01,
     6.7 -    PEP_MESSAGE_CONSUMED                            = 0xff02,
     6.8 -    PEP_MESSAGE_DISCARDED                           = 0xff03,
     6.9 +    PEP_MESSAGE_CONSUME                            = 0xff02,
    6.10 +    PEP_MESSAGE_IGNORE                           = 0xff03,
    6.11  
    6.12      PEP_RECORD_NOT_FOUND                            = -6,
    6.13      PEP_CANNOT_CREATE_TEMP_FILE                     = -5,
    6.14 @@ -421,6 +421,15 @@
    6.15  
    6.16  typedef unsigned int identity_flags_t;
    6.17  
    6.18 +typedef enum _keypair_flags {
    6.19 +    // the first octet flags are app defined settings
    6.20 +
    6.21 +    // the second octet flags are calculated
    6.22 +    PEP_kpf_own_key = 512   // key (was) used for own identity
    6.23 +} keypair_flags;
    6.24 +
    6.25 +typedef unsigned int keypair_flags_t;
    6.26 +
    6.27  typedef struct _pEp_identity {
    6.28      char *address;              // C string with address UTF-8 encoded
    6.29      char *fpr;                  // C string with fingerprint UTF-8 encoded
     7.1 --- a/src/pEp_internal.h	Wed Nov 09 15:28:45 2016 +0100
     7.2 +++ b/src/pEp_internal.h	Thu Nov 10 21:10:24 2016 +0100
     7.3 @@ -120,6 +120,7 @@
     7.4      // Own keys
     7.5      sqlite3_stmt *own_key_is_listed;
     7.6      sqlite3_stmt *own_identities_retrieve;
     7.7 +    sqlite3_stmt *keys_retrieve_by_flag;
     7.8  
     7.9      // sequence value
    7.10      sqlite3_stmt *sequence_value1;
     8.1 --- a/src/sync_impl.c	Wed Nov 09 15:28:45 2016 +0100
     8.2 +++ b/src/sync_impl.c	Thu Nov 10 21:10:24 2016 +0100
     8.3 @@ -343,7 +343,8 @@
     8.4                                  goto free_all;
     8.5                              }
     8.6                              status = get_trust(session, _from);
     8.7 -                            if (_from->comm_type < PEP_ct_strong_encryption) {
     8.8 +                            if (status != PEP_STATUS_OK || _from->comm_type < PEP_ct_strong_encryption) {
     8.9 +                                status = PEP_STATUS_OK;
    8.10                                  free_identity(_from);
    8.11                                  discard = true;
    8.12                                  goto free_all;
    8.13 @@ -374,7 +375,8 @@
    8.14                                  goto free_all;
    8.15                              }
    8.16                              status = get_trust(session, _from);
    8.17 -                            if (_from->comm_type < PEP_ct_pEp) {
    8.18 +                            if (status != PEP_STATUS_OK || _from->comm_type < PEP_ct_pEp) {
    8.19 +                                status = PEP_STATUS_OK;
    8.20                                  free_identity(_from);
    8.21                                  discard = true;
    8.22                                  goto free_all;
    8.23 @@ -422,7 +424,7 @@
    8.24      }
    8.25  
    8.26      if (force_keep_msg) {
    8.27 -        return PEP_MESSAGE_DISCARDED;
    8.28 +        return PEP_MESSAGE_IGNORE;
    8.29      }
    8.30  
    8.31      if (consume && !session->keep_sync_msg) {
    8.32 @@ -432,14 +434,14 @@
    8.33                      strcasecmp(spl->value->key, "pEp-auto-consume") == 0) {
    8.34                  if (spl->value->value &&
    8.35                          strcasecmp(spl->value->value, "yes") == 0)
    8.36 -                    return PEP_MESSAGE_CONSUMED;
    8.37 +                    return PEP_MESSAGE_CONSUME;
    8.38              }
    8.39          }
    8.40 -        return PEP_MESSAGE_DISCARDED;
    8.41 +        return PEP_MESSAGE_IGNORE;
    8.42      }
    8.43  
    8.44      if(discard)
    8.45 -        return PEP_MESSAGE_DISCARDED;
    8.46 +        return PEP_MESSAGE_IGNORE;
    8.47  
    8.48      if (!session->keep_sync_msg) {
    8.49          bloblist_t *last = NULL;
    8.50 @@ -565,8 +567,8 @@
    8.51      me = NULL;
    8.52  
    8.53      if (encrypted) {
    8.54 -        if (msg->payload.present == DeviceGroup_Protocol__payload_PR_groupKeys || 
    8.55 -            msg->payload.present == DeviceGroup_Protocol__payload_PR_groupUpdate) {
    8.56 +        bool attach_own_private_keys = false;
    8.57 +        if (msg->payload.present == DeviceGroup_Protocol__payload_PR_groupKeys) {
    8.58              PEP_rating rating = PEP_rating_undefined;
    8.59              status = outgoing_message_rating(session, _message, &rating);
    8.60              if (status != PEP_STATUS_OK)
    8.61 @@ -575,19 +577,52 @@
    8.62                  status = PEP_SYNC_NO_TRUST;
    8.63                  goto error;
    8.64              }
    8.65 -            
    8.66 -            IdentityList_t *list = 
    8.67 -                msg->payload.present == 
    8.68 -                  DeviceGroup_Protocol__payload_PR_groupKeys ?
    8.69 -                  &msg->payload.choice.groupKeys.ownIdentities :
    8.70 -                  &msg->payload.choice.groupUpdate.ownIdentities;
    8.71 +            attach_own_private_keys = true;
    8.72 +        }
    8.73  
    8.74 -            for (int i=0; i<list->list.count; i++) {
    8.75 -                Identity_t *ident = list->list.array[i];
    8.76 -                char *fpr = strndup((const char *)ident->fpr.buf, ident->fpr.size);
    8.77 -                assert(fpr);
    8.78 -                if (!fpr)
    8.79 -                    goto enomem;
    8.80 +        // outgoing_message_rating doesn't work for msg->to being own identity 
    8.81 +        // we check that from and to are the same, and with good comm_type
    8.82 +        if (msg->payload.present == DeviceGroup_Protocol__payload_PR_groupUpdate) {
    8.83 +            if(_message->to != NULL && _message->to->ident != NULL && 
    8.84 +               _message->to->next == NULL && _message->from != NULL &&
    8.85 +               strcmp(_message->to->ident->address, _message->from->address) == 0 && 
    8.86 +               strcmp(_message->to->ident->user_id, PEP_OWN_USERID) == 0 && 
    8.87 +               strcmp(_message->from->user_id, PEP_OWN_USERID) == 0) 
    8.88 +            {
    8.89 +                pEp_identity *_identity = NULL;
    8.90 +                status = get_identity(session,
    8.91 +                                      _message->to->ident->address,
    8.92 +                                      _message->to->ident->user_id,
    8.93 +                                      &_identity);
    8.94 +                
    8.95 +                if (status != PEP_STATUS_OK)
    8.96 +                    goto error;
    8.97 +
    8.98 +                PEP_comm_type _comm_type = _identity->comm_type;
    8.99 +                free_identity(_identity);
   8.100 +
   8.101 +                if(_comm_type != PEP_ct_pEp)
   8.102 +                {
   8.103 +                    status = PEP_SYNC_NO_TRUST;
   8.104 +                    goto error;
   8.105 +                }
   8.106 +            }
   8.107 +            else 
   8.108 +            {
   8.109 +                status = PEP_ILLEGAL_VALUE;
   8.110 +                goto error;
   8.111 +            }
   8.112 +            attach_own_private_keys = true;
   8.113 +        }
   8.114 +
   8.115 +        if(attach_own_private_keys){
   8.116 +            stringlist_t *keylist = NULL;
   8.117 +            status = keys_retrieve_by_flag(session, PEP_kpf_own_key, &keylist);
   8.118 +            if (status != PEP_STATUS_OK)
   8.119 +                goto error;
   8.120 +
   8.121 +            for (stringlist_t *_keylist=keylist; _keylist!=NULL; _keylist=_keylist->next) {
   8.122 +                char *fpr = _keylist->value;
   8.123                  static char filename[MAX_LINELENGTH];
   8.124                  int result = snprintf(filename, MAX_LINELENGTH, "%s-sec.asc", fpr);
   8.125                  if (result < 0)
   8.126 @@ -595,7 +630,6 @@
   8.127                  char *key = NULL;
   8.128                  size_t size = 0;
   8.129                  status = export_secrect_key(session, fpr, &key, &size);
   8.130 -                free(fpr);
   8.131                  if (status != PEP_STATUS_OK)
   8.132                      goto error;
   8.133                  bloblist_t *bl = bloblist_add(_message->attachments,