Added `-[NSArray validateAsPropertyList]` and `-[NSDictionary validateAsPropertyList...
[adiumx.git] / Source / ESOTRPreferences.m
blob1c436fa65792ad407c81eafa6d8f45ac58062989
1 /* 
2  * Adium is the legal property of its developers, whose names are listed in the copyright file included
3  * with this source distribution.
4  * 
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.
8  * 
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.
12  * 
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.
15  */
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>
25 #import "OTRCommon.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;
35 @end
37 @implementation ESOTRPreferences
39 //Preference pane properties
40 - (NSString *)label
42     return AILocalizedString(@"Encryption",nil);
44 - (NSString *)nibName
46     return @"OTRPrefs";
48 - (NSImage *)image
50         return [NSImage imageNamed:@"Lock_Locked State" forClass:[adium class]];
53 - (void)viewDidLoad
55         viewIsOpen = YES;
57         //Account Menu
58         accountMenu = [[AIAccountMenu accountMenuWithDelegate:self
59                                                                                           submenuType:AIAccountNoSubmenu
60                                                                                    showTitleVerbs:NO] retain];
61         
62         //Fingerprints
63         [tableView_fingerprints setDelegate:self];
64         [tableView_fingerprints setDataSource:self];
65         [tableView_fingerprints setTarget:self];
66         [tableView_fingerprints setDoubleAction:@selector(showFingerprint:)];
67         [self updateFingerprintsList];
68         
69         [self updatePrivateKeyList];
71         [textField_privateKey setSelectable:YES];
73         [self tableViewSelectionDidChange:nil];         
76 - (void)viewWillClose
78         viewIsOpen = NO;
79         [fingerprintDictArray release]; fingerprintDictArray = nil;
80         [accountMenu release]; accountMenu = nil;
81         
82         [[adium notificationCenter] removeObserver:self
83                                                                                   name:Account_ListChanged
84                                                                                 object:nil];
87 /*!
88  * @brief Deallocate
89  */
90 - (void)dealloc
92         [fingerprintDictArray release]; fingerprintDictArray = nil;
93         [[adium notificationCenter] removeObserver:self];
95         [super dealloc];
98 /*!
99  * @brief Update the fingerprint display
101  * Called by the OTR adapter when -otr informs us the fingerprint list changed
102  */
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];
113                 
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) {
121                                 char                    hash[45];
122                                 NSDictionary    *fingerprintDict;
123                                 NSString                *UID;
124                                 NSString                *state, *fingerprintString;
126                                 UID = [NSString stringWithUTF8String:context->username];
127                                 
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");
131                                 } else {
132                                         TrustLevel trustLevel = otrg_plugin_context_to_trust(context);
133                                         
134                                         switch (trustLevel) {
135                                                 case TRUST_NOT_PRIVATE:
136                                                         state = AILocalizedString(@"Not private",nil);
137                                                         break;
138                                                 case TRUST_UNVERIFIED:
139                                                         state = AILocalizedString(@"Unverified",nil);
140                                                         break;
141                                                 case TRUST_PRIVATE:
142                                                         state = AILocalizedString(@"Private",nil);
143                                                         break;
144                                                 case TRUST_FINISHED:
145                                                         state = AILocalizedString(@"Finished",nil);
146                                                         break;
147                                                 default:
148                                                         state = @"";
149                                                         break;
150                                         }
151                                 }
152                                 
153                                 otrl_privkey_hash_to_human(hash, fingerprint->fingerprint);
154                                 fingerprintString = [NSString stringWithUTF8String:hash];
155                                 
156                                 AIAccount *account = [[adium accountController] accountWithInternalObjectID:[NSString stringWithUTF8String:context->accountname]];
158                                 fingerprintDict = [NSDictionary dictionaryWithObjectsAndKeys:
159                                         UID, @"UID",
160                                         state, @"Status",
161                                         fingerprintString, @"FingerprintString",
162                                         [NSValue valueWithPointer:fingerprint], @"FingerprintValue",
163                                         account, @"AIAccount",
164                                         nil];
166                                 [fingerprintDictArray addObject:fingerprintDict];
168                                 fingerprint = fingerprint->next;
169                         }
170                 }
171                 
172                 [tableView_fingerprints reloadData];
173         }
177  * @brief Update the key list
179  * Called by the OTR adapter when -otr informs us the private key list changed
180  */
181 - (void)updatePrivateKeyList
183         if (viewIsOpen) {
184                 NSString                *fingerprintString = nil;
185                 AIAccount               *account = ([popUp_accounts numberOfItems] ? [[popUp_accounts selectedItem] representedObject] : nil);
186                 
187                 if (account) {
188                         const char              *accountname = [[account internalObjectID] UTF8String];
189                         const char              *protocol = [[[account service] serviceCodeUniqueID] UTF8String];
190                         char                    *fingerprint;
191                         OtrlUserState   otrg_plugin_userstate;
192                         
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);
197                                 
198                                 if (fingerprint) {
199                                         fingerprintString = [NSString stringWithFormat:AILocalizedString(@"Fingerprint: %.80s",nil), fingerprint];
200                                 } else {
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");
202                                 }
203                         }
204                 }
206                 [textField_privateKey setStringValue:(fingerprintString ?
207                                                                                           fingerprintString :
208                                                                                           @"")];
209         }       
213  * @brief Generate a new private key for the currently selected account
214  */
215 - (IBAction)generate:(id)sender
217         AIAccount       *account = ([popUp_accounts numberOfItems] ? [[popUp_accounts selectedItem] representedObject] : nil);
218         
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
225  */
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];
232         }
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];
247                 
248                 if ([identifier isEqualToString:@"UID"]) {
249                         return [fingerprintDict objectForKey:@"UID"];
250                         
251                 } else if ([identifier isEqualToString:@"Status"]) {
252                         return [fingerprintDict objectForKey:@"Status"];
253                         
254                 }
255         }
257         return @"";
260 - (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
262         
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
276  */ 
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;
294 @end