Urgh. Fixing bad merge (???)

doc_update_sequoia
Krista Bennett 5 years ago
parent b15638be12
commit 5f1dc494f9

@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
430BCC482015EE800077E998 /* pEp_string.h in Headers */ = {isa = PBXBuildFile; fileRef = 430BCC462015EE800077E998 /* pEp_string.h */; };
430BCC492015EE800077E998 /* pEp_string.c in Sources */ = {isa = PBXBuildFile; fileRef = 430BCC472015EE800077E998 /* pEp_string.c */; };
430D258B1C9ED75A00B94535 /* blacklist.c in Sources */ = {isa = PBXBuildFile; fileRef = 430D258A1C9ED75A00B94535 /* blacklist.c */; };
4354FF651D6EDF300033069C /* sync_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = 4354FF641D6EDF300033069C /* sync_impl.c */; };
4354FF691D6EE1A70033069C /* NULL.c in Sources */ = {isa = PBXBuildFile; fileRef = 4354FF681D6EE1A70033069C /* NULL.c */; };
@ -189,6 +191,8 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
430BCC462015EE800077E998 /* pEp_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pEp_string.h; path = ../src/pEp_string.h; sourceTree = "<group>"; };
430BCC472015EE800077E998 /* pEp_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pEp_string.c; path = ../src/pEp_string.c; sourceTree = "<group>"; };
430D258A1C9ED75A00B94535 /* blacklist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = blacklist.c; path = ../src/blacklist.c; sourceTree = "<group>"; };
4346F86A1ECB38E700381CBE /* sync_app.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = sync_app.h; path = ../src/sync_app.h; sourceTree = "<group>"; };
4354FF641D6EDF300033069C /* sync_impl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sync_impl.c; path = ../src/sync_impl.c; sourceTree = "<group>"; };
@ -508,6 +512,8 @@
64A8264B1B455C5600EECAF0 /* srcref */ = {
isa = PBXGroup;
children = (
430BCC472015EE800077E998 /* pEp_string.c */,
430BCC462015EE800077E998 /* pEp_string.h */,
43F6921C1F164A47009418F5 /* resource_id.c */,
43BA0F451D7964750059172F /* asn1_helper.c */,
4354FF641D6EDF300033069C /* sync_impl.c */,
@ -617,6 +623,7 @@
646C41481D510D2C00C63EFF /* sync_fsm.h in Headers */,
64A8268C1B455D9D00EECAF0 /* pEpEngine.h in Headers */,
646C41091D510CD800C63EFF /* constr_TYPE.h in Headers */,
430BCC482015EE800077E998 /* pEp_string.h in Headers */,
646C410D1D510CD800C63EFF /* der_encoder.h in Headers */,
646C41231D510CD800C63EFF /* NativeEnumerated.h in Headers */,
646C41071D510CD800C63EFF /* constr_SET_OF.h in Headers */,
@ -852,6 +859,7 @@
646C412A1D510CD800C63EFF /* per_encoder.c in Sources */,
646C412E1D510CD800C63EFF /* per_support.c in Sources */,
64A826781B455D0800EECAF0 /* bloblist.c in Sources */,
430BCC492015EE800077E998 /* pEp_string.c in Sources */,
646C41041D510CD800C63EFF /* constr_SEQUENCE.c in Sources */,
64A826881B455D0800EECAF0 /* timestamp.c in Sources */,
646C41221D510CD800C63EFF /* NativeEnumerated.c in Sources */,

@ -99,7 +99,7 @@ ifeq ($(BUILD_FOR),Linux)
CFLAGS+= -w
endif
ifdef DEBUG
CFLAGS+= -Og -ggdb -DDEBUG_ERRORSTACK
CFLAGS+= -g -ggdb -DDEBUG_ERRORSTACK
else
CFLAGS+= -O3 -DNDEBUG
endif
@ -148,7 +148,7 @@ ifeq ($(BUILD_FOR),Linux)
CXXFLAGS+= -w
endif
ifdef DEBUG
CXXFLAGS+= -Og -ggdb
CXXFLAGS+= -g -ggdb
else
CXXFLAGS+= -O3 -DNDEBUG
endif

@ -87,7 +87,10 @@ install: $(TARGET)
mkdir -p "$(PREFIX)/lib/"
cp $< $(PREFIX)/lib/
mkdir -p $(PREFIX)/include/pEp
cp pEpEngine.h keymanagement.h message_api.h dynamic_api.h stringlist.h timestamp.h identity_list.h bloblist.h stringpair.h message.h mime.h cryptotech.h sync.h sync_fsm.h sync_app.h blacklist.h openpgp_compat.h $(PREFIX)/include/pEp/
cp -v pEpEngine.h keymanagement.h message_api.h dynamic_api.h stringlist.h \
timestamp.h identity_list.h bloblist.h stringpair.h message.h mime.h \
cryptotech.h sync.h sync_fsm.h sync_app.h blacklist.h pEp_string.h \
openpgp_compat.h $(PREFIX)/include/pEp/
.PHONY: uninstall
uninstall:

@ -14,6 +14,13 @@ extern "C" {
// parameters:
// session (in) session to use
// fpr (in) fingerprint of key to blacklist
//
// caveat:
// there is no point in blacklisting an own key; for any own
// identity, this will be ignored. The correct function to use
// for own keys in this event is "key_reset_trust".
// Also, this is only effective for OpenPGP-level trust. If
// this key is for a pEp user, the blacklist is ignored.
DYNAMIC_API PEP_STATUS blacklist_add(PEP_SESSION session, const char *fpr);

@ -1,17 +1,17 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#include "pEp_internal.h"
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "platform.h"
#include "bloblist.h"
static bool set_blob_data(bloblist_t* bloblist, char* blob, size_t size, const char* mime_type,
const char* filename) {
const char* filename)
{
if (!bloblist)
return false;
@ -30,9 +30,8 @@ static bool set_blob_data(bloblist_t* bloblist, char* blob, size_t size, const c
}
/* Default behaviour, can be overwritten post-allocation with
set_blob_content_disposition */
if (strstr(filename, "cid://") == filename)
if (strncmp(filename, "cid://", 6) == 0)
bloblist->disposition = PEP_CONTENT_DISP_INLINE;
}
if (blob) {
@ -65,7 +64,10 @@ DYNAMIC_API void free_bloblist(bloblist_t *bloblist)
while (curr) {
bloblist_t *next = curr->next;
free(curr->value);
if (curr->release_value)
curr->release_value(curr->value);
else
free(curr->value);
free(curr->mime_type);
free(curr->filename);
free(curr);
@ -126,14 +128,15 @@ DYNAMIC_API bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t si
const char *mime_type, const char *filename)
{
assert(blob);
if (blob == NULL)
if (!blob)
return NULL;
if (bloblist == NULL)
if (!bloblist)
return new_bloblist(blob, size, mime_type, filename);
if (bloblist->value == NULL) { // empty list
if (bloblist->next != NULL)
if (!bloblist->value) { // empty list
assert(!bloblist->next);
if (bloblist->next)
return NULL; // invalid list
if (!set_blob_data(bloblist, blob, size, mime_type, filename)) {
@ -145,18 +148,19 @@ DYNAMIC_API bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t si
}
bloblist_t* list_curr = bloblist;
void (*release_value)(char *) = list_curr->release_value;
while (list_curr->next)
list_curr = list_curr->next;
list_curr->next = new_bloblist(blob, size, mime_type, filename);
list_curr->release_value = release_value;
assert(list_curr->next);
if (list_curr->next == NULL)
if (!list_curr->next)
return NULL;
return list_curr->next;
}
DYNAMIC_API int bloblist_length(const bloblist_t *bloblist)
@ -170,7 +174,8 @@ DYNAMIC_API int bloblist_length(const bloblist_t *bloblist)
}
DYNAMIC_API void set_blob_disposition(bloblist_t* blob,
content_disposition_type disposition) {
content_disposition_type disposition)
{
if (blob)
blob->disposition = disposition;
}

@ -17,15 +17,18 @@ typedef enum {
} content_disposition_type;
typedef struct _bloblist_t {
char *value; // blob
size_t size; // size of blob
char *mime_type; // UTF-8 string of MIME type of blob or
// NULL if unknown
char *filename; // UTF-8 string of file name of blob or
// NULL if unknown
content_disposition_type disposition; // default is attachment when allocated
// (see mime.h and RFC2183)
struct _bloblist_t *next;
char *value; // blob
size_t size; // size of blob
char *mime_type; // UTF-8 string of MIME type of blob or
// NULL if unknown
char *filename; // UTF-8 string of file name of blob or
// NULL if unknown
content_disposition_type disposition;
// default is attachment when allocated
// (see mime.h and RFC2183)
struct _bloblist_t *next; // this is a single linked list
void (*release_value)(char *); // pointer to release function;
// pEp_free() if not set
} bloblist_t;
@ -43,6 +46,10 @@ typedef struct _bloblist_t {
// caveat:
// the ownership of the blob goes to the bloblist; mime_type and filename
// are being copied, the originals remain in the ownership of the caller
//
// if blob is on a different heap then after the call release_value has to
// be set by the adapter; this is relevant on operating systems with
// multiple heaps like Microsoft Windows
DYNAMIC_API bloblist_t *new_bloblist(char *blob, size_t size, const char *mime_type,
const char *filename);
@ -69,6 +76,7 @@ DYNAMIC_API void free_bloblist(bloblist_t *bloblist);
DYNAMIC_API bloblist_t *bloblist_dup(const bloblist_t *src);
// bloblist_add() - add reference to a blob to bloblist
//
// parameters:
@ -87,6 +95,9 @@ DYNAMIC_API bloblist_t *bloblist_dup(const bloblist_t *src);
// are being copied, the originals remain in the ownership of the caller.
// bloblist input parameter equal to NULL or with value == NULL is a valid
// empty input list.
//
// If there is release_value set in bloblist it is copied to the added
// leaf
DYNAMIC_API bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t size,
const char *mime_type, const char *filename);
@ -102,6 +113,7 @@ DYNAMIC_API bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t si
DYNAMIC_API int bloblist_length(const bloblist_t *bloblist);
// set_blob_content_disposition() - set blob content disposition and parameters
// when necessary
//
@ -110,9 +122,7 @@ DYNAMIC_API int bloblist_length(const bloblist_t *bloblist);
// disposition (in) disposition type (see enum)
DYNAMIC_API void set_blob_disposition(bloblist_t* blob,
content_disposition_type disposition);
content_disposition_type disposition);
#ifdef __cplusplus

File diff suppressed because it is too large Load Diff

@ -14,39 +14,98 @@ extern "C" {
// parameters:
// session (in) session to use
// identity (inout) identity information of communication partner
// (identity->fpr is OUT ONLY)
// (identity->fpr is OUT ONLY), and at least
// .address must be set.
// If .username is set, it will be used to set or patch
// the username record for this identity.
// return value:
// PEP_STATUS_OK if identity could be updated,
// PEP_GET_KEY_FAILED for own identity that must be completed (myself())
// PEP_ILLEGAL_VALUE if called with illegal inputs, including an identity
// with .me set or with an own user_id specified in the
// *input* (see caveats)
// PEP_KEY_UNSUITABLE if a default key was found for this identity, no
// other acceptable keys were found; if this is returned,
// the reason for rejecting the first default key found
// may be found in the comm_type
// any other value on error
//
// caveat:
// if this function returns PEP_ct_unknown or PEP_ct_key_expired in
// identity->comm_type, the caller must insert the identity into the
// asynchronous management implementation, so retrieve_next_identity()
// will return this identity later
// at least identity->address must be a non-empty UTF-8 string as input
// update_identity() never writes flags; use set_identity_flags() for
// writing
// this function NEVER reads the incoming fpr, only writes to it.
// this function will fail if called on an identity which, with its input
// values, *explicitly* indicates it is an own identity (i.e. .me is set
// to true on input, or a user_id is given AND it is a known own user_id).
// however, it can RETURN an own identity if this is not indicated a
// priori, and in fact will do so with prejudice when not faced with a
// matching default (i.e. it is forced to search by address only).
// if the identity is known to be an own identity (or the caller wishes
// to make it one), call myself() on the identity instead.
//
// FIXME: is this next point accurate?
// if this function returns PEP_ct_unknown or PEP_ct_key_expired in
// identity->comm_type, the caller must insert the identity into the
// asynchronous management implementation, so retrieve_next_identity()
// will return this identity later
// END FIXME
DYNAMIC_API PEP_STATUS update_identity(
PEP_SESSION session, pEp_identity * identity
);
// initialise_own_identities () - ensures that an own identity is complete
//
// parameters:
// session (in) session to use
// my_idents (inout) identities of local user to quick-set
// For these, at least .address must be set.
// if no .user_id is set, AND the DB doesn't contain
// a default user_id, PEP_OWN_USERID will be used and
// become the perennial default for the DB.
//
// return value:
// PEP_STATUS_OK if identity could be set,
// any other value on error
//
// caveat:
// this function does NOT generate keypairs. It is intended to
// precede running of the engine on actual messages. It effectively
// behaves like myself(), but when there would normally be key generation
// (when there is no valid key, for example),
// it instead stores an identity without keys.
//
// N.B. to adapter devs - this function is likely unnecessary, so please
// do not put work into exposing it yet. Tickets will be filed if need be.
DYNAMIC_API PEP_STATUS initialise_own_identities(PEP_SESSION session,
identity_list* my_idents);
// myself() - ensures that the own identity is being complete
// myself() - ensures that an own identity is complete
//
// parameters:
// session (in) session to use
// identity (inout) identity of local user
// at least .address, .username, .user_id must be set
// both .address and .user_id must be set.
// if .fpr is set, an attempt will be made to make
// that the default key for this identity after key
// validation
// if .fpr is not set, key retrieval is performed
// If .username is set, it will be used to set or patch
// the username record for this identity.
//
// return value:
// PEP_STATUS_OK if identity could be completed or was already complete,
// any other value on error
//
// caveat:
// If an fpr was entered and is not a valid key, the reason for failure
// is immediately returned in the status and, possibly, identity->comm_type
// If a default own user_id exists in the database, an alias will
// be created for the default for the input user_id. The ENGINE'S default
// user_id is always returned in the .user_id field
// myself() NEVER elects keys from the keyring; it will only choose keys
// which have been set up explicitly via myself(), or which were imported
// during a first time DB setup from an OpenPGP keyring (compatibility only)
// this function generates a keypair on demand; because it's synchronous
// it can need a decent amount of time to return
// if you need to do this asynchronous, you need to return an identity
@ -130,6 +189,15 @@ DYNAMIC_API PEP_STATUS do_keymanagement(
// parameters:
// session (in) session to use
// ident (in) person and key which was compromised
// caveat:
// ident is INPUT ONLY. If you want updated trust on the identity, you'll have
// to call update_identity or myself respectively after this.
// N.B. If you are calling this on a key that is the identity or user default,
// it will be removed as the default key for ANY identity and user for which
// it is the default. Please keep in mind that the undo in undo_last_mistrust
// will only undo the current identity's / it's user's default, not any
// other identities which may be impacted (this will not affect most use
// cases)
DYNAMIC_API PEP_STATUS key_mistrusted(
PEP_SESSION session,
@ -155,7 +223,7 @@ DYNAMIC_API PEP_STATUS key_mistrusted(
DYNAMIC_API PEP_STATUS undo_last_mistrust(PEP_SESSION session);
// trust_personal_key() - mark a key as trusted with a person
// trust_personal_key() - mark a key as trusted for a user
//
// parameters:
// session (in) session to use
@ -163,6 +231,11 @@ DYNAMIC_API PEP_STATUS undo_last_mistrust(PEP_SESSION session);
//
// caveat:
// the fields user_id, address and fpr must be supplied
// for non-own users, this will 1) set the trust bit on its comm type in the DN,
// 2) set this key as the identity default if the current identity default
// is not trusted, and 3) set this key as the user default if the current
// user default is not trusted.
// For an own user, this is simply a call to myself().
DYNAMIC_API PEP_STATUS trust_personal_key(
PEP_SESSION session,
@ -170,12 +243,18 @@ DYNAMIC_API PEP_STATUS trust_personal_key(
);
// key_reset_trust() - undo trust_personal_key and key_mistrusted() for keys
// we don't own
//
// key_reset_trust() - reset trust bit or explicitly mistrusted status for an identity and
// its accompanying key/user_id pair.
// parameters:
// session (in) session to use
// ident (in) person and key which was compromized
// ident (in) identity for person and key whose trust status is to be reset
//
// caveat:
// ident is INPUT ONLY. If you want updated trust on the identity, you'll have
// to call update_identity or myself respectively after this.
// N.B. If you are calling this on a key that is the identity or user default,
// it will be removed as the default key for the identity and user (but is still
// available for key election, it is just not the cached default anymore)
DYNAMIC_API PEP_STATUS key_reset_trust(
PEP_SESSION session,
@ -263,6 +342,8 @@ DYNAMIC_API PEP_STATUS set_own_key(
const char *fpr
);
PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags);
#ifdef __cplusplus
}
#endif

@ -920,6 +920,33 @@ enomem:
return NULL;
}
static PEP_STATUS update_identity_recip_list(PEP_SESSION session,
identity_list* list) {
PEP_STATUS status = PEP_STATUS_OK;
if (!session)
return PEP_UNKNOWN_ERROR;
identity_list* id_list_ptr = NULL;
for (id_list_ptr = list; id_list_ptr; id_list_ptr = id_list_ptr->next) {
pEp_identity* curr_identity = id_list_ptr->ident;
if (curr_identity) {
if (!is_me(session, curr_identity))
status = update_identity(session, curr_identity);
else
status = myself(session, curr_identity);
if (status == PEP_ILLEGAL_VALUE || status == PEP_OUT_OF_MEMORY)
return status;
}
else
break;
}
return PEP_STATUS_OK;
}
static PEP_STATUS encrypt_PGP_MIME(
PEP_SESSION session,
const message *src,
@ -1206,13 +1233,17 @@ static PEP_rating keylist_rating(PEP_SESSION session, stringlist_t *keylist, cha
return rating;
}
// Internal function WARNING:
// Only call this on an ident that might have its FPR set from retrieval!
// (or on one without an fpr)
// We do not want myself() setting the fpr here.
static PEP_comm_type _get_comm_type(
PEP_SESSION session,
PEP_comm_type max_comm_type,
pEp_identity *ident
)
{
PEP_STATUS status = update_identity(session, ident);
PEP_STATUS status = PEP_STATUS_OK;
if (max_comm_type == PEP_ct_compromized)
return PEP_ct_compromized;
@ -1220,6 +1251,11 @@ static PEP_comm_type _get_comm_type(
if (max_comm_type == PEP_ct_mistrusted)
return PEP_ct_mistrusted;
if (!is_me(session, ident))
status = update_identity(session, ident);
else
status = myself(session, ident);
if (status == PEP_STATUS_OK) {
if (ident->comm_type == PEP_ct_compromized)
return PEP_ct_compromized;
@ -1433,6 +1469,15 @@ DYNAMIC_API PEP_STATUS encrypt_message(
*dst = NULL;
if (src->from && (!src->from->user_id || src->from->user_id[0] == '\0')) {
char* own_id = NULL;
status = get_default_own_userid(session, &own_id);
if (own_id) {
free(src->from->user_id);
src->from->user_id = own_id; // ownership transfer
}
}
status = myself(session, src->from);
if (status != PEP_STATUS_OK)
GOTO(pep_error);
@ -1466,7 +1511,16 @@ DYNAMIC_API PEP_STATUS encrypt_message(
return PEP_ILLEGAL_VALUE;
}
PEP_STATUS _status = update_identity(session, _il->ident);
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;
}
}
else
_status = myself(session, _il->ident);
if (_status != PEP_STATUS_OK) {
status = _status;
GOTO(pep_error);
@ -1487,7 +1541,16 @@ DYNAMIC_API PEP_STATUS encrypt_message(
else
{
for (_il = src->to; _il && _il->ident; _il = _il->next) {
PEP_STATUS _status = update_identity(session, _il->ident);
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;
}
}
else
_status = myself(session, _il->ident);
if (_status != PEP_STATUS_OK) {
status = _status;
GOTO(pep_error);
@ -1507,7 +1570,16 @@ DYNAMIC_API PEP_STATUS encrypt_message(
}
for (_il = src->cc; _il && _il->ident; _il = _il->next) {
PEP_STATUS _status = update_identity(session, _il->ident);
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;
}
}
else
_status = myself(session, _il->ident);
if (_status != PEP_STATUS_OK)
{
status = _status;
@ -1659,18 +1731,26 @@ DYNAMIC_API PEP_STATUS encrypt_message_for_self(
if (src->enc_format != PEP_enc_none)
return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
if (target_id && (!target_id->user_id || target_id->user_id[0] == '\0')) {
char* own_id = NULL;
status = get_default_own_userid(session, &own_id);
if (own_id) {
free(target_id->user_id);
target_id->user_id = own_id; // ownership transfer
}
}
status = myself(session, target_id);
if (status != PEP_STATUS_OK)
GOTO(pep_error);
*dst = NULL;
PEP_STATUS _status = update_identity(session, target_id);
if (_status != PEP_STATUS_OK) {
status = _status;
goto pep_error;
}
// PEP_STATUS _status = update_identity(session, target_id);
// if (_status != PEP_STATUS_OK) {
// status = _status;
// goto pep_error;
// }
char* target_fpr = target_id->fpr;
if (!target_fpr)
@ -1749,8 +1829,12 @@ static PEP_STATUS _update_identity_for_incoming_message(
)
{
PEP_STATUS status;
if (src->from && src->from->address) {
status = update_identity(session, src->from);
if (!is_me(session, src->from))
status = update_identity(session, src->from);
else
status = myself(session, src->from);
if (status == PEP_STATUS_OK
&& is_a_pEpmessage(src)
&& src->from->comm_type >= PEP_ct_OpenPGP_unconfirmed
@ -1958,11 +2042,15 @@ static PEP_STATUS amend_rating_according_to_sender_and_recipients(
return PEP_OUT_OF_MEMORY;
status = get_trust(session, _sender);
if (_sender->comm_type == PEP_ct_unknown) {
get_key_rating(session, fpr, &_sender->comm_type);
}
if (_sender->comm_type != PEP_ct_unknown) {
*rating = keylist_rating(session, recipients,
fpr, _rating(_sender->comm_type,
PEP_rating_undefined));
}
free_identity(_sender);
if (status == PEP_CANNOT_FIND_IDENTITY)
status = PEP_STATUS_OK;
@ -2304,14 +2392,37 @@ static PEP_STATUS import_priv_keys_from_decrypted_msg(PEP_SESSION session,
_private_il->ident->address)
*imported_private = true;
if (private_il && imported_private)
if (private_il && imported_private) {
// the private identity list should NOT be subject to myself() or
// update_identity() at this point.
// If the receiving app wants them to be in the trust DB, it
// should call myself() on them upon return.
// We do, however, prepare these so the app can use them
// directly in a myself() call by putting the own_id on it.
char* own_id = NULL;
status = get_default_own_userid(session, &own_id);
if (status != PEP_STATUS_OK) {
free(own_id);
own_id = NULL;
}
identity_list* il = _private_il;
for ( ; il; il = il->next) {
if (own_id) {
free(il->ident->user_id);
il->ident->user_id = strdup(own_id);
}
il->ident->me = true;
}
*private_il = _private_il;
free(own_id);
}
else
free_identity_list(_private_il);
if (imported_keys)
status = _update_identity_for_incoming_message(session, src);
return status;
}
@ -2361,7 +2472,18 @@ DYNAMIC_API PEP_STATUS _decrypt_message(
// Update src->from in case we just imported a key
// we would need to check signature
status = _update_identity_for_incoming_message(session, src);
if(status != PEP_STATUS_OK)
if (status == PEP_ILLEGAL_VALUE && src->from && is_me(session, src->from)) {
// the above function should fail if it's us.
// We don't need to update, as any revocations or expirations
// of our own key imported above, which are all that we
// would care about for anything imported,
// SHOULD get caught when they matter later.
// (Private keys imported above are not stored in the trust DB)
status = PEP_STATUS_OK;
}
if (status != PEP_STATUS_OK)
return ADD_TO_LOG(status);
/*** End Import any attached public keys and update identities accordingly ***/
@ -2522,8 +2644,12 @@ DYNAMIC_API PEP_STATUS _decrypt_message(
// FIXME: free msg, but check references
src = msg = inner_message;
if (src->from)
update_identity(session, src->from);
if (src->from) {
if (!is_me(session, src->from))
update_identity(session, (src->from));
else
myself(session, src->from);
}
break;
}
else { // should never happen
@ -2579,8 +2705,7 @@ DYNAMIC_API PEP_STATUS _decrypt_message(
// 1. Check to see if this message is to us and contains an own key imported
// from own trusted message
if (msg && *rating >= PEP_rating_trusted && imported_private_key_address &&
msg->to->ident->user_id &&
strcmp(msg->to->ident->user_id, PEP_OWN_USERID) == 0) {
msg->to && msg->to->ident && msg->to->ident->me) {
// flag it as such
*flags |= PEP_decrypt_flag_own_private_key;
@ -2682,8 +2807,12 @@ static void _max_comm_type_from_identity_list(
for (il = identities; il != NULL; il = il->next)
{
if (il->ident)
{
PEP_STATUS status = update_identity(session, il->ident);
{
PEP_STATUS status = PEP_STATUS_OK;
if (!is_me(session, il->ident))
status = update_identity(session, il->ident);
else
status = myself(session, il->ident);
if (status == PEP_STATUS_OK)
{
*max_comm_type = _get_comm_type(session, *max_comm_type,
@ -2749,7 +2878,7 @@ DYNAMIC_API PEP_STATUS identity_rating(
if (!(session && ident && rating))
return PEP_ILLEGAL_VALUE;
if (_identity_me(ident))
if (ident->me)
status = _myself(session, ident, false, true);
else
status = update_identity(session, ident);
@ -3123,6 +3252,29 @@ DYNAMIC_API PEP_STATUS MIME_decrypt_message(
if (status != PEP_STATUS_OK)
GOTO(pep_error);
// MIME decode message delivers only addresses. We need more.
if (tmp_msg->from) {
if (!is_me(session, tmp_msg->from))
status = update_identity(session, (tmp_msg->from));
else
status = myself(session, tmp_msg->from);
if (status == PEP_ILLEGAL_VALUE || status == PEP_OUT_OF_MEMORY)
GOTO(pep_error);
}
status = update_identity_recip_list(session, tmp_msg->to);
if (status != PEP_STATUS_OK)
GOTO(pep_error);
status = update_identity_recip_list(session, tmp_msg->cc);
if (status != PEP_STATUS_OK)
GOTO(pep_error);
status = update_identity_recip_list(session, tmp_msg->bcc);
if (status != PEP_STATUS_OK)
GOTO(pep_error);
PEP_STATUS decrypt_status = decrypt_message(session,
tmp_msg,
&dec_msg,
@ -3176,6 +3328,39 @@ DYNAMIC_API PEP_STATUS MIME_encrypt_message(
if (status != PEP_STATUS_OK)
GOTO(pep_error);
// MIME decode message delivers only addresses. We need more.
if (tmp_msg->from) {
char* own_id = NULL;
status = get_default_own_userid(session, &own_id);
free(tmp_msg->from->user_id);
if (status != PEP_STATUS_OK || !own_id) {
tmp_msg->from->user_id = strdup(PEP_OWN_USERID);
}
else {
tmp_msg->from->user_id = own_id; // ownership transfer
}
status = myself(session, tmp_msg->from);
if (status != PEP_STATUS_OK)
GOTO(pep_error);
}
// Own identities can be retrieved here where they would otherwise
// fail because we lack all other information. This is ok and even
// desired. FIXME: IS it?
status = update_identity_recip_list(session, tmp_msg->to);
if (status != PEP_STATUS_OK)
GOTO(pep_error);
status = update_identity_recip_list(session, tmp_msg->cc);
if (status != PEP_STATUS_OK)
GOTO(pep_error);
status = update_identity_recip_list(session, tmp_msg->bcc);
if (status != PEP_STATUS_OK)
GOTO(pep_error);
// This isn't incoming, though... so we need to reverse the direction
tmp_msg->dir = PEP_dir_outgoing;
status = encrypt_message(session,
@ -3375,7 +3560,11 @@ got_rating:
}
got_keylist:
status = update_identity(session, msg->from);
if (!is_me(session, msg->from))
status = update_identity(session, msg->from);
else
status = myself(session, msg->from);
if (status != PEP_STATUS_OK)
GOTO(pep_error);

File diff suppressed because it is too large Load Diff

@ -37,6 +37,9 @@ typedef enum {
PEP_INIT_GPGME_INIT_FAILED = 0x0111,
PEP_INIT_NO_GPG_HOME = 0x0112,
PEP_INIT_NETPGP_INIT_FAILED = 0x0113,
PEP_INIT_CANNOT_DETERMINE_GPG_VERSION = 0x0114,
PEP_INIT_UNSUPPORTED_GPG_VERSION = 0x0115,
PEP_INIT_CANNOT_CONFIG_GPG_AGENT = 0x0116,
PEP_INIT_SQLITE3_WITHOUT_MUTEX = 0x0120,
PEP_INIT_CANNOT_OPEN_DB = 0x0121,
@ -47,6 +50,7 @@ typedef enum {
PEP_GET_KEY_FAILED = 0x0203,
PEP_CANNOT_EXPORT_KEY = 0x0204,
PEP_CANNOT_EDIT_KEY = 0x0205,
PEP_KEY_UNSUITABLE = 0x0206,
PEP_CANNOT_FIND_IDENTITY = 0x0301,
PEP_CANNOT_SET_PERSON = 0x0381,
@ -54,6 +58,10 @@ typedef enum {
PEP_CANNOT_SET_IDENTITY = 0x0383,
PEP_CANNOT_SET_TRUST = 0x0384,
PEP_KEY_BLACKLISTED = 0x0385,
PEP_CANNOT_FIND_PERSON = 0x0386,
PEP_CANNOT_FIND_ALIAS = 0x0391,
PEP_CANNOT_SET_ALIAS = 0x0392,
PEP_UNENCRYPTED = 0x0400,
PEP_VERIFIED = 0x0401,
@ -470,7 +478,6 @@ typedef enum _identity_flags {
// the first octet flags are app defined settings
PEP_idf_not_for_sync = 0x0001, // don't use this identity for sync
PEP_idf_list = 0x0002, // identity of list of persons
// the second octet flags are calculated
PEP_idf_devicegroup = 0x0100 // identity of a device group member
} identity_flags;
@ -486,13 +493,15 @@ typedef struct _pEp_identity {
char *address; // C string with address UTF-8 encoded
char *fpr; // C string with fingerprint UTF-8 encoded
char *user_id; // C string with user ID UTF-8 encoded
// user_id must be set to "pEp_own_userId"
// user_id MIGHT be set to "pEp_own_userId"
// (use PEP_OWN_USERID preprocessor define)
// if this is own user's identity.
// But it is not REQUIRED to be.
char *username; // C string with user name UTF-8 encoded
PEP_comm_type comm_type; // type of communication with this ID
char lang[3]; // language of conversation
// ISO 639-1 ALPHA-2, last byte is 0
bool me; // if this is the local user herself/himself
identity_flags_t flags; // identity_flag1 | identity_flag2 | ...
} pEp_identity;
@ -600,6 +609,67 @@ DYNAMIC_API PEP_STATUS set_identity(
PEP_SESSION session, const pEp_identity *identity
);
// get_default own_userid() - get the user_id of the own user
//
// parameters:
// session (in) session handle
// userid (out) own user id (if it exists)
//
// return value:
// PEP_STATUS_OK = 0 userid was found
// PEP_CANNOT_FIND_IDENTITY no own_user found in the DB
// PEP_UNKNOWN_ERROR results were returned, but no ID
// found (no reason this should ever occur)
// caveat:
// userid will be NULL if not found; otherwise, returned string
// belongs to the caller.
DYNAMIC_API PEP_STATUS get_default_own_userid(
PEP_SESSION session,
char** userid
);
// get_userid_alias_default() - get the default user_id which corresponds
// to an alias
// parameters:
// session (in) session handle
// alias_id (in) the user_id which may be an alias for a default id
// default_id (out) the default id for this alias, if the alias
// is in the DB as an alias, else NULL
// return value:
// PEP_STATUS_OK = 0 userid was found
// PEP_CANNOT_FIND_ALIAS this userid is not listed as an
// alias in the DB
// PEP_UNKNOWN_ERROR results were returned, but no ID
// found (no reason this should ever occur)
// caveat:
// default_id will be NULL if not found; otherwise, returned string
// belongs to the caller.
// also, current implementation does NOT check to see if this userid
// IS a default.
DYNAMIC_API PEP_STATUS get_userid_alias_default(
PEP_SESSION session,
const char* alias_id,
char** default_id);
// set_userid_alias() - set an alias to correspond to a default id
// parameters:
// session (in) session handle
// default_id (in) the default id for this alias. This must
// correspond to the default user_id for an
// entry in the person (user) table.
// alias_id (in) the alias to be set for this default id
// return value:
// PEP_STATUS_OK = 0 userid was found
// PEP_CANNOT_SET_ALIAS there was an error setting this
DYNAMIC_API PEP_STATUS set_userid_alias (
PEP_SESSION session,
const char* default_id,
const char* alias_id);
// set_device_group() - update own person's device group
//
// parameters:
@ -853,7 +923,7 @@ DYNAMIC_API void pEp_free(void *p);
// parameters:
// session (in) session handle
// identity (inout) user_id and fpr to check as UTF-8 strings (in)
// user_id and comm_type as result (out)
// comm_type as result (out)
//
// this function modifies the given identity struct; the struct remains in
// the ownership of the caller
@ -1127,6 +1197,38 @@ DYNAMIC_API const char* get_engine_version();
DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session);
// This is used internally when there is a temporary identity to be retrieved
// that may not yet have an FPR attached. See get_identity() for functionality,
// params and caveats.
PEP_STATUS get_identity_without_trust_check(
PEP_SESSION session,
const char *address,
const char *user_id,
pEp_identity **identity
);
PEP_STATUS get_identities_by_address(
PEP_SESSION session,
const char *address,
identity_list** id_list
);
PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
const char* new_uid);
PEP_STATUS remove_fpr_as_default(PEP_SESSION session,
const char* fpr);
PEP_STATUS get_main_user_fpr(PEP_SESSION session,
const char* user_id,
char** main_fpr);
PEP_STATUS replace_main_user_fpr(PEP_SESSION session, const char* user_id,
const char* new_fpr);
PEP_STATUS refresh_userid_default_key(PEP_SESSION session, const char* user_id);
#ifdef __cplusplus
}
#endif

@ -82,7 +82,6 @@
#include "sqlite3.h"
#endif
#define _EXPORT_PEP_ENGINE_DLL
#include "pEpEngine.h"
// If not specified, build for GPG
@ -124,7 +123,13 @@ struct _pEpSession {
sqlite3_stmt *log;
sqlite3_stmt *trustword;
sqlite3_stmt *get_identity;
sqlite3_stmt *get_identity_without_trust_check;
sqlite3_stmt *get_identities_by_address;
sqlite3_stmt *replace_identities_fpr;
sqlite3_stmt *replace_main_user_fpr;
sqlite3_stmt *get_main_user_fpr;
sqlite3_stmt *refresh_userid_default_key;
sqlite3_stmt *remove_fpr_as_default;
sqlite3_stmt *set_person;
sqlite3_stmt *set_device_group;
sqlite3_stmt *get_device_group;
@ -141,6 +146,7 @@ struct _pEpSession {
sqlite3_stmt *crashdump;
sqlite3_stmt *languagelist;
sqlite3_stmt *i18n_token;
sqlite3_stmt *replace_userid;
// blacklist
sqlite3_stmt *blacklist_add;
@ -152,7 +158,11 @@ struct _pEpSession {
sqlite3_stmt *own_key_is_listed;
sqlite3_stmt *own_identities_retrieve;
sqlite3_stmt *own_keys_retrieve;
sqlite3_stmt *set_own_key;
sqlite3_stmt *get_user_default_key;
sqlite3_stmt *get_default_own_userid;
// sqlite3_stmt *set_own_key;
// sequence value
sqlite3_stmt *sequence_value1;
@ -163,6 +173,10 @@ struct _pEpSession {
sqlite3_stmt *set_revoked;
sqlite3_stmt *get_revoked;
// aliases
sqlite3_stmt *get_userid_alias_default;
sqlite3_stmt *add_userid_alias;
// callbacks
examine_identity_t examine_identity;
void *examine_management;
@ -340,13 +354,6 @@ static inline int _same_fpr(
return comparison == 0;
}
static inline bool _identity_me(
pEp_identity * identity
)
{
return identity->user_id && strcmp(identity->user_id, PEP_OWN_USERID) == 0;
}
// size is the length of the bytestr that's coming in. This is really only intended
// for comparing two full strings. If charstr's length is different from bytestr_size,
// we'll return a non-zero value.
@ -369,6 +376,32 @@ static inline char* _pep_subj_copy() {
#endif
}
static inline bool is_me(PEP_SESSION session, pEp_identity* test_ident) {
bool retval = false;
if (test_ident && test_ident->user_id) {
char* def_id = NULL;
get_default_own_userid(session, &def_id);
if (test_ident->me ||
(def_id && strcmp(def_id, test_ident->user_id) == 0)) {
retval = true;
}
free(def_id);
}
return retval;
}
#ifndef EMPTYSTR
#define EMPTYSTR(STR) ((STR) == NULL || (STR)[0] == '\0')
#endif
#ifndef _MIN
#define _MIN(A, B) ((B) > (A) ? (A) : (B))
#endif
#ifndef _MAX
#define _MAX(A, B) ((B) > (A) ? (B) : (A))
#endif
// These are globals used in generating message IDs and should only be
// computed once, as they're either really constants or OS-dependent

@ -1,6 +1,7 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#include "platform.h"
#include "pEp_string.h"
#include <stdlib.h>
@ -8,10 +9,6 @@
DYNAMIC_API char * new_string(const char *src, size_t len)
{
assert(src || len);
if (!(src || len))
return NULL;
char *s = NULL;
if (src) {
if (len)
@ -21,7 +18,7 @@ DYNAMIC_API char * new_string(const char *src, size_t len)
assert(s);
}
else {
s = calloc(1, len);
s = calloc(1, len + 1);
assert(s);
}

@ -20,12 +20,9 @@ extern "C" {
// return value:
// pointer to string object or NULL if out of memory
//
// caveat:
// one of the two parameters has to be set at least
//
// calling with str and len is equivalent to strndup()
// calling with str but len=0 is equivalent to strdup()
// calling with str=NULL and len is equivalent to calloc()
// calling with str=NULL is equivalent to calloc()
DYNAMIC_API char * new_string(const char *src, size_t len);

@ -174,6 +174,55 @@ static bool _email_heuristic_match(const char* str1, const char* str2) {
return false;
}
static PEP_STATUS _version_test(const char *s)
{
char *_s = strdup(s);
if (!_s)
return PEP_OUT_OF_MEMORY;
int major;
int minor;
int revision;
char *lasts = NULL;
char *p = strtok_r(_s, ".", &lasts);
if (!p)
goto unsupported;
else
major = atoi(p);
p = strtok_r(NULL, ".", &lasts);
if (!p)
goto unsupported;
else
minor = atoi(p);
p = strtok_r(NULL, ".", &lasts);
if (!p)
goto unsupported;
else
revision = atoi(p);
free(_s);
_s = NULL;
if (major > 2)
return PEP_STATUS_OK;
if (major == 2 && minor > 1)
return PEP_STATUS_OK;
if (major == 2 && minor == 0 && revision == 30)
return PEP_STATUS_OK;
if (major == 2 && minor == 1 && revision >= 17)
return PEP_STATUS_OK;
unsupported:
free(_s);
return PEP_INIT_UNSUPPORTED_GPG_VERSION;
}
PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
{
PEP_STATUS status = PEP_STATUS_OK;
@ -202,13 +251,16 @@ PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
stringlist_add(conf_keys, "ignore-time-conflict");
stringlist_add(conf_values, "");
stringlist_add(conf_keys, "allow-freeform-uid");
stringlist_add(conf_values, "");
bResult = ensure_config_values(conf_keys, conf_values, gpg_conf());
free_stringlist(conf_keys);
free_stringlist(conf_values);
assert(bResult);
if(!bResult){
if (!bResult) {
status = PEP_INIT_NO_GPG_HOME;
goto pep_error;
}
@ -225,8 +277,8 @@ PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
free_stringlist(conf_values);
assert(bResult);
if(!bResult){
status = PEP_INIT_NO_GPG_HOME; /* FIXME: Wrong error here? */
if (!bResult) {
status = PEP_INIT_CANNOT_CONFIG_GPG_AGENT;
goto pep_error;
}
@ -238,6 +290,25 @@ PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
memset(&gpg, 0, sizeof(struct gpg_s));
gpg.gpgme_get_engine_info
= (gpgme_get_engine_info_t) (intptr_t) dlsym(gpgme,
"gpgme_get_engine_info");
assert(gpg.gpgme_get_engine_info);
gpgme_engine_info_t info;
int err = gpg.gpgme_get_engine_info(&info);
assert(err == GPG_ERR_NO_ERROR);
if (err != GPG_ERR_NO_ERROR)
return PEP_OUT_OF_MEMORY;
assert(info->version);
if (!info->version)
return PEP_INIT_CANNOT_DETERMINE_GPG_VERSION;
status = _version_test(info->version);
if (status != PEP_STATUS_OK)
return status;
gpg.gpgme_set_locale
= (gpgme_set_locale_t) (intptr_t) dlsym(gpgme,
"gpgme_set_locale");
@ -256,11 +327,6 @@ PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
= (gpgme_release_t) (intptr_t) dlsym(gpgme, "gpgme_release");
assert(gpg.gpgme_release);
gpg.gpgme_get_engine_info
= (gpgme_get_engine_info_t) (intptr_t) dlsym(gpgme,
"gpgme_get_engine_info");
assert(gpg.gpgme_get_engine_info);
gpg.gpgme_set_protocol
= (gpgme_set_protocol_t) (intptr_t) dlsym(gpgme,
"gpgme_set_protocol");

@ -42,7 +42,7 @@ PEP_STATUS pgp_find_keys(
);
PEP_STATUS pgp_list_keyinfo(
PEP_SESSION session, const char* pattern, stringpair_list_t** keyinfo_list
PEP_SESSION session, const char* pattern, stringpair_list_t** keyinfo_list
);
PEP_STATUS pgp_generate_keypair(

@ -5,15 +5,16 @@
// Windows platform specifica
#define _EXPORT_PEP_ENGINE_DLL
#pragma warning(disable : 4996)
// We need to make sure winsock2 is included before windows.h, or we will get redefinitions of symbols
// as windows.h includes winsock1.h, so we will have duplicate symbols if windows.h is included first.
// It seems some of our code includes sync.h before including winsock.h, leading to the failure.
// Including winsock2.h here fixes the problem for now...
#ifdef WIN32
#include <winsock2.h>
#endif // WIN32
// We need to make sure winsock2 is included before windows.h, or we will get redefinitions of symbols
// as windows.h includes winsock1.h, so we will have duplicate symbols if windows.h is included first.
// It seems some of our code includes sync.h before including winsock.h, leading to the failure.
// Including winsock2.h here fixes the problem for now...
#ifdef WIN32
#include <winsock2.h>
#endif // WIN32
#include <Rpc.h>
#include <string.h>
@ -85,7 +86,7 @@ void uuid_generate_random(pEpUUID out);
int uuid_parse(char *in, pEpUUID uu);
void uuid_unparse_upper(pEpUUID uu, uuid_string_t out);
#ifndef inline
#ifndef __cplusplus
#define inline __inline
#endif

@ -56,8 +56,14 @@ int keyElectionWon(PEP_SESSION session, Identity partner)
// key created first wins
Identity me = NULL;
PEP_STATUS status = get_identity(session, partner->address, PEP_OWN_USERID,
&me);
char* own_id = NULL;
PEP_STATUS status = get_default_own_userid(session, &own_id);
if (own_id) {
status = get_identity(session, partner->address, own_id,
&me);
free(own_id);
}