Browse Source

merge default

generate_api
nk 2 years ago
parent
commit
0882eac7a6
150 changed files with 19374 additions and 2971 deletions
  1. +11
    -0
      Makefile.conf
  2. +8
    -0
      build-mac/pEpEngine.xcodeproj/project.pbxproj
  3. +3
    -1
      build-windows/generate_code.cmd
  4. +130
    -3
      build-windows/libpEpasn1/libpEpasn1.vcxproj
  5. +260
    -1568
      build-windows/libpEpasn1/libpEpasn1.vcxproj.filters
  6. +5
    -0
      build-windows/pEpEngine.vcxproj
  7. +11
    -0
      build-windows/pEpEngine.vcxproj.filters
  8. +1
    -1
      clean_sync_leftovers.sh
  9. +0
    -1
      doc/build-fedora.md
  10. +0
    -161
      doc/build-macos.md
  11. +0
    -43
      doc/build-netpgp.md
  12. +0
    -58
      doc/readme.md
  13. +0
    -2
      doc/testing.md
  14. +1
    -1
      src/Makefile
  15. +10
    -12
      src/aux_mime_msg.c
  16. +13
    -6
      src/base64.c
  17. +75
    -6
      src/baseprotocol.c
  18. +16
    -0
      src/baseprotocol.h
  19. +2
    -2
      src/cryptotech.h
  20. +247
    -116
      src/etpan_mime.c
  21. +0
    -1
      src/etpan_mime.h
  22. +164
    -0
      src/internal_format.c
  23. +72
    -0
      src/internal_format.h
  24. +12
    -2
      src/key_reset.c
  25. +106
    -3
      src/keymanagement.c
  26. +2
    -0
      src/keymanagement.h
  27. +0
    -10
      src/message.h
  28. +537
    -166
      src/message_api.c
  29. +43
    -15
      src/message_api.h
  30. +0
    -9
      src/mime.c
  31. +28
    -25
      src/mime.h
  32. +212
    -37
      src/pEpEngine.c
  33. +168
    -9
      src/pEpEngine.h
  34. +8
    -4
      src/pEp_internal.h
  35. +0
    -305
      src/pgp_gpg.h
  36. +489
    -145
      src/pgp_sequoia.c
  37. +3
    -1
      src/pgp_sequoia.h
  38. +4
    -0
      src/platform_unix.h
  39. +30
    -18
      src/platform_windows.cpp
  40. +5
    -0
      src/status_to_string.h
  41. +9
    -1
      src/sync_api.h
  42. +5
    -5
      sync/cond_act_sync.yml2
  43. +3
    -2
      sync/fsm.yml2
  44. +1
    -0
      sync/gen_message_func.ysl2
  45. +71
    -6
      sync/gen_statemachine.ysl2
  46. +15
    -6
      sync/sync.fsm
  47. +664
    -0
      sync/sync.md
  48. +5
    -0
      test/README.md
  49. +92
    -46
      test/convenience_scripts/keygen_for_test.py
  50. +2
    -2
      test/src/AppleMailTest.cc
  51. +1
    -1
      test/src/BlacklistAcceptNewKeyTest.cc
  52. +124
    -0
      test/src/CleanInvalidOwnKeysTest.cc
  53. +1
    -1
      test/src/DecorateTest.cc
  54. +419
    -0
      test/src/ElevatedAttachmentsTest.cc
  55. +587
    -0
      test/src/EmptyLongmsgFullHtmlTest.cc
  56. +1
    -1
      test/src/EncryptAttachPrivateKeyTest.cc
  57. +268
    -5
      test/src/EncryptForIdentityTest.cc
  58. +1
    -1
      test/src/EncryptMissingPrivateKeyTest.cc
  59. +284
    -0
      test/src/Engine514Test.cc
  60. +2
    -2
      test/src/Engine655Test.cc
  61. +46
    -61
      test/src/Engine736Test.cc
  62. +6
    -0
      test/src/HeaderKeyImportTest.cc
  63. +514
    -0
      test/src/IdentEncFormatTest.cc
  64. +328
    -0
      test/src/ImportKeyTest.cc
  65. +18
    -18
      test/src/KeyAttachmentTest.cc
  66. +57
    -21
      test/src/KeyResetMessageTest.cc
  67. +1
    -1
      test/src/LeastColorGroupTest.cc
  68. +2
    -2
      test/src/LeastCommonDenomColorTest.cc
  69. +4
    -4
      test/src/MessageApiTest.cc
  70. +4
    -4
      test/src/MessageTwoPointOhTest.cc
  71. +2
    -2
      test/src/MimeTest.cc
  72. +1313
    -0
      test/src/PassphraseTest.cc
  73. +13
    -13
      test/src/PepSubjectReceivedTest.cc
  74. +13
    -13
      test/src/ReencryptPlusExtraKeysTest.cc
  75. +1
    -1
      test/src/SenderFPRTest.cc
  76. +2
    -2
      test/src/SimpleBodyNotAltTest.cc
  77. +96
    -0
      test/src/URIAddressTest.cc
  78. +4
    -4
      test/src/UnencryptedPepMailTest.cc
  79. +7
    -15
      test/src/test_util.cc
  80. BIN
      test/test_files/ENGINE-750_check_clean_invalid_own_keys_no_alts_expired_keys.db
  81. BIN
      test/test_files/ENGINE-750_check_clean_invalid_own_keys_no_alts_expired_mgmt.db
  82. BIN
      test/test_files/ENGINE-750_check_clean_invalid_own_keys_no_alts_mistrusted_keys.db
  83. BIN
      test/test_files/ENGINE-750_check_clean_invalid_own_keys_no_alts_mistrusted_mgmt.db
  84. BIN
      test/test_files/ENGINE-750_check_clean_invalid_own_keys_no_alts_revoked_keys.db
  85. BIN
      test/test_files/ENGINE-750_check_clean_invalid_own_keys_no_alts_revoked_mgmt.db
  86. BIN
      test/test_files/meow.jpeg
  87. BIN
      test/test_keys/alice-no-passwords.pgp
  88. BIN
      test/test_keys/bob-primary-with-password-bob-subkey-without.pgp
  89. BIN
      test/test_keys/carol-subkeys-password-carol.pgp
  90. BIN
      test/test_keys/david-encryption-subkey-password-encrypt-signing-subkey-password-sign.pgp
  91. BIN
      test/test_keys/erwin-primary-encrypted-erwin-subkey-unencrypted.pgp
  92. +1580
    -0
      test/test_keys/import_keys_mega_concat.asc
  93. +17
    -0
      test/test_keys/import_multi_keys_5_rev.asc
  94. +57
    -0
      test/test_keys/priv/BIC_SYSTEMA_0xDA3FB4B9_priv.asc
  95. +57
    -0
      test/test_keys/priv/BIC_SYSTEMB_0x54139F26_priv.asc
  96. +187
    -0
      test/test_keys/priv/import_keys_alt_3-0x0EFC0849_priv.asc
  97. +106
    -0
      test/test_keys/priv/import_keys_multi_0-0xA1B2B234_priv.asc
  98. +106
    -0
      test/test_keys/priv/import_keys_multi_1-0x38CCF3A6_priv.asc
  99. +106
    -0
      test/test_keys/priv/import_keys_multi_1_expiry-0x38CCF3A6_priv.asc
  100. +106
    -0
      test/test_keys/priv/import_keys_multi_2-0xFDC1C32B_priv.asc

+ 11
- 0
Makefile.conf View File

@ -266,11 +266,22 @@ endif
######### Post processing assignments ########
# These variables are ineffective when set anywhere else but here.
# KB: I have no idea why we do this - it totally defeats the purpose of
# local.conf.
# For now: set if has no value.
ifeq ($(OPENPGP),SEQUOIA)
ifeq ($(SEQUOIA_CFLAGS),)
SEQUOIA_CFLAGS=$(shell pkg-config --cflags-only-other sequoia-openpgp)
endif
ifeq ($(SEQUOIA_LDFLAGS),)
SEQUOIA_LDFLAGS=$(shell pkg-config --libs-only-l --libs-only-other sequoia-openpgp)
endif
ifeq ($(SEQUOIA_LIB),)
SEQUOIA_LIB=$(shell pkg-config --libs-only-L sequoia-openpgp)
endif
ifeq ($(SEQUOIA_INC),)
SEQUOIA_INC=$(shell pkg-config --cflags-only-I sequoia-openpgp)
endif
CFLAGS+= $(SEQUOIA_CFLAGS)
LD_FLAGS+= $(SEQUOIA_LDFLAGS)
endif


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

@ -173,6 +173,8 @@
4378C79223D1AF1700D1AF3F /* ElectGroupKeyResetLeader.c in Sources */ = {isa = PBXBuildFile; fileRef = 4378C79023D1AF1700D1AF3F /* ElectGroupKeyResetLeader.c */; };
438C43B52167752C00C7425B /* labeled_int_list.h in Headers */ = {isa = PBXBuildFile; fileRef = 438C43AF2167752C00C7425B /* labeled_int_list.h */; };
438C43B62167752C00C7425B /* labeled_int_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 438C43B42167752C00C7425B /* labeled_int_list.c */; };
43C3778E246A8C0300962D22 /* internal_format.h in Headers */ = {isa = PBXBuildFile; fileRef = 43C37788246A8C0300962D22 /* internal_format.h */; };
43C3778F246A8C0300962D22 /* internal_format.c in Sources */ = {isa = PBXBuildFile; fileRef = 43C3778D246A8C0300962D22 /* internal_format.c */; };
43E4FBB22362C05600BC01F4 /* NegotiationRequestGrouped.c in Sources */ = {isa = PBXBuildFile; fileRef = 43E4FBAD2362C05600BC01F4 /* NegotiationRequestGrouped.c */; };
43E4FBB42362C29100BC01F4 /* GroupHandshake.c in Sources */ = {isa = PBXBuildFile; fileRef = 43E4FBB32362C29100BC01F4 /* GroupHandshake.c */; };
43F6921D1F164A47009418F5 /* resource_id.c in Sources */ = {isa = PBXBuildFile; fileRef = 43F6921C1F164A47009418F5 /* resource_id.c */; };
@ -426,6 +428,8 @@
438C43962167582400C7425B /* sync_api.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sync_api.h; path = ../src/sync_api.h; sourceTree = "<group>"; };
438C43AF2167752C00C7425B /* labeled_int_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = labeled_int_list.h; path = ../src/labeled_int_list.h; sourceTree = "<group>"; };
438C43B42167752C00C7425B /* labeled_int_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = labeled_int_list.c; path = ../src/labeled_int_list.c; sourceTree = "<group>"; };
43C37788246A8C0300962D22 /* internal_format.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = internal_format.h; path = ../src/internal_format.h; sourceTree = "<group>"; };
43C3778D246A8C0300962D22 /* internal_format.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = internal_format.c; path = ../src/internal_format.c; sourceTree = "<group>"; };
43D47A8A225CC60600E97C5B /* pEpTrustWords-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "pEpTrustWords-Info.plist"; path = "/Users/dirk/projects/pEp/pEpEngine/build-mac/pEpTrustWords-Info.plist"; sourceTree = "<absolute>"; };
43E4FBAD2362C05600BC01F4 /* NegotiationRequestGrouped.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = NegotiationRequestGrouped.c; path = ../asn.1/NegotiationRequestGrouped.c; sourceTree = "<group>"; };
43E4FBB32362C29100BC01F4 /* GroupHandshake.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = GroupHandshake.c; path = ../asn.1/GroupHandshake.c; sourceTree = "<group>"; };
@ -728,6 +732,8 @@
64A8264B1B455C5600EECAF0 /* srcref */ = {
isa = PBXGroup;
children = (
43C3778D246A8C0300962D22 /* internal_format.c */,
43C37788246A8C0300962D22 /* internal_format.h */,
43188ABE23C4BBDD008EF79C /* distribution_codec.c */,
43188ABF23C4BBDE008EF79C /* distribution_codec.h */,
43188AA223C4B4B3008EF79C /* keyreset_command.c */,
@ -820,6 +826,7 @@
159EF42822B6D3E900149C0C /* pgp_sequoia.h in Headers */,
15B037E222B2B822002D664C /* per_encoder.h in Headers */,
15B0380F22B2B823002D664C /* Sync.h in Headers */,
43C3778E246A8C0300962D22 /* internal_format.h in Headers */,
15B0380422B2B822002D664C /* constr_SET_OF.h in Headers */,
15B0381322B2B823002D664C /* asn_application.h in Headers */,
15B0380322B2B822002D664C /* OwnKeysRequester.h in Headers */,
@ -1172,6 +1179,7 @@
64A826811B455D0800EECAF0 /* pEpEngine.c in Sources */,
15B037FF22B2B822002D664C /* per_opentype.c in Sources */,
43188A9823C4B2DE008EF79C /* KeySync_fsm.c in Sources */,
43C3778F246A8C0300962D22 /* internal_format.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};


+ 3
- 1
build-windows/generate_code.cmd View File

@ -71,6 +71,8 @@ IF %ERRORLEVEL% NEQ 0 (
DEL *-sample.c
CD %pwd%\..
IF NOT EXIST pEp mklink /d pEp pEpEngine\src
RD /S/Q pEp
MKDIR pEp
XCOPY pEpEngine\src\*.h pEp\ /Y/F/I
POPD

+ 130
- 3
build-windows/libpEpasn1/libpEpasn1.vcxproj View File

@ -90,13 +90,140 @@
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\asn.1\*.h" />
<None Include="..\generate_code.cmd" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\asn.1\*.c" />
<ClCompile Include="..\..\asn.1\asn_codecs_prim.c" />
<ClCompile Include="..\..\asn.1\asn_SEQUENCE_OF.c" />
<ClCompile Include="..\..\asn.1\asn_SET_OF.c" />
<ClCompile Include="..\..\asn.1\Beacon.c" />
<ClCompile Include="..\..\asn.1\ber_decoder.c" />
<ClCompile Include="..\..\asn.1\ber_tlv_length.c" />
<ClCompile Include="..\..\asn.1\ber_tlv_tag.c" />
<ClCompile Include="..\..\asn.1\BIT_STRING.c" />
<ClCompile Include="..\..\asn.1\BOOLEAN.c" />
<ClCompile Include="..\..\asn.1\Command.c" />
<ClCompile Include="..\..\asn.1\Commands.c" />
<ClCompile Include="..\..\asn.1\CommitAccept.c" />
<ClCompile Include="..\..\asn.1\CommitAcceptForGroup.c" />
<ClCompile Include="..\..\asn.1\CommitAcceptOfferer.c" />
<ClCompile Include="..\..\asn.1\CommitAcceptRequester.c" />
<ClCompile Include="..\..\asn.1\CommitReject.c" />
<ClCompile Include="..\..\asn.1\constraints.c" />
<ClCompile Include="..\..\asn.1\constr_CHOICE.c" />
<ClCompile Include="..\..\asn.1\constr_SEQUENCE.c" />
<ClCompile Include="..\..\asn.1\constr_SEQUENCE_OF.c" />
<ClCompile Include="..\..\asn.1\constr_SET_OF.c" />
<ClCompile Include="..\..\asn.1\constr_TYPE.c" />
<ClCompile Include="..\..\asn.1\der_encoder.c" />
<ClCompile Include="..\..\asn.1\Distribution.c" />
<ClCompile Include="..\..\asn.1\ElectGroupKeyResetLeader.c" />
<ClCompile Include="..\..\asn.1\GroupHandshake.c" />
<ClCompile Include="..\..\asn.1\GroupKeysAndClose.c" />
<ClCompile Include="..\..\asn.1\GroupKeysForNewMember.c" />
<ClCompile Include="..\..\asn.1\GroupKeysUpdate.c" />
<ClCompile Include="..\..\asn.1\GroupTrustThisKey.c" />
<ClCompile Include="..\..\asn.1\Hash.c" />
<ClCompile Include="..\..\asn.1\Hex.c" />
<ClCompile Include="..\..\asn.1\Identity.c" />
<ClCompile Include="..\..\asn.1\IdentityList.c" />
<ClCompile Include="..\..\asn.1\InitUnledGroupKeyReset.c" />
<ClCompile Include="..\..\asn.1\INTEGER.c" />
<ClCompile Include="..\..\asn.1\ISO639-1.c" />
<ClCompile Include="..\..\asn.1\KeyReset.c" />
<ClCompile Include="..\..\asn.1\KeySync.c" />
<ClCompile Include="..\..\asn.1\NativeEnumerated.c" />
<ClCompile Include="..\..\asn.1\NativeInteger.c" />
<ClCompile Include="..\..\asn.1\NegotiationOpen.c" />
<ClCompile Include="..\..\asn.1\NegotiationRequest.c" />
<ClCompile Include="..\..\asn.1\NegotiationRequestGrouped.c" />
<ClCompile Include="..\..\asn.1\OCTET_STRING.c" />
<ClCompile Include="..\..\asn.1\OwnKeysOfferer.c" />
<ClCompile Include="..\..\asn.1\OwnKeysRequester.c" />
<ClCompile Include="..\..\asn.1\pdu_collection.c" />
<ClCompile Include="..\..\asn.1\per_decoder.c" />
<ClCompile Include="..\..\asn.1\per_encoder.c" />
<ClCompile Include="..\..\asn.1\per_opentype.c" />
<ClCompile Include="..\..\asn.1\per_support.c" />
<ClCompile Include="..\..\asn.1\PrintableString.c" />
<ClCompile Include="..\..\asn.1\PString.c" />
<ClCompile Include="..\..\asn.1\Rollback.c" />
<ClCompile Include="..\..\asn.1\Sync.c" />
<ClCompile Include="..\..\asn.1\SynchronizeGroupKeys.c" />
<ClCompile Include="..\..\asn.1\TID.c" />
<ClCompile Include="..\..\asn.1\UTF8String.c" />
<ClCompile Include="..\..\asn.1\Version.c" />
<ClCompile Include="..\..\asn.1\xer_decoder.c" />
<ClCompile Include="..\..\asn.1\xer_encoder.c" />
<ClCompile Include="..\..\asn.1\xer_support.c" />
</ItemGroup>
<ItemGroup>
<None Include="..\generate_code.cmd" />
<ClInclude Include="..\..\asn.1\asn_application.h" />
<ClInclude Include="..\..\asn.1\asn_codecs.h" />
<ClInclude Include="..\..\asn.1\asn_codecs_prim.h" />
<ClInclude Include="..\..\asn.1\asn_internal.h" />
<ClInclude Include="..\..\asn.1\asn_SEQUENCE_OF.h" />
<ClInclude Include="..\..\asn.1\asn_SET_OF.h" />
<ClInclude Include="..\..\asn.1\asn_system.h" />
<ClInclude Include="..\..\asn.1\Beacon.h" />
<ClInclude Include="..\..\asn.1\ber_decoder.h" />
<ClInclude Include="..\..\asn.1\ber_tlv_length.h" />
<ClInclude Include="..\..\asn.1\ber_tlv_tag.h" />
<ClInclude Include="..\..\asn.1\BIT_STRING.h" />
<ClInclude Include="..\..\asn.1\BOOLEAN.h" />
<ClInclude Include="..\..\asn.1\Command.h" />
<ClInclude Include="..\..\asn.1\Commands.h" />
<ClInclude Include="..\..\asn.1\CommitAccept.h" />
<ClInclude Include="..\..\asn.1\CommitAcceptForGroup.h" />
<ClInclude Include="..\..\asn.1\CommitAcceptOfferer.h" />
<ClInclude Include="..\..\asn.1\CommitAcceptRequester.h" />
<ClInclude Include="..\..\asn.1\CommitReject.h" />
<ClInclude Include="..\..\asn.1\constraints.h" />
<ClInclude Include="..\..\asn.1\constr_CHOICE.h" />
<ClInclude Include="..\..\asn.1\constr_SEQUENCE.h" />
<ClInclude Include="..\..\asn.1\constr_SEQUENCE_OF.h" />
<ClInclude Include="..\..\asn.1\constr_SET_OF.h" />
<ClInclude Include="..\..\asn.1\constr_TYPE.h" />
<ClInclude Include="..\..\asn.1\der_encoder.h" />
<ClInclude Include="..\..\asn.1\Distribution.h" />
<ClInclude Include="..\..\asn.1\ElectGroupKeyResetLeader.h" />
<ClInclude Include="..\..\asn.1\GroupHandshake.h" />
<ClInclude Include="..\..\asn.1\GroupKeysAndClose.h" />
<ClInclude Include="..\..\asn.1\GroupKeysForNewMember.h" />
<ClInclude Include="..\..\asn.1\GroupKeysUpdate.h" />
<ClInclude Include="..\..\asn.1\GroupTrustThisKey.h" />
<ClInclude Include="..\..\asn.1\Hash.h" />
<ClInclude Include="..\..\asn.1\Hex.h" />
<ClInclude Include="..\..\asn.1\Identity.h" />
<ClInclude Include="..\..\asn.1\IdentityList.h" />
<ClInclude Include="..\..\asn.1\InitUnledGroupKeyReset.h" />
<ClInclude Include="..\..\asn.1\INTEGER.h" />
<ClInclude Include="..\..\asn.1\ISO639-1.h" />
<ClInclude Include="..\..\asn.1\KeyReset.h" />
<ClInclude Include="..\..\asn.1\KeySync.h" />
<ClInclude Include="..\..\asn.1\NativeEnumerated.h" />
<ClInclude Include="..\..\asn.1\NativeInteger.h" />
<ClInclude Include="..\..\asn.1\NegotiationOpen.h" />
<ClInclude Include="..\..\asn.1\NegotiationRequest.h" />
<ClInclude Include="..\..\asn.1\NegotiationRequestGrouped.h" />
<ClInclude Include="..\..\asn.1\OCTET_STRING.h" />
<ClInclude Include="..\..\asn.1\OwnKeysOfferer.h" />
<ClInclude Include="..\..\asn.1\OwnKeysRequester.h" />
<ClInclude Include="..\..\asn.1\per_decoder.h" />
<ClInclude Include="..\..\asn.1\per_encoder.h" />
<ClInclude Include="..\..\asn.1\per_opentype.h" />
<ClInclude Include="..\..\asn.1\per_support.h" />
<ClInclude Include="..\..\asn.1\PrintableString.h" />
<ClInclude Include="..\..\asn.1\PString.h" />
<ClInclude Include="..\..\asn.1\Rollback.h" />
<ClInclude Include="..\..\asn.1\Sync.h" />
<ClInclude Include="..\..\asn.1\SynchronizeGroupKeys.h" />
<ClInclude Include="..\..\asn.1\TID.h" />
<ClInclude Include="..\..\asn.1\UTF8String.h" />
<ClInclude Include="..\..\asn.1\Version.h" />
<ClInclude Include="..\..\asn.1\xer_decoder.h" />
<ClInclude Include="..\..\asn.1\xer_encoder.h" />
<ClInclude Include="..\..\asn.1\xer_support.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />

+ 260
- 1568
build-windows/libpEpasn1/libpEpasn1.vcxproj.filters
File diff suppressed because it is too large
View File


+ 5
- 0
build-windows/pEpEngine.vcxproj View File

@ -139,6 +139,7 @@
<ClCompile Include="..\src\etpan_mime.c" />
<ClCompile Include="..\src\growing_buf.c" />
<ClCompile Include="..\src\identity_list.c" />
<ClCompile Include="..\src\internal_format.c" />
<ClCompile Include="..\src\keymanagement.c" />
<ClCompile Include="..\src\keyreset_command.c" />
<ClCompile Include="..\src\KeySync_fsm.c" />
@ -180,6 +181,7 @@
<ClInclude Include="..\src\fsm_common.h" />
<ClInclude Include="..\src\growing_buf.h" />
<ClInclude Include="..\src\identity_list.h" />
<ClInclude Include="..\src\internal_format.h" />
<ClInclude Include="..\src\keymanagement.h" />
<ClInclude Include="..\src\KeySync_fsm.h" />
<ClInclude Include="..\src\key_reset.h" />
@ -222,6 +224,9 @@
<Project>{9a67164d-b8f8-4601-a24b-28afe774d41c}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="generate_code.cmd" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>

+ 11
- 0
build-windows/pEpEngine.vcxproj.filters View File

@ -126,6 +126,9 @@
<ClCompile Include="..\src\distribution_codec.c">
<Filter>Quelldateien</Filter>
</ClCompile>
<ClCompile Include="..\src\internal_format.c">
<Filter>Quelldateien</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\keymanagement.h">
@ -266,8 +269,16 @@
<ClInclude Include="..\src\sync_codec.h">
<Filter>Headerdateien</Filter>
</ClInclude>
<ClInclude Include="..\src\internal_format.h">
<Filter>Headerdateien</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="..\LICENSE.txt" />
</ItemGroup>
<ItemGroup>
<None Include="generate_code.cmd">
<Filter>Quelldateien</Filter>
</None>
</ItemGroup>
</Project>

+ 1
- 1
clean_sync_leftovers.sh View File

@ -6,5 +6,5 @@ cd ../sync; hg status . | sed '/?\ /!d' | sed 's/?\ //' | xargs rm
cd ..
branch=`hg branch`
if [ "$branch" = "sync" ]; then
rm src/KeySync_fsm.c src/KeySync_fsm.h src/Sync_actions.c src/Sync_event.c src/Sync_event.h src/Sync_func.c src/Sync_func.h src/Sync_impl.c src/Sync_impl.h src/sync_codec.c src/sync_codec.h
rm -f src/TrustSync_fsm.c src/TrustSync_fsm.h src/KeySync_fsm.c src/KeySync_fsm.h src/Sync_actions.c src/Sync_event.c src/Sync_event.h src/Sync_func.c src/Sync_func.h src/Sync_impl.c src/Sync_impl.h src/sync_codec.c src/sync_codec.h
fi

+ 0
- 1
doc/build-fedora.md View File

@ -48,7 +48,6 @@ make install
mkdir -p ~/code/pep-engine
hg clone https://pep.foundation/dev/repos/pEpEngine/ ~/code/pep-engine
cd ~/code/pep-engine
hg update sync
mkdir ~/code/pep-engine/build
~~~


+ 0
- 161
doc/build-macos.md View File

@ -1,161 +0,0 @@
<!-- Copyright 2015-2017, pEp foundation, Switzerland
This file is part of the pEp Engine
This file may be used under the terms of the Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) License
See CC_BY-SA.txt -->
# Build instructions for macOS Sierra
# Installing packaged dependencies
You will find instructions for using either Macports or Homebrew below to install the compile-time dependencies.
## MacPorts
Install MacPorts according to the instructions found [here](https://www.macports.org/install.php).
Ensure that Macports' binary paths (`/opt/local/bin` and `/opt/local/sbin`) are in your `PATH` environment variable.
~~~
# general
sudo port install mercurial
# YML2
sudo port install py27-lxml
# libetpan
sudo port install git autoconf automake libtool
# asn1c
sudo port install asn1c
# engine
sudo port install gpgme
~~~
Ensure that `python` is Python 2.7:
~~~
sudo port select python python27
~~~
## Homebrew
Install Homebrew according to the instructions found [here](https://docs.brew.sh/Installation.html).
Ensure that Homebrew's binary path (`/usr/local/bin`) is in your `PATH` environment variable.
~~~
# general
brew install mercurial
# YML2
# If you don't have pip with your Python 2 distribution, you can install it with brew
brew install python
pip2 install --user lxml
# libetpan
brew install git autoconf automake libtool
# asn1c
brew install asn1c
# engine
brew install gpgme
~~~
# Installing unpackaged dependencies
## YML2
To check if lxml is properly installed, you can use this lxml "hello world" command:
~~~
python2 -c 'from lxml import etree; root = etree.Element("root"); print(root.tag)'
~~~
It should generate the following output:
~~~
root
~~~
~~~
mkdir -p ~/code/yml2
hg clone https://pep.foundation/dev/repos/yml2/ ~/code/yml2
~~~
## libetpan
pEp Engine requires libetpan with a set of patches that have not been upstreamed yet.
~~~
mkdir -p ~/code/libetpan
git clone https://github.com/fdik/libetpan ~/code/libetpan
cd ~/code/libetpan
mkdir ~/code/libetpan/build
./autogen.sh --prefix="$HOME/code/libetpan/build"
make
make install
~~~
## GPGME
The MacPorts-packaged GPGME links to a version of GNU libiconv that has files in the same include/library paths as GPGME. This version of libiconv must not be visible to the linker when the pEp Engine is build or run.
Thus the files of the GPGME distribution will have to be manually copied to separate include/library folders, so that no include or library paths used for building the pEp Engine contains files of MacPorts' libiconv distribution.
~~~
mkdir -p ~/code/gpgme/build/include
cp /opt/local/include/gpg*.h ~/code/gpgme/build/include
mkdir -p ~/code/gpgme/build/lib
cp -r /opt/local/lib/libgpg* ~/code/gpgme/build/lib
~~~
It's of course possible to skip MacPort's version, and use a self-compiled GPGME/GPG. The default build configuration assumes this case, and assumes you have installed your GPGME with `$(HOME)` as your prefix.
# 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
~~~
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`.
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, and libetpan.
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.
~~~
PREFIX=$(HOME)/code/engine/build
PER_MACHINE_DIRECTORY=$(PREFIX)/share/pEp
YML2_PATH=$(HOME)/code/yml2
ETPAN_LIB=-L$(HOME)/code/libetpan/build/lib
ETPAN_INC=-I$(HOME)/code/libetpan/build/include
GPGME_LIB=-L$(HOME)/lib
GPGME_INC=-I$(HOME)/include
~~~
The engine is built as follows:
~~~
make all
make db
~~~
If your build fails with an error message similar to the following:
~~~
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/locale.py", line 477, in _parse_localename
raise ValueError, 'unknown locale: %s' % localename
ValueError: unknown locale: UTF-8
~~~
or any other locale-related Python error, make sure Python does not have any locale-related environment variables set.
Usually, `unset LC_CTYPE` is sufficient to take care of the problem, but it depends on your macOS's regional and language settings and which terminal emulator you use.
This is a bug in Python, see [https://bugs.python.org/issue18378#msg215215](https://bugs.python.org/issue18378#msg215215).
The unit tests can be run without the engine library being installed, however `system.db` must be installed:
~~~
make -C db install
~~~
Since `system.db` rarely changes, its installation is not needed for every build.
Tests can be compiled and executed with the following commands:
~~~
make -C test compile
make test
~~~

+ 0
- 43
doc/build-netpgp.md View File

@ -1,43 +0,0 @@
# Using NetPGP instead of GnuPG
## Prepare
Get OpenSSL:
curl -O https://www.openssl.org/source/openssl-1.1.0f.tar.gz
Build it using the openssl-for-ios build script:
git clone https://github.com/sinofool/build-openssl-ios/ .
and build/install it as shared library.
```
wget https://www.openssl.org/source/old/1.0.1/openssl-1.0.1u.tar.gz
tar xvfz openssl-1.0.1u.tar.gz
cd openssl-1.0.1u
./Configure darwin64-x86_64-cc --prefix=$HOME shared
make install
```
Get and autoconf NetPGP
```
cd $SRC
hg clone https://pep.foundation/dev/repos/netpgp-et/
cd netpgp-et
autoreconf -i
```
## Build
Important : LDFLAGS is set to help finding OpenSSL shared lib. If not set,
system's default libcrypto may silently be used instead, causing memory
corruption or crash at runtime.
```
mkdir netpgp_debug
cd netpgp_debug
$SRC/netpgp-et/configure --with-openssl=$HOME --prefix=$HOME CPPFLAGS=-DDEBUG CXXFLAGS="-g -O0" LDFLAGS="-L${HOME}/lib"
make
make install
```

+ 0
- 58
doc/readme.md View File

@ -1,58 +0,0 @@
<!-- Copyright 2015-2017, pEp foundation, Switzerland
This file is part of the pEp Engine
This file may be used under the terms of the Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) License
See CC_BY-SA.txt -->
# Information about the pEp Engine
# Dependencies
The p≡p Engine depends on the following projects:
- run-time dependencies
- One of the following OpenPGP implementations:
- GnuPG version 2.1.17 or later with GPGME (at least version 1.7.0) [https://gnupg.org/](https://gnupg.org/)
- For platforms not supporting pinentry (e.g. Android) - GnuPG version 2.0.30 with GPGME version 1.6.0 (or later) [https://gnupg.org/](https://gnupg.org/)
- a fork of NetPGP, [https://pep.foundation/dev/repos/netpgp-et/](https://pep.foundation/dev/repos/netpgp-et/)
- Sequoia, which in turn requires:
- Rust
- libnettle
- One of the following MIME libraries:
- a fork of libetpan, [https://github.com/fdik/libetpan](https://github.com/fdik/libetpan)
- pEpMIME
- zlib, [http://zlib.net/](http://zlib.net/)
- libcurl (Only with NetPGP), [https://curl.haxx.se/libcurl/](https://curl.haxx.se/libcurl/)
- libuuid, [https://www.kernel.org/pub/linux/utils/util-linux/](https://www.kernel.org/pub/linux/utils/util-linux/)
- SQLite, [https://sqlite.org](https://sqlite.org)
- OpenSSL (Only with NetPGP), [https://www.openssl.org](https://www.openssl.org)
- compile-time dependencies
- asn1c (version v0.9.28), [http://lionet.info/asn1c/blog/](http://lionet.info/asn1c/blog/)
- yml2, [https://fdik.org/yml//toolchain](https://fdik.org/yml//toolchain)
- Python 3
- LXML
- One of the following build systems:
- GNU make (on Linux and macOS)
- MSBuild distributed with Microsoft Visual Studio 2015 (on Windows)
- One of the following compilers for C and C++:
- GNU GCC (on Linux)
- Apple "clang" LLVM (on MacOS)
- Microsoft MSVC/MSVC++ distributed with Microsoft Visual Studio 2015 (on Windows)
- A script for compiling OpenSSL for iOS, [https://github.com/sinofool/build-openssl-ios/](https://github.com/sinofool/build-openssl-ios/)
- binutils
# The pEp Engine's databases
The p≡p Engine uses two databases:
- the management database
- `~/.pEp_management` on \*NIX
- `%LOCALAPPDATA%\pEp\management.db` on Windows
- the Trustword database
- `/usr/local/share/system.db` on \*NIX
- `%ALLUSERSPROFILE%\pEp\system.db` on Windows
The management db is created by the first call of `init()` of p≡p Engine.
It does not need to be created manually.
`system.db` is created by using the DDL in `db/create_system_db.sql`; the database content is created by `db/dic2csv.py` out of hunspell's dictionary packages (or something similar) and then imported using `sqlite3`'s `.import` command.
Dictionary files for different languages are part of the p≡p Engine source distribution.
You can test the Trustwords in `system.db` using `db/trustwords.py`.
Both Python tools have a `--help` switch.

+ 0
- 2
doc/testing.md View File

@ -1,2 +0,0 @@
# Testing
For the documentation of the tests, see `test/README.md`

+ 1
- 1
src/Makefile View File

@ -100,7 +100,7 @@ install_headers: $(TARGET)
timestamp.h identity_list.h bloblist.h stringpair.h message.h mime.h \
cryptotech.h sync_api.h blacklist.h pEp_string.h openpgp_compat.h mime.h \
labeled_int_list.h key_reset.h base64.h sync_codec.h distribution_codec.h \
status_to_string.h aux_mime_msg.h keyreset_command.h ../asn.1/*.h \
status_to_string.h aux_mime_msg.h keyreset_command.h platform.h platform_unix.h ../asn.1/*.h \
$(PREFIX)/include/pEp/
install: $(TARGET) install_headers


+ 10
- 12
src/aux_mime_msg.c View File

@ -73,7 +73,7 @@ DYNAMIC_API PEP_STATUS MIME_decrypt_message(
message* dec_msg = NULL;
*mime_plaintext = NULL;
status = mime_decode_message(mimetext, size, &tmp_msg);
status = mime_decode_message(mimetext, size, &tmp_msg, NULL);
if (status != PEP_STATUS_OK)
goto pEp_error;
@ -120,7 +120,7 @@ DYNAMIC_API PEP_STATUS MIME_decrypt_message(
}
if (*flags & PEP_decrypt_flag_src_modified) {
_mime_encode_message_internal(tmp_msg, false, modified_src, true, false);
mime_encode_message(tmp_msg, false, modified_src, false);
if (!modified_src) {
*flags &= (~PEP_decrypt_flag_src_modified);
decrypt_status = PEP_CANNOT_REENCRYPT; // Because we couldn't return it, I guess.
@ -128,7 +128,7 @@ DYNAMIC_API PEP_STATUS MIME_decrypt_message(
}
// FIXME: test with att
status = _mime_encode_message_internal(dec_msg, false, mime_plaintext, true, false);
status = mime_encode_message(dec_msg, false, mime_plaintext, false);
if (status == PEP_STATUS_OK)
{
@ -161,7 +161,7 @@ DYNAMIC_API PEP_STATUS MIME_encrypt_message(
message* enc_msg = NULL;
message* ret_msg = NULL;
status = mime_decode_message(mimetext, size, &tmp_msg);
status = mime_decode_message(mimetext, size, &tmp_msg, NULL);
if (status != PEP_STATUS_OK)
goto pEp_error;
@ -217,12 +217,10 @@ DYNAMIC_API PEP_STATUS MIME_encrypt_message(
goto pEp_error;
}
tmp_status = _mime_encode_message_internal(
ret_msg,
false,
mime_ciphertext,
false,
false);
tmp_status = mime_encode_message(ret_msg,
false,
mime_ciphertext,
false);
if (tmp_status != PEP_STATUS_OK)
status = tmp_status;
@ -250,7 +248,7 @@ DYNAMIC_API PEP_STATUS MIME_encrypt_message_for_self(
message* tmp_msg = NULL;
message* enc_msg = NULL;
status = mime_decode_message(mimetext, size, &tmp_msg);
status = mime_decode_message(mimetext, size, &tmp_msg, NULL);
if (status != PEP_STATUS_OK)
goto pEp_error;
@ -271,7 +269,7 @@ DYNAMIC_API PEP_STATUS MIME_encrypt_message_for_self(
goto pEp_error;
}
status = mime_encode_message(enc_msg, false, mime_ciphertext);
status = mime_encode_message(enc_msg, false, mime_ciphertext, false);
pEp_error:
free_message(tmp_msg);


+ 13
- 6
src/base64.c View File

@ -85,18 +85,22 @@ bloblist_t* base64_str_to_binary_blob(const char* input, int length) {
return NULL;
trim_end(input, &length);
void* blobby = NULL;
const char* input_curr;
input_curr = input;
const char* input_end = input_curr + length;
length = subtract_whitespace(input, length);
size_t final_length = (length / 4) * 3;
// padded -- FIXME: whitespace in between ==!!!!
if (*(input_end - 1) == '=') {
// padded -- FIXME: whitespace in between ==!!!!
if (final_length && *(input_end - 1) == '=') {
final_length -= 1;
if (*(input_end - 2) == '=')
// if final length is now decreased by 1 and greater than 0,
// we know there's a char at (input_end - 2).
if (final_length && *(input_end - 2) == '=')
final_length -=1;
}
else {
@ -115,7 +119,11 @@ bloblist_t* base64_str_to_binary_blob(const char* input, int length) {
return NULL;
}
}
void* blobby = calloc(final_length, 1);
if (!final_length)
goto pEp_error;
blobby = calloc(final_length, 1);
char* blobby_curr = (char*)blobby;
// if the last 1 or 2 bytes are padded, we do those after
@ -217,4 +225,3 @@ pEp_error:
free(blobby);
return NULL;
}

+ 75
- 6
src/baseprotocol.c View File

@ -30,14 +30,26 @@ PEP_STATUS base_decorate_message(
if (!(msg && payload && size && type))
return PEP_ILLEGAL_VALUE;
bloblist_t *bl = bloblist_add(msg->attachments, payload, size,
_base_type[type], "ignore_this_attachment.pEp");
if (bl == NULL) {
goto enomem;
bloblist_t *bl;
switch (type) {
case BASE_SYNC:
bl = bloblist_add(msg->attachments, payload, size,
_base_type[type], "sync.pEp");
break;
case BASE_KEYRESET:
bl = bloblist_add(msg->attachments, payload, size,
_base_type[type], "distribution.pEp");
break;
default:
bl = bloblist_add(msg->attachments, payload, size,
_base_type[type], "ignore_this_attachment.pEp");
}
else if (!msg->attachments) {
if (bl == NULL)
goto enomem;
else if (!msg->attachments)
msg->attachments = bl;
}
if (fpr && fpr[0] != '\0') {
char *sign;
@ -202,3 +214,60 @@ the_end:
free_stringlist(keylist);
return status;
}
PEP_STATUS try_base_prepare_message(
PEP_SESSION session,
const pEp_identity *me,
const pEp_identity *partner,
base_protocol_type type,
char *payload,
size_t size,
const char *fpr,
message **result
)
{
PEP_STATUS status = PEP_STATUS_OK;
assert(session && session->messageToSend && session->notifyHandshake);
assert(me);
assert(partner);
assert(payload);
assert(size);
assert(result);
assert(type == BASE_SYNC || type == BASE_KEYRESET);
if (!(session && session->messageToSend && session->notifyHandshake))
return PEP_ILLEGAL_VALUE;
if (!(me && partner && payload && size && result && type))
return PEP_ILLEGAL_VALUE;
// https://dev.pep.foundation/Engine/MessageToSendPassphrase
if (session->curr_passphrase) {
// first try with empty passphrase
char *passphrase = session->curr_passphrase;
session->curr_passphrase = NULL;
status = base_prepare_message(session, me, partner, type, payload, size, fpr, result);
session->curr_passphrase = passphrase;
if (!(status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE))
return status;
}
do {
// then try passphrases
status = base_prepare_message(session, me, partner, type, payload, size, fpr, result);
if (status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE) {
PEP_STATUS status2 = session->messageToSend(NULL);
if (status2 == PEP_PASSPHRASE_REQUIRED || status2 == PEP_WRONG_PASSPHRASE) {
pEp_identity *_me = identity_dup(me);
if (!_me)
return PEP_OUT_OF_MEMORY;
session->notifyHandshake(_me, NULL, SYNC_PASSPHRASE_REQUIRED);
}
}
} while (status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE);
return status;
}

+ 16
- 0
src/baseprotocol.h View File

@ -106,6 +106,22 @@ PEP_STATUS base_extract_message(
);
// this is the internal function to be used by asynchronous network protocol
// implementations
//
// this function is calling messageToSend(NULL) in case there is a missing or wrong passphrase
PEP_STATUS try_base_prepare_message(
PEP_SESSION session,
const pEp_identity *me,
const pEp_identity *partner,
base_protocol_type type,
char *payload,
size_t size,
const char *fpr,
message **result
);
#ifdef __cplusplus
}
#endif


+ 2
- 2
src/cryptotech.h View File

@ -65,7 +65,8 @@ typedef PEP_STATUS (*get_key_rating_t)(
);
typedef PEP_STATUS (*import_key_t)(PEP_SESSION session, const char *key_data,
size_t size, identity_list **private_keys);
size_t size, identity_list **private_keys, stringlist_t** imported_keys,
uint64_t* changed_key_index);
typedef PEP_STATUS (*recv_key_t)(PEP_SESSION session, const char *pattern);
@ -133,4 +134,3 @@ typedef uint64_t cryptotech_mask;
PEP_STATUS init_cryptotech(PEP_SESSION session, bool in_first);
void release_cryptotech(PEP_SESSION session, bool out_last);

+ 247
- 116
src/etpan_mime.c View File

@ -324,8 +324,7 @@ struct mailmime * get_file_part(
const char * mime_type,
char * data,
size_t length,
bool transport_encode,
bool set_attachment_forward_comment
bool is_nf_message_attachment // non-forwarded msg as att
)
{
char * disposition_name = NULL;
@ -373,7 +372,9 @@ struct mailmime * get_file_part(
encoding = NULL;
if (transport_encode) {
bool already_ascii = !(must_chunk_be_encoded(data, length, true));
if (!is_nf_message_attachment && !already_ascii) {
encoding_type = MAILMIME_MECHANISM_BASE64;
encoding = mailmime_mechanism_new(encoding_type, NULL);
if (encoding == NULL)
@ -389,7 +390,7 @@ struct mailmime * get_file_part(
stringpair_list_t* extra_params = NULL;
if (set_attachment_forward_comment)
if (is_nf_message_attachment)
extra_params = new_stringpair_list(new_stringpair("forwarded", "no"));
mime = part_new_empty(content, mime_fields, extra_params, 1);
@ -555,20 +556,37 @@ struct mailimf_mailbox * mailbox_from_string(
const char *address
)
{
assert(address);
if (!address)
return NULL;
struct mailimf_mailbox *mb = NULL;
char *_name = NULL;
char *_address = NULL;
assert(address);
_name = name ? strdup(name) : strdup("");
if (_name == NULL)
goto enomem;
_address = strdup(address);
if (_address == NULL)
goto enomem;
char* at = strstr(address, "@");
if (!at) {
// Presumed URI
int added_char_len = 6; // " " @URI
int new_addr_len = strlen(address) + added_char_len + 1;
_address = calloc(new_addr_len, 1);
if (_address == NULL)
goto enomem;
_address[0] = '"';
strlcat(_address, address, new_addr_len);
strlcat(_address, "\"@URI", new_addr_len);
}
else {
_address = strdup(address);
if (_address == NULL)
goto enomem;
}
mb = mailimf_mailbox_new(_name, _address);
assert(mb);
if (mb == NULL)
@ -1005,7 +1023,7 @@ bool must_chunk_be_encoded(const void* value, size_t size, bool ignore_fws) {
static PEP_STATUS interpret_MIME(struct mailmime *mime,
message *msg,
bool* raise_msg_attachment);
bool* has_possible_pEp_msg);
// This function was rewritten to use in-memory buffers instead of
// temporary files when the pgp/mime support was implemented for
@ -1063,8 +1081,7 @@ pEp_error:
static PEP_STATUS mime_attachment(
bloblist_t *blob,
struct mailmime **result,
bool transport_encode,
bool set_attachment_forward_comment
bool is_nf_message_attachment // non-forwarded msg as att
)
{
PEP_STATUS status = PEP_STATUS_OK;
@ -1086,11 +1103,8 @@ static PEP_STATUS mime_attachment(
pEp_rid_list_t* resource = parse_uri(blob->filename);
bool already_ascii = !(must_chunk_be_encoded(blob->value, blob->size, true));
mime = get_file_part(resource, mime_type, blob->value, blob->size,
(already_ascii ? false : transport_encode),
set_attachment_forward_comment);
is_nf_message_attachment);
free_rid_list(resource);
assert(mime);
@ -1109,12 +1123,23 @@ enomem:
return status;
}
// This ONLY deals with handling the body
// content when html parts are present - thus,
// text/plain and text/html of the body, and
// related inline attachments for the html
// part. Non-inline attachments are handled
// outside this call!!!!
//
// N.B. As a result, this will only touch the
// "contained message" of pEp 2.x messages
// on the initial encoding where it is turned
// into attachment data!!
static PEP_STATUS mime_html_text(
const char *plaintext,
const char *htmltext,
bloblist_t *attachments,
struct mailmime **result,
bool transport_encode
struct mailmime **result
)
{
PEP_STATUS status = PEP_STATUS_OK;
@ -1129,33 +1154,50 @@ static PEP_STATUS mime_html_text(
*result = NULL;
mime = part_multiple_new("multipart/alternative");
assert(mime);
if (mime == NULL)
goto enomem;
pEp_rid_list_t* resource = NULL;
int encoding_type = (transport_encode ? MAILMIME_MECHANISM_QUOTED_PRINTABLE : 0);
submime = get_text_part(NULL, "text/plain", plaintext, strlen(plaintext),
encoding_type);
free_rid_list(resource);
resource = NULL;
assert(submime);
if (submime == NULL)
goto enomem;
bool already_ascii = false;
int encoding_type = 0;
if (*plaintext != '\0') {
mime = part_multiple_new("multipart/alternative");
assert(mime);
if (mime == NULL)
goto enomem;
// KB: pEpMIME transition comment - if we start getting
// underencoding errors here, the change to checking
// for ASCII and then encoding - or not - is one place
// to start looking.
int pt_length = strlen(plaintext);
already_ascii = !(must_chunk_be_encoded(plaintext, pt_length, true));
encoding_type = (already_ascii ? 0 : MAILMIME_MECHANISM_QUOTED_PRINTABLE);
submime = get_text_part(NULL, "text/plain", plaintext,
pt_length,
encoding_type);
// reset
already_ascii = false;
encoding_type = 0;
free_rid_list(resource);
resource = NULL;
assert(submime);
if (submime == NULL)
goto enomem;
r = mailmime_smart_add_part(mime, submime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY) {
goto enomem;
}
else {
// mailmime_smart_add_part() takes ownership of submime
submime = NULL;
r = mailmime_smart_add_part(mime, submime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY) {
goto enomem;
}
else {
// mailmime_smart_add_part() takes ownership of submime
submime = NULL;
}
}
bool inlined_attachments = false;
bloblist_t* traversal_ptr = attachments;
@ -1175,60 +1217,88 @@ static PEP_STATUS mime_html_text(
if (submime == NULL)
goto enomem;
// This is where all of the html MIME stuff will go
top_level_html_mime = submime;
r = mailmime_smart_add_part(mime, top_level_html_mime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY) {
goto enomem;
}
else {
// mailmime_smart_add_part() takes ownership of submime
submime = NULL;
}
if (!mime)
mime = top_level_html_mime;
else {
r = mailmime_smart_add_part(mime, top_level_html_mime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY) {
goto enomem;
}
else {
// mailmime_smart_add_part() takes ownership of submime
submime = NULL;
}
}
}
else {
// Otherwise, html MIME stuff gets added to the top node
// - may be NULL if there's no multipart!
top_level_html_mime = mime;
}
// resource = new_rid_node(PEP_RID_FILENAME, "msg.html");
submime = get_text_part(NULL, "text/html", htmltext, strlen(htmltext),
encoding_type);
int ht_length = strlen(htmltext);
already_ascii = !(must_chunk_be_encoded(htmltext, ht_length, true));
encoding_type = (already_ascii ? 0 : MAILMIME_MECHANISM_QUOTED_PRINTABLE);
submime = get_text_part(NULL, "text/html", htmltext,
ht_length,
encoding_type);
free_rid_list(resource);
resource = NULL;
assert(submime);
if (submime == NULL)
goto enomem;
// IF there are no inlined attachments AND mime is NULL, then
// we just have an HTML body here and won't need to
// process inlined attachments - submime will actually be
// the mime root of from this function, at least.
r = mailmime_smart_add_part(top_level_html_mime, submime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY)
goto enomem;
else {
// mailmime_smart_add_part() takes ownership of submime
if (!top_level_html_mime) {
mime = submime;
submime = NULL;
}
bloblist_t *_a;
for (_a = attachments; _a != NULL; _a = _a->next) {
if (_a->disposition != PEP_CONTENT_DISP_INLINE)
continue;
status = mime_attachment(_a, &submime, transport_encode, false);
if (status != PEP_STATUS_OK)
return PEP_UNKNOWN_ERROR; // FIXME
else {
r = mailmime_smart_add_part(top_level_html_mime, submime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY) {
if (r == MAILIMF_ERROR_MEMORY)
goto enomem;
}
else {
// mailmime_smart_add_part() takes ownership of submime
submime = NULL;
}
}
bloblist_t *_a;
// This will never have an embedded pEp message attachment
// sent for encoding here, so we don't need to pass down
// "(don't) transport encode this" info. If it's here and
// it's not an ASCII "text/*" attachment, it'll get encoded
for (_a = attachments; _a != NULL; _a = _a->next) {
if (_a->disposition != PEP_CONTENT_DISP_INLINE)
continue;
status = mime_attachment(_a, &submime, false);
if (status != PEP_STATUS_OK)
return PEP_UNKNOWN_ERROR; // FIXME
r = mailmime_smart_add_part(top_level_html_mime, submime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY) {
goto enomem;
}
else {
// mailmime_smart_add_part() takes ownership of submime
submime = NULL;
}
}
}
*result = mime;
return PEP_STATUS_OK;
@ -1245,7 +1315,6 @@ enomem:
}
// FIXME: maybe need to add transport_encode field here
static struct mailimf_mailbox * identity_to_mailbox(const pEp_identity *ident)
{
char *_username = NULL;
@ -1363,6 +1432,9 @@ enomem:
return NULL;
}
// KB: This seems to be always called with "true",
// but there was probably a reason for this. So
// leave it for now.
static clist * stringlist_to_clist(stringlist_t *sl, bool transport_encode)
{
clist * cl = clist_new();
@ -1691,8 +1763,7 @@ static PEP_STATUS mime_encode_message_plain(
const message *msg,
bool omit_fields,
struct mailmime **result,
bool transport_encode,
bool set_attachment_forward_comment
bool has_pEp_msg_attachment
)
{
struct mailmime * mime = NULL;
@ -1700,13 +1771,13 @@ static PEP_STATUS mime_encode_message_plain(
int r;
PEP_STATUS status;
//char *subject;
char *plaintext;
const char *plaintext;
char *htmltext;
assert(msg);
assert(result);
//subject = (msg->shortmsg) ? msg->shortmsg : "pEp"; // not used, yet.
// * Process body content, including html's inlined attachments *
plaintext = (msg->longmsg) ? msg->longmsg : "";
htmltext = msg->longmsg_formatted;
@ -1714,23 +1785,37 @@ static PEP_STATUS mime_encode_message_plain(
/* first, we need to strip out the inlined attachments to ensure this
gets set up correctly */
status = mime_html_text(plaintext, htmltext, msg->attachments, &mime,
transport_encode);
// Note: this only, regardless of whether this is being done
// for the to-be-embedded message attachment generation or
// an encapsulating message which contains this, touches
// the body text of this input message. So transport encoding
// only refers to the body content here and inlined-attachments, and
// is decided WITHIN this function, not as an argument.
status = mime_html_text(plaintext, htmltext, msg->attachments, &mime);
if (status != PEP_STATUS_OK)
goto pEp_error;
}
else {
else { /* body content only consists of a plaintext block */
pEp_rid_list_t* resource = NULL;
int pt_length = strlen(plaintext);
if (is_PGP_message_text(plaintext)) {
resource = NULL;
int encoding_type = (transport_encode ? MAILMIME_MECHANISM_7BIT : 0);
// So... I think we got overencoding here once, which would be a bug
// in libetpan, unless it had to do with whitespace. If removing
// transport encoding as a calculation here somehow leads to overencoding,
// either we or libetpan are doing something bad.
// int encoding_type = (transport_encode ? MAILMIME_MECHANISM_7BIT : 0);
mime = get_text_part(resource, "application/octet-stream", plaintext,
strlen(plaintext), encoding_type);
pt_length, MAILMIME_MECHANISM_7BIT);
}
else {
resource = NULL;
int encoding_type = (transport_encode ? MAILMIME_MECHANISM_QUOTED_PRINTABLE : 0);
bool already_ascii = !(must_chunk_be_encoded(plaintext, pt_length, true));
int encoding_type = (already_ascii ? MAILMIME_MECHANISM_7BIT : MAILMIME_MECHANISM_QUOTED_PRINTABLE);
mime = get_text_part(resource, "text/plain", plaintext, strlen(plaintext),
encoding_type);
}
@ -1741,10 +1826,21 @@ static PEP_STATUS mime_encode_message_plain(
goto enomem;
}
/* Body content processed, now process normal attachments */
bool normal_attachments = false;
bloblist_t* traversal_ptr = msg->attachments;
// If there were any inline attachments, they should have
// been stripped out in mime_html_text and dealt with.
// I'm not entirely sure what the alternative case
// is here. But basically, if there are any non-inlined
// attachments to deal with, this is designed to
// make sure we process them. So flag it for
// "hey, Bob, you got some regular attachments here"
// so Bob (obviously, the MIME engine is called Bob)
// can do the right thing in the next block.
while (traversal_ptr) {
if (traversal_ptr->disposition != PEP_CONTENT_DISP_INLINE) {
normal_attachments = true;
@ -1773,13 +1869,18 @@ static PEP_STATUS mime_encode_message_plain(
bloblist_t *_a;
bool first_one = true;
// Go through the non-inline attachments and add em.
for (_a = msg->attachments; _a != NULL; _a = _a->next) {
if (_a->disposition == PEP_CONTENT_DISP_INLINE)
continue;
status = mime_attachment(_a, &submime, transport_encode,
(first_one && set_attachment_forward_comment));
// solely for readability.
bool is_pEp_msg_attachment = (first_one && has_pEp_msg_attachment);
status = mime_attachment(_a, &submime,
is_pEp_msg_attachment);
if (status != PEP_STATUS_OK)
goto pEp_error;
@ -1891,12 +1992,11 @@ enomem:
return status;
}
PEP_STATUS _mime_encode_message_internal(
DYNAMIC_API PEP_STATUS mime_encode_message(
const message * msg,
bool omit_fields,
char **mimetext,
bool transport_encode,
bool set_attachment_forward_comment
bool has_pEp_msg_attachment
)
{
PEP_STATUS status = PEP_STATUS_OK;
@ -1916,12 +2016,12 @@ PEP_STATUS _mime_encode_message_internal(
switch (msg->enc_format) {
case PEP_enc_none:
status = mime_encode_message_plain(msg, omit_fields, &mime, transport_encode, set_attachment_forward_comment);
status = mime_encode_message_plain(msg, omit_fields, &mime, has_pEp_msg_attachment);
break;
// I'm presuming we should hardcore ignoring set_attachment_forward_comment here...
// I'm presuming we should hardcore ignoring has_pEp_msg_attachment here...
case PEP_enc_inline:
status = mime_encode_message_plain(msg, omit_fields, &mime, transport_encode, false);
status = mime_encode_message_plain(msg, omit_fields, &mime, false);
break;
case PEP_enc_S_MIME:
@ -1988,6 +2088,7 @@ pEp_error:
static pEp_identity *mailbox_to_identity(const struct mailimf_mailbox * mb)
{
char *username = NULL;
char *address = NULL;
assert(mb);
assert(mb->mb_addr_spec);
@ -2003,14 +2104,30 @@ static pEp_identity *mailbox_to_identity(const struct mailimf_mailbox * mb)
goto enomem;
}
pEp_identity *ident = new_identity(mb->mb_addr_spec, NULL, NULL, username);
const char* raw_addr = mb->mb_addr_spec;
if (raw_addr && raw_addr[0] == '"') {
int addr_len = strlen(raw_addr);
if (addr_len >= 6) { // ""@URI
const char* endcheck = strstr(raw_addr + 1, "\"@URI");
if (endcheck && *(endcheck + 5) == '\0') {
int actual_size = addr_len - 6;
address = calloc(actual_size + 1, 1);
if (!address)
goto enomem;
strlcpy(address, raw_addr + 1, actual_size + 1);
}
}
}
pEp_identity *ident = new_identity(address ? address : raw_addr, NULL, NULL, username);
if (ident == NULL)
goto enomem;
free(username);
free(address);
return ident;
enomem:
free(address);
free(username);
return NULL;
}
@ -2496,10 +2613,30 @@ static PEP_STATUS process_multipart_related(struct mailmime *mime,
return status;
}
static bool _is_marked_as_attachment(struct mailmime_fields *fields)
{
if (!(fields && fields->fld_list))
return false;
clistiter *cur;
for (cur = clist_begin(fields->fld_list); cur != NULL ; cur = clist_next(cur)) {
struct mailmime_field * field = clist_content(cur);
if (!(field && field->fld_type == MAILMIME_FIELD_DISPOSITION &&
field->fld_data.fld_disposition &&
field->fld_data.fld_disposition->dsp_type))
continue;
if (field->fld_data.fld_disposition->dsp_type->dsp_type ==
MAILMIME_DISPOSITION_TYPE_ATTACHMENT)
return true;
}
return false;
}
static PEP_STATUS interpret_MIME(
struct mailmime *mime,
message *msg,
bool* raise_msg_attachment
bool* has_possible_pEp_msg
)
{
PEP_STATUS status = PEP_STATUS_OK;
@ -2507,6 +2644,7 @@ static PEP_STATUS interpret_MIME(
assert(mime);
assert(msg);
struct mailmime_fields *fields = mime->mm_mime_fields;
struct mailmime_content *content = mime->mm_content_type;
if (content) {
if (_is_multipart(content, "alternative")) {
@ -2583,21 +2721,22 @@ static PEP_STATUS interpret_MIME(
return PEP_ILLEGAL_VALUE;
clistiter *cur;
// only add raise_msg_attachment on 2nd part!
// only add has_possible_pEp_msg on 2nd part!
int _att_count = 0;
for (cur = clist_begin(partlist); cur; cur = clist_next(cur), _att_count++) {
struct mailmime *part= clist_content(cur);
if (part == NULL)
return PEP_ILLEGAL_VALUE;
status = interpret_MIME(part, msg, _att_count == 1 ? raise_msg_attachment : NULL);
status = interpret_MIME(part, msg, _att_count == 1 ? has_possible_pEp_msg : NULL);
if (status != PEP_STATUS_OK)
return status;
}
}
else {
if (_is_text_part(content, "html") &&
msg->longmsg_formatted == NULL &&
msg->longmsg == NULL) {
!_is_marked_as_attachment(fields) &&
msg->longmsg_formatted == NULL &&
msg->longmsg == NULL) {
status = interpret_body(mime, &msg->longmsg_formatted,
NULL);
if (status)
@ -2609,21 +2748,23 @@ static PEP_STATUS interpret_MIME(
return status;
}
else if (_is_text_part(content, "plain") &&
msg->longmsg == NULL && msg->longmsg_formatted == NULL) {
!_is_marked_as_attachment(fields) &&
msg->longmsg == NULL && msg->longmsg_formatted == NULL) {
status = interpret_body(mime, &msg->longmsg, NULL);
if (status)
return status;
}
else if (_is_text_part(content, NULL) &&
!_is_text_part(content, "plain") &&
msg->longmsg == NULL) {
!_is_marked_as_attachment(fields) &&
!_is_text_part(content, "plain") &&
msg->longmsg == NULL) {
status = interpret_body(mime, &msg->longmsg, NULL);
if (status)
return status;
}
else {
// Fixme - we need a control on recursion level here - KG: maybe NOT. We only go to depth 1.
if (raise_msg_attachment != NULL) {
if (has_possible_pEp_msg != NULL) {
bool is_msg = (_is_message_part(content, "rfc822") || _is_text_part(content, "rfc822"));
if (is_msg) {
if (content->ct_parameters) {
@ -2633,7 +2774,7 @@ static PEP_STATUS interpret_MIME(
struct mailmime_parameter * param = clist_content(cur);
if (param && param->pa_name && strcasecmp(param->pa_name, "forwarded") == 0) {
if (param->pa_value && strcasecmp(param->pa_value, "no") == 0) {
*raise_msg_attachment = true;
*has_possible_pEp_msg = true;
break;
}
}