~ubuntu-branches/ubuntu/maverick/krb5/maverick

« back to all changes in this revision

Viewing changes to src/kim/agent/mac/KerberosAgentListener.m

  • Committer: Bazaar Package Importer
  • Author(s): Sam Hartman
  • Date: 2009-05-07 16:16:34 UTC
  • mfrom: (13.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20090507161634-xqyk0s9na0le4flj
Tags: 1.7dfsg~beta1-4
When  decrypting the TGS response fails with the subkey, try with the
session key to work around Heimdal bug, Closes: #527353 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2008 Massachusetts Institute of Technology.
 
3
 * All Rights Reserved.
 
4
 *
 
5
 * Export of this software from the United States of America may
 
6
 * require a specific license from the United States Government.
 
7
 * It is the responsibility of any person or organization contemplating
 
8
 * export to obtain such a license before exporting.
 
9
 * 
 
10
 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
 
11
 * distribute this software and its documentation for any purpose and
 
12
 * without fee is hereby granted, provided that the above copyright
 
13
 * notice appear in all copies and that both that copyright notice and
 
14
 * this permission notice appear in supporting documentation, and that
 
15
 * the name of M.I.T. not be used in advertising or publicity pertaining
 
16
 * to distribution of the software without specific, written prior
 
17
 * permission.  Furthermore if you modify this software you must label
 
18
 * your software as modified software and not distribute it in such a
 
19
 * fashion that it might be confused with the original M.I.T. software.
 
20
 * M.I.T. makes no representations about the suitability of
 
21
 * this software for any purpose.  It is provided "as is" without express
 
22
 * or implied warranty.
 
23
 */
 
24
 
 
25
 
 
26
#import "KerberosAgentListener.h"
 
27
#import "KIMUtilities.h"
 
28
#import "ServerDemux.h"
 
29
#import "IPCClient.h"
 
30
 
 
31
@implementation KerberosAgentListener
 
32
 
 
33
@synthesize thread;
 
34
 
 
35
- (id) init
 
36
{
 
37
    self = [super init];
 
38
    if (self != nil) {
 
39
        self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadMain) object:nil];
 
40
    }
 
41
    return self;
 
42
}
 
43
 
 
44
static KerberosAgentListener *sharedListener = nil;
 
45
 
 
46
+ (KerberosAgentListener *) sharedListener
 
47
{
 
48
    @synchronized(self) {
 
49
        if (sharedListener == nil) {
 
50
            [[self alloc] init]; // assignment not done here
 
51
        }
 
52
    }
 
53
    return sharedListener;
 
54
}
 
55
 
 
56
+ (id)allocWithZone:(NSZone *)zone
 
57
{
 
58
    @synchronized(self) {
 
59
        if (sharedListener == nil) {
 
60
            sharedListener = [super allocWithZone:zone];
 
61
            return sharedListener;  // assignment and return on first allocation
 
62
        }
 
63
    }
 
64
    return nil; //on subsequent allocation attempts return nil
 
65
}
 
66
 
 
67
- (id)copyWithZone:(NSZone *)zone
 
68
{
 
69
    return self;
 
70
}
 
71
 
 
72
- (id)retain
 
73
{
 
74
    return self;
 
75
}
 
76
 
 
77
- (unsigned)retainCount
 
78
{
 
79
    return UINT_MAX;  //denotes an object that cannot be released
 
80
}
 
81
 
 
82
- (void)release
 
83
{
 
84
    //do nothing
 
85
}
 
86
 
 
87
- (id)autorelease
 
88
{
 
89
    return self;
 
90
}
 
91
 
 
92
#pragma mark Thread management
 
93
 
 
94
// called from main thread to start listen thread
 
95
+ (void) startListening
 
96
{
 
97
//    NSLog(@"%s %@ thread", __FUNCTION__, ([NSThread isMainThread]) ? @"main" : @"not main");
 
98
 
 
99
    [[KerberosAgentListener sharedListener].thread start];
 
100
}
 
101
 
 
102
- (void) threadMain
 
103
{
 
104
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
105
    int32_t err = 0;
 
106
    
 
107
//    NSLog(@"%s starting up", __FUNCTION__);
 
108
    
 
109
    while (!err && ![self.thread isCancelled]) {
 
110
        err = kim_agent_listen_loop();
 
111
        if (!err) {
 
112
//            NSLog (@"%s loop resetting %@", __FUNCTION__, [[NSThread currentThread] description]);
 
113
        } else {
 
114
            NSLog (@"%s got error %d (%@) %@", __FUNCTION__, err, [KIMUtilities stringForLastKIMError:err], [[NSThread currentThread] description]);
 
115
            err = 0; /* The server quit unexpectedly -- just try again */
 
116
        }
 
117
        sleep(10);
 
118
    }
 
119
    
 
120
    [pool release];
 
121
}
 
122
 
 
123
#pragma mark IPC handlers
 
124
 
 
125
+ (void) addClientWithPort: (mach_port_t) client_port
 
126
                 replyPort: (mach_port_t) reply_port
 
127
                      name: (kim_string) name
 
128
                      path: (kim_string) path
 
129
{
 
130
    NSDictionary *info = [[NSDictionary alloc] initWithObjectsAndKeys:
 
131
                          [NSNumber numberWithInteger:client_port], @"client_port",
 
132
                          [NSNumber numberWithInteger:reply_port], @"reply_port",
 
133
                          [NSString stringWithUTF8String:name], @"name",
 
134
                          [NSString stringWithUTF8String:path], @"path",
 
135
                          nil];
 
136
    [[NSApp delegate] performSelectorOnMainThread:@selector(addClient:) 
 
137
                                       withObject:info
 
138
                                    waitUntilDone:NO];
 
139
}
 
140
 
 
141
+ (void) didAddClient: (NSDictionary *) info 
 
142
                error: (kim_error) error
 
143
{
 
144
    kim_error err = KIM_NO_ERROR;
 
145
    mach_port_t reply_port = [[info objectForKey:@"reply_port"] integerValue];
 
146
    err = kim_handle_reply_init(reply_port, error);
 
147
}
 
148
 
 
149
+ (void) enterIdentityWithClientPort: (mach_port_t) client_port
 
150
                           replyPort: (mach_port_t) reply_port
 
151
                             options: (kim_options) options
 
152
{
 
153
    NSDictionary *info = [[NSDictionary alloc] initWithObjectsAndKeys:
 
154
                          [NSNumber numberWithInteger:client_port], @"client_port",
 
155
                          [NSNumber numberWithInteger:reply_port], @"reply_port",
 
156
                          [KIMUtilities dictionaryForKimOptions:options], @"options",
 
157
                          nil];
 
158
    [[NSApp delegate] performSelectorOnMainThread:@selector(enterIdentity:) 
 
159
                                       withObject:info
 
160
                                    waitUntilDone:NO];
 
161
}
 
162
 
 
163
// contains reply_port, identity_string
 
164
+ (void) didEnterIdentity: (NSDictionary *) info 
 
165
                    error: (kim_error) error
 
166
{
 
167
    kim_error err = KIM_NO_ERROR;
 
168
    mach_port_t reply_port = [[info objectForKey:@"reply_port"] integerValue];
 
169
    NSString *identityString = [info objectForKey:@"identity_string"];
 
170
    kim_identity identity = NULL;
 
171
    kim_options options = NULL;
 
172
    BOOL wants_change_password = [[info objectForKey:@"wants_change_password"] boolValue];
 
173
    
 
174
    if (identityString) {
 
175
        err = kim_identity_create_from_string (&identity, [identityString UTF8String]);
 
176
    }
 
177
    
 
178
    if (!err) {
 
179
        options = [KIMUtilities kimOptionsForDictionary:[info objectForKey:@"options"]];
 
180
        
 
181
    }
 
182
 
 
183
    if (!err) {
 
184
        err = kim_handle_reply_enter_identity(reply_port, identity, options, wants_change_password, error);
 
185
    }
 
186
    
 
187
    kim_options_free (&options);
 
188
}
 
189
 
 
190
+ (void) selectIdentityWithClientPort: (mach_port_t) client_port
 
191
                            replyPort: (mach_port_t) reply_port
 
192
                                hints: (kim_selection_hints) hints
 
193
{
 
194
    NSDictionary *info = nil;
 
195
    
 
196
    info = [[NSDictionary alloc] initWithObjectsAndKeys:
 
197
            [NSNumber numberWithInteger:client_port], @"client_port",
 
198
            [NSNumber numberWithInteger:reply_port], @"reply_port",
 
199
            [KIMUtilities dictionaryForKimSelectionHints:hints], @"hints", 
 
200
            nil];
 
201
    
 
202
    [[NSApp delegate] performSelectorOnMainThread:@selector(selectIdentity:) 
 
203
                                       withObject:info
 
204
                                    waitUntilDone:NO];
 
205
}
 
206
 
 
207
// contains reply_port, identity_string
 
208
+ (void) didSelectIdentity: (NSDictionary *) info 
 
209
                     error: (int32_t) error
 
210
{
 
211
    kim_error err = KIM_NO_ERROR;
 
212
    NSNumber *portNumber = [info objectForKey:@"reply_port"];
 
213
    NSString *identityString = [info objectForKey:@"identity_string"];
 
214
    mach_port_t reply_port = [portNumber integerValue];
 
215
    kim_identity identity = NULL;
 
216
    kim_options options = NULL;
 
217
    BOOL wants_change_password = [[info objectForKey:@"wants_change_password"] boolValue];
 
218
 
 
219
    if (identityString) {
 
220
        err = kim_identity_create_from_string(&identity, [identityString UTF8String]);
 
221
    }
 
222
 
 
223
    if (!err) {
 
224
        options = [KIMUtilities kimOptionsForDictionary:[info objectForKey:@"options"]];
 
225
    }
 
226
 
 
227
    if (!err) {
 
228
        err = kim_handle_reply_select_identity(reply_port, identity, options, wants_change_password, error);
 
229
    }
 
230
    
 
231
    kim_options_free (&options);
 
232
}
 
233
 
 
234
+ (void) promptForAuthWithClientPort: (mach_port_t) client_port
 
235
                           replyPort: (mach_port_t) reply_port
 
236
                            identity: (kim_string) identity_string
 
237
                          promptType: (uint32_t) prompt_type
 
238
                           allowSave: (kim_boolean) allow_save  
 
239
                           hideReply: (kim_boolean) hide_reply
 
240
                               title: (kim_string) title
 
241
                             message: (kim_string) message
 
242
                         description: (kim_string) description
 
243
{
 
244
    NSDictionary *info = [[NSDictionary alloc] initWithObjectsAndKeys:
 
245
                          [NSNumber numberWithInteger:client_port], @"client_port",
 
246
                          [NSNumber numberWithInteger:reply_port], @"reply_port",
 
247
                          [NSString stringWithUTF8String:identity_string], @"identity_string",
 
248
                          [NSNumber numberWithUnsignedInt:prompt_type], @"prompt_type",
 
249
                          [NSNumber numberWithBool:allow_save], @"allow_save",
 
250
                          [NSNumber numberWithBool:hide_reply], @"hide_reply",
 
251
                          [NSString stringWithUTF8String:title], @"title",
 
252
                          [NSString stringWithUTF8String:message], @"message",
 
253
                          [NSString stringWithUTF8String:description], @"description",
 
254
                          nil];
 
255
    [[NSApp delegate] performSelectorOnMainThread:@selector(promptForAuth:) 
 
256
                                       withObject:info
 
257
                                    waitUntilDone:NO];
 
258
}
 
259
 
 
260
// contains reply_port, (string) prompt_response
 
261
+ (void) didPromptForAuth: (NSDictionary *) info 
 
262
                    error: (int32_t) error
 
263
{
 
264
    kim_error err = KIM_NO_ERROR;
 
265
    mach_port_t reply_port = [[info objectForKey:@"reply_port"] integerValue];
 
266
    kim_string prompt_response = [[info objectForKey:@"prompt_response"] UTF8String];
 
267
    kim_boolean save_response = [[info objectForKey:@"save_response"] boolValue];
 
268
 
 
269
    err = kim_handle_reply_auth_prompt(reply_port, prompt_response, save_response, error);
 
270
}
 
271
 
 
272
+ (void) changePasswordWithClientPort: (mach_port_t) client_port
 
273
                            replyPort: (mach_port_t) reply_port
 
274
                             identity: (kim_string) identity_string
 
275
                              expired: (kim_boolean) expired
 
276
{
 
277
    NSDictionary *info = [[NSDictionary alloc] initWithObjectsAndKeys:
 
278
                          [NSNumber numberWithInteger:client_port], @"client_port",
 
279
                          [NSNumber numberWithInteger:reply_port], @"reply_port",
 
280
                          [NSString stringWithUTF8String:identity_string], @"identity_string",
 
281
                          [NSNumber numberWithBool:expired], @"expired",
 
282
                          nil];
 
283
    [[NSApp delegate] performSelectorOnMainThread:@selector(changePassword:) 
 
284
                                       withObject:info
 
285
                                    waitUntilDone:NO];
 
286
}
 
287
 
 
288
// contains reply_port, old password, new password, verify password
 
289
+ (void) didChangePassword: (NSDictionary *) info 
 
290
                     error: (int32_t) error
 
291
{
 
292
    kim_error err = KIM_NO_ERROR;
 
293
    mach_port_t reply_port = [[info objectForKey:@"reply_port"] integerValue];
 
294
    kim_string old_pw = [[info objectForKey:@"old_password"] UTF8String];
 
295
    kim_string new_pw = [[info objectForKey:@"new_password"] UTF8String];
 
296
    kim_string verify_pw = [[info objectForKey:@"verify_password"] UTF8String];
 
297
 
 
298
    err = kim_handle_reply_change_password(reply_port, old_pw, new_pw, verify_pw, error);
 
299
}
 
300
 
 
301
+ (void) handleErrorWithClientPort: (mach_port_t) client_port
 
302
                         replyPort: (mach_port_t) reply_port
 
303
                          identity: (kim_string) identity_string
 
304
                             error: (kim_error) error
 
305
                           message: (kim_string) message
 
306
                       description: (kim_string) description
 
307
{
 
308
    NSDictionary *info = [[NSDictionary alloc] initWithObjectsAndKeys:
 
309
                          [NSNumber numberWithInteger:client_port], @"client_port",
 
310
                          [NSNumber numberWithInteger:reply_port], @"reply_port",
 
311
                          [NSString stringWithUTF8String:identity_string], @"identity_string",
 
312
                          [NSNumber numberWithUnsignedInt:error], @"error",
 
313
                          [NSString stringWithUTF8String:message], @"message",
 
314
                          [NSString stringWithUTF8String:description], @"description",
 
315
                          nil];
 
316
    [[NSApp delegate] performSelectorOnMainThread:@selector(handleError:) 
 
317
                                       withObject:info
 
318
                                    waitUntilDone:NO];
 
319
    
 
320
}
 
321
 
 
322
// contains reply_port
 
323
+ (void) didHandleError: (NSDictionary *) info 
 
324
                  error: (int32_t) error
 
325
{
 
326
    kim_error err = KIM_NO_ERROR;
 
327
    mach_port_t reply_port = [[info objectForKey:@"reply_port"] integerValue];
 
328
 
 
329
    err = kim_handle_reply_handle_error(reply_port, error);
 
330
}
 
331
 
 
332
+ (void) removeClientMatchingPort: (mach_port_t) client_port
 
333
                        replyPort: (mach_port_t) reply_port
 
334
{
 
335
    NSDictionary *info = [[NSDictionary alloc] initWithObjectsAndKeys:
 
336
                          [NSNumber numberWithInteger:client_port], @"client_port",
 
337
                          [NSNumber numberWithInteger:reply_port], @"reply_port",
 
338
                          nil];
 
339
    [[NSApp delegate] performSelectorOnMainThread:@selector(removeClient:) 
 
340
                                       withObject:info
 
341
                                    waitUntilDone:NO];
 
342
}
 
343
 
 
344
// contains reply_port
 
345
+ (void) didRemoveClient: (NSDictionary *)info
 
346
                   error: (int32_t) error
 
347
{
 
348
    kim_error err = KIM_NO_ERROR;
 
349
    mach_port_t reply_port = [[info objectForKey:@"reply_port"] integerValue];
 
350
    if (reply_port) {
 
351
        err = kim_handle_reply_fini(reply_port, error);
 
352
    }
 
353
}
 
354
 
 
355
@end