2 // MainMenuController.m
5 // Created by Jose Quaresma on 11/6/09.
6 // Copyright 2009 __MyCompanyName__. All rights reserved.
9 #import "MainMenuController.h"
10 #import "AdvMenuController.h"
11 #import "PreferenceController.h"
12 #import "ConnectionsDB.h"
13 #import "Connection.h"
14 #import <AppKit/NSCell.h>
17 #define OPENSWAN_COCOA_APP 1
19 #import "ipsecconf/confread.h"
20 #import "openswan/passert.h"
22 #import "programs/pluto/log.h"
27 char* progname = "openswan \0";
29 int warningsarefatal = 0;
30 #import "ipsecconf/confwrite.h"
33 @implementation MainMenuController
34 @synthesize db, connTime, connDuration, timer, connDurationPrint, selConn;
36 - (IBAction)showAdvMenu: (id)sender
38 //Is advMenuController nil?
39 if(!advMenuController){
40 advMenuController = [[AdvMenuController alloc] init];
41 [advMenuController setSelItemIndex:[[self selConn] indexOfSelectedItem]];
44 [[advMenuController selConn] selectItemAtIndex:[[self selConn] indexOfSelectedItem]];
47 NSLog(@"Showing %@", advMenuController);
48 [advMenuController showWindow: self];
51 - (IBAction)connDisc: (id) sender
53 if([sender state] == NSOnState){
54 [connView setHidden:YES];
55 [discView setHidden:NO];
58 [connView setHidden:NO];
59 [discView setHidden:YES];
65 [NSApp setDelegate: self];
67 [GrowlApplicationBridge setGrowlDelegate:self];
69 [self loadDataFromDisk];
71 [connView setHidden:NO];
72 [discView setHidden:YES];
73 [self setConnDurationPrint:[NSString stringWithString:@"0:0:0"]];
76 - (void) applicationWillTerminate: (NSNotification *)note
78 [self saveDataToDisk];
81 - (IBAction)showPreferencePanel: (id)sender
83 //Is preferenceController nil?
84 if(!preferenceController){
85 preferenceController = [[PreferenceController alloc] init];
87 NSLog(@"Showing %@", preferenceController);
88 [preferenceController showWindow: self];
91 #pragma mark archiving
92 - (NSString *) pathForDataFile
94 NSFileManager *fileManager = [NSFileManager defaultManager];
96 NSString *folder = @"~/Library/Application Support/Openswan/";
97 folder = [folder stringByExpandingTildeInPath];
99 if ([fileManager fileExistsAtPath: folder] == NO)
101 [fileManager createDirectoryAtPath: folder attributes: nil];
104 NSString *fileName = @"Openswan.data";
105 return [folder stringByAppendingPathComponent:fileName];
108 - (void) saveDataToDisk
110 NSLog(@"Saving data to disk");
111 NSString* path = [self pathForDataFile];
113 NSMutableDictionary* rootObject;
114 rootObject = [NSMutableDictionary dictionary];
116 [rootObject setValue:[self db] forKey:@"db"];
117 [NSKeyedArchiver archiveRootObject:rootObject toFile:path];
120 - (void) loadDataFromDisk
122 NSLog(@"Loading data from disk");
123 NSString* path = [self pathForDataFile];
124 NSDictionary* rootObject;
126 rootObject = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
127 [self setDb:[rootObject valueForKey:@"db"]];
129 //If there is no previously saved data
132 [self setDb:[ConnectionsDB sharedInstance]];
136 - (IBAction)saveData: (id)sender
138 [self saveDataToDisk];
140 - (IBAction)loadData: (id)sender
142 [self loadDataFromDisk];
147 static OSStatus DoConnect(CFStringRef reqConnName)
148 // This code shows how to do a typical BetterAuthorizationSample privileged operation
149 // in straight C. In this case, it does the low-numbered ports operation, which
150 // returns three file descriptors that are bound to low-numbered TCP ports.
154 CFStringRef bundleID;
158 CFDictionaryRef request;
159 CFDictionaryRef response;
160 BASFailCode failCode;
165 // Get our bundle information.
167 bundle = CFBundleGetMainBundle();
168 assert(bundle != NULL);
170 bundleID = CFBundleGetIdentifier(bundle);
171 assert(bundleID != NULL);
173 // Create the request. The request always contains the kBASCommandKey that
174 // describes the command to do. It also, optionally, contains the
175 // kSampleLowNumberedPortsForceFailure key that tells the tool to always return
176 // an error. The purpose of this is to test our error handling path (do we leak
177 // descriptors, for example).
180 keys[keyCount] = CFSTR(kBASCommandKey);
181 values[keyCount] = CFSTR(kConnectCommand);
184 keys[keyCount] = CFSTR("connName");
185 values[keyCount] = CFStringCreateCopy(NULL, reqConnName);
188 request = CFDictionaryCreate(
190 (const void **) keys,
191 (const void **) values,
193 &kCFTypeDictionaryKeyCallBacks,
194 &kCFTypeDictionaryValueCallBacks
196 assert(request != NULL);
202 err = BASExecuteRequestInHelperTool(
210 // If it failed, try to recover.
212 if ( (err != noErr) && (err != userCanceledErr) ) {
215 failCode = BASDiagnoseFailure(gAuth, bundleID);
217 // At this point we tell the user that something has gone wrong and that we need
218 // to authorize in order to fix it. Ideally we'd use failCode to describe the type of
219 // error to the user.
221 alertResult = NSRunAlertPanel(@"Needs Install", @"BAS needs to install", @"Install", @"Cancel", NULL);
223 if ( alertResult == NSAlertDefaultReturn ) {
224 // Try to fix things.
226 err = BASFixFailure(gAuth, (CFStringRef) bundleID, CFSTR("InstallTool"), CFSTR("HelperTool"), failCode);
228 // If the fix went OK, retry the request.
231 err = BASExecuteRequestInHelperTool(
240 err = userCanceledErr;
244 // If all of the above went OK, it means that the IPC to the helper tool worked. We
245 // now have to check the response dictionary to see if the command's execution within
246 // the helper tool was successful.
249 err = BASGetErrorFromResponse(response);
252 // Extract the descriptors from the response and copy them out to our caller.
255 CFStringRef returnString;
257 returnString = (CFStringRef) CFDictionaryGetValue(response, CFSTR(kBASTestString));
258 NSLog(@"Command ran: %@", returnString);
262 if (response != NULL) {
269 - (IBAction)connect: (id)sender
271 if([self timer] == nil) {
272 [self setConnTime:[NSDate date]];
274 NSTimer *tmpTimer = [NSTimer scheduledTimerWithTimeInterval:1
276 selector:@selector(updateConnDuration:)
279 [self setTimer:tmpTimer];
282 [[self timer] invalidate];
283 //[[self timer] release];
285 [self setConnDuration:0];
286 [self setConnDurationPrint:[NSString stringWithString:@"0:0:0"]];
288 if([sender state] == NSOnState){
289 [connView setHidden:YES];
290 [discView setHidden:NO];
292 [self saveConnToFile];
297 // Call the C code to do the real work.
299 Connection *conn = [[[ConnectionsDB sharedInstance] connDB] objectAtIndex:[selConn indexOfSelectedItem]];
302 [[conn connName] getCString:connName maxLength:100 encoding:NSMacOSRomanStringEncoding];
304 CFStringRef reqConnName = CFStringCreateWithCString(NULL, connName, CFStringGetSystemEncoding());
306 err = DoConnect(reqConnName);
314 [GrowlApplicationBridge
315 notifyWithTitle:@"Connected"
316 description:@"Connection was established"
317 notificationName:@"Openswan Growl Notification"
324 [connView setHidden:NO];
325 [discView setHidden:YES];
329 Connection *conn = [[[ConnectionsDB sharedInstance] connDB] objectAtIndex:[selConn indexOfSelectedItem]];
330 NSString *origFileName = [conn connName];
331 NSString *fileName = [origFileName stringByAppendingFormat:@".conf"];
332 NSString *origPath = @"~/Library/Application Support/Openswan";
333 NSString *filePath = [origPath stringByAppendingPathComponent:fileName];
334 NSString *path = [filePath stringByStandardizingPath];
336 NSFileManager *fileManager = [NSFileManager defaultManager];
337 if ([fileManager fileExistsAtPath: path] == YES)
339 [fileManager removeFileAtPath:path handler:nil];
343 [GrowlApplicationBridge
344 notifyWithTitle:@"Disconnected"
345 description:@"Connection was closed"
346 notificationName:@"Openswan Growl Notification"
354 - (void)updateConnDuration: (NSTimer*)aTimer
356 NSDate* now = [NSDate date];
357 [self setConnDuration:[now timeIntervalSinceDate: connTime]];
358 int hours = (NSInteger)connDuration / 3600;
359 [self setConnDuration:(NSInteger)connDuration % 3600];
360 int mins = (NSInteger)connDuration / 60;
361 [self setConnDuration:(NSInteger)connDuration % 60];
362 int secs = (NSInteger)connDuration;
363 [self setConnDurationPrint:[NSString stringWithFormat:@"%d:%d:%d", hours, mins, secs]];
367 - (NSDictionary*)registrationDictionaryForGrowl
369 NSArray *notifications;
370 notifications = [NSArray arrayWithObject:@"Openswan Growl Notification"];
373 dict = [NSDictionary dictionaryWithObjectsAndKeys:
374 notifications, GROWL_NOTIFICATIONS_ALL,
375 notifications, GROWL_NOTIFICATIONS_DEFAULT, nil];
380 int main(int argc, char *argv[])
384 // Create the AuthorizationRef that we'll use through this application. We ignore
385 // any error from this. A failure from AuthorizationCreate is very unusual, and if it
386 // happens there's no way to recover; Authorization Services just won't work.
388 junk = AuthorizationCreate(NULL, NULL, kAuthorizationFlagDefaults, &gAuth);
389 assert(junk == noErr);
390 assert( (junk == noErr) == (gAuth != NULL) );
392 // For each of our commands, check to see if a right specification exists and, if not,
395 // The last parameter is the name of a ".strings" file that contains the localised prompts
396 // for any custom rights that we use.
401 CFBundleGetIdentifier(CFBundleGetMainBundle()),
402 CFSTR("AuthorizationPrompts")
405 return NSApplicationMain(argc, (const char **) argv);
408 #pragma mark writeFile
409 - (void) saveConnToFile {
410 struct starter_config *cfg = NULL;
411 struct starter_conn *new_conn = NULL;
415 char *cPath = "../../test/testGUI.cfg";
417 //Connection *conn = [[[ConnectionsDB sharedInstance] connDB] objectAtIndex:[selConn indexOfSelectedItem]];
421 NSString *origFileName = [conn connName];
422 NSString *fileName = [origFileName stringByAppendingFormat:@".conf"];
423 NSString *origPath = @"~/Library/Application Support/Openswan";
424 NSString *filePath = [origPath stringByAppendingPathComponent:fileName];
425 NSString *path = [filePath stringByStandardizingPath];
427 [path getCString:cPath maxLength:100 encoding:NSMacOSRomanStringEncoding];
430 cfg = (struct starter_config *) malloc(sizeof(struct starter_config));
431 if (!cfg) printf("can't allocate memory");
433 memset(cfg, 0, sizeof(struct starter_config));
435 ipsecconf_default_values(cfg);
438 //char cConnName[20];
439 //[[conn connName] getCString:cConnName maxLength:20 encoding:NSMacOSRomanStringEncoding];
441 new_conn = alloc_add_conn(cfg, "test", &perr);
442 if(new_conn == NULL) printf("%s", perr);
444 cfg->setup.options_set[KBF_NATTRAVERSAL] = 1;
445 cfg->setup.options[KBF_NATTRAVERSAL] = 0;
447 cfg->setup.strings_set[KSF_PROTOSTACK] = 1;
448 cfg->setup.strings[KSF_PROTOSTACK] = strdup("netkey");
450 new_conn->connalias = strdup("anotheralias");
452 new_conn->left.rsakey2 = (unsigned char *)"0s23489234ba28934243";
453 new_conn->left.rsakey1 = (unsigned char *)"0sabcdabcdabcd";
455 new_conn->desired_state = STARTUP_START;
457 new_conn->options_set[KBF_AUTO] = 1;
458 new_conn->options[KBF_AUTO] = STARTUP_START;
460 new_conn->left.cert = "/my/cert/file";
462 file = fopen(cPath,"w");
463 confwrite(cfg, file);