2 * Adium is the legal property of its developers, whose names are listed in the copyright file included
3 * with this source distribution.
5 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
6 * General Public License as published by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
10 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
11 * Public License for more details.
13 * You should have received a copy of the GNU General Public License along with this program; if not,
14 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 #import "ESOTRPreferences.h"
18 #import <Adium/AIAccountControllerProtocol.h>
19 #import <AIUtilities/AIImageAdditions.h>
20 #import <AIUtilities/AIPopUpButtonAdditions.h>
21 #import "AIAccountMenu.h"
22 #import <Adium/AIAccount.h>
23 #import <Adium/AIService.h>
27 #import "AdiumOTREncryption.h"
29 /* Adium OTR headers */
30 #import "ESOTRFingerprintDetailsWindowController.h"
32 @interface ESOTRPreferences (PRIVATE)
33 - (void)tableViewSelectionDidChange:(NSNotification *)aNotification;
34 - (void)configureAccountsMenu;
37 @implementation ESOTRPreferences
39 //Preference pane properties
42 return AILocalizedString(@"Encryption",nil);
50 return [NSImage imageNamed:@"Lock_Locked State" forClass:[adium class]];
58 accountMenu = [[AIAccountMenu accountMenuWithDelegate:self
59 submenuType:AIAccountNoSubmenu
60 showTitleVerbs:NO] retain];
63 [tableView_fingerprints setDelegate:self];
64 [tableView_fingerprints setDataSource:self];
65 [tableView_fingerprints setTarget:self];
66 [tableView_fingerprints setDoubleAction:@selector(showFingerprint:)];
67 [self updateFingerprintsList];
69 [self updatePrivateKeyList];
71 [textField_privateKey setSelectable:YES];
73 [self tableViewSelectionDidChange:nil];
79 [fingerprintDictArray release]; fingerprintDictArray = nil;
80 [accountMenu release]; accountMenu = nil;
82 [[adium notificationCenter] removeObserver:self
83 name:Account_ListChanged
92 [fingerprintDictArray release]; fingerprintDictArray = nil;
93 [[adium notificationCenter] removeObserver:self];
99 * @brief Update the fingerprint display
101 * Called by the OTR adapter when -otr informs us the fingerprint list changed
103 - (void)updateFingerprintsList
105 OtrlUserState otrg_plugin_userstate = otrg_get_userstate();
107 if (viewIsOpen && otrg_plugin_userstate) {
108 ConnContext *context;
109 Fingerprint *fingerprint;
111 [fingerprintDictArray release];
112 fingerprintDictArray = [[NSMutableArray alloc] init];
114 for (context = otrg_plugin_userstate->context_root; context != NULL;
115 context = context->next) {
117 fingerprint = context->fingerprint_root.next;
118 /* If there's no fingerprint, don't add it to the known
119 * fingerprints list */
120 while (fingerprint) {
122 NSDictionary *fingerprintDict;
124 NSString *state, *fingerprintString;
126 UID = [NSString stringWithUTF8String:context->username];
128 if (context->msgstate == OTRL_MSGSTATE_ENCRYPTED &&
129 context->active_fingerprint != fingerprint) {
130 state = AILocalizedString(@"Unused","Word to describe an encryption fingerprint which is not currently being used");
132 TrustLevel trustLevel = otrg_plugin_context_to_trust(context);
134 switch (trustLevel) {
135 case TRUST_NOT_PRIVATE:
136 state = AILocalizedString(@"Not private",nil);
138 case TRUST_UNVERIFIED:
139 state = AILocalizedString(@"Unverified",nil);
142 state = AILocalizedString(@"Private",nil);
145 state = AILocalizedString(@"Finished",nil);
153 otrl_privkey_hash_to_human(hash, fingerprint->fingerprint);
154 fingerprintString = [NSString stringWithUTF8String:hash];
156 AIAccount *account = [[adium accountController] accountWithInternalObjectID:[NSString stringWithUTF8String:context->accountname]];
158 fingerprintDict = [NSDictionary dictionaryWithObjectsAndKeys:
161 fingerprintString, @"FingerprintString",
162 [NSValue valueWithPointer:fingerprint], @"FingerprintValue",
163 account, @"AIAccount",
166 [fingerprintDictArray addObject:fingerprintDict];
168 fingerprint = fingerprint->next;
172 [tableView_fingerprints reloadData];
177 * @brief Update the key list
179 * Called by the OTR adapter when -otr informs us the private key list changed
181 - (void)updatePrivateKeyList
184 NSString *fingerprintString = nil;
185 AIAccount *account = ([popUp_accounts numberOfItems] ? [[popUp_accounts selectedItem] representedObject] : nil);
188 const char *accountname = [[account internalObjectID] UTF8String];
189 const char *protocol = [[[account service] serviceCodeUniqueID] UTF8String];
191 OtrlUserState otrg_plugin_userstate;
193 if ((otrg_plugin_userstate = otrg_get_userstate())){
194 char fingerprint_buf[45];
195 fingerprint = otrl_privkey_fingerprint(otrg_plugin_userstate,
196 fingerprint_buf, accountname, protocol);
199 fingerprintString = [NSString stringWithFormat:AILocalizedString(@"Fingerprint: %.80s",nil), fingerprint];
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");
206 [textField_privateKey setStringValue:(fingerprintString ?
213 * @brief Generate a new private key for the currently selected account
215 - (IBAction)generate:(id)sender
217 AIAccount *account = ([popUp_accounts numberOfItems] ? [[popUp_accounts selectedItem] representedObject] : nil);
219 otrg_plugin_create_privkey([[account internalObjectID] UTF8String],
220 [[[account service] serviceCodeUniqueID] UTF8String]);
224 * @brief Show the fingerprint for the contact selected in the fingerprints NSTableView
226 - (IBAction)showFingerprint:(id)sender
228 int selectedRow = [tableView_fingerprints selectedRow];
229 if (selectedRow != -1) {
230 NSDictionary *fingerprintDict = [fingerprintDictArray objectAtIndex:selectedRow];
231 [ESOTRFingerprintDetailsWindowController showDetailsForFingerprintDict:fingerprintDict];
235 //Fingerprint tableview ------------------------------------------------------------------------------------------------
236 #pragma mark Fingerprint tableview
237 - (int)numberOfRowsInTableView:(NSTableView *)aTableView
239 return [fingerprintDictArray count];
242 - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
244 if ((rowIndex >= 0) && (rowIndex < [fingerprintDictArray count])) {
245 NSString *identifier = [aTableColumn identifier];
246 NSDictionary *fingerprintDict = [fingerprintDictArray objectAtIndex:rowIndex];
248 if ([identifier isEqualToString:@"UID"]) {
249 return [fingerprintDict objectForKey:@"UID"];
251 } else if ([identifier isEqualToString:@"Status"]) {
252 return [fingerprintDict objectForKey:@"Status"];
260 - (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
265 - (void)tableViewSelectionDidChange:(NSNotification *)aNotification
267 int selectedRow = [tableView_fingerprints selectedRow];
268 [button_showFingerprint setEnabled:(selectedRow != -1)];
272 //Account menu ---------------------------------------------------------------------------------------------------------
273 #pragma mark Account menu
275 * @brief Account menu delegate
277 - (void)accountMenu:(AIAccountMenu *)inAccountMenu didRebuildMenuItems:(NSArray *)menuItems {
278 [popUp_accounts setMenu:[inAccountMenu menu]];
280 BOOL hasItems = ([[popUp_accounts menu] numberOfItems] > 0);
281 [popUp_accounts setEnabled:hasItems];
282 [button_generate setEnabled:hasItems];
285 - (void)accountMenu:(AIAccountMenu *)inAccountMenu didSelectAccount:(AIAccount *)inAccount {
286 [self updatePrivateKeyList];
289 - (NSControlSize)controlSizeForAccountMenu:(AIAccountMenu *)inAccountMenu
291 return NSSmallControlSize;