From: Kent Sutherland Date: Tue, 28 Oct 2003 03:20:58 +0000 (+0000) Subject: Committing more stuff. Added password encryption with SHA, partially X-Git-Tag: v1.2~45 X-Git-Url: http://git.ithinksw.org/MenuTunes.git/commitdiff_plain/d11efc8d287ca1643e9ac6a7b561cad7cd659bda Committing more stuff. Added password encryption with SHA, partially added password checking. Added checking for servers that quit and reopen. Added more UI stuff. Added more more more more more. It's gonna be HUUUUUUGEEEE!!!! --- diff --git a/English.lproj/Preferences.nib/classes.nib b/English.lproj/Preferences.nib/classes.nib index ccf6333..68f916a 100755 --- a/English.lproj/Preferences.nib/classes.nib +++ b/English.lproj/Preferences.nib/classes.nib @@ -24,6 +24,7 @@ hotKeysTableView = NSTableView; launchAtLoginCheckbox = NSButton; launchPlayerAtLaunchCheckbox = NSButton; + locationTextField = NSTextField; manualView = NSView; menuTableView = CustomMenuTableView; nameCheckbox = NSButton; @@ -33,6 +34,7 @@ selectPlayerBox = NSBox; selectPlayerSheet = NSPanel; selectSharedPlayerButton = NSButton; + selectedPlayerTextField = NSTextField; shareMenuTunesCheckbox = NSButton; sharingTableView = NSTableView; showOnChangeCheckbox = NSButton; diff --git a/English.lproj/Preferences.nib/info.nib b/English.lproj/Preferences.nib/info.nib index 4695b7b..d4a5e32 100755 --- a/English.lproj/Preferences.nib/info.nib +++ b/English.lproj/Preferences.nib/info.nib @@ -19,8 +19,6 @@ IBOpenObjects - 639 - 634 6 IBSystem Version diff --git a/English.lproj/Preferences.nib/keyedobjects.nib b/English.lproj/Preferences.nib/keyedobjects.nib index 9cae2d6..88ffb88 100755 Binary files a/English.lproj/Preferences.nib/keyedobjects.nib and b/English.lproj/Preferences.nib/keyedobjects.nib differ diff --git a/ITMTRemote.h b/ITMTRemote.h index 82da725..91e4413 100755 --- a/ITMTRemote.h +++ b/ITMTRemote.h @@ -139,6 +139,14 @@ typedef enum { */ - (NSImage *)remoteIcon; +/*! + * @method sharedRemoteName + * @abstract Returns the shared remote's name. + * @discussion This title is shown while the user is selecting which shared remote to use. This is for informational purposes only, should not be overridden. + * @result An NSString containing the name of the shared remote. + */ +- (NSString *)sharedRemoteName; + /*! * @method begin * @abstract Sent when the remote should begin operation. diff --git a/ITMTRemote.m b/ITMTRemote.m index 96fecda..950e3d6 100755 --- a/ITMTRemote.m +++ b/ITMTRemote.m @@ -22,6 +22,14 @@ return nil; } +- (NSString *)sharedRemoteName +{ + NSString *name = [[NSUserDefaults standardUserDefaults] stringForKey:@"sharedPlayerName"]; + if (!name) + name = @"MenuTunes Shared Player"; + return name; +} + - (BOOL)begin { return NO; diff --git a/MainController.m b/MainController.m index f47c01b..2f4f820 100755 --- a/MainController.m +++ b/MainController.m @@ -61,8 +61,10 @@ static MainController *sharedController; networkController = [[NetworkController alloc] init]; if ([df boolForKey:@"enableSharing"]) { [self setServerStatus:YES]; - } else if ([df boolForKey:@"useSharedPlayer"] && [df boolForKey:@"alwaysUseSharedPlayer"]) { - [self connectToServer]; + } else if ([df boolForKey:@"useSharedPlayer"]) { + if (![self connectToServer]) { + [NSTimer scheduledTimerWithTimeInterval:45 target:self selector:@selector(checkForRemoteServer:) userInfo:nil repeats:YES]; + } } //Setup for notification of the remote player launching or quitting @@ -942,12 +944,15 @@ static MainController *sharedController; - (BOOL)connectToServer { + ITDebugLog(@"Attempting to connect to shared remote."); //Connect if ([networkController connectToHost:[df stringForKey:@"sharedPlayerHost"]]) { currentRemote = [networkController sharedRemote]; [refreshTimer invalidate]; + ITDebugLog(@"Connection successful."); return YES; } else { + ITDebugLog(@"Connection failed."); currentRemote = [remoteArray objectAtIndex:0]; return NO; } @@ -955,6 +960,7 @@ static MainController *sharedController; - (BOOL)disconnectFromServer { + ITDebugLog(@"Disconnecting from shared remote."); //Disconnect currentRemote = [remoteArray objectAtIndex:0]; [networkController disconnect]; @@ -962,14 +968,47 @@ static MainController *sharedController; return YES; } +- (void)checkForRemoteServer:(NSTimer *)timer +{ + ITDebugLog(@"Checking for remote server."); + if ([networkController checkForServerAtHost:[df stringForKey:@"sharedPlayerHost"]]) { + ITDebugLog(@"Remote server found."); + [timer invalidate]; + [[StatusWindowController sharedController] showReconnectQueryWindow]; + } else { + ITDebugLog(@"Remote server not found."); + } +} + - (void)networkError:(NSException *)exception { ITDebugLog(@"Remote exception thrown: %@: %@", [exception name], [exception reason]); - NSRunAlertPanel(@"Remote MenuTunes Disconnected", @"The MenuTunes server you were connected to stopped responding or quit. MenuTunes will revert back to the local player.", @"OK", nil, nil); + NSLog(@"Remote exception thrown: %@: %@", [exception name], [exception reason]); + NSRunCriticalAlertPanel(@"Remote MenuTunes Disconnected", @"The MenuTunes server you were connected to stopped responding or quit. MenuTunes will revert back to the local player.", @"OK", nil, nil); if ([networkController isConnectedToServer] && [self disconnectFromServer]) { + if ([[exception name] isEqualToString:NSPortTimeoutException]) { + [NSTimer scheduledTimerWithTimeInterval:45 target:self selector:@selector(checkForRemoteServer:) userInfo:nil repeats:YES]; + } } else { - ITDebugLog(@"CRITICAL ERROR DISCONNECTING!"); + ITDebugLog(@"CRITICAL ERROR, DISCONNECTING!"); + } +} + +- (void)reconnect +{ + if (![self connectToServer]) { + [NSTimer scheduledTimerWithTimeInterval:45 target:self selector:@selector(checkForRemoteServer:) userInfo:nil repeats:YES]; } + [[StatusWindow sharedWindow] setLocked:NO]; + [[StatusWindow sharedWindow] vanish:self]; + [[StatusWindow sharedWindow] setIgnoresMouseEvents:YES]; +} + +- (void)cancelReconnect +{ + [[StatusWindow sharedWindow] setLocked:NO]; + [[StatusWindow sharedWindow] vanish:self]; + [[StatusWindow sharedWindow] setIgnoresMouseEvents:YES]; } /*************************************************************************/ diff --git a/NetworkController.h b/NetworkController.h index de3801b..9a4024b 100755 --- a/NetworkController.h +++ b/NetworkController.h @@ -25,7 +25,9 @@ NSConnection *serverConnection, *clientConnection; NSSocketPort *serverPort, *clientPort; + NSString *remoteHost; BOOL serverOn, clientConnected, connectedToServer; + NSData *serverPass, *clientPass; ITMTRemote *clientProxy; } + (NetworkController *)sharedController; @@ -35,10 +37,12 @@ - (void)setServerStatus:(BOOL)status; - (BOOL)connectToHost:(NSString *)host; +- (BOOL)checkForServerAtHost:(NSString *)host; - (BOOL)disconnect; - (BOOL)isServerOn; - (BOOL)isClientConnected; - (BOOL)isConnectedToServer; +- (NSString *)remoteHost; - (ITMTRemote *)sharedRemote; - (NSArray *)remoteServices; diff --git a/NetworkController.m b/NetworkController.m index d6bfca0..fb3976c 100755 --- a/NetworkController.m +++ b/NetworkController.m @@ -43,6 +43,8 @@ static NetworkController *sharedController; [serverConnection invalidate]; [serverConnection release]; } + [serverPass release]; + [clientPass release]; [clientProxy release]; [remoteServices release]; [browser release]; @@ -67,6 +69,8 @@ static NetworkController *sharedController; { if (!serverOn && status) { NSString *name = [[NSUserDefaults standardUserDefaults] stringForKey:@"sharedPlayerName"]; + unsigned char buffer; + NSData *fullPass; //Turn on NS_DURING serverPort = [[NSSocketPort alloc] initWithTCPPort:SERVER_PORT]; @@ -76,6 +80,8 @@ static NetworkController *sharedController; [serverConnection registerName:@"ITMTPlayerHost"]; [serverConnection setDelegate:self]; NS_HANDLER + [serverConnection release]; + [serverPort release]; ITDebugLog(@"Error starting server!"); NS_ENDHANDLER ITDebugLog(@"Started server."); @@ -86,6 +92,14 @@ static NetworkController *sharedController; type:@"_mttp._tcp." name:name port:SERVER_PORT]; + fullPass = [[NSUserDefaults standardUserDefaults] dataForKey:@"sharedPlayerPassword"]; + if (fullPass) { + [fullPass getBytes:&buffer range:NSMakeRange(6, 4)]; + [serverPass release]; + serverPass = [[NSData alloc] initWithBytes:&buffer length:strlen(&buffer)]; + } else { + serverPass = nil; + } [service publish]; serverOn = YES; } else if (serverOn && !status && [serverConnection isValid]) { @@ -102,17 +116,30 @@ static NetworkController *sharedController; - (BOOL)connectToHost:(NSString *)host { + NSData *fullPass = [[NSUserDefaults standardUserDefaults] dataForKey:@"connectPassword"]; + unsigned char buffer; ITDebugLog(@"Connecting to host: %@", host); + remoteHost = [host copy]; + if (fullPass) { + [fullPass getBytes:&buffer range:NSMakeRange(6, 4)]; + [clientPass release]; + clientPass = [[NSData alloc] initWithBytes:&buffer length:strlen(&buffer)]; + } else { + clientPass = nil; + } NS_DURING clientPort = [[NSSocketPort alloc] initRemoteWithTCPPort:SERVER_PORT host:host]; clientConnection = [[NSConnection connectionWithReceivePort:nil sendPort:clientPort] retain]; + [clientConnection setDelegate:self]; + [clientConnection setReplyTimeout:5]; clientProxy = [[clientConnection rootProxy] retain]; NS_HANDLER + [clientConnection release]; + [clientPort release]; ITDebugLog(@"Connection to host failed: %@", host); return NO; NS_ENDHANDLER - [clientConnection setReplyTimeout:5]; ITDebugLog(@"Connected to host: %@", host); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(disconnect) name:NSConnectionDidDieNotification object:clientConnection]; connectedToServer = YES; @@ -123,6 +150,8 @@ static NetworkController *sharedController; { ITDebugLog(@"Disconnecting from host."); connectedToServer = NO; + [remoteHost release]; + remoteHost = nil; [[NSNotificationCenter defaultCenter] removeObserver:self]; [clientProxy release]; [clientConnection invalidate]; @@ -130,6 +159,43 @@ static NetworkController *sharedController; return YES; } +- (BOOL)checkForServerAtHost:(NSString *)host +{ + NSData *fullPass = [[NSUserDefaults standardUserDefaults] dataForKey:@"connectPassword"]; + unsigned char buffer; + NSConnection *testConnection; + NSSocketPort *testPort; + NSDistantObject *tempProxy; + ITDebugLog(@"Checking for shared remote at %@.", host); + if (fullPass) { + [fullPass getBytes:&buffer range:NSMakeRange(6, 4)]; + [clientPass release]; + clientPass = [[NSData alloc] initWithBytes:&buffer length:strlen(&buffer)]; + } else { + clientPass = nil; + } + + NS_DURING + testPort = [[NSSocketPort alloc] initRemoteWithTCPPort:SERVER_PORT + host:host]; + testConnection = [[NSConnection connectionWithReceivePort:nil sendPort:testPort] retain]; + [testConnection setReplyTimeout:2]; + tempProxy = [testConnection rootProxy]; + [testConnection setDelegate:self]; + [tempProxy sharedRemoteName]; + NS_HANDLER + ITDebugLog(@"Connection to host failed: %@", host); + [testConnection invalidate]; + [testConnection release]; + [testPort release]; + return NO; + NS_ENDHANDLER + [testConnection invalidate]; + [testConnection release]; + [testPort release]; + return YES; +} + - (BOOL)isServerOn { return serverOn; @@ -145,6 +211,11 @@ static NetworkController *sharedController; return connectedToServer; } +- (NSString *)remoteHost +{ + return remoteHost; +} + - (ITMTRemote *)sharedRemote { return (ITMTRemote *)clientProxy; @@ -155,6 +226,21 @@ static NetworkController *sharedController; return remoteServices; } +/*- (BOOL)authenticateComponents:(NSArray*)components withData:(NSData *)authenticationData +{ + return YES; + if (![[NSUserDefaults standardUserDefaults] boolForKey:@"enableSharingPassword"] || [authenticationData isEqualToData:serverPass]) { + return YES; + } else { + return NO; + } +} + +- (NSData *)authenticationDataForComponents:(NSArray *)components +{ + return clientPass; +}*/ + - (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing { ITDebugLog(@"Found service named %@.", [aNetService name]); @@ -180,6 +266,7 @@ static NetworkController *sharedController; ITDebugLog(@"Resolved service named %@.", [sender name]); NSLog(@"Resolved service named %@.", [sender name]); [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTFoundNetService" object:nil]; + [sender stop]; } - (void)netServiceWillResolve:(NSNetService *)sender diff --git a/PreferencesController.h b/PreferencesController.h index e8dcb81..394934a 100755 --- a/PreferencesController.h +++ b/PreferencesController.h @@ -27,12 +27,14 @@ IBOutlet NSTableView *hotKeysTableView; IBOutlet NSButton *launchAtLoginCheckbox; IBOutlet NSButton *launchPlayerAtLaunchCheckbox; + IBOutlet NSTextField *locationTextField; IBOutlet NSView *manualView; IBOutlet CustomMenuTableView *menuTableView; IBOutlet NSButton *nameCheckbox; IBOutlet NSTextField *nameTextField; IBOutlet NSTextField *passwordTextField; IBOutlet NSButton *ratingCheckbox; + IBOutlet NSTextField *selectedPlayerTextField; IBOutlet NSBox *selectPlayerBox; IBOutlet NSPanel *selectPlayerSheet; IBOutlet NSButton *selectSharedPlayerButton; diff --git a/PreferencesController.m b/PreferencesController.m index 85370d9..970ba88 100755 --- a/PreferencesController.m +++ b/PreferencesController.m @@ -4,8 +4,10 @@ #import "StatusWindow.h" #import "StatusWindowController.h" #import "CustomMenuTableView.h" -#import "netinet/in.h" -#import "arpa/inet.h" + +#import +#import +#import #import #import @@ -193,7 +195,18 @@ static PreferencesController *prefs = nil; } else if ( [sender tag] == 5020 ) { [df setBool:SENDER_STATE forKey:@"enableSharingPassword"]; } else if ( [sender tag] == 5030 ) { - [df setObject:[sender stringValue] forKey:@"sharedPlayerPassword"]; + //Set the server password + const char *instring = [[sender stringValue] UTF8String]; + const char *password = "password"; + unsigned char result; + NSData *hashedPass, *passwordStringHash; + SHA1(instring, strlen(instring), &result); + hashedPass = [NSData dataWithBytes:&result length:strlen(&result)]; + SHA1(password, strlen(password), &result); + passwordStringHash = [NSData dataWithBytes:&result length:strlen(&result)]; + if (![hashedPass isEqualToData:passwordStringHash]) { + [df setObject:hashedPass forKey:@"sharedPlayerPassword"]; + } } else if ( [sender tag] == 5040 ) { BOOL state = SENDER_STATE; [df setBool:state forKey:@"useSharedPlayer"]; @@ -210,10 +223,9 @@ static PreferencesController *prefs = nil; [controller disconnectFromServer]; } } else if ( [sender tag] == 5050 ) { - if ([sender clickedRow] > -1) { - //Set sharedPlayerHost - //[df setObject:[[[[NetworkController sharedController] remoteServices] objectAtIndex:[sender clickedRow]] objectForKey:@"ip"] forKey:@"sharedPlayerHost"]; - } + //Do nothing on table view click + } else if ( [sender tag] == 5051 ) { + [df setObject:[sender stringValue] forKey:@"sharedPlayerHost"]; } else if ( [sender tag] == 5060 ) { //Show selection sheet [NSApp beginSheet:selectPlayerSheet modalForWindow:window modalDelegate:self didEndSelector:NULL contextInfo:nil]; @@ -225,13 +237,20 @@ static PreferencesController *prefs = nil; frame.size.height = 273; [selectPlayerBox setContentView:zeroConfView]; [selectPlayerSheet setFrame:frame display:YES animate:YES]; - } else if ([selectPlayerBox contentView] != manualView) { + } else if ( ([sender indexOfItem:[sender selectedItem]] == 1) && ([selectPlayerBox contentView] != manualView) ){ NSRect frame = [selectPlayerSheet frame]; frame.origin.y += 58; frame.size.height = 215; + //[window makeFirstResponder:hostTextField]; [selectPlayerBox setContentView:manualView]; [selectPlayerSheet setFrame:frame display:YES animate:YES]; + [hostTextField selectText:nil]; } + } else if ( [sender tag] == 5150 ) { + const char *instring = [[sender stringValue] UTF8String]; + unsigned char result; + SHA1(instring, strlen(instring), &result); + [df setObject:[NSData dataWithBytes:&result length:strlen(&result)] forKey:@"connectPassword"]; } else if ( [sender tag] == 5110 ) { //Cancel [NSApp endSheet:selectPlayerSheet]; @@ -253,10 +272,12 @@ static PreferencesController *prefs = nil; } } - if (![controller connectToServer]) { - NSRunAlertPanel(@"Connection error.", @"The MenuTunes server you attempted to connect to was not responding. MenuTunes will revert back to the local player.", @"OK", nil, nil); - } else { + if ([controller connectToServer]) { [useSharedMenuTunesCheckbox setState:NSOnState]; + [selectedPlayerTextField setStringValue:[[[MainController sharedController] currentRemote] sharedRemoteName]]; + [locationTextField setStringValue:[[NetworkController sharedController] remoteHost]]; + } else { + NSRunAlertPanel(@"Connection error.", @"The MenuTunes server you attempted to connect to was not responding. MenuTunes will revert back to the local player.", @"OK", nil, nil); } } [df synchronize]; @@ -627,6 +648,7 @@ static PreferencesController *prefs = nil; } else if ([df boolForKey:@"useSharedPlayer"]) { [useSharedMenuTunesCheckbox setState:NSOnState]; [shareMenuTunesCheckbox setEnabled:NO]; + [selectSharedPlayerButton setEnabled:YES]; } [[NSNotificationCenter defaultCenter] addObserver:sharingTableView selector:@selector(reloadData) name:@"ITMTFoundNetService" object:nil]; @@ -639,12 +661,20 @@ static PreferencesController *prefs = nil; [selectPlayerBox setContentView:zeroConfView]; [usePasswordCheckbox setState:([df boolForKey:@"enableSharingPassword"] ? NSOnState : NSOffState)]; - if ([df stringForKey:@"sharedPlayerPassword"]) { - [passwordTextField setStringValue:@"*************"]; + if ([df dataForKey:@"sharedPlayerPassword"]) { + [passwordTextField setStringValue:@"password"]; } if ([df stringForKey:@"sharedPlayerHost"]) { [hostTextField setStringValue:[df stringForKey:@"sharedPlayerHost"]]; } + + if ([[NetworkController sharedController] isConnectedToServer]) { + [selectedPlayerTextField setStringValue:[[[MainController sharedController] currentRemote] sharedRemoteName]]; + [locationTextField setStringValue:[[NetworkController sharedController] remoteHost]]; + } else { + [selectedPlayerTextField setStringValue:@"No shared player selected."]; + [locationTextField setStringValue:@"-"]; + } } - (IBAction)changeMenus:(id)sender diff --git a/StatusWindowController.h b/StatusWindowController.h index a6633a8..11d7fe8 100755 --- a/StatusWindowController.h +++ b/StatusWindowController.h @@ -41,6 +41,7 @@ typedef enum { - (void)showRepeatWindowWithMode:(StatusWindowRepeatMode)mode; - (void)showSetupQueryWindow; - (void)showRegistrationQueryWindow; +- (void)showReconnectQueryWindow; - (void)showSongInfoWindowWithSource:(ITMTRemotePlayerSource)source title: (NSString *)title diff --git a/StatusWindowController.m b/StatusWindowController.m index 573aac8..6c8841c 100755 --- a/StatusWindowController.m +++ b/StatusWindowController.m @@ -242,5 +242,20 @@ static StatusWindowController *sharedController; [_window setLocked:YES]; } +- (void)showReconnectQueryWindow +{ + NSString *message = @"The selected shared player is available again.\nWould you like to reconnect to it?."; + + [_window setImage:[NSImage imageNamed:@"Register"]]; + [_window buildDialogWindowWithMessage:message + defaultButton:@"Reconnect" + alternateButton:@"Ignore" + target:[MainController sharedController] + defaultAction:@selector(reconnect) + alternateAction:@selector(cancelReconnect)]; + + [_window appear:self]; + [_window setLocked:YES]; +} @end \ No newline at end of file diff --git a/libValidate.a b/libValidate.a index 83fbaf1..99e5c62 100755 Binary files a/libValidate.a and b/libValidate.a differ