Commit 58815c2c authored by Matthieu Tanon's avatar Matthieu Tanon

Feature/server encrypted chatrooms

parent 1373b5ad
......@@ -93,11 +93,8 @@ static void call_received(SalCallOp *h) {
linphone_address_unref(toAddr);
linphone_address_unref(fromAddr);
if (sal_address_has_param(h->getRemoteContactAddress(), "text")) {
bool oneToOneChatRoom = false;
const char *oneToOneChatRoomStr = sal_custom_header_find(h->getRecvCustomHeaders(), "One-To-One-Chat-Room");
if (oneToOneChatRoomStr && (strcmp(oneToOneChatRoomStr, "true") == 0))
oneToOneChatRoom = true;
if (oneToOneChatRoom) {
if (oneToOneChatRoomStr && (strcmp(oneToOneChatRoomStr, "true") == 0)) {
bool_t oneToOneChatRoomEnabled = linphone_config_get_bool(linphone_core_get_config(lc), "misc", "enable_one_to_one_chat_room", TRUE);
if (!oneToOneChatRoomEnabled) {
h->decline(SalReasonNotAcceptable);
......@@ -111,7 +108,10 @@ static void call_received(SalCallOp *h) {
h->release();
return;
}
IdentityAddress confAddr = L_GET_PRIVATE_FROM_C_OBJECT(lc)->mainDb->findOneToOneConferenceChatRoomAddress(from, identAddresses.front());
const char *endToEndEncryptedStr = sal_custom_header_find(h->getRecvCustomHeaders(), "End-To-End-Encrypted");
bool encrypted = endToEndEncryptedStr && strcmp(endToEndEncryptedStr, "true") == 0;
IdentityAddress confAddr = L_GET_PRIVATE_FROM_C_OBJECT(lc)->mainDb->findOneToOneConferenceChatRoomAddress(from, identAddresses.front(), encrypted);
if (confAddr.isValid()) {
shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(ConferenceId(confAddr, confAddr));
L_GET_PRIVATE(static_pointer_cast<ServerGroupChatRoom>(chatRoom))->confirmRecreation(h);
......
......@@ -39,6 +39,7 @@
F(Conference /**< Use server (supports group chat) */, 1 << 2) \
F(Proxy /**< Special proxy chat room flag */, 1 << 3) \
F(Migratable /**< Chat room migratable from Basic to Conference */, 1 << 4) \
F(OneToOne /**< A communication between two participants (can be Basic or Conference) */, 1 << 5)
F(OneToOne /**< A communication between two participants (can be Basic or Conference) */, 1 << 5) \
F(Encrypted /**< Chat room is encrypted */, 1 << 6)
#endif // ifndef _L_CHAT_ROOM_ENUMS_H_
......@@ -485,7 +485,8 @@ void ServerGroupChatRoomPrivate::addCompatibleParticipants (const IdentityAddres
q->addParticipants(compatibleParticipants, nullptr, false);
if ((capabilities & ServerGroupChatRoom::Capabilities::OneToOne) && (q->getParticipantCount() == 2)) {
// Insert the one-to-one chat room in Db if participants count is 2.
q->getCore()->getPrivate()->mainDb->insertOneToOneConferenceChatRoom(q->getSharedFromThis());
bool encrypted = capabilities & ServerGroupChatRoom::Capabilities::Encrypted;
q->getCore()->getPrivate()->mainDb->insertOneToOneConferenceChatRoom(q->getSharedFromThis(), encrypted);
}
}
}
......@@ -638,6 +639,8 @@ void ServerGroupChatRoomPrivate::inviteDevice (const shared_ptr<ParticipantDevic
CallSessionParams csp;
if (capabilities & ServerGroupChatRoom::Capabilities::OneToOne)
csp.addCustomHeader("One-To-One-Chat-Room", "true");
if (capabilities & ServerGroupChatRoom::Capabilities::Encrypted)
csp.addCustomHeader("End-To-End-Encrypted", "true");
session = participant->getPrivate()->createSession(*q, &csp, false, this);
session->configure(LinphoneCallOutgoing, nullptr, nullptr, qConference->getPrivate()->conferenceAddress, device->getAddress());
device->setSession(session);
......@@ -816,6 +819,9 @@ LocalConference(getCore(), IdentityAddress(linphone_proxy_config_get_conference_
const char *oneToOneChatRoomStr = sal_custom_header_find(op->getRecvCustomHeaders(), "One-To-One-Chat-Room");
if (oneToOneChatRoomStr && (strcmp(oneToOneChatRoomStr, "true") == 0))
d->capabilities |= ServerGroupChatRoom::Capabilities::OneToOne;
const char *endToEndEncryptedStr = sal_custom_header_find(op->getRecvCustomHeaders(), "End-To-End-Encrypted");
if (endToEndEncryptedStr && (strcmp(endToEndEncryptedStr, "true") == 0))
d->capabilities |= ServerGroupChatRoom::Capabilities::Encrypted;
shared_ptr<CallSession> session = getMe()->getPrivate()->createSession(*this, nullptr, false, d);
session->configure(LinphoneCallIncoming, nullptr, op, Address(op->getFrom()), Address(op->getTo()));
getCore()->getPrivate()->localListEventHandler->addHandler(dConference->eventHandler.get());
......
......@@ -76,12 +76,14 @@ namespace Statements {
/* SelectOneToOneChatRoomId */ R"(
SELECT chat_room_id
FROM one_to_one_chat_room
LEFT JOIN chat_room ON chat_room.id = chat_room_id
WHERE participant_a_sip_address_id IN (:1, :2)
AND participant_b_sip_address_id IN (:1, :2)
AND (
(participant_a_sip_address_id <> participant_b_sip_address_id AND :1 <> :2) OR
(participant_a_sip_address_id = participant_b_sip_address_id AND :1 = :2)
)
AND (capabilities & :3) = :4
)",
/* SelectConferenceEvent */ R"(
......
......@@ -68,7 +68,7 @@ private:
long long selectChatRoomId (long long peerSipAddressId, long long localSipAddressId) const;
long long selectChatRoomId (const ConferenceId &conferenceId) const;
long long selectChatRoomParticipantId (long long chatRoomId, long long participantSipAddressId) const;
long long selectOneToOneChatRoomId (long long sipAddressIdA, long long sipAddressIdB) const;
long long selectOneToOneChatRoomId (long long sipAddressIdA, long long sipAddressIdB, bool encrypted) const;
void deleteContents (long long chatMessageId);
void deleteChatRoomParticipant (long long chatRoomId, long long participantSipAddressId);
......
......@@ -473,12 +473,15 @@ long long MainDbPrivate::selectChatRoomParticipantId (long long chatRoomId, long
return session->got_data() ? chatRoomParticipantId : -1;
}
long long MainDbPrivate::selectOneToOneChatRoomId (long long sipAddressIdA, long long sipAddressIdB) const {
long long MainDbPrivate::selectOneToOneChatRoomId (long long sipAddressIdA, long long sipAddressIdB, bool encrypted) const {
long long chatRoomId;
const int encryptedCapability = int(ChatRoom::Capabilities::Encrypted);
const int expectedCapabilities = encrypted ? encryptedCapability : 0;
soci::session *session = dbSession.getBackendSession();
*session << Statements::get(Statements::SelectOneToOneChatRoomId),
soci::use(sipAddressIdA, "1"), soci::use(sipAddressIdB, "2"),
soci::use(encryptedCapability, "3"), soci::use(expectedCapabilities, "4"),
soci::into(chatRoomId);
return session->got_data() ? chatRoomId : -1;
......@@ -2693,7 +2696,8 @@ IdentityAddress MainDb::findMissingOneToOneConferenceChatRoomParticipantAddress
IdentityAddress MainDb::findOneToOneConferenceChatRoomAddress (
const IdentityAddress &participantA,
const IdentityAddress &participantB
const IdentityAddress &participantB,
bool encrypted
) const {
return L_DB_TRANSACTION {
L_D();
......@@ -2703,7 +2707,9 @@ IdentityAddress MainDb::findOneToOneConferenceChatRoomAddress (
if (participantASipAddressId == -1 || participantBSipAddressId == -1)
return IdentityAddress();
const long long &chatRoomId = d->selectOneToOneChatRoomId(participantASipAddressId, participantBSipAddressId);
const long long &chatRoomId = d->selectOneToOneChatRoomId(participantASipAddressId, participantBSipAddressId, encrypted);
if (chatRoomId == -1)
return IdentityAddress();
string chatRoomAddress;
*d->dbSession.getBackendSession() << "SELECT sip_address.value"
......@@ -2715,7 +2721,7 @@ IdentityAddress MainDb::findOneToOneConferenceChatRoomAddress (
};
}
void MainDb::insertOneToOneConferenceChatRoom (const shared_ptr<AbstractChatRoom> &chatRoom) {
void MainDb::insertOneToOneConferenceChatRoom (const shared_ptr<AbstractChatRoom> &chatRoom, bool encrypted) {
L_ASSERT(linphone_core_conference_server_enabled(chatRoom->getCore()->getCCore()));
L_ASSERT(chatRoom->getCapabilities() & ChatRoom::Capabilities::OneToOne);
......@@ -2728,7 +2734,7 @@ void MainDb::insertOneToOneConferenceChatRoom (const shared_ptr<AbstractChatRoom
L_ASSERT(participantASipAddressId != -1);
L_ASSERT(participantBSipAddressId != -1);
long long chatRoomId = d->selectOneToOneChatRoomId(participantASipAddressId, participantBSipAddressId);
long long chatRoomId = d->selectOneToOneChatRoomId(participantASipAddressId, participantBSipAddressId, encrypted);
if (chatRoomId == -1) {
chatRoomId = d->selectChatRoomId(chatRoom->getConferenceId());
*d->dbSession.getBackendSession() << Statements::get(Statements::InsertOneToOneChatRoom, getBackend()),
......
......@@ -178,9 +178,10 @@ public:
);
IdentityAddress findOneToOneConferenceChatRoomAddress (
const IdentityAddress &participantA,
const IdentityAddress &participantB
const IdentityAddress &participantB,
bool encrypted
) const;
void insertOneToOneConferenceChatRoom (const std::shared_ptr<AbstractChatRoom> &chatRoom);
void insertOneToOneConferenceChatRoom (const std::shared_ptr<AbstractChatRoom> &chatRoom, bool encrypted);
void updateChatRoomParticipantDevice (
const std::shared_ptr<AbstractChatRoom> &chatRoom,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment