|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|