Browse Source

Merge default

doc_update_sequoia
Damiano Boppart 5 years ago
parent
commit
cc1c02b344
28 changed files with 1654 additions and 867 deletions
  1. +0
    -3
      Makefile
  2. +7
    -4
      Makefile.conf
  3. +2
    -2
      build-mac/pEpEngine.xcodeproj/project.pbxproj
  4. +2
    -2
      build-windows/pEpEngine.vcxproj
  5. +1
    -1
      doc/build-debian.md
  6. +10
    -5
      src/etpan_mime.c
  7. +2
    -1
      src/etpan_mime.h
  8. +26
    -0
      src/keymanagement.c
  9. +20
    -2
      src/keymanagement.h
  10. +0
    -1
      src/message.h
  11. +1176
    -777
      src/message_api.c
  12. +5
    -1
      src/message_api.h
  13. +55
    -27
      src/mime.c
  14. +13
    -0
      src/mime.h
  15. +49
    -10
      src/pEpEngine.c
  16. +8
    -1
      src/pEpEngine.h
  17. +29
    -1
      src/pEp_internal.h
  18. +14
    -12
      src/pgp_gpg.c
  19. +14
    -2
      src/platform_unix.c
  20. +2
    -2
      src/platform_windows.cpp
  21. +5
    -7
      test/Makefile
  22. +7
    -2
      test/external_revoke_test.cc
  23. +0
    -1
      test/mime_test.cc
  24. +75
    -0
      test/mistrust_undo_test.cc
  25. +44
    -1
      test/pEpEngineTest.cc
  26. +1
    -2
      test/revoke_regen_attach_test.cc
  27. +57
    -0
      test/test_keys/priv/mistrust.undo.test-0x39E5DAB5_priv.asc
  28. +30
    -0
      test/test_keys/pub/mistrust.undo.test-0x39E5DAB5_pub.asc

+ 0
- 3
Makefile View File

@ -7,9 +7,6 @@ HERE_REL := $(notdir $(CURDIR))
include Makefile.conf
# YML_PATH is needed in the environment of every call to a program of the YML2 distribution
export YML_PATH=$(YML2_PATH)
.PHONY: all
all: _override_info
$(MAKE) -C asn.1 generate


+ 7
- 4
Makefile.conf View File

@ -45,12 +45,12 @@ endif
# If empty, create a release build.
# Otherwise, create a debug build.
# This variable is ineffective in your override.conf file.
DEBUG=
# This variable is ineffective in your local.conf file.
DEBUG=YES
# If empty, suppress compiler warnings.
# Otherwise, print warnings.
# This variable is ineffective in your override.conf file.
# This variable is ineffective in your local.conf file.
WARN=placeholder
@ -98,7 +98,7 @@ ifeq ($(BUILD_FOR),Linux)
else
CFLAGS+= -O3 -DNDEBUG
endif
else ifeq ($(BUILD_FOR),Darwin)
else ifeq ($(BUILD_FOR),Darwin)
ifdef WARN
# FIXME Remove 'no-extended-offsetof' after ENGINE-236 is closed.
CFLAGS+= -Wall -pedantic -Wno-extended-offsetof
@ -169,6 +169,8 @@ YML2_PROC=$(YML2_PATH)/yml2proc
YML2_OPTS=--encoding=utf8
# YML_PATH is needed in the environment of every call to a program of the YML2 distribution
export YML_PATH=$(YML2_PATH)
######### asn1c #########
# asn1c binary
@ -195,6 +197,7 @@ SQLITE3_FROM_OS=placeholder
######### OpenPGP #########
# Path of GPG binary
# gpgconf is not available for old version of GPG, for example GPG 2.0.30. Override this variable, if you compile the engine for such an old version.
GPG_CMD:=$(shell gpgconf --list-components | awk -F: '/^gpg:/ { print $$3; exit 0; }')
# Selects OpenPGP implementation. must be either `GPG` or `NETPGP`


+ 2
- 2
build-mac/pEpEngine.xcodeproj/project.pbxproj View File

@ -123,7 +123,6 @@
64A826811B455D0800EECAF0 /* pEpEngine.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A826601B455D0800EECAF0 /* pEpEngine.c */; };
64A826821B455D0800EECAF0 /* pgp_netpgp.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A826631B455D0800EECAF0 /* pgp_netpgp.c */; };
64A826831B455D0800EECAF0 /* platform_unix.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A826651B455D0800EECAF0 /* platform_unix.c */; };
64A826851B455D0800EECAF0 /* sqlite3.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A8266B1B455D0800EECAF0 /* sqlite3.c */; };
64A826861B455D0800EECAF0 /* stringlist.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A8266D1B455D0800EECAF0 /* stringlist.c */; };
64A826871B455D0800EECAF0 /* stringpair.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A8266F1B455D0800EECAF0 /* stringpair.c */; };
64A826881B455D0800EECAF0 /* timestamp.c in Sources */ = {isa = PBXBuildFile; fileRef = 64A826711B455D0800EECAF0 /* timestamp.c */; };
@ -815,7 +814,6 @@
64A826861B455D0800EECAF0 /* stringlist.c in Sources */,
4354FF651D6EDF300033069C /* sync_impl.c in Sources */,
64A8267E1B455D0800EECAF0 /* message_api.c in Sources */,
64A826851B455D0800EECAF0 /* sqlite3.c in Sources */,
43E9BC7F1DB6720E00AD2352 /* UpdateRequest.c in Sources */,
646C41361D510CD800C63EFF /* Version.c in Sources */,
646C41081D510CD800C63EFF /* constr_TYPE.c in Sources */,
@ -959,6 +957,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "-DSQLITE3_FROM_OS";
SDKROOT = iphoneos;
};
name = Debug;
@ -1006,6 +1005,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
ONLY_ACTIVE_ARCH = NO;
OTHER_CFLAGS = "-DSQLITE3_FROM_OS";
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};


+ 2
- 2
build-windows/pEpEngine.vcxproj View File

@ -43,12 +43,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<RunCodeAnalysis>false</RunCodeAnalysis>
<IncludePath>$(ProjectDir)\..\..\libetpan\build-windows\include;C:\Program Files %28x86%29\GNU\GnuPG\include;$(IncludePath);$(ProjectDir)\asn.1;%ASN1C%\share\asn1c</IncludePath>
<IncludePath>$(ProjectDir)\..\..\libetpan\build-windows\include;C:\Program Files %28x86%29\GnuPG\include;$(IncludePath);$(ProjectDir)\asn.1;%ASN1C%\share\asn1c</IncludePath>
<LibraryPath>$(ProjectDir)\..\..\libetpan\build-windows\Debug;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(ProjectDir)\..\..\libetpan\build-windows\include;C:\Program Files %28x86%29\GNU\GnuPG\include;$(IncludePath);$(ProjectDir)\asn.1;%ASN1C%\share\asn1c</IncludePath>
<IncludePath>$(ProjectDir)\..\..\libetpan\build-windows\include;C:\Program Files %28x86%29\GnuPG\include;$(IncludePath);$(ProjectDir)\asn.1;%ASN1C%\share\asn1c</IncludePath>
<LibraryPath>$(ProjectDir)\..\..\libetpan\build-windows\Release;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">


+ 1
- 1
doc/build-debian.md View File

@ -17,7 +17,7 @@ apt install -y git build-essential automake libtool
# asn1c
apt install -y git build-essential automake libtool
# engine
apt install -y uuid-dev libgpgme11-dev libsqlite3-dev sqlite3
apt install -y uuid-dev libgpgme-dev libsqlite3-dev sqlite3
~~~
# Installing unpackaged dependencies


+ 10
- 5
src/etpan_mime.c View File

@ -284,7 +284,8 @@ struct mailmime * get_file_part(
pEp_rid_list_t* resource,
const char * mime_type,
char * data,
size_t length
size_t length,
bool transport_encode
)
{
char * disposition_name = NULL;
@ -330,10 +331,14 @@ struct mailmime * get_file_part(
if (content == NULL)
goto enomem;
encoding_type = MAILMIME_MECHANISM_BASE64;
encoding = mailmime_mechanism_new(encoding_type, NULL);
if (encoding == NULL)
goto enomem;
encoding = NULL;
if (transport_encode) {
encoding_type = MAILMIME_MECHANISM_BASE64;
encoding = mailmime_mechanism_new(encoding_type, NULL);
if (encoding == NULL)
goto enomem;
}
mime_fields = mailmime_fields_new_with_data(encoding, content_id, NULL,
disposition, NULL);


+ 2
- 1
src/etpan_mime.h View File

@ -29,7 +29,8 @@ struct mailmime * get_file_part(
pEp_rid_list_t* resource,
const char * mime_type,
char * data,
size_t length
size_t length,
bool transport_encode
);
struct mailmime * part_multiple_new(const char *type);


+ 26
- 0
src/keymanagement.c View File

@ -723,12 +723,38 @@ DYNAMIC_API PEP_STATUS key_mistrusted(
}
else
{
// for undo
if (session->cached_mistrusted)
free(session->cached_mistrusted);
session->cached_mistrusted = identity_dup(ident);
status = mark_as_compromized(session, ident->fpr);
}
return status;
}
DYNAMIC_API PEP_STATUS undo_last_mistrust(PEP_SESSION session) {
assert(session);
if (!session)
return PEP_ILLEGAL_VALUE;
PEP_STATUS status = PEP_STATUS_OK;
pEp_identity* cached_ident = session->cached_mistrusted;
if (!cached_ident)
status = PEP_CANNOT_FIND_IDENTITY;
else {
status = set_identity(session, cached_ident);
free_identity(session->cached_mistrusted);
}
session->cached_mistrusted = NULL;
return status;
}
DYNAMIC_API PEP_STATUS key_reset_trust(
PEP_SESSION session,
pEp_identity *ident


+ 20
- 2
src/keymanagement.h View File

@ -125,17 +125,35 @@ DYNAMIC_API PEP_STATUS do_keymanagement(
);
// key_mistrusted() - mark key as being compromized
// key_mistrusted() - mark key as being compromised
//
// parameters:
// session (in) session to use
// ident (in) person and key which was compromized
// ident (in) person and key which was compromised
DYNAMIC_API PEP_STATUS key_mistrusted(
PEP_SESSION session,
pEp_identity *ident
);
// undo_last_mistrust() - reset identity and trust status for the last
// identity in this session marked as mistrusted
// to their cached values from the time of mistrust
// parameters:
// session (in) session to use
//
// return value:
// PEP_STATUS_OK if identity and trust were successfully restored.
// Otherwise, error status from attempts to set.
//
// caveat:
// only works for this session, and only once. cache is invalidated
// upon use.
//
//  WILL NOT WORK ON MISTRUSTED OWN KEY
DYNAMIC_API PEP_STATUS undo_last_mistrust(PEP_SESSION session);
// trust_personal_key() - mark a key as trusted with a person
//


+ 0
- 1
src/message.h View File

@ -163,4 +163,3 @@ DYNAMIC_API message_ref_list *message_ref_list_add(message_ref_list *msg_list,
#ifdef __cplusplus
}
#endif

+ 1176
- 777
src/message_api.c
File diff suppressed because it is too large
View File


+ 5
- 1
src/message_api.h View File

@ -33,7 +33,11 @@ typedef enum _PEP_encrypt_flags {
// This flag is for special use cases and should not be used
// by normal pEp clients!
PEP_encrypt_flag_force_unsigned = 0x2,
PEP_encrypt_flag_force_no_attached_key = 0x4
PEP_encrypt_flag_force_no_attached_key = 0x4,
// This is used for outer messages (used to wrap the real message)
// This is only used internally and (eventually) by transport functions
PEP_encrypt_flag_inner_message = 0x8
} PEP_encrypt_flags;
typedef unsigned int PEP_encrypt_flags_t;


+ 55
- 27
src/mime.c View File

@ -100,7 +100,8 @@ pep_error:
static PEP_STATUS mime_attachment(
bloblist_t *blob,
struct mailmime **result
struct mailmime **result,
bool transport_encode
)
{
PEP_STATUS status = PEP_STATUS_OK;
@ -121,7 +122,7 @@ static PEP_STATUS mime_attachment(
mime_type = blob->mime_type;
pEp_rid_list_t* resource = parse_uri(blob->filename);
mime = get_file_part(resource, mime_type, blob->value, blob->size);
mime = get_file_part(resource, mime_type, blob->value, blob->size, transport_encode);
free_rid_list(resource);
assert(mime);
@ -144,7 +145,8 @@ static PEP_STATUS mime_html_text(
const char *plaintext,
const char *htmltext,
bloblist_t *attachments,
struct mailmime **result
struct mailmime **result,
bool transport_encode
)
{
PEP_STATUS status = PEP_STATUS_OK;
@ -166,8 +168,9 @@ static PEP_STATUS mime_html_text(
pEp_rid_list_t* resource = new_rid_node(PEP_RID_FILENAME, "msg.txt");
int encoding_type = (transport_encode ? MAILMIME_MECHANISM_QUOTED_PRINTABLE : 0);
submime = get_text_part(NULL, "text/plain", plaintext, strlen(plaintext),
MAILMIME_MECHANISM_QUOTED_PRINTABLE);
encoding_type);
free_rid_list(resource);
resource = NULL;
@ -222,7 +225,7 @@ static PEP_STATUS mime_html_text(
// resource = new_rid_node(PEP_RID_FILENAME, "msg.html");
submime = get_text_part(NULL, "text/html", htmltext, strlen(htmltext),
MAILMIME_MECHANISM_QUOTED_PRINTABLE);
encoding_type);
free_rid_list(resource);
resource = NULL;
@ -243,7 +246,7 @@ static PEP_STATUS mime_html_text(
for (_a = attachments; _a != NULL; _a = _a->next) {
if (_a->disposition != PEP_CONTENT_DISP_INLINE)
continue;
status = mime_attachment(_a, &submime);
status = mime_attachment(_a, &submime, transport_encode);
if (status != PEP_STATUS_OK)
return PEP_UNKNOWN_ERROR; // FIXME
@ -273,6 +276,8 @@ enomem:
return status;
}
// FIXME: maybe need to add transport_encode field here
static struct mailimf_mailbox * identity_to_mailbox(const pEp_identity *ident)
{
char *_username = NULL;
@ -384,17 +389,22 @@ enomem:
return NULL;
}
static clist * stringlist_to_clist(stringlist_t *sl)
static clist * stringlist_to_clist(stringlist_t *sl, bool transport_encode)
{
clist * cl = clist_new();
assert(cl);
if (cl == NULL)
return NULL;
if (!sl || ((!sl->value || sl->value[0] == '\0') && sl->next == NULL))
return cl;
stringlist_t *_sl;
for (_sl = sl; _sl; _sl = _sl->next) {
int r;
char * value = mailmime_encode_subject_header("utf-8", _sl->value, 0);
char * value = (transport_encode ?
mailmime_encode_subject_header("utf-8", _sl->value, 0) :
strdup(_sl->value));
assert(value);
if (value == NULL) {
clist_free(cl);
@ -412,7 +422,8 @@ static clist * stringlist_to_clist(stringlist_t *sl)
return cl;
}
static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **result)
static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **result,
bool transport_encode)
{
PEP_STATUS status = PEP_STATUS_OK;
struct mailimf_fields * fields = NULL;
@ -487,7 +498,9 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
}
/* if (subject) */ {
char *_subject = mailmime_encode_subject_header("utf-8", subject, 1);
char *_subject = (transport_encode ?
mailmime_encode_subject_header("utf-8", subject, 1) :
strdup(subject));
if (_subject == NULL)
goto enomem;
@ -539,7 +552,7 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
}
if (msg->in_reply_to) {
clist *in_reply_to = stringlist_to_clist(msg->in_reply_to);
clist *in_reply_to = stringlist_to_clist(msg->in_reply_to, transport_encode);
if (in_reply_to == NULL)
goto enomem;
@ -552,7 +565,7 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
}
if (msg->references) {
clist *references = stringlist_to_clist(msg->references);
clist *references = stringlist_to_clist(msg->references, transport_encode);
if (references == NULL)
goto enomem;
@ -565,7 +578,7 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
}
if (msg->keywords) {
clist *keywords = stringlist_to_clist(msg->keywords);
clist *keywords = stringlist_to_clist(msg->keywords, transport_encode);
if (keywords == NULL)
goto enomem;
@ -578,8 +591,9 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
}
if (msg->comments) {
char *comments = mailmime_encode_subject_header("utf-8", msg->comments,
0);
char *comments = (transport_encode ?
mailmime_encode_subject_header("utf-8", msg->comments, 0) :
strdup(msg->comments));
if (comments == NULL)
goto enomem;
@ -597,7 +611,9 @@ static PEP_STATUS build_fields(const message *msg, struct mailimf_fields **resul
char *key = _l->value->key;
char *value = _l->value->value;
if (key && value) {
char *_value = mailmime_encode_subject_header("utf-8", value, 0);
char *_value = (transport_encode ?
mailmime_encode_subject_header("utf-8", value, 0) :
strdup(value));
if (_value == NULL)
goto enomem;
@ -695,7 +711,8 @@ static pEp_rid_list_t* choose_resource_id(pEp_rid_list_t* rid_list) {
static PEP_STATUS mime_encode_message_plain(
const message *msg,
bool omit_fields,
struct mailmime **result
struct mailmime **result,
bool transport_encode
)
{
struct mailmime * mime = NULL;
@ -717,7 +734,8 @@ static PEP_STATUS mime_encode_message_plain(
/* first, we need to strip out the inlined attachments to ensure this
gets set up correctly */
status = mime_html_text(plaintext, htmltext, msg->attachments, &mime);
status = mime_html_text(plaintext, htmltext, msg->attachments, &mime,
transport_encode);
if (status != PEP_STATUS_OK)
goto pep_error;
@ -726,13 +744,15 @@ static PEP_STATUS mime_encode_message_plain(
pEp_rid_list_t* resource = NULL;
if (is_PGP_message_text(plaintext)) {
resource = new_rid_node(PEP_RID_FILENAME, "msg.asc");
int encoding_type = (transport_encode ? MAILMIME_MECHANISM_7BIT : 0);
mime = get_text_part(resource, "application/octet-stream", plaintext,
strlen(plaintext), MAILMIME_MECHANISM_7BIT);
strlen(plaintext), encoding_type);
}
else {
resource = new_rid_node(PEP_RID_FILENAME, "msg.txt");
int encoding_type = (transport_encode ? MAILMIME_MECHANISM_QUOTED_PRINTABLE : 0);
mime = get_text_part(resource, "text/plain", plaintext, strlen(plaintext),
MAILMIME_MECHANISM_QUOTED_PRINTABLE);
encoding_type);
}
free_rid_list(resource);
@ -776,7 +796,7 @@ static PEP_STATUS mime_encode_message_plain(
if (_a->disposition == PEP_CONTENT_DISP_INLINE)
continue;
status = mime_attachment(_a, &submime);
status = mime_attachment(_a, &submime, transport_encode);
if (status != PEP_STATUS_OK)
goto pep_error;
@ -819,14 +839,12 @@ static PEP_STATUS mime_encode_message_PGP_MIME(
struct mailmime_parameter * param;
int r;
PEP_STATUS status;
//char *subject;
char *plaintext;
size_t plaintext_size;
assert(msg->attachments && msg->attachments->next &&
msg->attachments->next->value);
//subject = (msg->shortmsg) ? msg->shortmsg : "pEp"; // not used, yet.
plaintext = msg->attachments->next->value;
plaintext_size = msg->attachments->next->size;
@ -893,6 +911,16 @@ DYNAMIC_API PEP_STATUS mime_encode_message(
bool omit_fields,
char **mimetext
)
{
return _mime_encode_message_internal(msg, omit_fields, mimetext, true);
}
PEP_STATUS _mime_encode_message_internal(
const message * msg,
bool omit_fields,
char **mimetext,
bool transport_encode
)
{
PEP_STATUS status = PEP_STATUS_OK;
struct mailmime * msg_mime = NULL;
@ -911,11 +939,11 @@ DYNAMIC_API PEP_STATUS mime_encode_message(
switch (msg->enc_format) {
case PEP_enc_none:
status = mime_encode_message_plain(msg, omit_fields, &mime);
status = mime_encode_message_plain(msg, omit_fields, &mime, transport_encode);
break;
case PEP_enc_pieces:
status = mime_encode_message_plain(msg, omit_fields, &mime);
status = mime_encode_message_plain(msg, omit_fields, &mime, transport_encode);
break;
case PEP_enc_S_MIME:
@ -948,7 +976,7 @@ DYNAMIC_API PEP_STATUS mime_encode_message(
mime = NULL;
if (!omit_fields) {
status = build_fields(msg, &fields);
status = build_fields(msg, &fields, transport_encode);
if (status != PEP_STATUS_OK)
goto pep_error;
@ -1093,7 +1121,7 @@ static stringlist_t * clist_to_stringlist(const clist *list)
text = NULL;
}
return _sl;
return sl;
enomem:
free_stringlist(sl);


+ 13
- 0
src/mime.h View File

@ -40,6 +40,10 @@ DYNAMIC_API bool is_PGP_message_text(const char *text);
// the resulttext will go to the ownership of the caller
// the message will remain in the ownership of the caller
// omit_fields is true for payload of PGP/MIME messages
//
// also: note that the encryption type will be used to determine what
// gets encoded from the message struct, so if using this on an
// already-encrypted message, set the enc_format of the msg to PEP_enc_none.
DYNAMIC_API PEP_STATUS mime_encode_message(
const message * msg,
@ -74,6 +78,15 @@ DYNAMIC_API PEP_STATUS mime_decode_message(
message **msg
);
/* sometimes we don't want to transport encode */
PEP_STATUS _mime_encode_message_internal(
const message * msg,
bool omit_fields,
char **mimetext,
bool transport_encode
);
#ifdef __cplusplus
}
#endif

+ 49
- 10
src/pEpEngine.c View File

@ -8,7 +8,10 @@
#include "blacklist.h"
#include "sync_fsm.h"
static int init_count = -1;
#include <time.h>
#include <stdlib.h>
static volatile int init_count = -1;
// sql overloaded functions - modified from sqlite3.c
static void _sql_lower(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
@ -264,9 +267,25 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
// a little race condition - but still a race condition
// mitigated by calling caveat (see documentation)
++init_count;
if (init_count == 0)
// this increment is made atomic IN THE ADAPTERS by
// guarding the call to init with the appropriate mutex.
int _count = ++init_count;
if (_count == 0)
in_first = true;
// Race condition mitigated by calling caveat starts here :
// If another call to init() preempts right now, then preemptive call
// will have in_first false, will not create SQL tables, and following
// calls relying on those tables will fail.
//
// Therefore, as above, adapters MUST guard init() with a mutex.
//
// Therefore, first session
// is to be created and last session to be deleted alone, and not
// concurently to other sessions creation or deletion.
// We expect adapters to enforce this either by implicitely creating a
// client session, or by using synchronization primitive to protect
// creation/deletion of first/last session from the app.
assert(session);
if (session == NULL)
@ -306,6 +325,16 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
goto pep_error;
}
int_result = sqlite3_exec(
_session->db,
"PRAGMA locking_mode=NORMAL;\n"
"PRAGMA journal_mode=WAL;\n",
NULL,
NULL,
NULL
);
sqlite3_busy_timeout(_session->db, BUSY_WAIT_TIME);
assert(SYSTEM_DB);
@ -352,8 +381,8 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
"create table if not exists log (\n"
" timestamp integer default (datetime('now')),\n"
" title text not null,\n"
" entity text not null,\n"
" description text,\n"
" entity text not null,\n"
" comment text\n"
");\n"
"create index if not exists log_timestamp on log (\n"
@ -546,6 +575,10 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
);
assert(int_result == SQLITE_OK);
}
// We need to init a few globals for message id that we'd rather not
// calculate more than once.
_init_globals();
}
int_result = sqlite3_prepare_v2(_session->db, sql_log,
@ -759,6 +792,12 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
_session->sync_session = _session;
*session = _session;
// Note: Following statement is NOT for any cryptographic/secure functionality; it is
// ONLY used for some randomness in generated outer message ID, which are
// required by the RFC to be globally unique!
srand(time(NULL));
return PEP_STATUS_OK;
enomem:
@ -772,19 +811,19 @@ pep_error:
DYNAMIC_API void release(PEP_SESSION session)
{
bool out_last = false;
assert(init_count >= 0);
int _count = --init_count;
assert(_count >= -1);
assert(session);
if (!((init_count >= 0) && session))
if (!((_count >= -1) && session))
return;
// a small race condition but still a race condition
// mitigated by calling caveat (see documentation)
if (init_count == 0)
// (release() is to be guarded by a mutex by the caller)
if (_count == -1)
out_last = true;
--init_count;
if (session) {
if (session->sync_state != DeviceState_state_NONE)


+ 8
- 1
src/pEpEngine.h View File

@ -16,7 +16,7 @@ extern "C" {
#include "stringpair.h"
#include "timestamp.h"
#define PEP_VERSION "1.0" // protocol version
#define PEP_VERSION "2.0" // protocol version
#define PEP_OWN_USERID "pEp_own_userId"
@ -129,6 +129,9 @@ typedef enum {
// opened
//
// caveat:
// THE CALLER MUST GUARD THIS CALL EXTERNALLY WITH A MUTEX. release() should
// be similarly guarded.
//
// the pointer is valid only if the return value is PEP_STATUS_OK
// in other case a NULL pointer will be returned; a valid handle must
// be released using release() when it's no longer needed
@ -145,6 +148,9 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session);
// session (in) session handle to release
//
// caveat:
// THE CALLER MUST GUARD THIS CALL EXTERNALLY WITH A MUTEX. init() should
// be similarly guarded.
//
// the last release() can be called only when all other release() calls
// are done
@ -856,6 +862,7 @@ DYNAMIC_API void pEp_free(void *p);
DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity);
PEP_STATUS set_trust(PEP_SESSION session,
const char* user_id,
const char* fpr,


+ 29
- 1
src/pEp_internal.h View File

@ -1,7 +1,7 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#define PEP_ENGINE_VERSION "0.8.0"
#define PEP_ENGINE_VERSION "0.9.0"
// maximum attachment size to import as key 1MB, maximum of 20 attachments
@ -37,6 +37,19 @@
#define PEP_SUBJ_BYTELEN 5
#endif
#ifndef PEP_SUBJ_KEY
#define PEP_SUBJ_KEY "Subject: "
#define PEP_SUBJ_KEY_LC "subject: "
#define PEP_SUBJ_KEY_LEN 9
#endif
#ifndef PEP_MSG_WRAP_KEY
#define PEP_MSG_WRAP_KEY "pEp-Wrapped-Message-Info: "
#define PEP_MSG_WRAP_KEY_LC "pep-wrapped-message-info: "
#define PEP_MSG_WRAP_KEY_LEN 26
#endif
#include "platform.h"
#ifdef WIN32
@ -61,6 +74,7 @@
#include <assert.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#ifdef SQLITE3_FROM_OS
#include <sqlite3.h>
@ -173,6 +187,9 @@ struct _pEpSession {
bool unencrypted_subject;
bool keep_sync_msg;
bool service_log;
// mistrust undo cache
pEp_identity* cached_mistrusted;
#ifdef DEBUG_ERRORSTACK
stringlist_t* errorstack;
@ -348,6 +365,17 @@ static inline char* _pep_subj_copy() {
return (char*)retval;
}
// These are globals used in generating message IDs and should only be
// computed once, as they're either really constants or OS-dependent
int _pEp_rand_max_bits;
double _pEp_log2_36;
static inline void _init_globals() {
_pEp_rand_max_bits = ceil(log2(RAND_MAX));
_pEp_log2_36 = log2(36);
}
#ifdef DEBUG_ERRORSTACK
PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status);
#define ADD_TO_LOG(status) session_add_error(session, __FILE__, __LINE__, (status))


+ 14
- 12
src/pgp_gpg.c View File

@ -1837,18 +1837,20 @@ static PEP_STATUS _pgp_search_keys(PEP_SESSION session, const char* pattern,
free_stringlist(_keylist);
_keylist = NULL;
// If match failed, check to see if we've got a dotted address in the pattern.
// (last chance of the heuristic, really)
// If so, try again without any dots.
const char* dotpos = strstr(pattern, ".");
const char* atpos = strstr(pattern, "@");
if (dotpos && atpos && (dotpos < atpos)) {
char* undotted = _undot_address(pattern);
if (undotted) {
PEP_STATUS status = _pgp_search_keys(session, undotted,
keylist, private_only);
free(undotted);
return status;
if (pattern != NULL) {
// If match failed, check to see if we've got a dotted address in the pattern.
// (last chance of the heuristic, really)
// If so, try again without any dots.
const char* dotpos = strstr(pattern, ".");
const char* atpos = strstr(pattern, "@");
if (dotpos && atpos && (dotpos < atpos)) {
char* undotted = _undot_address(pattern);
if (undotted) {
PEP_STATUS status = _pgp_search_keys(session, undotted,
keylist, private_only);
free(undotted);
return status;
}
}
}
}


+ 14
- 2
src/platform_unix.c View File

@ -297,8 +297,14 @@ static bool ensure_gpg_home(const char **conf, const char **home){
fd = open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
if(fd>0) {
write(fd, gpg_conf_empty, strlen(gpg_conf_empty));
ssize_t res;
len = strlen(gpg_conf_empty);
res = write(fd, gpg_conf_empty, len);
close(fd);
if(res < len) {
assert(0);
return false;
}
}
}
@ -344,8 +350,14 @@ static bool ensure_gpg_agent_conf(const char **agent_conf){
fd = open(agent_path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
if(fd>0) {
write(fd, gpg_conf_empty, strlen(gpg_conf_empty));
ssize_t res;
len = strlen(gpg_conf_empty);
res = write(fd, gpg_conf_empty, len);
close(fd);
if(res < len) {
assert(0);
return false;
}
}
}
done = true;


+ 2
- 2
src/platform_windows.cpp View File

@ -141,12 +141,12 @@ void *dlopen(const char *filename, int flag) {
// Look up GnuPG installation in current user scope
bool result = readRegistryString(HKEY_CURRENT_USER,
TEXT("SOFTWARE\\GNU\\GnuPG"), TEXT("Install Directory"), path,
TEXT("SOFTWARE\\GnuPG"), TEXT("Install Directory"), path,
PATH_BUF_SIZE, NULL);
// If not found in current user, look up in local machine
if (!result)
result = readRegistryString(HKEY_LOCAL_MACHINE,
TEXT("SOFTWARE\\GNU\\GnuPG"), TEXT("Install Directory"), path,
TEXT("SOFTWARE\\GnuPG"), TEXT("Install Directory"), path,
PATH_BUF_SIZE, NULL);
assert(result);
if (!result)


+ 5
- 7
test/Makefile View File

@ -10,8 +10,8 @@ include ../Makefile.conf
TARGET=pEpEngineTest
unexport GNUPGHOME
TEST_HOME=$(HERE)/test_home
TEST_GNUPGHOME=$(TEST_HOME)/.gnupg
TEST_HOME=$(HERE)test_home
TEST_GNUPGHOME=$(TEST_HOME)/gnupg
LDFLAGS+= $(ETPAN_LIB) -L../asn.1 -L../src
LDLIBS+= -letpan -lpEpEngine -lstdc++ -lasn1
@ -51,7 +51,7 @@ endif
# Remove trailing ':'
EXTRA_LIB_PATHS:=$(EXTRA_LIB_PATHS::=)
TEST_CMD_PFX=$(LIBPATH)=$(EXTRA_LIB_PATHS) HOME=$(TEST_HOME)
TEST_CMD_PFX=$(LIBPATH)=$(EXTRA_LIB_PATHS) HOME=$(TEST_HOME) GNUPGHOME=$(TEST_GNUPGHOME)
UNIT_TESTS_SOURCE=$(wildcard *_test.cc)
UNIT_TESTS=$(subst .cc,,$(UNIT_TESTS_SOURCE))
@ -79,16 +79,14 @@ all: $(TARGET) $(UNIT_TESTS)
.PHONY: test_home_
test_home_:
-gpgconf --kill gpg-agent
-HOME=$(TEST_HOME) gpgconf --kill gpg-agent
-killall gpg-agent
-GNUPGHOME=$(TEST_GNUPGHOME) gpgconf --kill gpg-agent
rm -rf $(TEST_HOME)
mkdir -p $(TEST_GNUPGHOME)/private-keys-v1.d
$(GPG_CMD) --import --batch --homedir $(TEST_GNUPGHOME) 0x*.asc *_sec.asc
.PHONY: clean
clean:
rm -f *.o $(TARGET) *.a *~ $(UNIT_TESTS) pep_Dokument_Titel.pdf msg4.asc
rm -f *.o $(TARGET) *.a *~ $(UNIT_TESTS) pep_Dokument_Titel.pdf msg4.asc msg_encrypt_for_self.asc
rm -Rf *.dSYM $(TEST_HOME) pubring.gpg secring.gpg random_seed *.conf trustdb.gpg
.PHONY: test


+ 7
- 2
test/external_revoke_test.cc View File

@ -247,6 +247,9 @@ int main() {
// encrypt something to the key
cout << "Creating message…\n";
// cout << "First, update identity though!\n";
// status = update_identity(session, recip1);
to_list = new_identity_list(identity_dup(recip1)); // to bob
outgoing_msg = new_message(PEP_dir_outgoing);
assert(outgoing_msg);
@ -258,8 +261,8 @@ int main() {
cout << "Message created.\n";
status = encrypt_message(session, outgoing_msg, NULL, &encrypted_outgoing_msg, PEP_enc_PGP_MIME, 0);
ct = (encrypted_outgoing_msg ? encrypted_outgoing_msg->to->ident->comm_type : outgoing_msg->to->ident->comm_type);
// CHECK STATUS???
cout << "Encryption returns with status " << tl_status_string(status) << endl;
@ -285,11 +288,13 @@ int main() {
status = decrypt_message(session, encrypted_outgoing_msg, &decrypted_msg, &keylist, &rating, &flags);
cout << "Decryption returns with status " << tl_status_string(status) << endl;
assert(status == PEP_STATUS_OK);
assert(decrypted_msg);
// check rating
cout << "Rating of decrypted message to trusted recip: " << tl_rating_string(rating) << endl;
assert(rating == PEP_rating_reliable);
status = update_identity(session, decrypted_msg->to->ident);
ct = (decrypted_msg ? decrypted_msg->to->ident->comm_type : outgoing_msg->to->ident->comm_type);
cout << "comm_type: " << tl_ct_string(ct) << endl;


+ 0
- 1
test/mime_test.cc View File

@ -102,4 +102,3 @@ int main() {
release(session);
return 0;
}

+ 75
- 0
test/mistrust_undo_test.cc View File

@ -0,0 +1,75 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "platform.h"
#include <iostream>
#include <fstream>
#include <assert.h>
#include "mime.h"
#include "message_api.h"
#include "test_util.h"
using namespace std;
int main() {
cout << "\n*** mistrust_undo_test ***\n\n";
PEP_SESSION session;
cout << "calling init()\n";
PEP_STATUS status = init(&session);
assert(status == PEP_STATUS_OK);
assert(session);
cout << "init() completed.\n";
cout << "importing key 0x39E5DAB5." << endl;
const string pub_key = slurp("test_keys/pub/mistrust.undo.test-0x39E5DAB5_pub.asc");
assert(pub_key.length() != 0);
PEP_STATUS statuspub = import_key(session, pub_key.c_str(), pub_key.length(), NULL);
assert(statuspub == PEP_STATUS_OK);
cout << "Key imported." << endl << endl;
cout << "Setting up identity for mistrust.undo.test@pep-project.org and making comm_type PEP_ct_pEp." << endl;
pEp_identity* recip1 = new_identity("mistrust.undo.test@pep-project.org", NULL, "TOFU_mistrust.undo.test@pep-project.org", "Mistrust Undo");
status = update_identity(session,recip1);
assert(status == PEP_STATUS_OK);
assert(strcmp(recip1->fpr, "BACC7A60A88A39A25D99B4A545D7542F39E5DAB5") == 0);
// This is not an external function. We use it to expedite the test since we don't do a sync exchange here.
status = update_trust_for_fpr(session, recip1->fpr, PEP_ct_pEp);
status = update_identity(session,recip1);
assert(status == PEP_STATUS_OK);
assert(recip1->comm_type == PEP_ct_pEp);
assert(strcmp(recip1->fpr, "BACC7A60A88A39A25D99B4A545D7542F39E5DAB5") == 0);
cout << "mistrust.undo.test@pep-project.org set up and comm_type is PEP_ct_pEp." << endl << endl;
// Ok, mistrust away
cout << "Mistrusting mistrust.undo.test@pep-project.org (BACC7A60A88A39A25D99B4A545D7542F39E5DAB5)." << endl;
status = key_mistrusted(session, recip1);
assert(status == PEP_STATUS_OK);
status = update_identity(session,recip1);
assert(status == PEP_STATUS_OK);
assert(recip1->comm_type == PEP_ct_mistrusted);
cout << "Mistrusted mistrust.undo.test@pep-project.org (BACC7A60A88A39A25D99B4A545D7542F39E5DAB5) and comm_type set to PEP_ct_mistrusted)." << endl << endl;
cout << "Undo mistrust (restore identity and trust in DB)" << endl;
// Undo it
status = undo_last_mistrust(session);
assert(status == PEP_STATUS_OK);
status = update_identity(session, recip1);
assert(recip1->comm_type == PEP_ct_pEp);
assert(strcmp(recip1->fpr, "BACC7A60A88A39A25D99B4A545D7542F39E5DAB5") == 0);
cout << "Undo mistrust (restore identity and trust in DB) - trust is now PEP_ct_pEp." << endl << endl;
cout << "Success!!!" << endl << endl;
free_identity(recip1);
release(session);
return 0;
}

+ 44
- 1
test/pEpEngineTest.cc View File

@ -9,15 +9,29 @@
#include <assert.h>
#include <string.h>
#include <sstream>
#include "../src/pEpEngine.h"
#include "../src/keymanagement.h"
using namespace std;
typedef std::string Buffer;
std::string slurp(const std::string& filename)
{
std::ifstream input(filename.c_str());
if(!input)
{
throw std::runtime_error("Cannot read file \"" + filename + "\"! ");
}
std::stringstream sstr;
sstr << input.rdbuf();
return sstr.str();
}
// no C++11, yet? So do our own implementation:
namespace{
std::string to_string(unsigned long u)
@ -96,6 +110,35 @@ int main(int argc, char* argv[])
cout << "dropping second session\n";
release(second_session);
cout << "Importing keys...";
string pub_key = slurp("test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc");
string priv_key = slurp("test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc");
PEP_STATUS statuspub = import_key(session, pub_key.c_str(), pub_key.length(), NULL);
PEP_STATUS statuspriv = import_key(session, priv_key.c_str(), priv_key.length(), NULL);
assert(statuspub == PEP_STATUS_OK);
assert(statuspriv == PEP_STATUS_OK);
pub_key = slurp("test_keys/pub/pep-test-john-0x70DCF575_pub.asc");
priv_key = slurp("test_keys/priv/pep-test-john-0x70DCF575_priv.asc");
statuspub = import_key(session, pub_key.c_str(), pub_key.length(), NULL);
statuspriv = import_key(session, priv_key.c_str(), priv_key.length(), NULL);
assert(statuspub == PEP_STATUS_OK);
assert(statuspriv == PEP_STATUS_OK);
pub_key = slurp("test_keys/pub/pep-test-bob-0xC9C2EE39_pub.asc");
statuspub = import_key(session, pub_key.c_str(), pub_key.length(), NULL);
assert(statuspub == PEP_STATUS_OK);
assert(statuspriv == PEP_STATUS_OK);
cout << "creating message…\n";
pEp_identity* alice = new_identity("pep.test.alice@pep-project.org", "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", PEP_OWN_USERID, "Alice Test");
pEp_identity* bob = new_identity("pep.test.bob@pep-project.org", NULL, "42", "Bob Test");
cout << "logging test\n";
log_event(session, "log test", "pEp Engine Test", "This is a logging test sample.", "please ignore this line");


+ 1
- 2
test/revoke_regen_attach_test.cc View File

@ -61,7 +61,6 @@ int main() {
message *enc_msg;
cout << "calling encrypt_message()\n";
status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
cout << status;
assert(status == PEP_STATUS_OK);
assert(enc_msg);
cout << "message encrypted.\n";
@ -71,7 +70,7 @@ int main() {
assert(strcmp(msg->attachments->filename, "file://pEpkey.asc") == 0);
assert(strcmp(msg->attachments->next->filename, "file://pEpkey.asc") == 0);
cout << "message contains 2 key attachements.\n";
cout << "message contains 2 key attachments.\n";
free_message(msg);
free_message(enc_msg);


+ 57
- 0
test/test_keys/priv/mistrust.undo.test-0x39E5DAB5_priv.asc View File

@ -0,0 +1,57 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
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
u/rtL+cuYZ38+YOc2vW35FVeMhU=
=pD3o
-----END PGP PRIVATE KEY BLOCK-----

+ 30
- 0
test/test_keys/pub/mistrust.undo.test-0x39E5DAB5_pub.asc View File

@ -0,0 +1,30 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFnTjWIBCAC78lI82/kYpsd/bQ7iUkQyKlOhT4e2MdnaaiTOSJf6N0liSjnt
Ah49e5+qus4Z3zAHgDWOZxSa7fOSPlVSAj35yM2X2Xn1nDJ5CxTYNCqluK5f811a
cUmvC166ZTsjdjmgNDAwzNpwmjbAEhKyibxnTd2vpJlW3+nVCCXg9JHMfuSj71t8
0OpZNZ3uqVqAekcY7SvMcaCQ41A44IkN/gAOK3Z/Cml62mRpsaKss85ZBJKXP7n+
61mKvT7EK1zc5dD2pdxROnjxDYaAGuJKtLwzoSm2/syvMY2VpTrh2rSQVI7gR+ep
WcGkT4kTFFP5mSrOYL5bKnUjfaybk/26G8TFABEBAAG0P01pc3RydXN0IFVuZG8g
KERPIE5PVCBVU0UpIDxtaXN0cnVzdC51bmRvLnRlc3RAcGVwLXByb2plY3Qub3Jn
PokBOAQTAQgAIgUCWdONYgIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQ
RddULznl2rUL3ggAlg6bnLr+Cw7e/yYDk3Mdo0M5hN8cmeMC95CY4iwiiDjbCK2A
sSCjhTGWM59hJ3pSA8x+GGBBeFCiGu0GLciEKuBPoJ1C4OFTUq5goDxvyysGHZ6O
wRyfnHLl4mSEW86op0fkSHle25V9lO/WjuWNwjoi9hLoW8IoN51dY0PZK69EeKua
X588nGJrOJeuZr3zLlziu9Km24Y5El6M3GIZkaQcbiW2nbM/WkkRNDgRJbCp1wZI
HledC6hgTjObaae1iXHzByM/62t1u/GzixLaccfC5GAFGBtFI338pWaLarfSRVVb
T6YBEMDJhrIcKtDWBi22yjRGxg/72Gz+mj0lLbkBDQRZ041iAQgAz34Vh5+c8qRa
11f5nbWDssmC/2jxZdsX0cqSSozXxuJ4l5lor/2dfqq2WCNWzdj+n8JGJrFVmpEL
9rVTAARkUbNHzWv5pAe353JWkuTMLIVFzdNIXymHyKck7S4QSohpoT/UA6gTtQD6
kLbSFqycfkRlRWw0qYpPJEYiIdCzlwEMffpu6ltzCXi3He6K7+S/XA5DXTIdArx3
UMB/rJ69WCeEh77S7i5l223MmZLjFIM9VRLP7SyIaOxnn1LlLCjbgT7gAX7S9aYe
AWi8aZqtBcQ/wrSlvKPNYElEvFsGkxrUCKYg6T1cWfU1ch4uCDqrrKdNQFpRF4Ng
UuFIOcnt8QARAQABiQEfBBgBCAAJBQJZ041iAhsMAAoJEEXXVC855dq1RHAH/iog
JhtuUKPaec9Mu+W9g3+lcfh+QAHvqeIuzo6ff0OJn1hQXkG8lfclhHhDw0dngLax
eTV3ZOYy08ScRWxWIz01BKeWXXM47MO2+qOpZsdZLwwpFb1FG7wOdsfrQWGWxfJ7
bew7HZOL8jG3xvWeCbXSt1BJGjA0hN1Oa9x02lwL5M/ALyYOGD0Z/F/8FG8gyQny
kuAnoT8zifzsv7keQDiJ+xQSrvWPAcsDsJ9XZxPd+jZ2b1q/xvMWD2WDUU4FB91u
KruSXnEOMo+/mr6NoSqKrkfvoQOep8Uz/2rr7Z5qwvRfV4aMtrz4aGh4u/rtL+cu
YZ38+YOc2vW35FVeMhU=
=cCkg
-----END PGP PUBLIC KEY BLOCK-----

Loading…
Cancel
Save