merge "default" into my branch :-) roker-linux
authorRoker <roker@pep-project.org>
Thu, 21 Jul 2016 17:53:04 +0200
branchroker-linux
changeset 95079244fc25166
parent 917 4d844c91fcf3
parent 942 6365f5d5f612
child 963 73886607a5a0
merge "default" into my branch :-)
     1.1 --- a/asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj	Thu Jul 21 15:16:23 2016 +0200
     1.2 +++ b/asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj	Thu Jul 21 17:53:04 2016 +0200
     1.3 @@ -60,23 +60,25 @@
     1.4        <GenerateDebugInformation>true</GenerateDebugInformation>
     1.5      </Link>
     1.6      <PreBuildEvent>
     1.7 -      <Command>
     1.8 -      </Command>
     1.9 -    </PreBuildEvent>
    1.10 -    <PreBuildEvent>
    1.11 -      <Message>ASN.1 source generation</Message>
    1.12 -    </PreBuildEvent>
    1.13 -    <CustomBuildStep>
    1.14        <Command>cd ..
    1.15  asn1c -gen-PER -fincludes-quoted -fcompound-names -pdu=PEP.Message pEp.asn1 devicegroup.asn1
    1.16  del converter-sample.c
    1.17  </Command>
    1.18 +    </PreBuildEvent>
    1.19 +    <PreBuildEvent>
    1.20 +      <Message>compiling ASN.1 description</Message>
    1.21 +    </PreBuildEvent>
    1.22 +    <CustomBuildStep>
    1.23 +      <Command>
    1.24 +      </Command>
    1.25      </CustomBuildStep>
    1.26      <CustomBuildStep>
    1.27 -      <Message>compiling ASN.1 description</Message>
    1.28 +      <Message>
    1.29 +      </Message>
    1.30      </CustomBuildStep>
    1.31      <CustomBuildStep>
    1.32 -      <Outputs>$(ProjectDir)..\DeviceGroup-Protocol.c;%(Outputs)</Outputs>
    1.33 +      <Outputs>
    1.34 +      </Outputs>
    1.35      </CustomBuildStep>
    1.36    </ItemDefinitionGroup>
    1.37    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    1.38 @@ -96,20 +98,23 @@
    1.39        <OptimizeReferences>true</OptimizeReferences>
    1.40      </Link>
    1.41      <PreBuildEvent>
    1.42 -      <Command>
    1.43 -      </Command>
    1.44 -    </PreBuildEvent>
    1.45 -    <CustomBuildStep>
    1.46        <Command>cd ..
    1.47  asn1c -gen-PER -fincludes-quoted -fcompound-names -pdu=PEP.Message pEp.asn1 devicegroup.asn1
    1.48  del converter-sample.c
    1.49  </Command>
    1.50 +      <Message>compiling ASN.1 description</Message>
    1.51 +    </PreBuildEvent>
    1.52 +    <CustomBuildStep>
    1.53 +      <Command>
    1.54 +      </Command>
    1.55      </CustomBuildStep>
    1.56      <CustomBuildStep>
    1.57 -      <Message>compiling ASN.1 description</Message>
    1.58 +      <Message>
    1.59 +      </Message>
    1.60      </CustomBuildStep>
    1.61      <CustomBuildStep>
    1.62 -      <Outputs>$(ProjectDir)..\DeviceGroup-Protocol.c;%(Outputs)</Outputs>
    1.63 +      <Outputs>
    1.64 +      </Outputs>
    1.65      </CustomBuildStep>
    1.66    </ItemDefinitionGroup>
    1.67    <ItemGroup>
     2.1 --- a/src/keymanagement.c	Thu Jul 21 15:16:23 2016 +0200
     2.2 +++ b/src/keymanagement.c	Thu Jul 21 17:53:04 2016 +0200
     2.3 @@ -134,7 +134,7 @@
     2.4          snprintf(identity->user_id, strlen(identity->address) + 5,
     2.5                   "TOFU_%s", identity->address);
     2.6      }
     2.7 -    
     2.8 + 
     2.9      status = get_identity(session,
    2.10                            identity->address,
    2.11                            identity->user_id,
    2.12 @@ -203,8 +203,12 @@
    2.13              identity->lang[1] = stored_identity->lang[1];
    2.14              identity->lang[2] = 0;
    2.15          }
    2.16 +
    2.17 +        identity->flags = stored_identity->flags;
    2.18      }
    2.19      else /* stored_identity == NULL */ {
    2.20 +        identity->flags = 0;
    2.21 +
    2.22          if (!EMPTYSTR(identity->fpr)) {
    2.23              PEP_comm_type _comm_type_key;
    2.24  
    2.25 @@ -230,6 +234,7 @@
    2.26          if (EMPTYSTR(identity->username)) { // mitigate
    2.27              free(identity->username);
    2.28              identity->username = strdup("anonymous");
    2.29 +            assert(identity->username);
    2.30              if (identity->username == NULL){
    2.31                  status = PEP_OUT_OF_MEMORY;
    2.32                  goto exit_free;
    2.33 @@ -389,6 +394,8 @@
    2.34                  return PEP_OUT_OF_MEMORY;
    2.35              }
    2.36          }
    2.37 +
    2.38 +        identity->flags = stored_identity->flags;
    2.39      }
    2.40      else if (!EMPTYSTR(identity->fpr))
    2.41      {
    2.42 @@ -396,6 +403,8 @@
    2.43          // import of private key, or similar.
    2.44  
    2.45          // Take given fpr as-is.
    2.46 +
    2.47 +        identity->flags = 0;
    2.48      }
    2.49      else
    2.50      {
    2.51 @@ -404,6 +413,8 @@
    2.52          if (status != PEP_STATUS_OK) {
    2.53              return status;
    2.54          }
    2.55 +
    2.56 +        identity->flags = 0;
    2.57      }
    2.58  
    2.59      bool revoked = false;
     3.1 --- a/src/keymanagement.h	Thu Jul 21 15:16:23 2016 +0200
     3.2 +++ b/src/keymanagement.h	Thu Jul 21 17:53:04 2016 +0200
     3.3 @@ -18,6 +18,8 @@
     3.4  //      asynchronous management implementation, so retrieve_next_identity()
     3.5  //      will return this identity later
     3.6  //      at least identity->address must be a non-empty UTF-8 string as input
     3.7 +//      update_identity() never writes flags; use set_identity_flags() for
     3.8 +//      writing
     3.9  
    3.10  DYNAMIC_API PEP_STATUS update_identity(
    3.11          PEP_SESSION session, pEp_identity * identity
    3.12 @@ -40,6 +42,7 @@
    3.13  //      it can need a decent amount of time to return
    3.14  //      if you need to do this asynchronous, you need to return an identity
    3.15  //      with retrieve_next_identity() where pEp_identity.me is true
    3.16 +//      myself() never writes flags; use set_identity_flags() for writing
    3.17  
    3.18  DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity);
    3.19  
     4.1 --- a/src/message_api.c	Thu Jul 21 15:16:23 2016 +0200
     4.2 +++ b/src/message_api.c	Thu Jul 21 17:53:04 2016 +0200
     4.3 @@ -8,6 +8,7 @@
     4.4  #include <string.h>
     4.5  #include <stdlib.h>
     4.6  
     4.7 +
     4.8  #ifndef MIN
     4.9  #define MIN(A, B) ((B) > (A) ? (A) : (B))
    4.10  #endif
    4.11 @@ -101,22 +102,21 @@
    4.12      if (longmsg == NULL)
    4.13          longmsg = "";
    4.14  
    4.15 -    size_t bufsize = strlen(shortmsg) + strlen(longmsg) + 12;
    4.16 +    const char * const subject = "Subject: ";
    4.17 +    const size_t SUBJ_LEN = 9;
    4.18 +    const char * const newlines = "\n\n";
    4.19 +    const size_t NL_LEN = 2;
    4.20 +
    4.21 +    size_t bufsize = SUBJ_LEN + strlen(shortmsg) + NL_LEN + strlen(longmsg) + 1;
    4.22      ptext = calloc(1, bufsize);
    4.23      assert(ptext);
    4.24      if (ptext == NULL)
    4.25          return NULL;
    4.26  
    4.27 -    strncpy(ptext, "Subject: ", bufsize);
    4.28 -    bufsize -= 9;
    4.29 -    
    4.30 -    strncat(ptext, shortmsg, bufsize);
    4.31 -    bufsize -= strlen(shortmsg);
    4.32 -    
    4.33 -    strncat(ptext, "\n\n", bufsize);
    4.34 -    bufsize -= 2;
    4.35 -    
    4.36 -    strncat(ptext, longmsg, bufsize);
    4.37 +    strlcpy(ptext, subject, bufsize);
    4.38 +    strlcat(ptext, shortmsg, bufsize);
    4.39 +    strlcat(ptext, newlines, bufsize);
    4.40 +    strlcat(ptext, longmsg, bufsize);
    4.41  
    4.42      return ptext;
    4.43  }
    4.44 @@ -536,8 +536,8 @@
    4.45                          if (filename == NULL)
    4.46                              goto enomem;
    4.47  
    4.48 -                        strncpy(filename, _s->filename, len);
    4.49 -                        strncpy(filename + len, ".pgp", 5);
    4.50 +                        strlcpy(filename, _s->filename, len);
    4.51 +                        strlcpy(filename + len, ".pgp", 5);
    4.52                      }
    4.53                      else {
    4.54                          filename = calloc(1, 20);
    4.55 @@ -641,7 +641,7 @@
    4.56  {
    4.57      assert(msg);
    4.58  
    4.59 -    add_opt_field(msg, "X-pEp-Version", "1.0");
    4.60 +    add_opt_field(msg, "X-pEp-Version", PEP_VERSION);
    4.61      
    4.62      if (color != PEP_rating_undefined)
    4.63          add_opt_field(msg, "X-EncStatus", color_to_string(color));
     5.1 --- a/src/pEpEngine.c	Thu Jul 21 15:16:23 2016 +0200
     5.2 +++ b/src/pEpEngine.c	Thu Jul 21 17:53:04 2016 +0200
     5.3 @@ -6,6 +6,19 @@
     5.4  
     5.5  static int init_count = -1;
     5.6  
     5.7 +static int user_version(void *_version, int count, char **text, char **name)
     5.8 +{
     5.9 +    assert(_version);
    5.10 +    assert(count == 1);
    5.11 +    assert(text && text[0]);
    5.12 +    if (!(_version && count == 1 && text && text[0]))
    5.13 +        return -1;
    5.14 +
    5.15 +    int *version = (int *) _version;
    5.16 +    *version = atoi(text[0]);
    5.17 +    return 0;
    5.18 +}
    5.19 +
    5.20  DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
    5.21  {
    5.22      PEP_STATUS status = PEP_STATUS_OK;
    5.23 @@ -16,6 +29,7 @@
    5.24      static const char *sql_set_person;
    5.25      static const char *sql_set_pgp_keypair;
    5.26      static const char *sql_set_identity;
    5.27 +    static const char *sql_set_identity_flags;
    5.28      static const char *sql_set_trust;
    5.29      static const char *sql_get_trust;
    5.30      static const char *sql_least_trust;
    5.31 @@ -112,15 +126,37 @@
    5.32  
    5.33      sqlite3_busy_timeout(_session->system_db, 1000);
    5.34  
    5.35 +// increment this when patching DDL
    5.36 +#define _DDL_USER_VERSION "1"
    5.37 +
    5.38      if (in_first) {
    5.39          int_result = sqlite3_exec(
    5.40              _session->db,
    5.41 -                "create table if not exists version_info (\n"
    5.42 +                "create table version_info (\n"
    5.43                  "   id integer primary key,\n"
    5.44                  "   timestamp integer default (datetime('now')) ,\n"
    5.45                  "   version text,\n"
    5.46                  "   comment text\n"
    5.47 -                ");\n"
    5.48 +                ");\n",
    5.49 +                NULL,
    5.50 +                NULL,
    5.51 +                NULL
    5.52 +        );
    5.53 +        if (int_result == SQLITE_OK) {
    5.54 +            int_result = sqlite3_exec(
    5.55 +                _session->db,
    5.56 +                "pragma user_version = "_DDL_USER_VERSION";\n"
    5.57 +                "insert or replace into version_info (id, version)"
    5.58 +                    "values (1, '" PEP_ENGINE_VERSION "');",
    5.59 +                NULL,
    5.60 +                NULL,
    5.61 +                NULL
    5.62 +            );
    5.63 +            assert(int_result == SQLITE_OK);
    5.64 +        }
    5.65 +
    5.66 +        int_result = sqlite3_exec(
    5.67 +            _session->db,
    5.68                  "create table if not exists log (\n"
    5.69                  "   timestamp integer default (datetime('now')) ,\n"
    5.70                  "   title text not null,\n"
    5.71 @@ -160,6 +196,7 @@
    5.72                  "       references pgp_keypair (fpr)\n"
    5.73                  "       on delete set null,\n"
    5.74                  "   comment text,\n"
    5.75 +                "   flags integer default (0),"
    5.76                  "   primary key (address, user_id)\n"
    5.77                  ");\n"
    5.78                  "create table if not exists trust (\n"
    5.79 @@ -196,19 +233,45 @@
    5.80          );
    5.81          assert(int_result == SQLITE_OK);
    5.82  
    5.83 +        int version;
    5.84          int_result = sqlite3_exec(
    5.85              _session->db,
    5.86 -            "insert or replace into version_info (id, version) values (1, '1.1');",
    5.87 -            NULL,
    5.88 -            NULL,
    5.89 +            "pragma user_version;",
    5.90 +            user_version,
    5.91 +            &version,
    5.92              NULL
    5.93          );
    5.94          assert(int_result == SQLITE_OK);
    5.95  
    5.96 +        if (version < 1) {
    5.97 +            int_result = sqlite3_exec(
    5.98 +                _session->db,
    5.99 +                "alter table identity\n"
   5.100 +                "   add column flags integer default (0);",
   5.101 +                NULL,
   5.102 +                NULL,
   5.103 +                NULL
   5.104 +            );
   5.105 +            assert(int_result == SQLITE_OK);
   5.106 +        }
   5.107 +
   5.108 +        if (version < atoi(_DDL_USER_VERSION)) {
   5.109 +            int_result = sqlite3_exec(
   5.110 +                _session->db,
   5.111 +                "pragma user_version = "_DDL_USER_VERSION";\n"
   5.112 +                "insert or replace into version_info (id, version)"
   5.113 +                    "values (1, '" PEP_ENGINE_VERSION "');",
   5.114 +                NULL,
   5.115 +                NULL,
   5.116 +                NULL
   5.117 +            );
   5.118 +            assert(int_result == SQLITE_OK);
   5.119 +        }
   5.120 +
   5.121          sql_log = "insert into log (title, entity, description, comment)"
   5.122                    "values (?1, ?2, ?3, ?4);";
   5.123  
   5.124 -        sql_get_identity =  "select fpr, username, comm_type, lang"
   5.125 +        sql_get_identity =  "select fpr, username, comm_type, lang, flags"
   5.126                              "   from identity"
   5.127                              "   join person on id = identity.user_id"
   5.128                              "   join pgp_keypair on fpr = identity.main_key_id"
   5.129 @@ -230,7 +293,11 @@
   5.130                                "values (upper(replace(?1,' ',''))) ;";
   5.131  
   5.132          sql_set_identity = "insert or replace into identity (address, main_key_id, "
   5.133 -                           "user_id) values (?1, upper(replace(?2,' ','')), ?3) ;";
   5.134 +                           "user_id, flags) values (?1, upper(replace(?2,' ','')),"
   5.135 +                           "?3, ?4) ;";
   5.136 +
   5.137 +        sql_set_identity_flags = "update identity set flags = ?1 "
   5.138 +                                 "where address = ?2 and user_id = ?3 ;";
   5.139  
   5.140          sql_set_trust = "insert or replace into trust (user_id, pgp_keypair_fpr, comm_type) "
   5.141                          "values (?1, upper(replace(?2,' ','')), ?3) ;";
   5.142 @@ -322,6 +389,10 @@
   5.143              (int)strlen(sql_set_identity), &_session->set_identity, NULL);
   5.144      assert(int_result == SQLITE_OK);
   5.145  
   5.146 +    int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_flags,
   5.147 +            (int)strlen(sql_set_identity_flags), &_session->set_identity_flags, NULL);
   5.148 +    assert(int_result == SQLITE_OK);
   5.149 +
   5.150      int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
   5.151              (int)strlen(sql_set_trust), &_session->set_trust, NULL);
   5.152      assert(int_result == SQLITE_OK);
   5.153 @@ -464,6 +535,8 @@
   5.154                  sqlite3_finalize(session->set_pgp_keypair);
   5.155              if (session->set_identity)
   5.156                  sqlite3_finalize(session->set_identity);
   5.157 +            if (session->set_identity_flags)
   5.158 +                sqlite3_finalize(session->set_identity_flags);
   5.159              if (session->set_trust)
   5.160                  sqlite3_finalize(session->set_trust);
   5.161              if (session->get_trust)
   5.162 @@ -753,6 +826,7 @@
   5.163      dup->lang[1] = src->lang[1];
   5.164      dup->lang[2] = 0;
   5.165      dup->me = src->me;
   5.166 +    dup->flags = src->flags;
   5.167  
   5.168      return dup;
   5.169  }
   5.170 @@ -815,6 +889,7 @@
   5.171              _identity->lang[1] = _lang[1];
   5.172              _identity->lang[2] = 0;
   5.173          }
   5.174 +        _identity->flags = (unsigned int) sqlite3_column_int(session->get_identity, 4);
   5.175          *identity = _identity;
   5.176          break;
   5.177      default:
   5.178 @@ -890,6 +965,7 @@
   5.179              SQLITE_STATIC);
   5.180      sqlite3_bind_text(session->set_identity, 3, identity->user_id, -1,
   5.181              SQLITE_STATIC);
   5.182 +    sqlite3_bind_int(session->set_identity, 4, identity->flags);
   5.183      result = sqlite3_step(session->set_identity);
   5.184      sqlite3_reset(session->set_identity);
   5.185      if (result != SQLITE_DONE) {
   5.186 @@ -917,6 +993,37 @@
   5.187          return PEP_COMMIT_FAILED;
   5.188  }
   5.189  
   5.190 +DYNAMIC_API PEP_STATUS set_identity_flags(
   5.191 +        PEP_SESSION session,
   5.192 +        pEp_identity *identity,
   5.193 +        unsigned int flags
   5.194 +    )
   5.195 +{
   5.196 +    int result;
   5.197 +
   5.198 +    assert(session);
   5.199 +    assert(identity);
   5.200 +    assert(identity->address);
   5.201 +    assert(identity->user_id);
   5.202 +
   5.203 +    if (!(session && identity && identity->address && identity->user_id))
   5.204 +        return PEP_ILLEGAL_VALUE;
   5.205 +
   5.206 +    sqlite3_reset(session->set_identity_flags);
   5.207 +    sqlite3_bind_int(session->set_identity_flags, 1, flags);
   5.208 +    sqlite3_bind_text(session->set_identity_flags, 2, identity->address, -1,
   5.209 +            SQLITE_STATIC);
   5.210 +    sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
   5.211 +            SQLITE_STATIC);
   5.212 +    result = sqlite3_step(session->set_identity_flags);
   5.213 +    sqlite3_reset(session->set_identity_flags);
   5.214 +    if (result != SQLITE_DONE)
   5.215 +        return PEP_CANNOT_SET_IDENTITY;
   5.216 +
   5.217 +    identity->flags = flags;
   5.218 +    return PEP_STATUS_OK;
   5.219 +}
   5.220 +
   5.221  DYNAMIC_API PEP_STATUS mark_as_compromized(
   5.222          PEP_SESSION session,
   5.223          const char *fpr
     6.1 --- a/src/pEpEngine.h	Thu Jul 21 15:16:23 2016 +0200
     6.2 +++ b/src/pEpEngine.h	Thu Jul 21 17:53:04 2016 +0200
     6.3 @@ -12,7 +12,7 @@
     6.4  #include "stringlist.h"
     6.5  #include "timestamp.h"
     6.6  
     6.7 -#define PEP_VERSION "1.0"
     6.8 +#define PEP_VERSION "1.0" // protocol version
     6.9  
    6.10  #define PEP_OWN_USERID "pEp_own_userId"
    6.11      
    6.12 @@ -379,6 +379,11 @@
    6.13      PEP_ct_pEp = 0xff
    6.14  } PEP_comm_type;
    6.15  
    6.16 +typedef enum _identity_flags {
    6.17 +    PEP_idf_not_for_sync = 1,   // don't use this identity for sync
    6.18 +    PEP_idf_group = 2           // identity of group of persons
    6.19 +} identity_flags;
    6.20 +
    6.21  typedef struct _pEp_identity {
    6.22      char *address;              // C string with address UTF-8 encoded
    6.23      char *fpr;                  // C string with fingerprint UTF-8 encoded
    6.24 @@ -388,6 +393,7 @@
    6.25      char lang[3];               // language of conversation
    6.26                                  // ISO 639-1 ALPHA-2, last byte is 0
    6.27      bool me;                    // if this is the local user herself/himself
    6.28 +    unsigned int flags;         // identity_flag1 | identity_flag2 | ...
    6.29  } pEp_identity;
    6.30  
    6.31  typedef struct _identity_list {
    6.32 @@ -405,7 +411,7 @@
    6.33  //      username (in)       UTF-8 string or NULL 
    6.34  //
    6.35  //  return value:
    6.36 -//      pEp_identity struct with correct size values or NULL if out of memory
    6.37 +//      pEp_identity struct or NULL if out of memory
    6.38  //
    6.39  //  caveat:
    6.40  //      the strings are copied; the original strings are still being owned by
    6.41 @@ -417,13 +423,13 @@
    6.42      );
    6.43  
    6.44  
    6.45 -// identity_dup() - allocate memory and set the string and size fields
    6.46 +// identity_dup() - allocate memory and duplicate
    6.47  //
    6.48  //  parameters:
    6.49  //      src (in)            identity to duplicate
    6.50  //
    6.51  //  return value:
    6.52 -//      pEp_identity struct with correct size values or NULL if out of memory
    6.53 +//      pEp_identity struct or NULL if out of memory
    6.54  //
    6.55  //  caveat:
    6.56  //      the strings are copied; the original strings are still being owned by
    6.57 @@ -480,18 +486,37 @@
    6.58  //        PEP_CANNOT_SET_PGP_KEYPAIR    writing to table pgp_keypair failed
    6.59  //        PEP_CANNOT_SET_IDENTITY       writing to table identity failed
    6.60  //        PEP_COMMIT_FAILED             SQL commit failed
    6.61 -//      PEP_KEY_BLACKLISTED             Key blacklisted, cannot set identity
    6.62 +//        PEP_KEY_BLACKLISTED           Key blacklisted, cannot set identity
    6.63  //
    6.64  //    caveat:
    6.65 -//        in the identity structure you need to set the const char * fields to
    6.66 -//        UTF-8 C strings
    6.67 -//        the size fields are ignored
    6.68 +//        address, fpr, user_id and username must be given
    6.69  
    6.70  DYNAMIC_API PEP_STATUS set_identity(
    6.71          PEP_SESSION session, const pEp_identity *identity
    6.72      );
    6.73  
    6.74  
    6.75 +// set_identity_flags() - update identity flags on existing identity
    6.76 +//
    6.77 +//    parameters:
    6.78 +//        session (in)        session handle
    6.79 +//        identity (in,out)   pointer to pEp_identity structure
    6.80 +//        flags (in)          new value for flags
    6.81 +//
    6.82 +//    return value:
    6.83 +//        PEP_STATUS_OK = 0             encryption and signing succeeded
    6.84 +//        PEP_CANNOT_SET_IDENTITY       update of identity failed
    6.85 +//
    6.86 +//    caveat:
    6.87 +//        address and user_id must be given in identity
    6.88 +
    6.89 +DYNAMIC_API PEP_STATUS set_identity_flags(
    6.90 +        PEP_SESSION session,
    6.91 +        pEp_identity *identity,
    6.92 +        unsigned int flags
    6.93 +    );
    6.94 +
    6.95 +
    6.96  // mark_as_compromized() - mark key in trust db as compromized
    6.97  //
    6.98  //    parameters:
     7.1 --- a/src/pEp_internal.h	Thu Jul 21 15:16:23 2016 +0200
     7.2 +++ b/src/pEp_internal.h	Thu Jul 21 17:53:04 2016 +0200
     7.3 @@ -1,4 +1,4 @@
     7.4 -#define PEP_ENGINE_VERSION "0.7.0"
     7.5 +#define PEP_ENGINE_VERSION "0.8.0"
     7.6  
     7.7  // maximum attachment size to import as key 1MB, maximum of 20 attachments
     7.8  
     7.9 @@ -97,6 +97,7 @@
    7.10      sqlite3_stmt *set_person;
    7.11      sqlite3_stmt *set_pgp_keypair;
    7.12      sqlite3_stmt *set_identity;
    7.13 +    sqlite3_stmt *set_identity_flags;
    7.14      sqlite3_stmt *set_trust;
    7.15      sqlite3_stmt *get_trust;
    7.16      sqlite3_stmt *least_trust;
     8.1 --- a/src/platform_unix.c	Thu Jul 21 15:16:23 2016 +0200
     8.2 +++ b/src/platform_unix.c	Thu Jul 21 17:53:04 2016 +0200
     8.3 @@ -94,6 +94,37 @@
     8.4  }
     8.5  #endif
     8.6  
     8.7 +#if !defined(BSD) && !defined(__APPLE__)
     8.8 +
     8.9 +size_t strlcpy(char* dst, const	char* src, size_t size) {
    8.10 +    size_t retval = strlen(src);
    8.11 +    size_t size_to_copy = (retval < size ? retval : size - 1);
    8.12 +    
    8.13 +    // strlcpy doc says src and dst not allowed to overlap, as
    8.14 +    // it's undefined. So this is acceptable:
    8.15 +    memcpy((void*)dst, (void*)src, size_to_copy); // no defined error return, but strcpy doesn't either
    8.16 +    dst[size_to_copy] = '\0';
    8.17 +    return retval;
    8.18 +}
    8.19 +
    8.20 +size_t strlcat(char* dst, const	char* src, size_t size) {
    8.21 +    size_t start_len = strnlen(dst, size);
    8.22 +    if (start_len == size)
    8.23 +        return size; // no copy, no null termination in size bytes, according to spec
    8.24 +    
    8.25 +    size_t add_len = strlen(src);
    8.26 +    size_t retval = start_len + add_len;
    8.27 +    size_t size_to_copy = (retval < size ? add_len : (size - start_len) - 1);
    8.28 +    
    8.29 +    // strlcat doc says src and dst not allowed to overlap, as
    8.30 +    // it's undefined. So this is acceptable:
    8.31 +    memcpy((void*)(dst + start_len), (void*)src, size_to_copy); // no defined error return, but strcpy doesn't either
    8.32 +    dst[start_len + size_to_copy] = '\0';
    8.33 +    return retval;
    8.34 +}
    8.35 +
    8.36 +#endif
    8.37 +
    8.38  const char *unix_local_db(void)
    8.39  {
    8.40      static char buffer[MAX_PATH];
     9.1 --- a/src/platform_unix.h	Thu Jul 21 15:16:23 2016 +0200
     9.2 +++ b/src/platform_unix.h	Thu Jul 21 17:53:04 2016 +0200
     9.3 @@ -1,4 +1,6 @@
     9.4 +#ifndef __APPLE__
     9.5  #define _POSIX_C_SOURCE 200809L
     9.6 +#endif
     9.7  
     9.8  #include <unistd.h>
     9.9  #include <strings.h>
    9.10 @@ -29,6 +31,7 @@
    9.11  
    9.12  #elif __APPLE__
    9.13  #include "TargetConditionals.h"
    9.14 +#include <string.h>
    9.15  #if TARGET_OS_IPHONE
    9.16  
    9.17  extern char* SystemDB;
    9.18 @@ -37,6 +40,11 @@
    9.19  #endif
    9.20  #endif
    9.21  
    9.22 +#if !defined(BSD) && !defined(__APPLE__)
    9.23 +size_t strlcpy(char* dst, const	char* src, size_t size);
    9.24 +size_t strlcat(char* dst, const	char* src, size_t size);
    9.25 +#endif
    9.26 +
    9.27  #ifdef __cplusplus
    9.28  }
    9.29  #endif
    10.1 --- a/src/platform_windows.cpp	Thu Jul 21 15:16:23 2016 +0200
    10.2 +++ b/src/platform_windows.cpp	Thu Jul 21 17:53:04 2016 +0200
    10.3 @@ -233,6 +233,32 @@
    10.4      return dst;
    10.5  }
    10.6  
    10.7 +size_t strlcpy(char* dst, const	char* src, size_t size) {
    10.8 +    size_t retval = strlen(src);
    10.9 +    size_t size_to_copy = (retval < size ? retval : size - 1);
   10.10 +    
   10.11 +    // strlcpy doc says src and dst not allowed to overlap, as
   10.12 +    // it's undefined. So this is acceptable:
   10.13 +    memcpy((void*)dst, (void*)src, size_to_copy); // no defined error return, but strcpy doesn't either
   10.14 +    dst[size_to_copy] = '\0';
   10.15 +    return retval;
   10.16 +}
   10.17 +size_t strlcat(char* dst, const	char* src, size_t size) {
   10.18 +    size_t start_len = strnlen(dst, size);
   10.19 +    if (start_len == size)
   10.20 +        return size; // no copy, no null termination in size bytes, according to spec
   10.21 +    
   10.22 +    size_t add_len = strlen(src);
   10.23 +    size_t retval = start_len + add_len;
   10.24 +    size_t size_to_copy = (retval < size ? add_len : (size - start_len) - 1);
   10.25 +    
   10.26 +    // strlcat doc says src and dst not allowed to overlap, as
   10.27 +    // it's undefined. So this is acceptable:
   10.28 +    memcpy((void*)(dst + start_len), (void*)src, size_to_copy); // no defined error return, but strcpy doesn't either
   10.29 +    dst[start_len + size_to_copy] = '\0';
   10.30 +    return retval;
   10.31 +}
   10.32 +
   10.33  int mkstemp(char *templ)
   10.34  {
   10.35      char *pathname = _mktemp(templ);
    11.1 --- a/src/platform_windows.h	Thu Jul 21 15:16:23 2016 +0200
    11.2 +++ b/src/platform_windows.h	Thu Jul 21 17:53:04 2016 +0200
    11.3 @@ -49,6 +49,9 @@
    11.4  char *strndup(const char *s1, size_t n);
    11.5  char *stpcpy(char *dst, const char *src);
    11.6  
    11.7 +size_t strlcpy(char* dst, const	char* src, size_t size);
    11.8 +size_t strlcat(char* dst, const	char* src, size_t size);
    11.9 +
   11.10  const char *windoze_local_db(void);
   11.11  const char *windoze_system_db(void);
   11.12  const char *gpg_conf(void);
    12.1 --- a/test/msg_no_key.asc	Thu Jul 21 15:16:23 2016 +0200
    12.2 +++ b/test/msg_no_key.asc	Thu Jul 21 17:53:04 2016 +0200
    12.3 @@ -1,86 +1,44 @@
    12.4 -From: Test no key <test@nokey.plop>
    12.5 -To: Still no key <still@nokey.blup>
    12.6 -Subject: pEp
    12.7 -X-pEp-Version: 1.0
    12.8 +To: notreal@kgrothoff.org
    12.9 +From: Krista Grothoff <notreal@kgrothoff.org>
   12.10 +Subject: test3
   12.11 +Message-ID: <579B4AB5.4090402@kgrothoff.org>
   12.12 +Date: Fri, 29 Jul 2016 14:23:17 +0200
   12.13 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101
   12.14 + Thunderbird/38.8.0
   12.15  MIME-Version: 1.0
   12.16 -Content-Type: multipart/encrypted; boundary="74b0dc5119495cff2ae8944a625558ec"; 
   12.17 - protocol="application/pgp-encrypted"
   12.18 +Content-Type: multipart/encrypted;
   12.19 + protocol="application/pgp-encrypted";
   12.20 + boundary="Vkb6PtN2UuPCNGnI4hCGU6LNQN66590UU"
   12.21  
   12.22 ---74b0dc5119495cff2ae8944a625558ec
   12.23 +This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156)
   12.24 +--Vkb6PtN2UuPCNGnI4hCGU6LNQN66590UU
   12.25  Content-Type: application/pgp-encrypted
   12.26 +Content-Description: PGP/MIME version identification
   12.27  
   12.28  Version: 1
   12.29 ---74b0dc5119495cff2ae8944a625558ec
   12.30 -Content-Type: application/octet-stream
   12.31 -Content-Transfer-Encoding: 7bit
   12.32 -Content-Disposition: inline; filename="msg.asc"
   12.33 +
   12.34 +--Vkb6PtN2UuPCNGnI4hCGU6LNQN66590UU
   12.35 +Content-Type: application/octet-stream; name="encrypted.asc"
   12.36 +Content-Description: OpenPGP encrypted message
   12.37 +Content-Disposition: inline; filename="encrypted.asc"
   12.38  
   12.39  -----BEGIN PGP MESSAGE-----
   12.40  
   12.41 -hQEMA3RCTrevwG3jAQf/ajRuor6jilyO5RvQqkhTH5EIl70QbRKCFv+R09/JVY3J
   12.42 -+UmpmZUWR91STplFyHWap2bIPnmLi7iTYhJf2n7w5NmDVju4fykw8rVl+khShdZu
   12.43 -harEilWGdiKnPoux/iBeicflLSiKI5hoR/kk2XPPvyDCCFUIwF3md96W+PFom3mv
   12.44 -asgJ5wUGW2VXIx608pP0iRh6Nb6adtcShggK2ClBYMfLvHXZ6J/hxAJLa03geIWR
   12.45 -rsPEsYvGHlF8pkpnJj1SqbIL5Wl1SDjzxvd3xj19O+ykOtcs+1SDIL8ieup1xBUy
   12.46 -2dnTaWbNwl/i6YkyFWFH03pj0g1UH5U0j60BAVHdBIUBDAPkhdA1fp/D8QEH/32c
   12.47 -Bvfo7YSQ4Lh2yLAJbNsw9vi6Pn+FeNQRLFJK0ncnUMHEywIQTXrhRPOI52Y1Dl5C
   12.48 -JlRbba1e3APOClWr1h12kF+7eTNTPjcnAK+qifzCZgqudL47eMbZQUdc/ycBHsML
   12.49 -5Am1LoDnaRIGUoNVJyrH2sQCov3tSCMcaQ4RoCkDwNef6iLYEtBh+jE9mIIOr5fE
   12.50 -6iLwAigzOh4zx94znCv58nV7jp6wWbCGCRjMTQEI3bLiwv6qVwzTYOoch719LYen
   12.51 -+lRMufz+JwQpn8Uj4d8HYNB3Dzn+WMPORG0ANxO7s1CT1a8GwEEX3Kxc4McxLWX0
   12.52 -4KH5dsV1Sb2u7pM1vqTS6wGi6x3rXCef/fD52xGy4yoBputlqT7esWa7yptmlhwD
   12.53 -nnP40nDubynyKCnxzEHpoLDsmULyDlZqXEFSjLOBxFu/sBfm2uzZ47MR/Eod5rEB
   12.54 -tzcXOBDS8Hc/yr5bRBoKxXoLdcocZtTnczgFNcaTlRy219DkqvUM8DQfkPcsWqBE
   12.55 -Thn83B92nkQbm/so3oRNAUdm3Z8w2a3wZao+WB73OYKgB3ugXf52L6GWTWOOxn1H
   12.56 -VXqxTJokGMCBomIsBJn300gEDXwNJhyYWGHpYPp9am/Ym/ZamwnKSfQlh8+d4z63
   12.57 -8NM78UHJWKUNnn7yP8Vd4zc05fYQFyxM1mXS2YlW5Ch5DkOOu0XNSam2f/9W/7xd
   12.58 -9WMtgKGQ33h+vqmnJ6gpzyUSfJ8QRcYzuCMxW0rPLIrxnP/V5+lV0GqaIkMyQxCH
   12.59 -OvaclLOTvsW9gNRAkUFxvfPdwq3pTim8GSd2oCxETIaBI2xca2NQ6NtKjddbADbV
   12.60 -mbPdyJHKahEVuAXLQ8KVmdcvEjaJYt+Mch14p439vxo611VNYTaSOuoqEeB9VYEP
   12.61 -8TkP80l7d7q9iJ9mF1jw/+ykdpDWPGn3zECeg2vXCvksqtyMJ/XeflYxge3H8LRZ
   12.62 -DUwDa5crXH5Iq7pSwdzWvVTzjkBZzawY3zJGMTpnnb4EdTQldBdHQxCgTHMBWn7f
   12.63 -6FqFXmMAHJC3nYs8ysFmfGLIiOjdedGc3O95oMFcYjzHafKc6LH1GGkNCDRXYC8M
   12.64 -mJm3lpDxkCselGXeHBopuxLFmmv8xZ2vdu454r69lMIDgE2huEdsNyTzKc3aG00B
   12.65 -jE5etwcxGEFRAbHS4EvYY63DwCYr4Qh7uKh7jID2skT8zGPQitPOYBuOJ/2h0thK
   12.66 -e3Ztohf+P/VSYIipXZP6dCYNRTVoaPFfKA9+OyLXWccADpmqXJe8wCQ397Eo2gNW
   12.67 -Yl6P57cCHn8mW7SIWwePmSnYAHn0uAkpIYked6p5vNHX/6xHjXLeeFTVC3ZK5gFh
   12.68 -6C2xEvLh41ACLPdeqM3ANXWiZDYnkZ9LlwV2EZywTI6urd+OcslGuRf1lrfnFDWm
   12.69 -K2w4PKxhoziizxrn6OjAzF+d9iqn0VOLh1H9PuMVbHwEO8vhYH0vfyjxkXUdLBgK
   12.70 -nSXZ9BPv9IL1CYhhN6hFiP1Va8SteHDhmMzRLZ9hjkTdLEP5Lu+AVwH0FkviaAan
   12.71 -s5gGdFe+pOmmkuC5s589XTpIGGug60z2u38SoN0LvtSPene7Wh1nNyzVPiyaFR1L
   12.72 -r78VH3BfUWHEVfGcAlNjajHWFZoCMHjKUPvlcMURls6ZfQwhF/3RGs1X2F6Ts1LO
   12.73 -CaoU4R+iKAgzfSYBKfCKbkjbBXAfq17IBohXcVZZlbKUbKUlGLdxqHWppI5wYJki
   12.74 -ME5iHyoM5HZYHWnsi76fA3sHrwifIuFTl85EZQgR2OUJb3tn3g1ckz5sTscUm2Af
   12.75 -fquWYyPcfF4MyVfbbxjTvVqg0JUAwSXY3t+b1JGBlnrmcu0JBprEuYL60KWmNh+p
   12.76 -jawapj1Cu7GXBrWanEjhZrLKZF3GO3SCBKnINLnWTxWOxO3aSBskGkiNTjMUtWur
   12.77 -7V37A2OKmVTZccTzWzHfppHmsBdvdflMNz1aYy+YgC3YF/5/gDBSsStQoECiZQDx
   12.78 -oENYxI9p6qXepgl0HAeagvWoX82/iKf42mMXdgjPRM+hd0vXvzI1KubQ641b6DUZ
   12.79 -JYYdMFcCW1LfbFb8+/9vF7orFSYIqVW75SLNcb9MMas5KoOcHWrJIK3vHyV+w6fI
   12.80 -8tNzkcvUCMRyiCBkq74JXt1a/yalNjtMvXqU7W3dhTQeZ4OwbYSx0wHJWVjk0o3d
   12.81 -dIl9Y0ig+QJF6MDYOw5NQ/ys3iNhDZVurgFk3eIncFoIHB4k9QovGQNUA/F2qtyR
   12.82 -BtVFYiS5aIQ7tosWWTb7FbBlSTZV1rO8YDi/oQ3XiVLV0ZDan68lQfOO8pE6oIQ+
   12.83 -ZaWXi1jK2koJjV4Vc7+NqLw0FhEuJME7EFI+iuIg8aXKQxP3H0vsdq71L/qxSIcb
   12.84 -V7RnSCDEZPbfssuShzegOkdVWn4u+5lF2ZB6vtt5/noOuopfup1DLBe9OTs8PEg8
   12.85 -JawLixRqWE5njDCVWxinmoovvlaWkshG+2C9+Pc0R6MB1j3G3HdOV03jk+yrAQ2S
   12.86 -hwXmkWEHhhKbF6tdamKJan2ahO/wuW4DSYiAc64ys1bpWctipgaDodgmXa1KkEan
   12.87 -44cQMf0yISdBex8uKqddQDplNxojT1ysky824X3vnApYjZ1O9/9EnQRn9BYuHdIL
   12.88 -8zat3qQAJO0cS0qAnQquoWzPzq7rumHxn248+mox6hD7Bxr+j6lbwyZRnaCcWFbu
   12.89 -11LUs0+pXDB+tKR6iGbuBuLLnj87LtjfzgkpDvlogBiaTFylJ+z4mfvpco05DfmU
   12.90 -CPyLr8LNIm6C3BVWDotgfVzIpsVuLGn+0JGB32RwYK79ngiFbgzjyTpGoIrPSAlr
   12.91 -gcrPR2XpXKMqOIktxJXMNWkBEg0w0ho7pviRCev+/yIxFV5zBNNUYYux1iAJPInQ
   12.92 -HDODyPFxC3YkRiFsw1c1GxI0dWdefQD7ClS8PFDrMIUeuPZMMt1TwUDB49uJqI7i
   12.93 -+n4MSfrxk1VTdSBH6dGk34ryoymMRwdLFcMyjNOICeCBnvmbc8qbBNg1hnr1Mbaz
   12.94 -pJl0dVXorszIZtx0EdE4KXu0+F8+LED6ASSH4lYLlsKirZkfDuTCE88d6MIIpjpb
   12.95 -wOm9ZP7Cb7YbCtFDm1pUF/L/J4TMnPjhufGdXbHwX1E1rB8pcnsShOLJrIhZWeq/
   12.96 -TWl9kmfbcM6OZVzedz1Eq9H5GE5BT/yTNmlrVR5Z2a7xwjbxE6uP+SPhx3Tga4Us
   12.97 -ivBOudkcifSy44AxjYOhPLaFxygs7We4JLIn0WOB6D7hvRDjL4osOKRiqJ5G56kZ
   12.98 -pZ6wGXUUZJzdUAuPPl2mAyxkpErZTXe3ENMFh3vU7YF3ovWgT7en6sRlVV6aCBc+
   12.99 -VNyM6OHFQlMeMowLWacONMQCVKsbMsOtLgBKryqTXugIBJclSV8vDy0zhuQoeQ1B
  12.100 -hUeA4uxoljnTkr5bLnBeKbC8vpViC2cHKsnmDX0cpE/ybyvXAHhbKHGbW912gylv
  12.101 -5V2h/Sct/wleXYYHBTQTsZpbQjAZmn8R8LUfG6H1Ig4CfH8oeBIkjaSt4z9zUBsp
  12.102 -0FdLyughCihVz98UJGVDh/H4fQIyXytqycFwF/mst//GXH9/VzJwRcqUz7MKQxoO
  12.103 -Pd2Y0r3rz5hfj78l1NOXYgdpEzLvQkyQbujU8foJJOxA0pRYlLN9Xr3AoQ==
  12.104 -=uymV
  12.105 +hQEMAxqoixpCqEC5AQgAw2FSvhWUNOLTXDigj/0sSAvjsiRnywXoa+IWXECZhIy0
  12.106 +78J+Ib66VgdVUuHuxa2tw1EojKWtSrDlcxJUnWwcewRaRzwGmZ2OTTvMb+ri8y4B
  12.107 +YdwDsL0MthWiXO/V81kiYjyA5jn6e1p4kYPWJCHTeBu1DKZFreulD/ckMFBFgbwt
  12.108 +fttSaMMDuU3gjlQET3kOppWLatMevosXiwUOBr3fhDZvGIGu9OI6tiXlul0B1+aG
  12.109 +YSn81tIaZKPixlgVVmJYXVbz/P1PM2ilbGbOOyrcDvY2YDFiQfjdjh7V+noshB9u
  12.110 +n3MBQ/altgUdjfPX8KDp7RACddr2QuoY2SGF1PMcwNLAmgFZ4T1kAtaT4l7+/nF5
  12.111 +c/DhDccRFLtb3wNjuhMs1QJQy+2O5cJBvT42U+0TM72MFTwRNwXlWNkn8r8eJfZj
  12.112 +6TUyZqNK6LqKKZksNUIVhGPcore3HPhfiSVV8k7iRG8mZ2wfMe25hhGG/0+pCOiB
  12.113 +9/OCXKOgFNlWSVzfmbQ9dAvxaZVlDOrgy7weS8aGkH73B+u70SX9iXNvmfLoXv90
  12.114 +0oimyhfkMd+9lK9rFwqh/RankVun1V03lQJhyaPMotWOIw06Z+8s495G3h6UiUIu
  12.115 +vqBfr6mPzIVVrIuSeWSBY/lE+1+3DUUTbx5lDWynRxND7bd7m1uwcl2nIAcmsJ+R
  12.116 +JKm1+JTEwoYgcPBUT+lxshFexqXv19hk7NWIAmhNmEpRRsi27gqmk5IVDmeR4upr
  12.117 +w65H7Es9EN0no0C5ZjUdGke4jQ0ILL8akqDFTWp8vCUuQgKZNHRayQZ84cg=
  12.118 +=q/R9
  12.119  -----END PGP MESSAGE-----
  12.120  
  12.121 ---74b0dc5119495cff2ae8944a625558ec--
  12.122 +--Vkb6PtN2UuPCNGnI4hCGU6LNQN66590UU--
  12.123 +