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.
25 #import "KerberosAgentController.h"
26 #import "SelectIdentityController.h"
27 #import "AuthenticationController.h"
28 #import "KerberosAgentListener.h"
30 #import "ServerDemux.h"
32 #define SECONDS_BEFORE_AUTO_QUIT_ON_START 600
33 #define SECONDS_BEFORE_AUTO_QUIT_ON_NO_CLIENTS 1
35 @implementation KerberosAgentController
39 // ---------------------------------------------------------------------------
41 - (void) applicationDidFinishLaunching: (NSNotification *) notification
43 self.clients = [NSMutableArray array];
44 [KerberosAgentListener startListening];
46 [NSApp activateIgnoringOtherApps:YES];
48 autoQuitTimer = [NSTimer scheduledTimerWithTimeInterval:SECONDS_BEFORE_AUTO_QUIT_ON_START
50 selector:@selector(quitIfIdle:)
58 [autoQuitTimer invalidate];
59 [autoQuitTimer release];
64 - (void) quitIfIdle: (NSTimer *) timer
66 if ([self.clients count] == 0) {
67 [NSApp terminate:nil];
72 - (IPCClient *)clientForPort:(mach_port_t)client_port
74 IPCClient *aClient = nil;
76 for (aClient in self.clients) {
77 if (aClient.port == client_port) {
85 - (IPCClient *)clientForInfo:(NSDictionary *)info
87 mach_port_t client_port = [[info objectForKey:@"client_port"] integerValue];
88 return [self clientForPort:client_port];
91 - (IBAction) fakeANewClient: (id) sender
93 IPCClient *aClient = [[IPCClient alloc] init];
95 aClient.name = @"Barry";
96 aClient.path = [[NSBundle mainBundle] bundlePath];
97 [self.clients addObject:aClient];
101 #pragma mark Client actions
104 - (void) addClient: (NSDictionary *) info
107 IPCClient *aClient = [self clientForInfo:info];
110 // already registered
111 err = KIM_IDENTITY_ALREADY_IN_LIST_ERR;
113 aClient = [[IPCClient alloc] init];
114 aClient.port = [[info objectForKey:@"client_port"] integerValue];
115 aClient.name = [info objectForKey:@"name"];
116 aClient.path = [info objectForKey:@"path"];
117 [self.clients addObject:aClient];
121 [autoQuitTimer invalidate];
124 [KerberosAgentListener didAddClient:info error:err];
129 - (void) enterIdentity: (NSDictionary *) info
131 kim_error err = KIM_NO_ERROR;
132 IPCClient *aClient = nil;
134 // get client object for matching info, creating if it doesn't exist
135 aClient = [self clientForInfo:info];
136 if (!aClient) { err = KIM_IDENTITY_NOT_IN_LIST_ERR; }
138 err = [aClient enterIdentity:info];
141 [KerberosAgentListener didEnterIdentity:info error:err];
146 - (void) selectIdentity: (NSDictionary *) info
148 kim_error err = KIM_NO_ERROR;
149 IPCClient *aClient = nil;
151 // get client object for matching info, creating if it doesn't exist
152 aClient = [self clientForInfo:info];
153 if (!aClient) { err = KIM_IDENTITY_NOT_IN_LIST_ERR; }
155 err = [aClient selectIdentity:info];
158 [KerberosAgentListener didSelectIdentity:info error:err];
163 - (void) promptForAuth: (NSDictionary *) info
165 kim_error err = KIM_NO_ERROR;
166 IPCClient *aClient = nil;
168 aClient = [self clientForInfo:info];
169 if (!aClient) { err = KIM_IDENTITY_NOT_IN_LIST_ERR; }
171 err = [aClient promptForAuth:info];
176 - (void) changePassword: (NSDictionary *) info
178 kim_error err = KIM_NO_ERROR;
179 IPCClient *aClient = nil;
181 aClient = [self clientForInfo:info];
182 if (!aClient) { err = KIM_IDENTITY_NOT_IN_LIST_ERR; }
184 err = [aClient changePassword:info];
189 - (void) handleError: (NSDictionary *) info
191 kim_error err = KIM_NO_ERROR;
192 IPCClient *aClient = nil;
194 aClient = [self clientForInfo:info];
195 if (!aClient) { err = KIM_IDENTITY_NOT_IN_LIST_ERR; }
197 err = [aClient handleError:info];
202 - (void) removeClient: (NSDictionary *) info
204 kim_error err = KIM_NO_ERROR;
205 IPCClient *aClient = [self clientForInfo:info];
208 err = KIM_IDENTITY_NOT_IN_LIST_ERR;
210 // close all windows associated with it
212 [self.clients removeObject:aClient];
213 if ([self.clients count] == 0) {
214 // the client removes itself after select identity,
215 // but might come back shortly afterward in need of an auth prompt
216 [autoQuitTimer invalidate];
217 autoQuitTimer = [NSTimer scheduledTimerWithTimeInterval:SECONDS_BEFORE_AUTO_QUIT_ON_NO_CLIENTS
219 selector:@selector(quitIfIdle:)
225 // called after user finishes prompt
226 [KerberosAgentListener didRemoveClient:info error:err];