2
* Copyright 2008 Massachusetts Institute of Technology.
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.
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.
26
#import "KerberosAgentListener.h"
27
#import "KIMUtilities.h"
28
#import "ServerDemux.h"
31
@implementation KerberosAgentListener
39
self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadMain) object:nil];
44
static KerberosAgentListener *sharedListener = nil;
46
+ (KerberosAgentListener *) sharedListener
49
if (sharedListener == nil) {
50
[[self alloc] init]; // assignment not done here
53
return sharedListener;
56
+ (id)allocWithZone:(NSZone *)zone
59
if (sharedListener == nil) {
60
sharedListener = [super allocWithZone:zone];
61
return sharedListener; // assignment and return on first allocation
64
return nil; //on subsequent allocation attempts return nil
67
- (id)copyWithZone:(NSZone *)zone
77
- (unsigned)retainCount
79
return UINT_MAX; //denotes an object that cannot be released
92
#pragma mark Thread management
94
// called from main thread to start listen thread
95
+ (void) startListening
97
// NSLog(@"%s %@ thread", __FUNCTION__, ([NSThread isMainThread]) ? @"main" : @"not main");
99
[[KerberosAgentListener sharedListener].thread start];
104
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
107
// NSLog(@"%s starting up", __FUNCTION__);
109
while (!err && ![self.thread isCancelled]) {
110
err = kim_agent_listen_loop();
112
// NSLog (@"%s loop resetting %@", __FUNCTION__, [[NSThread currentThread] description]);
114
NSLog (@"%s got error %d (%@) %@", __FUNCTION__, err, [KIMUtilities stringForLastKIMError:err], [[NSThread currentThread] description]);
115
err = 0; /* The server quit unexpectedly -- just try again */
123
#pragma mark IPC handlers
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
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",
136
[[NSApp delegate] performSelectorOnMainThread:@selector(addClient:)
141
+ (void) didAddClient: (NSDictionary *) info
142
error: (kim_error) error
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);
149
+ (void) enterIdentityWithClientPort: (mach_port_t) client_port
150
replyPort: (mach_port_t) reply_port
151
options: (kim_options) options
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",
158
[[NSApp delegate] performSelectorOnMainThread:@selector(enterIdentity:)
163
// contains reply_port, identity_string
164
+ (void) didEnterIdentity: (NSDictionary *) info
165
error: (kim_error) error
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];
174
if (identityString) {
175
err = kim_identity_create_from_string (&identity, [identityString UTF8String]);
179
options = [KIMUtilities kimOptionsForDictionary:[info objectForKey:@"options"]];
184
err = kim_handle_reply_enter_identity(reply_port, identity, options, wants_change_password, error);
187
kim_options_free (&options);
190
+ (void) selectIdentityWithClientPort: (mach_port_t) client_port
191
replyPort: (mach_port_t) reply_port
192
hints: (kim_selection_hints) hints
194
NSDictionary *info = nil;
196
info = [[NSDictionary alloc] initWithObjectsAndKeys:
197
[NSNumber numberWithInteger:client_port], @"client_port",
198
[NSNumber numberWithInteger:reply_port], @"reply_port",
199
[KIMUtilities dictionaryForKimSelectionHints:hints], @"hints",
202
[[NSApp delegate] performSelectorOnMainThread:@selector(selectIdentity:)
207
// contains reply_port, identity_string
208
+ (void) didSelectIdentity: (NSDictionary *) info
209
error: (int32_t) error
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];
219
if (identityString) {
220
err = kim_identity_create_from_string(&identity, [identityString UTF8String]);
224
options = [KIMUtilities kimOptionsForDictionary:[info objectForKey:@"options"]];
228
err = kim_handle_reply_select_identity(reply_port, identity, options, wants_change_password, error);
231
kim_options_free (&options);
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
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",
255
[[NSApp delegate] performSelectorOnMainThread:@selector(promptForAuth:)
260
// contains reply_port, (string) prompt_response
261
+ (void) didPromptForAuth: (NSDictionary *) info
262
error: (int32_t) error
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];
269
err = kim_handle_reply_auth_prompt(reply_port, prompt_response, save_response, error);
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
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",
283
[[NSApp delegate] performSelectorOnMainThread:@selector(changePassword:)
288
// contains reply_port, old password, new password, verify password
289
+ (void) didChangePassword: (NSDictionary *) info
290
error: (int32_t) error
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];
298
err = kim_handle_reply_change_password(reply_port, old_pw, new_pw, verify_pw, error);
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
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",
316
[[NSApp delegate] performSelectorOnMainThread:@selector(handleError:)
322
// contains reply_port
323
+ (void) didHandleError: (NSDictionary *) info
324
error: (int32_t) error
326
kim_error err = KIM_NO_ERROR;
327
mach_port_t reply_port = [[info objectForKey:@"reply_port"] integerValue];
329
err = kim_handle_reply_handle_error(reply_port, error);
332
+ (void) removeClientMatchingPort: (mach_port_t) client_port
333
replyPort: (mach_port_t) reply_port
335
NSDictionary *info = [[NSDictionary alloc] initWithObjectsAndKeys:
336
[NSNumber numberWithInteger:client_port], @"client_port",
337
[NSNumber numberWithInteger:reply_port], @"reply_port",
339
[[NSApp delegate] performSelectorOnMainThread:@selector(removeClient:)
344
// contains reply_port
345
+ (void) didRemoveClient: (NSDictionary *)info
346
error: (int32_t) error
348
kim_error err = KIM_NO_ERROR;
349
mach_port_t reply_port = [[info objectForKey:@"reply_port"] integerValue];
351
err = kim_handle_reply_fini(reply_port, error);