Committing more stuff. Added password encryption with SHA, partially
authorKent Sutherland <ksuther@ithinksw.com>
Tue, 28 Oct 2003 03:20:58 +0000 (03:20 +0000)
committerKent Sutherland <ksuther@ithinksw.com>
Tue, 28 Oct 2003 03:20:58 +0000 (03:20 +0000)
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!!!!

13 files changed:
English.lproj/Preferences.nib/classes.nib
English.lproj/Preferences.nib/info.nib
English.lproj/Preferences.nib/keyedobjects.nib
ITMTRemote.h
ITMTRemote.m
MainController.m
NetworkController.h
NetworkController.m
PreferencesController.h
PreferencesController.m
StatusWindowController.h
StatusWindowController.m
libValidate.a

index ccf6333..68f916a 100755 (executable)
@@ -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; 
index 4695b7b..d4a5e32 100755 (executable)
@@ -19,8 +19,6 @@
        </array>
        <key>IBOpenObjects</key>
        <array>
-               <integer>639</integer>
-               <integer>634</integer>
                <integer>6</integer>
        </array>
        <key>IBSystem Version</key>
index 9cae2d6..88ffb88 100755 (executable)
Binary files a/English.lproj/Preferences.nib/keyedobjects.nib and b/English.lproj/Preferences.nib/keyedobjects.nib differ
index 82da725..91e4413 100755 (executable)
@@ -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.
index 96fecda..950e3d6 100755 (executable)
     return nil;
 }
 
+- (NSString *)sharedRemoteName
+{
+    NSString *name = [[NSUserDefaults standardUserDefaults] stringForKey:@"sharedPlayerName"];
+    if (!name)
+        name = @"MenuTunes Shared Player";
+    return name;
+}
+
 - (BOOL)begin
 {
     return NO;
index f47c01b..2f4f820 100755 (executable)
@@ -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];
 }
 
 /*************************************************************************/
index de3801b..9a4024b 100755 (executable)
@@ -25,7 +25,9 @@
     
     NSConnection *serverConnection, *clientConnection;
     NSSocketPort *serverPort, *clientPort;
+    NSString *remoteHost;
     BOOL serverOn, clientConnected, connectedToServer;
+    NSData *serverPass, *clientPass;
     ITMTRemote *clientProxy;
 }
 + (NetworkController *)sharedController;
 
 - (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;
index d6bfca0..fb3976c 100755 (executable)
@@ -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
index e8dcb81..394934a 100755 (executable)
     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;
index 85370d9..970ba88 100755 (executable)
@@ -4,8 +4,10 @@
 #import "StatusWindow.h"
 #import "StatusWindowController.h"
 #import "CustomMenuTableView.h"
-#import "netinet/in.h"
-#import "arpa/inet.h"
+
+#import <netinet/in.h>
+#import <arpa/inet.h>
+#import <openssl/sha.h>
 
 #import <ITKit/ITHotKeyCenter.h>
 #import <ITKit/ITKeyCombo.h>
@@ -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
index a6633a8..11d7fe8 100755 (executable)
@@ -41,6 +41,7 @@ typedef enum {
 - (void)showRepeatWindowWithMode:(StatusWindowRepeatMode)mode;
 - (void)showSetupQueryWindow;
 - (void)showRegistrationQueryWindow;
+- (void)showReconnectQueryWindow;
 
 - (void)showSongInfoWindowWithSource:(ITMTRemotePlayerSource)source
                                title:            (NSString *)title
index 573aac8..6c8841c 100755 (executable)
@@ -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
index 83fbaf1..99e5c62 100755 (executable)
Binary files a/libValidate.a and b/libValidate.a differ