|
David@0
|
1 |
/* |
|
David@0
|
2 |
* Adium is the legal property of its developers, whose names are listed in the copyright file included |
|
David@0
|
3 |
* with this source distribution. |
|
David@0
|
4 |
* |
|
David@0
|
5 |
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU |
|
David@0
|
6 |
* General Public License as published by the Free Software Foundation; either version 2 of the License, |
|
David@0
|
7 |
* or (at your option) any later version. |
|
David@0
|
8 |
* |
|
David@0
|
9 |
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even |
|
David@0
|
10 |
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General |
|
David@0
|
11 |
* Public License for more details. |
|
David@0
|
12 |
* |
|
David@0
|
13 |
* You should have received a copy of the GNU General Public License along with this program; if not, |
|
David@0
|
14 |
* write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|
David@0
|
15 |
*/ |
|
David@0
|
16 |
|
|
David@0
|
17 |
#import "ESOTRPreferences.h" |
|
David@0
|
18 |
#import <Adium/AIAccountControllerProtocol.h> |
|
David@0
|
19 |
#import <AIUtilities/AIImageAdditions.h> |
|
David@0
|
20 |
#import <AIUtilities/AIPopUpButtonAdditions.h> |
|
David@0
|
21 |
#import <Adium/AIAccount.h> |
|
David@0
|
22 |
#import <Adium/AIService.h> |
|
David@0
|
23 |
|
|
David@0
|
24 |
#import "OTRCommon.h" |
|
David@0
|
25 |
|
|
David@0
|
26 |
#import "AdiumOTREncryption.h" |
|
David@0
|
27 |
|
|
David@0
|
28 |
/* Adium OTR headers */ |
|
David@0
|
29 |
#import "ESOTRFingerprintDetailsWindowController.h" |
|
David@0
|
30 |
|
|
David@84
|
31 |
@interface ESOTRPreferences () |
|
David@0
|
32 |
- (void)tableViewSelectionDidChange:(NSNotification *)aNotification; |
|
David@0
|
33 |
@end |
|
David@0
|
34 |
|
|
David@0
|
35 |
@implementation ESOTRPreferences |
|
David@0
|
36 |
|
|
David@0
|
37 |
//Preference pane properties |
|
David@0
|
38 |
- (NSString *)label |
|
David@0
|
39 |
{ |
|
David@0
|
40 |
return AILocalizedString(@"Encryption",nil); |
|
David@0
|
41 |
} |
|
David@0
|
42 |
- (NSString *)nibName |
|
David@0
|
43 |
{ |
|
David@0
|
44 |
return @"OTRPrefs"; |
|
David@0
|
45 |
} |
|
David@0
|
46 |
- (NSImage *)image |
|
David@0
|
47 |
{ |
|
David@0
|
48 |
return [NSImage imageNamed:@"Lock_Locked State" forClass:[adium class]]; |
|
David@0
|
49 |
} |
|
David@0
|
50 |
|
|
David@0
|
51 |
- (void)viewDidLoad |
|
David@0
|
52 |
{ |
|
David@0
|
53 |
viewIsOpen = YES; |
|
David@0
|
54 |
|
|
David@0
|
55 |
//Account Menu |
|
David@0
|
56 |
accountMenu = [[AIAccountMenu accountMenuWithDelegate:self |
|
David@0
|
57 |
submenuType:AIAccountNoSubmenu |
|
David@0
|
58 |
showTitleVerbs:NO] retain]; |
|
David@0
|
59 |
|
|
David@0
|
60 |
//Fingerprints |
|
David@0
|
61 |
[tableView_fingerprints setDelegate:self]; |
|
David@0
|
62 |
[tableView_fingerprints setDataSource:self]; |
|
David@0
|
63 |
[tableView_fingerprints setTarget:self]; |
|
David@0
|
64 |
[tableView_fingerprints setDoubleAction:@selector(showFingerprint:)]; |
|
David@0
|
65 |
[self updateFingerprintsList]; |
|
David@0
|
66 |
|
|
David@0
|
67 |
[self updatePrivateKeyList]; |
|
David@0
|
68 |
|
|
David@0
|
69 |
[textField_privateKey setSelectable:YES]; |
|
David@0
|
70 |
|
|
David@0
|
71 |
[self tableViewSelectionDidChange:nil]; |
|
David@0
|
72 |
} |
|
David@0
|
73 |
|
|
David@0
|
74 |
- (void)viewWillClose |
|
David@0
|
75 |
{ |
|
David@0
|
76 |
viewIsOpen = NO; |
|
David@0
|
77 |
[fingerprintDictArray release]; fingerprintDictArray = nil; |
|
David@0
|
78 |
[accountMenu release]; accountMenu = nil; |
|
David@0
|
79 |
|
|
David@1109
|
80 |
[[NSNotificationCenter defaultCenter] removeObserver:self |
|
David@0
|
81 |
name:Account_ListChanged |
|
David@0
|
82 |
object:nil]; |
|
David@0
|
83 |
} |
|
David@0
|
84 |
|
|
David@0
|
85 |
/*! |
|
David@0
|
86 |
* @brief Deallocate |
|
David@0
|
87 |
*/ |
|
David@0
|
88 |
- (void)dealloc |
|
David@0
|
89 |
{ |
|
David@0
|
90 |
[fingerprintDictArray release]; fingerprintDictArray = nil; |
|
David@1109
|
91 |
[[NSNotificationCenter defaultCenter] removeObserver:self]; |
|
David@0
|
92 |
|
|
David@0
|
93 |
[super dealloc]; |
|
David@0
|
94 |
} |
|
David@0
|
95 |
|
|
David@0
|
96 |
/*! |
|
David@0
|
97 |
* @brief Update the fingerprint display |
|
David@0
|
98 |
* |
|
David@0
|
99 |
* Called by the OTR adapter when -otr informs us the fingerprint list changed |
|
David@0
|
100 |
*/ |
|
David@0
|
101 |
- (void)updateFingerprintsList |
|
David@0
|
102 |
{ |
|
David@0
|
103 |
OtrlUserState otrg_plugin_userstate = otrg_get_userstate(); |
|
David@0
|
104 |
|
|
David@0
|
105 |
if (viewIsOpen && otrg_plugin_userstate) { |
|
David@0
|
106 |
ConnContext *context; |
|
David@0
|
107 |
Fingerprint *fingerprint; |
|
David@0
|
108 |
|
|
David@0
|
109 |
[fingerprintDictArray release]; |
|
David@0
|
110 |
fingerprintDictArray = [[NSMutableArray alloc] init]; |
|
David@0
|
111 |
|
|
David@0
|
112 |
for (context = otrg_plugin_userstate->context_root; context != NULL; |
|
David@0
|
113 |
context = context->next) { |
|
David@0
|
114 |
|
|
David@0
|
115 |
fingerprint = context->fingerprint_root.next; |
|
David@0
|
116 |
/* If there's no fingerprint, don't add it to the known |
|
David@0
|
117 |
* fingerprints list */ |
|
David@0
|
118 |
while (fingerprint) { |
|
David@0
|
119 |
char hash[45]; |
|
David@0
|
120 |
NSDictionary *fingerprintDict; |
|
David@0
|
121 |
NSString *UID; |
|
David@0
|
122 |
NSString *state, *fingerprintString; |
|
David@0
|
123 |
|
|
David@0
|
124 |
UID = [NSString stringWithUTF8String:context->username]; |
|
David@0
|
125 |
|
|
David@0
|
126 |
if (context->msgstate == OTRL_MSGSTATE_ENCRYPTED && |
|
David@0
|
127 |
context->active_fingerprint != fingerprint) { |
|
David@0
|
128 |
state = AILocalizedString(@"Unused","Word to describe an encryption fingerprint which is not currently being used"); |
|
David@0
|
129 |
} else { |
|
David@0
|
130 |
TrustLevel trustLevel = otrg_plugin_context_to_trust(context); |
|
David@0
|
131 |
|
|
David@0
|
132 |
switch (trustLevel) { |
|
David@0
|
133 |
case TRUST_NOT_PRIVATE: |
|
David@0
|
134 |
state = AILocalizedString(@"Not private",nil); |
|
David@0
|
135 |
break; |
|
David@0
|
136 |
case TRUST_UNVERIFIED: |
|
David@0
|
137 |
state = AILocalizedString(@"Unverified",nil); |
|
David@0
|
138 |
break; |
|
David@0
|
139 |
case TRUST_PRIVATE: |
|
David@0
|
140 |
state = AILocalizedString(@"Private",nil); |
|
David@0
|
141 |
break; |
|
David@0
|
142 |
case TRUST_FINISHED: |
|
David@0
|
143 |
state = AILocalizedString(@"Finished",nil); |
|
David@0
|
144 |
break; |
|
David@0
|
145 |
default: |
|
David@0
|
146 |
state = @""; |
|
David@0
|
147 |
break; |
|
David@0
|
148 |
} |
|
David@0
|
149 |
} |
|
David@0
|
150 |
|
|
David@0
|
151 |
otrl_privkey_hash_to_human(hash, fingerprint->fingerprint); |
|
David@0
|
152 |
fingerprintString = [NSString stringWithUTF8String:hash]; |
|
David@0
|
153 |
|
|
David@95
|
154 |
AIAccount *account = [adium.accountController accountWithInternalObjectID:[NSString stringWithUTF8String:context->accountname]]; |
|
David@0
|
155 |
|
|
David@0
|
156 |
fingerprintDict = [NSDictionary dictionaryWithObjectsAndKeys: |
|
David@0
|
157 |
UID, @"UID", |
|
David@0
|
158 |
state, @"Status", |
|
David@0
|
159 |
fingerprintString, @"FingerprintString", |
|
David@0
|
160 |
[NSValue valueWithPointer:fingerprint], @"FingerprintValue", |
|
David@0
|
161 |
account, @"AIAccount", |
|
David@0
|
162 |
nil]; |
|
David@0
|
163 |
|
|
David@0
|
164 |
[fingerprintDictArray addObject:fingerprintDict]; |
|
David@0
|
165 |
|
|
David@0
|
166 |
fingerprint = fingerprint->next; |
|
David@0
|
167 |
} |
|
David@0
|
168 |
} |
|
David@0
|
169 |
|
|
David@0
|
170 |
[tableView_fingerprints reloadData]; |
|
David@0
|
171 |
} |
|
David@0
|
172 |
} |
|
David@0
|
173 |
|
|
David@0
|
174 |
/*! |
|
David@0
|
175 |
* @brief Update the key list |
|
David@0
|
176 |
* |
|
David@0
|
177 |
* Called by the OTR adapter when -otr informs us the private key list changed |
|
David@0
|
178 |
*/ |
|
David@0
|
179 |
- (void)updatePrivateKeyList |
|
David@0
|
180 |
{ |
|
David@0
|
181 |
if (viewIsOpen) { |
|
David@0
|
182 |
NSString *fingerprintString = nil; |
|
David@0
|
183 |
AIAccount *account = ([popUp_accounts numberOfItems] ? [[popUp_accounts selectedItem] representedObject] : nil); |
|
David@0
|
184 |
|
|
David@0
|
185 |
if (account) { |
|
David@838
|
186 |
const char *accountname = [account.internalObjectID UTF8String]; |
|
David@838
|
187 |
const char *protocol = [account.service.serviceCodeUniqueID UTF8String]; |
|
David@0
|
188 |
char *fingerprint; |
|
David@0
|
189 |
OtrlUserState otrg_plugin_userstate; |
|
David@0
|
190 |
|
|
David@0
|
191 |
if ((otrg_plugin_userstate = otrg_get_userstate())){ |
|
David@0
|
192 |
char fingerprint_buf[45]; |
|
David@0
|
193 |
fingerprint = otrl_privkey_fingerprint(otrg_plugin_userstate, |
|
David@0
|
194 |
fingerprint_buf, accountname, protocol); |
|
David@0
|
195 |
|
|
David@0
|
196 |
if (fingerprint) { |
|
tyler@3159
|
197 |
[button_generate setTitle:AILocalizedString(@"Regenerate", nil)]; |
|
David@0
|
198 |
fingerprintString = [NSString stringWithFormat:AILocalizedString(@"Fingerprint: %.80s",nil), fingerprint]; |
|
David@0
|
199 |
} else { |
|
tyler@3159
|
200 |
[button_generate setTitle:AILocalizedString(@"Generate", nil)]; |
|
David@0
|
201 |
fingerprintString = AILocalizedString(@"No private key present", "Message to show in the Encryption OTR preferences when an account is selected which does not have a private key"); |
|
David@0
|
202 |
} |
|
David@0
|
203 |
} |
|
David@0
|
204 |
} |
|
David@0
|
205 |
|
|
David@0
|
206 |
[textField_privateKey setStringValue:(fingerprintString ? |
|
David@0
|
207 |
fingerprintString : |
|
David@0
|
208 |
@"")]; |
|
David@0
|
209 |
} |
|
David@0
|
210 |
} |
|
David@0
|
211 |
|
|
David@0
|
212 |
/*! |
|
David@0
|
213 |
* @brief Generate a new private key for the currently selected account |
|
David@0
|
214 |
*/ |
|
David@0
|
215 |
- (IBAction)generate:(id)sender |
|
David@0
|
216 |
{ |
|
David@0
|
217 |
AIAccount *account = ([popUp_accounts numberOfItems] ? [[popUp_accounts selectedItem] representedObject] : nil); |
|
David@0
|
218 |
|
|
David@838
|
219 |
otrg_plugin_create_privkey([account.internalObjectID UTF8String], |
|
David@838
|
220 |
[account.service.serviceCodeUniqueID UTF8String]); |
|
David@0
|
221 |
} |
|
David@0
|
222 |
|
|
David@0
|
223 |
/*! |
|
David@0
|
224 |
* @brief Show the fingerprint for the contact selected in the fingerprints NSTableView |
|
David@0
|
225 |
*/ |
|
David@0
|
226 |
- (IBAction)showFingerprint:(id)sender |
|
David@0
|
227 |
{ |
|
David@3
|
228 |
NSInteger selectedRow = [tableView_fingerprints selectedRow]; |
|
David@0
|
229 |
if (selectedRow != -1) { |
|
David@0
|
230 |
NSDictionary *fingerprintDict = [fingerprintDictArray objectAtIndex:selectedRow]; |
|
David@0
|
231 |
[ESOTRFingerprintDetailsWindowController showDetailsForFingerprintDict:fingerprintDict]; |
|
David@0
|
232 |
} |
|
David@0
|
233 |
} |
|
David@0
|
234 |
|
|
David@0
|
235 |
//Fingerprint tableview ------------------------------------------------------------------------------------------------ |
|
David@0
|
236 |
#pragma mark Fingerprint tableview |
|
David@3
|
237 |
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView |
|
David@0
|
238 |
{ |
|
David@0
|
239 |
return [fingerprintDictArray count]; |
|
David@0
|
240 |
} |
|
David@0
|
241 |
|
|
David@3
|
242 |
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex |
|
David@0
|
243 |
{ |
|
David@0
|
244 |
if ((rowIndex >= 0) && (rowIndex < [fingerprintDictArray count])) { |
|
David@0
|
245 |
NSString *identifier = [aTableColumn identifier]; |
|
David@0
|
246 |
NSDictionary *fingerprintDict = [fingerprintDictArray objectAtIndex:rowIndex]; |
|
David@0
|
247 |
|
|
David@0
|
248 |
if ([identifier isEqualToString:@"UID"]) { |
|
David@0
|
249 |
return [fingerprintDict objectForKey:@"UID"]; |
|
David@0
|
250 |
|
|
David@0
|
251 |
} else if ([identifier isEqualToString:@"Status"]) { |
|
David@0
|
252 |
return [fingerprintDict objectForKey:@"Status"]; |
|
David@0
|
253 |
|
|
David@0
|
254 |
} |
|
David@0
|
255 |
} |
|
David@0
|
256 |
|
|
David@0
|
257 |
return @""; |
|
David@0
|
258 |
} |
|
David@0
|
259 |
|
|
David@3
|
260 |
- (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex |
|
David@0
|
261 |
{ |
|
David@0
|
262 |
|
|
David@0
|
263 |
} |
|
David@0
|
264 |
|
|
David@0
|
265 |
- (void)tableViewSelectionDidChange:(NSNotification *)aNotification |
|
David@0
|
266 |
{ |
|
David@3
|
267 |
NSInteger selectedRow = [tableView_fingerprints selectedRow]; |
|
David@0
|
268 |
[button_showFingerprint setEnabled:(selectedRow != -1)]; |
|
David@0
|
269 |
} |
|
David@0
|
270 |
|
|
David@0
|
271 |
|
|
David@0
|
272 |
//Account menu --------------------------------------------------------------------------------------------------------- |
|
David@0
|
273 |
#pragma mark Account menu |
|
David@0
|
274 |
/*! |
|
David@0
|
275 |
* @brief Account menu delegate |
|
David@0
|
276 |
*/ |
|
David@0
|
277 |
- (void)accountMenu:(AIAccountMenu *)inAccountMenu didRebuildMenuItems:(NSArray *)menuItems { |
|
David@0
|
278 |
[popUp_accounts setMenu:[inAccountMenu menu]]; |
|
David@0
|
279 |
|
|
David@0
|
280 |
BOOL hasItems = ([[popUp_accounts menu] numberOfItems] > 0); |
|
David@0
|
281 |
[popUp_accounts setEnabled:hasItems]; |
|
David@0
|
282 |
[button_generate setEnabled:hasItems]; |
|
David@0
|
283 |
} |
|
David@0
|
284 |
|
|
David@0
|
285 |
- (void)accountMenu:(AIAccountMenu *)inAccountMenu didSelectAccount:(AIAccount *)inAccount { |
|
David@0
|
286 |
[self updatePrivateKeyList]; |
|
David@0
|
287 |
} |
|
David@0
|
288 |
|
|
David@0
|
289 |
- (NSControlSize)controlSizeForAccountMenu:(AIAccountMenu *)inAccountMenu |
|
David@0
|
290 |
{ |
|
David@0
|
291 |
return NSSmallControlSize; |
|
David@0
|
292 |
} |
|
David@0
|
293 |
|
|
David@0
|
294 |
@end |