From 9ab2f716e00ff614e4043cd59103a2fbaa5b7899 Mon Sep 17 00:00:00 2001 From: Andreas Buff Date: Tue, 27 Jul 2021 13:43:35 +0200 Subject: [PATCH 01/60] IOS-2882 rm now unused dependencies (iconv dylib) --- build-mac/pEpEngine.xcodeproj/project.pbxproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/build-mac/pEpEngine.xcodeproj/project.pbxproj b/build-mac/pEpEngine.xcodeproj/project.pbxproj index c764aafd..ae9d461e 100644 --- a/build-mac/pEpEngine.xcodeproj/project.pbxproj +++ b/build-mac/pEpEngine.xcodeproj/project.pbxproj @@ -34,7 +34,6 @@ 1543DA4C2577F8BE0041EFB5 /* Sync_event.h in Headers */ = {isa = PBXBuildFile; fileRef = 43188A8823C4B2DD008EF79C /* Sync_event.h */; }; 1543DAA9257801880041EFB5 /* baseprotocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 646C414C1D510D8800C63EFF /* baseprotocol.c */; }; 1543DAAD257801A90041EFB5 /* resource_id.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F6921C1F164A47009418F5 /* resource_id.c */; }; - 1549181222B92EA20091B6D6 /* libiconv.2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 1549180D22B92EA20091B6D6 /* libiconv.2.tbd */; }; 154918AB22B940200091B6D6 /* fsm_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 1549189222B9401D0091B6D6 /* fsm_common.h */; platformFilter = ios; }; 154918AC22B940200091B6D6 /* status_to_string.h in Headers */ = {isa = PBXBuildFile; fileRef = 1549189322B9401E0091B6D6 /* status_to_string.h */; platformFilter = ios; }; 154918B222B940200091B6D6 /* aux_mime_msg.h in Headers */ = {isa = PBXBuildFile; fileRef = 1549189922B9401E0091B6D6 /* aux_mime_msg.h */; platformFilter = ios; }; @@ -310,7 +309,6 @@ 154917FA22B926700091B6D6 /* libsequoia_openpgp_ffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsequoia_openpgp_ffi.a; path = ../../sequoia4ios/build/lib/libsequoia_openpgp_ffi.a; sourceTree = ""; }; 154917FB22B926700091B6D6 /* libhogweed.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libhogweed.a; path = ../../sequoia4ios/build/lib/libhogweed.a; sourceTree = ""; }; 154917FC22B926700091B6D6 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgmp.a; path = ../../sequoia4ios/build/lib/libgmp.a; sourceTree = ""; }; - 1549180D22B92EA20091B6D6 /* libiconv.2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.2.tbd; path = usr/lib/libiconv.2.tbd; sourceTree = SDKROOT; }; 1549189222B9401D0091B6D6 /* fsm_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fsm_common.h; path = ../src/fsm_common.h; sourceTree = ""; }; 1549189322B9401E0091B6D6 /* status_to_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = status_to_string.h; path = ../src/status_to_string.h; sourceTree = ""; }; 1549189922B9401E0091B6D6 /* aux_mime_msg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = aux_mime_msg.h; path = ../src/aux_mime_msg.h; sourceTree = ""; }; @@ -426,7 +424,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 1549181222B92EA20091B6D6 /* libiconv.2.tbd in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -546,7 +543,6 @@ 1585EF5A26A08B2000B822E1 /* CommonPEPDependencies.xcodeproj */, 15A3261C2611F6B5009D07EB /* PEPSQLITE3.xcodeproj */, 15A3203B260E030B009D07EB /* pEpASN1.xcodeproj */, - 1549180D22B92EA20091B6D6 /* libiconv.2.tbd */, 64951A1B1BE0FCD800B10E71 /* system.db */, 64DA24121B832EBA000BEE80 /* libetpan.xcodeproj */, 43188A5523C4A7F8008EF79C /* sync-generated */, From d5dfd19a3f18bc0f4c5c946bdb0043ccb80c4e4a Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Wed, 4 Aug 2021 11:31:22 +0200 Subject: [PATCH 02/60] =?UTF-8?q?add=20message.asn1=20with=20ASN.1=20based?= =?UTF-8?q?=20p=E2=89=A1p=20message=20format?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- asn.1/Makefile | 6 ++- asn.1/message.asn1 | 106 +++++++++++++++++++++++++++++++++++++++++++++ asn.1/pEp.asn1 | 10 ++++- 3 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 asn.1/message.asn1 diff --git a/asn.1/Makefile b/asn.1/Makefile index 87de07b7..bec195cf 100644 --- a/asn.1/Makefile +++ b/asn.1/Makefile @@ -19,7 +19,7 @@ STORAGE_FILES = $(addsuffix .asn1, $(STORAGE)) .PHONY: all clean install uninstall -all: Sync.c Distribution.c Storage.c +all: Sync.c Distribution.c Storage.c PEPMessage.c $(MAKE) libasn1.a libasn1.a: $(ALL_OBJECTS) @@ -43,6 +43,10 @@ Storage.c: $(STORAGE_FILES) pEp.asn1 rm -f converter-sample.c touch Storage.c +PEPMessage.c: message.asn1 pEp.asn1 + $(ASN1C) -gen-PER $(ASN1C_OPTIONS) $+ + rm -f converter-sample.c + clean: rm -f *.a *.o *.c *.h *.sample \ $(SYNC_FILES) $(DISTRIBUTION_FILES) $(STORAGE_FILES) diff --git a/asn.1/message.asn1 b/asn.1/message.asn1 new file mode 100644 index 00000000..f6608607 --- /dev/null +++ b/asn.1/message.asn1 @@ -0,0 +1,106 @@ +-- This file is under BSD License 2.0 +-- +-- Sync protocol for p≡p +-- Copyright (c) 2021 p≡p foundation +-- +-- Written by Hartmut Goebel + + +PEP-MESSAGE { + iso(1) org(3) dod(6) internet(1) private(4) + enterprise(1) pEp(47878) message(1) + } +DEFINITIONS + AUTOMATIC TAGS EXTENSIBILITY IMPLIED ::= +BEGIN + +EXPORTS Message; + +IMPORTS + PString, PStringList, Identity, IdentityList, StringPairList, Hash + FROM PEP { iso(1) org(3) dod(6) internet(1) private(4) + enterprise(1) pEp(47878) basic(0) }; + + +MessageDirection ::= ENUMERATED { + incoming (0), + outgoing (1) +} + + +Blob ::= SEQUENCE { + value OCTET STRING (SIZE(0..102400000)), -- up to 100 MB + mime-type PString OPTIONAL, + filename PString OPTIONAL +} +BlobList ::= SEQUENCE OF Blob + + +/* +For the purposes of this profile, GeneralizedTime values MUST be +expressed in Coordinated Universal Time (UTC) and MUST include seconds +(i.e., times are YYYYMMDDHHMMSSZ), even where the number of seconds +is zero. GeneralizedTime values MUST NOT include fractional seconds. +To make this more explicit, the type-name "Timestamp" is used in this profile. +*/ +Timestamp ::= GeneralizedTime + + +EncFormat ::= ENUMERATED { + none (0), -- message is not encrypted + inline (1), -- + s-mime (2), -- RFC5751 + pgp-mime (3), -- RFC3156 + pEp (4), -- pEp encryption format + pgp-mime-outlook1 (5), -- Message B0rken by Outlook type 1 + inline-ea (6) + -- not used on wire: + -- auto (255) -- -- figure out automatically where possible +} + + +PEPMessage ::= SEQUENCE { + direction MessageDirection OPTIONAL, -- used only in "inner" messages + id PString OPTIONAL, -- UTF-8 string of message ID + + -- At least one of shortmsg, longmsg, longmsg-formatted must be present + -- FIXME: Can this be constrained? + shortmsg PString OPTIONAL, -- UTF-8 string of short message + + -- longmsg must only be used if implementation can handle dynamic allocation + longmsg UTF8String OPTIONAL, -- UTF-8 string of long message + -- (plain) + + -- longmsg-formatted must only be used if implementation can handle + -- dynamic allocation + longmsg-formatted UTF8String OPTIONAL, -- UTF-8 string of long message + -- (formatted) + + attachments BlobList OPTIONAL, -- blobs with attachments + -- internal: rawmsg + sent Timestamp OPTIONAL, -- when the message is sent + recv Timestamp OPTIONAL, -- when the message is received + from Identity, -- whom the message is from + -- At least one of to, cc must not be an empty list + -- FIXME: Can this be constrained? + to IdentityList OPTIONAL, -- whom the message is to + cc IdentityList OPTIONAL, -- whom a CC is being sent + bcc IdentityList OPTIONAL, -- whom a BCC is being sent + recv-by Identity OPTIONAL, -- via which identity the message + -- is received + reply-to IdentityList OPTIONAL, -- where a reply should go to + in-reply-to PStringList OPTIONAL, -- list of UTF-8 strings with + -- MessageIDs of refering messages + -- internal: refering_msg_ref + references PStringList OPTIONAL, -- list of UTF-8 strings with + -- references + -- internal: refered_by _message-ref-list + keywords PStringList OPTIONAL, -- list of UTF-8 strings with keywords + comments PString OPTIONAL, -- UTF-8 string with comments + opt-fields StringPairList OPTIONAL, -- optional fields + enc-format EncFormat DEFAULT none, -- format of encrypted data + sender-fpr Hash OPTIONAL -- fingerprint of sending signer +} + +END + diff --git a/asn.1/pEp.asn1 b/asn.1/pEp.asn1 index 540bfbd9..2b54600c 100644 --- a/asn.1/pEp.asn1 +++ b/asn.1/pEp.asn1 @@ -12,12 +12,13 @@ DEFINITIONS AUTOMATIC TAGS EXTENSIBILITY IMPLIED ::= BEGIN -EXPORTS Identity, IdentityList, TID, Hash, Version, Rating; +EXPORTS Identity, IdentityList, TID, Hash, Version, Rating, PString, PStringList, StringPair, StringPairList; ISO639-1 ::= PrintableString(FROM ("a".."z")) (SIZE(2)) Hex ::= PrintableString(FROM ("A".."F") | FROM ("0".."9")) Hash ::= Hex(SIZE(16..128)) -- 32bit Key ID to SHA512 in hex PString ::= UTF8String (SIZE(1..1024)) +PStringList ::= SEQUENCE OF PString TID ::= OCTET STRING (SIZE(16)) -- UUID version 4 variant 1 Identity ::= SEQUENCE { @@ -62,5 +63,12 @@ Rating ::= ENUMERATED { under-attack (-3) } +StringPair ::= SEQUENCE { + key PString, + value PString +} + +StringPairList ::= SEQUENCE OF StringPair + END From 3c46ea46f0d8a7557240662cf1a532fb2b672dd6 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Wed, 4 Aug 2021 11:38:08 +0200 Subject: [PATCH 03/60] nameclash --- asn.1/message.asn1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asn.1/message.asn1 b/asn.1/message.asn1 index f6608607..5702b4e2 100644 --- a/asn.1/message.asn1 +++ b/asn.1/message.asn1 @@ -14,7 +14,7 @@ DEFINITIONS AUTOMATIC TAGS EXTENSIBILITY IMPLIED ::= BEGIN -EXPORTS Message; +EXPORTS PEPMessage; IMPORTS PString, PStringList, Identity, IdentityList, StringPairList, Hash From c256b6305158990fd103615d8616fd7f15b58963 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Wed, 4 Aug 2021 11:39:05 +0200 Subject: [PATCH 04/60] avoid double build --- asn.1/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/asn.1/Makefile b/asn.1/Makefile index bec195cf..10614c3c 100644 --- a/asn.1/Makefile +++ b/asn.1/Makefile @@ -46,6 +46,7 @@ Storage.c: $(STORAGE_FILES) pEp.asn1 PEPMessage.c: message.asn1 pEp.asn1 $(ASN1C) -gen-PER $(ASN1C_OPTIONS) $+ rm -f converter-sample.c + touch PEPMessage.c clean: rm -f *.a *.o *.c *.h *.sample \ From 7de726962a9c17c8ba981c71b2f85d8a43c35460 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Wed, 4 Aug 2021 14:33:47 +0200 Subject: [PATCH 05/60] changes in PEPMessage --- asn.1/message.asn1 | 40 ++++++++++++++++++++-------------------- asn.1/pEp.asn1 | 4 ++-- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/asn.1/message.asn1 b/asn.1/message.asn1 index 5702b4e2..71708d19 100644 --- a/asn.1/message.asn1 +++ b/asn.1/message.asn1 @@ -62,25 +62,9 @@ EncFormat ::= ENUMERATED { PEPMessage ::= SEQUENCE { direction MessageDirection OPTIONAL, -- used only in "inner" messages id PString OPTIONAL, -- UTF-8 string of message ID - - -- At least one of shortmsg, longmsg, longmsg-formatted must be present - -- FIXME: Can this be constrained? - shortmsg PString OPTIONAL, -- UTF-8 string of short message - - -- longmsg must only be used if implementation can handle dynamic allocation - longmsg UTF8String OPTIONAL, -- UTF-8 string of long message - -- (plain) - - -- longmsg-formatted must only be used if implementation can handle - -- dynamic allocation - longmsg-formatted UTF8String OPTIONAL, -- UTF-8 string of long message - -- (formatted) - - attachments BlobList OPTIONAL, -- blobs with attachments - -- internal: rawmsg - sent Timestamp OPTIONAL, -- when the message is sent - recv Timestamp OPTIONAL, -- when the message is received - from Identity, -- whom the message is from + sent Timestamp OPTIONAL, -- when the message is sent + recv Timestamp OPTIONAL, -- when the message is received + from Identity, -- whom the message is from -- At least one of to, cc must not be an empty list -- FIXME: Can this be constrained? to IdentityList OPTIONAL, -- whom the message is to @@ -99,7 +83,23 @@ PEPMessage ::= SEQUENCE { comments PString OPTIONAL, -- UTF-8 string with comments opt-fields StringPairList OPTIONAL, -- optional fields enc-format EncFormat DEFAULT none, -- format of encrypted data - sender-fpr Hash OPTIONAL -- fingerprint of sending signer + sender-fpr Hash OPTIONAL, -- fingerprint of sending signer + + -- At least one of shortmsg, longmsg, longmsg-formatted must be present + -- FIXME: Can this be constrained? + shortmsg PString OPTIONAL, -- UTF-8 string of short message + + -- longmsg must only be used if implementation can handle dynamic allocation + longmsg UTF8String OPTIONAL, -- UTF-8 string of long message + -- (plain) + + -- longmsg-formatted must only be used if implementation can handle + -- dynamic allocation + longmsg-formatted UTF8String OPTIONAL, -- UTF-8 string of long message + -- (formatted) + + attachments BlobList OPTIONAL -- blobs with attachments + -- internal: rawmsg } END diff --git a/asn.1/pEp.asn1 b/asn.1/pEp.asn1 index 2b54600c..c99c1307 100644 --- a/asn.1/pEp.asn1 +++ b/asn.1/pEp.asn1 @@ -15,9 +15,9 @@ BEGIN EXPORTS Identity, IdentityList, TID, Hash, Version, Rating, PString, PStringList, StringPair, StringPairList; ISO639-1 ::= PrintableString(FROM ("a".."z")) (SIZE(2)) -Hex ::= PrintableString(FROM ("A".."F") | FROM ("0".."9")) +Hex ::= PrintableString(FROM ("A".."F" | "0".."9")) Hash ::= Hex(SIZE(16..128)) -- 32bit Key ID to SHA512 in hex -PString ::= UTF8String (SIZE(1..1024)) +PString ::= UTF8String (SIZE(0..1024)) PStringList ::= SEQUENCE OF PString TID ::= OCTET STRING (SIZE(16)) -- UUID version 4 variant 1 From 052e23d2c6e563ae805118d0495413b5973b3215 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Sun, 8 Aug 2021 07:54:54 +0200 Subject: [PATCH 06/60] conversion of base types --- src/map_asn1.c | 211 +++++++++++++++++++++++++++++++++++++++++++++++++ src/map_asn1.h | 120 ++++++++++++++++++++++++++++ 2 files changed, 331 insertions(+) diff --git a/src/map_asn1.c b/src/map_asn1.c index c6ba31f3..f1840304 100644 --- a/src/map_asn1.c +++ b/src/map_asn1.c @@ -190,3 +190,214 @@ enomem: return NULL; } +StringPair_t *StringPair_from_Struct( + const stringpair_t *value, + StringPair_t *result + ) +{ + bool allocated = !result; + + assert(value); + if (!value) + return NULL; + + if (allocated) + result = (StringPair_t *) calloc(1, sizeof(StringPair_t)); + assert(result); + if (!result) + return NULL; + + if (value->key) { + int r = OCTET_STRING_fromBuf(&result->key, value->key, -1); + if (r) + goto enomem; + } + + if (value->value) { + int r = OCTET_STRING_fromBuf(&result->value, value->value, -1); + if (r) + goto enomem; + } + + return result; + +enomem: + if (allocated) + ASN_STRUCT_FREE(asn_DEF_StringPair, result); + return NULL; +} + +stringpair_t *StringPair_to_Struct(StringPair_t *value, stringpair_t *result) +{ + bool allocated = !result; + + assert(value); + if (!value) + return NULL; + + if (allocated) + result = new_stringpair(NULL, NULL); + if (!result) + return NULL; + + result->key = strndup((char *) value->key.buf, + value->key.size); + assert(result->key); + if (!result->key) + goto enomem; + + result->value = strndup((char *) value->value.buf, + value->value.size); + assert(result->value); + if (!result->value) + goto enomem; + + return result; + +enomem: + if (allocated) + free_stringpair(result); + return NULL; +} + +StringPairList_t *StringPairList_from_stringpair_list( + const stringpair_list_t *list, + StringPairList_t *result + ) +{ + bool allocated = !result; + + assert(list); + if (!list) + return NULL; + + if (allocated) { + result = (StringPairList_t *) calloc(1, sizeof(StringPairList_t)); + assert(result); + if (!result) + return NULL; + } + else { + asn_sequence_empty(result); + } + + for (const stringpair_list_t *l = list; l && l->value; l=l->next) { + StringPair_t *value = StringPair_from_Struct(l->value, NULL); + if (ASN_SEQUENCE_ADD(&result->list, value)) { + ASN_STRUCT_FREE(asn_DEF_StringPair, value); + goto enomem; + } + } + + return result; + +enomem: + if (allocated) + ASN_STRUCT_FREE(asn_DEF_StringPairList, result); + return NULL; +} + +stringpair_list_t *StringPairList_to_stringpair_list( + StringPairList_t *list, + stringpair_list_t *result + ) +{ + bool allocated = !result; + + assert(list); + if (!list) + return NULL; + + if (allocated) + result = new_stringpair_list(NULL); + if (!result) + return NULL; + + stringpair_list_t *r = result; + for (int i=0; ilist.count; i++) { + stringpair_t *value = StringPair_to_Struct(list->list.array[i], NULL); + r = stringpair_list_add(r, value); + if (!r) + goto enomem; + } + + return result; + +enomem: + if (allocated) + free_stringpair_list(result); + return NULL; +} + +PStringList_t *PStringList_from_stringlist( + const stringlist_t *list, + PStringList_t *result + ) +{ + bool allocated = !result; + + assert(list); + if (!list) + return NULL; + + if (allocated) { + result = (PStringList_t *) calloc(1, sizeof(PStringList_t)); + assert(result); + if (!result) + return NULL; + } + else { + asn_sequence_empty(result); + } + + for (const stringlist_t *l = list; l && l->value; l=l->next) { + PString_t *element = NULL; + int r = OCTET_STRING_fromBuf(element, l->value, -1); + if (r) + goto enomem; + if (ASN_SEQUENCE_ADD(&result->list, element)) { + ASN_STRUCT_FREE(asn_DEF_PString, element); + goto enomem; + } + } + + return result; + +enomem: + if (allocated) + ASN_STRUCT_FREE(asn_DEF_PStringList, result); + return NULL; +} + +stringlist_t *PStringList_to_stringlist( + PStringList_t *list, + stringlist_t *result + ) +{ + bool allocated = !result; + + assert(list); + if (!list) + return NULL; + + if (allocated) + result = new_stringlist(NULL); + if (!result) + return NULL; + + for (int i=0; ilist.count; i++) { + result->value = strndup((char *) list->list.array[i]->buf, + list->list.array[i]->size); + assert(result->value); + if (!result->value) + goto enomem; + } + + return result; + +enomem: + if (allocated) + free_stringlist(result); + return NULL; +} + diff --git a/src/map_asn1.h b/src/map_asn1.h index d13ccd92..5c526cb7 100644 --- a/src/map_asn1.h +++ b/src/map_asn1.h @@ -11,6 +11,10 @@ #include "identity_list.h" #include "../asn.1/Identity.h" #include "../asn.1/IdentityList.h" +#include "../asn.1/StringPair.h" +#include "../asn.1/StringPair.h" +#include "../asn.1/StringPairList.h" +#include "../asn.1/PStringList.h" #ifdef __cplusplus extern "C" { @@ -89,6 +93,122 @@ IdentityList_t *IdentityList_from_identity_list( identity_list *IdentityList_to_identity_list(IdentityList_t *list, identity_list *result); + +/** + * + * + * @brief Convert stringpair_t into ASN.1 StringPair_t + * + * @param value[in] stringpair_t to convert + * @param result[in,out] StringPair_t to update or NULL to alloc a new one + * + * @retval pointer to updated or allocated result + * + * @warning if a new struct is allocated, the ownership goes to the caller + * + */ + +StringPair_t *StringPair_from_Struct( + const stringpair_t *value, + StringPair_t *result + ); + + +/** + * + * + * @brief Convert ASN.1 StringPair_t into stringpair_t + * + * @param value[in] StringPair_t to convert + * @param result[inout] stringpair_t to update or NULL to alloc a new one + * + * @retval pointer to updated or allocated result + * + * @warning if a new struct is allocated, the ownership goes to the caller + * + */ + +stringpair_t *StringPair_to_Struct(StringPair_t *value, stringpair_t *result); + + +/** + * + * + * @brief Convert stringpair_list_t into ASN.1 StringPairList_t + * + * @param list[in] stringpair_list to convert + * @param result[inout] StringPairList_t to update or NULL to alloc a new one + * + * @retval pointer to updated or allocated result + * + * @warning if a new struct is allocated, the ownership goes to the caller + * + */ + +StringPairList_t *StringPairList_from_stringpair_list( + const stringpair_list_t *list, + StringPairList_t *result + ); + +/** + * + * + * @brief Convert ASN.1 StringPairList_t to stringpair_list_t + * + * @param list[in] ASN.1 StringPairList_t to convert + * @param result[inout] stringpair_list_t to update or NULL to alloc a new one + * + * @retval pointer to updated or allocated result + * + * @warning if a new struct is allocated, the ownership goes to the caller + * + */ + +stringpair_list_t *StringPairList_to_stringpair_list( + StringPairList_t *list, + stringpair_list_t *result + ); + + +/** + * + * + * @brief Convert stringlist_t into ASN.1 PStringList_t + * + * @param list[in] stringlist to convert + * @param result[inout] PStringList_t to update or NULL to alloc a new one + * + * @retval pointer to updated or allocated result + * + * @warning if a new struct is allocated, the ownership goes to the caller + * + */ + +PStringList_t *PStringList_from_stringlist( + const stringlist_t *list, + PStringList_t *result + ); + +/** + * + * + * @brief Convert ASN.1 PStringList_t to stringlist_t + * + * @param list[in] ASN.1 PStringList_t to convert + * @param result[inout] stringlist_t to update or NULL to alloc a new one + * + * @retval pointer to updated or allocated result + * + * @warning if a new struct is allocated, the ownership goes to the caller + * + */ + +stringlist_t *StringPairList_to_stringlist( + StringPairList_t *list, + stringlist_t *result + ); + + #ifdef __cplusplus } #endif From a0efd037bb999b36ae86a7180931bb63e7fb5254 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Sun, 8 Aug 2021 11:56:16 +0200 Subject: [PATCH 07/60] implement BlobList_from_bloblist() --- asn.1/message.asn1 | 22 ++++++---- src/map_asn1.c | 100 +++++++++++++++++++++++++++++++++++++++++++++ src/map_asn1.h | 51 ++++++++++++++++++++++- 3 files changed, 163 insertions(+), 10 deletions(-) diff --git a/asn.1/message.asn1 b/asn.1/message.asn1 index 71708d19..230108ed 100644 --- a/asn.1/message.asn1 +++ b/asn.1/message.asn1 @@ -27,22 +27,28 @@ MessageDirection ::= ENUMERATED { outgoing (1) } +ContentDisposition ::= ENUMERATED { + attachment (0), + inline (1), + other (2) +} Blob ::= SEQUENCE { value OCTET STRING (SIZE(0..102400000)), -- up to 100 MB mime-type PString OPTIONAL, - filename PString OPTIONAL + filename PString OPTIONAL, + disposition ContentDisposition } BlobList ::= SEQUENCE OF Blob -/* -For the purposes of this profile, GeneralizedTime values MUST be -expressed in Coordinated Universal Time (UTC) and MUST include seconds -(i.e., times are YYYYMMDDHHMMSSZ), even where the number of seconds -is zero. GeneralizedTime values MUST NOT include fractional seconds. -To make this more explicit, the type-name "Timestamp" is used in this profile. -*/ +-- For the purposes of this profile, GeneralizedTime values MUST be +-- expressed in Coordinated Universal Time (UTC) and MUST include seconds +-- (i.e., times are YYYYMMDDHHMMSSZ), even where the number of seconds +-- is zero. GeneralizedTime values MUST NOT include fractional seconds. +-- To make this more explicit, the type-name "Timestamp" is used in this +-- profile. + Timestamp ::= GeneralizedTime diff --git a/src/map_asn1.c b/src/map_asn1.c index f1840304..60dd1aed 100644 --- a/src/map_asn1.c +++ b/src/map_asn1.c @@ -401,3 +401,103 @@ enomem: return NULL; } +BlobList_t *BlobList_from_bloblist( + bloblist_t *list, + BlobList_t *result, + bool copy, + size_t max_blob_size + ) +{ + bool allocated = !result; + + assert(list); + if (!list) + return NULL; + + if (allocated) { + result = (BlobList_t *) calloc(1, sizeof(BlobList_t)); + assert(result); + if (!result) + return NULL; + } + else { + asn_sequence_empty(result); + } + + size_t rest_blob_size = max_blob_size; + + for (bloblist_t *l = list; l && l->value; l=l->next) { + Blob_t *element = (Blob_t *) calloc(1, sizeof(Blob_t)); + assert(element); + if (!element) + goto enomem; + + int r = 0; + + if (l->size > rest_blob_size) + goto enomem; + rest_blob_size -= l->size; + + if (copy) { + r = OCTET_STRING_fromBuf(&element->value, l->value, l->size); + if (r) + goto enomem; + } + else /* move */ { +#if defined(__CHAR_BIT__) && __CHAR_BIT__ == 8 + element->value.buf = (uint8_t *) l->value; +#else + // FIXME: this is problematic on platforms with bytes != octets + // we want this warning + element->value.buf = l->value; +#endif + l->value = NULL; + element->value.size = l->size; + l->size = 0; + } + + if (!EMPTYSTR(l->mime_type)) { + PString_t *_mime_type = NULL; + r = OCTET_STRING_fromBuf(_mime_type, l->mime_type, -1); + if (r) + goto enomem; + element->mime_type = _mime_type; + } + + if (!EMPTYSTR(l->filename)) { + PString_t *_filename = NULL; + r = OCTET_STRING_fromBuf(_filename, l->filename, -1); + if (r) + goto enomem; + element->filename = _filename; + } + + switch (l->disposition) { + case PEP_CONTENT_DISP_ATTACHMENT: + element->disposition = ContentDisposition_attachment; + break; + case PEP_CONTENT_DISP_INLINE: + element->disposition = ContentDisposition_inline; + break; + case PEP_CONTENT_DISP_OTHER: + element->disposition = ContentDisposition_other; + break; + default: + assert(0); // should not happen; use default + element->disposition = ContentDisposition_attachment; + } + + if (ASN_SEQUENCE_ADD(&result->list, element)) { + ASN_STRUCT_FREE(asn_DEF_Blob, element); + goto enomem; + } + } + + return result; + +enomem: + if (allocated) + ASN_STRUCT_FREE(asn_DEF_BlobList, result); + return NULL; +} + diff --git a/src/map_asn1.h b/src/map_asn1.h index 5c526cb7..4828183c 100644 --- a/src/map_asn1.h +++ b/src/map_asn1.h @@ -15,6 +15,7 @@ #include "../asn.1/StringPair.h" #include "../asn.1/StringPairList.h" #include "../asn.1/PStringList.h" +#include "../asn.1/BlobList.h" #ifdef __cplusplus extern "C" { @@ -203,12 +204,58 @@ PStringList_t *PStringList_from_stringlist( * */ -stringlist_t *StringPairList_to_stringlist( - StringPairList_t *list, +stringlist_t *PStringList_to_stringlist( + PStringList_t *list, stringlist_t *result ); +/** + * + * + * @brief Convert bloblist_t into ASN.1 BlobList_t + * + * @param list[in] bloblist to convert + * @param result[inout] BlobList_t to update or NULL to alloc a new one + * @param copy copy data if true, move data otherwise + * @param max_blob_size reject if sum(blob.size) > max_blob_size + * + * @retval pointer to updated or allocated result + * + * @warning if a new struct is allocated, the ownership goes to the caller + * + */ + +BlobList_t *BlobList_from_bloblist( + bloblist_t *list, + BlobList_t *result, + bool copy, + size_t max_blob_size + ); + +/** + * + * + * @brief Convert ASN.1 BlobList_t to bloblist_t + * + * @param list[in] ASN.1 BlobList_t to convert + * @param result[inout] bloblist_t to update or NULL to alloc a new one + * @param copy copy data if true, move data otherwise + * @param max_blob_size reject if sum(blob.size) > max_blob_size + * + * @retval pointer to updated or allocated result + * + * @warning if a new struct is allocated, the ownership goes to the caller + * + */ + +bloblist_t *BlobList_to_bloblist( + BlobList_t *list, + bloblist_t *result, + bool copy, + size_t max_blob_size + ); + #ifdef __cplusplus } #endif From 7c6b80d77415a1756967b1229d0033a7ce8bb0e3 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Sun, 8 Aug 2021 12:46:33 +0200 Subject: [PATCH 08/60] implement BlobList_to_bloblist() --- src/map_asn1.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/src/map_asn1.c b/src/map_asn1.c index 60dd1aed..c6ad33a5 100644 --- a/src/map_asn1.c +++ b/src/map_asn1.c @@ -501,3 +501,98 @@ enomem: return NULL; } +bloblist_t *BlobList_to_bloblist( + BlobList_t *list, + bloblist_t *result, + bool copy, + size_t max_blob_size + ) +{ + bool allocated = !result; + + assert(list); + if (!list) + return NULL; + + if (allocated) + result = new_bloblist(NULL, 0, NULL, NULL); + if (!result) + return NULL; + + size_t rest_blob_size = max_blob_size; + + bloblist_t *r = result; + for (int i=0; ilist.count; i++) { + if (list->list.array[i]->value.size > rest_blob_size) + goto enomem; + rest_blob_size -= list->list.array[i]->value.size; + + char *_mime_type = NULL; + if (list->list.array[i]->mime_type) { + _mime_type = strndup((char *) list->list.array[i]->mime_type->buf, + list->list.array[i]->mime_type->size); + assert(_mime_type); + if (!_mime_type) + goto enomem; + } + + char *_filename = NULL; + if (list->list.array[i]->filename) { + _filename = strndup((char *) list->list.array[i]->filename->buf, + list->list.array[i]->filename->size); + assert(_filename); + if (!_filename) + goto enomem; + } + +#if defined(__CHAR_BIT__) && __CHAR_BIT__ == 8 + char *_data = (char *) list->list.array[i]->value.buf; +#else + // FIXME: this is problematic on platforms with bytes != octets + // we want this warning + char *_data = list->list.array[i]->value.buf; +#endif + + if (copy) { + _data = strndup(_data, list->list.array[i]->value.size); + assert(_data); + if (!_data) + goto enomem; + } + + // bloblist_add() has move semantics + r = bloblist_add(r, _data, list->list.array[i]->value.size, _mime_type, + _filename); + + if (!copy) { + list->list.array[i]->value.buf = NULL; + list->list.array[i]->value.size = 0; + } + + if (!r) + goto enomem; + + switch (list->list.array[i]->disposition) { + case ContentDisposition_attachment: + r->disposition = PEP_CONTENT_DISP_ATTACHMENT; + break; + case ContentDisposition_inline: + r->disposition = PEP_CONTENT_DISP_INLINE; + break; + case ContentDisposition_other: + r->disposition = PEP_CONTENT_DISP_OTHER; + break; + default: + assert(0); // should not happen; use default + r->disposition = PEP_CONTENT_DISP_ATTACHMENT; + } + } + + return result; + +enomem: + if (allocated) + free_bloblist(result); + return NULL; +} + From 9f761a04ba652488aabf183aebaddf9e25862491 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Sun, 8 Aug 2021 12:51:22 +0200 Subject: [PATCH 09/60] adding safeguard; if the structure is healthy this should never happen --- src/map_asn1.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/map_asn1.c b/src/map_asn1.c index c6ad33a5..62c63354 100644 --- a/src/map_asn1.c +++ b/src/map_asn1.c @@ -523,6 +523,11 @@ bloblist_t *BlobList_to_bloblist( bloblist_t *r = result; for (int i=0; ilist.count; i++) { + // this should not happen + assert(list->list.array[i]); + if (!list->list.array[i]) + goto enomem; + if (list->list.array[i]->value.size > rest_blob_size) goto enomem; rest_blob_size -= list->list.array[i]->value.size; From b1a1be1ee1b5a6d411e216987bcbb6b69a1f1b88 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Tue, 10 Aug 2021 10:29:35 +0200 Subject: [PATCH 10/60] adding PEPMessage_from_message() --- src/map_asn1.c | 298 +++++++++++++++++++++++++++++++++++++++++++++++-- src/map_asn1.h | 61 ++++++++-- 2 files changed, 340 insertions(+), 19 deletions(-) diff --git a/src/map_asn1.c b/src/map_asn1.c index 62c63354..1dbd9db9 100644 --- a/src/map_asn1.c +++ b/src/map_asn1.c @@ -131,8 +131,8 @@ IdentityList_t *IdentityList_from_identity_list( { bool allocated = !result; - assert(list); - if (!list) + assert(list && list->ident); + if (!(list && list->ident)) return NULL; if (allocated) { @@ -267,8 +267,8 @@ StringPairList_t *StringPairList_from_stringpair_list( { bool allocated = !result; - assert(list); - if (!list) + assert(list && list->value); + if (!(list && list->value)) return NULL; if (allocated) { @@ -336,8 +336,8 @@ PStringList_t *PStringList_from_stringlist( { bool allocated = !result; - assert(list); - if (!list) + assert(list && list->value); + if (!(list && list->value)) return NULL; if (allocated) { @@ -410,8 +410,8 @@ BlobList_t *BlobList_from_bloblist( { bool allocated = !result; - assert(list); - if (!list) + assert(list && list->value); + if (!(list && list->value)) return NULL; if (allocated) { @@ -457,7 +457,11 @@ BlobList_t *BlobList_from_bloblist( } if (!EMPTYSTR(l->mime_type)) { - PString_t *_mime_type = NULL; + PString_t *_mime_type = (PString_t *) calloc(1, sizeof(PString_t)); + assert(_mime_type); + if (!_mime_type) + goto enomem; + r = OCTET_STRING_fromBuf(_mime_type, l->mime_type, -1); if (r) goto enomem; @@ -465,7 +469,11 @@ BlobList_t *BlobList_from_bloblist( } if (!EMPTYSTR(l->filename)) { - PString_t *_filename = NULL; + PString_t *_filename = (PString_t *) calloc(1, sizeof(PString_t)); + assert(_filename); + if (!_filename) + goto enomem; + r = OCTET_STRING_fromBuf(_filename, l->filename, -1); if (r) goto enomem; @@ -601,3 +609,273 @@ enomem: return NULL; } +PEPMessage_t *PEPMessage_from_message( + message *msg, + PEPMessage_t *result, + bool copy, + size_t max_blob_size + ) +{ + bool allocated = !result; + + assert(msg); + if (!msg) + return NULL; + + if (allocated) { + result = (PEPMessage_t *) calloc(1, sizeof(PEPMessage_t)); + assert(result); + if (!result) + return NULL; + } + else { + asn_sequence_empty(result); + } + + // direction will be skipped on the line + + if (!EMPTYSTR(msg->id)) { + PString_t *str = (PString_t *) calloc(1, sizeof(PString_t)); + assert(str); + if (!str) + goto enomem; + + int r = OCTET_STRING_fromBuf(str, msg->id, -1); + if (r) + goto enomem; + + result->id = str; + } + + if (msg->sent) { + Timestamp_t *ts = asn_time2GT(NULL, msg->sent, 1); + if (!ts) + goto enomem; + + result->sent = ts; + } + + if (msg->recv) { + Timestamp_t *ts = asn_time2GT(NULL, msg->recv, 1); + if (!ts) + goto enomem; + + result->recv = ts; + } + + if (!msg->from) // from is not optional + goto enomem; + Identity_from_Struct(msg->from, &result->from); + + if (msg->to && msg->to->ident) { + IdentityList_t *l = IdentityList_from_identity_list(msg->to, NULL); + if (!l) + goto enomem; + + result->to = l; + } + + if (msg->cc && msg->cc->ident) { + IdentityList_t *l = IdentityList_from_identity_list(msg->cc, NULL); + if (!l) + goto enomem; + + result->cc = l; + } + + if (msg->bcc && msg->bcc->ident) { + IdentityList_t *l = IdentityList_from_identity_list(msg->bcc, NULL); + if (!l) + goto enomem; + + result->bcc = l; + } + + if (msg->recv_by) { + Identity_t *i = Identity_from_Struct(msg->recv_by, NULL); + if (!i) + goto enomem; + + result->recv_by = i; + } + + if (msg->reply_to && msg->reply_to->ident) { + IdentityList_t *l = IdentityList_from_identity_list(msg->reply_to, NULL); + if (!l) + goto enomem; + + result->reply_to = l; + } + + if (msg->in_reply_to && msg->in_reply_to->value) { + PStringList_t *l = PStringList_from_stringlist(msg->in_reply_to, NULL); + if (!l) + goto enomem; + + result->in_reply_to = l; + } + + if (msg->references && msg->references->value) { + PStringList_t *l = PStringList_from_stringlist(msg->references, NULL); + if (!l) + goto enomem; + + result->references = l; + } + + if (msg->keywords && msg->keywords->value) { + PStringList_t *l = PStringList_from_stringlist(msg->keywords, NULL); + if (!l) + goto enomem; + + result->keywords = l; + } + + if (!EMPTYSTR(msg->comments)) { + PString_t *str = (PString_t *) calloc(1, sizeof(PString_t)); + assert(str); + if (!str) + goto enomem; + + int r = OCTET_STRING_fromBuf(str, msg->comments, -1); + if (r) + goto enomem; + + result->comments = str; + } + + if (msg->opt_fields && msg->opt_fields->value) { + StringPairList_t *l = StringPairList_from_stringpair_list(msg->opt_fields, NULL); + if (!l) + goto enomem; + + result->opt_fields = l; + } + + switch (msg->enc_format) { + case PEP_enc_none: + result->enc_format = EncFormat_none; + break; + // case PEP_enc_pieces: + case PEP_enc_inline: + result->enc_format = EncFormat_inline; + break; + case PEP_enc_S_MIME: + result->enc_format = EncFormat_s_mime; + break; + case PEP_enc_PGP_MIME: + result->enc_format = EncFormat_pgp_mime; + break; + case PEP_enc_PEP: + result->enc_format = EncFormat_pEp; + break; + case PEP_enc_PGP_MIME_Outlook1: + result->enc_format = EncFormat_pgp_mime_outlook1; + break; + case PEP_enc_inline_EA: + result->enc_format = EncFormat_inline_ea; + break; + case PEP_enc_auto: + result->enc_format = EncFormat_pEp; + break; + default: + assert(0); + result->enc_format = EncFormat_pEp; + } + + if (!EMPTYSTR(msg->_sender_fpr)) { + Hash_t *str = (Hash_t *) calloc(1, sizeof(Hash_t)); + assert(str); + if (!str) + goto enomem; + + int r = OCTET_STRING_fromBuf(str, msg->_sender_fpr, -1); + if (r) + goto enomem; + + result->sender_fpr = str; + } + + if (!EMPTYSTR(msg->shortmsg)) { + PString_t *str = (PString_t *) calloc(1, sizeof(PString_t)); + assert(str); + if (!str) + goto enomem; + + int r = OCTET_STRING_fromBuf(str, msg->shortmsg, -1); + if (r) + goto enomem; + + result->shortmsg = str; + } + + size_t rest_blob_size = max_blob_size; + + if (!EMPTYSTR(msg->longmsg)) { + PString_t *str = (PString_t *) calloc(1, sizeof(PString_t)); + assert(str); + if (!str) + goto enomem; + + if (copy) { + int r = OCTET_STRING_fromBuf(str, msg->longmsg, -1); + if (r) + goto enomem; + if (str->size > rest_blob_size) + goto enomem; + } + else /* move */ { + str->size = strlen(msg->longmsg); + if (str->size > rest_blob_size) + goto enomem; + + str->buf = (uint8_t *) msg->longmsg; + msg->longmsg = NULL; + } + + rest_blob_size -= str->size; + result->longmsg = str; + } + + if (!EMPTYSTR(msg->longmsg_formatted)) { + PString_t *str = (PString_t *) calloc(1, sizeof(PString_t)); + assert(str); + if (!str) + goto enomem; + + if (copy) { + int r = OCTET_STRING_fromBuf(str, msg->longmsg_formatted, -1); + if (r) + goto enomem; + if (str->size > rest_blob_size) + goto enomem; + } + else /* move */ { + str->size = strlen(msg->longmsg_formatted); + if (str->size > rest_blob_size) + goto enomem; + + str->buf = (uint8_t *) msg->longmsg_formatted; + msg->longmsg_formatted = NULL; + } + + rest_blob_size -= str->size; + result->longmsg_formatted = str; + } + + if (msg->attachments && msg->attachments->value) { + BlobList_t *bl = BlobList_from_bloblist(msg->attachments, NULL, copy, + rest_blob_size); + if (!bl) + goto enomem; + result->attachments = bl; + } + + return result; + +enomem: + if (allocated) + ASN_STRUCT_FREE(asn_DEF_PEPMessage, result); + return NULL; +} + diff --git a/src/map_asn1.h b/src/map_asn1.h index 4828183c..b82846af 100644 --- a/src/map_asn1.h +++ b/src/map_asn1.h @@ -7,15 +7,8 @@ #ifndef MAP_ASN1_H #define MAP_ASN1_H -#include "pEpEngine.h" -#include "identity_list.h" -#include "../asn.1/Identity.h" -#include "../asn.1/IdentityList.h" -#include "../asn.1/StringPair.h" -#include "../asn.1/StringPair.h" -#include "../asn.1/StringPairList.h" -#include "../asn.1/PStringList.h" -#include "../asn.1/BlobList.h" +#include "message.h" +#include "../asn.1/PEPMessage.h" #ifdef __cplusplus extern "C" { @@ -233,6 +226,7 @@ BlobList_t *BlobList_from_bloblist( size_t max_blob_size ); + /** * * @@ -256,6 +250,55 @@ bloblist_t *BlobList_to_bloblist( size_t max_blob_size ); + +/** + * + * + * @brief Convert message into ASN.1 PEPMessage_t + * + * @param msg[in] message to convert + * @param result[inout] PEPMessage_t to update or NULL to alloc a new one + * @param copy copy data if true, move data otherwise + * @param max_blob_size reject if sum(blob.size) > max_blob_size + * + * @retval pointer to updated or allocated result + * + * @warning if a new struct is allocated, the ownership goes to the caller + * + */ + +PEPMessage_t *PEPMessage_from_message( + message *msg, + PEPMessage_t *result, + bool copy, + size_t max_blob_size + ); + + +/** + * + * + * @brief Convert ASN.1 PEPMessage_t to message + * + * @param msg[in] ASN.1 PEPMessage_t to convert + * @param result[inout] message to update or NULL to alloc a new one + * @param copy copy data if true, move data otherwise + * @param max_blob_size reject if sum(blob.size) > max_blob_size + * + * @retval pointer to updated or allocated result + * + * @warning if a new struct is allocated, the ownership goes to the caller + * + */ + +message *PEPMessage_to_message( + PEPMessage_t *msg, + message *result, + bool copy, + size_t max_blob_size + ); + + #ifdef __cplusplus } #endif From 1d421c9389d9827a40bec5244ff34dab49381962 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Tue, 10 Aug 2021 16:00:33 +0200 Subject: [PATCH 11/60] add PEPMessage_to_message() --- asn.1/message.asn1 | 14 --- src/map_asn1.c | 259 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 228 insertions(+), 45 deletions(-) diff --git a/asn.1/message.asn1 b/asn.1/message.asn1 index 230108ed..15ae5fa4 100644 --- a/asn.1/message.asn1 +++ b/asn.1/message.asn1 @@ -52,19 +52,6 @@ BlobList ::= SEQUENCE OF Blob Timestamp ::= GeneralizedTime -EncFormat ::= ENUMERATED { - none (0), -- message is not encrypted - inline (1), -- - s-mime (2), -- RFC5751 - pgp-mime (3), -- RFC3156 - pEp (4), -- pEp encryption format - pgp-mime-outlook1 (5), -- Message B0rken by Outlook type 1 - inline-ea (6) - -- not used on wire: - -- auto (255) -- -- figure out automatically where possible -} - - PEPMessage ::= SEQUENCE { direction MessageDirection OPTIONAL, -- used only in "inner" messages id PString OPTIONAL, -- UTF-8 string of message ID @@ -88,7 +75,6 @@ PEPMessage ::= SEQUENCE { keywords PStringList OPTIONAL, -- list of UTF-8 strings with keywords comments PString OPTIONAL, -- UTF-8 string with comments opt-fields StringPairList OPTIONAL, -- optional fields - enc-format EncFormat DEFAULT none, -- format of encrypted data sender-fpr Hash OPTIONAL, -- fingerprint of sending signer -- At least one of shortmsg, longmsg, longmsg-formatted must be present diff --git a/src/map_asn1.c b/src/map_asn1.c index 1dbd9db9..57e807fa 100644 --- a/src/map_asn1.c +++ b/src/map_asn1.c @@ -752,37 +752,6 @@ PEPMessage_t *PEPMessage_from_message( result->opt_fields = l; } - switch (msg->enc_format) { - case PEP_enc_none: - result->enc_format = EncFormat_none; - break; - // case PEP_enc_pieces: - case PEP_enc_inline: - result->enc_format = EncFormat_inline; - break; - case PEP_enc_S_MIME: - result->enc_format = EncFormat_s_mime; - break; - case PEP_enc_PGP_MIME: - result->enc_format = EncFormat_pgp_mime; - break; - case PEP_enc_PEP: - result->enc_format = EncFormat_pEp; - break; - case PEP_enc_PGP_MIME_Outlook1: - result->enc_format = EncFormat_pgp_mime_outlook1; - break; - case PEP_enc_inline_EA: - result->enc_format = EncFormat_inline_ea; - break; - case PEP_enc_auto: - result->enc_format = EncFormat_pEp; - break; - default: - assert(0); - result->enc_format = EncFormat_pEp; - } - if (!EMPTYSTR(msg->_sender_fpr)) { Hash_t *str = (Hash_t *) calloc(1, sizeof(Hash_t)); assert(str); @@ -879,3 +848,231 @@ enomem: return NULL; } +message *PEPMessage_to_message( + PEPMessage_t *msg, + message *result, + bool copy, + size_t max_blob_size + ) +{ + bool allocated = !result; + + assert(msg); + if (!msg) + return NULL; + + if (allocated) { + result = new_message(PEP_dir_incoming); + if (!result) + goto enomem; + } + + if (msg->direction) { + switch (*msg->direction) { + case MessageDirection_incoming: + result->dir = PEP_dir_incoming; + break; + case MessageDirection_outgoing: + result->dir = PEP_dir_outgoing; + break; + default: + assert(0); + } + } + + if (msg->id) { + result->id = strndup((char *) msg->id->buf, msg->id->size); + assert(result->id); + if (!result->id) + goto enomem; + } + + if (msg->sent) { + timestamp *_sent = new_timestamp(0); + if (!_sent) + goto enomem; + + if (asn_GT2time(msg->sent, _sent, 1) == -1) + goto enomem; + result->sent = _sent; + } + + if (msg->recv) { + timestamp *_recv = new_timestamp(0); + if (!_recv) + goto enomem; + + if (asn_GT2time(msg->recv, _recv, 1) == -1) + goto enomem; + result->recv = _recv; + } + + // from is mandatory + result->from = Identity_to_Struct(&msg->from, NULL); + if (!result->from) + goto enomem; + + if (msg->to) { + identity_list *il = IdentityList_to_identity_list(msg->to, NULL); + if (!il) + goto enomem; + + result->to = il; + } + + if (msg->cc) { + identity_list *il = IdentityList_to_identity_list(msg->cc, NULL); + if (!il) + goto enomem; + + result->cc = il; + } + + if (msg->bcc) { + identity_list *il = IdentityList_to_identity_list(msg->bcc, NULL); + if (!il) + goto enomem; + + result->bcc = il; + } + + if (msg->recv_by) { + pEp_identity *i = Identity_to_Struct(msg->recv_by, NULL); + if (!i) + goto enomem; + + result->recv_by = i; + } + + if (msg->reply_to) { + identity_list *il = IdentityList_to_identity_list(msg->reply_to, NULL); + if (!il) + goto enomem; + + result->reply_to = il; + } + + if (msg->in_reply_to) { + stringlist_t *l = PStringList_to_stringlist(msg->in_reply_to, NULL); + if (!l) + goto enomem; + + result->in_reply_to = l; + } + + if (msg->references) { + stringlist_t *l = PStringList_to_stringlist(msg->references, NULL); + if (!l) + goto enomem; + + result->references = l; + } + + if (msg->keywords) { + stringlist_t *l = PStringList_to_stringlist(msg->keywords, NULL); + if (!l) + goto enomem; + + result->keywords = l; + } + + if (msg->comments) { + char *s = strndup((char *) msg->comments->buf, msg->comments->size); + assert(s); + if (!s) + goto enomem; + + result->comments = s; + } + + if (msg->opt_fields) { + stringpair_list_t *l = + StringPairList_to_stringpair_list(msg->opt_fields, NULL); + if (!l) + goto enomem; + + result->opt_fields = l; + } + + if (msg->sender_fpr) { + char *_sender_fpr = strndup((char *) msg->sender_fpr->buf, + msg->sender_fpr->size); + if (_sender_fpr) + goto enomem; + + result->_sender_fpr = _sender_fpr; + } + + if (msg->shortmsg) { + char *s = strndup((char *) msg->shortmsg->buf, msg->shortmsg->size); + assert(s); + if (!s) + goto enomem; + + result->shortmsg = s; + } + + size_t rest_blob_size = max_blob_size; + + if (msg->longmsg) { + if (msg->longmsg->size > rest_blob_size) + goto enomem; + + char *s = NULL; + + if (copy) { + s = strndup((char *) msg->longmsg->buf, msg->longmsg->size); + if (!s) + goto enomem; + rest_blob_size -= msg->longmsg->size; + } + else /* move */ { + s = (char *) msg->longmsg->buf; + msg->longmsg->buf = NULL; + rest_blob_size -= msg->longmsg->size; + msg->longmsg->size = 0; + } + + result->longmsg = s; + } + + if (msg->longmsg_formatted) { + if (msg->longmsg_formatted->size > rest_blob_size) + goto enomem; + + char *s = NULL; + + if (copy) { + s = strndup((char *) msg->longmsg_formatted->buf, + msg->longmsg_formatted->size); + if (!s) + goto enomem; + rest_blob_size -= msg->longmsg_formatted->size; + } + else /* move */ { + s = (char *) msg->longmsg_formatted->buf; + msg->longmsg_formatted->buf = NULL; + rest_blob_size -= msg->longmsg_formatted->size; + msg->longmsg_formatted->size = 0; + } + + result->longmsg_formatted = s; + } + + if (msg->attachments) { + bloblist_t *a = BlobList_to_bloblist(msg->attachments, NULL, copy, + rest_blob_size); + if (!a) + goto enomem; + + result->attachments = a; + } + + return result; + +enomem: + if (allocated) + free_message(result); + return NULL; +} + From 00c658e7356a76ce42a6f87272ff4bacf1a72539 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Tue, 10 Aug 2021 18:39:55 +0200 Subject: [PATCH 12/60] support disabling max_blob_size --- src/map_asn1.c | 8 ++++++++ src/map_asn1.h | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/map_asn1.c b/src/map_asn1.c index 57e807fa..02306c23 100644 --- a/src/map_asn1.c +++ b/src/map_asn1.c @@ -409,6 +409,8 @@ BlobList_t *BlobList_from_bloblist( ) { bool allocated = !result; + if (!max_blob_size) + max_blob_size = SIZE_MAX; assert(list && list->value); if (!(list && list->value)) @@ -517,6 +519,8 @@ bloblist_t *BlobList_to_bloblist( ) { bool allocated = !result; + if (!max_blob_size) + max_blob_size = SIZE_MAX; assert(list); if (!list) @@ -617,6 +621,8 @@ PEPMessage_t *PEPMessage_from_message( ) { bool allocated = !result; + if (!max_blob_size) + max_blob_size = SIZE_MAX; assert(msg); if (!msg) @@ -856,6 +862,8 @@ message *PEPMessage_to_message( ) { bool allocated = !result; + if (!max_blob_size) + max_blob_size = SIZE_MAX; assert(msg); if (!msg) diff --git a/src/map_asn1.h b/src/map_asn1.h index b82846af..19037f94 100644 --- a/src/map_asn1.h +++ b/src/map_asn1.h @@ -212,6 +212,7 @@ stringlist_t *PStringList_to_stringlist( * @param result[inout] BlobList_t to update or NULL to alloc a new one * @param copy copy data if true, move data otherwise * @param max_blob_size reject if sum(blob.size) > max_blob_size + * to disable set to 0 * * @retval pointer to updated or allocated result * @@ -236,6 +237,7 @@ BlobList_t *BlobList_from_bloblist( * @param result[inout] bloblist_t to update or NULL to alloc a new one * @param copy copy data if true, move data otherwise * @param max_blob_size reject if sum(blob.size) > max_blob_size + * to disable set to 0 * * @retval pointer to updated or allocated result * @@ -260,6 +262,7 @@ bloblist_t *BlobList_to_bloblist( * @param result[inout] PEPMessage_t to update or NULL to alloc a new one * @param copy copy data if true, move data otherwise * @param max_blob_size reject if sum(blob.size) > max_blob_size + * to disable set to 0 * * @retval pointer to updated or allocated result * @@ -284,6 +287,7 @@ PEPMessage_t *PEPMessage_from_message( * @param result[inout] message to update or NULL to alloc a new one * @param copy copy data if true, move data otherwise * @param max_blob_size reject if sum(blob.size) > max_blob_size + * to disable set to 0 * * @retval pointer to updated or allocated result * From 0999587a013d48bbc9cce901aad2be787692b316 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Tue, 10 Aug 2021 23:50:20 +0200 Subject: [PATCH 13/60] adding MapAsn1Test.check_map_asn1_message --- src/map_asn1.c | 61 +++++++++++++++++++----------------- src/map_asn1.h | 13 +++----- test/src/MapAsn1Test.cc | 69 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 37 deletions(-) diff --git a/src/map_asn1.c b/src/map_asn1.c index 02306c23..7513c0bd 100644 --- a/src/map_asn1.c +++ b/src/map_asn1.c @@ -227,18 +227,16 @@ enomem: return NULL; } -stringpair_t *StringPair_to_Struct(StringPair_t *value, stringpair_t *result) +stringpair_t *StringPair_to_Struct(StringPair_t *value) { - bool allocated = !result; - assert(value); if (!value) return NULL; - if (allocated) - result = new_stringpair(NULL, NULL); + stringpair_t *result = (stringpair_t *) calloc(1, sizeof(stringpair_t)); + assert(result); if (!result) - return NULL; + goto enomem; result->key = strndup((char *) value->key.buf, value->key.size); @@ -255,8 +253,7 @@ stringpair_t *StringPair_to_Struct(StringPair_t *value, stringpair_t *result) return result; enomem: - if (allocated) - free_stringpair(result); + free_stringpair(result); return NULL; } @@ -315,7 +312,7 @@ stringpair_list_t *StringPairList_to_stringpair_list( stringpair_list_t *r = result; for (int i=0; ilist.count; i++) { - stringpair_t *value = StringPair_to_Struct(list->list.array[i], NULL); + stringpair_t *value = StringPair_to_Struct(list->list.array[i]); r = stringpair_list_add(r, value); if (!r) goto enomem; @@ -351,7 +348,11 @@ PStringList_t *PStringList_from_stringlist( } for (const stringlist_t *l = list; l && l->value; l=l->next) { - PString_t *element = NULL; + PString_t *element = (PString_t *) calloc(1, sizeof(PString_t)); + assert(element); + if (!element) + goto enomem; + int r = OCTET_STRING_fromBuf(element, l->value, -1); if (r) goto enomem; @@ -369,35 +370,39 @@ enomem: return NULL; } -stringlist_t *PStringList_to_stringlist( - PStringList_t *list, - stringlist_t *result - ) +stringlist_t *PStringList_to_stringlist(PStringList_t *list) { - bool allocated = !result; - assert(list); if (!list) return NULL; - if (allocated) - result = new_stringlist(NULL); + stringlist_t *result = (stringlist_t *) calloc(1, sizeof(stringlist_t)); + assert(result); if (!result) - return NULL; + goto enomem; + + stringlist_t *r = result; for (int i=0; ilist.count; i++) { - result->value = strndup((char *) list->list.array[i]->buf, + char *s = strndup((char *) list->list.array[i]->buf, list->list.array[i]->size); - assert(result->value); - if (!result->value) + assert(s); + if (!s) goto enomem; + r->value = s; + if (i < list->list.count-1) { + r->next = (stringlist_t *) calloc(1, sizeof(stringlist_t)); + assert(r->next); + if (!r->next) + goto enomem; + r = r->next; + } } return result; enomem: - if (allocated) - free_stringlist(result); + free_stringlist(result); return NULL; } @@ -961,7 +966,7 @@ message *PEPMessage_to_message( } if (msg->in_reply_to) { - stringlist_t *l = PStringList_to_stringlist(msg->in_reply_to, NULL); + stringlist_t *l = PStringList_to_stringlist(msg->in_reply_to); if (!l) goto enomem; @@ -969,7 +974,7 @@ message *PEPMessage_to_message( } if (msg->references) { - stringlist_t *l = PStringList_to_stringlist(msg->references, NULL); + stringlist_t *l = PStringList_to_stringlist(msg->references); if (!l) goto enomem; @@ -977,7 +982,7 @@ message *PEPMessage_to_message( } if (msg->keywords) { - stringlist_t *l = PStringList_to_stringlist(msg->keywords, NULL); + stringlist_t *l = PStringList_to_stringlist(msg->keywords); if (!l) goto enomem; @@ -1005,7 +1010,7 @@ message *PEPMessage_to_message( if (msg->sender_fpr) { char *_sender_fpr = strndup((char *) msg->sender_fpr->buf, msg->sender_fpr->size); - if (_sender_fpr) + if (!_sender_fpr) goto enomem; result->_sender_fpr = _sender_fpr; diff --git a/src/map_asn1.h b/src/map_asn1.h index 19037f94..86c0b3e1 100644 --- a/src/map_asn1.h +++ b/src/map_asn1.h @@ -114,15 +114,14 @@ StringPair_t *StringPair_from_Struct( * @brief Convert ASN.1 StringPair_t into stringpair_t * * @param value[in] StringPair_t to convert - * @param result[inout] stringpair_t to update or NULL to alloc a new one * * @retval pointer to updated or allocated result * - * @warning if a new struct is allocated, the ownership goes to the caller + * @warning a new struct is allocated, the ownership goes to the caller * */ -stringpair_t *StringPair_to_Struct(StringPair_t *value, stringpair_t *result); +stringpair_t *StringPair_to_Struct(StringPair_t *value); /** @@ -189,18 +188,14 @@ PStringList_t *PStringList_from_stringlist( * @brief Convert ASN.1 PStringList_t to stringlist_t * * @param list[in] ASN.1 PStringList_t to convert - * @param result[inout] stringlist_t to update or NULL to alloc a new one * * @retval pointer to updated or allocated result * - * @warning if a new struct is allocated, the ownership goes to the caller + * @warning a new struct is allocated, the ownership goes to the caller * */ -stringlist_t *PStringList_to_stringlist( - PStringList_t *list, - stringlist_t *result - ); +stringlist_t *PStringList_to_stringlist(PStringList_t *list); /** diff --git a/test/src/MapAsn1Test.cc b/test/src/MapAsn1Test.cc index 90a61ee8..d5fdd2b8 100644 --- a/test/src/MapAsn1Test.cc +++ b/test/src/MapAsn1Test.cc @@ -119,3 +119,72 @@ TEST_F(MapAsn1Test, check_map_asn1) { free_identity(ident1); free_identity(ident2); } + +TEST_F(MapAsn1Test, check_map_asn1_message) { + output_stream << "testing PEPMessage...\n"; + + message *msg = new_message(PEP_dir_outgoing); + msg->id = strdup("423"); + msg->shortmsg = strdup("hello, world"); + msg->longmsg = strdup("long message"); + msg->longmsg_formatted = strdup("

long message

"); + msg->attachments = new_bloblist(strdup("blob"), 5, "text/plain", "test.txt"); + bloblist_add(msg->attachments, strdup("bla"), 4, "application/octet-stream", "data.dat"); + msg->sent = new_timestamp(23); + msg->recv = new_timestamp(42); + msg->from = new_identity("alice@mail.com", "2342234223422342", "23", "Alice Miller"); + msg->from->comm_type = PEP_ct_pEp; + msg->from->lang[0] = 'd'; msg->from->lang[1] = 'e'; + msg->to = new_identity_list(new_identity("bob@mail.com", "4223422342234223", "42", "Bob Smith")); + identity_list_add(msg->to, new_identity("alice@mail.com", "2342234223422342", "23", "Alice Miller")); + msg->recv_by = new_identity("bob@mail.com", "4223422342234223", "42", "Bob Smith"); + msg->cc = new_identity_list(new_identity("bob@mail.com", "4223422342234223", "42", "Bob Smith")); + identity_list_add(msg->cc, new_identity("alice@mail.com", "2342234223422342", "23", "Alice Miller")); + msg->bcc = new_identity_list(new_identity("bob@mail.com", "4223422342234223", "42", "Bob Smith")); + identity_list_add(msg->bcc, new_identity("alice@mail.com", "2342234223422342", "23", "Alice Miller")); + msg->reply_to = new_identity_list(new_identity("bob@mail.com", "4223422342234223", "42", "Bob Smith")); + identity_list_add(msg->reply_to, new_identity("alice@mail.com", "2342234223422342", "23", "Alice Miller")); + msg->in_reply_to = new_stringlist("23234242"); + stringlist_add(msg->in_reply_to, "323234242"); + msg->references = new_stringlist("23234242"); + stringlist_add(msg->references , "323234242"); + msg->keywords = new_stringlist("something"); + stringlist_add(msg->keywords, "else"); + msg->comments = strdup("hello there"); + msg->opt_fields = new_stringpair_list(new_stringpair("key", "value")); + stringpair_list_add(msg->opt_fields, new_stringpair("otherkey", "othervalue")); + msg->_sender_fpr = strdup("2342234223422342"); + + PEPMessage_t *pm = PEPMessage_from_message(msg, NULL, false, 1024); + message *msg2 = PEPMessage_to_message(pm, NULL, false, 1024); + + ASSERT_STREQ(msg2->id, "423"); + ASSERT_STREQ(msg2->shortmsg, "hello, world"); + ASSERT_STREQ(msg2->longmsg, "long message"); + ASSERT_STREQ(msg2->longmsg_formatted, "

long message

"); + ASSERT_STREQ(msg2->attachments->mime_type, "text/plain"); + ASSERT_EQ(msg2->attachments->next->value[0], 'b'); + ASSERT_NULL(msg2->attachments->next->next); + ASSERT_EQ(msg2->sent->tm_sec, 23); + ASSERT_EQ(msg2->recv->tm_sec, 42); + ASSERT_STREQ(msg2->from->user_id, "23"); + ASSERT_STREQ(msg2->to->ident->user_id, "42"); + ASSERT_STREQ(msg2->to->next->ident->user_id, "23"); + ASSERT_STREQ(msg2->recv_by->user_id, "42"); + ASSERT_STREQ(msg2->cc->next->ident->user_id, "23"); + ASSERT_STREQ(msg2->bcc->next->ident->user_id, "23"); + ASSERT_STREQ(msg2->reply_to->next->ident->user_id, "23"); + ASSERT_STREQ(msg2->in_reply_to->value, "23234242"); + ASSERT_STREQ(msg2->in_reply_to->next->value, "323234242"); + ASSERT_STREQ(msg2->references->next->value, "323234242"); + ASSERT_STREQ(msg2->keywords->next->value, "else"); + ASSERT_STREQ(msg2->comments, "hello there"); + ASSERT_STREQ(msg2->opt_fields->value->key, "key"); + ASSERT_STREQ(msg2->opt_fields->next->value->value, "othervalue"); + ASSERT_STREQ(msg2->_sender_fpr, "2342234223422342"); + + ASN_STRUCT_FREE(asn_DEF_PEPMessage, pm); + free_message(msg); + free_message(msg2); +} + From e964ec6f2a5b0cf0deda4e1a0ad4977980d9240b Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Wed, 11 Aug 2021 10:44:31 +0200 Subject: [PATCH 14/60] add PEPMessage codec functions --- src/message_codec.c | 141 ++++++++++++++++++++++++++++++++++++++++++++ src/message_codec.h | 103 ++++++++++++++++++++++++++++++++ src/pEpEngine.h | 1 + 3 files changed, 245 insertions(+) create mode 100644 src/message_codec.c create mode 100644 src/message_codec.h diff --git a/src/message_codec.c b/src/message_codec.c new file mode 100644 index 00000000..d2da1688 --- /dev/null +++ b/src/message_codec.c @@ -0,0 +1,141 @@ +/** + * @file PEPMessage_codec.c + * @brief Implementation for PEPMessage encode and decode functions which transform message payloads to + * and from PER-encoded data, and XER text to and from PER + * + * @see https://www.itu.int/en/ITU-T/asn1/Pages/introduction.aspx + * + * @license GNU General Public License 3.0 - see LICENSE.txt + */ + +#include "platform.h" + +#include "distribution_codec.h" +#include "../asn.1/PEPMessage.h" +#include "pEp_internal.h" +#include "growing_buf.h" + +DYNAMIC_API PEP_STATUS decode_PEPMessage_message( + const char *data, + size_t size, + PEPMessage_t **msg + ) +{ + assert(data && msg); + if (!(data && msg)) + return PEP_ILLEGAL_VALUE; + + *msg = NULL; + PEPMessage_t *_msg = NULL; + uper_decode_complete(NULL, &asn_DEF_PEPMessage, (void **) &_msg, data, size); + if (!_msg) + return PEP_PEPMESSAGE_ILLEGAL_MESSAGE; + + *msg = _msg; + return PEP_STATUS_OK; +} + +PEP_STATUS encode_PEPMessage_message( + PEPMessage_t *msg, + char **data, + size_t *size + ) +{ + assert(data && msg); + if (!(data && msg)) + return PEP_ILLEGAL_VALUE; + + *data = NULL; + *size = 0; + + char *_data = NULL; + ssize_t _size = uper_encode_to_new_buffer(&asn_DEF_PEPMessage, NULL, msg, + (void **) &_data); + if (_size == -1) + return PEP_CANNOT_ENCODE; + + *data = _data; + *size = (size_t) _size; + + return PEP_STATUS_OK; +} + +PEP_STATUS PER_to_XER_PEPMessage_msg( + const char *data, + size_t size, + char **text + ) +{ + PEP_STATUS status = PEP_STATUS_OK; + growing_buf_t *dst = NULL; + + assert(data && text); + if (!(data && text)) + return PEP_ILLEGAL_VALUE; + + *text = NULL; + + PEPMessage_t *msg = NULL; + status = decode_PEPMessage_message(data, size, &msg); + if (status) + goto the_end; + + dst = new_growing_buf(); + if (!dst) { + status = PEP_OUT_OF_MEMORY; + goto the_end; + } + + asn_enc_rval_t er = xer_encode(&asn_DEF_PEPMessage, msg, XER_F_BASIC, + (asn_app_consume_bytes_f *) growing_buf_consume, (void *) dst); + if (er.encoded == -1) { + status = PEP_CANNOT_ENCODE; + goto the_end; + } + + *text = dst->data; + dst->data = NULL; + +the_end: + free_growing_buf(dst); + ASN_STRUCT_FREE(asn_DEF_PEPMessage, msg); + return status; +} + +PEP_STATUS XER_to_PER_PEPMessage_msg( + const char *text, + char **data, + size_t *size + ) +{ + PEP_STATUS status = PEP_STATUS_OK; + + assert(text && data && size); + if (!(text && data && size)) + return PEP_ILLEGAL_VALUE; + + *data = NULL; + *size = 0; + + PEPMessage_t *msg = NULL; + asn_dec_rval_t dr = xer_decode(NULL, &asn_DEF_PEPMessage, (void **) &msg, + (const void *) text, strlen(text)); + if (dr.code != RC_OK) { + status = PEP_PEPMESSAGE_ILLEGAL_MESSAGE; + goto the_end; + } + + char *_data = NULL; + size_t _size = 0; + status = encode_PEPMessage_message(msg, &_data, &_size); + if (status) + goto the_end; + + *data = _data; + *size = (size_t) _size; + +the_end: + ASN_STRUCT_FREE(asn_DEF_PEPMessage, msg); + return status; +} + diff --git a/src/message_codec.h b/src/message_codec.h new file mode 100644 index 00000000..6a451104 --- /dev/null +++ b/src/message_codec.h @@ -0,0 +1,103 @@ +/** + * @file PEPMessage_codec.h + * @brief Definitions for PEPMessage encode and decode functions which transform message payloads to + * and from PER-encoded data, and XER text to and from PER + * + * @see https://www.itu.int/en/ITU-T/asn1/Pages/introduction.aspx + * + * @license GNU General Public License 3.0 - see LICENSE.txt + */ + + +#ifndef PEPMESSAGE_CODEC_H +#define PEPMESSAGE_CODEC_H + +#include "pEpEngine.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +struct PEPMessage; + +/** + * + * + * @brief decode PER encoded PEPMessage message + * + * @param[in] data PER encoded data + * @param[in] size size of PER encoded data + * @param[out] msg decoded PEPMessage message + * + * @retval status + * + * @ownership msg goes into the ownership of the caller + */ +DYNAMIC_API PEP_STATUS decode_PEPMessage_message( + const char *data, + size_t size, + struct PEPMessage **msg + ); + +/** + * + * + * @brief decode PER encoded PEPMessage message + * + * @param[in] msg PEPMessage message to encode + * @param[out] data PER encoded data + * @param[out] size size of PER encoded data + * + * @retval status + * + * @ownership msg goes into the ownership of the caller + */ +DYNAMIC_API PEP_STATUS encode_PEPMessage_message( + struct PEPMessage *msg, + char **data, + size_t *size + ); + + +/** + * + * + * @brief decode PEPMessage message from PER into XER + * + * @param[in] data PER encoded data + * @param[in] size size of PER encoded data + * @param[out] text XER text of the same PEPMessage message + * + * @retval status + */ +DYNAMIC_API PEP_STATUS PER_to_XER_PEPMessage_msg( + const char *data, + size_t size, + char **text + ); + +/** + * + * + * @brief encode PEPMessage message from XER into PER + * + * @param[in] text string text with XER text of the PEPMessage message + * @param[out] data PER encoded data + * @param[out] size size of PER encoded data + * + * @retval status + */ +DYNAMIC_API PEP_STATUS XER_to_PER_PEPMessage_msg( + const char *text, + char **data, + size_t *size + ); + + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/src/pEpEngine.h b/src/pEpEngine.h index 0ea84d0b..f4906160 100644 --- a/src/pEpEngine.h +++ b/src/pEpEngine.h @@ -160,6 +160,7 @@ typedef enum { PEP_DISTRIBUTION_ILLEGAL_MESSAGE = 0x1002, PEP_STORAGE_ILLEGAL_MESSAGE = 0x1102, + PEP_PEPMESSAGE_ILLEGAL_MESSAGE = 0x1202, PEP_COMMIT_FAILED = 0xff01, PEP_MESSAGE_CONSUME = 0xff02, From 314b7a9fd81fe58762c3d9996a5aa43381993c18 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Wed, 11 Aug 2021 10:44:31 +0200 Subject: [PATCH 15/60] add PEPMessage codec functions and complete ENGINE-898 --- src/message_codec.c | 141 ++++++++++++++++++++++++++++++++++++++++++++ src/message_codec.h | 103 ++++++++++++++++++++++++++++++++ src/pEpEngine.h | 1 + 3 files changed, 245 insertions(+) create mode 100644 src/message_codec.c create mode 100644 src/message_codec.h diff --git a/src/message_codec.c b/src/message_codec.c new file mode 100644 index 00000000..d2da1688 --- /dev/null +++ b/src/message_codec.c @@ -0,0 +1,141 @@ +/** + * @file PEPMessage_codec.c + * @brief Implementation for PEPMessage encode and decode functions which transform message payloads to + * and from PER-encoded data, and XER text to and from PER + * + * @see https://www.itu.int/en/ITU-T/asn1/Pages/introduction.aspx + * + * @license GNU General Public License 3.0 - see LICENSE.txt + */ + +#include "platform.h" + +#include "distribution_codec.h" +#include "../asn.1/PEPMessage.h" +#include "pEp_internal.h" +#include "growing_buf.h" + +DYNAMIC_API PEP_STATUS decode_PEPMessage_message( + const char *data, + size_t size, + PEPMessage_t **msg + ) +{ + assert(data && msg); + if (!(data && msg)) + return PEP_ILLEGAL_VALUE; + + *msg = NULL; + PEPMessage_t *_msg = NULL; + uper_decode_complete(NULL, &asn_DEF_PEPMessage, (void **) &_msg, data, size); + if (!_msg) + return PEP_PEPMESSAGE_ILLEGAL_MESSAGE; + + *msg = _msg; + return PEP_STATUS_OK; +} + +PEP_STATUS encode_PEPMessage_message( + PEPMessage_t *msg, + char **data, + size_t *size + ) +{ + assert(data && msg); + if (!(data && msg)) + return PEP_ILLEGAL_VALUE; + + *data = NULL; + *size = 0; + + char *_data = NULL; + ssize_t _size = uper_encode_to_new_buffer(&asn_DEF_PEPMessage, NULL, msg, + (void **) &_data); + if (_size == -1) + return PEP_CANNOT_ENCODE; + + *data = _data; + *size = (size_t) _size; + + return PEP_STATUS_OK; +} + +PEP_STATUS PER_to_XER_PEPMessage_msg( + const char *data, + size_t size, + char **text + ) +{ + PEP_STATUS status = PEP_STATUS_OK; + growing_buf_t *dst = NULL; + + assert(data && text); + if (!(data && text)) + return PEP_ILLEGAL_VALUE; + + *text = NULL; + + PEPMessage_t *msg = NULL; + status = decode_PEPMessage_message(data, size, &msg); + if (status) + goto the_end; + + dst = new_growing_buf(); + if (!dst) { + status = PEP_OUT_OF_MEMORY; + goto the_end; + } + + asn_enc_rval_t er = xer_encode(&asn_DEF_PEPMessage, msg, XER_F_BASIC, + (asn_app_consume_bytes_f *) growing_buf_consume, (void *) dst); + if (er.encoded == -1) { + status = PEP_CANNOT_ENCODE; + goto the_end; + } + + *text = dst->data; + dst->data = NULL; + +the_end: + free_growing_buf(dst); + ASN_STRUCT_FREE(asn_DEF_PEPMessage, msg); + return status; +} + +PEP_STATUS XER_to_PER_PEPMessage_msg( + const char *text, + char **data, + size_t *size + ) +{ + PEP_STATUS status = PEP_STATUS_OK; + + assert(text && data && size); + if (!(text && data && size)) + return PEP_ILLEGAL_VALUE; + + *data = NULL; + *size = 0; + + PEPMessage_t *msg = NULL; + asn_dec_rval_t dr = xer_decode(NULL, &asn_DEF_PEPMessage, (void **) &msg, + (const void *) text, strlen(text)); + if (dr.code != RC_OK) { + status = PEP_PEPMESSAGE_ILLEGAL_MESSAGE; + goto the_end; + } + + char *_data = NULL; + size_t _size = 0; + status = encode_PEPMessage_message(msg, &_data, &_size); + if (status) + goto the_end; + + *data = _data; + *size = (size_t) _size; + +the_end: + ASN_STRUCT_FREE(asn_DEF_PEPMessage, msg); + return status; +} + diff --git a/src/message_codec.h b/src/message_codec.h new file mode 100644 index 00000000..6a451104 --- /dev/null +++ b/src/message_codec.h @@ -0,0 +1,103 @@ +/** + * @file PEPMessage_codec.h + * @brief Definitions for PEPMessage encode and decode functions which transform message payloads to + * and from PER-encoded data, and XER text to and from PER + * + * @see https://www.itu.int/en/ITU-T/asn1/Pages/introduction.aspx + * + * @license GNU General Public License 3.0 - see LICENSE.txt + */ + + +#ifndef PEPMESSAGE_CODEC_H +#define PEPMESSAGE_CODEC_H + +#include "pEpEngine.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +struct PEPMessage; + +/** + * + * + * @brief decode PER encoded PEPMessage message + * + * @param[in] data PER encoded data + * @param[in] size size of PER encoded data + * @param[out] msg decoded PEPMessage message + * + * @retval status + * + * @ownership msg goes into the ownership of the caller + */ +DYNAMIC_API PEP_STATUS decode_PEPMessage_message( + const char *data, + size_t size, + struct PEPMessage **msg + ); + +/** + * + * + * @brief decode PER encoded PEPMessage message + * + * @param[in] msg PEPMessage message to encode + * @param[out] data PER encoded data + * @param[out] size size of PER encoded data + * + * @retval status + * + * @ownership msg goes into the ownership of the caller + */ +DYNAMIC_API PEP_STATUS encode_PEPMessage_message( + struct PEPMessage *msg, + char **data, + size_t *size + ); + + +/** + * + * + * @brief decode PEPMessage message from PER into XER + * + * @param[in] data PER encoded data + * @param[in] size size of PER encoded data + * @param[out] text XER text of the same PEPMessage message + * + * @retval status + */ +DYNAMIC_API PEP_STATUS PER_to_XER_PEPMessage_msg( + const char *data, + size_t size, + char **text + ); + +/** + * + * + * @brief encode PEPMessage message from XER into PER + * + * @param[in] text string text with XER text of the PEPMessage message + * @param[out] data PER encoded data + * @param[out] size size of PER encoded data + * + * @retval status + */ +DYNAMIC_API PEP_STATUS XER_to_PER_PEPMessage_msg( + const char *text, + char **data, + size_t *size + ); + + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/src/pEpEngine.h b/src/pEpEngine.h index 0ea84d0b..f4906160 100644 --- a/src/pEpEngine.h +++ b/src/pEpEngine.h @@ -160,6 +160,7 @@ typedef enum { PEP_DISTRIBUTION_ILLEGAL_MESSAGE = 0x1002, PEP_STORAGE_ILLEGAL_MESSAGE = 0x1102, + PEP_PEPMESSAGE_ILLEGAL_MESSAGE = 0x1202, PEP_COMMIT_FAILED = 0xff01, PEP_MESSAGE_CONSUME = 0xff02, From 63cad5dc47d6c3bdbd34be8cd12ca8e9afd07466 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Wed, 11 Aug 2021 10:55:53 +0200 Subject: [PATCH 16/60] Bumped header patch number for NEXT release --- src/pEpEngine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pEpEngine.h b/src/pEpEngine.h index f4906160..689eeaa1 100644 --- a/src/pEpEngine.h +++ b/src/pEpEngine.h @@ -29,7 +29,7 @@ extern "C" { #define PEP_ENGINE_VERSION_MAJOR 3 #define PEP_ENGINE_VERSION_MINOR 2 #define PEP_ENGINE_VERSION_PATCH 0 -#define PEP_ENGINE_VERSION_RC 1 +#define PEP_ENGINE_VERSION_RC 2 #define PEP_OWN_USERID "pEp_own_userId" From 77e5ecb9ba86d3022b9c32878dd23c95008a1a38 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Wed, 11 Aug 2021 18:11:06 +0200 Subject: [PATCH 17/60] add encode_PEPMessage_message() and decode_PEPMessage_message() to MapAsn1Test.check_map_asn1_message --- test/src/MapAsn1Test.cc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/test/src/MapAsn1Test.cc b/test/src/MapAsn1Test.cc index d5fdd2b8..e5faec65 100644 --- a/test/src/MapAsn1Test.cc +++ b/test/src/MapAsn1Test.cc @@ -10,6 +10,7 @@ #include "pEpEngine.h" #include "pEp_internal.h" #include "map_asn1.h" +#include "message_codec.h" #include "TestUtilities.h" @@ -156,7 +157,17 @@ TEST_F(MapAsn1Test, check_map_asn1_message) { msg->_sender_fpr = strdup("2342234223422342"); PEPMessage_t *pm = PEPMessage_from_message(msg, NULL, false, 1024); - message *msg2 = PEPMessage_to_message(pm, NULL, false, 1024); + + char *data = NULL; + size_t data_size = 0; + PEP_STATUS status = encode_PEPMessage_message(pm, &data, &data_size); + ASSERT_EQ(status, PEP_STATUS_OK); + + PEPMessage_t *pm2 = NULL; + status = decode_PEPMessage_message(data, data_size, &pm2); + ASSERT_EQ(status, PEP_STATUS_OK); + + message *msg2 = PEPMessage_to_message(pm2, NULL, false, 1024); ASSERT_STREQ(msg2->id, "423"); ASSERT_STREQ(msg2->shortmsg, "hello, world"); @@ -184,7 +195,9 @@ TEST_F(MapAsn1Test, check_map_asn1_message) { ASSERT_STREQ(msg2->_sender_fpr, "2342234223422342"); ASN_STRUCT_FREE(asn_DEF_PEPMessage, pm); + ASN_STRUCT_FREE(asn_DEF_PEPMessage, pm2); free_message(msg); free_message(msg2); + free(data); } From cd0fdedcf5b2c3919e99cf8e090976bf85fa1e0f Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 12 Aug 2021 12:08:36 +0200 Subject: [PATCH 18/60] slightly redesigned --- src/pEpEngine.h | 15 +++++++++++++++ src/trans_auto.c | 6 ++++-- src/trans_auto.h | 8 ++++++-- src/transport.h | 30 +++++++++++++++++++++--------- 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/pEpEngine.h b/src/pEpEngine.h index 689eeaa1..3b5e6044 100644 --- a/src/pEpEngine.h +++ b/src/pEpEngine.h @@ -162,6 +162,21 @@ typedef enum { PEP_STORAGE_ILLEGAL_MESSAGE = 0x1102, PEP_PEPMESSAGE_ILLEGAL_MESSAGE = 0x1202, + // transport cannot init at all + PEP_TRANSPORT_CANNOT_INIT = 0x2000, + + // transport can init recv but not send + PEP_TRANSPORT_CANNOT_INIT_SEND = 0x2001, + + // transport can init send but not recv + PEP_TRANSPORT_CANNOT_INIT_RECV = 0x2002, + + // transport init good but temporary down + PEP_TRANSPORT_DOWN = 0x2003, + + // general error in transport + PEP_TRANSPORT_ERROR = 0x20ff, + PEP_COMMIT_FAILED = 0xff01, PEP_MESSAGE_CONSUME = 0xff02, PEP_MESSAGE_IGNORE = 0xff03, diff --git a/src/trans_auto.c b/src/trans_auto.c index ae371ca9..0f03ae59 100644 --- a/src/trans_auto.c +++ b/src/trans_auto.c @@ -6,13 +6,15 @@ #include "trans_auto.h" -PEP_STATUS auto_sendto(PEP_SESSION session, const message *msg) +PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, + PEP_transport_status_code *tsc) { return PEP_STATUS_OK; } -PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, PEP_transport_t **via) +PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, + PEP_transport_status_code *tsc) { return PEP_STATUS_OK; diff --git a/src/trans_auto.h b/src/trans_auto.h index 1cd85e3d..4a1584dc 100644 --- a/src/trans_auto.h +++ b/src/trans_auto.h @@ -9,7 +9,9 @@ #include "transport.h" -PEP_STATUS auto_sendto(PEP_SESSION session, const message *msg); +PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, + PEP_transport_status_code *tsc); + /** * * @@ -20,6 +22,8 @@ PEP_STATUS auto_sendto(PEP_SESSION session, const message *msg); * @param[out] via PEP_transport_t** * */ -PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, PEP_transport_t **via); + +PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, + PEP_transport_status_code *tsc); #endif diff --git a/src/transport.h b/src/transport.h index 062fb52e..1315a67f 100644 --- a/src/transport.h +++ b/src/transport.h @@ -29,11 +29,19 @@ typedef enum _PEP_transports { PEP_trans__count } PEP_transports; +// transports are delivering the transport status code +// this is defined here: +// https://dev.pep.foundation/Engine/TransportStatusCode + +typedef uint32_t PEP_transport_status_code; + typedef struct _PEP_transport_t PEP_transport_t; -typedef PEP_STATUS (*sendto_t)(PEP_SESSION session, const message *msg); -typedef PEP_STATUS (*readnext_t)(PEP_SESSION session, message **msg, - PEP_transport_t **via); +typedef PEP_STATUS (*sendto_t)(PEP_SESSION session, message *msg, + PEP_transport_status_code *tsc); + +typedef PEP_STATUS (*recvnext_t)(PEP_SESSION session, message **msg, + PEP_transport_status_code *tsc); /** * @struct _PEP_transport_t @@ -42,13 +50,17 @@ typedef PEP_STATUS (*readnext_t)(PEP_SESSION session, message **msg, * */ struct _PEP_transport_t { - uint8_t id; // transport ID + PEP_transports id; // transport ID + sendto_t sendto; // sendto function - readnext_t readnext; // readnext function - bool long_message_supported; // flag if this transport supports - // long messages - bool formatted_message_supported; // flag if this transport supports - // formatted messages + recvnext_t readnext; // readnext function + + bool is_online_transport; + + bool shortmsg_supported; + bool longmsg_supported; + bool longmsg_formatted_supported; + PEP_text_format native_text_format; // native format of the transport }; From 54e3758a3e2580b962b1774f124d5f544a345c83 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 12 Aug 2021 16:36:53 +0200 Subject: [PATCH 19/60] extending transport system --- src/trans_auto.c | 17 ++++++++++++++++- src/trans_auto.h | 8 +++++++- src/transport.c | 4 ++++ src/transport.h | 40 ++++++++++++++++++++++++++++++---------- 4 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/trans_auto.c b/src/trans_auto.c index 0f03ae59..b87d911f 100644 --- a/src/trans_auto.c +++ b/src/trans_auto.c @@ -6,8 +6,15 @@ #include "trans_auto.h" +PEP_STATUS auto_init(PEP_transport_t *transport, + PEP_SESSION session, PEP_transport_status_code *tsc) +{ + + return PEP_STATUS_OK; +} + PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, - PEP_transport_status_code *tsc) + stringlist_t **unreachable_addresses, PEP_transport_status_code *tsc) { return PEP_STATUS_OK; @@ -19,3 +26,11 @@ PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, return PEP_STATUS_OK; } + +PEP_STATUS auto_signal_statuschange(PEP_transport_id id, + PEP_transport_status_code tsc) +{ + + return PEP_STATUS_OK; +} + diff --git a/src/trans_auto.h b/src/trans_auto.h index 4a1584dc..b706bc63 100644 --- a/src/trans_auto.h +++ b/src/trans_auto.h @@ -10,7 +10,7 @@ #include "transport.h" PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, - PEP_transport_status_code *tsc); + stringlist_t **unreachable_addresses, PEP_transport_status_code *tsc); /** * @@ -23,7 +23,13 @@ PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, * */ +PEP_STATUS auto_init(PEP_transport_t *transport, + PEP_SESSION session, PEP_transport_status_code *tsc); + PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, PEP_transport_status_code *tsc); +PEP_STATUS auto_signal_statuschange(PEP_transport_id id, + PEP_transport_status_code tsc); + #endif diff --git a/src/transport.c b/src/transport.c index 0e0bdbab..38c0846d 100644 --- a/src/transport.c +++ b/src/transport.c @@ -22,8 +22,12 @@ PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first) memset(transports, 0, sizeof(PEP_transport_t) * PEP_trans__count); transports[PEP_trans_auto].id = PEP_trans_auto; + + transports[PEP_trans_auto].init = auto_init; transports[PEP_trans_auto].sendto = auto_sendto; transports[PEP_trans_auto].readnext = auto_readnext; + + transports[PEP_trans_auto].signal_statuschange = auto_signal_statuschange; } return PEP_STATUS_OK; diff --git a/src/transport.h b/src/transport.h index 1315a67f..19e7f879 100644 --- a/src/transport.h +++ b/src/transport.h @@ -15,19 +15,20 @@ extern "C" { #endif /** - * @enum PEP_transports + * @enum PEP_transport_id * * @brief TODO * */ -typedef enum _PEP_transports { +typedef enum _PEP_transport_id { // auto transport chooses transport per message automatically PEP_trans_auto = 0, -// PEP_trans_email, -// PEP_trans_whatsapp, +// PEP_trans_Email = 0x01, +// PEP_trans_RCE = 0x02, - PEP_trans__count -} PEP_transports; + PEP_trans__count, + PEP_trans_CC = 0xfe +} PEP_transport_id; // transports are delivering the transport status code // this is defined here: @@ -37,12 +38,22 @@ typedef uint32_t PEP_transport_status_code; typedef struct _PEP_transport_t PEP_transport_t; +// functions offered by transport + +typedef PEP_STATUS (*init_transport_t)(PEP_transport_t *transport, + PEP_SESSION session, PEP_transport_status_code *tsc); + typedef PEP_STATUS (*sendto_t)(PEP_SESSION session, message *msg, - PEP_transport_status_code *tsc); + stringlist_t **unreachable_addresses, PEP_transport_status_code *tsc); typedef PEP_STATUS (*recvnext_t)(PEP_SESSION session, message **msg, PEP_transport_status_code *tsc); +// functions offered by transport system + +typedef PEP_STATUS (*signal_statuschange_t)(PEP_transport_id id, + PEP_transport_status_code tsc); + /** * @struct _PEP_transport_t * @@ -50,10 +61,19 @@ typedef PEP_STATUS (*recvnext_t)(PEP_SESSION session, message **msg, * */ struct _PEP_transport_t { - PEP_transports id; // transport ID + PEP_transport_id id; // transport ID + const char *uri_scheme; // URI scheme this transport is + // covering + + // functions offered by transport + + init_transport_t init; + sendto_t sendto; + recvnext_t readnext; + + // functions offered by transport system - sendto_t sendto; // sendto function - recvnext_t readnext; // readnext function + signal_statuschange_t signal_statuschange; bool is_online_transport; From 1b6d5d34a14c150f5634ca9774deb7d203320d70 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 12 Aug 2021 17:24:16 +0200 Subject: [PATCH 20/60] =?UTF-8?q?renaming=20PEPMessage=20to=20ASN1Message?= =?UTF-8?q?=20to=20avoid=20the=20name=20clash=20with=20p=E2=89=A1p=20Objec?= =?UTF-8?q?tive=20C=20adapter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- asn.1/Makefile | 6 +++--- asn.1/message.asn1 | 4 ++-- src/map_asn1.c | 12 ++++++------ src/map_asn1.h | 22 +++++++++++----------- src/message_codec.c | 40 ++++++++++++++++++++-------------------- src/message_codec.h | 42 +++++++++++++++++++++--------------------- 6 files changed, 63 insertions(+), 63 deletions(-) diff --git a/asn.1/Makefile b/asn.1/Makefile index 10614c3c..792c31b8 100644 --- a/asn.1/Makefile +++ b/asn.1/Makefile @@ -19,7 +19,7 @@ STORAGE_FILES = $(addsuffix .asn1, $(STORAGE)) .PHONY: all clean install uninstall -all: Sync.c Distribution.c Storage.c PEPMessage.c +all: Sync.c Distribution.c Storage.c ASN1Message.c $(MAKE) libasn1.a libasn1.a: $(ALL_OBJECTS) @@ -43,10 +43,10 @@ Storage.c: $(STORAGE_FILES) pEp.asn1 rm -f converter-sample.c touch Storage.c -PEPMessage.c: message.asn1 pEp.asn1 +ASN1Message.c: message.asn1 pEp.asn1 $(ASN1C) -gen-PER $(ASN1C_OPTIONS) $+ rm -f converter-sample.c - touch PEPMessage.c + touch ASN1Message.c clean: rm -f *.a *.o *.c *.h *.sample \ diff --git a/asn.1/message.asn1 b/asn.1/message.asn1 index 15ae5fa4..e9750ca8 100644 --- a/asn.1/message.asn1 +++ b/asn.1/message.asn1 @@ -14,7 +14,7 @@ DEFINITIONS AUTOMATIC TAGS EXTENSIBILITY IMPLIED ::= BEGIN -EXPORTS PEPMessage; +EXPORTS ASN1Message; IMPORTS PString, PStringList, Identity, IdentityList, StringPairList, Hash @@ -52,7 +52,7 @@ BlobList ::= SEQUENCE OF Blob Timestamp ::= GeneralizedTime -PEPMessage ::= SEQUENCE { +ASN1Message ::= SEQUENCE { direction MessageDirection OPTIONAL, -- used only in "inner" messages id PString OPTIONAL, -- UTF-8 string of message ID sent Timestamp OPTIONAL, -- when the message is sent diff --git a/src/map_asn1.c b/src/map_asn1.c index 7513c0bd..d45ec750 100644 --- a/src/map_asn1.c +++ b/src/map_asn1.c @@ -618,9 +618,9 @@ enomem: return NULL; } -PEPMessage_t *PEPMessage_from_message( +ASN1Message_t *ASN1Message_from_message( message *msg, - PEPMessage_t *result, + ASN1Message_t *result, bool copy, size_t max_blob_size ) @@ -634,7 +634,7 @@ PEPMessage_t *PEPMessage_from_message( return NULL; if (allocated) { - result = (PEPMessage_t *) calloc(1, sizeof(PEPMessage_t)); + result = (ASN1Message_t *) calloc(1, sizeof(ASN1Message_t)); assert(result); if (!result) return NULL; @@ -855,12 +855,12 @@ PEPMessage_t *PEPMessage_from_message( enomem: if (allocated) - ASN_STRUCT_FREE(asn_DEF_PEPMessage, result); + ASN_STRUCT_FREE(asn_DEF_ASN1Message, result); return NULL; } -message *PEPMessage_to_message( - PEPMessage_t *msg, +message *ASN1Message_to_message( + ASN1Message_t *msg, message *result, bool copy, size_t max_blob_size diff --git a/src/map_asn1.h b/src/map_asn1.h index 86c0b3e1..8373b80a 100644 --- a/src/map_asn1.h +++ b/src/map_asn1.h @@ -8,7 +8,7 @@ #define MAP_ASN1_H #include "message.h" -#include "../asn.1/PEPMessage.h" +#include "../asn.1/ASN1Message.h" #ifdef __cplusplus extern "C" { @@ -249,12 +249,12 @@ bloblist_t *BlobList_to_bloblist( /** - * + * * - * @brief Convert message into ASN.1 PEPMessage_t + * @brief Convert message into ASN.1 ASN1Message_t * * @param msg[in] message to convert - * @param result[inout] PEPMessage_t to update or NULL to alloc a new one + * @param result[inout] ASN1Message_t to update or NULL to alloc a new one * @param copy copy data if true, move data otherwise * @param max_blob_size reject if sum(blob.size) > max_blob_size * to disable set to 0 @@ -265,20 +265,20 @@ bloblist_t *BlobList_to_bloblist( * */ -PEPMessage_t *PEPMessage_from_message( +ASN1Message_t *ASN1Message_from_message( message *msg, - PEPMessage_t *result, + ASN1Message_t *result, bool copy, size_t max_blob_size ); /** - * + * * - * @brief Convert ASN.1 PEPMessage_t to message + * @brief Convert ASN.1 ASN1Message_t to message * - * @param msg[in] ASN.1 PEPMessage_t to convert + * @param msg[in] ASN.1 ASN1Message_t to convert * @param result[inout] message to update or NULL to alloc a new one * @param copy copy data if true, move data otherwise * @param max_blob_size reject if sum(blob.size) > max_blob_size @@ -290,8 +290,8 @@ PEPMessage_t *PEPMessage_from_message( * */ -message *PEPMessage_to_message( - PEPMessage_t *msg, +message *ASN1Message_to_message( + ASN1Message_t *msg, message *result, bool copy, size_t max_blob_size diff --git a/src/message_codec.c b/src/message_codec.c index d2da1688..ba8d6df5 100644 --- a/src/message_codec.c +++ b/src/message_codec.c @@ -1,6 +1,6 @@ /** - * @file PEPMessage_codec.c - * @brief Implementation for PEPMessage encode and decode functions which transform message payloads to + * @file ASN1Message_codec.c + * @brief Implementation for ASN1Message encode and decode functions which transform message payloads to * and from PER-encoded data, and XER text to and from PER * * @see https://www.itu.int/en/ITU-T/asn1/Pages/introduction.aspx @@ -11,14 +11,14 @@ #include "platform.h" #include "distribution_codec.h" -#include "../asn.1/PEPMessage.h" +#include "../asn.1/ASN1Message.h" #include "pEp_internal.h" #include "growing_buf.h" -DYNAMIC_API PEP_STATUS decode_PEPMessage_message( +DYNAMIC_API PEP_STATUS decode_ASN1Message_message( const char *data, size_t size, - PEPMessage_t **msg + ASN1Message_t **msg ) { assert(data && msg); @@ -26,8 +26,8 @@ DYNAMIC_API PEP_STATUS decode_PEPMessage_message( return PEP_ILLEGAL_VALUE; *msg = NULL; - PEPMessage_t *_msg = NULL; - uper_decode_complete(NULL, &asn_DEF_PEPMessage, (void **) &_msg, data, size); + ASN1Message_t *_msg = NULL; + uper_decode_complete(NULL, &asn_DEF_ASN1Message, (void **) &_msg, data, size); if (!_msg) return PEP_PEPMESSAGE_ILLEGAL_MESSAGE; @@ -35,8 +35,8 @@ DYNAMIC_API PEP_STATUS decode_PEPMessage_message( return PEP_STATUS_OK; } -PEP_STATUS encode_PEPMessage_message( - PEPMessage_t *msg, +PEP_STATUS encode_ASN1Message_message( + ASN1Message_t *msg, char **data, size_t *size ) @@ -49,7 +49,7 @@ PEP_STATUS encode_PEPMessage_message( *size = 0; char *_data = NULL; - ssize_t _size = uper_encode_to_new_buffer(&asn_DEF_PEPMessage, NULL, msg, + ssize_t _size = uper_encode_to_new_buffer(&asn_DEF_ASN1Message, NULL, msg, (void **) &_data); if (_size == -1) return PEP_CANNOT_ENCODE; @@ -60,7 +60,7 @@ PEP_STATUS encode_PEPMessage_message( return PEP_STATUS_OK; } -PEP_STATUS PER_to_XER_PEPMessage_msg( +PEP_STATUS PER_to_XER_ASN1Message_msg( const char *data, size_t size, char **text @@ -75,8 +75,8 @@ PEP_STATUS PER_to_XER_PEPMessage_msg( *text = NULL; - PEPMessage_t *msg = NULL; - status = decode_PEPMessage_message(data, size, &msg); + ASN1Message_t *msg = NULL; + status = decode_ASN1Message_message(data, size, &msg); if (status) goto the_end; @@ -86,7 +86,7 @@ PEP_STATUS PER_to_XER_PEPMessage_msg( goto the_end; } - asn_enc_rval_t er = xer_encode(&asn_DEF_PEPMessage, msg, XER_F_BASIC, + asn_enc_rval_t er = xer_encode(&asn_DEF_ASN1Message, msg, XER_F_BASIC, (asn_app_consume_bytes_f *) growing_buf_consume, (void *) dst); if (er.encoded == -1) { status = PEP_CANNOT_ENCODE; @@ -98,11 +98,11 @@ PEP_STATUS PER_to_XER_PEPMessage_msg( the_end: free_growing_buf(dst); - ASN_STRUCT_FREE(asn_DEF_PEPMessage, msg); + ASN_STRUCT_FREE(asn_DEF_ASN1Message, msg); return status; } -PEP_STATUS XER_to_PER_PEPMessage_msg( +PEP_STATUS XER_to_PER_ASN1Message_msg( const char *text, char **data, size_t *size @@ -117,8 +117,8 @@ PEP_STATUS XER_to_PER_PEPMessage_msg( *data = NULL; *size = 0; - PEPMessage_t *msg = NULL; - asn_dec_rval_t dr = xer_decode(NULL, &asn_DEF_PEPMessage, (void **) &msg, + ASN1Message_t *msg = NULL; + asn_dec_rval_t dr = xer_decode(NULL, &asn_DEF_ASN1Message, (void **) &msg, (const void *) text, strlen(text)); if (dr.code != RC_OK) { status = PEP_PEPMESSAGE_ILLEGAL_MESSAGE; @@ -127,7 +127,7 @@ PEP_STATUS XER_to_PER_PEPMessage_msg( char *_data = NULL; size_t _size = 0; - status = encode_PEPMessage_message(msg, &_data, &_size); + status = encode_ASN1Message_message(msg, &_data, &_size); if (status) goto the_end; @@ -135,7 +135,7 @@ PEP_STATUS XER_to_PER_PEPMessage_msg( *size = (size_t) _size; the_end: - ASN_STRUCT_FREE(asn_DEF_PEPMessage, msg); + ASN_STRUCT_FREE(asn_DEF_ASN1Message, msg); return status; } diff --git a/src/message_codec.h b/src/message_codec.h index 6a451104..059e9088 100644 --- a/src/message_codec.h +++ b/src/message_codec.h @@ -1,6 +1,6 @@ /** - * @file PEPMessage_codec.h - * @brief Definitions for PEPMessage encode and decode functions which transform message payloads to + * @file ASN1Message_codec.h + * @brief Definitions for ASN1Message encode and decode functions which transform message payloads to * and from PER-encoded data, and XER text to and from PER * * @see https://www.itu.int/en/ITU-T/asn1/Pages/introduction.aspx @@ -20,33 +20,33 @@ extern "C" { #endif -struct PEPMessage; +struct ASN1Message; /** - * + * * - * @brief decode PER encoded PEPMessage message + * @brief decode PER encoded ASN1Message message * * @param[in] data PER encoded data * @param[in] size size of PER encoded data - * @param[out] msg decoded PEPMessage message + * @param[out] msg decoded ASN1Message message * * @retval status * * @ownership msg goes into the ownership of the caller */ -DYNAMIC_API PEP_STATUS decode_PEPMessage_message( +DYNAMIC_API PEP_STATUS decode_ASN1Message_message( const char *data, size_t size, - struct PEPMessage **msg + struct ASN1Message **msg ); /** - * + * * - * @brief decode PER encoded PEPMessage message + * @brief decode PER encoded ASN1Message message * - * @param[in] msg PEPMessage message to encode + * @param[in] msg ASN1Message message to encode * @param[out] data PER encoded data * @param[out] size size of PER encoded data * @@ -54,42 +54,42 @@ DYNAMIC_API PEP_STATUS decode_PEPMessage_message( * * @ownership msg goes into the ownership of the caller */ -DYNAMIC_API PEP_STATUS encode_PEPMessage_message( - struct PEPMessage *msg, +DYNAMIC_API PEP_STATUS encode_ASN1Message_message( + struct ASN1Message *msg, char **data, size_t *size ); /** - * + * * - * @brief decode PEPMessage message from PER into XER + * @brief decode ASN1Message message from PER into XER * * @param[in] data PER encoded data * @param[in] size size of PER encoded data - * @param[out] text XER text of the same PEPMessage message + * @param[out] text XER text of the same ASN1Message message * * @retval status */ -DYNAMIC_API PEP_STATUS PER_to_XER_PEPMessage_msg( +DYNAMIC_API PEP_STATUS PER_to_XER_ASN1Message_msg( const char *data, size_t size, char **text ); /** - * + * * - * @brief encode PEPMessage message from XER into PER + * @brief encode ASN1Message message from XER into PER * - * @param[in] text string text with XER text of the PEPMessage message + * @param[in] text string text with XER text of the ASN1Message message * @param[out] data PER encoded data * @param[out] size size of PER encoded data * * @retval status */ -DYNAMIC_API PEP_STATUS XER_to_PER_PEPMessage_msg( +DYNAMIC_API PEP_STATUS XER_to_PER_ASN1Message_msg( const char *text, char **data, size_t *size From 46cdf6066c50bbe134aba181d8a32131ad6cc1ab Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 12 Aug 2021 17:24:54 +0200 Subject: [PATCH 21/60] Bumped header patch number for NEXT release --- src/pEpEngine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pEpEngine.h b/src/pEpEngine.h index 689eeaa1..f181513e 100644 --- a/src/pEpEngine.h +++ b/src/pEpEngine.h @@ -29,7 +29,7 @@ extern "C" { #define PEP_ENGINE_VERSION_MAJOR 3 #define PEP_ENGINE_VERSION_MINOR 2 #define PEP_ENGINE_VERSION_PATCH 0 -#define PEP_ENGINE_VERSION_RC 2 +#define PEP_ENGINE_VERSION_RC 3 #define PEP_OWN_USERID "pEp_own_userId" From e7aaeb5569877bfec72b310b1916320bebf2fba3 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 12 Aug 2021 17:32:13 +0200 Subject: [PATCH 22/60] adapting test to rename of PEPMessage to ASN1Message --- test/src/MapAsn1Test.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/src/MapAsn1Test.cc b/test/src/MapAsn1Test.cc index e5faec65..314a03bf 100644 --- a/test/src/MapAsn1Test.cc +++ b/test/src/MapAsn1Test.cc @@ -122,7 +122,7 @@ TEST_F(MapAsn1Test, check_map_asn1) { } TEST_F(MapAsn1Test, check_map_asn1_message) { - output_stream << "testing PEPMessage...\n"; + output_stream << "testing ASN1Message...\n"; message *msg = new_message(PEP_dir_outgoing); msg->id = strdup("423"); @@ -156,18 +156,18 @@ TEST_F(MapAsn1Test, check_map_asn1_message) { stringpair_list_add(msg->opt_fields, new_stringpair("otherkey", "othervalue")); msg->_sender_fpr = strdup("2342234223422342"); - PEPMessage_t *pm = PEPMessage_from_message(msg, NULL, false, 1024); + ASN1Message_t *pm = ASN1Message_from_message(msg, NULL, false, 1024); char *data = NULL; size_t data_size = 0; - PEP_STATUS status = encode_PEPMessage_message(pm, &data, &data_size); + PEP_STATUS status = encode_ASN1Message_message(pm, &data, &data_size); ASSERT_EQ(status, PEP_STATUS_OK); - PEPMessage_t *pm2 = NULL; - status = decode_PEPMessage_message(data, data_size, &pm2); + ASN1Message_t *pm2 = NULL; + status = decode_ASN1Message_message(data, data_size, &pm2); ASSERT_EQ(status, PEP_STATUS_OK); - message *msg2 = PEPMessage_to_message(pm2, NULL, false, 1024); + message *msg2 = ASN1Message_to_message(pm2, NULL, false, 1024); ASSERT_STREQ(msg2->id, "423"); ASSERT_STREQ(msg2->shortmsg, "hello, world"); @@ -194,8 +194,8 @@ TEST_F(MapAsn1Test, check_map_asn1_message) { ASSERT_STREQ(msg2->opt_fields->next->value->value, "othervalue"); ASSERT_STREQ(msg2->_sender_fpr, "2342234223422342"); - ASN_STRUCT_FREE(asn_DEF_PEPMessage, pm); - ASN_STRUCT_FREE(asn_DEF_PEPMessage, pm2); + ASN_STRUCT_FREE(asn_DEF_ASN1Message, pm); + ASN_STRUCT_FREE(asn_DEF_ASN1Message, pm2); free_message(msg); free_message(msg2); free(data); From f8845107284f42d25f38f888747c4c70454cafd5 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 12 Aug 2021 18:09:57 +0200 Subject: [PATCH 23/60] Bumped header patch number for NEXT release --- src/pEpEngine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pEpEngine.h b/src/pEpEngine.h index f181513e..2c5435aa 100644 --- a/src/pEpEngine.h +++ b/src/pEpEngine.h @@ -29,7 +29,7 @@ extern "C" { #define PEP_ENGINE_VERSION_MAJOR 3 #define PEP_ENGINE_VERSION_MINOR 2 #define PEP_ENGINE_VERSION_PATCH 0 -#define PEP_ENGINE_VERSION_RC 3 +#define PEP_ENGINE_VERSION_RC 4 #define PEP_OWN_USERID "pEp_own_userId" From f5d60177926fba9c4c20129f146e6abeb71319e9 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 12 Aug 2021 19:48:16 +0200 Subject: [PATCH 24/60] notification concept --- src/trans_auto.c | 19 +++++++++++++------ src/trans_auto.h | 26 +++++++++----------------- src/transport.c | 9 ++++++--- src/transport.h | 32 +++++++++++++++++++++++--------- 4 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/trans_auto.c b/src/trans_auto.c index b87d911f..723deb08 100644 --- a/src/trans_auto.c +++ b/src/trans_auto.c @@ -6,29 +6,36 @@ #include "trans_auto.h" -PEP_STATUS auto_init(PEP_transport_t *transport, - PEP_SESSION session, PEP_transport_status_code *tsc) +PEP_STATUS auto_startup(PEP_transport_t *transport, + PEP_transport_status_code *tsc) +{ + + return PEP_STATUS_OK; +} + +PEP_STATUS auto_shutdown(PEP_transport_t *transport, + PEP_transport_status_code *tsc) { return PEP_STATUS_OK; } PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, - stringlist_t **unreachable_addresses, PEP_transport_status_code *tsc) + PEP_transport_status_code *tsc) { return PEP_STATUS_OK; } -PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, +PEP_STATUS auto_recvnext(PEP_SESSION session, message **msg, PEP_transport_status_code *tsc) { return PEP_STATUS_OK; } -PEP_STATUS auto_signal_statuschange(PEP_transport_id id, - PEP_transport_status_code tsc) +PEP_STATUS auto_notify(signal_statuschange_t status_change, + signal_sendto_result_t sendto_result) { return PEP_STATUS_OK; diff --git a/src/trans_auto.h b/src/trans_auto.h index b706bc63..f4251584 100644 --- a/src/trans_auto.h +++ b/src/trans_auto.h @@ -9,27 +9,19 @@ #include "transport.h" -PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, - stringlist_t **unreachable_addresses, PEP_transport_status_code *tsc); +PEP_STATUS auto_startup(PEP_transport_t *transport, + PEP_transport_status_code *tsc); -/** - * - * - * @brief TODO - * - * @param[in] session PEP_SESSION - * @param[out] msg message** - * @param[out] via PEP_transport_t** - * - */ +PEP_STATUS auto_shutdown(PEP_transport_t *transport, + PEP_transport_status_code *tsc); -PEP_STATUS auto_init(PEP_transport_t *transport, - PEP_SESSION session, PEP_transport_status_code *tsc); +PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, + PEP_transport_status_code *tsc); -PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, +PEP_STATUS auto_recvnext(PEP_SESSION session, message **msg, PEP_transport_status_code *tsc); -PEP_STATUS auto_signal_statuschange(PEP_transport_id id, - PEP_transport_status_code tsc); +PEP_STATUS auto_notify(signal_statuschange_t status_change, + signal_sendto_result_t sendto_result); #endif diff --git a/src/transport.c b/src/transport.c index 38c0846d..9ec2e23f 100644 --- a/src/transport.c +++ b/src/transport.c @@ -22,12 +22,15 @@ PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first) memset(transports, 0, sizeof(PEP_transport_t) * PEP_trans__count); transports[PEP_trans_auto].id = PEP_trans_auto; + transports[PEP_trans_auto].uri_scheme = ""; + + transports[PEP_trans_auto].startup = auto_startup; + transports[PEP_trans_auto].shutdown = auto_shutdown; - transports[PEP_trans_auto].init = auto_init; transports[PEP_trans_auto].sendto = auto_sendto; - transports[PEP_trans_auto].readnext = auto_readnext; + transports[PEP_trans_auto].recvnext = auto_recvnext; - transports[PEP_trans_auto].signal_statuschange = auto_signal_statuschange; + transports[PEP_trans_auto].notify = auto_notify; } return PEP_STATUS_OK; diff --git a/src/transport.h b/src/transport.h index 19e7f879..74d88082 100644 --- a/src/transport.h +++ b/src/transport.h @@ -40,20 +40,32 @@ typedef struct _PEP_transport_t PEP_transport_t; // functions offered by transport -typedef PEP_STATUS (*init_transport_t)(PEP_transport_t *transport, - PEP_SESSION session, PEP_transport_status_code *tsc); +typedef PEP_STATUS (*startup_transport_t)(PEP_transport_t *transport, + PEP_transport_status_code *tsc); + +typedef PEP_STATUS (*shutdown_transport_t)(PEP_transport_t *transport, + PEP_transport_status_code *tsc); typedef PEP_STATUS (*sendto_t)(PEP_SESSION session, message *msg, - stringlist_t **unreachable_addresses, PEP_transport_status_code *tsc); + PEP_transport_status_code *tsc); typedef PEP_STATUS (*recvnext_t)(PEP_SESSION session, message **msg, PEP_transport_status_code *tsc); -// functions offered by transport system +// callbacks typedef PEP_STATUS (*signal_statuschange_t)(PEP_transport_id id, PEP_transport_status_code tsc); +typedef PEP_STATUS (*signal_sendto_result_t)(PEP_transport_id id, char *message_id, + char *address, PEP_transport_status_code tsc); + +// call this to receive signals +// this function does not terminate until shutdown of the transport + +typedef PEP_STATUS (*notify_transport_t)(signal_statuschange_t status_change, + signal_sendto_result_t sendto_result); + /** * @struct _PEP_transport_t * @@ -61,19 +73,21 @@ typedef PEP_STATUS (*signal_statuschange_t)(PEP_transport_id id, * */ struct _PEP_transport_t { - PEP_transport_id id; // transport ID + PEP_transport_id id; // transport ID const char *uri_scheme; // URI scheme this transport is // covering // functions offered by transport - init_transport_t init; + startup_transport_t startup; + shutdown_transport_t shutdown; + sendto_t sendto; - recvnext_t readnext; + recvnext_t recvnext; - // functions offered by transport system + notify_transport_t notify; - signal_statuschange_t signal_statuschange; + // functions offered by transport system bool is_online_transport; From 7fc9ab7d2825fd7376656f7d487d3503705c847a Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 12 Aug 2021 21:15:32 +0200 Subject: [PATCH 25/60] ... --- src/transport.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/transport.h b/src/transport.h index 74d88082..583beab5 100644 --- a/src/transport.h +++ b/src/transport.h @@ -87,8 +87,6 @@ struct _PEP_transport_t { notify_transport_t notify; - // functions offered by transport system - bool is_online_transport; bool shortmsg_supported; From cac54182278726d57c8350be1875a2ea94585e2c Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Fri, 13 Aug 2021 02:16:40 +0200 Subject: [PATCH 26/60] adding configure_transport --- src/trans_auto.c | 7 +++++++ src/trans_auto.h | 3 +++ src/transport.c | 1 + src/transport.h | 12 ++++++++++++ 4 files changed, 23 insertions(+) diff --git a/src/trans_auto.c b/src/trans_auto.c index 723deb08..9e45df8e 100644 --- a/src/trans_auto.c +++ b/src/trans_auto.c @@ -6,6 +6,13 @@ #include "trans_auto.h" +PEP_STATUS auto_configure(PEP_transport_t *transport, + transport_config_t *config, PEP_transport_status_code *tsc) +{ + + return PEP_STATUS_OK; +} + PEP_STATUS auto_startup(PEP_transport_t *transport, PEP_transport_status_code *tsc) { diff --git a/src/trans_auto.h b/src/trans_auto.h index f4251584..5141fbe4 100644 --- a/src/trans_auto.h +++ b/src/trans_auto.h @@ -9,6 +9,9 @@ #include "transport.h" +PEP_STATUS auto_configure(PEP_transport_t *transport, + transport_config_t *config, PEP_transport_status_code *tsc); + PEP_STATUS auto_startup(PEP_transport_t *transport, PEP_transport_status_code *tsc); diff --git a/src/transport.c b/src/transport.c index 9ec2e23f..1d9a8d9b 100644 --- a/src/transport.c +++ b/src/transport.c @@ -24,6 +24,7 @@ PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first) transports[PEP_trans_auto].id = PEP_trans_auto; transports[PEP_trans_auto].uri_scheme = ""; + transports[PEP_trans_auto].configure = auto_configure; transports[PEP_trans_auto].startup = auto_startup; transports[PEP_trans_auto].shutdown = auto_shutdown; diff --git a/src/transport.h b/src/transport.h index 583beab5..fafe850f 100644 --- a/src/transport.h +++ b/src/transport.h @@ -30,6 +30,14 @@ typedef enum _PEP_transport_id { PEP_trans_CC = 0xfe } PEP_transport_id; +typedef struct _transport_config { + // set size field when initializing + size_t size; + + // expand here + // in C++ this must be POD +} transport_config_t; + // transports are delivering the transport status code // this is defined here: // https://dev.pep.foundation/Engine/TransportStatusCode @@ -40,6 +48,9 @@ typedef struct _PEP_transport_t PEP_transport_t; // functions offered by transport +typedef PEP_STATUS (*configure_transport_t)(PEP_transport_t *transport, + transport_config_t *config, PEP_transport_status_code *tsc); + typedef PEP_STATUS (*startup_transport_t)(PEP_transport_t *transport, PEP_transport_status_code *tsc); @@ -79,6 +90,7 @@ struct _PEP_transport_t { // functions offered by transport + configure_transport_t configure; startup_transport_t startup; shutdown_transport_t shutdown; From e684b9ab6ff9147ce736a83029e21e6d7bd3a12a Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 12 Aug 2021 12:08:36 +0200 Subject: [PATCH 27/60] slightly redesigned --- src/pEpEngine.h | 15 +++++++++++++++ src/trans_auto.c | 6 ++++-- src/trans_auto.h | 8 ++++++-- src/transport.h | 30 +++++++++++++++++++++--------- 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/pEpEngine.h b/src/pEpEngine.h index 2c5435aa..a8310bda 100644 --- a/src/pEpEngine.h +++ b/src/pEpEngine.h @@ -162,6 +162,21 @@ typedef enum { PEP_STORAGE_ILLEGAL_MESSAGE = 0x1102, PEP_PEPMESSAGE_ILLEGAL_MESSAGE = 0x1202, + // transport cannot init at all + PEP_TRANSPORT_CANNOT_INIT = 0x2000, + + // transport can init recv but not send + PEP_TRANSPORT_CANNOT_INIT_SEND = 0x2001, + + // transport can init send but not recv + PEP_TRANSPORT_CANNOT_INIT_RECV = 0x2002, + + // transport init good but temporary down + PEP_TRANSPORT_DOWN = 0x2003, + + // general error in transport + PEP_TRANSPORT_ERROR = 0x20ff, + PEP_COMMIT_FAILED = 0xff01, PEP_MESSAGE_CONSUME = 0xff02, PEP_MESSAGE_IGNORE = 0xff03, diff --git a/src/trans_auto.c b/src/trans_auto.c index ae371ca9..0f03ae59 100644 --- a/src/trans_auto.c +++ b/src/trans_auto.c @@ -6,13 +6,15 @@ #include "trans_auto.h" -PEP_STATUS auto_sendto(PEP_SESSION session, const message *msg) +PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, + PEP_transport_status_code *tsc) { return PEP_STATUS_OK; } -PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, PEP_transport_t **via) +PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, + PEP_transport_status_code *tsc) { return PEP_STATUS_OK; diff --git a/src/trans_auto.h b/src/trans_auto.h index 1cd85e3d..4a1584dc 100644 --- a/src/trans_auto.h +++ b/src/trans_auto.h @@ -9,7 +9,9 @@ #include "transport.h" -PEP_STATUS auto_sendto(PEP_SESSION session, const message *msg); +PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, + PEP_transport_status_code *tsc); + /** * * @@ -20,6 +22,8 @@ PEP_STATUS auto_sendto(PEP_SESSION session, const message *msg); * @param[out] via PEP_transport_t** * */ -PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, PEP_transport_t **via); + +PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, + PEP_transport_status_code *tsc); #endif diff --git a/src/transport.h b/src/transport.h index 062fb52e..1315a67f 100644 --- a/src/transport.h +++ b/src/transport.h @@ -29,11 +29,19 @@ typedef enum _PEP_transports { PEP_trans__count } PEP_transports; +// transports are delivering the transport status code +// this is defined here: +// https://dev.pep.foundation/Engine/TransportStatusCode + +typedef uint32_t PEP_transport_status_code; + typedef struct _PEP_transport_t PEP_transport_t; -typedef PEP_STATUS (*sendto_t)(PEP_SESSION session, const message *msg); -typedef PEP_STATUS (*readnext_t)(PEP_SESSION session, message **msg, - PEP_transport_t **via); +typedef PEP_STATUS (*sendto_t)(PEP_SESSION session, message *msg, + PEP_transport_status_code *tsc); + +typedef PEP_STATUS (*recvnext_t)(PEP_SESSION session, message **msg, + PEP_transport_status_code *tsc); /** * @struct _PEP_transport_t @@ -42,13 +50,17 @@ typedef PEP_STATUS (*readnext_t)(PEP_SESSION session, message **msg, * */ struct _PEP_transport_t { - uint8_t id; // transport ID + PEP_transports id; // transport ID + sendto_t sendto; // sendto function - readnext_t readnext; // readnext function - bool long_message_supported; // flag if this transport supports - // long messages - bool formatted_message_supported; // flag if this transport supports - // formatted messages + recvnext_t readnext; // readnext function + + bool is_online_transport; + + bool shortmsg_supported; + bool longmsg_supported; + bool longmsg_formatted_supported; + PEP_text_format native_text_format; // native format of the transport }; From bebfbac5162ba15855132dd88cf811137788c8a5 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 12 Aug 2021 16:36:53 +0200 Subject: [PATCH 28/60] extending transport system --- src/trans_auto.c | 17 ++++++++++++++++- src/trans_auto.h | 8 +++++++- src/transport.c | 4 ++++ src/transport.h | 40 ++++++++++++++++++++++++++++++---------- 4 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/trans_auto.c b/src/trans_auto.c index 0f03ae59..b87d911f 100644 --- a/src/trans_auto.c +++ b/src/trans_auto.c @@ -6,8 +6,15 @@ #include "trans_auto.h" +PEP_STATUS auto_init(PEP_transport_t *transport, + PEP_SESSION session, PEP_transport_status_code *tsc) +{ + + return PEP_STATUS_OK; +} + PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, - PEP_transport_status_code *tsc) + stringlist_t **unreachable_addresses, PEP_transport_status_code *tsc) { return PEP_STATUS_OK; @@ -19,3 +26,11 @@ PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, return PEP_STATUS_OK; } + +PEP_STATUS auto_signal_statuschange(PEP_transport_id id, + PEP_transport_status_code tsc) +{ + + return PEP_STATUS_OK; +} + diff --git a/src/trans_auto.h b/src/trans_auto.h index 4a1584dc..b706bc63 100644 --- a/src/trans_auto.h +++ b/src/trans_auto.h @@ -10,7 +10,7 @@ #include "transport.h" PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, - PEP_transport_status_code *tsc); + stringlist_t **unreachable_addresses, PEP_transport_status_code *tsc); /** * @@ -23,7 +23,13 @@ PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, * */ +PEP_STATUS auto_init(PEP_transport_t *transport, + PEP_SESSION session, PEP_transport_status_code *tsc); + PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, PEP_transport_status_code *tsc); +PEP_STATUS auto_signal_statuschange(PEP_transport_id id, + PEP_transport_status_code tsc); + #endif diff --git a/src/transport.c b/src/transport.c index 0e0bdbab..38c0846d 100644 --- a/src/transport.c +++ b/src/transport.c @@ -22,8 +22,12 @@ PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first) memset(transports, 0, sizeof(PEP_transport_t) * PEP_trans__count); transports[PEP_trans_auto].id = PEP_trans_auto; + + transports[PEP_trans_auto].init = auto_init; transports[PEP_trans_auto].sendto = auto_sendto; transports[PEP_trans_auto].readnext = auto_readnext; + + transports[PEP_trans_auto].signal_statuschange = auto_signal_statuschange; } return PEP_STATUS_OK; diff --git a/src/transport.h b/src/transport.h index 1315a67f..19e7f879 100644 --- a/src/transport.h +++ b/src/transport.h @@ -15,19 +15,20 @@ extern "C" { #endif /** - * @enum PEP_transports + * @enum PEP_transport_id * * @brief TODO * */ -typedef enum _PEP_transports { +typedef enum _PEP_transport_id { // auto transport chooses transport per message automatically PEP_trans_auto = 0, -// PEP_trans_email, -// PEP_trans_whatsapp, +// PEP_trans_Email = 0x01, +// PEP_trans_RCE = 0x02, - PEP_trans__count -} PEP_transports; + PEP_trans__count, + PEP_trans_CC = 0xfe +} PEP_transport_id; // transports are delivering the transport status code // this is defined here: @@ -37,12 +38,22 @@ typedef uint32_t PEP_transport_status_code; typedef struct _PEP_transport_t PEP_transport_t; +// functions offered by transport + +typedef PEP_STATUS (*init_transport_t)(PEP_transport_t *transport, + PEP_SESSION session, PEP_transport_status_code *tsc); + typedef PEP_STATUS (*sendto_t)(PEP_SESSION session, message *msg, - PEP_transport_status_code *tsc); + stringlist_t **unreachable_addresses, PEP_transport_status_code *tsc); typedef PEP_STATUS (*recvnext_t)(PEP_SESSION session, message **msg, PEP_transport_status_code *tsc); +// functions offered by transport system + +typedef PEP_STATUS (*signal_statuschange_t)(PEP_transport_id id, + PEP_transport_status_code tsc); + /** * @struct _PEP_transport_t * @@ -50,10 +61,19 @@ typedef PEP_STATUS (*recvnext_t)(PEP_SESSION session, message **msg, * */ struct _PEP_transport_t { - PEP_transports id; // transport ID + PEP_transport_id id; // transport ID + const char *uri_scheme; // URI scheme this transport is + // covering + + // functions offered by transport + + init_transport_t init; + sendto_t sendto; + recvnext_t readnext; + + // functions offered by transport system - sendto_t sendto; // sendto function - recvnext_t readnext; // readnext function + signal_statuschange_t signal_statuschange; bool is_online_transport; From 66da4bd67a8a165807ac46ce847ce7e37f4d424a Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 12 Aug 2021 19:48:16 +0200 Subject: [PATCH 29/60] notification concept --- src/trans_auto.c | 19 +++++++++++++------ src/trans_auto.h | 26 +++++++++----------------- src/transport.c | 9 ++++++--- src/transport.h | 32 +++++++++++++++++++++++--------- 4 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/trans_auto.c b/src/trans_auto.c index b87d911f..723deb08 100644 --- a/src/trans_auto.c +++ b/src/trans_auto.c @@ -6,29 +6,36 @@ #include "trans_auto.h" -PEP_STATUS auto_init(PEP_transport_t *transport, - PEP_SESSION session, PEP_transport_status_code *tsc) +PEP_STATUS auto_startup(PEP_transport_t *transport, + PEP_transport_status_code *tsc) +{ + + return PEP_STATUS_OK; +} + +PEP_STATUS auto_shutdown(PEP_transport_t *transport, + PEP_transport_status_code *tsc) { return PEP_STATUS_OK; } PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, - stringlist_t **unreachable_addresses, PEP_transport_status_code *tsc) + PEP_transport_status_code *tsc) { return PEP_STATUS_OK; } -PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, +PEP_STATUS auto_recvnext(PEP_SESSION session, message **msg, PEP_transport_status_code *tsc) { return PEP_STATUS_OK; } -PEP_STATUS auto_signal_statuschange(PEP_transport_id id, - PEP_transport_status_code tsc) +PEP_STATUS auto_notify(signal_statuschange_t status_change, + signal_sendto_result_t sendto_result) { return PEP_STATUS_OK; diff --git a/src/trans_auto.h b/src/trans_auto.h index b706bc63..f4251584 100644 --- a/src/trans_auto.h +++ b/src/trans_auto.h @@ -9,27 +9,19 @@ #include "transport.h" -PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, - stringlist_t **unreachable_addresses, PEP_transport_status_code *tsc); +PEP_STATUS auto_startup(PEP_transport_t *transport, + PEP_transport_status_code *tsc); -/** - * - * - * @brief TODO - * - * @param[in] session PEP_SESSION - * @param[out] msg message** - * @param[out] via PEP_transport_t** - * - */ +PEP_STATUS auto_shutdown(PEP_transport_t *transport, + PEP_transport_status_code *tsc); -PEP_STATUS auto_init(PEP_transport_t *transport, - PEP_SESSION session, PEP_transport_status_code *tsc); +PEP_STATUS auto_sendto(PEP_SESSION session, message *msg, + PEP_transport_status_code *tsc); -PEP_STATUS auto_readnext(PEP_SESSION session, message **msg, +PEP_STATUS auto_recvnext(PEP_SESSION session, message **msg, PEP_transport_status_code *tsc); -PEP_STATUS auto_signal_statuschange(PEP_transport_id id, - PEP_transport_status_code tsc); +PEP_STATUS auto_notify(signal_statuschange_t status_change, + signal_sendto_result_t sendto_result); #endif diff --git a/src/transport.c b/src/transport.c index 38c0846d..9ec2e23f 100644 --- a/src/transport.c +++ b/src/transport.c @@ -22,12 +22,15 @@ PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first) memset(transports, 0, sizeof(PEP_transport_t) * PEP_trans__count); transports[PEP_trans_auto].id = PEP_trans_auto; + transports[PEP_trans_auto].uri_scheme = ""; + + transports[PEP_trans_auto].startup = auto_startup; + transports[PEP_trans_auto].shutdown = auto_shutdown; - transports[PEP_trans_auto].init = auto_init; transports[PEP_trans_auto].sendto = auto_sendto; - transports[PEP_trans_auto].readnext = auto_readnext; + transports[PEP_trans_auto].recvnext = auto_recvnext; - transports[PEP_trans_auto].signal_statuschange = auto_signal_statuschange; + transports[PEP_trans_auto].notify = auto_notify; } return PEP_STATUS_OK; diff --git a/src/transport.h b/src/transport.h index 19e7f879..74d88082 100644 --- a/src/transport.h +++ b/src/transport.h @@ -40,20 +40,32 @@ typedef struct _PEP_transport_t PEP_transport_t; // functions offered by transport -typedef PEP_STATUS (*init_transport_t)(PEP_transport_t *transport, - PEP_SESSION session, PEP_transport_status_code *tsc); +typedef PEP_STATUS (*startup_transport_t)(PEP_transport_t *transport, + PEP_transport_status_code *tsc); + +typedef PEP_STATUS (*shutdown_transport_t)(PEP_transport_t *transport, + PEP_transport_status_code *tsc); typedef PEP_STATUS (*sendto_t)(PEP_SESSION session, message *msg, - stringlist_t **unreachable_addresses, PEP_transport_status_code *tsc); + PEP_transport_status_code *tsc); typedef PEP_STATUS (*recvnext_t)(PEP_SESSION session, message **msg, PEP_transport_status_code *tsc); -// functions offered by transport system +// callbacks typedef PEP_STATUS (*signal_statuschange_t)(PEP_transport_id id, PEP_transport_status_code tsc); +typedef PEP_STATUS (*signal_sendto_result_t)(PEP_transport_id id, char *message_id, + char *address, PEP_transport_status_code tsc); + +// call this to receive signals +// this function does not terminate until shutdown of the transport + +typedef PEP_STATUS (*notify_transport_t)(signal_statuschange_t status_change, + signal_sendto_result_t sendto_result); + /** * @struct _PEP_transport_t * @@ -61,19 +73,21 @@ typedef PEP_STATUS (*signal_statuschange_t)(PEP_transport_id id, * */ struct _PEP_transport_t { - PEP_transport_id id; // transport ID + PEP_transport_id id; // transport ID const char *uri_scheme; // URI scheme this transport is // covering // functions offered by transport - init_transport_t init; + startup_transport_t startup; + shutdown_transport_t shutdown; + sendto_t sendto; - recvnext_t readnext; + recvnext_t recvnext; - // functions offered by transport system + notify_transport_t notify; - signal_statuschange_t signal_statuschange; + // functions offered by transport system bool is_online_transport; From 32956eb8b2bd278db2593f7c5dae3c4a9a852774 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 12 Aug 2021 21:15:32 +0200 Subject: [PATCH 30/60] ... --- src/transport.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/transport.h b/src/transport.h index 74d88082..583beab5 100644 --- a/src/transport.h +++ b/src/transport.h @@ -87,8 +87,6 @@ struct _PEP_transport_t { notify_transport_t notify; - // functions offered by transport system - bool is_online_transport; bool shortmsg_supported; From 5e7c4fef87395b4446a8a6197733f4c72532ee7f Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Fri, 13 Aug 2021 02:16:40 +0200 Subject: [PATCH 31/60] adding configure_transport --- src/trans_auto.c | 7 +++++++ src/trans_auto.h | 3 +++ src/transport.c | 1 + src/transport.h | 12 ++++++++++++ 4 files changed, 23 insertions(+) diff --git a/src/trans_auto.c b/src/trans_auto.c index 723deb08..9e45df8e 100644 --- a/src/trans_auto.c +++ b/src/trans_auto.c @@ -6,6 +6,13 @@ #include "trans_auto.h" +PEP_STATUS auto_configure(PEP_transport_t *transport, + transport_config_t *config, PEP_transport_status_code *tsc) +{ + + return PEP_STATUS_OK; +} + PEP_STATUS auto_startup(PEP_transport_t *transport, PEP_transport_status_code *tsc) { diff --git a/src/trans_auto.h b/src/trans_auto.h index f4251584..5141fbe4 100644 --- a/src/trans_auto.h +++ b/src/trans_auto.h @@ -9,6 +9,9 @@ #include "transport.h" +PEP_STATUS auto_configure(PEP_transport_t *transport, + transport_config_t *config, PEP_transport_status_code *tsc); + PEP_STATUS auto_startup(PEP_transport_t *transport, PEP_transport_status_code *tsc); diff --git a/src/transport.c b/src/transport.c index 9ec2e23f..1d9a8d9b 100644 --- a/src/transport.c +++ b/src/transport.c @@ -24,6 +24,7 @@ PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first) transports[PEP_trans_auto].id = PEP_trans_auto; transports[PEP_trans_auto].uri_scheme = ""; + transports[PEP_trans_auto].configure = auto_configure; transports[PEP_trans_auto].startup = auto_startup; transports[PEP_trans_auto].shutdown = auto_shutdown; diff --git a/src/transport.h b/src/transport.h index 583beab5..fafe850f 100644 --- a/src/transport.h +++ b/src/transport.h @@ -30,6 +30,14 @@ typedef enum _PEP_transport_id { PEP_trans_CC = 0xfe } PEP_transport_id; +typedef struct _transport_config { + // set size field when initializing + size_t size; + + // expand here + // in C++ this must be POD +} transport_config_t; + // transports are delivering the transport status code // this is defined here: // https://dev.pep.foundation/Engine/TransportStatusCode @@ -40,6 +48,9 @@ typedef struct _PEP_transport_t PEP_transport_t; // functions offered by transport +typedef PEP_STATUS (*configure_transport_t)(PEP_transport_t *transport, + transport_config_t *config, PEP_transport_status_code *tsc); + typedef PEP_STATUS (*startup_transport_t)(PEP_transport_t *transport, PEP_transport_status_code *tsc); @@ -79,6 +90,7 @@ struct _PEP_transport_t { // functions offered by transport + configure_transport_t configure; startup_transport_t startup; shutdown_transport_t shutdown; From 5690a3732bcaabd6a220940ff1d177679f9a4013 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Fri, 13 Aug 2021 10:29:55 +0200 Subject: [PATCH 32/60] supporting different execution environments --- src/trans_auto.c | 2 +- src/trans_auto.h | 2 +- src/transport.h | 12 ++++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/trans_auto.c b/src/trans_auto.c index 9e45df8e..c9570b9c 100644 --- a/src/trans_auto.c +++ b/src/trans_auto.c @@ -42,7 +42,7 @@ PEP_STATUS auto_recvnext(PEP_SESSION session, message **msg, } PEP_STATUS auto_notify(signal_statuschange_t status_change, - signal_sendto_result_t sendto_result) + signal_sendto_result_t sendto_result, callback_execution cbe) { return PEP_STATUS_OK; diff --git a/src/trans_auto.h b/src/trans_auto.h index 5141fbe4..ce6685e3 100644 --- a/src/trans_auto.h +++ b/src/trans_auto.h @@ -25,6 +25,6 @@ PEP_STATUS auto_recvnext(PEP_SESSION session, message **msg, PEP_transport_status_code *tsc); PEP_STATUS auto_notify(signal_statuschange_t status_change, - signal_sendto_result_t sendto_result); + signal_sendto_result_t sendto_result, callback_execution cbe); #endif diff --git a/src/transport.h b/src/transport.h index fafe850f..15026788 100644 --- a/src/transport.h +++ b/src/transport.h @@ -72,10 +72,18 @@ typedef PEP_STATUS (*signal_sendto_result_t)(PEP_transport_id id, char *message_ char *address, PEP_transport_status_code tsc); // call this to receive signals -// this function does not terminate until shutdown of the transport + +typedef enum _callback_execution { + PEP_cbe_polling = 0, // execute callbacks immediately only + PEP_cbe_async, // execute callbacks later on any thread + + // the last one is for the transport system only + // do not implement it in transports + PEP_cbe_blocking = 255 +} callback_execution; typedef PEP_STATUS (*notify_transport_t)(signal_statuschange_t status_change, - signal_sendto_result_t sendto_result); + signal_sendto_result_t sendto_result, callback_execution cbe); /** * @struct _PEP_transport_t From f2686c52a86f761df568fc30bb41e98fbce1cf3e Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Fri, 13 Aug 2021 10:35:16 +0200 Subject: [PATCH 33/60] ...0 --- src/transport.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/transport.h b/src/transport.h index 15026788..66c91828 100644 --- a/src/transport.h +++ b/src/transport.h @@ -75,13 +75,16 @@ typedef PEP_STATUS (*signal_sendto_result_t)(PEP_transport_id id, char *message_ typedef enum _callback_execution { PEP_cbe_polling = 0, // execute callbacks immediately only - PEP_cbe_async, // execute callbacks later on any thread + PEP_cbe_async, // execute callbacks multiple times later on any + // thread; call with PEP_cbe_polling to disable // the last one is for the transport system only // do not implement it in transports PEP_cbe_blocking = 255 } callback_execution; +// provide NULL for callbacks to avoid being called + typedef PEP_STATUS (*notify_transport_t)(signal_statuschange_t status_change, signal_sendto_result_t sendto_result, callback_execution cbe); From 5b2a028f51647e2908458719578752b48a3ee16d Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Fri, 13 Aug 2021 15:57:51 +0200 Subject: [PATCH 34/60] add signal_incoming_message_t --- src/trans_auto.c | 3 ++- src/trans_auto.h | 3 ++- src/transport.h | 6 +++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/trans_auto.c b/src/trans_auto.c index c9570b9c..a039a95c 100644 --- a/src/trans_auto.c +++ b/src/trans_auto.c @@ -42,7 +42,8 @@ PEP_STATUS auto_recvnext(PEP_SESSION session, message **msg, } PEP_STATUS auto_notify(signal_statuschange_t status_change, - signal_sendto_result_t sendto_result, callback_execution cbe) + signal_sendto_result_t sendto_result, + signal_incoming_message_t incoming, callback_execution cbe) { return PEP_STATUS_OK; diff --git a/src/trans_auto.h b/src/trans_auto.h index ce6685e3..809e85c6 100644 --- a/src/trans_auto.h +++ b/src/trans_auto.h @@ -25,6 +25,7 @@ PEP_STATUS auto_recvnext(PEP_SESSION session, message **msg, PEP_transport_status_code *tsc); PEP_STATUS auto_notify(signal_statuschange_t status_change, - signal_sendto_result_t sendto_result, callback_execution cbe); + signal_sendto_result_t sendto_result, + signal_incoming_message_t incoming, callback_execution cbe); #endif diff --git a/src/transport.h b/src/transport.h index 66c91828..e7ddd4e0 100644 --- a/src/transport.h +++ b/src/transport.h @@ -71,6 +71,9 @@ typedef PEP_STATUS (*signal_statuschange_t)(PEP_transport_id id, typedef PEP_STATUS (*signal_sendto_result_t)(PEP_transport_id id, char *message_id, char *address, PEP_transport_status_code tsc); +typedef PEP_STATUS (*signal_incoming_message_t)(PEP_transport_id id, + PEP_transport_status_code tsc); + // call this to receive signals typedef enum _callback_execution { @@ -86,7 +89,8 @@ typedef enum _callback_execution { // provide NULL for callbacks to avoid being called typedef PEP_STATUS (*notify_transport_t)(signal_statuschange_t status_change, - signal_sendto_result_t sendto_result, callback_execution cbe); + signal_sendto_result_t sendto_result, + signal_incoming_message_t incoming, callback_execution cbe); /** * @struct _PEP_transport_t From a47fff012bcddb0f292886e777b3e0e674df6b03 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 19 Aug 2021 13:15:20 +0200 Subject: [PATCH 35/60] avoid name clashes --- asn.1/message.asn1 | 18 +++++++----------- asn.1/pEp.asn1 | 6 +++--- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/asn.1/message.asn1 b/asn.1/message.asn1 index e9750ca8..2334d2ff 100644 --- a/asn.1/message.asn1 +++ b/asn.1/message.asn1 @@ -17,7 +17,7 @@ BEGIN EXPORTS ASN1Message; IMPORTS - PString, PStringList, Identity, IdentityList, StringPairList, Hash + PString, PStringList, Identity, IdentityList, PStringPairList, Hash FROM PEP { iso(1) org(3) dod(6) internet(1) private(4) enterprise(1) pEp(47878) basic(0) }; @@ -33,30 +33,26 @@ ContentDisposition ::= ENUMERATED { other (2) } -Blob ::= SEQUENCE { +PBlob ::= SEQUENCE { value OCTET STRING (SIZE(0..102400000)), -- up to 100 MB mime-type PString OPTIONAL, filename PString OPTIONAL, disposition ContentDisposition } -BlobList ::= SEQUENCE OF Blob +PBlobList ::= SEQUENCE OF PBlob -- For the purposes of this profile, GeneralizedTime values MUST be -- expressed in Coordinated Universal Time (UTC) and MUST include seconds -- (i.e., times are YYYYMMDDHHMMSSZ), even where the number of seconds -- is zero. GeneralizedTime values MUST NOT include fractional seconds. --- To make this more explicit, the type-name "Timestamp" is used in this --- profile. - -Timestamp ::= GeneralizedTime ASN1Message ::= SEQUENCE { direction MessageDirection OPTIONAL, -- used only in "inner" messages id PString OPTIONAL, -- UTF-8 string of message ID - sent Timestamp OPTIONAL, -- when the message is sent - recv Timestamp OPTIONAL, -- when the message is received + sent GeneralizedTime OPTIONAL, -- when the message is sent + recv GeneralizedTime OPTIONAL, -- when the message is received from Identity, -- whom the message is from -- At least one of to, cc must not be an empty list -- FIXME: Can this be constrained? @@ -74,7 +70,7 @@ ASN1Message ::= SEQUENCE { -- internal: refered_by _message-ref-list keywords PStringList OPTIONAL, -- list of UTF-8 strings with keywords comments PString OPTIONAL, -- UTF-8 string with comments - opt-fields StringPairList OPTIONAL, -- optional fields + opt-fields PStringPairList OPTIONAL, -- optional fields sender-fpr Hash OPTIONAL, -- fingerprint of sending signer -- At least one of shortmsg, longmsg, longmsg-formatted must be present @@ -90,7 +86,7 @@ ASN1Message ::= SEQUENCE { longmsg-formatted UTF8String OPTIONAL, -- UTF-8 string of long message -- (formatted) - attachments BlobList OPTIONAL -- blobs with attachments + attachments PBlobList OPTIONAL -- blobs with attachments -- internal: rawmsg } diff --git a/asn.1/pEp.asn1 b/asn.1/pEp.asn1 index c99c1307..21606228 100644 --- a/asn.1/pEp.asn1 +++ b/asn.1/pEp.asn1 @@ -12,7 +12,7 @@ DEFINITIONS AUTOMATIC TAGS EXTENSIBILITY IMPLIED ::= BEGIN -EXPORTS Identity, IdentityList, TID, Hash, Version, Rating, PString, PStringList, StringPair, StringPairList; +EXPORTS Identity, IdentityList, TID, Hash, Version, Rating, PString, PStringList, PStringPair, PStringPairList; ISO639-1 ::= PrintableString(FROM ("a".."z")) (SIZE(2)) Hex ::= PrintableString(FROM ("A".."F" | "0".."9")) @@ -63,12 +63,12 @@ Rating ::= ENUMERATED { under-attack (-3) } -StringPair ::= SEQUENCE { +PStringPair ::= SEQUENCE { key PString, value PString } -StringPairList ::= SEQUENCE OF StringPair +PStringPairList ::= SEQUENCE OF PStringPair END From 90878323300deba21f7394893d4bce2f00755a3b Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 19 Aug 2021 13:15:44 +0200 Subject: [PATCH 36/60] adapt to renaming --- src/map_asn1.c | 63 +++++++++++++++++++++++++------------------------- src/map_asn1.h | 58 +++++++++++++++++++++++----------------------- 2 files changed, 60 insertions(+), 61 deletions(-) diff --git a/src/map_asn1.c b/src/map_asn1.c index d45ec750..8ea479bd 100644 --- a/src/map_asn1.c +++ b/src/map_asn1.c @@ -131,7 +131,6 @@ IdentityList_t *IdentityList_from_identity_list( { bool allocated = !result; - assert(list && list->ident); if (!(list && list->ident)) return NULL; @@ -190,9 +189,9 @@ enomem: return NULL; } -StringPair_t *StringPair_from_Struct( +PStringPair_t *PStringPair_from_Struct( const stringpair_t *value, - StringPair_t *result + PStringPair_t *result ) { bool allocated = !result; @@ -202,7 +201,7 @@ StringPair_t *StringPair_from_Struct( return NULL; if (allocated) - result = (StringPair_t *) calloc(1, sizeof(StringPair_t)); + result = (PStringPair_t *) calloc(1, sizeof(PStringPair_t)); assert(result); if (!result) return NULL; @@ -223,11 +222,11 @@ StringPair_t *StringPair_from_Struct( enomem: if (allocated) - ASN_STRUCT_FREE(asn_DEF_StringPair, result); + ASN_STRUCT_FREE(asn_DEF_PStringPair, result); return NULL; } -stringpair_t *StringPair_to_Struct(StringPair_t *value) +stringpair_t *PStringPair_to_Struct(PStringPair_t *value) { assert(value); if (!value) @@ -257,19 +256,19 @@ enomem: return NULL; } -StringPairList_t *StringPairList_from_stringpair_list( +PStringPairList_t *PStringPairList_from_stringpair_list( const stringpair_list_t *list, - StringPairList_t *result + PStringPairList_t *result ) { bool allocated = !result; - assert(list && list->value); + assert(list); if (!(list && list->value)) return NULL; if (allocated) { - result = (StringPairList_t *) calloc(1, sizeof(StringPairList_t)); + result = (PStringPairList_t *) calloc(1, sizeof(PStringPairList_t)); assert(result); if (!result) return NULL; @@ -279,9 +278,9 @@ StringPairList_t *StringPairList_from_stringpair_list( } for (const stringpair_list_t *l = list; l && l->value; l=l->next) { - StringPair_t *value = StringPair_from_Struct(l->value, NULL); + PStringPair_t *value = PStringPair_from_Struct(l->value, NULL); if (ASN_SEQUENCE_ADD(&result->list, value)) { - ASN_STRUCT_FREE(asn_DEF_StringPair, value); + ASN_STRUCT_FREE(asn_DEF_PStringPair, value); goto enomem; } } @@ -290,12 +289,12 @@ StringPairList_t *StringPairList_from_stringpair_list( enomem: if (allocated) - ASN_STRUCT_FREE(asn_DEF_StringPairList, result); + ASN_STRUCT_FREE(asn_DEF_PStringPairList, result); return NULL; } -stringpair_list_t *StringPairList_to_stringpair_list( - StringPairList_t *list, +stringpair_list_t *PStringPairList_to_stringpair_list( + PStringPairList_t *list, stringpair_list_t *result ) { @@ -312,7 +311,7 @@ stringpair_list_t *StringPairList_to_stringpair_list( stringpair_list_t *r = result; for (int i=0; ilist.count; i++) { - stringpair_t *value = StringPair_to_Struct(list->list.array[i]); + stringpair_t *value = PStringPair_to_Struct(list->list.array[i]); r = stringpair_list_add(r, value); if (!r) goto enomem; @@ -333,7 +332,7 @@ PStringList_t *PStringList_from_stringlist( { bool allocated = !result; - assert(list && list->value); + assert(list); if (!(list && list->value)) return NULL; @@ -406,9 +405,9 @@ enomem: return NULL; } -BlobList_t *BlobList_from_bloblist( +PBlobList_t *PBlobList_from_bloblist( bloblist_t *list, - BlobList_t *result, + PBlobList_t *result, bool copy, size_t max_blob_size ) @@ -417,12 +416,12 @@ BlobList_t *BlobList_from_bloblist( if (!max_blob_size) max_blob_size = SIZE_MAX; - assert(list && list->value); + assert(list); if (!(list && list->value)) return NULL; if (allocated) { - result = (BlobList_t *) calloc(1, sizeof(BlobList_t)); + result = (PBlobList_t *) calloc(1, sizeof(PBlobList_t)); assert(result); if (!result) return NULL; @@ -434,7 +433,7 @@ BlobList_t *BlobList_from_bloblist( size_t rest_blob_size = max_blob_size; for (bloblist_t *l = list; l && l->value; l=l->next) { - Blob_t *element = (Blob_t *) calloc(1, sizeof(Blob_t)); + PBlob_t *element = (PBlob_t *) calloc(1, sizeof(PBlob_t)); assert(element); if (!element) goto enomem; @@ -503,7 +502,7 @@ BlobList_t *BlobList_from_bloblist( } if (ASN_SEQUENCE_ADD(&result->list, element)) { - ASN_STRUCT_FREE(asn_DEF_Blob, element); + ASN_STRUCT_FREE(asn_DEF_PBlob, element); goto enomem; } } @@ -512,12 +511,12 @@ BlobList_t *BlobList_from_bloblist( enomem: if (allocated) - ASN_STRUCT_FREE(asn_DEF_BlobList, result); + ASN_STRUCT_FREE(asn_DEF_PBlobList, result); return NULL; } -bloblist_t *BlobList_to_bloblist( - BlobList_t *list, +bloblist_t *PBlobList_to_bloblist( + PBlobList_t *list, bloblist_t *result, bool copy, size_t max_blob_size @@ -659,7 +658,7 @@ ASN1Message_t *ASN1Message_from_message( } if (msg->sent) { - Timestamp_t *ts = asn_time2GT(NULL, msg->sent, 1); + GeneralizedTime_t *ts = asn_time2GT(NULL, msg->sent, 1); if (!ts) goto enomem; @@ -667,7 +666,7 @@ ASN1Message_t *ASN1Message_from_message( } if (msg->recv) { - Timestamp_t *ts = asn_time2GT(NULL, msg->recv, 1); + GeneralizedTime_t *ts = asn_time2GT(NULL, msg->recv, 1); if (!ts) goto enomem; @@ -756,7 +755,7 @@ ASN1Message_t *ASN1Message_from_message( } if (msg->opt_fields && msg->opt_fields->value) { - StringPairList_t *l = StringPairList_from_stringpair_list(msg->opt_fields, NULL); + PStringPairList_t *l = PStringPairList_from_stringpair_list(msg->opt_fields, NULL); if (!l) goto enomem; @@ -844,7 +843,7 @@ ASN1Message_t *ASN1Message_from_message( } if (msg->attachments && msg->attachments->value) { - BlobList_t *bl = BlobList_from_bloblist(msg->attachments, NULL, copy, + PBlobList_t *bl = PBlobList_from_bloblist(msg->attachments, NULL, copy, rest_blob_size); if (!bl) goto enomem; @@ -1000,7 +999,7 @@ message *ASN1Message_to_message( if (msg->opt_fields) { stringpair_list_t *l = - StringPairList_to_stringpair_list(msg->opt_fields, NULL); + PStringPairList_to_stringpair_list(msg->opt_fields, NULL); if (!l) goto enomem; @@ -1073,7 +1072,7 @@ message *ASN1Message_to_message( } if (msg->attachments) { - bloblist_t *a = BlobList_to_bloblist(msg->attachments, NULL, copy, + bloblist_t *a = PBlobList_to_bloblist(msg->attachments, NULL, copy, rest_blob_size); if (!a) goto enomem; diff --git a/src/map_asn1.h b/src/map_asn1.h index 8373b80a..2ace2f27 100644 --- a/src/map_asn1.h +++ b/src/map_asn1.h @@ -89,12 +89,12 @@ identity_list *IdentityList_to_identity_list(IdentityList_t *list, identity_list /** - * + * * - * @brief Convert stringpair_t into ASN.1 StringPair_t + * @brief Convert stringpair_t into ASN.1 PStringPair_t * * @param value[in] stringpair_t to convert - * @param result[in,out] StringPair_t to update or NULL to alloc a new one + * @param result[in,out] PStringPair_t to update or NULL to alloc a new one * * @retval pointer to updated or allocated result * @@ -102,18 +102,18 @@ identity_list *IdentityList_to_identity_list(IdentityList_t *list, identity_list * */ -StringPair_t *StringPair_from_Struct( +PStringPair_t *PStringPair_from_Struct( const stringpair_t *value, - StringPair_t *result + PStringPair_t *result ); /** - * + * * - * @brief Convert ASN.1 StringPair_t into stringpair_t + * @brief Convert ASN.1 PStringPair_t into stringpair_t * - * @param value[in] StringPair_t to convert + * @param value[in] PStringPair_t to convert * * @retval pointer to updated or allocated result * @@ -121,16 +121,16 @@ StringPair_t *StringPair_from_Struct( * */ -stringpair_t *StringPair_to_Struct(StringPair_t *value); +stringpair_t *PStringPair_to_Struct(PStringPair_t *value); /** - * + * * - * @brief Convert stringpair_list_t into ASN.1 StringPairList_t + * @brief Convert stringpair_list_t into ASN.1 PStringPairList_t * * @param list[in] stringpair_list to convert - * @param result[inout] StringPairList_t to update or NULL to alloc a new one + * @param result[inout] PStringPairList_t to update or NULL to alloc a new one * * @retval pointer to updated or allocated result * @@ -138,17 +138,17 @@ stringpair_t *StringPair_to_Struct(StringPair_t *value); * */ -StringPairList_t *StringPairList_from_stringpair_list( +PStringPairList_t *PStringPairList_from_stringpair_list( const stringpair_list_t *list, - StringPairList_t *result + PStringPairList_t *result ); /** - * + * * - * @brief Convert ASN.1 StringPairList_t to stringpair_list_t + * @brief Convert ASN.1 PStringPairList_t to stringpair_list_t * - * @param list[in] ASN.1 StringPairList_t to convert + * @param list[in] ASN.1 PStringPairList_t to convert * @param result[inout] stringpair_list_t to update or NULL to alloc a new one * * @retval pointer to updated or allocated result @@ -157,8 +157,8 @@ StringPairList_t *StringPairList_from_stringpair_list( * */ -stringpair_list_t *StringPairList_to_stringpair_list( - StringPairList_t *list, +stringpair_list_t *PStringPairList_to_stringpair_list( + PStringPairList_t *list, stringpair_list_t *result ); @@ -199,12 +199,12 @@ stringlist_t *PStringList_to_stringlist(PStringList_t *list); /** - * + * * - * @brief Convert bloblist_t into ASN.1 BlobList_t + * @brief Convert bloblist_t into ASN.1 PBlobList_t * * @param list[in] bloblist to convert - * @param result[inout] BlobList_t to update or NULL to alloc a new one + * @param result[inout] PBlobList_t to update or NULL to alloc a new one * @param copy copy data if true, move data otherwise * @param max_blob_size reject if sum(blob.size) > max_blob_size * to disable set to 0 @@ -215,20 +215,20 @@ stringlist_t *PStringList_to_stringlist(PStringList_t *list); * */ -BlobList_t *BlobList_from_bloblist( +PBlobList_t *PBlobList_from_bloblist( bloblist_t *list, - BlobList_t *result, + PBlobList_t *result, bool copy, size_t max_blob_size ); /** - * + * * - * @brief Convert ASN.1 BlobList_t to bloblist_t + * @brief Convert ASN.1 PBlobList_t to bloblist_t * - * @param list[in] ASN.1 BlobList_t to convert + * @param list[in] ASN.1 PBlobList_t to convert * @param result[inout] bloblist_t to update or NULL to alloc a new one * @param copy copy data if true, move data otherwise * @param max_blob_size reject if sum(blob.size) > max_blob_size @@ -240,8 +240,8 @@ BlobList_t *BlobList_from_bloblist( * */ -bloblist_t *BlobList_to_bloblist( - BlobList_t *list, +bloblist_t *PBlobList_to_bloblist( + PBlobList_t *list, bloblist_t *result, bool copy, size_t max_blob_size From 0eca1d413b87945941a8bbdcdcfcf3360d893b24 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 19 Aug 2021 13:25:51 +0200 Subject: [PATCH 37/60] correct gen_dot --- codegen/Makefile | 2 +- codegen/gen_dot.ysl2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/codegen/Makefile b/codegen/Makefile index 5c679018..3afa49e8 100644 --- a/codegen/Makefile +++ b/codegen/Makefile @@ -44,5 +44,5 @@ svg: $(patsubst %.dot,%.svg,$(wildcard *.dot)) $(YML2_PROC) -y gen_dot.ysl2 $< -o $@ %.svg: %.dot - dot -Tsvg -o $@ $< + dot -Tsvg $< -o $@ > /dev/null diff --git a/codegen/gen_dot.ysl2 b/codegen/gen_dot.ysl2 index 03b785de..c7f2a6da 100644 --- a/codegen/gen_dot.ysl2 +++ b/codegen/gen_dot.ysl2 @@ -4,7 +4,7 @@ include yslt.yml2 tstylesheet { - template "protocol/fsm[count(state)>0]" document "{@name}.dot", "text" + template "/protocol/fsm[count(state)>0]" || digraph finite_state_machine { rankdir=LR; From 812b8f8065be2e584a0b41771c4e681fd760b93f Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 19 Aug 2021 13:42:08 +0200 Subject: [PATCH 38/60] Bumped header patch number for NEXT release --- src/pEpEngine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pEpEngine.h b/src/pEpEngine.h index a8310bda..2c97df92 100644 --- a/src/pEpEngine.h +++ b/src/pEpEngine.h @@ -29,7 +29,7 @@ extern "C" { #define PEP_ENGINE_VERSION_MAJOR 3 #define PEP_ENGINE_VERSION_MINOR 2 #define PEP_ENGINE_VERSION_PATCH 0 -#define PEP_ENGINE_VERSION_RC 4 +#define PEP_ENGINE_VERSION_RC 5 #define PEP_OWN_USERID "pEp_own_userId" From 1bd8d6c503d1d1eb0212d9c2fba7f56c82d752d2 Mon Sep 17 00:00:00 2001 From: Luca Saiu Date: Fri, 20 Aug 2021 13:53:44 +0200 Subject: [PATCH 39/60] improve build system documentation --- doc/build-debian.md | 96 +++++++++++++++++++++++++++++++-------------- test/README.md | 79 ++++++++++++++++++++++++++++++------- 2 files changed, 132 insertions(+), 43 deletions(-) diff --git a/doc/build-debian.md b/doc/build-debian.md index 56edca16..9bc295e4 100644 --- a/doc/build-debian.md +++ b/doc/build-debian.md @@ -1,43 +1,56 @@ - -# Build instructions for Debian 9 +# Build instructions for Debian 9 and 10 + +We assume the user keeps sources under `~/pep-src`. There is no single +installation prefix: each package is built, or when supported installed, in +either its source directory or in a subdirectory of its source directory. +Rationale: we do not pollute the user system, uninstalling is trivial. + +This is Unix: we assume no spaces in user names. + +~~~ +mkdir -p ~/pep-src +~~~ # Installing packaged dependencies ~~~ # general -apt install -y mercurial -# YML2 -apt install -y python-lxml +apt install -y git # libetpan apt install -y git build-essential automake libtool # asn1c apt install -y git build-essential automake libtool autoconf +# sequoia +apt install git rustc cargo clang libclang-dev make pkg-config nettle-dev libssl-dev capnproto libsqlite3-dev # engine apt install -y uuid-dev libgpgme-dev libsqlite3-dev sqlite3 +# optional: developer documentation +apt install -y doxygen pandoc ~~~ # Installing unpackaged dependencies ## YML2 ~~~ -mkdir -p ~/code/yml2 -git clone https://gitea.pep.foundation/fdik/yml2.git ~/code/yml2 +mkdir -p ~/pep-src/yml2 +git clone https://gitea.pep.foundation/fdik/yml2.git ~/pep-src/yml2 ~~~ ## libetpan pEp Engine requires libetpan with a set of patches that have not been upstreamed yet. ~~~ -mkdir -p ~/code/libetpan +mkdir -p ~/pep-src/libetpan -git clone https://gitea.pep.foundation/pEp.foundation/libetpan.git ~/code/libetpan -cd ~/code/libetpan -mkdir ~/code/libetpan/build -./autogen.sh --prefix="$HOME/code/libetpan/build" +git clone https://gitea.pep.foundation/pEp.foundation/libetpan.git ~/pep-src/libetpan +cd ~/pep-src/libetpan +mkdir ~/pep-src/libetpan/build +./autogen.sh --prefix="$HOME/pep-src/libetpan/build" make make install ~~~ @@ -45,45 +58,70 @@ make install ## asn1c ~~~ -mkdir -p ~/code/asn1c -git clone git://github.com/vlm/asn1c.git ~/code/asn1c -cd ~/code/asn1c +mkdir -p ~/pep-src/asn1c +git clone git://github.com/vlm/asn1c.git ~/pep-src/asn1c +cd ~/pep-src/asn1c git checkout tags/v0.9.28 -b pep-engine autoreconf -iv -mkdir ~/code/asn1c/build -./configure --prefix="$HOME/code/asn1c/build" +mkdir ~/pep-src/asn1c/build +./configure --prefix="$HOME/pep-src/asn1c/build" make make install ~~~ +## sequoia + +~~~ +git clone https://gitlab.com/sequoia-pgp/sequoia +cd ~/pep-src/sequoia +git checkout openpgp/v1.3.0 +# Make an optimised sequoia build. +cargo build --all --release -j16 +~~~ + +This alternative for the last line above is faster, but generates compiled libraries +in `~/pep-src/sequoia/target/debug` instead of `~/pep-src/sequoia/target/release`: +several definitions below need to be adapted. +~~~ +# Alternative: make a debugging sequoia build. +cargo build --all -j16 +~~~ + # pEp Engine ~~~ -mkdir -p ~/code/pep-engine -hg clone https://pep.foundation/dev/repos/pEpEngine/ ~/code/pep-engine -cd ~/code/pep-engine -mkdir ~/code/pep-engine/build +mkdir -p ~/pep-src/pep-engine +git clone https://gitea.pep.foundation/pEp.foundation/pEpEngine ~/pep-src/pep-engine +cd ~/pep-src/pep-engine +mkdir build ~~~ -Edit the build configuration to your needs in `Makefile.conf`, or create a `local.conf` that sets any of the make variables documented in `Makefile.conf`. All the default values for the build configuration variables on each platform are documented in `Makefile.conf`. +Edit the build configuration to your needs in `Makefile.conf`, or create a `local.conf` in your source directory (the same containing `Makefile.conf`) that sets any of the make variables documented in `Makefile.conf`. All the default values for the build configuration variables on each platform are documented in `Makefile.conf`. If a dependency is not found in your system's default include or library paths, you will have to specify the according paths in a make variable. Typically, this has to be done at least for YML2, libetpan and asn1c. For a more detailed explanation of the mechanics of these build configuration files, and overriding defaults, see the comments in `Makefile.conf`. -Below is a sample `./local.conf` file, for orientation. +The following `./local.conf` example should work in the configuration described here. ~~~ -PREFIX=$(HOME)/code/pep-engine/build +PREFIX=$(HOME)/pep-src/pep-engine/build PER_MACHINE_DIRECTORY=$(PREFIX)/share/pEp -YML2_PATH=$(HOME)/code/yml2 +YML2_PATH=$(HOME)/pep-src/yml2 + +ETPAN_LIB=-L$(HOME)/pep-src/libetpan/build/lib +ETPAN_INC=-I$(HOME)/pep-src/libetpan/build/include + +ASN1C=$(HOME)/pep-src/asn1c/build/bin/asn1c +ASN1C_INC=-I$(HOME)/pep-src/asn1c/build/share/asn1c -ETPAN_LIB=-L$(HOME)/code/libetpan/build/lib -ETPAN_INC=-I$(HOME)/code/libetpan/build/include +SEQUOIA_INC=-I$(HOME)/pep-src/sequoia/openpgp-ffi/include +SEQUOIA_LDFLAGS=-L$(HOME)/pep-src/sequoia/target/release -ASN1C=$(HOME)/code/asn1c/build/bin/asn1c -ASN1C_INC=-I$(HOME)/code/asn1c/build/share/asn1c +GTEST_SRC_DIR=$(HOME)/pep-src/googletest/googletest +GTEST_INC_DIR=$(HOME)/pep-src/googletest/googletest/include +GTEST_PL=$(HOME)/pep-src/gtest-parallel/gtest_parallel.py ~~~ The engine is built as follows: diff --git a/test/README.md b/test/README.md index 553bc823..33b88c46 100644 --- a/test/README.md +++ b/test/README.md @@ -80,40 +80,61 @@ Ubuntu](https://www.eriksmistad.no/getting-started-with-google-test-on-ubuntu/)) 1. Get the source, Fred. (Luke is tired of the source, I hear.) ``` - git clone https://github.com/google/googletest.git + mkdir -p ~/pep-src/googletest + git clone https://github.com/google/googletest.git ~/pep-src/googletest ``` - 2. Switch into the source directory and find the directory - containing the `src` and `include` directories. Mark this directory - for later. (For me, this is `./googletest/googletest`) - - 3. Edit `CMakeLists.txt` here to contain the following line at the top: + 2. Switch into the source directory and find the subdirectory of + `googletest` (the source distribution of googletest also contains a + `googlemock` library which is not useful to us here) + containing the `src` and `include` directories. Remember this + directory's path. For me it is `~/pep-src/googletest/googletest` . + + 3. Edit the file `CMakeLists.txt` in that directory, adding the + following line at the top: ``` set (CMAKE_CXX_STANDARD 11) ``` (If you don't, it won't compile, and I will shake my fist at you.) - 4. Execute, in this directory: + 4. Go to the googletest source directory (it should be the parent + directory of the directory containing the file you edited) and build + the library. + ``` + cd ~/pep-src/googletest cmake CMakeLists.txt make ``` 5. In the lib directory of your current directory are located the - library files you'll use (`lib/*.a`). Copy or symlink them to the library + library files you'll use (`lib/*.a`). You may leave them there without + installing them, if you accept running a more complex command line than + ``` + make test + ``` + later. If you want to install the library, read on. + + Copy or symlink them to the library location of your choice (make sure this is a directory that can be seen during the test build process - i.e. one that's in one of the library paths used in building. Mine are located in `$HOME/lib`. - - 6. See `Makefile` and `local.conf` under "Building the test suite" below - + See `Makefile` and `local.conf` under "Building the test suite" below - In this scenario, I set `GTEST_SRC_DIR` as `/googletest/googletest` (i.e. the absolute path of where the `src` and `include` directories were - above - for me, `/Users/krista/googletest/googletest`). + above - for example, `/Users/krista/googletest/googletest`). ### Installing `gtest-parallel` Pick a source directory and put your `gtest-parallel` source there -(e.g. via `git clone https://github.com/google/gtest-parallel.git`). +(e.g. via `git clone https://github.com/google/gtest-parallel.git`): + +``` +mkdir -p ~/pep-src/gtest-parallel +git clone https://github.com/google/gtest-parallel.git ~/pep-src/gtest-parallel +``` + +This library is written in Python and does not require any actual build. We'll deal more with this when preparing to compile the test suite. @@ -133,13 +154,43 @@ are: * `GTEST_INC_DIR`: This is where the include files for googletest are located (defaults to `$(GTEST_SRC_DIR)/include`) - * `GTEST_PL`: This is the full path to the *python file* for `gtest_parallel` + * `GTEST_PL`: This is the full path to the *python file* for `gtest_parallel.py` (default presumes you cloned it under `src` in your home directory, i.e. it is `$(HOME)/src/gtest-parallel/gtest_parallel.py`) +The sample `local.conf` included in `../doc/build-debian.md` contains correct +definitions for these variables, assuming the user installed from sources under +`~/pep-src` as described here. + ### Building -Presuming the above works, then from the top test directory, simply run make. +Presuming the above works and you installed every library, then from the top test +directory, simply run ``make``. + +Libraries which have not been installed into the `lib` subdirectory of some +standard prefix will not be found automatically. But this problem is easy to +circumbent by setting environment libraries (on system using the GNU +linked-loader `LD_LIBRARY_PATH` for dynamic libraries, `LIBRARY_PATH` for static +libraries). + +For example, this should be sufficient to run the test suite under a debian +system following the instruction at `../doc/build-debian.md`: +``` +cd ~/pep-src/pep-engine +LIBRARY_PATH=$LIBRARY_PATH:$HOME/pep-src/googletest/lib LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/pep-src/pep-engine/src:$HOME/pep-src/sequoia/target/release:$HOME/pep-src/libetpan/build/lib make test +``` + +Such variable definitions may be prepended to the command lines below for running +individual tests or the entire test suite. + +In case of test failures remember to build the database, on which the test suite +depends, and to copy it into the system directory: +``` +make dbinstall +``` +The database does not need to be rebuilt and reinstalled for every test suite +run: running the `dbinstall` target once suffices. + ## Running the test suite From 7e18d17aeee74c0e5c7a33b720f8e0fa7d44f2d9 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Fri, 20 Aug 2021 17:30:32 +0200 Subject: [PATCH 40/60] adding transport ID for PDL --- src/transport.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/transport.h b/src/transport.h index e7ddd4e0..5d4f586f 100644 --- a/src/transport.h +++ b/src/transport.h @@ -25,6 +25,7 @@ typedef enum _PEP_transport_id { PEP_trans_auto = 0, // PEP_trans_Email = 0x01, // PEP_trans_RCE = 0x02, +// PEP_trans_PDL = 0x03, PEP_trans__count, PEP_trans_CC = 0xfe From 855f87655be2b77c368e2bf242c28b9d466235cf Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 26 Aug 2021 11:03:09 +0200 Subject: [PATCH 41/60] this is needed because map_asn1.h is now an external header --- src/map_asn1.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/map_asn1.h b/src/map_asn1.h index 2ace2f27..e9aa35ff 100644 --- a/src/map_asn1.h +++ b/src/map_asn1.h @@ -8,7 +8,7 @@ #define MAP_ASN1_H #include "message.h" -#include "../asn.1/ASN1Message.h" +#include "ASN1Message.h" #ifdef __cplusplus extern "C" { From 82713a4ecd63bc8a61e3d91055f0e6b071d51c51 Mon Sep 17 00:00:00 2001 From: Luca Saiu Date: Fri, 27 Aug 2021 11:34:50 +0200 Subject: [PATCH 42/60] fix ENGINE-570: new database user version 19, the only difference being indices Change SQL definitions. Add code to migrate cleanly from version 18. --- src/engine_sql.c | 27 ++++++++++++++++++++++++++- src/engine_sql.h | 2 +- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/engine_sql.c b/src/engine_sql.c index a983c5ea..5bee4f75 100644 --- a/src/engine_sql.c +++ b/src/engine_sql.c @@ -713,7 +713,7 @@ static PEP_STATUS _create_core_tables(PEP_SESSION session) { " timestamp integer default (datetime('now')),\n" " primary key (address, user_id)\n" ");\n" - "create index if not exists identity_userid_addr on identity(address, user_id);\n" + "create index if not exists identity_userid on identity (user_id);\n" "create table if not exists trust (\n" " user_id text not null\n" " references person (id)\n" @@ -1548,6 +1548,27 @@ static PEP_STATUS _upgrade_DB_to_ver_18(PEP_SESSION session) { return _force_upgrade_own_latest_message_version(session); } +static PEP_STATUS _upgrade_DB_to_ver_19(PEP_SESSION session) { + int int_result = sqlite3_exec( + session->db, + /* This index was useless: it was an index on the (multi-column) + primary key, always implemented using an index which gets also + used in queries. */ + "drop index if exists identity_userid_addr;\n" + "\n" + "create index if not exists identity_userid on identity (user_id);\n" + NULL, + NULL, + NULL + ); + assert(int_result == SQLITE_OK); + + if (int_result != SQLITE_OK) + return PEP_UNKNOWN_DB_ERROR; + + return PEP_STATUS_OK; +} + // Honestly, the upgrades should be redone in a transaction IMHO. static PEP_STATUS _check_and_execute_upgrades(PEP_SESSION session, int version) { PEP_STATUS status = PEP_STATUS_OK; @@ -1620,6 +1641,10 @@ static PEP_STATUS _check_and_execute_upgrades(PEP_SESSION session, int version) if (status != PEP_STATUS_OK) return status; case 18: + status = _upgrade_DB_to_ver_19(session); + if (status != PEP_STATUS_OK) + return status; + case 19: break; default: return PEP_ILLEGAL_VALUE; diff --git a/src/engine_sql.h b/src/engine_sql.h index 0bcd6415..25d98ea4 100644 --- a/src/engine_sql.h +++ b/src/engine_sql.h @@ -3,7 +3,7 @@ #include "pEp_internal.h" // increment this when patching DDL -#define _DDL_USER_VERSION "18" +#define _DDL_USER_VERSION "19" PEP_STATUS init_databases(PEP_SESSION session); PEP_STATUS pEp_sql_init(PEP_SESSION session); From 324e3e92b04131ac2ce8c20d5b3ca4d02858fa8a Mon Sep 17 00:00:00 2001 From: Luca Saiu Date: Fri, 27 Aug 2021 12:20:43 +0200 Subject: [PATCH 43/60] fix silly syntax error --- src/engine_sql.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine_sql.c b/src/engine_sql.c index 5bee4f75..344fb96d 100644 --- a/src/engine_sql.c +++ b/src/engine_sql.c @@ -1556,7 +1556,7 @@ static PEP_STATUS _upgrade_DB_to_ver_19(PEP_SESSION session) { used in queries. */ "drop index if exists identity_userid_addr;\n" "\n" - "create index if not exists identity_userid on identity (user_id);\n" + "create index if not exists identity_userid on identity (user_id);\n", NULL, NULL, NULL From 6039b10ca5a837655a5fb1b22c3ff5f2e19941b8 Mon Sep 17 00:00:00 2001 From: Krista Bennett Date: Fri, 27 Aug 2021 10:52:13 +0200 Subject: [PATCH 44/60] Fixed decoder generation to create decoder that fails when entire blob isn't consumed (or on other failure), indicating an illegal message --- codegen/gen_codec.ysl2 | 9 +++++++-- test/src/ElevatedAttachmentsTest.cc | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/codegen/gen_codec.ysl2 b/codegen/gen_codec.ysl2 index 8aae0382..131c0fe9 100644 --- a/codegen/gen_codec.ysl2 +++ b/codegen/gen_codec.ysl2 @@ -152,8 +152,13 @@ tstylesheet { *msg = NULL; «@name»_t *_msg = NULL; - uper_decode_complete(NULL, &asn_DEF_«@name», (void **) &_msg, data, size); - if (!_msg) + asn_dec_rval_t rval = uper_decode_complete(NULL, &asn_DEF_«@name», (void **) &_msg, data, size); + + // N.B: If you plan on having messages were the full message isn't consumed by decoding here, + // then please look into uper_decode_complete; we still may get a message, even if to contains + // nothing. RC_FAIL is an obvious case, but we also need to fail if RC_WMORE is the code, especially + // if rval.consumed == 0. Volker, please look into this and decide what you want. + if (!_msg || rval.code != RC_OK) return PEP_«yml:ucase(@name)»_ILLEGAL_MESSAGE; *msg = _msg; diff --git a/test/src/ElevatedAttachmentsTest.cc b/test/src/ElevatedAttachmentsTest.cc index 9b6812f6..aeb4a768 100644 --- a/test/src/ElevatedAttachmentsTest.cc +++ b/test/src/ElevatedAttachmentsTest.cc @@ -226,6 +226,8 @@ TEST_F(ElevatedAttachmentsTest, check_encrypt_decrypt_message) { msg->shortmsg = strdup("Yo Bob!"); msg->longmsg = strdup("Look at my hot new sender fpr field!"); + // Volker: This is a sloppy way to test - it got processed as a real distribution message because data has meaning + // and happily exposed a bug in your generation code, but... well, you know better :) const char *distribution = "simulation of distribution data"; msg->attachments = new_bloblist(strdup(distribution), strlen(distribution) + 1, "application/pEp.distribution", "distribution.pEp"); From c3797c3ccde4eeee17d39dc3cfa9b70d940a95fe Mon Sep 17 00:00:00 2001 From: Luca Saiu Date: Tue, 31 Aug 2021 17:37:06 +0200 Subject: [PATCH 45/60] fix minor memory leak: free session->curr_passphrase at session closing Another leak, much more complex and difficult to reproduce, remains. See _do_full_reset_on_single_own_ungrouped_identity in src/key_reset.c . --- src/pEpEngine.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/pEpEngine.c b/src/pEpEngine.c index 1dac1961..31e7f9b6 100644 --- a/src/pEpEngine.c +++ b/src/pEpEngine.c @@ -161,6 +161,12 @@ DYNAMIC_API void release(PEP_SESSION session) sqlite3_close_v2(session->system_db); } + if (!EMPTYSTR(session->curr_passphrase)) { + free (session->curr_passphrase); + /* In case the following freeing code still uses the field. */ + session->curr_passphrase = NULL; + } + release_transport_system(session, out_last); release_cryptotech(session, out_last); free(session); From 5f24d321309dd913f7ea29b6acd3d3eee1bb195e Mon Sep 17 00:00:00 2001 From: Luca Saiu Date: Wed, 1 Sep 2021 17:56:02 +0200 Subject: [PATCH 46/60] remove distracting log line from generated code --- codegen/gen_statemachine.ysl2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codegen/gen_statemachine.ysl2 b/codegen/gen_statemachine.ysl2 index bc206dff..07019b6f 100644 --- a/codegen/gen_statemachine.ysl2 +++ b/codegen/gen_statemachine.ysl2 @@ -1705,7 +1705,7 @@ tstylesheet { switch (event) { case None: - «../@name»_SERVICE_LOG("received Timeout event", "ignoring"); + // received Timeout event, ignoring break; || From 02b9afda5a6f307dba2a3e3a74514702965e951d Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 2 Sep 2021 10:07:51 +0200 Subject: [PATCH 47/60] adding SCTP transport --- src/transport.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/transport.h b/src/transport.h index 5d4f586f..2b0eac6d 100644 --- a/src/transport.h +++ b/src/transport.h @@ -26,6 +26,7 @@ typedef enum _PEP_transport_id { // PEP_trans_Email = 0x01, // PEP_trans_RCE = 0x02, // PEP_trans_PDL = 0x03, +// PEP_trans_SCTP = 0x04, PEP_trans__count, PEP_trans_CC = 0xfe From 7e039df16aa987bcb24ff76d841904c53a6404c1 Mon Sep 17 00:00:00 2001 From: Luca Saiu Date: Thu, 2 Sep 2021 15:33:36 +0200 Subject: [PATCH 48/60] remove keyserver lookup Remove keyserver functionality in keymanagement.c and in the API, including now useless callbacks. --- src/keymanagement.c | 67 ----------------------------------- src/keymanagement.h | 86 --------------------------------------------- src/pEp_internal.h | 2 -- 3 files changed, 155 deletions(-) diff --git a/src/keymanagement.c b/src/keymanagement.c index 315546a8..7e4f60f5 100644 --- a/src/keymanagement.c +++ b/src/keymanagement.c @@ -875,13 +875,6 @@ DYNAMIC_API PEP_STATUS update_identity( if (identity->comm_type == PEP_ct_unknown) identity->comm_type = PEP_ct_key_not_found; } - - // VB says, and I quote, "that is not implemented and no one is using it right now" - // about this bit. So, um, you're forewarned. - if (identity->comm_type != PEP_ct_compromised && - identity->comm_type < PEP_ct_strong_but_unconfirmed) - if (session->examine_identity) - session->examine_identity(identity, session->examine_management); goto pEp_free; @@ -1256,66 +1249,6 @@ DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity) return _myself(session, identity, true, true, false, false); } -DYNAMIC_API PEP_STATUS register_examine_function( - PEP_SESSION session, - examine_identity_t examine_identity, - void *management - ) -{ - assert(session); - if (!session) - return PEP_ILLEGAL_VALUE; - - session->examine_management = management; - session->examine_identity = examine_identity; - - return PEP_STATUS_OK; -} - -DYNAMIC_API PEP_STATUS do_keymanagement( - retrieve_next_identity_t retrieve_next_identity, - void *management - ) -{ - PEP_SESSION session; - pEp_identity *identity; - // FIXME_NOW: ensure_decrypt callback??? - PEP_STATUS status = init(&session, NULL, NULL, NULL); - assert(!status); - if (status) - return status; - - assert(session && retrieve_next_identity); - if (!(session && retrieve_next_identity)) - return PEP_ILLEGAL_VALUE; - - log_event(session, "keymanagement thread started", "pEp engine", NULL, NULL); - - while ((identity = retrieve_next_identity(management))) - { - assert(identity->address); - if(identity->address) - { - DEBUG_LOG("do_keymanagement", "retrieve_next_identity", identity->address); - - if (identity->me) { - status = myself(session, identity); - } else { - status = recv_key(session, identity->address); - } - - assert(status != PEP_OUT_OF_MEMORY); - if(status == PEP_OUT_OF_MEMORY) - return PEP_OUT_OF_MEMORY; - } - free_identity(identity); - } - - log_event(session, "keymanagement thread shutdown", "pEp engine", NULL, NULL); - release(session); - return PEP_STATUS_OK; -} - DYNAMIC_API PEP_STATUS key_mistrusted( PEP_SESSION session, pEp_identity *ident diff --git a/src/keymanagement.h b/src/keymanagement.h index 18a38b3b..ce097fc1 100644 --- a/src/keymanagement.h +++ b/src/keymanagement.h @@ -122,92 +122,6 @@ DYNAMIC_API PEP_STATUS update_identity( DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity); -/** - * - * - * @brief Callback being called by do_keymanagement() - * - * @param[in] management data structure to deliver (implementation defined) - * - * @retval identity to check or NULL to terminate do_keymanagement() - * if given identity must be created with new_identity() - * the identity struct is going to the ownership of this library - * it must not be freed by the callee - * - * @warning this callback has to block until an identity or NULL can be returned - * an implementation is not provided by this library; instead it has to be - * implemented by the user of this library - * - */ - -typedef pEp_identity *(*retrieve_next_identity_t)(void *management); - - -/** - * - * - * @brief Callback for appending to queue - * - * @param[in] ident identity to examine - * @param[in] management data structure to deliver (implementation defined) - * - * @retval 0 if identity was added successfully to queue or nonzero otherwise - * - * - */ - -typedef int (*examine_identity_t)(pEp_identity *ident, void *management); - - -/** - * - * - * @brief Register examine_identity() callback - * - * @param[in] session session to use - * @param[in] examine_identity examine_identity() function to register - * @param[in] management data structure to deliver (implementation defined) - * - * @retval PEP_STATUS_OK - * @retval PEP_ILLEGAL_VALUE illegal parameter values - * - */ - -DYNAMIC_API PEP_STATUS register_examine_function( - PEP_SESSION session, - examine_identity_t examine_identity, - void *management - ); - - -/** - * - * - * @brief Function to be run on an extra thread - * - * @param[in] retrieve_next_identity pointer to retrieve_next_identity() - * callback which returns at least a valid - * address field in the identity struct - * - * @retval PEP_STATUS_OK if thread has to terminate successfully - * @retval PEP_ILLEGAL_VALUE illegal parameter values - * @retval PEP_OUT_OF_MEMORY out of memory - * @retval any other value on failure - * - * @warning to ensure proper working of this library, a thread has to be started - * with this function immediately after initialization - * do_keymanagement() calls retrieve_next_identity(management) - * messageToSend can only be null if no transport is application based - * if transport system is not used it must not be NULL - * - */ - -DYNAMIC_API PEP_STATUS do_keymanagement( - retrieve_next_identity_t retrieve_next_identity, - void *management - ); - - /** * * diff --git a/src/pEp_internal.h b/src/pEp_internal.h index 23391b03..a7bcd34e 100644 --- a/src/pEp_internal.h +++ b/src/pEp_internal.h @@ -298,8 +298,6 @@ struct _pEpSession { sqlite3_stmt *add_userid_alias; // callbacks - examine_identity_t examine_identity; - void *examine_management; notifyHandshake_t notifyHandshake; inject_sync_event_t inject_sync_event; retrieve_next_sync_event_t retrieve_next_sync_event; From 3095f39fec022b5de34266c6df8a48f1796460cc Mon Sep 17 00:00:00 2001 From: Luca Saiu Date: Fri, 3 Sep 2021 18:14:23 +0200 Subject: [PATCH 49/60] fix ENGINE-956 It is now possible to use shell environment variables in PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY, expanded at *run* time. This is meant to allow more freedom to the deployment engineer, without affecting development. Notice that, when PER_USER_DIRECTORY and PER_MACHINE_DIRECTORY are defined in the Makefile, dollar signs must be escaped (a dollar becomes a double dollar) because of *make* syntax: this has nothing to do with pEp engine code. Expansion follows the Unix shell $VARIABLE syntax: ${VARIABLE} is not supported. See _expand_variables. src/platform_unix.c contained some duplicated logic about caching path results into static variables; this change set would have added to the complexity by calling the new path expansion function, in many different places. Seize the occasion for factoring. Do not change the meaning of PER_USER_DIRECTORY yet; I would like to do it, since it is confusing and inconsistent with per_user_directory (PER_USER_DIRECTORY is a relative path on Unix, while per_user_directory is absolute), but the actual semantics with respect to $HOME and $PEP_HOME is complicated and I do not want to break it. New API function per_user_relative_directory. Remove the ugly "reset" argument from unix_local_db (which was conditionally defined according to NDEBUG!), used to force path re-computation in the test suite after changing an environment variable so as to work in a new "home" directory. In the place of this reset argument add clear API functions to the engine for handling the cache. My quick grapping and IRC interaction confirm that nobody was using the functionality out of the engine test suite. Adapt the test suite to use the new API. Tentatively add caching and expansion functionality to android_system_db as well. --- db/Makefile | 7 +- src/Makefile | 7 +- src/pEpEngine.c | 10 + src/pEpEngine.h | 44 +++- src/pEp_internal.h | 5 - src/pgp_sequoia.c | 24 +- src/platform_unix.c | 483 ++++++++++++++++++++++++++++++++------- src/platform_unix.h | 10 +- src/platform_windows.cpp | 14 ++ test/src/Engine.cc | 32 ++- 10 files changed, 519 insertions(+), 117 deletions(-) diff --git a/db/Makefile b/db/Makefile index cd8362b9..af5fdbd0 100644 --- a/db/Makefile +++ b/db/Makefile @@ -18,8 +18,11 @@ system.db: create_system_db.sql $(DICOS) .PHONY: install install: system.db - mkdir -p $(DESTDIR)$(PER_MACHINE_DIRECTORY) - cp system.db $(DESTDIR)$(PER_MACHINE_DIRECTORY) + # Notice that the expansion of these make variables may still contain + # shell variable occurrences, to be expanded in their turn. This + # serves to leave more freedom to the deployment engineer. + mkdir -p "$(DESTDIR)$(PER_MACHINE_DIRECTORY)" + cp system.db "$(DESTDIR)$(PER_MACHINE_DIRECTORY)" .PHONY: clean clean: diff --git a/src/Makefile b/src/Makefile index b18b8eda..0c1af16b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -5,12 +5,15 @@ include ../Makefile.conf +# Notice the single quotes below: since user definitions can contain dollar +# signs it is important to prevent their expansion: shell variable references +# here must be expanded at run time, and not at compile time. ifdef PER_USER_DIRECTORY - EXTRA_MACROS+= -DPER_USER_DIRECTORY=$(PER_USER_DIRECTORY) + EXTRA_MACROS+= -DPER_USER_DIRECTORY='"$(PER_USER_DIRECTORY)"' endif ifdef PER_MACHINE_DIRECTORY - EXTRA_MACROS+= -DPER_MACHINE_DIRECTORY=\"$(PER_MACHINE_DIRECTORY)\" + EXTRA_MACROS+= -DPER_MACHINE_DIRECTORY='"$(PER_MACHINE_DIRECTORY)"' endif NO_SOURCE= diff --git a/src/pEpEngine.c b/src/pEpEngine.c index 31e7f9b6..94636964 100644 --- a/src/pEpEngine.c +++ b/src/pEpEngine.c @@ -28,6 +28,13 @@ DYNAMIC_API PEP_STATUS init( { PEP_STATUS status = PEP_STATUS_OK; + // Initialise the path cache. It is the state of the environment at this + // time that determines path names, unless the path cache is explicitly + // reset later. + status = reset_path_cache (); + if (status != PEP_STATUS_OK) + return status; + bool in_first = false; assert(sqlite3_threadsafe()); @@ -143,6 +150,9 @@ DYNAMIC_API void release(PEP_SESSION session) if (session) { free_Sync_state(session); + // Clear the path cache, releasing a little memory. + clear_path_cache (); + if (session->db) { pEp_finalize_sql_stmts(session); if (session->db) { diff --git a/src/pEpEngine.h b/src/pEpEngine.h index 2c97df92..e8300253 100644 --- a/src/pEpEngine.h +++ b/src/pEpEngine.h @@ -182,6 +182,8 @@ typedef enum { PEP_MESSAGE_IGNORE = 0xff03, PEP_CANNOT_CONFIG = 0xff04, + PEP_UNBOUND_ENVIRONMENT_VARIABLE = -8, + PEP_PATH_SYNTAX_ERROR = -7, PEP_RECORD_NOT_FOUND = -6, PEP_CANNOT_CREATE_TEMP_FILE = -5, PEP_ILLEGAL_VALUE = -4, @@ -189,7 +191,7 @@ typedef enum { PEP_OUT_OF_MEMORY = -2, PEP_UNKNOWN_ERROR = -1, - PEP_VERSION_MISMATCH = -7, + PEP_VERSION_MISMATCH = -9, } PEP_STATUS; /** @@ -1757,7 +1759,21 @@ DYNAMIC_API PEP_STATUS is_pEp_user(PEP_SESSION session, pEp_identity *identity, bool* is_pEp); + /** + * + * + * @brief Returns the directory for pEp management db as a relative + * path from the home directory (or the pEp home directory) + * + * @retval char* relative pathname + * @retval NULL on failure + * + */ + +DYNAMIC_API const char *per_user_relative_directory(void); + + /** * * * @brief Returns the directory for pEp management db @@ -1949,6 +1965,32 @@ DYNAMIC_API PEP_STATUS get_replacement_fpr( */ DYNAMIC_API PEP_STATUS set_as_pEp_user(PEP_SESSION session, pEp_identity* user); +/** + * + * + * @brief Recompute pathnames according to the current value of the + * environment. This is automatically called by init on + * platforms where a pathname cache exists, but it is possible + * to call it again explicitly in case the paths need to be + * recomputed from updated environment variables; the intended + * use case is test suites, working with temporary + * directories. + * + * @retval PEP_STATUS_OK success + * @retval PEP_UNBOUND_ENVIRONMENT_VARIABLE unknown variable referenced + * @retval PEP_PATH_SYNTAX_ERROR invalid syntax in argument + * @retval PEP_OUT_OF_MEMORY out of memory + * + */ +DYNAMIC_API PEP_STATUS reset_path_cache(void); + + /** + * + * + * @brief Empty the path cache, releasing resources. + * + */ +DYNAMIC_API void clear_path_cache(void); #ifdef __cplusplus } diff --git a/src/pEp_internal.h b/src/pEp_internal.h index a7bcd34e..c4090d23 100644 --- a/src/pEp_internal.h +++ b/src/pEp_internal.h @@ -77,12 +77,7 @@ #else // UNIX #define _POSIX_C_SOURCE 200809L #include -#ifdef NDEBUG #define LOCAL_DB unix_local_db() -#else -#define LOCAL_DB unix_local_db(false) -#define LOCAL_DB_RESET unix_local_db(true) -#endif #ifdef ANDROID #define SYSTEM_DB android_system_db() #else diff --git a/src/pgp_sequoia.c b/src/pgp_sequoia.c index e1e969c6..95807f07 100644 --- a/src/pgp_sequoia.c +++ b/src/pgp_sequoia.c @@ -451,28 +451,24 @@ PEP_STATUS pgp_init(PEP_SESSION session, bool in_first) | SQLITE_OPEN_PRIVATECACHE, NULL); #else - // Create the home directory. - char *home_env = NULL; -#ifndef NDEBUG - home_env = getenv("PEP_HOME"); -#endif - -#define PEP_KEYS_PATH "/.pEp/keys.db" - - if (!home_env) - home_env = getenv("HOME"); - if (!home_env) - ERROR_OUT(NULL, PEP_INIT_CRYPTO_LIB_INIT_FAILED, "HOME unset"); + // Compute a string containing the DB absolute path name. +#define PEP_KEYS_RELATIVE_FILENAME "keys.db" + const char *directory = per_user_directory(); // Create the DB and initialize it. - size_t path_size = strlen(home_env) + sizeof(PEP_KEYS_PATH); + size_t path_size + = (strlen(directory) + + 1 /* '/' */ + + strlen(PEP_KEYS_RELATIVE_FILENAME) + + 1 /* '\0' */); char *path = (char *) calloc(path_size, 1); assert(path); if (!path) ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory"); - int r = snprintf(path, path_size, "%s" PEP_KEYS_PATH, home_env); + int r = snprintf(path, path_size, "%s/%s", + directory, PEP_KEYS_RELATIVE_FILENAME); assert(r >= 0 && r < path_size); if (r < 0) { free(path); diff --git a/src/platform_unix.c b/src/platform_unix.c index 5b67774c..4f37c4b0 100644 --- a/src/platform_unix.c +++ b/src/platform_unix.c @@ -25,6 +25,7 @@ #include #include +#include "pEpEngine.h" /* For PEP_STATUS */ #include "platform_unix.h" #include "dynamic_api.h" @@ -99,29 +100,28 @@ long int random(void) return nrand48(xsubi); } */ -const char *android_system_db(void) +/* This is a non-caching function: see the comments in "Internal path caching + functionality" below. */ +static char *_android_system_db(void) { - static char buffer[MAX_PATH]; - static bool done = false; - - if (!done) { - char *tw_env; - if(tw_env = getenv("TRUSTWORDS")){ - char *p = stpncpy(buffer, tw_env, MAX_PATH); - ssize_t len = MAX_PATH - (p - buffer) - 2; - - if (len < strlen(SYSTEM_DB_FILENAME)) { - assert(0); - return NULL; - } + char *buffer = malloc (MAX_PATH); + if (buffer == NULL) + return NULL; + + char *tw_env; + if(tw_env = getenv("TRUSTWORDS")){ + char *p = stpncpy(buffer, tw_env, MAX_PATH); + ssize_t len = MAX_PATH - (p - buffer) - 2; - *p++ = '/'; - strncpy(p, SYSTEM_DB_FILENAME, len); - done = true; - }else{ + if (len < strlen(SYSTEM_DB_FILENAME)) { + assert(0); return NULL; } + *p++ = '/'; + strncpy(p, SYSTEM_DB_FILENAME, len); + }else{ + return NULL; } return buffer; } @@ -341,7 +341,383 @@ static void _move(const char *o, const char *ext, const char *n) free(_new); } -#ifndef NDEBUG +/** + * @internal + * + * + * + * @brief Return a malloc-allocated copy of the given string, or (this + * is the added functionality with respect to the standard + * strdup) a malloc-allocated copy of "" if the argument is + * NULL. + * + * @param[in] *original constchar + * @retval NULL out of memory + * @retval non-NULL malloc-allocated buffer + */ +static char *_strdup_or_NULL(const char *original) +{ + if (original == NULL) + original = ""; + return strdup (original); +} + + +/* + * Environment variable expansion + * ********************************************************************** + */ + +/* The state of a DFA implementing variable recognition in _expand_variables , + below. */ +enum _expand_variable_state { + _expand_variable_state_non_variable, + _expand_variable_state_after_dollar, + _expand_variable_state_after_backslash, + _expand_variable_state_in_variable +}; + +/** + * @internal + * + * + * + * @brief Set a malloc-allocated '\0'-terminated string which is + * a copy of the argument with shell variables expanded, where + * variable references use Unix shell-style syntax $VARIABLE. + * Notice that the alternative syntax ${VARIABLE} is not + * supported. + * See [FIXME: deployment-engineer documentation]. + * + * @param[in] string_with_variables char * + * @param[out] copy_with_variables_expanded char ** + * @retval PEP_STATUS_OK success + * @retval PEP_UNBOUND_ENVIRONMENT_VARIABLE unknown variable referenced + * @retval PEP_PATH_SYNTAX_ERROR invalid syntax in argument + * @retval PEP_OUT_OF_MEMORY out of memory + * + */ +static PEP_STATUS _expand_variables(char **out, + const char *string_with_variables) +{ + PEP_STATUS res = PEP_STATUS_OK; + size_t in_length = strlen(string_with_variables); + const char *variable_name_beginning; /* This points within the input. */ + char *variable_name_copy = NULL /* we free on error. */; + size_t allocated_size +#ifdef NDEBUG + = 1024; +#else + = 1 /* Notice that 0 is incorrect: this grows by doubling. */; +#endif // #ifdef NDEBUG + int out_index = 0; /* The out index is also the used out size */ + const char *in = string_with_variables; + /* In the pEp engine we adopt the convention of "" behaving the same as + NULL. Notice that we never free this, so it is not a problem if this + string is not malloc-allocated. */ + if (in == NULL) + in = ""; + /* We free on error. */ + * out = NULL ; + + /* Recognise a variable according to POSIX syntax which, luckily for us, + only allows for letters, digits and underscores -- The first character + may not be a digit... */ +#define VALID_FIRST_CHARACTER_FOR_VARIABLE(c) \ + ( ((c) >= 'a' && (c) <= 'z') \ + || ((c) >= 'A' && (c) <= 'Z') \ + || ((c) == '_')) + /* ...But characters after the first may be. */ +#define VALID_NON_FIRST_CHARACTER_FOR_VARIABLE(c) \ + ( VALID_FIRST_CHARACTER_FOR_VARIABLE(c) \ + || ((c) >= '0' && (c) <= '9')) + + /* Append the char argument to the result string, automatically resizing it + if needed. */ +#define EMIT_CHAR(c) \ + do \ + { \ + if (out_index == allocated_size) { \ + allocated_size *= 2; \ + /*fprintf (stderr, "ALLOCATED SIZE: %i -> %i\n", (int) allocated_size / 2, (int) allocated_size);*/\ + * out = realloc (* out, allocated_size); \ + if (* out == NULL) \ + FATAL (PEP_OUT_OF_MEMORY, \ + "cannot grow buffer"); \ + } \ + (* out) [out_index] = (c); \ + out_index ++; \ + } \ + while (false) + + /* Append the string argument to the output string, automatically resizing + it as needed. */ +#define EMIT_STRING(s) \ + do { \ + const char *p; \ + for (p = (s); (* p) != '\0'; p ++) \ + EMIT_CHAR (* p); \ + } while (false) + + /* Emit the expansion of the environment variable whose name is delimited on + the left by variable_name_beginning and on the right by the character + coming right *before* in. Fail fatally if the variable is unbound. + The expansion is emitted by appending to the result string, automatically + resizing it as needed. */ +#define EMIT_CURRENT_VARIABLE \ + do { \ + const char *variable_past_end = in; \ + size_t variable_name_length \ + = variable_past_end - variable_name_beginning; \ + strcpy (variable_name_copy, variable_name_beginning); \ + variable_name_copy [variable_name_length] = '\0'; \ + const char *variable_value = getenv (variable_name_copy); \ + if (variable_value == NULL) \ + FATAL_NAME (PEP_UNBOUND_ENVIRONMENT_VARIABLE, \ + "unbound variable", variable_name_copy); \ + EMIT_STRING (variable_value); \ + } while (false) + +#define FATAL(code, message) \ + do { res = (code); goto failure; } while (false) +#define FATAL_NAME(code, message, name) \ + FATAL((code), (message)) + + /* We can allocate buffers, now that we have FATAL. */ + if ((variable_name_copy + = malloc (in_length + 1 /* a safe upper bound for a sub-string. */)) + == NULL) + FATAL (PEP_OUT_OF_MEMORY, "out of mmeory"); + if (((* out) = malloc (allocated_size)) == NULL) + FATAL (PEP_OUT_OF_MEMORY, "out of memory"); + + /* This logic implements a DFA. */ + enum _expand_variable_state s = _expand_variable_state_non_variable; + char c; + while (true) { + c = * in; + switch (s) { + case _expand_variable_state_non_variable: + if (c == '$') { + variable_name_beginning = in + 1; + s = _expand_variable_state_after_dollar; + } + else if (c == '\\') + s = _expand_variable_state_after_backslash; + else /* This includes c == '\0'. */ + EMIT_CHAR (c); + if (c == '\0') + goto success; + break; + + case _expand_variable_state_after_backslash: + if (c == '$' || c == '\\') { + EMIT_CHAR (c); + s = _expand_variable_state_non_variable; + } + else if (c == '\0') /* Just to give a nicer error message */ + FATAL (PEP_PATH_SYNTAX_ERROR, "trailing unescaped '\\'"); + else /* this would be correct even with '\0' */ + FATAL (PEP_PATH_SYNTAX_ERROR, "invalid escape"); + break; + + case _expand_variable_state_after_dollar: + if (VALID_FIRST_CHARACTER_FOR_VARIABLE (c)) + s = _expand_variable_state_in_variable; + else if (c == '\0') /* Just to give a nicer error message */ + FATAL (PEP_PATH_SYNTAX_ERROR,"trailing '$' character"); + else if (c == '\\') /* Just to give a nicer error message */ + FATAL (PEP_PATH_SYNTAX_ERROR, + "empty variable name followed by escape"); + else if (c == '$') /* Just to give a nicer error message */ + FATAL (PEP_PATH_SYNTAX_ERROR, "two consecutive '$' characters"); + else + FATAL (PEP_PATH_SYNTAX_ERROR, + "invalid variable first character after '$'"); + break; + + case _expand_variable_state_in_variable: + if (VALID_NON_FIRST_CHARACTER_FOR_VARIABLE (c)) + /* Do nothing */; + else if (c == '\\') { + EMIT_CURRENT_VARIABLE; + s = _expand_variable_state_after_backslash; + } + else { + /* This includes c == '\0'. */ + EMIT_CURRENT_VARIABLE; + EMIT_CHAR (c); + if (c == '\0') + goto success; + else + s = _expand_variable_state_non_variable; + } + break; + + default: + FATAL (PEP_STATEMACHINE_INVALID_STATE /* Slightly questionable: this + should be an assertion. */, + "impossible DFA state"); + } /* switch */ + + in ++; + } /* while */ + + success: + free(variable_name_copy); + return res; + + failure: + free(* out); + * out = NULL; + goto success; +#undef VALID_FIRST_CHARACTER_FOR_VARIABLE +#undef VALID_NON_FIRST_CHARACTER_FOR_VARIABLE +#undef EMIT_CHAR +#undef EMIT_STRING +#undef EMIT_CURRENT_VARIABLE +#undef FATAL +#undef FATAL_NAME +} + + +/* + * Internal path caching functionality + * ********************************************************************** + */ + +/* Several functions in this compilation unit return paths to files or + * directories, always returning pointers to the same internally managed memory + * at every call. + * + * The cache is filled at engine initialisation, using the value of environment + * variables at initialisation time: after that point no out-of-memory errors + * are possible, until reset. + * + * In debugging mode the cache can be "reset", with every path recomputed on + * demand according to the current environment. + */ + +/* For each path we define: + - a static char * variable pointing to the cached value; + - a prototype for a static function returning a malloc-allocated copy of + the value, unexapanded, not using the cache (to be defined below by hand); + - a public API function returning a pointer to cached memory. */ +#define DEFINE_CACHED_PATH(name) \ + /* A static variable holding the cached path, or NULL. */ \ + static char *_ ## name ## _cache = NULL; \ + \ + /* A prototype for the hand-written function returning the \ + computed value for the path, without using the cache and \ + without expanding variables. */ \ + static char *_ ## name(void); \ + \ + /* The public version of the function, using the cache. */ \ + DYNAMIC_API const char *name(void) \ + { \ + if (_ ## name ## _cache == NULL) { \ + /* It is unusual and slightly bizarre than a path is \ + accessed before initialisation; however it can happen \ + in the engine test suite. */ \ + fprintf (stderr, \ + "WARNING: accessing %s before its cache is set:" \ + " this should not happen in production.\n", \ + #name); \ + reset_path_cache(); \ + } \ + return _ ## name ## _cache; \ + } + +/* Define cached paths using the functionality above: */ +DEFINE_CACHED_PATH (per_user_relative_directory) +DEFINE_CACHED_PATH (per_user_directory) +DEFINE_CACHED_PATH (per_machine_directory) +#ifdef ANDROID + DEFINE_CACHED_PATH (android_system_db) +#endif +DEFINE_CACHED_PATH (unix_system_db) +DEFINE_CACHED_PATH (unix_local_db) + +/* Free every cache variable and re-initialise it to NULL: this + re-initialisation is important when this function is used here, + internally, as part of cleanup on errors. */ +DYNAMIC_API void clear_path_cache (void) +{ +#define UNSET(name) \ + do { \ + free((void *) _ ## name ## _cache); \ + (_ ## name ## _cache) = NULL; \ + } while (false) + + UNSET (per_user_relative_directory); + UNSET (per_user_directory); + UNSET (per_machine_directory); +#ifdef ANDROID + UNSET (android_system_db); +#endif + UNSET (unix_system_db); + UNSET (unix_local_db); + +#undef UNSET +} + +DYNAMIC_API PEP_STATUS reset_path_cache(void) +{ + PEP_STATUS res = PEP_STATUS_OK; + +#define SET_OR_FAIL(name) \ + do { \ + unexpanded_path = (_ ## name)(); \ + if (unexpanded_path == NULL) { \ + res = PEP_OUT_OF_MEMORY; \ + goto free_everything_and_fail; \ + } \ + res = _expand_variables(& _ ## name ## _cache, unexpanded_path); \ + if (res != PEP_STATUS_OK) \ + goto free_everything_and_fail; \ + /* Clear unxpanded_path for the next call of SET_OR_FAIL. */ \ + free((void *) unexpanded_path); \ + unexpanded_path = NULL; \ + } while (false) + + /* In case this is not the first invocation, start by releasing memory. */ + clear_path_cache (); + + const char *unexpanded_path = NULL; + + SET_OR_FAIL (per_user_relative_directory); + SET_OR_FAIL (per_user_directory); + SET_OR_FAIL (per_machine_directory); +#ifdef ANDROID + SET_OR_FAIL (android_system_db); +#endif + SET_OR_FAIL (unix_system_db); + SET_OR_FAIL (unix_local_db); + + return res; + + free_everything_and_fail: + free((void *) unexpanded_path); + clear_path_cache (); + return res; + +#undef SET_OR_FAIL +} + + +/** + * @internal + * + * + * + * @brief TODO + * + */ +static char *_per_user_relative_directory(void) +{ + return _strdup_or_NULL(PER_USER_DIRECTORY); +} + /** * @internal * @@ -349,27 +725,10 @@ static void _move(const char *o, const char *ext, const char *n) * * @brief TODO * - * @param[in] reset int - * */ -static const char *_per_user_directory(int reset) -#else -static const char *_per_user_directory(void) -#endif +static char *_per_user_directory(void) { - static char *path = NULL; - -#ifdef NDEBUG - if (path) - return path; -#else - if (path && !reset) - return path; - else if (path) { - free(path); - path = NULL; - } -#endif + char *path = NULL; const char *home = NULL; #ifndef NDEBUG @@ -401,32 +760,9 @@ error: return NULL; } -#ifdef NDEBUG -const char *unix_local_db(void) -#else -const char *unix_local_db(int reset) -#endif +char *_unix_local_db(void) { - static char *path = NULL; -#ifdef NDEBUG - if (path) -#else - if (path && !reset) -#endif - return path; - - const char* pathret = NULL; -#ifndef NDEBUG - pathret = _per_user_directory(reset); -#else - pathret = _per_user_directory(); -#endif - - if (!pathret) - return NULL; - - path = strdup(pathret); - assert(path); + char* path = (char *) _per_user_directory() /* This memory is not shared. */; if (!path) return NULL; @@ -538,26 +874,15 @@ the_end: return path; } -DYNAMIC_API const char *per_user_directory(void) { -#ifdef NDEBUG - return _per_user_directory(); -#else - return _per_user_directory(false); -#endif -} - -DYNAMIC_API const char *per_machine_directory(void) -{ - return PER_MACHINE_DIRECTORY; +static char *_per_machine_directory(void) { + return _strdup_or_NULL(PER_MACHINE_DIRECTORY); } -const char *unix_system_db(void) +char *_unix_system_db(void) { - static char *path = NULL; - if (path) - return path; + char *path = NULL; - path = strdup(per_machine_directory()); + path = _per_machine_directory() /* Use this fresh copy. */; assert(path); if (!path) return NULL; diff --git a/src/platform_unix.h b/src/platform_unix.h index 0bf9a4fc..63dfe29d 100644 --- a/src/platform_unix.h +++ b/src/platform_unix.h @@ -41,25 +41,19 @@ extern "C" { #endif -#ifdef NDEBUG -const char *unix_local_db(void); -#else /** * * * @brief TODO * - * @param[in] reset int - * */ -const char *unix_local_db(int reset); -#endif +const char *unix_local_db(void); + /** * * * @brief TODO * - * */ const char *unix_system_db(void); diff --git a/src/platform_windows.cpp b/src/platform_windows.cpp index 34441897..3db377db 100644 --- a/src/platform_windows.cpp +++ b/src/platform_windows.cpp @@ -22,6 +22,8 @@ #include #include +#include "pEpEngine.h" // just for PEP_STATUS + #define LOCAL_DB_FILENAME "management.db" #define SYSTEM_DB_FILENAME "system.db" #define KEYS_DB "keys.db" @@ -458,4 +460,16 @@ void log_output_debug(const char *title, OutputDebugStringA(str); } +DYNAMIC_API PEP_STATUS reset_path_cache(void) +{ + /* Do nothing and return success. This only exists for API compatibility + with the Unix version. */ + return PEP_STATUS_OK; +} + +DYNAMIC_API void clear_path_cache (void) +{ + /* Like reset_path_cache, do nothing. */ +} + } // "C" diff --git a/test/src/Engine.cc b/test/src/Engine.cc index 45c8172f..ce951b2f 100644 --- a/test/src/Engine.cc +++ b/test/src/Engine.cc @@ -19,6 +19,7 @@ #include "TestUtilities.h" #include "Engine.h" #include "pEpTestStatic.h" +#include "pEpEngine_internal.h" #include #include "TestConstants.h" @@ -91,16 +92,34 @@ void Engine::start() { if (success != 0) throw std::runtime_error("SETUP: Cannot set engine_home for init."); - unix_local_db(true); - - PEP_STATUS status = init(&session, cached_messageToSend, cached_inject_sync_event, cached_ensure_passphrase); + PEP_STATUS status; + status = reset_path_cache(); + assert(status == PEP_STATUS_OK); + +FILE *f = fopen ("/home/luca/pep-src/pep-engine/PER_USER_DIRECTORY", "w"); + fprintf (f, "* per_user_directory (): %s\n", per_user_directory ()); +fclose (f); +f = fopen ("/home/luca/pep-src/pep-engine/PER_MACHINE_DIRECTORY", "w"); + fprintf (f, "* per_machine_directory (): %s\n", per_machine_directory ()); +fclose (f); +fprintf (stderr, "* per_user_directory (): %s\n", per_user_directory ()); +fprintf (stderr, "* per_user_directory (): %s\n", per_user_directory ()); + + status = init(&session, cached_messageToSend, cached_inject_sync_event, cached_ensure_passphrase); assert(status == PEP_STATUS_OK); assert(session); } void Engine::copy_conf_file_to_test_dir(const char* dest_path, const char* conf_orig_path, const char* conf_dest_name) { - string conf_dest_path = string(dest_path) + "/.pEp/"; - + string conf_dest_path + = (string(dest_path) + + string("/") + + string(per_user_relative_directory ()) + + string("/")); +fprintf (stderr, "COPYING %s from %s to %s\n", + dest_path, + conf_orig_path, + conf_dest_path.c_str ()); struct stat pathinfo; if(stat(conf_dest_path.c_str(), &pathinfo) != 0) { @@ -149,5 +168,6 @@ void Engine::shut_down() { if (success != 0) throw std::runtime_error("RESTORE: Cannot reset home directory! Either set environment variable manually back to your home, or quit this session!"); - unix_local_db(true); + PEP_STATUS status = reset_path_cache(); + assert(status == PEP_STATUS_OK); } From ea414ac15f5816fe0140028c6d7b409e5dfcf892 Mon Sep 17 00:00:00 2001 From: Luca Saiu Date: Wed, 8 Sep 2021 16:24:27 +0200 Subject: [PATCH 50/60] 956: remove debugging prints, improve comments, fix the test suite (!) Fix some test suite failures due to subtle interactions with the debugging prints I forgot to remove. Add a some important comments and a few minor cosmetic improvements. --- src/pEpEngine.h | 16 ++++++++++++++-- src/platform_unix.c | 5 ++++- src/platform_unix.h | 14 ++++++++++++++ test/src/Engine.cc | 9 --------- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/pEpEngine.h b/src/pEpEngine.h index e8300253..1aa94503 100644 --- a/src/pEpEngine.h +++ b/src/pEpEngine.h @@ -1765,6 +1765,9 @@ DYNAMIC_API PEP_STATUS is_pEp_user(PEP_SESSION session, * * @brief Returns the directory for pEp management db as a relative * path from the home directory (or the pEp home directory) + * The returned pointed refers memory managed by + * the engine, which will remain valid until + * the next call to reset_path_cache. * * @retval char* relative pathname * @retval NULL on failure @@ -1776,7 +1779,10 @@ DYNAMIC_API const char *per_user_relative_directory(void); /** * * - * @brief Returns the directory for pEp management db + * @brief Returns the directory for pEp management db. + * The returned pointed refers memory managed by + * the engine, which will remain valid until + * the next call to reset_path_cache. * * @retval char* path to actual per user directory * @retval NULL on failure @@ -1791,6 +1797,9 @@ DYNAMIC_API const char *per_user_directory(void); * * * @brief Returns the directory for pEp system db + * The returned pointed refers memory managed by + * the engine, which will remain valid until + * the next call to reset_path_cache. * * @retval char* path to actual per machine directory * @retval NULL on failure @@ -1987,7 +1996,10 @@ DYNAMIC_API PEP_STATUS reset_path_cache(void); /** * * - * @brief Empty the path cache, releasing resources. + * @brief Empty the path cache, releasing resources. This may invalidate + * the memory used by the results of per_user_relative_directory, + * per_user_directory, per_machine_directory, android_system_db, + * unix_system_db, unix_local_db. * */ DYNAMIC_API void clear_path_cache(void); diff --git a/src/platform_unix.c b/src/platform_unix.c index 4f37c4b0..46236bf4 100644 --- a/src/platform_unix.c +++ b/src/platform_unix.c @@ -350,6 +350,7 @@ static void _move(const char *o, const char *ext, const char *n) * is the added functionality with respect to the standard * strdup) a malloc-allocated copy of "" if the argument is * NULL. + * Return NULL only in case of an out-of-memory error. * * @param[in] *original constchar * @retval NULL out of memory @@ -625,6 +626,7 @@ static PEP_STATUS _expand_variables(char **out, #name); \ reset_path_cache(); \ } \ + assert (_ ## name ## _cache != NULL); \ return _ ## name ## _cache; \ } @@ -680,7 +682,8 @@ DYNAMIC_API PEP_STATUS reset_path_cache(void) unexpanded_path = NULL; \ } while (false) - /* In case this is not the first invocation, start by releasing memory. */ + /* Start by releasing memory, which is needed in case this is not the first + invocation. */ clear_path_cache (); const char *unexpanded_path = NULL; diff --git a/src/platform_unix.h b/src/platform_unix.h index 63dfe29d..955462dd 100644 --- a/src/platform_unix.h +++ b/src/platform_unix.h @@ -45,6 +45,9 @@ extern "C" { * * * @brief TODO + * The returned pointed refers memory managed by + * the engine, which will remain valid until + * the next call to reset_path_cache. * */ const char *unix_local_db(void); @@ -53,6 +56,9 @@ const char *unix_local_db(void); * * * @brief TODO + * The returned pointed refers memory managed by + * the engine, which will remain valid until + * the next call to reset_path_cache. * */ const char *unix_system_db(void); @@ -69,6 +75,14 @@ char *stpcpy(char *, const char *); // Only the lowest 31 bits are filled randomly. //long int random(void); +/* + * + * + * @brief TODO + * The returned pointed refers memory managed by + * the engine, which will remain valid until + * the next call to reset_path_cache. + */ const char *android_system_db(void); #define SYSTEM_DB android_system_db() diff --git a/test/src/Engine.cc b/test/src/Engine.cc index ce951b2f..1911597c 100644 --- a/test/src/Engine.cc +++ b/test/src/Engine.cc @@ -96,15 +96,6 @@ void Engine::start() { status = reset_path_cache(); assert(status == PEP_STATUS_OK); -FILE *f = fopen ("/home/luca/pep-src/pep-engine/PER_USER_DIRECTORY", "w"); - fprintf (f, "* per_user_directory (): %s\n", per_user_directory ()); -fclose (f); -f = fopen ("/home/luca/pep-src/pep-engine/PER_MACHINE_DIRECTORY", "w"); - fprintf (f, "* per_machine_directory (): %s\n", per_machine_directory ()); -fclose (f); -fprintf (stderr, "* per_user_directory (): %s\n", per_user_directory ()); -fprintf (stderr, "* per_user_directory (): %s\n", per_user_directory ()); - status = init(&session, cached_messageToSend, cached_inject_sync_event, cached_ensure_passphrase); assert(status == PEP_STATUS_OK); assert(session); From f36a23a50d0ffd350f2c4598da246b0c9813d877 Mon Sep 17 00:00:00 2001 From: Luca Saiu Date: Wed, 8 Sep 2021 16:53:14 +0200 Subject: [PATCH 51/60] ENGINE-957: fix off-by-one bug in the test suite Make the found array have 4 elements instead of 3. src/GroupEncryptionTest.cc:2489:18: warning: iteration 3 invokes undefined behavior [-Waggressive-loop-optimizations] 2489 | found[i] = false; | ~~~~~~~~~^~~~~~~ src/GroupEncryptionTest.cc:2488:23: note: within this loop 2488 | for (int i = 0; i < 4; i++) | ~~^~~ --- test/src/GroupEncryptionTest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/src/GroupEncryptionTest.cc b/test/src/GroupEncryptionTest.cc index ae4de663..91a10500 100644 --- a/test/src/GroupEncryptionTest.cc +++ b/test/src/GroupEncryptionTest.cc @@ -2358,7 +2358,7 @@ TEST_F(GroupEncryptionTest, check_protocol_group_create_different_own_identity_m const char* member_addrs[] = {member_1_address, member_2_address, member_3_address, member_4_address}; const char* member_fprs[] = {member_1_fpr, member_2_fpr, member_3_fpr, member_4_fpr}; - bool found[] = {false, false, false}; + bool found[] = {false, false, false, false}; int count = 0; for (member_list* curr_member = group1_info->members; From 8bc79db685199c6e36bfb118f623e0e02f4f5863 Mon Sep 17 00:00:00 2001 From: Luca Saiu Date: Wed, 8 Sep 2021 18:30:23 +0200 Subject: [PATCH 52/60] ENGINE-558: scan from_address right-to-left searching for '@' This should be enough to solve the problem. --- src/message_api.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/message_api.c b/src/message_api.c index e2e3c8ea..4802a9bf 100644 --- a/src/message_api.c +++ b/src/message_api.c @@ -775,11 +775,19 @@ static PEP_STATUS generate_message_id(message* msg) { size_t buf_len = 2; // NUL + @ char* from_addr = msg->from->address; - char* domain_ptr = strstr(from_addr, "@"); - if (!domain_ptr || *(domain_ptr + 1) == '\0') - domain_ptr = "localhost"; - else - domain_ptr++; + + /* Look for the *last* occurrence of '@' within the string beginning at + from_addr; if no '@' exists or if it is at the very end then keep the + "localhost" default as domain. */ + char *p; + char *domain_ptr = "localhost"; + for (p = from_addr + strlen (from_addr); p >= from_addr; p --) + if (* p == '@') + { + if (p [1] != '\0') + domain_ptr = p + 1; + break; + } buf_len += strlen(domain_ptr); From 2e934f3706cd4a3f4ed40a2d38e0ddd671cb4ddf Mon Sep 17 00:00:00 2001 From: Luca Saiu Date: Sun, 12 Sep 2021 21:41:50 +0200 Subject: [PATCH 53/60] ENGINE-958: test suite change: redefine ASSERT_OK --- test/src/TestUtilities.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/src/TestUtilities.h b/test/src/TestUtilities.h index 83b4e023..b4c3f32f 100644 --- a/test/src/TestUtilities.h +++ b/test/src/TestUtilities.h @@ -11,6 +11,7 @@ #include "pEpEngine.h" #include "message_api.h" #include "mime.h" +#include "status_to_string.h" #include @@ -37,7 +38,14 @@ char* get_new_uuid(); */ #ifndef ASSERT_OK -#define ASSERT_OK ASSERT_EQ(status, PEP_STATUS_OK) +#define ASSERT_OK \ + do { \ + if (status != PEP_STATUS_OK) \ + std::cout << "status is " << status << " (" \ + << pEp_status_to_string(status) << ")" \ + << std::endl; \ + ASSERT_EQ(status, PEP_STATUS_OK); \ + } while (false) #endif #ifndef ASSERT_NOTNULL From 9e7a1109cdf9a1d369f6da877a4520c1a65f0d6c Mon Sep 17 00:00:00 2001 From: Luca Saiu Date: Sun, 12 Sep 2021 22:01:00 +0200 Subject: [PATCH 54/60] ENGINE-619: add test case --- test/src/Engine619Test.cc | 467 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 467 insertions(+) create mode 100644 test/src/Engine619Test.cc diff --git a/test/src/Engine619Test.cc b/test/src/Engine619Test.cc new file mode 100644 index 00000000..779ee77a --- /dev/null +++ b/test/src/Engine619Test.cc @@ -0,0 +1,467 @@ +#include +#include +#include + +#include "internal_format.h" + +#include "TestUtilities.h" +#include "TestConstants.h" +#include "Engine.h" + +#include + + +namespace { + + //The fixture for Engine619Test + class Engine619Test : public ::testing::Test { + public: + Engine* engine; + PEP_SESSION session; + + protected: + // You can remove any or all of the following functions if its body + // is empty. + Engine619Test() { + // You can do set-up work for each test here. + test_suite_name = ::testing::UnitTest::GetInstance()->current_test_info()->GTEST_SUITE_SYM(); + test_name = ::testing::UnitTest::GetInstance()->current_test_info()->name(); + test_path = get_main_test_home_dir() + "/" + test_suite_name + "/" + test_name; + std::cout << "QQQQ " << get_main_test_home_dir() << "," << test_suite_name << "," << test_name << "\n"; + } + + ~Engine619Test() override { + // You can do clean-up work that doesn't throw exceptions here. + } + + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: + + void SetUp() override { + // Code here will be called immediately after the constructor (right + // before each test). + + // Leave this empty if there are no files to copy to the home directory path + std::vector> init_files = std::vector>(); + + // Get a new test Engine. + engine = new Engine(test_path); + ASSERT_NOTNULL(engine); + + // Ok, let's initialize test directories etc. + engine->prep(NULL, NULL, NULL, init_files); + + // Ok, try to start this bugger. + engine->start(); + ASSERT_NOTNULL(engine->session); + session = engine->session; + + // Engine is up. Keep on truckin' + } + + void TearDown() override { + // Code here will be called immediately after each test (right + // before the destructor). + engine->shut_down(); + delete engine; + engine = NULL; + session = NULL; + } + + private: + const char* test_suite_name; + const char* test_name; + string test_path; + // Objects declared here can be used by all tests in the Engine619Test suite. + + }; + +} // namespace + +// TEST_F(Engine619Test, check_internal_format) { +// const char *data = "simulated data"; +// size_t data_size = strlen(data) + 1; + +// char *code; +// size_t code_size; + +// // test PGP keys + +// PEP_STATUS status = encode_internal(data, data_size, "application/pgp-keys", &code, &code_size); +// ASSERT_EQ(status, PEP_STATUS_OK); + +// ASSERT_EQ(code_size, data_size + 4); + +// ASSERT_EQ(code[0], 0); +// ASSERT_EQ(code[1], 'K'); +// ASSERT_EQ(code[2], 2); + +// ASSERT_STREQ(code + 4, data); + +// // decode + +// char *value; +// size_t size; +// char *mime_type; + +// status = decode_internal(code, code_size, &value, &size, &mime_type); +// ASSERT_EQ(status, PEP_STATUS_OK); + +// ASSERT_EQ(size, data_size); +// ASSERT_STREQ(value, data); +// ASSERT_STREQ(mime_type, "application/pgp-keys"); + +// free(value); +// free(code); + +// // test Sync + +// status = encode_internal(data, data_size, "application/pEp.sync", &code, &code_size); +// ASSERT_EQ(status, PEP_STATUS_OK); + +// ASSERT_EQ(code_size, data_size + 4); + +// ASSERT_EQ(code[0], 0); +// ASSERT_EQ(code[1], 'S'); +// ASSERT_EQ(code[2], 0); + +// ASSERT_STREQ(code + 4, data); + +// // decode + +// status = decode_internal(code, code_size, &value, &size, &mime_type); +// ASSERT_EQ(status, PEP_STATUS_OK); + +// ASSERT_EQ(size, data_size); +// ASSERT_STREQ(value, data); +// ASSERT_STREQ(mime_type, "application/pEp.sync"); + +// free(value); +// free(code); + +// // test Distribution + +// status = encode_internal(data, data_size, "application/pEp.distribution", &code, &code_size); +// ASSERT_EQ(status, PEP_STATUS_OK); + +// ASSERT_EQ(code_size, data_size + 4); + +// ASSERT_EQ(code[0], 0); +// ASSERT_EQ(code[1], 'D'); +// ASSERT_EQ(code[2], 0); + +// ASSERT_STREQ(code + 4, data); + +// // decode + +// status = decode_internal(code, code_size, &value, &size, &mime_type); +// ASSERT_EQ(status, PEP_STATUS_OK); + +// ASSERT_EQ(size, data_size); +// ASSERT_STREQ(value, data); +// ASSERT_STREQ(mime_type, "application/pEp.distribution"); + +// free(value); +// free(code); + +// // test PGP signature + +// status = encode_internal(data, data_size, "application/pgp-signature", &code, &code_size); +// ASSERT_EQ(status, PEP_STATUS_OK); + +// ASSERT_EQ(code_size, data_size + 4); + +// ASSERT_EQ(code[0], 0); +// ASSERT_EQ(code[1], 'A'); +// ASSERT_EQ(code[2], 2); + +// ASSERT_STREQ(code + 4, data); + +// // decode + +// status = decode_internal(code, code_size, &value, &size, &mime_type); +// ASSERT_EQ(status, PEP_STATUS_OK); + +// ASSERT_EQ(size, data_size); +// ASSERT_STREQ(value, data); +// ASSERT_STREQ(mime_type, "application/pgp-signature"); + +// free(value); +// free(code); +// } + +// TEST_F(Engine619Test, check_encrypt_decrypt_message) { +// // a message from me, Alice, to Bob + +// const char* alice_fpr = "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97"; +// const char* bob_fpr = "BFCDB7F301DEEEBBF947F29659BFF488C9C2EE39"; +// PEP_STATUS status = read_file_and_import_key(session, +// "test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc"); +// ASSERT_EQ(status , PEP_KEY_IMPORTED); +// status = set_up_ident_from_scratch(session, +// "test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc", +// "pep.test.alice@pep-project.org", alice_fpr, +// PEP_OWN_USERID, "Alice in Wonderland", NULL, true +// ); +// ASSERT_OK; +// ASSERT_TRUE(slurp_and_import_key(session, "test_keys/pub/pep-test-bob-0xC9C2EE39_pub.asc")); + +// message* msg = new_message(PEP_dir_outgoing); +// pEp_identity* alice = new_identity("pep.test.alice@pep-project.org", NULL, PEP_OWN_USERID, NULL); +// pEp_identity* bob = new_identity("pep.test.bob@pep-project.org", NULL, "Bob", NULL); +// status = myself(session, alice); +// ASSERT_OK; +// status = update_identity(session, bob); +// ASSERT_OK; +// bob->fpr = strdup(bob_fpr); +// status = set_identity(session, bob); +// ASSERT_OK; +// status = update_identity(session, bob); +// ASSERT_OK; +// status = set_as_pEp_user(session, bob); +// ASSERT_OK; + +// msg->to = new_identity_list(bob); +// msg->from = alice; +// msg->shortmsg = strdup("Yo Bob!"); +// msg->longmsg = strdup("Look at my hot new sender fpr field!"); + +// // Volker: This is a sloppy way to test - it got processed as a real distribution message because data has meaning +// // and happily exposed a bug in your generation code, but... well, you know better :) +// const char *distribution = "simulation of distribution data"; +// msg->attachments = new_bloblist(strdup(distribution), strlen(distribution) +// + 1, "application/pEp.distribution", "distribution.pEp"); + +// // encrypt this message inline + +// message* enc_msg = NULL; +// status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_inline, 0); +// ASSERT_OK; + +// // .shortmsg will stay unencrypted +// ASSERT_STREQ(msg->shortmsg, enc_msg->shortmsg); + +// // .longmsg will go encrypted +// ASSERT_TRUE(is_PGP_message_text(enc_msg->longmsg)); + +// ASSERT_TRUE(enc_msg->attachments); +// ASSERT_TRUE(enc_msg->attachments->value); + +// bloblist_t *ad = enc_msg->attachments; + +// // distribution message is encrypted +// ASSERT_TRUE(is_PGP_message_text(ad->value)); +// ASSERT_STREQ(ad->mime_type, "application/octet-stream"); +// ASSERT_STREQ(ad->filename, "distribution.pEp.pgp"); + +// // next attachment +// ASSERT_TRUE(ad->next); +// ad = ad->next; + +// // attached key is encrypted +// ASSERT_TRUE(is_PGP_message_text(ad->value)); +// ASSERT_STREQ(ad->mime_type, "application/octet-stream"); +// // ASSERT_STREQ(ad->filename, "file://pEpkey.asc.pgp"); +// // As of ENGINE-633: +// ASSERT_STREQ(ad->filename, "file://sender_key.asc.pgp"); +// // decrypt this message + +// message *dec_msg = NULL; +// stringlist_t *keylist = NULL; +// PEP_rating rating; +// PEP_decrypt_flags_t flags = 0; + +// status = decrypt_message(session, enc_msg, &dec_msg, &keylist, &rating, &flags); +// ASSERT_EQ(status, PEP_STATUS_OK); +// ASSERT_STREQ(dec_msg->shortmsg, enc_msg->shortmsg); +// ASSERT_STREQ(msg->longmsg, dec_msg->longmsg); + +// // check attachments +// ASSERT_TRUE(dec_msg->attachments); +// ASSERT_TRUE(dec_msg->attachments->value); +// bloblist_t *as = dec_msg->attachments; +// bloblist_t *bl = msg->attachments; + +// ASSERT_STREQ(as->filename, "file://distribution.pEp"); +// // the MIME will be derived from filename +// ASSERT_STREQ(as->mime_type, "application/pEp.distribution"); + +// free_message(msg); +// free_message(enc_msg); +// free_message(dec_msg); +// } + +// TEST_F(Engine619Test, check_encrypt_decrypt_message_elevated) { +// // a message from me, Alice, to Bob + +// const char* alice_fpr = "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97"; +// const char* bob_fpr = "BFCDB7F301DEEEBBF947F29659BFF488C9C2EE39"; +// PEP_STATUS status = read_file_and_import_key(session, +// "test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc"); +// ASSERT_EQ(status , PEP_KEY_IMPORTED); +// status = set_up_ident_from_scratch(session, +// "test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc", +// "pep.test.alice@pep-project.org", alice_fpr, +// PEP_OWN_USERID, "Alice in Wonderland", NULL, true +// ); +// ASSERT_OK; +// ASSERT_TRUE(slurp_and_import_key(session, "test_keys/pub/pep-test-bob-0xC9C2EE39_pub.asc")); + +// message* msg = new_message(PEP_dir_outgoing); +// pEp_identity* alice = new_identity("pep.test.alice@pep-project.org", NULL, PEP_OWN_USERID, NULL); +// pEp_identity* bob = new_identity("pep.test.bob@pep-project.org", NULL, "Bob", NULL); +// status = myself(session, alice); +// ASSERT_OK; +// status = update_identity(session, bob); +// ASSERT_OK; +// bob->fpr = strdup(bob_fpr); +// status = set_identity(session, bob); +// ASSERT_OK; +// status = update_identity(session, bob); +// ASSERT_OK; +// status = set_as_pEp_user(session, bob); +// ASSERT_OK; + +// msg->to = new_identity_list(bob); +// msg->from = alice; +// msg->shortmsg = strdup("Yo Bob!"); +// msg->longmsg = strdup("Look at my hot new sender fpr field!"); + +// const char *distribution = "simulation of distribution data"; +// msg->attachments = new_bloblist(strdup(distribution), strlen(distribution) +// + 1, "application/pEp.distribution", "distribution.pEp"); + +// // encrypt this message inline + +// message* enc_msg = NULL; +// status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_inline_EA, 0); +// ASSERT_OK; + +// // .longmsg will go encrypted +// ASSERT_TRUE(is_PGP_message_text(enc_msg->longmsg)); + +// ASSERT_TRUE(enc_msg->attachments); +// ASSERT_TRUE(enc_msg->attachments->value); + +// bloblist_t *ad = enc_msg->attachments; + +// // distribution message is encrypted +// ASSERT_TRUE(is_PGP_message_text(ad->value)); +// ASSERT_STREQ(ad->mime_type, "application/octet-stream"); +// ASSERT_STREQ(ad->filename, "distribution.pEp.pgp"); + +// // next attachment +// ASSERT_TRUE(ad->next); +// ad = ad->next; + +// // attached key is encrypted +// ASSERT_TRUE(is_PGP_message_text(ad->value)); +// ASSERT_STREQ(ad->mime_type, "application/octet-stream"); +// // ASSERT_STREQ(ad->filename, "file://pEpkey.asc.pgp"); +// // As of ENGINE-633: +// ASSERT_STREQ(ad->filename, "file://sender_key.asc.pgp"); +// // decrypt this message + +// char *ct = strdup(ad->value); + +// { +// // test if this is an elevated attachment + +// char *pt; +// size_t pt_size; +// stringlist_t *keylist; + +// // decrypt this part + +// status = decrypt_and_verify(session, ct, strlen(ct) + 1, NULL, 0, &pt, &pt_size, &keylist, NULL); +// ASSERT_EQ(status, PEP_DECRYPTED_AND_VERIFIED); + +// // decode internal message format + +// char *dt; +// size_t dt_size; +// char *mime_type; +// status = decode_internal(pt, pt_size, &dt, &dt_size, &mime_type); +// ASSERT_EQ(status, PEP_STATUS_OK); +// ASSERT_TRUE(dt); +// ASSERT_STREQ(mime_type, "application/pgp-keys"); + +// free(pt); +// free(dt); +// free(mime_type); +// free_stringlist(keylist); +// } + +// // create artificial message for Key like a transport would do + +// message *art_msg = new_message(PEP_dir_incoming); +// art_msg->enc_format = PEP_enc_inline_EA; +// art_msg->from = identity_dup(enc_msg->to->ident); +// art_msg->to = new_identity_list(identity_dup(enc_msg->from)); +// art_msg->longmsg = ct; + +// // decrypt this message + +// message *dec_msg = NULL; +// stringlist_t *keylist = NULL; +// PEP_rating rating; +// PEP_decrypt_flags_t flags = 0; + +// status = decrypt_message(session, art_msg, &dec_msg, &keylist, &rating, &flags); +// ASSERT_EQ(status, PEP_STATUS_OK); +// ASSERT_TRUE(dec_msg); +// // today the engine is sucking keys in +// // ASSERT_STREQ(dec_msg->attachments->mime_type, "application/pgp-keys"); +// ASSERT_STREQ(dec_msg->shortmsg, "pEp"); + +// stringpair_list_t *of; +// bool pEp_auto_consume_found = false; +// for (of = dec_msg->opt_fields; of && of->value; of = of->next) { +// if (strcasecmp(of->value->key, "pEp-auto-consume") == 0) { +// ASSERT_STREQ(of->value->value, "yes"); +// pEp_auto_consume_found = true; +// break; +// } +// } +// ASSERT_TRUE(pEp_auto_consume_found); + +// free_message(msg); +// free_message(enc_msg); +// free_message(dec_msg); +// free_message(art_msg); +// } + +TEST_F(Engine619Test, decrypt_message_with_private_key) { + PEP_STATUS status = PEP_STATUS_OK; + message *message_src + = slurp_message_file_into_struct("test_mails/ExtraKeyPrivateKeyAttached.eml"); + ASSERT_NOTNULL (message_src); + + message *message_dst; + stringlist_t* keys = NULL; + PEP_rating rating; + PEP_decrypt_flags_t flags = 0; + + status = decrypt_message(session, message_src, & message_dst, + & keys, & rating, & flags); + /* It is normal and expected that decryption fails here: this message is + unencrypted. The point of this test is to arrive at a call to + pgp_import_keydata , which used to corrut the heap (ENGINE-619). */ + ASSERT_EQ (status, PEP_UNENCRYPTED); + + /* Check that the message content matches what we expect. */ + ASSERT_NOTNULL (message_src->shortmsg); + ASSERT_NOTNULL (message_src->longmsg); + ASSERT_NULL (message_src->longmsg_formatted); + + /* The message has exactly one attachment, the private key. */ + bloblist_t *attachments = message_src->attachments; + ASSERT_NOTNULL (attachments); + ASSERT_NULL (attachments->next); + + /* We can even print it. */ + std::cerr << "THE FIRST ATTACHMENT HAS SIZE " << attachments->size << "\n"; + std::cerr << "THE FIRST ATTACHMENT IS:\n"; + std::cerr << attachments->value; + std::cerr << "\n"; +} From 482bf394971058a77917e9976eeea05d1adb63b6 Mon Sep 17 00:00:00 2001 From: Devan Carpenter Date: Fri, 3 Sep 2021 14:37:10 -0700 Subject: [PATCH 55/60] CI: make build jobs much faster All jobs were running as docker image builds inside of KVMs. Now the first build job runs as a regular job inside the docker image generated in the dependencies stage. This reduces the initial build jobs to around 1 minute, down from 10~ minutes. The jobs building the docker images have been moved into their own seperate stage which only runs if the first quick builds succeed. --- .gitlab-ci.yml | 92 +++++++++++++++++-- scripts/centos8/Makefile | 23 +++-- .../centos8/deps.pEpEngine.centos8.Dockerfile | 3 + .../build.pEpEngine.Dockerfile} | 3 +- scripts/debian10/Makefile | 29 +++++- ...ile => deps.pEpEngine.debian10.Dockerfile} | 22 ++--- 6 files changed, 136 insertions(+), 36 deletions(-) rename scripts/{centos8/pEpEngine.centos8.Dockerfile => common/build.pEpEngine.Dockerfile} (90%) rename scripts/debian10/{pEpEngine.debian10.Dockerfile => deps.pEpEngine.debian10.Dockerfile} (63%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5508fa96..7d0a5a50 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,14 +4,33 @@ include: stages: - deps - build + - build-docker - packages # Debian -debian10:build: +debian10:deps: extends: .make_in_docker + stage: deps + variables: + MAKE_TARGET: "deps" + CI_DISTRO_TARGET: "debian10" + DEBIAN_FRONTEND: "noninteractive" + rules: + - changes: + - DEPENDENCIES + - scripts/debian10/deps.pEpEngine.debian10.Dockerfile + - scripts/common/build_pEpEngine_deps.sh + +debian10:build: + tags: + - linux stage: build + image: ${DOCKER_REGISTRY_HOST}/pep-debian10-engine-deps:latest + script: + - cd scripts/${CI_DISTRO_TARGET} + - make ${MAKE_TARGET} variables: MAKE_TARGET: "build" CI_DISTRO_TARGET: "debian10" @@ -20,8 +39,13 @@ debian10:build: - if: '$CI_COMMIT_TAG !~ /^Release_[0-9]+\.[0-9]+\.[0-9]+$/' debian10:tagged-build: - extends: .make_in_docker + tags: + - linux stage: build + image: ${DOCKER_REGISTRY_HOST}/pep-debian10-engine-deps:latest + script: + - cd scripts/${CI_DISTRO_TARGET} + - make ${MAKE_TARGET} variables: MAKE_TARGET: "build" CI_DISTRO_TARGET: "debian10" @@ -30,6 +54,29 @@ debian10:tagged-build: rules: - if: '$CI_COMMIT_TAG =~ /^Release_[0-9]+\.[0-9]+\.[0-9]+$/' +debian10:build-docker: + extends: .make_in_docker + stage: build-docker + needs: ["debian10:build"] + variables: + MAKE_TARGET: "build-docker" + CI_DISTRO_TARGET: "debian10" + DEBIAN_FRONTEND: "noninteractive" + rules: + - if: '$CI_COMMIT_TAG !~ /^Release_[0-9]+\.[0-9]+\.[0-9]+$/' + +debian10:tagged-build-docker: + extends: .make_in_docker + stage: build-docker + needs: ["debian10:tagged-build"] + variables: + MAKE_TARGET: "build-docker" + CI_DISTRO_TARGET: "debian10" + DEBIAN_FRONTEND: "noninteractive" + TAGGED_BUILD: "true" + rules: + - if: '$CI_COMMIT_TAG =~ /^Release_[0-9]+\.[0-9]+\.[0-9]+$/' + # CentOS centos8:deps: @@ -41,11 +88,18 @@ centos8:deps: rules: - changes: - DEPENDENCIES + - scripts/centos8/deps.pEpEngine.centos8.Dockerfile + - scripts/common/build_pEpEngine_deps.sh centos8:build: - extends: .make_in_docker + tags: + - linux stage: build + image: ${DOCKER_REGISTRY_HOST}/pep-centos8-engine-deps:latest + script: + - cd scripts/${CI_DISTRO_TARGET} + - make ${MAKE_TARGET} variables: MAKE_TARGET: "build" CI_DISTRO_TARGET: "centos8" @@ -53,8 +107,13 @@ centos8:build: - if: '$CI_COMMIT_TAG !~ /^Release_[0-9]+\.[0-9]+\.[0-9]+$/' centos8:tagged-build: - extends: .make_in_docker + tags: + - linux stage: build + image: ${DOCKER_REGISTRY_HOST}/pep-centos8-engine-deps:latest + script: + - cd scripts/${CI_DISTRO_TARGET} + - make ${MAKE_TARGET} variables: MAKE_TARGET: "build" CI_DISTRO_TARGET: "centos8" @@ -62,10 +121,31 @@ centos8:tagged-build: rules: - if: '$CI_COMMIT_TAG =~ /^Release_[0-9]+\.[0-9]+\.[0-9]+$/' +centos8:build-docker: + extends: .make_in_docker + stage: build-docker + needs: ["centos8:build"] + variables: + MAKE_TARGET: "build-docker" + CI_DISTRO_TARGET: "centos8" + rules: + - if: '$CI_COMMIT_TAG !~ /^Release_[0-9]+\.[0-9]+\.[0-9]+$/' + +centos8:tagged-build-docker: + extends: .make_in_docker + stage: build-docker + needs: ["centos8:tagged-build"] + variables: + MAKE_TARGET: "build-docker" + CI_DISTRO_TARGET: "centos8" + TAGGED_BUILD: "true" + rules: + - if: '$CI_COMMIT_TAG =~ /^Release_[0-9]+\.[0-9]+\.[0-9]+$/' + centos8:rpm: extends: .make_in_docker stage: packages - needs: ["centos8:build"] + needs: ["centos8:build-docker"] variables: MAKE_TARGET: "rpm" CI_DISTRO_TARGET: "centos8" @@ -76,7 +156,7 @@ centos8:rpm: centos8:rpm:tagged-build: extends: .upload_pkg stage: packages - needs: ["centos8:tagged-build"] + needs: ["centos8:tagged-build-docker"] variables: MAKE_TARGET: "rpm" CI_DISTRO_TARGET: "centos8" diff --git a/scripts/centos8/Makefile b/scripts/centos8/Makefile index ab60889d..c0e6e9b1 100644 --- a/scripts/centos8/Makefile +++ b/scripts/centos8/Makefile @@ -22,7 +22,7 @@ endif all: deps build deps: - -docker pull $(IMAGE_NAME)-deps:latest + -docker pull --quiet $(IMAGE_NAME)-deps:latest cd ../../ && docker build --build-arg CURRENT_DISTRO=$(CURRENT_DISTRO) \ --build-arg DOCKER_REGISTRY_HOST=${DOCKER_REGISTRY_HOST} \ --build-arg PEPENGINE_VERSION=$(PEPENGINE_VERSION) \ @@ -33,11 +33,14 @@ deps: --tag=$(IMAGE_NAME)-deps:$(SEQUOIA_VERSION)-$(YML2_VERSION) \ --tag=$(IMAGE_NAME)-deps:latest \ -f scripts/${CURRENT_DISTRO}/deps.$(DOCKERFILE) . - docker push $(IMAGE_NAME)-deps:$(SEQUOIA_VERSION)-$(YML2_VERSION) - docker push $(IMAGE_NAME)-deps:latest + docker push --quiet $(IMAGE_NAME)-deps:$(SEQUOIA_VERSION)-$(YML2_VERSION) + docker push --quiet $(IMAGE_NAME)-deps:latest build: - -docker pull $(IMAGE_NAME):latest + cd ../../ && /bin/sh ./scripts/common/build_pEpEngine.sh + +build-docker: + -docker pull --quiet $(IMAGE_NAME):latest cd ../../ && docker build --build-arg CURRENT_DISTRO=$(CURRENT_DISTRO) \ --build-arg DOCKER_REGISTRY_HOST=${DOCKER_REGISTRY_HOST} \ --build-arg PEPENGINE_VERSION=$(PEPENGINE_VERSION) \ @@ -47,12 +50,12 @@ build: --cache-from $(IMAGE_NAME):latest \ --tag=$(IMAGE_NAME):$(PEPENGINE_VERSION) \ --tag=$(IMAGE_NAME):latest \ - -f scripts/${CURRENT_DISTRO}/$(DOCKERFILE) . - docker push $(IMAGE_NAME):$(PEPENGINE_VERSION) - docker push $(IMAGE_NAME):latest + -f scripts/common/build.pEpEngine.Dockerfile . + docker push --quiet $(IMAGE_NAME):$(PEPENGINE_VERSION) + docker push --quiet $(IMAGE_NAME):latest rpm: - -docker pull $(PKG_BUILD_IMAGE)-engine:latest + -docker pull --quiet $(PKG_BUILD_IMAGE)-engine:latest @docker build --build-arg CURRENT_DISTRO=$(CURRENT_DISTRO) \ --build-arg PEPENGINE_VERSION=$(PEPENGINE_VERSION) \ --build-arg DOCKER_REGISTRY_HOST=${DOCKER_REGISTRY_HOST} \ @@ -62,8 +65,8 @@ rpm: --tag=$(PKG_BUILD_IMAGE)-engine:$(PEPENGINE_VERSION) \ --tag=$(PKG_BUILD_IMAGE)-engine:latest \ packages/rpm - @docker push $(PKG_BUILD_IMAGE)-engine:$(PEPENGINE_VERSION) - @docker push $(PKG_BUILD_IMAGE)-engine:latest + @docker push --quiet $(PKG_BUILD_IMAGE)-engine:$(PEPENGINE_VERSION) + @docker push --quiet $(PKG_BUILD_IMAGE)-engine:latest @docker run -e PEPENGINE_VERSION=$(PEPENGINE_VERSION) \ -e PEP_MACHINE_DIR=$(PEP_MACHINE_DIR) \ -e PKG_VERSION=$(PEPENGINE_VERSION) \ diff --git a/scripts/centos8/deps.pEpEngine.centos8.Dockerfile b/scripts/centos8/deps.pEpEngine.centos8.Dockerfile index 94ca52b6..e0f210ee 100644 --- a/scripts/centos8/deps.pEpEngine.centos8.Dockerfile +++ b/scripts/centos8/deps.pEpEngine.centos8.Dockerfile @@ -17,6 +17,9 @@ USER root RUN yum install -y python3 python3-lxml binutils && yum clean all +### Setup PEP_MACHINE_DIR +RUN mkdir -p ${PEP_MACHINE_DIR} + RUN chown -R pep-builder:pep-builder ${BUILDROOT}/pEpEngine WORKDIR ${BUILDROOT}/pEpEngine diff --git a/scripts/centos8/pEpEngine.centos8.Dockerfile b/scripts/common/build.pEpEngine.Dockerfile similarity index 90% rename from scripts/centos8/pEpEngine.centos8.Dockerfile rename to scripts/common/build.pEpEngine.Dockerfile index 635799ee..1d6ef779 100644 --- a/scripts/centos8/pEpEngine.centos8.Dockerfile +++ b/scripts/common/build.pEpEngine.Dockerfile @@ -12,7 +12,8 @@ ARG PEP_MACHINE_DIR ### Setup working directory USER root -RUN mkdir -p ${BUILDROOT}/pEpEngine +RUN rm -rf ${BUILDROOT}/pEpEngine && \ + mkdir -p ${BUILDROOT}/pEpEngine COPY . ${BUILDROOT}/pEpEngine RUN chown -R pep-builder:pep-builder ${BUILDROOT}/pEpEngine diff --git a/scripts/debian10/Makefile b/scripts/debian10/Makefile index da5399cf..24c78f18 100644 --- a/scripts/debian10/Makefile +++ b/scripts/debian10/Makefile @@ -6,6 +6,7 @@ SEQUOIA_VERSION=$(shell echo ${sequoia} | sed 's/\//-/') CURRENT_DISTRO=$(shell basename $(shell pwd)) IMAGE_NAME=${DOCKER_REGISTRY_HOST}/pep-$(CURRENT_DISTRO)-engine DOCKERFILE=pEpEngine.$(CURRENT_DISTRO).Dockerfile +PKG_INSTALL_PATH=/opt/pEp IS_TAGGED=${TAGGED_BUILD} ifeq ($(IS_TAGGED), true) # $CI_COMMIT_TAG is a predefined environment variable from Gitlab @@ -13,10 +14,28 @@ ifeq ($(IS_TAGGED), true) else PEPENGINE_VERSION=$(shell git rev-parse --short=8 HEAD) endif -all: build +all: deps build + +deps: + -docker pull --quiet $(IMAGE_NAME)-deps:latest + cd ../../ && docker build --build-arg CURRENT_DISTRO=$(CURRENT_DISTRO) \ + --build-arg DOCKER_REGISTRY_HOST=${DOCKER_REGISTRY_HOST} \ + --build-arg PEPENGINE_VERSION=$(PEPENGINE_VERSION) \ + --build-arg SEQUOIA_VERSION=$(SEQUOIA_VERSION) \ + --build-arg YML2_VERSION=$(YML2_VERSION) \ + --build-arg PEP_MACHINE_DIR=$(PEP_MACHINE_DIR) \ + --cache-from $(IMAGE_NAME):latest \ + --tag=$(IMAGE_NAME)-deps:$(SEQUOIA_VERSION)-$(YML2_VERSION) \ + --tag=$(IMAGE_NAME)-deps:latest \ + -f scripts/${CURRENT_DISTRO}/deps.$(DOCKERFILE) . + docker push --quiet $(IMAGE_NAME)-deps:$(SEQUOIA_VERSION)-$(YML2_VERSION) + docker push --quiet $(IMAGE_NAME)-deps:latest build: - -docker pull $(IMAGE_NAME):latest + cd ../../ && /bin/sh ./scripts/common/build_pEpEngine.sh + +build-docker: + -docker pull --quiet $(IMAGE_NAME):latest cd ../../ && docker build --build-arg CURRENT_DISTRO=$(CURRENT_DISTRO) \ --build-arg DOCKER_REGISTRY_HOST=${DOCKER_REGISTRY_HOST} \ --build-arg PEPENGINE_VERSION=$(PEPENGINE_VERSION) \ @@ -26,6 +45,6 @@ build: --cache-from $(IMAGE_NAME):latest \ --tag=$(IMAGE_NAME):$(PEPENGINE_VERSION) \ --tag=$(IMAGE_NAME):latest \ - -f scripts/${CURRENT_DISTRO}/$(DOCKERFILE) . - docker push $(IMAGE_NAME):$(PEPENGINE_VERSION) - docker push $(IMAGE_NAME):latest + -f scripts/common/build.pEpEngine.Dockerfile . + docker push --quiet $(IMAGE_NAME):$(PEPENGINE_VERSION) + docker push --quiet $(IMAGE_NAME):latest diff --git a/scripts/debian10/pEpEngine.debian10.Dockerfile b/scripts/debian10/deps.pEpEngine.debian10.Dockerfile similarity index 63% rename from scripts/debian10/pEpEngine.debian10.Dockerfile rename to scripts/debian10/deps.pEpEngine.debian10.Dockerfile index 088ccd58..e2663535 100644 --- a/scripts/debian10/pEpEngine.debian10.Dockerfile +++ b/scripts/debian10/deps.pEpEngine.debian10.Dockerfile @@ -11,10 +11,16 @@ ARG PEP_MACHINE_DIR ### Setup working directory RUN mkdir ${BUILDROOT}/pEpEngine -COPY . ${BUILDROOT}/pEpEngine +COPY ./scripts/common/build_pEpEngine_deps.sh ${BUILDROOT}/pEpEngine USER root +RUN apt-get update && apt-get install -y bzip2 && \ + rm -rf /var/lib/apt/lists/* + +### Setup PEP_MACHINE_DIR +RUN mkdir -p ${PEP_MACHINE_DIR} + RUN chown -R pep-builder:pep-builder ${BUILDROOT}/pEpEngine WORKDIR ${BUILDROOT}/pEpEngine @@ -22,19 +28,7 @@ ARG YML2_VERSION ARG ENGINE_VERSION ARG CURRENT_DISTRO -RUN apt-get update && apt-get install -y bzip2 && \ - rm -rf /var/lib/apt/lists/* - ### Build pEpEngine dependencies USER pep-builder -RUN sh ./scripts/common/build_pEpEngine_deps.sh - -### Build pEpEngine -RUN sh ./scripts/common/build_pEpEngine.sh - -### Install Systemdb -USER root - -RUN sh ./scripts/common/install_pEpEngine_systemdb.sh && \ - rm -rf ${BUILDROOT}/* +RUN sh ./build_pEpEngine_deps.sh From b11a1d55ef19223265e0df51e93effe9744b5c79 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 23 Sep 2021 11:10:28 +0200 Subject: [PATCH 56/60] deliver rating for sent messages --- src/transport.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transport.h b/src/transport.h index 2b0eac6d..32a7c15e 100644 --- a/src/transport.h +++ b/src/transport.h @@ -8,7 +8,7 @@ #define TRANSPORT_H #include "pEpEngine.h" -#include "message.h" +#include "message_api.h" #ifdef __cplusplus extern "C" { @@ -71,7 +71,7 @@ typedef PEP_STATUS (*signal_statuschange_t)(PEP_transport_id id, PEP_transport_status_code tsc); typedef PEP_STATUS (*signal_sendto_result_t)(PEP_transport_id id, char *message_id, - char *address, PEP_transport_status_code tsc); + char *address, PEP_rating rating, PEP_transport_status_code tsc); typedef PEP_STATUS (*signal_incoming_message_t)(PEP_transport_id id, PEP_transport_status_code tsc); From b0b3862b79e6ad9751ab3b136c28aa2e6bbb8429 Mon Sep 17 00:00:00 2001 From: Luca Saiu Date: Thu, 23 Sep 2021 15:27:40 +0200 Subject: [PATCH 57/60] obvious fix for ENGINE-962 --- src/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 0c1af16b..ded8e906 100644 --- a/src/Makefile +++ b/src/Makefile @@ -109,7 +109,8 @@ install_headers: $(TARGET) timestamp.h identity_list.h bloblist.h stringpair.h message.h mime.h group.h \ cryptotech.h sync_api.h pEp_string.h openpgp_compat.h engine_sql.h \ labeled_int_list.h key_reset.h base64.h sync_codec.h distribution_codec.h storage_codec.h \ - status_to_string.h keyreset_command.h platform.h platform_unix.h ../asn.1/*.h \ + status_to_string.h keyreset_command.h platform.h platform_unix.h \ + transport.h ../asn.1/*.h \ $(DESTDIR)$(PREFIX)/include/pEp/ # FIXME: Does anyone but Roker use install_headers? Otherwise, remove the dependency. From 9d8de493835269b8efd621eaa6e1f029f87f5d29 Mon Sep 17 00:00:00 2001 From: Luca Saiu Date: Thu, 23 Sep 2021 16:37:51 +0200 Subject: [PATCH 58/60] when uninstalling headers, actually only remove our ones; minor makefile factoring It would be possible to install every header under src/ using a wildcard expansion, but Volker confirms that we may want to keep internal headers which are not installed. --- src/Makefile | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Makefile b/src/Makefile index ded8e906..49ffee15 100644 --- a/src/Makefile +++ b/src/Makefile @@ -100,18 +100,20 @@ clean: rm -Rf $(TARGET).dSYM rm -f KeySync_fsm.* Sync_actions.c Sync_event.* Sync_func.* Sync_impl.* sync_codec.* distribution_codec.* storage_codec.* +HEADERS_TO_INSTALL = \ + 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 group.h \ + cryptotech.h sync_api.h pEp_string.h openpgp_compat.h engine_sql.h \ + labeled_int_list.h key_reset.h base64.h sync_codec.h distribution_codec.h \ + storage_codec.h status_to_string.h keyreset_command.h platform.h platform_unix.h \ + transport.h $(wildcard ../asn.1/*.h) + # CAVEAT: # install_headers is needed for building *STANDALONE* pEp MIME - it is NOT used for built-in functionality!!! install_headers: $(TARGET) mkdir -p $(DESTDIR)$(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 group.h \ - cryptotech.h sync_api.h pEp_string.h openpgp_compat.h engine_sql.h \ - labeled_int_list.h key_reset.h base64.h sync_codec.h distribution_codec.h storage_codec.h \ - status_to_string.h keyreset_command.h platform.h platform_unix.h \ - transport.h ../asn.1/*.h \ - $(DESTDIR)$(PREFIX)/include/pEp/ + cp $(HEADERS_TO_INSTALL) $(DESTDIR)$(PREFIX)/include/pEp/ # FIXME: Does anyone but Roker use install_headers? Otherwise, remove the dependency. install: $(TARGET) install_headers @@ -124,7 +126,8 @@ beinstall: install uninstall: rm -f $(DESTDIR)$(PREFIX)/lib/$(TARGET) - rm -rf $(DESTDIR)$(PREFIX)/include/pEp + rm $(addprefix $(DESTDIR)$(PREFIX)/include/pEp/,$(notdir $(HEADERS_TO_INSTALL))) + rmdir $(DESTDIR)$(PREFIX)/include/pEp 2> /dev/null || true tags: $(wildcard *.c) $(wildcard *.h) ctags --sort=yes *.c *.h From d4763df3a6a575a62d8932707bac3d3150f57093 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 23 Sep 2021 17:49:35 +0200 Subject: [PATCH 59/60] adding growing_buf.h to the installed headers --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 49ffee15..e85453af 100644 --- a/src/Makefile +++ b/src/Makefile @@ -106,7 +106,7 @@ HEADERS_TO_INSTALL = \ cryptotech.h sync_api.h pEp_string.h openpgp_compat.h engine_sql.h \ labeled_int_list.h key_reset.h base64.h sync_codec.h distribution_codec.h \ storage_codec.h status_to_string.h keyreset_command.h platform.h platform_unix.h \ - transport.h $(wildcard ../asn.1/*.h) + transport.h growing_buf.h $(wildcard ../asn.1/*.h) # CAVEAT: # install_headers is needed for building *STANDALONE* pEp MIME - it is NOT used for built-in functionality!!! From 42a702610b33f8424c8a1c0f20792960eb91084e Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Thu, 23 Sep 2021 19:13:10 +0200 Subject: [PATCH 60/60] using transport status code --- src/transport.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/transport.h b/src/transport.h index 32a7c15e..da7419d5 100644 --- a/src/transport.h +++ b/src/transport.h @@ -9,6 +9,7 @@ #include "pEpEngine.h" #include "message_api.h" +#include #ifdef __cplusplus extern "C" { @@ -44,8 +45,6 @@ typedef struct _transport_config { // this is defined here: // https://dev.pep.foundation/Engine/TransportStatusCode -typedef uint32_t PEP_transport_status_code; - typedef struct _PEP_transport_t PEP_transport_t; // functions offered by transport