Imported Upstream version 1.10.2
[platform/upstream/krb5.git] / src / kim / agent / mac / KerberosAgentController.m
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 #import "KerberosAgentController.h"
26 #import "SelectIdentityController.h"
27 #import "AuthenticationController.h"
28 #import "KerberosAgentListener.h"
29 #import "IPCClient.h"
30 #import "ServerDemux.h"
31
32 #define SECONDS_BEFORE_AUTO_QUIT_ON_START 600
33 #define SECONDS_BEFORE_AUTO_QUIT_ON_NO_CLIENTS 1
34
35 @implementation KerberosAgentController
36
37 @synthesize clients;
38
39 // ---------------------------------------------------------------------------
40
41 - (void) applicationDidFinishLaunching: (NSNotification *) notification
42 {
43     self.clients = [NSMutableArray array];
44     [KerberosAgentListener startListening];
45     
46     [NSApp activateIgnoringOtherApps:YES];
47     
48     autoQuitTimer = [NSTimer scheduledTimerWithTimeInterval:SECONDS_BEFORE_AUTO_QUIT_ON_START
49                                                      target:self
50                                                    selector:@selector(quitIfIdle:)
51                                                    userInfo:nil 
52                                                     repeats:NO];
53 }
54
55 - (void) dealloc
56 {
57     self.clients = nil;
58     [autoQuitTimer invalidate];
59     [autoQuitTimer release];
60     
61     [super dealloc];
62 }
63
64 - (void) quitIfIdle: (NSTimer *) timer
65 {
66     if ([self.clients count] == 0) {
67         [NSApp terminate:nil];
68     }
69     autoQuitTimer = nil;
70 }
71
72 - (IPCClient *)clientForPort:(mach_port_t)client_port
73 {
74     IPCClient *aClient = nil;
75     
76     for (aClient in self.clients) {
77         if (aClient.port == client_port) {
78             break;
79         }
80     }
81     
82     return aClient;
83 }
84
85 - (IPCClient *)clientForInfo:(NSDictionary *)info
86 {
87     mach_port_t client_port = [[info objectForKey:@"client_port"] integerValue];
88     return [self clientForPort:client_port];
89 }
90
91 - (IBAction) fakeANewClient: (id) sender
92 {
93     IPCClient *aClient = [[IPCClient alloc] init];
94     aClient.port = 1;
95     aClient.name = @"Barry";
96     aClient.path = [[NSBundle mainBundle] bundlePath];
97     [self.clients addObject:aClient];
98     [aClient release];
99 }
100
101 #pragma mark Client actions
102
103 // init
104 - (void) addClient: (NSDictionary *) info
105 {
106     int32_t err = 0;
107     IPCClient *aClient = [self clientForInfo:info];
108
109     if (aClient) {
110         // already registered
111         err = KIM_IDENTITY_ALREADY_IN_LIST_ERR;
112     } else {
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];
118         [aClient release];
119     }
120     
121     [autoQuitTimer invalidate];
122     autoQuitTimer = nil;
123     
124     [KerberosAgentListener didAddClient:info error:err];
125     [info release];
126 }
127
128 // enter
129 - (void) enterIdentity: (NSDictionary *) info
130 {
131     kim_error err = KIM_NO_ERROR;
132     IPCClient *aClient = nil;
133
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; }
137     else {
138         err = [aClient enterIdentity:info];
139     }
140     if (err) {
141         [KerberosAgentListener didEnterIdentity:info error:err];
142     }
143 }
144
145 // select
146 - (void) selectIdentity: (NSDictionary *) info
147 {
148     kim_error err = KIM_NO_ERROR;
149     IPCClient *aClient = nil;
150     
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; }
154     else {
155         err = [aClient selectIdentity:info];
156     }
157     if (err) {
158         [KerberosAgentListener didSelectIdentity:info error:err];
159     }
160 }
161
162 // auth
163 - (void) promptForAuth: (NSDictionary *) info
164 {
165     kim_error err = KIM_NO_ERROR;
166     IPCClient *aClient = nil;
167     
168     aClient = [self clientForInfo:info];
169     if (!aClient) { err = KIM_IDENTITY_NOT_IN_LIST_ERR; }
170     else {
171         err = [aClient promptForAuth:info];
172     }
173 }
174
175 // change password
176 - (void) changePassword: (NSDictionary *) info
177 {
178     kim_error err = KIM_NO_ERROR;
179     IPCClient *aClient = nil;
180     
181     aClient = [self clientForInfo:info];
182     if (!aClient) { err = KIM_IDENTITY_NOT_IN_LIST_ERR; }
183     else {
184         err = [aClient changePassword:info];
185     }
186 }
187
188 // error
189 - (void) handleError: (NSDictionary *) info
190 {
191     kim_error err = KIM_NO_ERROR;
192     IPCClient *aClient = nil;
193     
194     aClient = [self clientForInfo:info];
195     if (!aClient) { err = KIM_IDENTITY_NOT_IN_LIST_ERR; }
196     else {
197         err = [aClient handleError:info];
198     }
199 }
200
201 // fini
202 - (void) removeClient: (NSDictionary *) info
203 {
204     kim_error err = KIM_NO_ERROR;
205     IPCClient *aClient = [self clientForInfo:info];
206     
207     if (!aClient) {
208         err = KIM_IDENTITY_NOT_IN_LIST_ERR;
209     } else {
210         // close all windows associated with it
211         [aClient cleanup];
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
218                                                              target:self
219                                                            selector:@selector(quitIfIdle:)
220                                                            userInfo:nil 
221                                                             repeats:NO];
222         }
223     }
224     
225     // called after user finishes prompt
226     [KerberosAgentListener didRemoveClient:info error:err];
227     [info release];
228 }
229
230 @end