Browse Source

ENGINE-606 squash commit

IOSAD-201
Krista Bennett 1 year ago
parent
commit
e560a80d3e
83 changed files with 18366 additions and 938 deletions
  1. +3
    -3
      asn.1/Makefile
  2. +40
    -0
      asn.1/managedgroup.asn1
  3. +1
    -1
      src/Makefile
  4. +14
    -14
      src/base64.c
  5. +2
    -2
      src/blacklist.c
  6. +1
    -1
      src/email.h
  7. +51
    -33
      src/engine_sql.c
  8. +8
    -1
      src/engine_sql.h
  9. +102
    -102
      src/etpan_mime.c
  10. +2375
    -0
      src/group.c
  11. +623
    -0
      src/group.h
  12. +541
    -280
      src/key_reset.c
  13. +12
    -0
      src/key_reset.h
  14. +31
    -31
      src/keymanagement.c
  15. +441
    -311
      src/message_api.c
  16. +1
    -1
      src/mime.c
  17. +76
    -76
      src/pEpEngine.c
  18. +19
    -2
      src/pEpEngine.h
  19. +5
    -3
      src/pEp_internal.h
  20. +54
    -48
      src/pgp_sequoia.c
  21. +14
    -14
      src/platform_unix.c
  22. +2
    -2
      src/platform_windows.cpp
  23. +7
    -7
      src/stringlist.c
  24. +5
    -5
      src/stringpair.c
  25. +19
    -0
      sync/distribution.fsm
  26. +3
    -1
      sync/gen_messages.ysl2
  27. +3982
    -0
      test/src/GroupEncryptionTest.cc
  28. +1
    -0
      test/src/KeyResetMessageTest.cc
  29. +9
    -0
      test/src/test_util.cc
  30. +1
    -0
      test/src/test_util.h
  31. +58
    -0
      test/test_keys/priv/abner_0x75909622_priv.asc
  32. +57
    -0
      test/test_keys/priv/bad_manager_0xF4F44414_priv.asc
  33. +58
    -0
      test/test_keys/priv/emperor_0xD1AC4929_priv.asc
  34. +58
    -0
      test/test_keys/priv/fennarion_0x268B111B_priv.asc
  35. +58
    -0
      test/test_keys/priv/lyris_0x00E3D05A_priv.asc
  36. +58
    -0
      test/test_keys/priv/not_bad_vampires_0x0A7893F2_priv.asc
  37. +58
    -0
      test/test_keys/priv/sai_sahan_0xFD070276_priv.asc
  38. +58
    -0
      test/test_keys/priv/vanus.galerion_0x9C875C78_priv.asc
  39. +58
    -0
      test/test_keys/priv/vanus_for_archmage_0x6456E7C7_priv.asc
  40. +30
    -0
      test/test_keys/pub/abner_0x75909622_pub.asc
  41. +30
    -0
      test/test_keys/pub/bad_manager_0xF4F44414_pub.asc
  42. +31
    -0
      test/test_keys/pub/emperor_0xD1AC4929_pub.asc
  43. +31
    -0
      test/test_keys/pub/fennarion_0x268B111B_pub.asc
  44. +30
    -0
      test/test_keys/pub/lyris_0x00E3D05A_pub.asc
  45. +31
    -0
      test/test_keys/pub/not_bad_vampires_0x0A7893F2_pub.asc
  46. +31
    -0
      test/test_keys/pub/sai_sahan_0xFD070276_pub.asc
  47. +31
    -0
      test/test_keys/pub/vanus.galerion_0x9C875C78_pub.asc
  48. +31
    -0
      test/test_keys/pub/vanus_for_archmage_0x6456E7C7_pub.asc
  49. +271
    -0
      test/test_mails/group_create_abner_0x75909622.eml
  50. +259
    -0
      test/test_mails/group_create_different_own_identity_managers_group_1_abner_0x75909622.eml
  51. +259
    -0
      test/test_mails/group_create_different_own_identity_managers_group_1_emperor_0xD1AC4929.eml
  52. +259
    -0
      test/test_mails/group_create_different_own_identity_managers_group_1_lyris_0x00E3D05A.eml
  53. +259
    -0
      test/test_mails/group_create_different_own_identity_managers_group_1_sai_sahan_0xFD070276.eml
  54. +259
    -0
      test/test_mails/group_create_different_own_identity_managers_group_2_abner_0x75909622.eml
  55. +259
    -0
      test/test_mails/group_create_different_own_identity_managers_group_2_emperor_0xD1AC4929.eml
  56. +259
    -0
      test/test_mails/group_create_different_own_identity_managers_group_2_sai_sahan_0xFD070276.eml
  57. +272
    -0
      test/test_mails/group_create_emperor_0xD1AC4929.eml
  58. +259
    -0
      test/test_mails/group_create_extant_key_abner_0x75909622.eml
  59. +259
    -0
      test/test_mails/group_create_extant_key_emperor_0xD1AC4929.eml
  60. +259
    -0
      test/test_mails/group_create_extant_key_lyris_0x00E3D05A.eml
  61. +259
    -0
      test/test_mails/group_create_extant_key_sai_sahan_0xFD070276.eml
  62. +272
    -0
      test/test_mails/group_create_lyris_0x00E3D05A.eml
  63. +272
    -0
      test/test_mails/group_create_sai_sahan_0xFD070276.eml
  64. +271
    -0
      test/test_mails/group_dissolve_emperor_0xD1AC4929.eml
  65. +271
    -0
      test/test_mails/group_dissolve_lyris_0x00E3D05A.eml
  66. +271
    -0
      test/test_mails/group_dissolve_not_manager_emperor_0xD1AC4929.eml
  67. +271
    -0
      test/test_mails/group_dissolve_sai_sahan_0xFD070276.eml
  68. +151
    -0
      test/test_mails/group_join_abner_0x75909622.eml
  69. +152
    -0
      test/test_mails/group_join_emperor_0xD1AC4929.eml
  70. +153
    -0
      test/test_mails/group_join_lyris_0x00E3D05A.eml
  71. +153
    -0
      test/test_mails/group_join_sai_sahan_0xFD070276.eml
  72. +391
    -0
      test/test_mails/group_key_reset_mixed_output_to_member_private_abner@tharn.cool.eml
  73. +390
    -0
      test/test_mails/group_key_reset_mixed_output_to_member_private_emperor@aquilarios.cyrodiil.eml
  74. +390
    -0
      test/test_mails/group_key_reset_mixed_output_to_member_private_lyris@titanborn.skyrim.eml
  75. +391
    -0
      test/test_mails/group_key_reset_mixed_output_to_member_private_sai_sahan@blades.hammerfall.eml
  76. +218
    -0
      test/test_mails/group_key_reset_mixed_output_to_partner_public_pep.test.bob@pep-project.org.eml
  77. +218
    -0
      test/test_mails/group_key_reset_mixed_output_to_partner_public_vanus.galerion@mage.guild.eml
  78. +103
    -0
      test/test_mails/group_key_reset_receive_to_group_from_bob_0xC9C2EE39.eml
  79. +103
    -0
      test/test_mails/group_key_reset_receive_to_group_from_vanus_for_archmage_0x6456E7C7.eml
  80. +323
    -0
      test/test_mails/group_key_reset_simple_to_member_abner_0x75909622.eml
  81. +323
    -0
      test/test_mails/group_key_reset_simple_to_member_emperor_0xD1AC4929.eml
  82. +323
    -0
      test/test_mails/group_key_reset_simple_to_member_lyris_0x00E3D05A.eml
  83. +324
    -0
      test/test_mails/group_key_reset_simple_to_member_sai_sahan_0xFD070276.eml

+ 3
- 3
asn.1/Makefile View File

@ -24,13 +24,13 @@ Sync.c: sync.asn1 keysync.asn1 pEp.asn1
rm -f converter-sample.c
touch Sync.c
Distribution.c: distribution.asn1 keyreset.asn1 pEp.asn1
$(ASN1C) -gen-PER -fincludes-quoted -fcompound-names -pdu=auto pEp.asn1 keyreset.asn1 $<
Distribution.c: distribution.asn1 keyreset.asn1 managedgroup.asn1 pEp.asn1
$(ASN1C) -gen-PER -fincludes-quoted -fcompound-names -pdu=auto pEp.asn1 keyreset.asn1 managedgroup.asn1 $<
rm -f converter-sample.c
touch Distribution.c
clean:
rm -f *.a *.o *.c *.h *.sample sync.asn1 keysync.asn1 distribution.asn1 keyreset.asn1
rm -f *.a *.o *.c *.h *.sample sync.asn1 keysync.asn1 distribution.asn1 keyreset.asn1 managedgroup.asn1
install:


+ 40
- 0
asn.1/managedgroup.asn1 View File

@ -0,0 +1,40 @@
-- This file is under BSD License 2.0
-- ManagedGroup protocol for p≡p
-- Copyleft 2016-2020 by p≡p foundation
-- Written by Volker Birk
MANAGEDGROUP
{ iso(1) org(3) dod(6) internet(1) private(4) enterprise(1) pEp(47878) distribution(2) managedgroup(2) }
DEFINITIONS AUTOMATIC TAGS EXTENSIBILITY IMPLIED ::=
BEGIN
EXPORTS ManagedGroup;
IMPORTS Version, Identity, IdentityList, TID, Hash, Rating FROM PEP;
GroupCreate ::= SEQUENCE {
groupIdentity Identity,
manager Identity
}
GroupAdopted ::= SEQUENCE {
groupIdentity Identity,
member Identity
}
GroupDissolve ::= SEQUENCE {
groupIdentity Identity,
manager Identity
}
ManagedGroup ::= CHOICE {
groupCreate [APPLICATION 2] GroupCreate,
groupAdopted [APPLICATION 3] GroupAdopted,
groupDissolve [APPLICATION 4] GroupDissolve
}
END

+ 1
- 1
src/Makefile View File

@ -104,7 +104,7 @@ install_headers: $(TARGET)
mkdir -p $(PREFIX)/include/pEp
cp pEpEngine.h keymanagement.h message_api.h dynamic_api.h stringlist.h \
timestamp.h identity_list.h bloblist.h stringpair.h message.h mime.h \
cryptotech.h sync_api.h blacklist.h pEp_string.h openpgp_compat.h \
cryptotech.h sync_api.h blacklist.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 \
status_to_string.h aux_mime_msg.h keyreset_command.h platform.h platform_unix.h ../asn.1/*.h \
$(PREFIX)/include/pEp/


+ 14
- 14
src/base64.c View File

@ -38,7 +38,7 @@ static char translate_char_to_bits(char input) {
* @brief checks if a character is a whitespace character
* end returns true if so, false otherwise
*
* @param[in] in char to be checked
* @param[in] in char to be checked
* @retval bool true if whitespace, false otherwise
*
*/
@ -59,11 +59,11 @@ static bool _is_whitespace(const char in) {
*
* <!-- subtract_whitespace() -->
*
* @brief returns the length of the C string
* @brief returns the length of the C string
* not counting whitespaces
*
* @param[in] *input C string
* @param[in] length length of the C string
* @param[in] *input C string
* @param[in] length length of the C string
* @retval size_t actual size of string without whitespaces
*
*/
@ -83,11 +83,11 @@ static size_t subtract_whitespace(const char* input, int length) {
*
* <!-- trim_end() -->
*
* @brief determine length of C string without
* trailing whitespace characters
* @brief determine length of C string without
* trailing whitespace characters
*
* @param[in] *input C string to check
* @param[out] *length returns the resulting lenght
* @param[in] *input C string to check
* @param[out] *length returns the resulting lenght
*
*/
static void trim_end(const char* input, int* length) {
@ -109,10 +109,10 @@ static void trim_end(const char* input, int* length) {
*
* <!-- next_char() -->
*
* @brief returns the next non-whitespace character in a C string
* @brief returns the next non-whitespace character in a C string
*
* @param[in] **input_ptr pointer to C string
* @param[in] *end pointer to last char of input string
* @param[in] **input_ptr pointer to C string
* @param[in] *end pointer to last char of input string
*
* @retval char next non-whitespace character
*
@ -139,12 +139,12 @@ char next_char(const char** input_ptr, const char* end) {
*
* <!-- base64_str_to_binary_blob() -->
*
* @brief converts base64 to a binary blob, putting 4 characters into
* @brief converts base64 to a binary blob, putting 4 characters into
* 3 output bytes, returning a pointer to a bloblist containing
* the binary blob.
*
* @param[in] *input input as C string
* @param[in] int length of C string
* @param[in] *input input as C string
* @param[in] int length of C string
*
* @retval pointer to bloblist, or NULL on failure
*/


+ 2
- 2
src/blacklist.c View File

@ -19,7 +19,7 @@ DYNAMIC_API PEP_STATUS blacklist_add(PEP_SESSION session, const char *fpr)
sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
sqlite3_reset(session->blacklist_add);
sqlite3_bind_text(session->blacklist_add, 1, fpr, -1, SQLITE_STATIC);
sqlite3_bind_text(session->blacklist_add, 1, fpr, -1, SQLITE_STATIC);
int result;
@ -49,7 +49,7 @@ DYNAMIC_API PEP_STATUS blacklist_delete(PEP_SESSION session, const char *fpr)
return PEP_ILLEGAL_VALUE;
sqlite3_reset(session->blacklist_delete);
sqlite3_bind_text(session->blacklist_delete, 1, fpr, -1, SQLITE_STATIC);
sqlite3_bind_text(session->blacklist_delete, 1, fpr, -1, SQLITE_STATIC);
int result;


+ 1
- 1
src/email.h View File

@ -13,7 +13,7 @@
/**
* <!-- email_sendto() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] session PEP_SESSION
* @param[in] msg message*


+ 51
- 33
src/engine_sql.c View File

@ -7,11 +7,11 @@
*
* <!-- _sql_lower() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *ctx sqlite3_context
* @param[in] argc int
* @param[in] **argv sqlite3_value
* @param[in] *ctx sqlite3_context
* @param[in] argc int
* @param[in] **argv sqlite3_value
*
*/
static void _sql_lower(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
@ -43,12 +43,12 @@ static void _sql_lower(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
*
* <!-- sql_trace_callback() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] trace_constant unsigned
* @param[in] *context_ptr void
* @param[in] *P void
* @param[in] *X void
* @param[in] trace_constant unsigned
* @param[in] *context_ptr void
* @param[in] *P void
* @param[in] *X void
*
*/
int sql_trace_callback (unsigned trace_constant,
@ -83,11 +83,11 @@ int sql_trace_callback (unsigned trace_constant,
*
* <!-- errorLogCallback() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *pArg void
* @param[in] iErrCode int
* @param[in] *zMsg constchar
* @param[in] *pArg void
* @param[in] iErrCode int
* @param[in] *zMsg constchar
*
*/
void errorLogCallback(void *pArg, int iErrCode, const char *zMsg){
@ -100,10 +100,10 @@ void errorLogCallback(void *pArg, int iErrCode, const char *zMsg){
*
* <!-- db_contains_table() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] session PEP_SESSION
* @param[in] *table_name constchar
* @param[in] session PEP_SESSION
* @param[in] *table_name constchar
*
*/
static int db_contains_table(PEP_SESSION session, const char* table_name) {
@ -155,11 +155,11 @@ static int db_contains_table(PEP_SESSION session, const char* table_name) {
*
* <!-- table_contains_column() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] session PEP_SESSION
* @param[in] *table_name constchar
* @param[in] *col_name constchar
* @param[in] session PEP_SESSION
* @param[in] *table_name constchar
* @param[in] *col_name constchar
*
*/
static int table_contains_column(PEP_SESSION session, const char* table_name,
@ -217,9 +217,9 @@ static int table_contains_column(PEP_SESSION session, const char* table_name,
*
* <!-- repair_altered_tables() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] session PEP_SESSION
* @param[in] session PEP_SESSION
*
*/
#define _PEP_MAX_AFFECTED 5
@ -406,9 +406,9 @@ PEP_STATUS repair_altered_tables(PEP_SESSION session) {
*
* <!-- upgrade_revoc_contact_to_13() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] session PEP_SESSION
* @param[in] session PEP_SESSION
*
*/
static PEP_STATUS upgrade_revoc_contact_to_13(PEP_SESSION session) {
@ -547,12 +547,12 @@ static PEP_STATUS upgrade_revoc_contact_to_13(PEP_SESSION session) {
*
* <!-- user_version() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *_version void
* @param[in] count int
* @param[in] **text char
* @param[in] **name char
* @param[in] *_version void
* @param[in] count int
* @param[in] **text char
* @param[in] **name char
*
*/
static int user_version(void *_version, int count, char **text, char **name)
@ -2338,6 +2338,13 @@ PEP_STATUS pEp_prepare_sql_stmts(PEP_SESSION session) {
(int)strlen(sql_group_add_member), &session->group_add_member, NULL);
assert(int_result == SQLITE_OK);
if (int_result != SQLITE_OK)
return PEP_UNKNOWN_DB_ERROR;
int_result = sqlite3_prepare_v2(session->db, sql_group_delete_member,
(int)strlen(sql_group_delete_member), &session->group_delete_member, NULL);
assert(int_result == SQLITE_OK);
if (int_result != SQLITE_OK)
return PEP_UNKNOWN_DB_ERROR;
@ -2349,8 +2356,8 @@ PEP_STATUS pEp_prepare_sql_stmts(PEP_SESSION session) {
if (int_result != SQLITE_OK)
return PEP_UNKNOWN_DB_ERROR;
int_result = sqlite3_prepare_v2(session->db, sql_join_group,
(int)strlen(sql_join_group), &session->join_group, NULL);
int_result = sqlite3_prepare_v2(session->db, sql_group_join,
(int)strlen(sql_group_join), &session->group_join, NULL);
assert(int_result == SQLITE_OK);
if (int_result != SQLITE_OK)
@ -2439,7 +2446,14 @@ PEP_STATUS pEp_prepare_sql_stmts(PEP_SESSION session) {
if (int_result != SQLITE_OK)
return PEP_UNKNOWN_DB_ERROR;
int_result = sqlite3_prepare_v2(session->db, sql_is_active_group_member,
(int)strlen(sql_is_active_group_member), &session->is_active_group_member, NULL);
assert(int_result == SQLITE_OK);
if (int_result != SQLITE_OK)
return PEP_UNKNOWN_DB_ERROR;
int_result = sqlite3_prepare_v2(session->db, sql_is_group_active,
(int)strlen(sql_is_group_active), &session->is_group_active, NULL);
assert(int_result == SQLITE_OK);
@ -2624,10 +2638,12 @@ PEP_STATUS pEp_finalize_sql_stmts(PEP_SESSION session) {
sqlite3_finalize(session->exists_group_entry);
if (session->group_add_member)
sqlite3_finalize(session->group_add_member);
if (session->group_delete_member)
sqlite3_finalize(session->group_delete_member);
if (session->set_group_member_status)
sqlite3_finalize(session->set_group_member_status);
if (session->join_group)
sqlite3_finalize(session->join_group);
if (session->group_join)
sqlite3_finalize(session->group_join);
if (session->leave_group)
sqlite3_finalize(session->leave_group);
if (session->get_all_members)
@ -2650,6 +2666,8 @@ PEP_STATUS pEp_finalize_sql_stmts(PEP_SESSION session) {
sqlite3_finalize(session->get_group_manager);
if (session->is_invited_group_member)
sqlite3_finalize(session->is_invited_group_member);
if (session->is_active_group_member)
sqlite3_finalize(session->is_active_group_member);
if (session->is_group_active)
sqlite3_finalize(session->is_group_active);
if (session->set_pgp_keypair_flags)


+ 8
- 1
src/engine_sql.h View File

@ -525,11 +525,15 @@ static const char *sql_exists_group_entry =
static const char *sql_group_add_member =
"insert or ignore into own_groups_members (group_id, group_address, member_id, member_address) "
" values (?1, ?2, ?3, ?4) ;";
static const char *sql_group_delete_member =
"delete from own_groups_members "
" where group_id = ?1 and group_address = ?2 and "
" member_id = ?3 and member_address = ?4 ;";
static const char *sql_set_group_member_status =
"update own_groups_members set active_member = ?1 "
" where group_id = ?2 and group_address = ?3 and "
" member_id = ?4 and member_address = ?5; ";
static const char *sql_join_group =
static const char *sql_group_join =
"update own_memberships set have_joined = 1 "
" where group_id = ?1 and group_address = ?2 and "
" own_id = ?3 and own_address = ?4; ";
@ -549,6 +553,9 @@ static const char *sql_get_group_manager =
static const char *sql_is_invited_group_member =
"select count(*) from own_groups_members "
" where group_id = ?1 and group_address = ?2 and member_id = ?3 and member_address = ?4; ";
static const char *sql_is_active_group_member =
"select active_member from own_groups_members "
" where group_id = ?1 and group_address = ?2 and member_id = ?3 and member_address = ?4; ";
static const char *sql_get_all_groups =
"select group_id, group_address from own_memberships; ";
static const char *sql_get_active_groups =


+ 102
- 102
src/etpan_mime.c View File

@ -49,7 +49,7 @@ static bool ascii_exceeds_line_length(const char* data, size_t size) {
*
* <!-- generate_boundary() -->
*
* @brief TODO
* @brief TODO
*
*
*/
@ -844,11 +844,11 @@ char * _get_filename_or_cid(struct mailmime *mime)
*
* <!-- parameter_has_value() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *content structmailmime_content
* @param[in] *name constchar
* @param[in] *value constchar
* @param[in] *content structmailmime_content
* @param[in] *name constchar
* @param[in] *value constchar
*
*/
static bool parameter_has_value(
@ -932,10 +932,10 @@ bool _is_text_part(struct mailmime_content *content, const char *subtype)
*
* <!-- _is_message_part() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *content structmailmime_content
* @param[in] *subtype constchar
* @param[in] *content structmailmime_content
* @param[in] *subtype constchar
*
*/
bool _is_message_part(struct mailmime_content *content, const char* subtype) {
@ -1102,10 +1102,10 @@ static PEP_STATUS interpret_MIME(struct mailmime *mime,
*
* <!-- render_mime() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *mime structmailmime
* @param[in] **mimetext char
* @param[in] *mime structmailmime
* @param[in] **mimetext char
*
* @retval PEP_STATUS_OK
* @retval PEP_OUT_OF_MEMORY out of memory
@ -1116,31 +1116,31 @@ static PEP_STATUS render_mime(struct mailmime *mime, char **mimetext)
PEP_STATUS status = PEP_STATUS_OK;
int col;
int r;
size_t len;
char* buf = NULL;
MMAPString* buffer;
buffer = mmap_string_new(NULL);
if (buffer == NULL)
goto enomem;
col = 0;
r = mailmime_write_mem(buffer, &col, mime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY)
goto enomem;
else if (r != MAILIMF_NO_ERROR)
goto err_file;
// we overallocate by 1 byte, so we have a terminating 0.
len = buffer->len;
buf = calloc(len + 1, 1);
if (buf == NULL)
goto enomem;
memcpy(buf, buffer->str, len);
mmap_string_free(buffer);
size_t len;
char* buf = NULL;
MMAPString* buffer;
buffer = mmap_string_new(NULL);
if (buffer == NULL)
goto enomem;
col = 0;
r = mailmime_write_mem(buffer, &col, mime);
assert(r == MAILIMF_NO_ERROR);
if (r == MAILIMF_ERROR_MEMORY)
goto enomem;
else if (r != MAILIMF_NO_ERROR)
goto err_file;
// we overallocate by 1 byte, so we have a terminating 0.
len = buffer->len;
buf = calloc(len + 1, 1);
if (buf == NULL)
goto enomem;
memcpy(buf, buffer->str, len);
mmap_string_free(buffer);
*mimetext = buf;
return PEP_STATUS_OK;
@ -1153,10 +1153,10 @@ enomem:
status = PEP_OUT_OF_MEMORY;
pEp_error:
if (buffer)
mmap_string_free(buffer);
if (buf)
free(buf);
if (buffer)
mmap_string_free(buffer);
if (buf)
free(buf);
return status;
}
@ -1165,11 +1165,11 @@ pEp_error:
*
* <!-- mime_attachment() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *blob bloblist_t
* @param[in] **result structmailmime
* @param[in] is_nf_message_attachment bool
* @param[in] *blob bloblist_t
* @param[in] **result structmailmime
* @param[in] is_nf_message_attachment bool
*
* @retval PEP_STATUS_OK
* @retval PEP_OUT_OF_MEMORY out of memory
@ -1238,12 +1238,12 @@ enomem:
*
* <!-- mime_html_text() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *plaintext constchar
* @param[in] *htmltext constchar
* @param[in] *attachments bloblist_t
* @param[in] **result structmailmime
* @param[in] *plaintext constchar
* @param[in] *htmltext constchar
* @param[in] *attachments bloblist_t
* @param[in] **result structmailmime
*
* @retval PEP_STATUS_OK
* @retval PEP_OUT_OF_MEMORY out of memory
@ -1434,9 +1434,9 @@ enomem:
*
* <!-- identity_to_mailbox() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *ident constpEp_identity
* @param[in] *ident constpEp_identity
*
*/
static struct mailimf_mailbox * identity_to_mailbox(const pEp_identity *ident)
@ -1474,9 +1474,9 @@ enomem:
*
* <!-- identity_to_mbl() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *ident constpEp_identity
* @param[in] *ident constpEp_identity
*
*/
static struct mailimf_mailbox_list * identity_to_mbl(
@ -1522,9 +1522,9 @@ enomem:
*
* <!-- identity_list_to_mal() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *il identity_list
* @param[in] *il identity_list
*
*/
static struct mailimf_address_list * identity_list_to_mal(identity_list *il)
@ -1584,10 +1584,10 @@ enomem:
*
* <!-- stringlist_to_clist() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *sl stringlist_t
* @param[in] transport_encode bool
* @param[in] *sl stringlist_t
* @param[in] transport_encode bool
*
*/
static clist * stringlist_to_clist(stringlist_t *sl, bool transport_encode)
@ -1628,10 +1628,10 @@ static clist * stringlist_to_clist(stringlist_t *sl, bool transport_encode)
*
* <!-- build_fields() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *msg constmessage
* @param[in] **result structmailimf_fields
* @param[in] *msg constmessage
* @param[in] **result structmailimf_fields
*
* @retval PEP_STATUS_OK
* @retval PEP_OUT_OF_MEMORY out of memory
@ -1871,9 +1871,9 @@ enomem:
*
* <!-- has_exceptional_extension() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *filename char
* @param[in] *filename char
*
*/
static bool has_exceptional_extension(char* filename) {
@ -1894,9 +1894,9 @@ static bool has_exceptional_extension(char* filename) {
*
* <!-- choose_resource_id() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *rid_list pEp_rid_list_t
* @param[in] *rid_list pEp_rid_list_t
*
*/
static pEp_rid_list_t* choose_resource_id(pEp_rid_list_t* rid_list) {
@ -1953,12 +1953,12 @@ static pEp_rid_list_t* choose_resource_id(pEp_rid_list_t* rid_list) {
*
* <!-- mime_encode_message_plain() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *msg constmessage
* @param[in] omit_fields bool
* @param[in] **result structmailmime
* @param[in] has_pEp_msg_attachment bool
* @param[in] *msg constmessage
* @param[in] omit_fields bool
* @param[in] **result structmailmime
* @param[in] has_pEp_msg_attachment bool
*
* @retval PEP_STATUS_OK
* @retval PEP_OUT_OF_MEMORY out of memory
@ -2124,11 +2124,11 @@ pEp_error:
*
* <!-- mime_encode_message_PGP_MIME() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *msg constmessage
* @param[in] omit_fields bool
* @param[in] **result structmailmime
* @param[in] *msg constmessage
* @param[in] omit_fields bool
* @param[in] **result structmailmime
*
* @retval PEP_STATUS_OK
* @retval PEP_OUT_OF_MEMORY out of memory
@ -2143,7 +2143,7 @@ static PEP_STATUS mime_encode_message_PGP_MIME(
{
struct mailmime * mime = NULL;
struct mailmime * submime = NULL;
struct mailmime_parameter * param;
struct mailmime_parameter * param;
int r;
PEP_STATUS status;
char *plaintext;
@ -2311,9 +2311,9 @@ pEp_error:
*
* <!-- mailbox_to_identity() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *mb conststructmailimf_mailbox
* @param[in] *mb conststructmailimf_mailbox
*
*/
static pEp_identity *mailbox_to_identity(const struct mailimf_mailbox * mb)
@ -2368,9 +2368,9 @@ enomem:
*
* <!-- mbl_to_identity() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *mbl conststructmailimf_mailbox_list
* @param[in] *mbl conststructmailimf_mailbox_list
*
*/
static pEp_identity * mbl_to_identity(const struct mailimf_mailbox_list * mbl)
@ -2384,9 +2384,9 @@ static pEp_identity * mbl_to_identity(const struct mailimf_mailbox_list * mbl)
*
* <!-- mal_to_identity_list() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *mal conststructmailimf_address_list
* @param[in] *mal conststructmailimf_address_list
*
*/
static identity_list * mal_to_identity_list(
@ -2455,9 +2455,9 @@ enomem:
*
* <!-- clist_to_stringlist() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *list constclist
* @param[in] *list constclist
*
*/
static stringlist_t * clist_to_stringlist(const clist *list)
@ -2499,10 +2499,10 @@ enomem:
*
* <!-- read_fields() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *msg message
* @param[in] *fieldlist clist
* @param[in] *msg message
* @param[in] *fieldlist clist
*
* @retval PEP_STATUS_OK
* @retval PEP_OUT_OF_MEMORY out of memory
@ -2723,11 +2723,11 @@ pEp_error:
*
* <!-- interpret_body() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *part structmailmime
* @param[in] **longmsg char
* @param[in] *size size_t
* @param[in] *part structmailmime
* @param[in] **longmsg char
* @param[in] *size size_t
*
* @retval PEP_STATUS_OK
* @retval PEP_ILLEGAL_VALUE illegal parameter values
@ -2817,10 +2817,10 @@ static PEP_STATUS interpret_body(struct mailmime *part, char **longmsg, size_t *
*
* <!-- interpret_protected_headers() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *mime structmailmime
* @param[in] *msg message
* @param[in] *mime structmailmime
* @param[in] *msg message
*
*/
static PEP_STATUS interpret_protected_headers(
@ -2868,10 +2868,10 @@ static PEP_STATUS interpret_protected_headers(
*
* <!-- process_multipart_related() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *mime structmailmime
* @param[in] *msg message
* @param[in] *mime structmailmime
* @param[in] *msg message
*
* @retval PEP_STATUS_OK
* @retval PEP_ILLEGAL_VALUE illegal parameter values
@ -2939,9 +2939,9 @@ static PEP_STATUS process_multipart_related(struct mailmime *mime,
*
* <!-- _is_marked_as_attachment() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *fields structmailmime_fields
* @param[in] *fields structmailmime_fields
*
*/
static bool _is_marked_as_attachment(struct mailmime_fields *fields)
@ -2969,11 +2969,11 @@ static bool _is_marked_as_attachment(struct mailmime_fields *fields)
*
* <!-- interpret_MIME() -->
*
* @brief TODO
* @brief TODO
*
* @param[in] *mime structmailmime
* @param[in] *msg message
* @param[in] *has_possible_pEp_msg bool
* @param[in] *mime structmailmime
* @param[in] *msg message
* @param[in] *has_possible_pEp_msg bool
*
* @retval PEP_STATUS_OK
* @retval PEP_ILLEGAL_VALUE illegal parameter values


+ 2375
- 0
src/group.c
File diff suppressed because it is too large
View File


+ 623
- 0
src/group.h View File

@ -0,0 +1,623 @@
#ifndef GROUP_H
#define GROUP_H
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#include "message_api.h"
#include "../asn.1/Distribution.h"
#ifdef __cplusplus
extern "C" {
#endif
/*************************************************************************************************
* In-memory objects and functions for representation of groups
*************************************************************************************************/
/**
* @struct pEp_member
* @brief memory object for holding information about an invited group member
* and whether they have joined the group
* (groups are persistent and are stored in the management database)
*/
typedef struct _pEp_member {
pEp_identity *ident; //!< member identity
bool joined; //!< boolean for whether the member has accepted the invite
} pEp_member;
/**
* <!-- new_member() -->
*
* @brief allocate pEp_member struct. This struct only allocates the member object for
* group representation.
*
* @param[in] ident the pEp_identity object representing the member
*
* @retval pEp_member allocated member struct on success
* NULL if ident is not present or other failure occurs
*
* @ownership ownership of all parameters goes to the struct
*
* @warning This is only an in-memory object allocator and performs NONE of the
* database or key management functions for groups or members!
*
*/
DYNAMIC_API pEp_member *new_member(pEp_identity *ident);
/**
* <!-- free_member() -->
*
* @brief deallocate pEp_member struct and the identity it points to.
*
* @param[in] member member object to be freed
*
* @ownership ALL objects pointed to by the struct will be freed!
*
* @warning This is only an in-memory object deallocator and performs NONE of the
* database or key management functions for group members!
*
*/
DYNAMIC_API void free_member(pEp_member *member);
/**
* @struct member_list
* @brief list structure for pEp_member objects
* @see pEp_member
*/
typedef struct _member_list {
pEp_member *member; //!< member object containing the identity and joined status for this list node
struct _member_list *next; //!< pointer to next node in list
} member_list;
/**
* <!-- new_memberlist() -->
*
* @brief allocate member_list node struct. This struct only allocates the member_list object for
* group representation.
*
* @param[in] member the member to be associated with this member_list node
*
* @retval member_list allocated member_list struct on success
* NULL if failure occurs (typically: out of memory)
*
* @ownership ownership of all parameters goes to the struct
*
* @warning This is only an in-memory object allocator and performs NONE of the
* database or key management functions for groups or members!
*
*/
DYNAMIC_API member_list *new_memberlist(pEp_member *member);
/**
* <!-- free_memberlist() -->
*
* @brief deallocate the node pointed to by the list argument and all nodes following it in the list
* and their associated objects
*
* @param[in] list memberlist object to be freed
*
* @ownership ALL objects pointed to by the struct will be freed!
*
* @warning This is only an in-memory object deallocator and performs NONE of the
* database or key management functions for group members!
*
*/
DYNAMIC_API void free_memberlist(member_list *list);
/**
* <!-- memberlist_add() -->
*
* @brief add memberlist node containing this member to the end of the list
* pointed to by the list argument and return a pointer to the tail of the list
*
* @param[in,out] list node pointing to the list to add to (if this is NULL,
* a new list will be created and returned)
* @param[in] member member to add to the list
*
* @retval member_list tail of list on success (or pointer to new list if input list was NULL)
* NULL if failure occurs (typically: out of memory)
*
* @ownership ownership of all parameters goes to the callee
*
* @warning This is only an in-memory object allocator and performs NONE of the
* database or key management functions for groups or members!
*
*/
DYNAMIC_API member_list *memberlist_add(member_list *list, pEp_member *member);
/**
* @struct pEp group
* @brief memory object for holding all information about a group
* (groups are persistent and are stored in the management database)
*/
typedef struct _pEp_group {
pEp_identity *group_identity; //!< identity representing this group
pEp_identity *manager; //!< identity of the group manager
member_list *members; //!< list of members associated with group
bool active; //!< boolean true if group is marked as active, else false
} pEp_group;
/**
* <!-- new_group() -->
*
* @brief allocate pEp_group struct. This function does not create
* a group in the database, it only allocates the object for
* group representation.
*
* @param[in] group_identity the pEp_identity object representing the group
* @param[in] manager the pEp_identity object representing the group's manager
* @param[in] memberlist optional list of group members
*
* @retval group allocated group struct on success
* NULL if group_identity is not present or other failure occurs
*
* @ownership ownership of all parameters goes to the struct
*
* @warning This is only an in-memory object allocator and performs NONE of the
* database or key management functions for groups!
*
*/
DYNAMIC_API pEp_group *new_group(
pEp_identity *group_identity,
pEp_identity *manager,
member_list *memberlist
);
/**
* <!-- free_group() -->
*
* @brief deallocate pEp_group struct and all objects it points to.
* This function does not dissolve groups, only deallocates the memory object
* representing a group.
*
* @param[in] group group object to be freed
*
* @ownership ALL objects pointed to by the struct will be freed!
*
* @warning This is only an in-memory object deallocator and performs NONE of the
* database or key management functions for groups!
*
*/
DYNAMIC_API void free_group(pEp_group *group);
/*************************************************************************************************
* Group management functions
*************************************************************************************************/
/**
* <!-- group_create() -->
*
* @brief Create a group in the database with the input group_identity and manager and invite new members to the group
* if this is an own group (for the external API, this is always the case).
*
* This function sets up the actual database structures for a group and invites new members to the group.
*
* For the external API, it is used when creating an own group. The group is represented by the
* incoming group_identity, which contains the user_id and address for the group.
* If no key is present for the former, it will be generated - if there is already
* a default key for the group_identity in the database, that will be used instead.
* The manager
*
* @param[in] session associated session object
* @param[in,out] group_identity the pEp_identity object representing the group. Must contain at least
* a user_id and address
* @param[in,out] manager the pEp_identity object representing the group's manager. Must contain
* a user_id and address, and there must be a default key for the manager
* present in the database
* @param[in,out] member_ident_list list of group member identities
* @param[in,out] group Optional reference for pointer to group object
* representing the created group.
* (When input is NULL, no object is created)
*
* @retval PEP_STATUS_OK on success
* error on failure
*
* @ownership All input values stay with the caller
*
* @warning starts a DB transaction - do not call from within a function which
* is already in the middle of another one.
*
* @note in,out fields are labelled as such because they get updated by update_identity()/myself()
* and have group flags added. group_identity may have its user_id freed and replaced
* with the canonical own user id.
*
*/
DYNAMIC_API PEP_STATUS group_create(
PEP_SESSION session,
pEp_identity *group_identity,
pEp_identity *manager,
identity_list *memberlist,
pEp_group **group
);
/**
* <!-- group_join() -->
*
* @brief Join a group for which we have received an invitation, marking
* our own membership in the database for the group and sending the manager
* a confirmation of the acceptance of the invitation
*
* @param[in] session associated session object
* @param[in] group_identity the pEp_identity object representing the group. Must contain at least
* a user_id and address
* @param[in] as_member the pEp_identity object representing the own identity we want to use to
* join the group. This must match the identity which was invited to the group.
* Must contain a user_id and address.
*
* @retval PEP_STATUS_OK on success
* error on failure
*
* @ownership FIXME
*
*
*/
DYNAMIC_API PEP_STATUS group_join(
PEP_SESSION session,
pEp_identity *group_identity,
pEp_identity *as_member
);
/**
* <!-- group_dissolve() -->
*
* @brief Dissolve a group, revoke its key, notify all members of the dissolution and
* revocation, and mark the group as inactive in the database
*
* @param[in] session associated session object
* @param[in] group_identity the pEp_identity object representing the group. Must contain at least
* a user_id and address
* @param[in] manager the pEp_identity object representing the group's manager. Must contain
* a user_id and address, and there must be a default key for the manager
* present in the database
*
* @retval PEP_STATUS_OK on success
* error on failure
*
* @ownership FIXME
*
* @warning For recipients to accept the dissolution, the sender/manager key used must be a key that they
* have a trust entry for.
*/
DYNAMIC_API PEP_STATUS group_dissolve(
PEP_SESSION session,
pEp_identity *group_identity,
pEp_identity *manager
);
/**
* <!-- group_invite_member() -->
*
* @brief Invite a member to an extant group, marking the member as invited in the database and
* sending out an invitation to said member
*
* @param[in] session associated session object
* @param[in] group_identity the pEp_identity object representing the group. Must contain at least
* a user_id and address
* @param[in] group_member the pEp_identity object representing the member to invite. Must contain
* a user_id and address, and there must be a default key for the member
* present in the database
*
* @retval PEP_STATUS_OK on success
* error on failure
*
* @ownership FIXME
*
* @note This generates a GroupCreate message even though the group already exists - this is because
* this is the accepted message format for invitations to potential members
*
*/
DYNAMIC_API PEP_STATUS group_invite_member(
PEP_SESSION session,
pEp_identity *group_identity,
pEp_identity *group_member
);
/**
* <!-- group_remove_member() -->
*
* @brief Remove a member from a group, deleting the member from the member list and executing a key
* reset on the group identity
*
* @param[in] session associated session object
* @param[in] group_identity the pEp_identity object representing the group. Must contain at least
* a user_id and address
* @param[in] group_member the pEp_identity object representing the member to remove. Must contain
* a user_id and address
*
* @retval PEP_STATUS_OK on success
* error on failure
*
* @ownership FIXME
*
* @todo Revamp implementation and execute key reset
*
*/
PEP_STATUS group_remove_member(
PEP_SESSION session,
pEp_identity *group_identity,
pEp_identity *group_member
);
/**
* <!-- group_rating() -->
*
* @brief Get the rating for this group - if the caller is the manager, this will return the aggregate rating
* of group members. For members, this will return the rating of the group_identity
*
* @param[in] session associated session object
* @param[in] group_identity the pEp_identity object representing the group. Must contain at least
* a user_id and address
* @param[in] manager the pEp_identity object representing the member to remove. Must contain
* a user_id and address
* @param[out] rating the group rating
*
* @retval PEP_STATUS_OK on success
* error on failure
*
* @ownership FIXME
*
*/
DYNAMIC_API PEP_STATUS group_rating(
PEP_SESSION session,
pEp_identity *group_identity,
pEp_identity *manager,
PEP_rating *rating
);
/*************************************************************************************************
* Internal functions
*************************************************************************************************/
/**
* @internal
*
* <!-- group_enable() -->
*
* @brief Mark an extant group in the database as active
*
* @param[in] session associated session object
* @param[in] group_identity the pEp_identity object representing the group. Must contain at least
* a user_id and address
*
* @retval PEP_STATUS_OK on success
* error on failure
*
* @ownership all arguments belong to the callee
*
*/
PEP_STATUS group_enable(
PEP_SESSION session,
pEp_identity *group_identity
);
/**
* @internal
*
* @param session
* @param group_identity
* @param group_member
* @return
*/
PEP_STATUS group_add_member(
PEP_SESSION session,
pEp_identity *group_identity,
pEp_identity *group_member
);
// leave_group() - leave group as member
//
// params:
// group_identity (in)
// as_member (in) own identity
/**
* @internal
*
* @param session
* @param group_identity
* @param member_identity
* @return
*/
PEP_STATUS leave_group(
PEP_SESSION session,
pEp_identity *group_identity,
pEp_identity *member_identity
);
/**
* @internal
*
* @param session
* @param group_identity
* @param exists
* @return
*/
PEP_STATUS exists_group(
PEP_SESSION session,
pEp_identity* group_identity,
bool* exists
);
// group_identity stays with caller now - FIXME: adapt assumptions
/**
* @internal
*
* @param session
* @param group_identity
* @param group_info
* @return
*/
PEP_STATUS retrieve_group_info(
PEP_SESSION session,
pEp_identity* group_identity,
pEp_group** group_info
);
/**
* @internal
*
* @param session
* @param group_identity
* @param active
* @return
*/
PEP_STATUS is_group_active(
PEP_SESSION session,
pEp_identity*
group_identity,
bool* active);
/**
* @internal
*
* @param session
* @param group_identity
* @param members
* @return
*/
PEP_STATUS retrieve_full_group_membership(
PEP_SESSION session,
pEp_identity* group_identity,
member_list** members);
/**
* @internal
*
* @param session
* @param group_identity
* @param members
* @return
*/
PEP_STATUS retrieve_active_group_membership(
PEP_SESSION session,
pEp_identity* group_identity,
member_list** members);
/**
* @internal
*
* @param session
* @param group
* @return
*/
PEP_STATUS create_group_entry(PEP_SESSION session,
pEp_group* group);
/**
* @internal
*
* @param session
* @param group_identity
* @param manager
* @param own_identity_recip
* @return
*/
PEP_STATUS add_own_membership_entry(PEP_SESSION session,
pEp_identity* group_identity,
pEp_identity* manager,
pEp_identity* own_identity_recip);
/**
* @internal
*
* @param session
* @param group
* @param own_identity
* @return
*/
PEP_STATUS retrieve_own_membership_info_for_group_and_identity(PEP_SESSION session,
pEp_group* group,
pEp_identity* own_identity);
/**
* @internal
*
* @param session
* @param msg
* @param rating
* @param dist
* @return
*/
PEP_STATUS receive_managed_group_message(PEP_SESSION session, message* msg, PEP_rating rating, Distribution_t* dist);
/**
* @internal
*
* @param session
* @param group_identity
* @param mbr_idents
* @return
*/
PEP_STATUS retrieve_active_member_list(
PEP_SESSION session,
pEp_identity* group_identity,
member_list** mbr_idents);
/**
* @internal
*
* @param session
* @param group_identity
* @param as_member
* @param active
* @return
*/
PEP_STATUS set_membership_status(PEP_SESSION session,
pEp_identity* group_identity,
pEp_identity* as_member,
bool active);
/**
* @internal
*
* @param session
* @param group_identity
* @param is_own
* @return
*/
PEP_STATUS is_own_group_identity(PEP_SESSION session, pEp_identity* group_identity, bool* is_own);
/**
* @internal
*
* @param memberlist
* @return
*/
identity_list* member_list_to_identity_list(member_list* memberlist);
/**
*
* @param session