aboutsummaryrefslogtreecommitdiffstats
path: root/src/frontends/osx/strongSwan/AppDelegate.m
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontends/osx/strongSwan/AppDelegate.m')
-rw-r--r--src/frontends/osx/strongSwan/AppDelegate.m358
1 files changed, 358 insertions, 0 deletions
diff --git a/src/frontends/osx/strongSwan/AppDelegate.m b/src/frontends/osx/strongSwan/AppDelegate.m
new file mode 100644
index 000000000..8fe997e0e
--- /dev/null
+++ b/src/frontends/osx/strongSwan/AppDelegate.m
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#import "AppDelegate.h"
+#import "Control.h"
+#import "LogController.h"
+#import "ConnController.h"
+#import "PasswordController.h"
+
+@implementation AppDelegate {
+ NSStatusItem *statusItem;
+ NSImage *active;
+ NSImage *inactive;
+ NSInteger nonConnectionItemCount;
+ NSMutableArray *connections;
+ Control *control;
+ ConnController *editor;
+ PasswordController *password;
+}
+
+- (void)change:(connectionState)state withConnection:(NSDictionary*)conn
+{
+ NSInteger idx;
+ NSMenuItem *item;
+
+ idx = [statusMenu indexOfItemWithRepresentedObject:conn];
+ if (idx != -1)
+ {
+ item = [statusMenu itemAtIndex:idx];
+
+ switch (state) {
+ case STATE_DOWN:
+ [item setState:NSOffState];
+ [item setAction:@selector(doConnection:)];
+ [[[item submenu] itemAtIndex:0] setAction:@selector(doConnection:)];
+ [[[item submenu] itemAtIndex:0] setTitle:@"Connect"];
+ [[[item submenu] itemAtIndex:1] setAction:@selector(editConnection:)];
+ [[[item submenu] itemAtIndex:2] setAction:@selector(removeConnection:)];
+ [self updateIcon];
+ break;
+ case STATE_WORKING:
+ [item setState:NSMixedState];
+ [item setAction:@selector(undoConnection:)];
+ [[[item submenu] itemAtIndex:0] setAction:@selector(undoConnection:)];
+ [[[item submenu] itemAtIndex:0] setTitle:@"Disconnect"];
+ [[[item submenu] itemAtIndex:1] setAction:nil];
+ [[[item submenu] itemAtIndex:2] setAction:nil];
+ [self updateIcon];
+ break;
+ case STATE_UP:
+ [item setState:NSOnState];
+ [self updateIcon];
+ break;
+ }
+ }
+}
+
+- (NSString*)createPasswordWithConnection:(NSDictionary*)conn
+{
+ return [password query];
+}
+
+- (void)raise:(NSString*)alert withConnection:(NSDictionary*)conn
+{
+ NSAlert *popup;
+ NSString *text;
+
+ text = [[NSString alloc]
+ initWithFormat:@"Establishing connection %@ failed:",
+ [conn objectForKey:@"name"]];
+ popup = [[NSAlert alloc] init];
+ [popup setMessageText:text];
+ [popup setInformativeText:alert];
+ [popup runModal];
+ [text release];
+ [popup release];
+}
+
+- (void)log:(NSString*)line withConnection:(NSDictionary*)conn
+{
+ [[self findLog:conn] appendLine:line];
+}
+
+- (IBAction)undoConnection:(id)sender
+{
+ NSDictionary *conn;
+
+ conn = [sender representedObject];
+ [control disconnect:conn];
+}
+
+- (IBAction)doConnection:(id)sender
+{
+ NSDictionary *conn;
+
+ conn = [sender representedObject];
+ [[self findLog:conn] clear];
+ [control connect:conn];
+}
+
+- (IBAction)addConnection:(id)sender
+{
+ NSMutableDictionary *conn;
+
+ conn = [editor createConnection];
+ if (conn)
+ {
+ [connections insertObject:conn atIndex:[connections count]];
+ [self saveConnections];
+ }
+}
+
+- (IBAction)editConnection:(id)sender
+{
+ NSMutableDictionary *conn;
+
+ conn = [sender representedObject];
+ if ([editor editConnection:conn])
+ {
+ [self saveConnections];
+ }
+}
+
+- (IBAction)removeConnection:(id)sender
+{
+ NSDictionary *conn;
+
+ conn = [sender representedObject];
+ [connections removeObject:conn];
+ [self saveConnections];
+}
+
+- (void)loadConnections
+{
+ NSUserDefaults *defaults;
+ NSArray *array;
+
+ defaults = [NSUserDefaults standardUserDefaults];
+ array = [defaults arrayForKey:@"connections"];
+ if (array)
+ {
+ [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+ if ([obj isKindOfClass:[NSDictionary class]])
+ {
+ NSMutableDictionary *dict;
+
+ dict = [obj mutableCopy];
+ [connections insertObject:dict atIndex:[connections count]];
+ [dict release];
+ }
+ }];
+ }
+ [defaults addObserver:self
+ forKeyPath:@"connections"
+ options:NSKeyValueObservingOptionNew
+ context:NULL];
+}
+
+- (void)saveConnections
+{
+ NSUserDefaults *defaults;
+
+ defaults = [NSUserDefaults standardUserDefaults];
+ [defaults setObject:connections forKey:@"connections"];
+ [defaults synchronize];
+}
+
+- (void)viewLog:(id)sender
+{
+ [[sender representedObject] show];
+}
+
+- (LogController*)findLog:(NSDictionary *)connection
+{
+ NSInteger idx;
+ NSMenuItem *item;
+
+ idx = [statusMenu indexOfItemWithRepresentedObject:connection];
+ if (idx != -1)
+ {
+ item = [statusMenu itemAtIndex:idx];
+ item = [[item submenu] itemAtIndex:3];
+ return [item representedObject];
+ }
+ return nil;
+}
+
+- (void)addMenuItem:(NSDictionary *)connection
+{
+ NSString *name, *title;
+ NSMenuItem *item;
+ NSMenu *submenu;
+ LogController *ctl;
+
+ name = [connection objectForKey:@"name"];
+ if (name) {
+ /* create submenu first */
+ submenu = [[NSMenu alloc] initWithTitle:@"submenu"];
+
+ item = [[NSMenuItem alloc] initWithTitle:@"Connect"
+ action:@selector(doConnection:)
+ keyEquivalent:@""];
+ [item setTarget:self];
+ [item setRepresentedObject:connection];
+ [submenu insertItem:item atIndex:0];
+ [item release];
+
+ item = [[NSMenuItem alloc] initWithTitle:@"Edit..."
+ action:@selector(editConnection:)
+ keyEquivalent:@""];
+ [item setTarget:self];
+ [item setRepresentedObject:connection];
+ [submenu insertItem:item atIndex:1];
+ [item release];
+
+ item = [[NSMenuItem alloc] initWithTitle:@"Remove"
+ action:@selector(removeConnection:)
+ keyEquivalent:@""];
+ [item setTarget:self];
+ [item setRepresentedObject:connection];
+ [submenu insertItem:item atIndex:2];
+ [item release];
+
+ item = [[NSMenuItem alloc] initWithTitle:@"View Log..."
+ action:@selector(viewLog:)
+ keyEquivalent:@""];
+ [item setTarget:self];
+ ctl = [[LogController alloc] initWithWindowNibName:@"LogWindow"];
+ title = [NSString stringWithFormat: @"strongSwan Log: %@", name];
+ [[ctl window] setTitle:title];
+ [item setRepresentedObject:ctl];
+ [ctl release];
+ [submenu insertItem:item atIndex:3];
+ [item release];
+
+ item = [[NSMenuItem alloc] initWithTitle:name
+ action:@selector(doConnection:)
+ keyEquivalent:@""];
+ [item setTarget:self];
+ [item setRepresentedObject:connection];
+ [item setSubmenu:submenu];
+ [submenu release];
+ [statusMenu insertItem:item atIndex:
+ [statusMenu numberOfItems] - nonConnectionItemCount];
+ [item release];
+ }
+}
+
+- (void)repopulateMenu
+{
+ while ([statusMenu numberOfItems] > nonConnectionItemCount)
+ {
+ [statusMenu removeItemAtIndex:0];
+ }
+ [connections enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) {
+ if ([obj isKindOfClass:[NSDictionary class]]) {
+ [self addMenuItem:obj];
+ }
+ }];
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath
+ ofObject:(id)object change:(NSDictionary *)change
+ context:(void *)context
+{
+ [self repopulateMenu];
+}
+
+- (void)updateIcon
+{
+ NSMenuItem *item;
+ bool anyactive = FALSE;
+ int i;
+
+ for (i = 0; i < [statusMenu numberOfItems] - nonConnectionItemCount; i++)
+ {
+ item = [statusMenu itemAtIndex:i];
+ if ([item state] == NSOnState)
+ {
+ anyactive = TRUE;
+ break;
+ }
+ }
+ [statusItem setImage: anyactive ? active : inactive];
+}
+
+- (void)initializeMenu
+{
+ NSImage *icon;
+ NSString *path;
+
+ statusItem = [[[NSStatusBar systemStatusBar]
+ statusItemWithLength:NSVariableStatusItemLength] retain];
+ [statusItem setMenu:statusMenu];
+ [statusItem setHighlightMode:YES];
+
+ path = [[NSBundle mainBundle] pathForResource:@"icon" ofType:@"png"];
+ icon = [[NSImage alloc] initWithContentsOfFile:path];
+ [statusItem setImage:icon];
+ inactive = icon;
+
+ path = [[NSBundle mainBundle] pathForResource:@"icon-active" ofType:@"png"];
+ icon = [[NSImage alloc] initWithContentsOfFile:path];
+ active = icon;
+
+ path = [[NSBundle mainBundle] pathForResource:@"icon-alt" ofType:@"png"];
+ icon = [[NSImage alloc] initWithContentsOfFile:path];
+ [statusItem setAlternateImage:icon];
+ [icon release];
+
+ nonConnectionItemCount = [statusMenu numberOfItems];
+
+ [self repopulateMenu];
+}
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
+{
+ [self loadConnections];
+ [self initializeMenu];
+}
+
+- (id)init
+{
+ self = [super init];
+ control = [[Control alloc] initWithDelegate:self];
+ connections = [[NSMutableArray alloc] init];
+ editor = [[ConnController alloc] initWithWindowNibName:@"ConnWindow"];
+ password = [[PasswordController alloc] initWithWindowNibName:@"PasswordWindow"];
+ return self;
+}
+
+- (void)dealloc
+{
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ [defaults removeObserver:self forKeyPath:@"connections"];
+ [statusItem release];
+ [active release];
+ [inactive release];
+ [connections release];
+ [control release];
+ [editor release];
+ [password release];
+ [super dealloc];
+}
+
+@end