KerberosAgentController.m [plain text]
/*
* Copyright 2008 Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
*
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission. Furthermore if you modify this software you must label
* your software as modified software and not distribute it in such a
* fashion that it might be confused with the original M.I.T. software.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*/
#import "KerberosAgentController.h"
#import "SelectIdentityController.h"
#import "AuthenticationController.h"
#import "KerberosAgentListener.h"
#import "IPCClient.h"
#import "ServerDemux.h"
#define SECONDS_BEFORE_AUTO_QUIT_ON_START 600
#define SECONDS_BEFORE_AUTO_QUIT_ON_NO_CLIENTS 1
@implementation KerberosAgentController
@synthesize clients;
// ---------------------------------------------------------------------------
- (void) applicationDidFinishLaunching: (NSNotification *) notification
{
self.clients = [NSMutableArray array];
[KerberosAgentListener startListening];
[NSApp activateIgnoringOtherApps:YES];
autoQuitTimer = [NSTimer scheduledTimerWithTimeInterval:SECONDS_BEFORE_AUTO_QUIT_ON_START
target:self
selector:@selector(quitIfIdle:)
userInfo:nil
repeats:NO];
}
- (void) dealloc
{
self.clients = nil;
[autoQuitTimer invalidate];
[autoQuitTimer release];
[super dealloc];
}
- (void) quitIfIdle: (NSTimer *) timer
{
if ([self.clients count] == 0) {
[NSApp terminate:nil];
}
autoQuitTimer = nil;
}
- (IPCClient *)clientForPort:(mach_port_t)client_port
{
IPCClient *aClient = nil;
for (aClient in self.clients) {
if (aClient.port == client_port) {
break;
}
}
return aClient;
}
- (IPCClient *)clientForInfo:(NSDictionary *)info
{
mach_port_t client_port = [[info objectForKey:@"client_port"] integerValue];
return [self clientForPort:client_port];
}
- (IBAction) fakeANewClient: (id) sender
{
IPCClient *aClient = [[IPCClient alloc] init];
aClient.port = 1;
aClient.name = @"Barry";
aClient.path = [[NSBundle mainBundle] bundlePath];
[self.clients addObject:aClient];
[aClient release];
}
#pragma mark Client actions
// init
- (void) addClient: (NSDictionary *) info
{
int32_t err = 0;
IPCClient *aClient = [self clientForInfo:info];
if (aClient) {
// already registered
err = KIM_IDENTITY_ALREADY_IN_LIST_ERR;
} else {
aClient = [[IPCClient alloc] init];
aClient.port = [[info objectForKey:@"client_port"] integerValue];
aClient.name = [info objectForKey:@"name"];
aClient.path = [info objectForKey:@"path"];
[self.clients addObject:aClient];
[aClient release];
}
[autoQuitTimer invalidate];
autoQuitTimer = nil;
[KerberosAgentListener didAddClient:info error:err];
[info release];
}
// enter
- (void) enterIdentity: (NSDictionary *) info
{
kim_error err = KIM_NO_ERROR;
IPCClient *aClient = nil;
// get client object for matching info, creating if it doesn't exist
aClient = [self clientForInfo:info];
if (!aClient) { err = KIM_IDENTITY_NOT_IN_LIST_ERR; }
else {
err = [aClient enterIdentity:info];
}
if (err) {
[KerberosAgentListener didEnterIdentity:info error:err];
}
}
// select
- (void) selectIdentity: (NSDictionary *) info
{
kim_error err = KIM_NO_ERROR;
IPCClient *aClient = nil;
// get client object for matching info, creating if it doesn't exist
aClient = [self clientForInfo:info];
if (!aClient) { err = KIM_IDENTITY_NOT_IN_LIST_ERR; }
else {
err = [aClient selectIdentity:info];
}
if (err) {
[KerberosAgentListener didSelectIdentity:info error:err];
}
}
// auth
- (void) promptForAuth: (NSDictionary *) info
{
kim_error err = KIM_NO_ERROR;
IPCClient *aClient = nil;
aClient = [self clientForInfo:info];
if (!aClient) { err = KIM_IDENTITY_NOT_IN_LIST_ERR; }
else {
err = [aClient promptForAuth:info];
}
}
// change password
- (void) changePassword: (NSDictionary *) info
{
kim_error err = KIM_NO_ERROR;
IPCClient *aClient = nil;
aClient = [self clientForInfo:info];
if (!aClient) { err = KIM_IDENTITY_NOT_IN_LIST_ERR; }
else {
err = [aClient changePassword:info];
}
}
// error
- (void) handleError: (NSDictionary *) info
{
kim_error err = KIM_NO_ERROR;
IPCClient *aClient = nil;
aClient = [self clientForInfo:info];
if (!aClient) { err = KIM_IDENTITY_NOT_IN_LIST_ERR; }
else {
err = [aClient handleError:info];
}
}
// fini
- (void) removeClient: (NSDictionary *) info
{
kim_error err = KIM_NO_ERROR;
IPCClient *aClient = [self clientForInfo:info];
if (!aClient) {
err = KIM_IDENTITY_NOT_IN_LIST_ERR;
} else {
// close all windows associated with it
[aClient cleanup];
[self.clients removeObject:aClient];
if ([self.clients count] == 0) {
// the client removes itself after select identity,
// but might come back shortly afterward in need of an auth prompt
[autoQuitTimer invalidate];
autoQuitTimer = [NSTimer scheduledTimerWithTimeInterval:SECONDS_BEFORE_AUTO_QUIT_ON_NO_CLIENTS
target:self
selector:@selector(quitIfIdle:)
userInfo:nil
repeats:NO];
}
}
// called after user finishes prompt
[KerberosAgentListener didRemoveClient:info error:err];
[info release];
}
@end