Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions include/e2ees/e2ees.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@
#include "e2ees/RemoveGroupMembersRequest.pb-c.h"
#include "e2ees/RemoveGroupMembersResponse.pb-c.h"
#include "e2ees/RemoveUserDeviceMsg.pb-c.h"
#include "e2ees/RenewGroupMsg.pb-c.h"
#include "e2ees/RenewGroupRequest.pb-c.h"
#include "e2ees/RenewGroupResponse.pb-c.h"
#include "e2ees/ResponseCode.pb-c.h"
#include "e2ees/SendGroupMsgRequest.pb-c.h"
#include "e2ees/SendGroupMsgResponse.pb-c.h"
Expand Down Expand Up @@ -643,6 +646,18 @@ typedef struct e2ees_proto_handler_t {
const char *auth,
E2ees__CreateGroupRequest *request
);
/**
* @brief Renew group
* @param from
* @param auth
* @param request
* @return response
*/
E2ees__RenewGroupResponse *(*renew_group)(
E2ees__E2eeAddress *from,
const char *auth,
E2ees__RenewGroupRequest *request
);
/**
* @brief Add group members
* @param from
Expand Down
13 changes: 13 additions & 0 deletions include/e2ees/e2ees_client_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,19 @@ E2ees__SendOne2oneMsgResponse *send_one2one_msg_internal(
const uint8_t *plaintext_data, size_t plaintext_data_len
);

/**
* @brief Renew a group.
* @param response_out
* @param sender_address
* @param group_address
* @return 0 if success
*/
int renew_group_internal(
E2ees__RenewGroupResponse **response_out,
E2ees__E2eeAddress *sender_address,
E2ees__E2eeAddress *group_address
);

/**
* @brief Send add_group_member_device request to server.
* @param response_out
Expand Down
33 changes: 33 additions & 0 deletions include/e2ees/group_session_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,39 @@ bool consume_create_group_msg(
E2ees__CreateGroupMsg *msg
);

/**
* @brief Create a RenewGroupRequest message to be sent to server.
* @param request_out
* @param outbound_group_session
* @return 0 if success
*/
int produce_renew_group_request(
E2ees__RenewGroupRequest **request_out,
E2ees__GroupSession *outbound_group_session
);

/**
* @brief Process an incoming RenewGroupResponse message.
* @param outbound_group_session
* @param response
* @return 0 if success
*/
int consume_renew_group_response(
E2ees__GroupSession *outbound_group_session,
E2ees__RenewGroupResponse *response
);

/**
* @brief Create a RenewGroupMsg message to be sent to server.
* @param receiver_address
* @param msg
* @return true for success
*/
bool consume_renew_group_msg(
E2ees__E2eeAddress *receiver_address,
E2ees__RenewGroupMsg *msg
);

/**
* @brief Process an incoming GetGroupResponse message.
* @param response
Expand Down
3 changes: 3 additions & 0 deletions include/e2ees/log_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ enum LogCode {
BAD_PUBLISH_SPK_REQUEST = 7091,
BAD_REGISTER_USER_REQUEST = 7101,
BAD_REMOVE_GROUP_MEMBERS_REQUEST = 7111,
BAD_RENEW_GROUP_REQUEST = 7116,
BAD_SEND_GROUP_MSG_REQUEST = 7121,
BAD_SEND_ONE2ONE_MSG_REQUEST = 7131,
BAD_SUPPLY_OPKS_REQUEST = 7141,
Expand All @@ -114,6 +115,7 @@ enum LogCode {
BAD_PUBLISH_SPK_RESPONSE = 7391,
BAD_REGISTER_USER_RESPONSE = 7401,
BAD_REMOVE_GROUP_MEMBERS_RESPONSE = 7411,
BAD_RENEW_GROUP_RESPONSE = 7416,
BAD_SEND_GROUP_MSG_RESPONSE = 7421,
BAD_SEND_ONE2ONE_MSG_RESPONSE = 7431,
BAD_SUPPLY_OPKS_RESPONSE = 7441,
Expand All @@ -133,6 +135,7 @@ enum LogCode {
BAD_PUBLISH_SPK_MSG = 7701,
BAD_REGISTER_USER_MSG = 7711,
BAD_REMOVE_GROUP_MEMBERS_MSG = 7721,
BAD_RENEW_GROUP_MSG = 7726,
BAD_SUPPLY_OPKS_MSG = 7731,
BAD_UPDATE_USER_MSG = 7741,

Expand Down
8 changes: 8 additions & 0 deletions include/e2ees/mem_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,14 @@ void copy_group_info(E2ees__GroupInfo **dest, E2ees__GroupInfo *src);
*/
void copy_create_group_msg(E2ees__CreateGroupMsg **dest, E2ees__CreateGroupMsg *src);

/**
* @brief Copy E2ees__RenewGroupMsg from src to dest.
*
* @param dest
* @param src
*/
void copy_renew_group_msg(E2ees__RenewGroupMsg **dest, E2ees__RenewGroupMsg *src);

/**
* @brief Copy E2ees__AddGroupMembersMsg from src to dest.
*
Expand Down
2 changes: 1 addition & 1 deletion src/e2ees.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ void e2ees_notify_log(E2ees__E2eeAddress *user_address, LogCode log_code, const
char stack_trace[512] = {0};
get_stack_trace(stack_trace, sizeof(stack_trace));

char log_msg[4096 + 512] = {0};
char log_msg[4096 + 512 + 128] = {0};
snprintf(log_msg, sizeof(log_msg), "<%s> %s\nStack trace:\n%s", logcode_str, msg, stack_trace);
e2ees_plugin->event_handler.on_log(user_address, log_code, log_msg);
}
Expand Down
29 changes: 29 additions & 0 deletions src/e2ees_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,35 @@ int send_group_msg_with_filter(
}
}

// proactive rotation
if (ret == E2EES_RESULT_SUCC) {
// if the sequence reach the limit, renew the group
if (outbound_group_session->sequence >= 100) {
e2ees_notify_log(sender_address, DEBUG_LOG, "Sequence limit reached, renewing group...");

// renew_group
ret = renew_group_internal(NULL, sender_address, group_address);

// unload the old group session, whether renewing group success or not
e2ees__group_session__free_unpacked(outbound_group_session, NULL);
outbound_group_session = NULL;

// load the group session if success
if (ret == E2EES_RESULT_SUCC) {
get_e2ees_plugin()->db_handler.load_group_session_by_address(
sender_address, sender_address, group_address, &outbound_group_session
);

// validate
if (!is_valid_group_session(outbound_group_session)) {
ret = E2EES_RESULT_FAIL;
}
} else {
e2ees_notify_log(sender_address, BAD_RENEW_GROUP_RESPONSE, "Proactive rotation failed, cannot send message");
}
}
}

if (ret == E2EES_RESULT_SUCC) {
ret = encrypt_group_msg(
&group_msg_payload,
Expand Down
78 changes: 78 additions & 0 deletions src/e2ees_client_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <string.h>

#include "e2ees/account_manager.h"
#include "e2ees/group_session.h"
#include "e2ees/group_session_manager.h"
#include "e2ees/mem_util.h"
#include "e2ees/validation.h"
Expand Down Expand Up @@ -482,6 +483,83 @@ E2ees__SendOne2oneMsgResponse *send_one2one_msg_internal(
return response;
}

int renew_group_internal(
E2ees__RenewGroupResponse **response_out,
E2ees__E2eeAddress *sender_address,
E2ees__E2eeAddress *group_address
) {
int ret = E2EES_RESULT_SUCC;

E2ees__RenewGroupRequest *renew_group_request = NULL;
E2ees__RenewGroupResponse *renew_group_response = NULL;
E2ees__Account *account = NULL;
E2ees__GroupSession *outbound_group_session = NULL;

// validate
if (sender_address == NULL || group_address == NULL) {
ret = E2EES_RESULT_FAIL;
}

if (ret == E2EES_RESULT_SUCC) {
get_e2ees_plugin()->db_handler.load_account_by_address(sender_address, &account);
if (!account || !is_valid_e2ees_pack_id(account->e2ees_pack_id) || !is_valid_string(account->auth)) {
e2ees_notify_log(sender_address, BAD_ACCOUNT, "renew_group(): invalid account");
ret = E2EES_RESULT_FAIL;
}
}

// load outbound_group_session
if (ret == E2EES_RESULT_SUCC) {
get_e2ees_plugin()->db_handler.load_group_session_by_address(sender_address, sender_address, group_address, &outbound_group_session);
if (outbound_group_session == NULL) {
e2ees_notify_log(sender_address, BAD_GROUP_SESSION, "renew_group(): cannot load existing outbound group session");
ret = E2EES_RESULT_FAIL;
}
}

// produce
if (ret == E2EES_RESULT_SUCC) {
ret = produce_renew_group_request(&renew_group_request, outbound_group_session);
}

// send to server
if (ret == E2EES_RESULT_SUCC) {
renew_group_response = dispatch_proto_request(get_e2ees_plugin()->proto_handler.renew_group, renew_group_request, sender_address, account->auth);

// validate response
if (renew_group_response == NULL || renew_group_response->code != E2EES__RESPONSE_CODE__RESPONSE_CODE_OK) {
e2ees_notify_log(sender_address, BAD_CREATE_GROUP_RESPONSE, "renew_group(): invalid renew_group_response");
ret = E2EES_RESULT_FAIL;
}
}

// consume response
if (ret == E2EES_RESULT_SUCC) {
ret = consume_renew_group_response(outbound_group_session, renew_group_response);
if (ret != E2EES_RESULT_SUCC) {
e2ees_notify_log(sender_address, BAD_CONSUME, "Server renewed group but local consume response failed");
}
}

// release
free_proto(account);
free_proto(renew_group_request);
if (outbound_group_session != NULL) {
e2ees__group_session__free_unpacked(outbound_group_session, NULL);
}

if (renew_group_response != NULL) {
if (response_out != NULL) {
*response_out = renew_group_response;
} else {
free_proto(renew_group_response);
}
}

// done
return ret;
}

int add_group_member_device_internal(
E2ees__AddGroupMemberDeviceResponse **response_out,
E2ees__E2eeAddress *sender_address,
Expand Down
2 changes: 2 additions & 0 deletions src/group_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,8 @@ int new_outbound_group_session_by_sender(
);
// release
free_invite_response_list(&invite_response_list, invite_response_num);
invite_response_list = NULL;
invite_response_num = 0;
}
}

Expand Down
Loading