// // MainMenuController.m // Openswan // // Created by Jose Quaresma on 11/6/09. // Copyright 2009 __MyCompanyName__. All rights reserved. // #import "MainMenuController.h" #import "AdvMenuController.h" #import "PreferenceController.h" #import "ConnectionsDB.h" #import "Connection.h" #import //Stuff from Openswan #define OPENSWAN_COCOA_APP 1 #import #import "ipsecconf/confread.h" #import "openswan/passert.h" #import "oswlog.h" #import "programs/pluto/log.h" void exit_tool(int x) { exit(x); } char* progname = "openswan \0"; int verbose=0; int warningsarefatal = 0; #import "ipsecconf/confwrite.h" @implementation MainMenuController @synthesize db, connTime, connDuration, timer, connDurationPrint, selConn; - (IBAction)showAdvMenu: (id)sender { //Is advMenuController nil? if(!advMenuController){ advMenuController = [[AdvMenuController alloc] init]; [advMenuController setSelItemIndex:[[self selConn] indexOfSelectedItem]]; } else{ [[advMenuController selConn] selectItemAtIndex:[[self selConn] indexOfSelectedItem]]; } NSLog(@"Showing %@", advMenuController); [advMenuController showWindow: self]; } - (IBAction)connDisc: (id) sender { if([sender state] == NSOnState){ [connView setHidden:YES]; [discView setHidden:NO]; } else{ [connView setHidden:NO]; [discView setHidden:YES]; } } - (void)awakeFromNib { [NSApp setDelegate: self]; [GrowlApplicationBridge setGrowlDelegate:self]; [self loadDataFromDisk]; [connView setHidden:NO]; [discView setHidden:YES]; [self setConnDurationPrint:[NSString stringWithString:@"0:0:0"]]; } - (void) applicationWillTerminate: (NSNotification *)note { [self saveDataToDisk]; } - (IBAction)showPreferencePanel: (id)sender { //Is preferenceController nil? if(!preferenceController){ preferenceController = [[PreferenceController alloc] init]; } NSLog(@"Showing %@", preferenceController); [preferenceController showWindow: self]; } #pragma mark archiving - (NSString *) pathForDataFile { NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *folder = @"~/Library/Application Support/Openswan/"; folder = [folder stringByExpandingTildeInPath]; if ([fileManager fileExistsAtPath: folder] == NO) { [fileManager createDirectoryAtPath: folder attributes: nil]; } NSString *fileName = @"Openswan.data"; return [folder stringByAppendingPathComponent:fileName]; } - (void) saveDataToDisk { NSLog(@"Saving data to disk"); NSString* path = [self pathForDataFile]; NSMutableDictionary* rootObject; rootObject = [NSMutableDictionary dictionary]; [rootObject setValue:[self db] forKey:@"db"]; [NSKeyedArchiver archiveRootObject:rootObject toFile:path]; } - (void) loadDataFromDisk { NSLog(@"Loading data from disk"); NSString* path = [self pathForDataFile]; NSDictionary* rootObject; rootObject = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; [self setDb:[rootObject valueForKey:@"db"]]; //If there is no previously saved data if(db==NULL) { [self setDb:[ConnectionsDB sharedInstance]]; } } - (IBAction)saveData: (id)sender { [self saveDataToDisk]; } - (IBAction)loadData: (id)sender { [self loadDataFromDisk]; } //Helper Tool static OSStatus DoConnect(CFStringRef reqConnName) // This code shows how to do a typical BetterAuthorizationSample privileged operation // in straight C. In this case, it does the low-numbered ports operation, which // returns three file descriptors that are bound to low-numbered TCP ports. { OSStatus err; CFBundleRef bundle; CFStringRef bundleID; CFIndex keyCount; CFStringRef keys[2]; CFTypeRef values[2]; CFDictionaryRef request; CFDictionaryRef response; BASFailCode failCode; // Pre-conditions // Get our bundle information. bundle = CFBundleGetMainBundle(); assert(bundle != NULL); bundleID = CFBundleGetIdentifier(bundle); assert(bundleID != NULL); // Create the request. The request always contains the kBASCommandKey that // describes the command to do. It also, optionally, contains the // kSampleLowNumberedPortsForceFailure key that tells the tool to always return // an error. The purpose of this is to test our error handling path (do we leak // descriptors, for example). keyCount = 0; keys[keyCount] = CFSTR(kBASCommandKey); values[keyCount] = CFSTR(kConnectCommand); keyCount += 1; keys[keyCount] = CFSTR("connName"); values[keyCount] = CFStringCreateCopy(NULL, reqConnName); keyCount += 1; request = CFDictionaryCreate( NULL, (const void **) keys, (const void **) values, keyCount, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); assert(request != NULL); response = NULL; // Execute it. err = BASExecuteRequestInHelperTool( gAuth, kCommandSet, bundleID, request, &response ); // If it failed, try to recover. if ( (err != noErr) && (err != userCanceledErr) ) { int alertResult; failCode = BASDiagnoseFailure(gAuth, bundleID); // At this point we tell the user that something has gone wrong and that we need // to authorize in order to fix it. Ideally we'd use failCode to describe the type of // error to the user. alertResult = NSRunAlertPanel(@"Needs Install", @"BAS needs to install", @"Install", @"Cancel", NULL); if ( alertResult == NSAlertDefaultReturn ) { // Try to fix things. err = BASFixFailure(gAuth, (CFStringRef) bundleID, CFSTR("InstallTool"), CFSTR("HelperTool"), failCode); // If the fix went OK, retry the request. if (err == noErr) { err = BASExecuteRequestInHelperTool( gAuth, kCommandSet, bundleID, request, &response ); } } else { err = userCanceledErr; } } // If all of the above went OK, it means that the IPC to the helper tool worked. We // now have to check the response dictionary to see if the command's execution within // the helper tool was successful. if (err == noErr) { err = BASGetErrorFromResponse(response); } // Extract the descriptors from the response and copy them out to our caller. if (err == noErr) { CFStringRef returnString; returnString = (CFStringRef) CFDictionaryGetValue(response, CFSTR(kBASTestString)); NSLog(@"Command ran: %@", returnString); } if (response != NULL) { CFRelease(response); } return err; } - (IBAction)connect: (id)sender { if([self timer] == nil) { [self setConnTime:[NSDate date]]; NSTimer *tmpTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateConnDuration:) userInfo:nil repeats:YES]; [self setTimer:tmpTimer]; } else { [[self timer] invalidate]; //[[self timer] release]; [self setTimer:nil]; [self setConnDuration:0]; [self setConnDurationPrint:[NSString stringWithString:@"0:0:0"]]; } if([sender state] == NSOnState){ [connView setHidden:YES]; [discView setHidden:NO]; [self saveConnToFile]; /////////////// OSStatus err; // Call the C code to do the real work. Connection *conn = [[[ConnectionsDB sharedInstance] connDB] objectAtIndex:[selConn indexOfSelectedItem]]; char connName[100]; [[conn connName] getCString:connName maxLength:100 encoding:NSMacOSRomanStringEncoding]; CFStringRef reqConnName = CFStringCreateWithCString(NULL, connName, CFStringGetSystemEncoding()); err = DoConnect(reqConnName); // Log our results. ////////////// [GrowlApplicationBridge notifyWithTitle:@"Connected" description:@"Connection was established" notificationName:@"Openswan Growl Notification" iconData:nil priority:0 isSticky:NO clickContext:nil]; } else{ [connView setHidden:NO]; [discView setHidden:YES]; //Delete conn file? /* Connection *conn = [[[ConnectionsDB sharedInstance] connDB] objectAtIndex:[selConn indexOfSelectedItem]]; NSString *origFileName = [conn connName]; NSString *fileName = [origFileName stringByAppendingFormat:@".conf"]; NSString *origPath = @"~/Library/Application Support/Openswan"; NSString *filePath = [origPath stringByAppendingPathComponent:fileName]; NSString *path = [filePath stringByStandardizingPath]; NSFileManager *fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath: path] == YES) { [fileManager removeFileAtPath:path handler:nil]; } */ [GrowlApplicationBridge notifyWithTitle:@"Disconnected" description:@"Connection was closed" notificationName:@"Openswan Growl Notification" iconData:nil priority:0 isSticky:NO clickContext:nil]; } } - (void)updateConnDuration: (NSTimer*)aTimer { NSDate* now = [NSDate date]; [self setConnDuration:[now timeIntervalSinceDate: connTime]]; int hours = (NSInteger)connDuration / 3600; [self setConnDuration:(NSInteger)connDuration % 3600]; int mins = (NSInteger)connDuration / 60; [self setConnDuration:(NSInteger)connDuration % 60]; int secs = (NSInteger)connDuration; [self setConnDurationPrint:[NSString stringWithFormat:@"%d:%d:%d", hours, mins, secs]]; } //Growl - (NSDictionary*)registrationDictionaryForGrowl { NSArray *notifications; notifications = [NSArray arrayWithObject:@"Openswan Growl Notification"]; NSDictionary *dict; dict = [NSDictionary dictionaryWithObjectsAndKeys: notifications, GROWL_NOTIFICATIONS_ALL, notifications, GROWL_NOTIFICATIONS_DEFAULT, nil]; return dict; } int main(int argc, char *argv[]) { OSStatus junk; // Create the AuthorizationRef that we'll use through this application. We ignore // any error from this. A failure from AuthorizationCreate is very unusual, and if it // happens there's no way to recover; Authorization Services just won't work. junk = AuthorizationCreate(NULL, NULL, kAuthorizationFlagDefaults, &gAuth); assert(junk == noErr); assert( (junk == noErr) == (gAuth != NULL) ); // For each of our commands, check to see if a right specification exists and, if not, // create it. // // The last parameter is the name of a ".strings" file that contains the localised prompts // for any custom rights that we use. BASSetDefaultRules( gAuth, kCommandSet, CFBundleGetIdentifier(CFBundleGetMainBundle()), CFSTR("AuthorizationPrompts") ); return NSApplicationMain(argc, (const char **) argv); } #pragma mark writeFile - (void) saveConnToFile { struct starter_config *cfg = NULL; struct starter_conn *new_conn = NULL; err_t perr = NULL; FILE *file = NULL; char *cPath = "../../test/testGUI.cfg"; //Connection *conn = [[[ConnectionsDB sharedInstance] connDB] objectAtIndex:[selConn indexOfSelectedItem]]; //file pathname /* NSString *origFileName = [conn connName]; NSString *fileName = [origFileName stringByAppendingFormat:@".conf"]; NSString *origPath = @"~/Library/Application Support/Openswan"; NSString *filePath = [origPath stringByAppendingPathComponent:fileName]; NSString *path = [filePath stringByStandardizingPath]; char cPath[100]; [path getCString:cPath maxLength:100 encoding:NSMacOSRomanStringEncoding]; */ cfg = (struct starter_config *) malloc(sizeof(struct starter_config)); if (!cfg) printf("can't allocate memory"); memset(cfg, 0, sizeof(struct starter_config)); ipsecconf_default_values(cfg); //NSString to char* //char cConnName[20]; //[[conn connName] getCString:cConnName maxLength:20 encoding:NSMacOSRomanStringEncoding]; new_conn = alloc_add_conn(cfg, "test", &perr); if(new_conn == NULL) printf("%s", perr); cfg->setup.options_set[KBF_NATTRAVERSAL] = 1; cfg->setup.options[KBF_NATTRAVERSAL] = 0; cfg->setup.strings_set[KSF_PROTOSTACK] = 1; cfg->setup.strings[KSF_PROTOSTACK] = strdup("netkey"); new_conn->connalias = strdup("anotheralias"); new_conn->left.rsakey2 = (unsigned char *)"0s23489234ba28934243"; new_conn->left.rsakey1 = (unsigned char *)"0sabcdabcdabcd"; new_conn->desired_state = STARTUP_START; new_conn->options_set[KBF_AUTO] = 1; new_conn->options[KBF_AUTO] = STARTUP_START; new_conn->left.cert = "/my/cert/file"; file = fopen(cPath,"w"); confwrite(cfg, file); fclose(file); } @end