Adium: BEAST mitigations for 10.8.5
[siplcs.git] / src / adium / ESPurpleSIPEAccount.m
blobb1628faa1212d4d8661d16b422f24e1432711499
1 //
2 //  ESSIPEAccount.m
3 //  SIPEAdiumPlugin
4 //
5 //  Created by Matt Meissner on 10/30/09.
6 //  Modified by Michael Lamb on 2/27/13
7 //  Copyright 2013 Michael Lamb/Harris Kauffman. All rights reserved.
8 //
10 #import <AISharedAdium.h>
11 #import <AIAdium.h>
12 #import <Adium/AIStatus.h>
13 #import <Adium/AIStatusControllerProtocol.h>
14 #import <ESDebugAILog.h>
16 #import "ESPurpleSIPEAccount.h"
17 #import "ESSIPEService.h"
19 #include "sipe-core.h"
20 #include "sipe-backend.h"
21 #include "purple-private.h"
23 @class AICoreComponentLoader;
25 @implementation ESPurpleSIPEAccount
27 - (void)initAccount
29     [super initAccount];
30     
31     sipe_to_adium_status =
32     [[NSDictionary alloc] initWithObjectsAndKeys:
33      STATUS_NAME_AVAILABLE,         @"available",                 //SIPE_ACTIVITY_AVAILABLE
34      STATUS_NAME_AVAILABLE,         @"online",                    //SIPE_ACTIVITY_ONLINE
35      STATUS_NAME_AWAY,              @"idle",                      //SIPE_ACTIVITY_INACTIVE
36      STATUS_NAME_BUSY,              @"busy",                      //SIPE_ACTIVITY_BUSY
37      STATUS_NAME_BUSY,              @"busyidle",                  //SIPE_ACTIVITY_BUSYIDLE
38      STATUS_NAME_DND,               @"do-not-disturb",            //SIPE_ACTIVITY_DND
39      STATUS_NAME_BRB,               @"be-right-back",             //SIPE_ACTIVITY_BRB
40      STATUS_NAME_AWAY,              @"away",                      //SIPE_ACTIVITY_AWAY
41      STATUS_NAME_LUNCH,             @"out-to-lunch",              //SIPE_ACTIVITY_LUNCH
42      STATUS_NAME_INVISIBLE,         @"invisible",                 //SIPE_ACTIVITY_INVISIBLE
43      STATUS_NAME_OFFLINE,           @"offline",                   //SIPE_ACTIVITY_OFFLINE
44      STATUS_NAME_PHONE,             @"on-the-phone",              //SIPE_ACTIVITY_ON_PHONE
45      STATUS_NAME_NOT_AT_DESK,       @"in-a-conference",           //SIPE_ACTIVITY_IN_CONF
46      STATUS_NAME_NOT_AT_DESK,       @"in-a-meeting",              //SIPE_ACTIVITY_IN_MEETING
47      STATUS_NAME_NOT_IN_OFFICE,     @"out-of-office",             //SIPE_ACTIVITY_OOF
48      STATUS_NAME_AWAY_FRIENDS_ONLY, @"urgent-interruptions-only", //SIPE_ACTIVITY_URGENT_ONLY
49      nil
50      ];
51     
52     adium_to_sipe_status =
53     [[NSDictionary alloc] initWithObjectsAndKeys:
54      @"available",                 STATUS_NAME_AVAILABLE,         //SIPE_ACTIVITY_AVAILABLE
55      @"busy",                      STATUS_NAME_BUSY,              //SIPE_ACTIVITY_BUSY
56      @"do-not-disturb",            STATUS_NAME_DND,               //SIPE_ACTIVITY_DND
57      @"be-right-back",             STATUS_NAME_BRB,               //SIPE_ACTIVITY_BRB
58      @"away",                      STATUS_NAME_AWAY,              //SIPE_ACTIVITY_AWAY
59      @"out-to-lunch",              STATUS_NAME_LUNCH,             //SIPE_ACTIVITY_LUNCH
60      @"invisible",                 STATUS_NAME_INVISIBLE,         //SIPE_ACTIVITY_INVISIBLE
61      @"offline",                   STATUS_NAME_OFFLINE,           //SIPE_ACTIVITY_OFFLINE
62      @"on-the-phone",              STATUS_NAME_PHONE,             //SIPE_ACTIVITY_ON_PHONE
63      @"in-a-meeting",              STATUS_NAME_NOT_AT_DESK,       //SIPE_ACTIVITY_IN_MEETING
64      @"out-of-office",             STATUS_NAME_NOT_IN_OFFICE,     //SIPE_ACTIVITY_OOF
65      @"urgent-interruptions-only", STATUS_NAME_AWAY_FRIENDS_ONLY, //SIPE_ACTIVITY_URGENT_ONLY
66      nil
67      ];
70 - (void)dealloc
72     [adium_to_sipe_status release];
73     [sipe_to_adium_status release];
74     [super dealloc];
77 - (const char*)protocolPlugin
79         return "prpl-sipe";
82 - (const char *)purpleAccountName
84     NSString *completeUserName = [NSString stringWithUTF8String:[super purpleAccountName]];
85     NSString *windowsLogin =[self preferenceForKey:KEY_SIPE_WINDOWS_LOGIN group:GROUP_ACCOUNT_STATUS];
86     
87     if ( ![windowsLogin isEqualToString:@""] ) {
88         completeUserName = [NSString stringWithFormat:@"%@,%@", completeUserName, windowsLogin];
89     }
90     
91         return [completeUserName UTF8String];
94 #pragma mark Account Configuration
95 - (void)configurePurpleAccount
97     // Account preferences
98     AILog(@"(ESPurpleSIPEAccount) Configuring account: %s\n", self.purpleAccountName);
100     NSArray *myArray = [NSArray arrayWithObjects:@"auto", @"tls", @"tcp", nil];
101     
102     NSDictionary *keys_to_account =
103     [NSDictionary dictionaryWithObjectsAndKeys:
104      @"server",                        KEY_SIPE_CONNECT_HOST,
105      @"password",                      KEY_SIPE_PASSWORD,
106      @"transport",                     KEY_SIPE_CONNECTION_TYPE,
107      @"email",                         KEY_SIPE_EMAIL,
108      @"email_login",                   KEY_SIPE_EMAIL_LOGIN,
109      @"email_url",                     KEY_SIPE_EMAIL_URL,
110      @"email_password",                KEY_SIPE_EMAIL_PASSWORD,
111      @"groupchat_user",                KEY_SIPE_GROUP_CHAT_PROXY,
112      @"useragent",                     KEY_SIPE_USER_AGENT,
113      @"sso",                           KEY_SIPE_SINGLE_SIGN_ON,
114      @"dont-publish",                  KEY_SIPE_DONT_PUBLISH,
115      @"authentication",                KEY_SIPE_AUTH_SCHEME,
116      @"ssl_cdsa_beast_tls_workaround", KEY_SIPE_BEAST_DISABLE,
117      nil
118      ];
119     
120     for (NSString* key in keys_to_account) {
121         NSString *prpl_key = [keys_to_account objectForKey:key];
122         id value = [self preferenceForKey:key group:GROUP_ACCOUNT_STATUS];
123         
124         if ([value isKindOfClass:[NSString class]]) {
125             if ([key isEqualToString:KEY_SIPE_CONNECT_HOST]) {
126                 if ([value isEqualToString:@""]) {
127                     // An empty sipe_connect_host means we're autodetecting the server
128                     // So we set this to our own hostname, so that the reachability test has a *network* address (i.e. non-loopback) to check connectivity against.
129                     [self setPreference:[[NSHost currentHost] localizedName] forKey:KEY_CONNECT_HOST group:GROUP_ACCOUNT_STATUS];
130                 } else {
131                     // If the user entered server:port only give the server portion to adium
132                     // otherwise the DNS lookup will fail the reachability test
133                     NSArray *server = [value componentsSeparatedByString:@":"];
134                     [self setPreference:[server objectAtIndex:0] forKey:KEY_CONNECT_HOST group:GROUP_ACCOUNT_STATUS];
135                 }
136             }
137             
138             purple_account_set_string(account, [prpl_key UTF8String], [value UTF8String]);
139         } else if ([value isKindOfClass:[NSNumber class]]) {
140             if ([key isEqualToString:KEY_SIPE_CONNECTION_TYPE]) {
141                 NSString *tmp = [myArray objectAtIndex:(NSUInteger)value];
142                 purple_account_set_string(account, [prpl_key UTF8String], [tmp UTF8String]);
143             } else {
144                 purple_account_set_bool(account, [prpl_key UTF8String], [value boolValue]);
145             }
146         } else {
147             AILog(@"(ESPurpleSIPEAccount) Unknown class %@ for key %@", [value class], key);
148         }
149     }
150     
151     // Adium doesn't honor our "optional" password on account creation and will prompt if the password field is left blank, so we must force it to think there is one, but only if there isn't already a password saved
152     if ( [[self preferenceForKey:KEY_SIPE_SINGLE_SIGN_ON group:GROUP_ACCOUNT_STATUS] boolValue] &&
153         [[self preferenceForKey:KEY_SIPE_PASSWORD group:GROUP_ACCOUNT_STATUS] isEqualToString:@""] )
154     {
155         [self setPasswordTemporarily:@"placeholder"];
156     }
159 #pragma mark File transfer
161 - (BOOL)canSendFolders
163         return NO;
166 - (void)beginSendOfFileTransfer:(ESFileTransfer *)fileTransfer
168         [super _beginSendOfFileTransfer:fileTransfer];
171 - (void)acceptFileTransferRequest:(ESFileTransfer *)fileTransfer
173     [super acceptFileTransferRequest:fileTransfer];
176 - (void)rejectFileReceiveRequest:(ESFileTransfer *)fileTransfer
178     [super rejectFileReceiveRequest:fileTransfer];
181 - (void)cancelFileTransfer:(ESFileTransfer *)fileTransfer
183         [super cancelFileTransfer:fileTransfer];
186 #pragma mark Status Messages
188  * @brief Status name to use for a Purple buddy
189  */
190 - (NSString *)statusNameForPurpleBuddy:(PurpleBuddy *)buddy
192     NSString *statusName = [super statusNameForPurpleBuddy:buddy];
193     PurplePresence  *presence = purple_buddy_get_presence(buddy);
194     PurpleStatus    *status = purple_presence_get_active_status(presence);
195     NSString        *purpleStatusID = [NSString stringWithUTF8String:purple_status_get_id(status)];
196     
197     if (!purpleStatusID) return nil;
198     
199     if (sipe_to_adium_status[purpleStatusID])
200         statusName = sipe_to_adium_status[purpleStatusID];
201     else {
202         AILog(@"(ESPurpleSIPEAccount) Unknown purpleStatusID in statusNameForPurpleBuddy: %@", purpleStatusID);
203         statusName = STATUS_NAME_OFFLINE;
204     }
205     
206     return statusName;
210  * @brief Maps purple status IDs to Adium statuses
211  */
212  - (const char *)purpleStatusIDForStatus:(AIStatus *)statusState arguments:(NSMutableDictionary *)arguments
214      const gchar    *statusID;
215      NSString           *statusName = statusState.statusName;
216      NSString           *statusMessageString = [statusState statusMessageString];
218      if (!statusMessageString) statusMessageString = @"";
219      
220      if ( adium_to_sipe_status[statusName] )
221          statusID = [adium_to_sipe_status[statusName] UTF8String];
222      else {
223          AILog(@"(ESPurpleSIPEAccount): Unknown statusName in purpleStatusIDForStatus: %@", statusName);
224          statusID = [super purpleStatusIDForStatus:statusState arguments:arguments];
225      }
226      
227      return statusID;
231 @end