-
Notifications
You must be signed in to change notification settings - Fork 72
/
CKFTPOverSSLConnection.m
174 lines (147 loc) · 5.78 KB
/
CKFTPOverSSLConnection.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
//
// FTPOverSSLConnection.m
// FTPConnection
//
// Created by Greg Hulands on 7/12/05.
// Copyright 2005 __MyCompanyName__. All rights reserved.
//
#import "CKFTPOverSSLConnection.h"
@implementation CKFTPOverSSLConnection
+ (void)load // registration of this class
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSDictionary *port = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:990], ACTypeValueKey, ACPortTypeKey, ACTypeKey, nil];
NSDictionary *url = [NSDictionary dictionaryWithObjectsAndKeys:@"ftps://", ACTypeValueKey, ACURLTypeKey, ACTypeKey, nil];
[CKAbstractConnection registerConnectionClass:[CKFTPOverSSLConnection class] forTypes:[NSArray arrayWithObjects:port, url, nil]];
[pool release];
}
+ (NSString *)name
{
return @"FTP over SSL";
}
- (id)initWithURL:(NSURL *)URL
{
if (self = [super initWithURL:URL]) {
_ssl = SSLVersionNegotiated;
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
#pragma mark -
#pragma mark SSL Specific
- (void)setSSLVersion:(SSLVersion)version
{
_ssl = version;
}
- (SSLVersion)sslVersion
{
return _ssl;
}
#pragma mark -
#pragma mark Connection Overrides
- (void)connect
{
[self emptyCommandQueue];
NSHost *host = [NSHost hostWithName:_connectionHost];
if(!host){
//if ([CKAbstractConnection debugEnabled])
NSLog(@"Cannot find the host: %@", _connectionHost);
if (_flags.error)
{
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
LocalizedStringInConnectionKitBundle(@"Host Unavailable", @"Host Unavailable"), NSLocalizedDescriptionKey,
_connectionHost, ConnectionHostKey, nil];
NSError *error = [NSError errorWithDomain:CKConnectionErrorDomain code:EHOSTUNREACH userInfo:userInfo];
[_forwarder connection:self didReceiveError:error];
}
return;
}
/* If the host has multiple names it can screw up the order in the list of name */
if ([[host names] count] > 1) {
#warning Applying KVC Hack
[host setValue:[NSArray arrayWithObject:_connectionHost] forKey:@"names"];
}
int connectionPort = [_connectionPort intValue];
if (0 == connectionPort)
{
connectionPort = 990; // standard FTP over SSL control port
}
[self closeStreams]; // make sure streams are closed before opening/allocating new ones
[NSStream getStreamsToHost:host
port:connectionPort
inputStream:&_receiveStream
outputStream:&_sendStream];
[_receiveStream retain]; // the above objects are created autorelease; we have to retain them
[_sendStream retain];
//set the SSL Version
switch (_ssl) {
case SSLVersion2:
[_receiveStream setProperty:NSStreamSocketSecurityLevelSSLv2 forKey:NSStreamSocketSecurityLevelKey];
[_sendStream setProperty:NSStreamSocketSecurityLevelSSLv2 forKey:NSStreamSocketSecurityLevelKey];
break;
case SSLVersion3:
[_receiveStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];
[_sendStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];
break;
case SSLVersionTLS:
[_receiveStream setProperty:NSStreamSocketSecurityLevelTLSv1 forKey:NSStreamSocketSecurityLevelKey];
[_sendStream setProperty:NSStreamSocketSecurityLevelTLSv1 forKey:NSStreamSocketSecurityLevelKey];
break;
case SSLVersionNegotiated:
[_receiveStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey];
[_sendStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey];
break;
}
if(!_receiveStream && _sendStream){
//if ([CKAbstractConnection debugEnabled])
NSLog(@"Cannot create a stream for the host: %@", _connectionHost);
if (_flags.error)
{
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
LocalizedStringInConnectionKitBundle(@"Stream Unavailable", @"Error creating stream"), NSLocalizedDescriptionKey,
_connectionHost, ConnectionHostKey, nil];
NSError *error = [NSError errorWithDomain:ConnectionErrorDomain code:EHOSTUNREACH userInfo:userInfo];
[_forwarder connection:self didReceiveError:error];
}
return;
}
[self sendPortMessage:CONNECT]; // finish the job -- scheduling in the runloop -- in the background thread
}
- (void)openDataStreamsToHost:(NSHost *)aHost port:(int)aPort
{
[NSStream getStreamsToHost:aHost
port:aPort
inputStream:&_dataReceiveStream
outputStream:&_dataSendStream];
[_dataReceiveStream retain];
[_dataSendStream retain];
//set the SSL Version
switch (_ssl) {
case SSLVersion2:
[_dataReceiveStream setProperty:NSStreamSocketSecurityLevelSSLv2 forKey:NSStreamSocketSecurityLevelKey];
[_dataSendStream setProperty:NSStreamSocketSecurityLevelSSLv2 forKey:NSStreamSocketSecurityLevelKey];
break;
case SSLVersion3:
[_dataReceiveStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];
[_dataSendStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];
break;
case SSLVersionTLS:
[_dataReceiveStream setProperty:NSStreamSocketSecurityLevelTLSv1 forKey:NSStreamSocketSecurityLevelKey];
[_dataSendStream setProperty:NSStreamSocketSecurityLevelTLSv1 forKey:NSStreamSocketSecurityLevelKey];
break;
case SSLVersionNegotiated:
[_dataReceiveStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey];
[_dataSendStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey];
break;
}
[_dataReceiveStream setDelegate:self];
[_dataSendStream setDelegate:self];
[_dataReceiveStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[_dataSendStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[_dataReceiveStream open];
[_dataSendStream open];
}
@end