Committing more stuff. Added password encryption with SHA, partially
[MenuTunes.git] / NetworkController.m
1 /*
2  *      MenuTunes
3  *  NetworkController
4  *    Rendezvous network controller
5  *
6  *  Original Author : Kent Sutherland <ksuther@ithinksw.com>
7  *   Responsibility : Kent Sutherland <ksuther@ithinksw.com>
8  *
9  *  Copyright (c) 2003 iThink Software.
10  *  All Rights Reserved
11  *
12  */
13
14 #import "NetworkController.h"
15 #import "MainController.h"
16 #import <ITFoundation/ITDebug.h>
17 #import <ITFoundation/ITFoundation.h>
18 #import <ITMTRemote/ITMTRemote.h>
19
20 static NetworkController *sharedController;
21
22 @implementation NetworkController
23
24 + (NetworkController *)sharedController
25 {
26     return sharedController;
27 }
28
29 - (id)init
30 {
31     if ( (self = [super init]) ) {
32         sharedController = self;
33         browser = [[NSNetServiceBrowser alloc] init];
34         [browser setDelegate:self];
35     }
36     return self;
37 }
38
39 - (void)dealloc
40 {
41     [self disconnect];
42     if (serverOn) {
43         [serverConnection invalidate];
44         [serverConnection release];
45     }
46     [serverPass release];
47     [clientPass release];
48     [clientProxy release];
49     [remoteServices release];
50     [browser release];
51     [service stop];
52     [service release];
53     [super dealloc];
54 }
55
56 - (void)startRemoteServerSearch
57 {
58     [browser searchForServicesOfType:@"_mttp._tcp." inDomain:@""];
59     [remoteServices release];
60     remoteServices = [[NSMutableArray alloc] init];
61 }
62
63 - (void)stopRemoteServerSearch
64 {
65     [browser stop];
66 }
67
68 - (void)setServerStatus:(BOOL)status
69 {
70     if (!serverOn && status) {
71         NSString *name = [[NSUserDefaults standardUserDefaults] stringForKey:@"sharedPlayerName"];
72         unsigned char buffer;
73         NSData *fullPass;
74         //Turn on
75         NS_DURING
76             serverPort = [[NSSocketPort alloc] initWithTCPPort:SERVER_PORT];
77             serverConnection = [[NSConnection alloc] initWithReceivePort:serverPort
78                                                      sendPort:serverPort];
79             [serverConnection setRootObject:[[MainController sharedController] currentRemote]];
80             [serverConnection registerName:@"ITMTPlayerHost"];
81             [serverConnection setDelegate:self];
82         NS_HANDLER
83             [serverConnection release];
84             [serverPort release];
85             ITDebugLog(@"Error starting server!");
86         NS_ENDHANDLER
87         ITDebugLog(@"Started server.");
88         if (!name) {
89             name = @"MenuTunes Shared Player";
90         }
91         service = [[NSNetService alloc] initWithDomain:@""
92                                         type:@"_mttp._tcp."
93                                         name:name
94                                         port:SERVER_PORT];
95         fullPass = [[NSUserDefaults standardUserDefaults] dataForKey:@"sharedPlayerPassword"];
96         if (fullPass) {
97             [fullPass getBytes:&buffer range:NSMakeRange(6, 4)];
98             [serverPass release];
99             serverPass = [[NSData alloc] initWithBytes:&buffer length:strlen(&buffer)];
100         } else {
101             serverPass = nil;
102         }
103         [service publish];
104         serverOn = YES;
105     } else if (serverOn && !status && [serverConnection isValid]) {
106         //Turn off
107         [service stop];
108         [serverConnection registerName:nil];
109         [serverPort invalidate];
110         [serverConnection invalidate];
111         [serverConnection release];
112         ITDebugLog(@"Stopped server.");
113         serverOn = NO;
114     }
115 }
116
117 - (BOOL)connectToHost:(NSString *)host
118 {
119     NSData *fullPass = [[NSUserDefaults standardUserDefaults] dataForKey:@"connectPassword"];
120     unsigned char buffer;
121     ITDebugLog(@"Connecting to host: %@", host);
122     remoteHost = [host copy];
123     if (fullPass) {
124         [fullPass getBytes:&buffer range:NSMakeRange(6, 4)];
125         [clientPass release];
126         clientPass = [[NSData alloc] initWithBytes:&buffer length:strlen(&buffer)];
127     } else {
128         clientPass = nil;
129     }
130     NS_DURING
131         clientPort = [[NSSocketPort alloc] initRemoteWithTCPPort:SERVER_PORT
132                                            host:host];
133         clientConnection = [[NSConnection connectionWithReceivePort:nil sendPort:clientPort] retain];
134         [clientConnection setDelegate:self];
135         [clientConnection setReplyTimeout:5];
136         clientProxy = [[clientConnection rootProxy] retain];
137     NS_HANDLER
138         [clientConnection release];
139         [clientPort release];
140         ITDebugLog(@"Connection to host failed: %@", host);
141         return NO;
142     NS_ENDHANDLER
143     ITDebugLog(@"Connected to host: %@", host);
144     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(disconnect) name:NSConnectionDidDieNotification object:clientConnection];
145     connectedToServer = YES;
146     return YES;
147 }
148
149 - (BOOL)disconnect
150 {
151     ITDebugLog(@"Disconnecting from host.");
152     connectedToServer = NO;
153     [remoteHost release];
154     remoteHost = nil;
155     [[NSNotificationCenter defaultCenter] removeObserver:self];
156     [clientProxy release];
157     [clientConnection invalidate];
158     [clientConnection release];
159     return YES;
160 }
161
162 - (BOOL)checkForServerAtHost:(NSString *)host
163 {
164     NSData *fullPass = [[NSUserDefaults standardUserDefaults] dataForKey:@"connectPassword"];
165     unsigned char buffer;
166     NSConnection *testConnection;
167     NSSocketPort *testPort;
168     NSDistantObject *tempProxy;
169     ITDebugLog(@"Checking for shared remote at %@.", host);
170     if (fullPass) {
171         [fullPass getBytes:&buffer range:NSMakeRange(6, 4)];
172         [clientPass release];
173         clientPass = [[NSData alloc] initWithBytes:&buffer length:strlen(&buffer)];
174     } else {
175         clientPass = nil;
176     }
177     
178     NS_DURING
179         testPort = [[NSSocketPort alloc] initRemoteWithTCPPort:SERVER_PORT
180                                            host:host];
181         testConnection = [[NSConnection connectionWithReceivePort:nil sendPort:testPort] retain];
182         [testConnection setReplyTimeout:2];
183         tempProxy = [testConnection rootProxy];
184         [testConnection setDelegate:self];
185         [tempProxy sharedRemoteName];
186     NS_HANDLER
187         ITDebugLog(@"Connection to host failed: %@", host);
188         [testConnection invalidate];
189         [testConnection release];
190         [testPort release];
191         return NO;
192     NS_ENDHANDLER
193     [testConnection invalidate];
194     [testConnection release];
195     [testPort release];
196     return YES;
197 }
198
199 - (BOOL)isServerOn
200 {
201     return serverOn;
202 }
203
204 - (BOOL)isClientConnected
205 {
206     return clientConnected;
207 }
208
209 - (BOOL)isConnectedToServer
210 {
211     return connectedToServer;
212 }
213
214 - (NSString *)remoteHost
215 {
216     return remoteHost;
217 }
218
219 - (ITMTRemote *)sharedRemote
220 {
221     return (ITMTRemote *)clientProxy;
222 }
223
224 - (NSArray *)remoteServices
225 {
226     return remoteServices;
227 }
228
229 /*- (BOOL)authenticateComponents:(NSArray*)components withData:(NSData *)authenticationData
230 {
231     return YES;
232     if (![[NSUserDefaults standardUserDefaults] boolForKey:@"enableSharingPassword"] || [authenticationData isEqualToData:serverPass]) {
233         return YES;
234     } else {
235         return NO;
236     }
237 }
238
239 - (NSData *)authenticationDataForComponents:(NSArray *)components
240 {
241     return clientPass;
242 }*/
243
244 - (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing
245 {
246     ITDebugLog(@"Found service named %@.", [aNetService name]);
247     [remoteServices addObject:aNetService];
248     [aNetService setDelegate:self];
249     [aNetService resolve];
250     if (!moreComing) {
251         [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTFoundNetService" object:nil];
252     }
253 }
254
255 - (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didRemoveService:(NSNetService*)aNetService moreComing:(BOOL)moreComing
256 {
257     ITDebugLog(@"Removed service named %@.", [aNetService name]);
258     [remoteServices removeObject:aNetService];
259     if (!moreComing) {
260         [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTFoundNetService" object:nil];
261     }
262 }
263
264 - (void)netServiceDidResolveAddress:(NSNetService *)sender
265 {
266     ITDebugLog(@"Resolved service named %@.", [sender name]);
267     NSLog(@"Resolved service named %@.", [sender name]);
268     [[NSNotificationCenter defaultCenter] postNotificationName:@"ITMTFoundNetService" object:nil];
269     [sender stop];
270 }
271
272 - (void)netServiceWillResolve:(NSNetService *)sender
273 {
274     ITDebugLog(@"Resolving service named %@.", [sender name]);
275 }
276
277 - (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict
278 {
279     ITDebugLog(@"Error resolving service %@.", errorDict);
280 }
281
282 @end