|
|
@ -1808,6 +1808,107 @@ static bool failed_test(PEP_STATUS status) |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
static PEP_STATUS _update_state_for_ident_list( |
|
|
|
PEP_SESSION session, |
|
|
|
pEp_identity* from_ident, |
|
|
|
identity_list* ident_list, |
|
|
|
stringlist_t** keylist, |
|
|
|
PEP_comm_type* max_comm_type, |
|
|
|
unsigned int* max_version_major, |
|
|
|
unsigned int* max_version_minor, |
|
|
|
bool* has_pEp_user, |
|
|
|
bool* dest_keys_found, |
|
|
|
bool suppress_update_for_bcc |
|
|
|
) |
|
|
|
{ |
|
|
|
if (!ident_list || !max_version_major || !max_version_minor |
|
|
|
|| !has_pEp_user || !dest_keys_found |
|
|
|
|| !keylist) |
|
|
|
return PEP_ILLEGAL_VALUE; |
|
|
|
|
|
|
|
PEP_STATUS status = PEP_STATUS_OK; |
|
|
|
|
|
|
|
identity_list* _il = ident_list; |
|
|
|
|
|
|
|
for ( ; _il && _il->ident; _il = _il->next) { |
|
|
|
|
|
|
|
PEP_STATUS status = PEP_STATUS_OK; |
|
|
|
|
|
|
|
if (!is_me(session, _il->ident)) { |
|
|
|
status = update_identity(session, _il->ident); |
|
|
|
|
|
|
|
// If it turned out to be an own identity, we |
|
|
|
// just internally called _myself on it. |
|
|
|
if (!is_me(session, _il->ident)) { |
|
|
|
if (status == PEP_CANNOT_FIND_IDENTITY) { |
|
|
|
_il->ident->comm_type = PEP_ct_key_not_found; |
|
|
|
status = PEP_STATUS_OK; |
|
|
|
} |
|
|
|
// 0 unless set, so safe. |
|
|
|
|
|
|
|
if (!suppress_update_for_bcc) { |
|
|
|
set_min_version( _il->ident->major_ver, _il->ident->minor_ver, |
|
|
|
*max_version_major, *max_version_minor, |
|
|
|
max_version_major, max_version_minor); |
|
|
|
} |
|
|
|
|
|
|
|
bool is_blacklisted = false; |
|
|
|
if (_il->ident->fpr && IS_PGP_CT(_il->ident->comm_type)) { |
|
|
|
status = blacklist_is_listed(session, _il->ident->fpr, &is_blacklisted); |
|
|
|
if (status != PEP_STATUS_OK) { |
|
|
|
// DB error |
|
|
|
status = PEP_UNENCRYPTED; |
|
|
|
goto pEp_done; |
|
|
|
} |
|
|
|
if (is_blacklisted) { |
|
|
|
bool user_default, ident_default, address_default; |
|
|
|
status = get_valid_pubkey(session, _il->ident, |
|
|
|
&ident_default, &user_default, |
|
|
|
&address_default, |
|
|
|
true); |
|
|
|
if (status != PEP_STATUS_OK || _il->ident->fpr == NULL) { |
|
|
|
_il->ident->comm_type = PEP_ct_key_not_found; |
|
|
|
status = PEP_STATUS_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (!(*has_pEp_user) && !EMPTYSTR(_il->ident->user_id)) |
|
|
|
is_pEp_user(session, _il->ident, has_pEp_user); |
|
|
|
|
|
|
|
if (!suppress_update_for_bcc && from_ident) { |
|
|
|
status = bind_own_ident_with_contact_ident(session, from_ident, _il->ident); |
|
|
|
if (status != PEP_STATUS_OK) { |
|
|
|
status = PEP_UNKNOWN_DB_ERROR; |
|
|
|
goto pEp_done; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
status = myself(session, _il->ident); |
|
|
|
|
|
|
|
if (status != PEP_STATUS_OK) |
|
|
|
goto pEp_done; |
|
|
|
|
|
|
|
if (!EMPTYSTR(_il->ident->fpr)) { |
|
|
|
*keylist = stringlist_add(*keylist, _il->ident->fpr); |
|
|
|
if (*keylist == NULL) { |
|
|
|
status = PEP_OUT_OF_MEMORY; |
|
|
|
goto pEp_done; |
|
|
|
} |
|
|
|
*max_comm_type = _get_comm_type(session, *max_comm_type, |
|
|
|
_il->ident); |
|
|
|
} |
|
|
|
else { |
|
|
|
*dest_keys_found = false; |
|
|
|
// ? status = PEP_KEY_NOT_FOUND; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
pEp_done: |
|
|
|
return status; |
|
|
|
} |
|
|
|
|
|
|
|
DYNAMIC_API PEP_STATUS encrypt_message( |
|
|
|
PEP_SESSION session, |
|
|
|
message *src, |
|
|
@ -1886,6 +1987,10 @@ DYNAMIC_API PEP_STATUS encrypt_message( |
|
|
|
|
|
|
|
identity_list * _il = NULL; |
|
|
|
|
|
|
|
// |
|
|
|
// Update the identities and gather key and version information |
|
|
|
// for sending |
|
|
|
// |
|
|
|
if (enc_format != PEP_enc_none && (_il = src->bcc) && _il->ident) |
|
|
|
// BCC limited support: |
|
|
|
{ |
|
|
@ -1897,181 +2002,85 @@ DYNAMIC_API PEP_STATUS encrypt_message( |
|
|
|
return PEP_ILLEGAL_VALUE; |
|
|
|
} |
|
|
|
|
|
|
|
PEP_STATUS _status = PEP_STATUS_OK; |
|
|
|
if (!is_me(session, _il->ident)) { |
|
|
|
_status = update_identity(session, _il->ident); |
|
|
|
if (_status == PEP_CANNOT_FIND_IDENTITY) { |
|
|
|
_il->ident->comm_type = PEP_ct_key_not_found; |
|
|
|
_status = PEP_STATUS_OK; |
|
|
|
} |
|
|
|
// 0 unless set, so safe. |
|
|
|
|
|
|
|
set_min_version( _il->ident->major_ver, _il->ident->minor_ver, |
|
|
|
max_version_major, max_version_minor, |
|
|
|
&max_version_major, &max_version_minor); |
|
|
|
|
|
|
|
bool is_blacklisted = false; |
|
|
|
if (_il->ident->fpr && IS_PGP_CT(_il->ident->comm_type)) { |
|
|
|
_status = blacklist_is_listed(session, _il->ident->fpr, &is_blacklisted); |
|
|
|
if (_status != PEP_STATUS_OK) { |
|
|
|
// DB error |
|
|
|
status = PEP_UNENCRYPTED; |
|
|
|
goto pEp_error; |
|
|
|
} |
|
|
|
if (is_blacklisted) { |
|
|
|
bool user_default, ident_default, address_default; |
|
|
|
_status = get_valid_pubkey(session, _il->ident, |
|
|
|
&ident_default, &user_default, |
|
|
|
&address_default, |
|
|
|
true); |
|
|
|
if (_status != PEP_STATUS_OK || _il->ident->fpr == NULL) { |
|
|
|
_il->ident->comm_type = PEP_ct_key_not_found; |
|
|
|
_status = PEP_STATUS_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (!has_pEp_user && !EMPTYSTR(_il->ident->user_id)) |
|
|
|
is_pEp_user(session, _il->ident, &has_pEp_user); |
|
|
|
} |
|
|
|
else |
|
|
|
_status = myself(session, _il->ident); |
|
|
|
|
|
|
|
if (_status != PEP_STATUS_OK) { |
|
|
|
status = PEP_UNENCRYPTED; |
|
|
|
goto pEp_error; |
|
|
|
} |
|
|
|
|
|
|
|
if (_il->ident->fpr && _il->ident->fpr[0]) { |
|
|
|
_k = stringlist_add(_k, _il->ident->fpr); |
|
|
|
if (_k == NULL) |
|
|
|
goto enomem; |
|
|
|
max_comm_type = _get_comm_type(session, max_comm_type, |
|
|
|
_il->ident); |
|
|
|
} |
|
|
|
else { |
|
|
|
dest_keys_found = false; |
|
|
|
status = PEP_KEY_NOT_FOUND; |
|
|
|
// If you think this call is a beast, try the cut-and-pasted code 3 x |
|
|
|
PEP_STATUS _status = _update_state_for_ident_list( |
|
|
|
session, src->from, _il, |
|
|
|
&_k, |
|
|
|
&max_comm_type, |
|
|
|
&max_version_major, |
|
|
|
&max_version_minor, |
|
|
|
&has_pEp_user, |
|
|
|
&dest_keys_found, |
|
|
|
true); |
|
|
|
|
|
|
|
switch (_status) { |
|
|
|
case PEP_PASSPHRASE_REQUIRED: |
|
|
|
case PEP_PASSPHRASE_FOR_NEW_KEYS_REQUIRED: |
|
|
|
case PEP_WRONG_PASSPHRASE: |
|
|
|
status = _status; |
|
|
|
goto pEp_error; |
|
|
|
case PEP_STATUS_OK: |
|
|
|
break; |
|
|
|
default: |
|
|
|
status = PEP_UNENCRYPTED; |
|
|
|
goto pEp_error; |
|
|
|
} |
|
|
|
} |
|
|
|
else // Non BCC |
|
|
|
{ |
|
|
|
for (_il = src->to; _il && _il->ident; _il = _il->next) { |
|
|
|
PEP_STATUS _status = PEP_STATUS_OK; |
|
|
|
if (!is_me(session, _il->ident)) { |
|
|
|
_status = update_identity(session, _il->ident); |
|
|
|
if (_status == PEP_CANNOT_FIND_IDENTITY) { |
|
|
|
_il->ident->comm_type = PEP_ct_key_not_found; |
|
|
|
_status = PEP_STATUS_OK; |
|
|
|
} |
|
|
|
// 0 unless set, so safe. |
|
|
|
set_min_version( _il->ident->major_ver, _il->ident->minor_ver, |
|
|
|
max_version_major, max_version_minor, |
|
|
|
&max_version_major, &max_version_minor); |
|
|
|
|
|
|
|
bool is_blacklisted = false; |
|
|
|
if (_il->ident->fpr && IS_PGP_CT(_il->ident->comm_type)) { |
|
|
|
_status = blacklist_is_listed(session, _il->ident->fpr, &is_blacklisted); |
|
|
|
if (_status != PEP_STATUS_OK) { |
|
|
|
// DB error |
|
|
|
status = PEP_UNENCRYPTED; |
|
|
|
goto pEp_error; |
|
|
|
} |
|
|
|
if (is_blacklisted) { |
|
|
|
bool user_default, ident_default, address_default; |
|
|
|
_status = get_valid_pubkey(session, _il->ident, |
|
|
|
&ident_default, &user_default, |
|
|
|
&address_default, |
|
|
|
true); |
|
|
|
if (_status != PEP_STATUS_OK || _il->ident->fpr == NULL) { |
|
|
|
_il->ident->comm_type = PEP_ct_key_not_found; |
|
|
|
_status = PEP_STATUS_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (!has_pEp_user && !EMPTYSTR(_il->ident->user_id)) |
|
|
|
is_pEp_user(session, _il->ident, &has_pEp_user); |
|
|
|
|
|
|
|
_status = bind_own_ident_with_contact_ident(session, src->from, _il->ident); |
|
|
|
if (_status != PEP_STATUS_OK) { |
|
|
|
status = PEP_UNKNOWN_DB_ERROR; |
|
|
|
goto pEp_error; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
else |
|
|
|
_status = myself(session, _il->ident); |
|
|
|
|
|
|
|
if (_status != PEP_STATUS_OK) { |
|
|
|
status = PEP_UNENCRYPTED; |
|
|
|
goto pEp_error; |
|
|
|
} |
|
|
|
|
|
|
|
if (_il->ident->fpr && _il->ident->fpr[0]) { |
|
|
|
_k = stringlist_add(_k, _il->ident->fpr); |
|
|
|
if (_k == NULL) |
|
|
|
goto enomem; |
|
|
|
max_comm_type = _get_comm_type(session, max_comm_type, |
|
|
|
_il->ident); |
|
|
|
} |
|
|
|
else { |
|
|
|
dest_keys_found = false; |
|
|
|
status = PEP_KEY_NOT_FOUND; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
for (_il = src->cc; _il && _il->ident; _il = _il->next) { |
|
|
|
PEP_STATUS _status = PEP_STATUS_OK; |
|
|
|
if (!is_me(session, _il->ident)) { |
|
|
|
_status = update_identity(session, _il->ident); |
|
|
|
if (_status == PEP_CANNOT_FIND_IDENTITY) { |
|
|
|
_il->ident->comm_type = PEP_ct_key_not_found; |
|
|
|
_status = PEP_STATUS_OK; |
|
|
|
} |
|
|
|
bool is_blacklisted = false; |
|
|
|
if (_il->ident->fpr && IS_PGP_CT(_il->ident->comm_type)) { |
|
|
|
_status = blacklist_is_listed(session, _il->ident->fpr, &is_blacklisted); |
|
|
|
if (_status != PEP_STATUS_OK) { |
|
|
|
// DB error |
|
|
|
status = PEP_UNENCRYPTED; |
|
|
|
goto pEp_error; |
|
|
|
} |
|
|
|
if (is_blacklisted) { |
|
|
|
bool user_default, ident_default, address_default; |
|
|
|
_status = get_valid_pubkey(session, _il->ident, |
|
|
|
&ident_default, &user_default, |
|
|
|
&address_default, |
|
|
|
true); |
|
|
|
if (_status != PEP_STATUS_OK || _il->ident->fpr == NULL) { |
|
|
|
_il->ident->comm_type = PEP_ct_key_not_found; |
|
|
|
_status = PEP_STATUS_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
if (!has_pEp_user && !EMPTYSTR(_il->ident->user_id)) |
|
|
|
is_pEp_user(session, _il->ident, &has_pEp_user); |
|
|
|
} |
|
|
|
else |
|
|
|
_status = myself(session, _il->ident); |
|
|
|
if (_status != PEP_STATUS_OK) |
|
|
|
{ |
|
|
|
status = PEP_UNENCRYPTED; |
|
|
|
goto pEp_error; |
|
|
|
} |
|
|
|
|
|
|
|
if (_il->ident->fpr && _il->ident->fpr[0]) { |
|
|
|
_k = stringlist_add(_k, _il->ident->fpr); |
|
|
|
if (_k == NULL) |
|
|
|
goto enomem; |
|
|
|
max_comm_type = _get_comm_type(session, max_comm_type, |
|
|
|
_il->ident); |
|
|
|
} |
|
|
|
else { |
|
|
|
dest_keys_found = false; |
|
|
|
} |
|
|
|
// If you think this call is a beast, try the cut-and-pasted code 3 x |
|
|
|
PEP_STATUS _status = PEP_STATUS_OK; |
|
|
|
|
|
|
|
if (src->to) { |
|
|
|
_status = _update_state_for_ident_list( |
|
|
|
session, src->from, src->to, |
|
|
|
&_k, |
|
|
|
&max_comm_type, |
|
|
|
&max_version_major, |
|
|
|
&max_version_minor, |
|
|
|
&has_pEp_user, |
|
|
|
&dest_keys_found, |
|
|
|
false |
|
|
|
); |
|
|
|
switch (_status) { |
|
|
|
case PEP_PASSPHRASE_REQUIRED: |
|
|
|
case PEP_PASSPHRASE_FOR_NEW_KEYS_REQUIRED: |
|
|
|
case PEP_WRONG_PASSPHRASE: |
|
|
|
goto pEp_error; |
|
|
|
case PEP_STATUS_OK: |
|
|
|
break; |
|
|
|
default: |
|
|
|
status = PEP_UNENCRYPTED; |
|
|
|
goto pEp_error; |
|
|
|
} |
|
|
|
} |
|
|
|
if (src->cc) { |
|
|
|
_status = _update_state_for_ident_list( |
|
|
|
session, src->from, src->cc, |
|
|
|
&_k, |
|
|
|
&max_comm_type, |
|
|
|
&max_version_major, |
|
|
|
&max_version_minor, |
|
|
|
&has_pEp_user, |
|
|
|
&dest_keys_found, |
|
|
|
false |
|
|
|
); |
|
|
|
switch (_status) { |
|
|
|
case PEP_PASSPHRASE_REQUIRED: |
|
|
|
case PEP_PASSPHRASE_FOR_NEW_KEYS_REQUIRED: |
|
|
|
case PEP_WRONG_PASSPHRASE: |
|
|
|
goto pEp_error; |
|
|
|
case PEP_STATUS_OK: |
|
|
|
break; |
|
|
|
default: |
|
|
|
status = PEP_UNENCRYPTED; |
|
|
|
goto pEp_error; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (max_version_major == 1) |
|
|
|
if (max_version_major < 2) |
|
|
|
force_v_1 = true; |
|
|
|
|
|
|
|
if (enc_format == PEP_enc_auto) { |
|
|
@ -4806,6 +4815,8 @@ DYNAMIC_API PEP_STATUS outgoing_message_rating_preview( |
|
|
|
return PEP_STATUS_OK; |
|
|
|
} |
|
|
|
|
|
|
|
// CAN return PASSPHRASE errors on own keys because |
|
|
|
// of myself or discovered own identities |
|
|
|
DYNAMIC_API PEP_STATUS identity_rating( |
|
|
|
PEP_SESSION session, |
|
|
|
pEp_identity *ident, |
|
|
@ -4825,25 +4836,31 @@ DYNAMIC_API PEP_STATUS identity_rating( |
|
|
|
|
|
|
|
if (ident->me) |
|
|
|
status = _myself(session, ident, false, true, true); |
|
|
|
else |
|
|
|
else { // Since we don't blacklist own keys, we only check it in here |
|
|
|
status = update_identity(session, ident); |
|
|
|
|
|
|
|
bool is_blacklisted = false; |
|
|
|
|
|
|
|
if (ident->fpr && IS_PGP_CT(ident->comm_type)) { |
|
|
|
status = blacklist_is_listed(session, ident->fpr, &is_blacklisted); |
|
|
|
if (status != PEP_STATUS_OK) { |
|
|
|
return status; // DB ERROR |
|
|
|
} |
|
|
|
if (is_blacklisted) { |
|
|
|
bool user_default, ident_default, address_default; |
|
|
|
status = get_valid_pubkey(session, ident, |
|
|
|
&ident_default, &user_default, |
|
|
|
&address_default, |
|
|
|
true); |
|
|
|
if (status != PEP_STATUS_OK || ident->fpr == NULL) { |
|
|
|
ident->comm_type = PEP_ct_key_not_found; |
|
|
|
status = PEP_STATUS_OK; |
|
|
|
// double-check, in case update_identity had to call |
|
|
|
// _myself internally |
|
|
|
|
|
|
|
if (!ident->me) { |
|
|
|
bool is_blacklisted = false; |
|
|
|
|
|
|
|
if (ident->fpr && IS_PGP_CT(ident->comm_type)) { |
|
|
|
status = blacklist_is_listed(session, ident->fpr, &is_blacklisted); |
|
|
|
if (status != PEP_STATUS_OK) { |
|
|
|
return status; // DB ERROR |
|
|
|
} |
|
|
|
if (is_blacklisted) { |
|
|
|
bool user_default, ident_default, address_default; |
|
|
|
status = get_valid_pubkey(session, ident, |
|
|
|
&ident_default, &user_default, |
|
|
|
&address_default, |
|
|
|
true); |
|
|
|
if (status != PEP_STATUS_OK || ident->fpr == NULL) { |
|
|
|
ident->comm_type = PEP_ct_key_not_found; |
|
|
|
status = PEP_STATUS_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|