Skip to content

Commit 304085b

Browse files
committed
refactor identity key change handling, clear sibling sessions on encounter
fixes #63, fixes #62
1 parent f6da5a0 commit 304085b

13 files changed

+277
-86
lines changed

Signal-Windows/Controls/Conversation.xaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818
<DataTemplate x:Key="UnreadMarkerTemplate">
1919
<local:UnreadMarker />
2020
</DataTemplate>
21-
<local:MessageTemplateSelector x:Key="MessageDataTemplateSelector" NormalMessage="{StaticResource NormalMessageTemplate}" UnreadMarker="{StaticResource UnreadMarkerTemplate}" />
21+
<DataTemplate x:Key="IdentityKeyChangeTemplate">
22+
<local:IdentityKeyChangeMessage />
23+
</DataTemplate>
24+
<local:MessageTemplateSelector x:Key="MessageDataTemplateSelector" NormalMessage="{StaticResource NormalMessageTemplate}" UnreadMarker="{StaticResource UnreadMarkerTemplate}" IdentityKeyChangeMessage="{StaticResource IdentityKeyChangeTemplate}" />
2225
</Control.Resources>
2326
<Grid>
2427
<Grid.RowDefinitions>

Signal-Windows/Controls/Conversation.xaml.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,12 +225,18 @@ public class MessageTemplateSelector : DataTemplateSelector
225225
{
226226
public DataTemplate NormalMessage { get; set; }
227227
public DataTemplate UnreadMarker { get; set; }
228+
public DataTemplate IdentityKeyChangeMessage { get; set; }
228229

229230
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
230231
{
231232
FrameworkElement element = container as FrameworkElement;
232233
if (item is SignalMessage)
233234
{
235+
SignalMessage sm = (SignalMessage)item;
236+
if (sm.Type == SignalMessageType.IdentityKeyChange)
237+
{
238+
return IdentityKeyChangeMessage;
239+
}
234240
return NormalMessage;
235241
}
236242
if (item is SignalUnreadMarker)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<UserControl
2+
x:Class="Signal_Windows.Controls.IdentityKeyChangeMessage"
3+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+
xmlns:local="using:Signal_Windows.Controls"
6+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
7+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8+
mc:Ignorable="d"
9+
d:DesignHeight="300"
10+
d:DesignWidth="400">
11+
12+
<Border HorizontalAlignment="Center" BorderBrush="#00000000" BorderThickness="1,1,1,1" CornerRadius="8,8,8,8" Background="Beige" Padding="50 5 50 5">
13+
<TextBlock Name="MessageTextBlock" />
14+
</Border>
15+
</UserControl>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using Signal_Windows.Models;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.IO;
5+
using System.Linq;
6+
using System.Runtime.InteropServices.WindowsRuntime;
7+
using Windows.Foundation;
8+
using Windows.Foundation.Collections;
9+
using Windows.UI.Xaml;
10+
using Windows.UI.Xaml.Controls;
11+
using Windows.UI.Xaml.Controls.Primitives;
12+
using Windows.UI.Xaml.Data;
13+
using Windows.UI.Xaml.Input;
14+
using Windows.UI.Xaml.Media;
15+
using Windows.UI.Xaml.Navigation;
16+
17+
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
18+
19+
namespace Signal_Windows.Controls
20+
{
21+
public sealed partial class IdentityKeyChangeMessage : UserControl
22+
{
23+
public IdentityKeyChangeMessage()
24+
{
25+
this.InitializeComponent();
26+
DataContextChanged += IdentityKeyChangeMessage_DataContextChanged;
27+
}
28+
public SignalMessage Model
29+
{
30+
get
31+
{
32+
return this.DataContext as SignalMessage;
33+
}
34+
set
35+
{
36+
this.DataContext = value;
37+
}
38+
}
39+
40+
private void IdentityKeyChangeMessage_DataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
41+
{
42+
MessageTextBlock.Text = Model.Content.Content;
43+
}
44+
}
45+
}

Signal-Windows/Controls/Message.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ private void UpdateSignalMessageStatusIcon(SignalMessage updatedMessage)
121121

122122
private void UpdateResendButton(SignalMessage updatedMessage)
123123
{
124-
if (updatedMessage.Direction == SignalMessageDirection.Outgoing && (updatedMessage.Status == SignalMessageStatus.Failed_Identity || updatedMessage.Status == SignalMessageStatus.Failed_Network))
124+
if (updatedMessage.Direction == SignalMessageDirection.Outgoing && updatedMessage.Status != SignalMessageStatus.Pending && updatedMessage.Status != SignalMessageStatus.Confirmed && updatedMessage.Status != SignalMessageStatus.Received)
125125
{
126126
ResendVisibility = Visibility.Visible;
127127
}

Signal-Windows/Models/SignalMessage.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public enum SignalMessageType
3030
Normal = 0,
3131
GroupUpdate = 1,
3232
SessionReset = 2,
33-
ExpireUpdate = 3
33+
ExpireUpdate = 3,
34+
IdentityKeyChange = 4
3435
}
3536

3637
public enum SignalMessageDirection
@@ -46,6 +47,8 @@ public enum SignalMessageStatus
4647
Confirmed = 1,
4748
Received = 2,
4849
Failed_Identity = 3,
49-
Failed_Network = 4
50+
Failed_Network = 4,
51+
Failed_Ratelimit = 5,
52+
Failed_Unknown = 6
5053
}
5154
}

Signal-Windows/Signal-Windows.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@
104104
<Compile Include="App.xaml.cs">
105105
<DependentUpon>App.xaml</DependentUpon>
106106
</Compile>
107+
<Compile Include="Controls\IdentityKeyChangeMessage.xaml.cs">
108+
<DependentUpon>IdentityKeyChangeMessage.xaml</DependentUpon>
109+
</Compile>
107110
<Compile Include="Controls\Message.xaml.cs">
108111
<DependentUpon>Message.xaml</DependentUpon>
109112
</Compile>
@@ -194,6 +197,10 @@
194197
<Generator>MSBuild:Compile</Generator>
195198
<SubType>Designer</SubType>
196199
</ApplicationDefinition>
200+
<Page Include="Controls\IdentityKeyChangeMessage.xaml">
201+
<SubType>Designer</SubType>
202+
<Generator>MSBuild:Compile</Generator>
203+
</Page>
197204
<Page Include="Controls\Message.xaml">
198205
<SubType>Designer</SubType>
199206
<Generator>MSBuild:Compile</Generator>

Signal-Windows/Signal/IncomingMessages.cs

Lines changed: 48 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -77,79 +77,76 @@ public void onMessages(SignalServiceEnvelope[] envelopes)
7777

7878
private void HandleMessage(SignalServiceEnvelope envelope)
7979
{
80-
try
81-
{
82-
var cipher = new SignalServiceCipher(new SignalServiceAddress(App.Store.Username), new Store());
83-
var content = cipher.decrypt(envelope);
84-
long timestamp = Util.CurrentTimeMillis();
80+
var cipher = new SignalServiceCipher(new SignalServiceAddress(App.Store.Username), new Store());
81+
var content = cipher.decrypt(envelope);
82+
long timestamp = Util.CurrentTimeMillis();
8583

86-
if (content.Message != null)
84+
if (content.Message != null)
85+
{
86+
SignalServiceDataMessage message = content.Message;
87+
if (message.EndSession)
8788
{
88-
SignalServiceDataMessage message = content.Message;
89-
if (message.EndSession)
90-
{
91-
LibsignalDBContext.DeleteAllSessions(envelope.getSource());
92-
}
93-
else if (message.IsGroupUpdate())
89+
LibsignalDBContext.DeleteAllSessions(envelope.getSource());
90+
}
91+
else if (message.IsGroupUpdate())
92+
{
93+
if (message.Group.Type == SignalServiceGroup.GroupType.DELIVER)
9494
{
9595
HandleGroupUpdateMessage(envelope, content, message, timestamp);
9696
}
97-
else if (message.ExpirationUpdate)
97+
}
98+
else if (message.ExpirationUpdate)
99+
{
100+
string threadid;
101+
if (message.Group != null)
98102
{
99-
string threadid;
100-
if (message.Group != null)
101-
{
102-
threadid = Base64.encodeBytes(message.Group.GroupId);
103-
SignalDBContext.GetOrCreateGroupLocked(threadid, timestamp, this);
104-
}
105-
else
106-
{
107-
threadid = envelope.getSource();
108-
SignalDBContext.GetOrCreateContactLocked(threadid, timestamp, this);
109-
}
110-
SignalDBContext.UpdateExpiresInLocked(new SignalConversation() { ThreadId = threadid }, (uint)message.ExpiresInSeconds);
103+
threadid = Base64.encodeBytes(message.Group.GroupId);
104+
SignalDBContext.GetOrCreateGroupLocked(threadid, timestamp, this);
111105
}
112106
else
113107
{
114-
//TODO check both the db for duplicates
115-
HandleSignalMessage(envelope, content, message, false, timestamp);
108+
threadid = envelope.getSource();
109+
SignalDBContext.GetOrCreateContactLocked(threadid, timestamp, this);
116110
}
111+
SignalDBContext.UpdateExpiresInLocked(new SignalConversation() { ThreadId = threadid }, (uint)message.ExpiresInSeconds);
117112
}
118-
else if (content.SynchronizeMessage != null)
113+
else
119114
{
120-
if (content.SynchronizeMessage.getSent().HasValue)
115+
//TODO check both the db for duplicates
116+
HandleSignalMessage(envelope, content, message, false, timestamp);
117+
}
118+
}
119+
else if (content.SynchronizeMessage != null)
120+
{
121+
if (content.SynchronizeMessage.getSent().HasValue)
122+
{
123+
var syncMessage = content.SynchronizeMessage.getSent().ForceGetValue();
124+
var dataMessage = syncMessage.getMessage();
125+
//TODO check both the db for duplicates
126+
if (dataMessage.IsGroupUpdate())
121127
{
122-
var syncMessage = content.SynchronizeMessage.getSent().ForceGetValue();
123-
var dataMessage = syncMessage.getMessage();
124-
//TODO check both the db for duplicates
125-
if (dataMessage.IsGroupUpdate())
128+
if (dataMessage.Group.Type == SignalServiceGroup.GroupType.DELIVER)
126129
{
127130
HandleGroupUpdateMessage(envelope, content, dataMessage, timestamp);
128131
}
129-
else
130-
{
131-
HandleSignalMessage(envelope, content, dataMessage, true, timestamp);
132-
}
133132
}
134-
else if (content.SynchronizeMessage.getRead().HasValue)
133+
else
135134
{
136-
var readMessages = content.SynchronizeMessage.getRead().ForceGetValue();
137-
foreach (var readMessage in readMessages)
138-
{
139-
//TODO
140-
}
135+
HandleSignalMessage(envelope, content, dataMessage, true, timestamp);
141136
}
142-
} //TODO callmessages
143-
else
137+
}
138+
else if (content.SynchronizeMessage.getRead().HasValue)
144139
{
145-
Debug.WriteLine("HandleMessage got unrecognized message from " + envelope.getSource());
140+
var readMessages = content.SynchronizeMessage.getRead().ForceGetValue();
141+
foreach (var readMessage in readMessages)
142+
{
143+
//TODO
144+
}
146145
}
147-
}
148-
catch (libsignal.exceptions.UntrustedIdentityException e)
146+
} //TODO callmessages
147+
else
149148
{
150-
Debug.WriteLine("HandleMessage received message from changed identity");
151-
LibsignalDBContext.UpdateIdentityLocked(e.getName(), Base64.encodeBytes(e.getUntrustedIdentity().serialize()), VerifiedStatus.Default, this);
152-
HandleMessage(envelope);
149+
Debug.WriteLine("HandleMessage got unrecognized message from " + envelope.getSource());
153150
}
154151
}
155152

Signal-Windows/Signal/OutgoingMessages.cs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
using libsignal;
2+
using libsignalservice.crypto;
13
using libsignalservice.messages;
24
using libsignalservice.push;
5+
using libsignalservice.push.exceptions;
36
using libsignalservice.util;
47
using Signal_Windows.Models;
58
using Signal_Windows.Storage;
@@ -76,18 +79,50 @@ public void HandleOutgoingMessages()
7679
Debug.WriteLine("HandleOutgoingMessages finished");
7780
return;
7881
}
79-
catch (libsignal.exceptions.UntrustedIdentityException e)
82+
catch (EncapsulatedExceptions exceptions)
83+
{
84+
Debug.WriteLine(exceptions.Message);
85+
Debug.WriteLine(exceptions.StackTrace);
86+
IList<UntrustedIdentityException> identityExceptions = exceptions.getUntrustedIdentityExceptions();
87+
if (exceptions.getNetworkExceptions().Count > 0)
88+
{
89+
outgoingSignalMessage.Status = SignalMessageStatus.Failed_Network;
90+
}
91+
if (identityExceptions.Count > 0)
92+
{
93+
outgoingSignalMessage.Status = SignalMessageStatus.Failed_Identity;
94+
}
95+
foreach (UntrustedIdentityException e in identityExceptions)
96+
{
97+
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
98+
{
99+
await MainPage.NotifyNewIdentity(e.getE164Number());
100+
}).AsTask().Wait();
101+
LibsignalDBContext.SaveIdentityLocked(new SignalProtocolAddress(e.getE164Number(), 1), Base64.encodeBytes(e.getIdentityKey().serialize()));
102+
}
103+
}
104+
catch (RateLimitException e)
105+
{
106+
Debug.WriteLine(e.Message);
107+
Debug.WriteLine(e.StackTrace);
108+
outgoingSignalMessage.Status = SignalMessageStatus.Failed_Ratelimit;
109+
}
110+
catch (UntrustedIdentityException e)
80111
{
81-
//LibsignalDBContext.UpdateIdentityLocked(e.getName(), Base64.encodeBytes(e.getUntrustedIdentity().serialize()), VerifiedStatus.Default, this);
82112
Debug.WriteLine(e.Message);
83113
Debug.WriteLine(e.StackTrace);
84114
outgoingSignalMessage.Status = SignalMessageStatus.Failed_Identity;
115+
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
116+
{
117+
await MainPage.NotifyNewIdentity(e.getE164Number());
118+
}).AsTask().Wait();
119+
LibsignalDBContext.SaveIdentityLocked(new SignalProtocolAddress(e.getE164Number(), 1), Base64.encodeBytes(e.getIdentityKey().serialize()));
85120
}
86121
catch (Exception e)
87122
{
88123
Debug.WriteLine(e.Message);
89124
Debug.WriteLine(e.StackTrace);
90-
outgoingSignalMessage.Status = SignalMessageStatus.Failed_Network;
125+
outgoingSignalMessage.Status = SignalMessageStatus.Failed_Unknown;
91126
}
92127
SignalDBContext.UpdateMessageStatus(outgoingSignalMessage, this);
93128
}

0 commit comments

Comments
 (0)