-
Notifications
You must be signed in to change notification settings - Fork 7
/
ChatOTR.py
176 lines (145 loc) · 7.1 KB
/
ChatOTR.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# Copyright (C) 2013 AG Projects. See LICENSE for details.
#
from AppKit import NSApp, NSOKButton, NSCancelButton, NSOnState, NSControlTextDidChangeNotification
from Foundation import NSObject, NSBundle, NSColor, NSLocalizedString, NSTimer, NSRunLoop, NSRunLoopCommonModes, NSNotificationCenter
import objc
import os
import shutil
from application.system import makedirs
from sipsimple.streams.msrp.chat import ChatStreamError
from sipsimple.util import ISOTimestamp
from util import format_identity_to_string
from resources import ApplicationData
from BlinkLogger import BlinkLogger
class ChatOtrSmp(NSObject):
window = objc.IBOutlet()
labelText = objc.IBOutlet()
secretText = objc.IBOutlet()
questionText = objc.IBOutlet()
progressBar = objc.IBOutlet()
statusText = objc.IBOutlet()
continueButton = objc.IBOutlet()
cancelButton = objc.IBOutlet()
finished = False
requested_by_remote = None
timer = None
smp_running = False
def __new__(cls, *args, **kwargs):
return cls.alloc().init()
def __init__(self, controller):
NSBundle.loadNibNamed_owner_("ChatOtrSmp", self)
self.controller = controller
self.statusText.setStringValue_('')
self.progressBar.startAnimation_(None)
self.window.setTitle_(NSLocalizedString("Identity Verification for %s", "Window title") % self.controller.sessionController.titleShort)
self.stream = self.controller.stream
self.remote_address = self.controller.sessionController.remoteAOR
NSNotificationCenter.defaultCenter().addObserver_selector_name_object_(self, "controlTextDidChange:", NSControlTextDidChangeNotification, self.secretText)
def close(self):
self.controller = None
if self.timer is not None:
if self.timer.isValid():
self.timer.invalidate()
self.timer = None
self.release()
def dealloc(self):
objc.super(ChatOtrSmp, self).dealloc()
@objc.IBAction
def okClicked_(self, sender):
self.statusText.setTextColor_(NSColor.blackColor())
if self.finished:
self.window.orderOut_(self)
return
secret = self.secretText.stringValue()
secret = secret.encode() if secret else None
if self.requested_by_remote:
self.controller.sessionController.log_info("OTR SMP verification will be answered")
self.stream.encryption.smp_answer(secret)
self.smp_running = True
self.progressBar.setDoubleValue_(6)
else:
qtext = self.questionText.stringValue()
qtext = qtext.encode() if qtext else None
self.controller.sessionController.log_info("OTR SMP verification will be requested")
self.stream.encryption.smp_verify(secret, qtext)
self.progressBar.setIndeterminate_(False)
self.smp_running = True
self.progressBar.setDoubleValue_(3)
self.statusText.setStringValue_(NSLocalizedString("Verification request sent", "Label"))
self.continueButton.setEnabled_(False)
@objc.IBAction
def secretEntered_(self, sender):
self.okClicked_(None)
def controlTextDidChange_(self, notification):
secret = self.secretText.stringValue().encode('utf-8')
self.continueButton.setEnabled_(bool(secret))
@objc.IBAction
def cancelClicked_(self, sender):
self.window.orderOut_(self)
if self.smp_running:
self.controller.sessionController.log_info("OTR SMP verification will be aborted")
self.stream.encryption.smp_abort()
self.smp_running = False
def handle_remote_response(self, same_secrets=False):
if not same_secrets:
self.statusText.setTextColor_(NSColor.redColor())
self.statusText.setStringValue_(NSLocalizedString("Identity verification failed. Try again later.", "Label"))
result = False
else:
self.stream.encryption.verified = True
self.statusText.setTextColor_(NSColor.greenColor())
self.statusText.setStringValue_(NSLocalizedString("Identity verification succeeded", "Label"))
self.controller.revalidateToolbar()
self.controller.updateEncryptionWidgets()
result = True
self._finish(result)
return result
def _finish(self, result=False):
self.finished = True
self.smp_running = False
self.requested_by_remote = False
self.secretText.setEnabled_(False)
self.questionText.setEnabled_(False)
self.progressBar.setDoubleValue_(9)
self.continueButton.setEnabled_(False)
self.continueButton.setTitle_(NSLocalizedString("Finish", "Button Title"))
self.cancelButton.setHidden_(True)
self.continueButton.setEnabled_(True)
wait_interval = 5 if result else 10
self.timer = NSTimer.timerWithTimeInterval_target_selector_userInfo_repeats_(wait_interval, self, "verificationFinished:", None, False)
NSRunLoop.currentRunLoop().addTimer_forMode_(self.timer, NSRunLoopCommonModes)
def verificationFinished_(self, timer):
self.okClicked_(None)
def show(self, question=None, remote=False):
self.smp_running = True
self.finished = False
if remote:
self.requested_by_remote = True
self.statusText.setStringValue_(NSLocalizedString("Identity verification request received", "Label"))
self.secretText.setEnabled_(True)
self.questionText.setEnabled_(True)
self.cancelButton.setHidden_(False)
self.continueButton.setTitle_(NSLocalizedString("Continue", "Button title"))
self.progressBar.setIndeterminate_(False)
self.progressBar.setDoubleValue_(3 if self.requested_by_remote else 0)
self.secretText.setStringValue_('')
self.window.makeKeyAndOrderFront_(None)
if self.requested_by_remote:
self.continueButton.setTitle_(NSLocalizedString("Respond", "Button title"))
self.progressBar.setIndeterminate_(False)
self.progressBar.setDoubleValue_(3)
if question is None:
self.questionText.setHidden_(True)
self.labelText.setStringValue_(NSLocalizedString("%s wants to verify your identity using a commonly known secret.", "Label") % self.remote_address)
else:
self.questionText.setHidden_(False)
self.secretText.setHidden_(False)
self.questionText.setStringValue_(question.decode())
self.questionText.setEnabled_(False)
self.labelText.setStringValue_(NSLocalizedString("%s has asked you a question to verify your identity:", "Label") % self.remote_address)
else:
self.statusText.setStringValue_('')
self.questionText.setHidden_(False)
self.questionText.setStringValue_('')
self.questionText.setEnabled_(True)
self.labelText.setStringValue_(NSLocalizedString("You want to verify the identity of %s using a commonly known secret. Optionally, you can ask a question as a hint.", "Label") % self.remote_address)