1.1 --- a/db/en.csv Tue May 03 08:30:22 2016 +0200
1.2 +++ b/db/en.csv Tue May 03 08:30:41 2016 +0200
1.3 @@ -1891,7 +1891,7 @@
1.4 en,1890,ANESTHETIC,0
1.5 en,1891,ANESTHETIST,0
1.6 en,1892,ANESTHETIZE,0
1.7 -en,1893,ANESTHETIZER,0
1.8 +en,1893,STAPLE,0
1.9 en,1894,ANET,0
1.10 en,1895,ANET,0
1.11 en,1896,ANETT,0
1.12 @@ -7845,7 +7845,7 @@
1.13 en,7844,CASSANDRE,0
1.14 en,7845,CASSANDRY,0
1.15 en,7846,CASSATT,0
1.16 -en,7847,CASSAUNDRA,0
1.17 +en,7847,HORSE,0
1.18 en,7848,CASSAVA,0
1.19 en,7849,CASSEROLE,0
1.20 en,7850,CASSETTE,0
1.21 @@ -11681,7 +11681,7 @@
1.22 en,11680,CUCKOO,0
1.23 en,11681,CUCUMBER,0
1.24 en,11682,CUDDLE,0
1.25 -en,11683,CUDDLY,0
1.26 +en,11683,BATTERY,0
1.27 en,11684,CUDGEL,0
1.28 en,11685,CUE,0
1.29 en,11686,CUFF,0
1.30 @@ -16555,7 +16555,7 @@
1.31 en,16554,EVERYPLACE,0
1.32 en,16555,EVERYTHING,0
1.33 en,16556,EVERYWHERE,0
1.34 -en,16557,EVICT,0
1.35 +en,16557,CORRECT,0
1.36 en,16558,EVICTION,0
1.37 en,16559,EVIDENCE,0
1.38 en,16560,EVIDENT,0
1.39 @@ -22884,7 +22884,7 @@
1.40 en,22883,HORRIFYING,0
1.41 en,22884,HORROR,0
1.42 en,22885,HORS,0
1.43 -en,22886,HORSE,0
1.44 +en,22886,CASSAUNDRA,0
1.45 en,22887,HORSEBACK,0
1.46 en,22888,HORSEDOM,0
1.47 en,22889,HORSEFLESH,0
1.48 @@ -31918,7 +31918,7 @@
1.49 en,31917,NAMER,0
1.50 en,31918,NAMESAKE,0
1.51 en,31919,NAMIBIA,0
1.52 -en,31920,NAMIBIAN,0
1.53 +en,31920,XKCD,0
1.54 en,31921,NAMING,0
1.55 en,31922,NAN,0
1.56 en,31923,NANA,0
1.57 @@ -44371,7 +44371,7 @@
1.58 en,44370,STANZA,0
1.59 en,44371,STAPH,0
1.60 en,44372,STAPHS,0
1.61 -en,44373,STAPLE,0
1.62 +en,44373,ANESTHETIZER,0
1.63 en,44374,STAPLED,0
1.64 en,44375,STAPLER,0
1.65 en,44376,STAPLETON,0
1.66 @@ -54021,7 +54021,7 @@
1.67 en,54020,ANESTHETIC,0
1.68 en,54021,ANESTHETIST,0
1.69 en,54022,ANESTHETIZE,0
1.70 -en,54023,ANESTHETIZER,0
1.71 +en,54023,STAPLE,0
1.72 en,54024,ANET,0
1.73 en,54025,ANET,0
1.74 en,54026,ANETT,0
1.75 @@ -56428,7 +56428,7 @@
1.76 en,56427,BATTED,0
1.77 en,56428,BATTEN,0
1.78 en,56429,BATTER,0
1.79 -en,56430,BATTERY,0
1.80 +en,56430,CUDDLY,0
1.81 en,56431,BATTING,0
1.82 en,56432,BATTLE,0
1.83 en,56433,BATTLEDORE,0
1.84 @@ -63034,7 +63034,7 @@
1.85 en,63033,CORRAL,0
1.86 en,63034,CORRALLED,0
1.87 en,63035,CORRALLING,0
1.88 -en,63036,CORRECT,0
1.89 +en,63036,EVICT,0
1.90 en,63037,CORRECTABLE,0
1.91 en,63038,CORRECTED,0
1.92 en,63039,CORRECTION,0
1.93 @@ -63811,7 +63811,7 @@
1.94 en,63810,CUCKOO,0
1.95 en,63811,CUCUMBER,0
1.96 en,63812,CUDDLE,0
1.97 -en,63813,CUDDLY,0
1.98 +en,63813,BATTERY,0
1.99 en,63814,CUDGEL,0
1.100 en,63815,CUE,0
1.101 en,63816,CUFF,0
2.1 --- a/src/keymanagement.c Tue May 03 08:30:22 2016 +0200
2.2 +++ b/src/keymanagement.c Tue May 03 08:30:41 2016 +0200
2.3 @@ -70,7 +70,31 @@
2.4 if (!(session && identity && !EMPTYSTR(identity->address)))
2.5 return PEP_ILLEGAL_VALUE;
2.6
2.7 - status = get_identity(session, identity->address, &stored_identity);
2.8 + int _no_user_id = EMPTYSTR(identity->user_id);
2.9 +
2.10 + if (_no_user_id)
2.11 + {
2.12 + free(identity->user_id);
2.13 +
2.14 + identity->user_id = calloc(1, identity->address_size + 6);
2.15 + if (!identity->user_id)
2.16 + {
2.17 + return PEP_OUT_OF_MEMORY;
2.18 + }
2.19 + snprintf(identity->user_id, identity->address_size + 5,
2.20 + "TOFU_%s", identity->address);
2.21 +
2.22 + if(identity->user_id)
2.23 + {
2.24 + identity->user_id_size = strlen(identity->user_id);
2.25 + }
2.26 + }
2.27 +
2.28 + status = get_identity(session,
2.29 + identity->address,
2.30 + identity->user_id,
2.31 + &stored_identity);
2.32 +
2.33 assert(status != PEP_OUT_OF_MEMORY);
2.34 if (status == PEP_OUT_OF_MEMORY)
2.35 return PEP_OUT_OF_MEMORY;
2.36 @@ -82,15 +106,6 @@
2.37 if (status == PEP_OUT_OF_MEMORY)
2.38 return PEP_OUT_OF_MEMORY;
2.39
2.40 - if (EMPTYSTR(identity->user_id)) {
2.41 - free(identity->user_id);
2.42 - identity->user_id = strndup(stored_identity->user_id, stored_identity->user_id_size);
2.43 - assert(identity->user_id);
2.44 - if (identity->user_id == NULL)
2.45 - return PEP_OUT_OF_MEMORY;
2.46 - identity->user_id_size = stored_identity->user_id_size;
2.47 - }
2.48 -
2.49 if (EMPTYSTR(identity->username)) {
2.50 free(identity->username);
2.51 identity->username = strndup(stored_identity->username, stored_identity->username_size);
2.52 @@ -218,10 +233,15 @@
2.53 identity->username_size = 9;
2.54 }
2.55
2.56 - status = set_identity(session, identity);
2.57 - assert(status == PEP_STATUS_OK);
2.58 - if (status != PEP_STATUS_OK) {
2.59 - return status;
2.60 + // Identity doesn't get stored if is was just about checking existing
2.61 + // user by address (i.e. no user id but already stored)
2.62 + if (!(_no_user_id && stored_identity))
2.63 + {
2.64 + status = set_identity(session, identity);
2.65 + assert(status == PEP_STATUS_OK);
2.66 + if (status != PEP_STATUS_OK) {
2.67 + return status;
2.68 + }
2.69 }
2.70 }
2.71
2.72 @@ -235,6 +255,7 @@
2.73
2.74 DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity)
2.75 {
2.76 + pEp_identity *stored_identity;
2.77 PEP_STATUS status;
2.78 stringlist_t *keylist = NULL;
2.79
2.80 @@ -253,12 +274,69 @@
2.81
2.82 DEBUG_LOG("myself", "debug", identity->address);
2.83
2.84 - status = find_keys(session, identity->address, &keylist);
2.85 +
2.86 + status = get_identity(session,
2.87 + identity->address,
2.88 + identity->user_id,
2.89 + &stored_identity);
2.90 +
2.91 assert(status != PEP_OUT_OF_MEMORY);
2.92 if (status == PEP_OUT_OF_MEMORY)
2.93 return PEP_OUT_OF_MEMORY;
2.94 -
2.95 - if (keylist == NULL || keylist->value == NULL) {
2.96 +
2.97 + if (stored_identity)
2.98 + {
2.99 + if (EMPTYSTR(identity->fpr)) {
2.100 + identity->fpr = strndup(stored_identity->fpr, stored_identity->fpr_size);
2.101 + assert(identity->fpr);
2.102 + if (identity->fpr == NULL)
2.103 + {
2.104 + return PEP_OUT_OF_MEMORY;
2.105 + }
2.106 + identity->fpr_size = stored_identity->fpr_size;
2.107 + }
2.108 + }
2.109 + else
2.110 + {
2.111 + free(identity->fpr);
2.112 + identity->fpr_size = 0;
2.113 +
2.114 + status = find_keys(session, identity->address, &keylist);
2.115 + assert(status != PEP_OUT_OF_MEMORY);
2.116 + if (status == PEP_OUT_OF_MEMORY)
2.117 + return PEP_OUT_OF_MEMORY;
2.118 +
2.119 + if (keylist != NULL && keylist->value != NULL)
2.120 + {
2.121 + // BUG : Vulnerable to auto-key-import poisoning.
2.122 + // Attacker's key with forged userId could have been
2.123 + // auto imported from already received email and be used here
2.124 +
2.125 + // TODO : iterate over list to elect best key
2.126 + // TODO : discard keys which aren't private
2.127 + // TODO : discard keys which aren't either
2.128 + // - own generated key
2.129 + // - own from synchronized device group
2.130 + // - already fully trusted as a public key of known
2.131 + // identity, for that same address
2.132 + // (case of imported key for mailing lists)
2.133 +
2.134 + identity->fpr = strdup(keylist->value);
2.135 + assert(identity->fpr);
2.136 + if (identity->fpr == NULL)
2.137 + {
2.138 + return PEP_OUT_OF_MEMORY;
2.139 + }
2.140 + identity->fpr_size = strlen(identity->fpr);
2.141 + }
2.142 +
2.143 + }
2.144 +
2.145 + // TODO : Check key for revoked state
2.146 +
2.147 + if (EMPTYSTR(identity->fpr) /* or revoked */)
2.148 + {
2.149 +
2.150 DEBUG_LOG("generating key pair", "debug", identity->address);
2.151 status = generate_keypair(session, identity);
2.152 assert(status != PEP_OUT_OF_MEMORY);
2.153 @@ -268,20 +346,21 @@
2.154 DEBUG_LOG("generating key pair failed", "debug", buf);
2.155 return status;
2.156 }
2.157 -
2.158 +
2.159 status = find_keys(session, identity->address, &keylist);
2.160 assert(status != PEP_OUT_OF_MEMORY);
2.161 if (status == PEP_OUT_OF_MEMORY)
2.162 return PEP_OUT_OF_MEMORY;
2.163 -
2.164 +
2.165 assert(keylist && keylist->value);
2.166 if (keylist == NULL || keylist->value == NULL) {
2.167 return PEP_UNKNOWN_ERROR;
2.168 }
2.169 }
2.170 - else {
2.171 + else
2.172 + {
2.173 bool expired;
2.174 - status = key_expired(session, keylist->value, &expired);
2.175 + status = key_expired(session, identity->fpr, &expired);
2.176 assert(status == PEP_STATUS_OK);
2.177 if (status != PEP_STATUS_OK) {
2.178 goto free_keylist;
2.179 @@ -289,21 +368,11 @@
2.180
2.181 if (status == PEP_STATUS_OK && expired) {
2.182 timestamp *ts = new_timestamp(time(NULL) + KEY_EXPIRE_DELTA);
2.183 - renew_key(session, keylist->value, ts);
2.184 + renew_key(session, identity->fpr, ts);
2.185 free_timestamp(ts);
2.186 }
2.187 }
2.188
2.189 - if (identity->fpr)
2.190 - free(identity->fpr);
2.191 - identity->fpr = strdup(keylist->value);
2.192 - assert(identity->fpr);
2.193 - if (identity->fpr == NULL){
2.194 - status = PEP_OUT_OF_MEMORY;
2.195 - goto free_keylist;
2.196 - }
2.197 - identity->fpr_size = strlen(identity->fpr);
2.198 -
2.199 status = set_identity(session, identity);
2.200 assert(status == PEP_STATUS_OK);
2.201 if (status != PEP_STATUS_OK) {
3.1 --- a/src/message_api.c Tue May 03 08:30:22 2016 +0200
3.2 +++ b/src/message_api.c Tue May 03 08:30:41 2016 +0200
3.3 @@ -877,6 +877,9 @@
3.4 assert(session);
3.5 assert(msg);
3.6
3.7 + if (msg->dir == PEP_dir_incoming)
3.8 + return;
3.9 +
3.10 assert(msg->from && msg->from->fpr);
3.11 if (msg->from == NULL || msg->from->fpr == NULL)
3.12 return;
3.13 @@ -929,8 +932,9 @@
3.14 assert(session);
3.15 assert(src);
3.16 assert(dst);
3.17 + assert(enc_format != PEP_enc_none);
3.18
3.19 - if (!(session && src && dst))
3.20 + if (!(session && src && dst && enc_format != PEP_enc_none))
3.21 return PEP_ILLEGAL_VALUE;
3.22
3.23 if (src->dir == PEP_dir_incoming)
3.24 @@ -945,13 +949,7 @@
3.25 status = myself(session, src->from);
3.26 if (status != PEP_STATUS_OK)
3.27 goto pep_error;
3.28 -
3.29 - if (enc_format == PEP_enc_none)
3.30 - {
3.31 - attach_own_key(session, src);
3.32 - return PEP_UNENCRYPTED;
3.33 - }
3.34 -
3.35 +
3.36 keys = new_stringlist(src->from->fpr);
3.37 if (keys == NULL)
3.38 goto enomem;
4.1 --- a/src/pEpEngine.c Tue May 03 08:30:22 2016 +0200
4.2 +++ b/src/pEpEngine.c Tue May 03 08:30:41 2016 +0200
4.3 @@ -140,14 +140,15 @@
4.4 " comment text\n"
4.5 ");\n"
4.6 "create table if not exists identity (\n"
4.7 - " address text primary key,\n"
4.8 + " address text,\n"
4.9 " user_id text\n"
4.10 " references person (id)\n"
4.11 " on delete cascade,\n"
4.12 " main_key_id text\n"
4.13 " references pgp_keypair (fpr)\n"
4.14 " on delete set null,\n"
4.15 - " comment text\n"
4.16 + " comment text,\n"
4.17 + " primary key (address, user_id)\n"
4.18 ");\n"
4.19 "create table if not exists trust (\n"
4.20 " user_id text not null\n"
4.21 @@ -186,13 +187,13 @@
4.22 sql_log = "insert into log (title, entity, description, comment)"
4.23 "values (?1, ?2, ?3, ?4);";
4.24
4.25 - sql_get_identity = "select fpr, identity.user_id, username, comm_type, lang"
4.26 + sql_get_identity = "select fpr, username, comm_type, lang"
4.27 " from identity"
4.28 " join person on id = identity.user_id"
4.29 " join pgp_keypair on fpr = identity.main_key_id"
4.30 " join trust on id = trust.user_id"
4.31 " and pgp_keypair_fpr = identity.main_key_id"
4.32 - " where address = ?1 ;";
4.33 + " where address = ?1 and identity.user_id = ?2;";
4.34
4.35 sql_trustword = "select id, word from wordlist where lang = lower(?1) "
4.36 "and id = ?2 ;";
4.37 @@ -201,21 +202,21 @@
4.38 "values (?1, ?2, ?3) ;";
4.39
4.40 sql_set_pgp_keypair = "insert or replace into pgp_keypair (fpr) "
4.41 - "values (?1) ;";
4.42 + "values (upper(replace(?1,' ',''))) ;";
4.43
4.44 sql_set_identity = "insert or replace into identity (address, main_key_id, "
4.45 - "user_id) values (?1, ?2, ?3) ;";
4.46 + "user_id) values (?1, upper(replace(?2,' ','')), ?3) ;";
4.47
4.48 sql_set_trust = "insert or replace into trust (user_id, pgp_keypair_fpr, comm_type) "
4.49 - "values (?1, ?2, ?3) ;";
4.50 + "values (?1, upper(replace(?2,' ','')), ?3) ;";
4.51
4.52 - sql_get_trust = "select user_id, comm_type from trust where user_id = ?1 "
4.53 - "and pgp_keypair_fpr = ?2 ;";
4.54 + sql_get_trust = "select comm_type from trust where user_id = ?1 "
4.55 + "and pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
4.56
4.57 - sql_least_trust = "select min(comm_type) from trust where pgp_keypair_fpr = ?1 ;";
4.58 + sql_least_trust = "select min(comm_type) from trust where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
4.59
4.60 sql_mark_as_compromized = "update trust not indexed set comm_type = 15"
4.61 - " where pgp_keypair_fpr = ?1 ;";
4.62 + " where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
4.63
4.64 sql_crashdump = "select timestamp, title, entity, description, comment"
4.65 " from log order by timestamp desc limit ?1 ;";
4.66 @@ -226,13 +227,13 @@
4.67
4.68 // blacklist
4.69
4.70 - sql_blacklist_add = "insert or replace into blacklist_keys (fpr) values (?1) ;"
4.71 - "delete from identity where main_key_id = ?1 ;"
4.72 - "delete from pgp_keypair where fpr = ?1 ;";
4.73 + sql_blacklist_add = "insert or replace into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
4.74 + "delete from identity where main_key_id = upper(replace(?1,' ','')) ;"
4.75 + "delete from pgp_keypair where fpr = upper(replace(?1,' ','')) ;";
4.76
4.77 - sql_blacklist_delete = "delete from blacklist_keys where fpr = ?1 ;";
4.78 + sql_blacklist_delete = "delete from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
4.79
4.80 - sql_blacklist_is_listed = "select count(*) from blacklist_keys where fpr = ?1 ;";
4.81 + sql_blacklist_is_listed = "select count(*) from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
4.82
4.83 sql_blacklist_retrieve = "select * from blacklist_keys ;";
4.84 }
4.85 @@ -671,7 +672,9 @@
4.86 }
4.87
4.88 DYNAMIC_API PEP_STATUS get_identity(
4.89 - PEP_SESSION session, const char *address,
4.90 + PEP_SESSION session,
4.91 + const char *address,
4.92 + const char *user_id,
4.93 pEp_identity **identity
4.94 )
4.95 {
4.96 @@ -689,6 +692,7 @@
4.97
4.98 sqlite3_reset(session->get_identity);
4.99 sqlite3_bind_text(session->get_identity, 1, address, -1, SQLITE_STATIC);
4.100 + sqlite3_bind_text(session->get_identity, 2, user_id, -1, SQLITE_STATIC);
4.101
4.102 result = sqlite3_step(session->get_identity);
4.103 switch (result) {
4.104 @@ -696,15 +700,15 @@
4.105 _identity = new_identity(
4.106 address,
4.107 (const char *) sqlite3_column_text(session->get_identity, 0),
4.108 - (const char *) sqlite3_column_text(session->get_identity, 1),
4.109 - (const char *) sqlite3_column_text(session->get_identity, 2)
4.110 + user_id,
4.111 + (const char *) sqlite3_column_text(session->get_identity, 1)
4.112 );
4.113 assert(_identity);
4.114 if (_identity == NULL)
4.115 return PEP_OUT_OF_MEMORY;
4.116
4.117 - _identity->comm_type = (PEP_comm_type) sqlite3_column_int(session->get_identity, 3);
4.118 - _lang = (const char *) sqlite3_column_text(session->get_identity, 4);
4.119 + _identity->comm_type = (PEP_comm_type) sqlite3_column_int(session->get_identity, 2);
4.120 + _lang = (const char *) sqlite3_column_text(session->get_identity, 3);
4.121 if (_lang && _lang[0]) {
4.122 assert(_lang[0] >= 'a' && _lang[0] <= 'z');
4.123 assert(_lang[1] >= 'a' && _lang[1] <= 'z');
4.124 @@ -868,16 +872,7 @@
4.125 result = sqlite3_step(session->get_trust);
4.126 switch (result) {
4.127 case SQLITE_ROW: {
4.128 - const char * user_id = (const char *) sqlite3_column_text(session->get_trust, 0);
4.129 - int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust, 1);
4.130 -
4.131 - if (strcmp(user_id, identity->user_id) != 0) {
4.132 - free(identity->user_id);
4.133 - identity->user_id = strdup(user_id);
4.134 - assert(identity->user_id);
4.135 - if (identity->user_id == NULL)
4.136 - return PEP_OUT_OF_MEMORY;
4.137 - }
4.138 + int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust, 0);
4.139 identity->comm_type = comm_type;
4.140 break;
4.141 }
5.1 --- a/src/pEpEngine.h Tue May 03 08:30:22 2016 +0200
5.2 +++ b/src/pEpEngine.h Tue May 03 08:30:41 2016 +0200
5.3 @@ -432,6 +432,8 @@
5.4 // parameters:
5.5 // session (in) session handle
5.6 // address (in) C string with communication address, UTF-8 encoded
5.7 +// user_id (in) unique C string to identify person that identity
5.8 +// is refering to
5.9 // identity (out) pointer to pEp_identity structure with results or
5.10 // NULL if failure
5.11 //
5.12 @@ -443,11 +445,12 @@
5.13 // more
5.14
5.15 DYNAMIC_API PEP_STATUS get_identity(
5.16 - PEP_SESSION session, const char *address,
5.17 + PEP_SESSION session,
5.18 + const char *address,
5.19 + const char *user_id,
5.20 pEp_identity **identity
5.21 );
5.22
5.23 -
5.24 // set_identity() - set identity information
5.25 //
5.26 // parameters: