]> git.saurik.com Git - apple/cf.git/blob - Stream.subproj/CFSocketStream.c
CF-368.28.tar.gz
[apple/cf.git] / Stream.subproj / CFSocketStream.c
1 /*
2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /* CFSocketStream.c
24 Copyright 2000-2002, Apple, Inc. All rights reserved.
25 Responsibility: Jeremy Wyld
26 */
27 // Original Author: Becky Willrich
28
29
30 #include <CoreFoundation/CoreFoundation.h>
31 #include "CFInternal.h"
32 #include "CFStreamPriv.h"
33
34 #if defined(__WIN32__)
35 #include <winsock2.h>
36 #elif defined(__MACH__)
37 #endif
38
39 #if defined(__MACH__)
40 // On Mach these live in CF for historical reasons, even though they are declared in CFNetwork
41
42 const int kCFStreamErrorDomainSSL = 3;
43 const int kCFStreamErrorDomainSOCKS = 5;
44
45 CONST_STRING_DECL(kCFStreamPropertyShouldCloseNativeSocket, "kCFStreamPropertyShouldCloseNativeSocket")
46 CONST_STRING_DECL(kCFStreamPropertyAutoErrorOnSystemChange, "kCFStreamPropertyAutoErrorOnSystemChange");
47
48 CONST_STRING_DECL(kCFStreamPropertySOCKSProxy, "kCFStreamPropertySOCKSProxy")
49 CONST_STRING_DECL(kCFStreamPropertySOCKSProxyHost, "SOCKSProxy")
50 CONST_STRING_DECL(kCFStreamPropertySOCKSProxyPort, "SOCKSPort")
51 CONST_STRING_DECL(kCFStreamPropertySOCKSVersion, "kCFStreamPropertySOCKSVersion")
52 CONST_STRING_DECL(kCFStreamSocketSOCKSVersion4, "kCFStreamSocketSOCKSVersion4")
53 CONST_STRING_DECL(kCFStreamSocketSOCKSVersion5, "kCFStreamSocketSOCKSVersion5")
54 CONST_STRING_DECL(kCFStreamPropertySOCKSUser, "kCFStreamPropertySOCKSUser")
55 CONST_STRING_DECL(kCFStreamPropertySOCKSPassword, "kCFStreamPropertySOCKSPassword")
56
57 CONST_STRING_DECL(kCFStreamPropertySocketSecurityLevel, "kCFStreamPropertySocketSecurityLevel");
58 CONST_STRING_DECL(kCFStreamSocketSecurityLevelNone, "kCFStreamSocketSecurityLevelNone");
59 CONST_STRING_DECL(kCFStreamSocketSecurityLevelSSLv2, "kCFStreamSocketSecurityLevelSSLv2");
60 CONST_STRING_DECL(kCFStreamSocketSecurityLevelSSLv3, "kCFStreamSocketSecurityLevelSSLv3");
61 CONST_STRING_DECL(kCFStreamSocketSecurityLevelTLSv1, "kCFStreamSocketSecurityLevelTLSv1");
62 CONST_STRING_DECL(kCFStreamSocketSecurityLevelNegotiatedSSL, "kCFStreamSocketSecurityLevelNegotiatedSSL");
63 #endif // !__MACH__
64
65 // These are duplicated in CFNetwork, who actually externs them in its headers
66 CONST_STRING_DECL(kCFStreamPropertySocketSSLContext, "kCFStreamPropertySocketSSLContext")
67 CONST_STRING_DECL(_kCFStreamPropertySocketSecurityAuthenticatesServerCertificate, "_kCFStreamPropertySocketSecurityAuthenticatesServerCertificate");
68
69
70 CF_EXPORT
71 void _CFSocketStreamSetAuthenticatesServerCertificateDefault(Boolean shouldAuthenticate) {
72 CFLog(__kCFLogAssertion, CFSTR("_CFSocketStreamSetAuthenticatesServerCertificateDefault(): This call has been deprecated. Use SetProperty(_kCFStreamPropertySocketSecurityAuthenticatesServerCertificate, kCFBooleanTrue/False)\n"));
73 }
74
75
76 /* CF_EXPORT */ Boolean
77 _CFSocketStreamGetAuthenticatesServerCertificateDefault(void) {
78 CFLog(__kCFLogAssertion, CFSTR("_CFSocketStreamGetAuthenticatesServerCertificateDefault(): This call has been removed as a security risk. Use security properties on individual streams instead.\n"));
79 return FALSE;
80 }
81
82
83 /* CF_EXPORT */ void
84 _CFSocketStreamPairSetAuthenticatesServerCertificate(CFReadStreamRef rStream, CFWriteStreamRef wStream, Boolean authenticates) {
85
86 CFBooleanRef value = (!authenticates ? kCFBooleanFalse : kCFBooleanTrue);
87
88 if (rStream)
89 CFReadStreamSetProperty(rStream, _kCFStreamPropertySocketSecurityAuthenticatesServerCertificate, value);
90 else
91 CFWriteStreamSetProperty(wStream, _kCFStreamPropertySocketSecurityAuthenticatesServerCertificate, value);
92 }
93
94
95 // Flags for dyld loading of libraries.
96 enum {
97 kTriedToLoad = 0,
98 kInitialized
99 };
100
101 static struct {
102 CFSpinLock_t lock;
103 UInt32 flags;
104
105 const char* const path;
106 #if defined(__MACH__)
107 #elif defined(__WIN32__)
108 HMODULE image;
109 #endif
110
111 void (*_CFSocketStreamCreatePair)(CFAllocatorRef, CFStringRef, UInt32, CFSocketNativeHandle, const CFSocketSignature*, CFReadStreamRef*, CFWriteStreamRef*);
112 } CFNetworkSupport = {
113 0,
114 0x0,
115 "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CFNetwork.framework/Versions/A/CFNetwork",
116 NULL,
117 NULL
118 };
119
120 #define CFNETWORK_CALL(sym, args) ((CFNetworkSupport.sym)args)
121 #if defined(__MACH__)
122 #define CFNETWORK_LOAD_SYM(sym) \
123 __CFLookupCFNetworkFunction(#sym)
124 #elif defined(__WIN32__)
125 #define CFNETWORK_LOAD_SYM(sym) \
126 (void *)GetProcAddress(CFNetworkSupport.image, #sym)
127 #endif
128
129 static void
130 createPair(CFAllocatorRef alloc, CFStringRef host, UInt32 port, CFSocketNativeHandle sock, const CFSocketSignature* sig, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream)
131 {
132 if (readStream)
133 *readStream = NULL;
134
135 if (writeStream)
136 *writeStream = NULL;
137
138 __CFSpinLock(&(CFNetworkSupport.lock));
139
140 if (!__CFBitIsSet(CFNetworkSupport.flags, kTriedToLoad)) {
141
142 __CFBitSet(CFNetworkSupport.flags, kTriedToLoad);
143
144 #if defined(__MACH__)
145 CFNetworkSupport._CFSocketStreamCreatePair = CFNETWORK_LOAD_SYM(_CFSocketStreamCreatePair);
146
147 #elif defined(__WIN32__)
148
149 // See if we can already find it in our address space. This let's us check without
150 // having to specify a filename.
151 #if defined(DEBUG)
152 CFNetworkSupport.image = GetModuleHandle("CFNetwork_debug.dll");
153 #elif defined(PROFILE)
154 CFNetworkSupport.image = GetModuleHandle("CFNetwork_profile.dll");
155 #endif
156 // In any case, look for the release version
157 if (!CFNetworkSupport.image) {
158 CFNetworkSupport.image = GetModuleHandle("CFNetwork.dll");
159 }
160
161 if (!CFNetworkSupport.image) {
162 // not loaded yet, try to load from the filesystem
163 char path[MAX_PATH+1];
164 #if defined(DEBUG)
165 strcpy(path, _CFDLLPath());
166 strcat(path, "\\CFNetwork_debug.dll");
167 CFNetworkSupport.image = LoadLibrary(path);
168 #elif defined(PROFILE)
169 strcpy(path, _CFDLLPath());
170 strcat(path, "\\CFNetwork_profile.dll");
171 CFNetworkSupport.image = LoadLibrary(path);
172 #endif
173 if (!CFNetworkSupport.image) {
174 strcpy(path, _CFDLLPath());
175 strcat(path, "\\CFNetwork.dll");
176 CFNetworkSupport.image = LoadLibrary(path);
177 }
178 }
179
180 if (!CFNetworkSupport.image)
181 CFLog(__kCFLogAssertion, CFSTR("_CFSocketStreamCreatePair(): failed to dynamically load CFNetwork"));
182 if (CFNetworkSupport.image)
183 CFNetworkSupport._CFSocketStreamCreatePair = CFNETWORK_LOAD_SYM(_CFSocketStreamCreatePair);
184 #else
185 #warning _CFSocketStreamCreatePair unimplemented
186 #endif
187
188 if (!CFNetworkSupport._CFSocketStreamCreatePair)
189 CFLog(__kCFLogAssertion, CFSTR("_CFSocketStreamCreatePair(): failed to dynamically link symbol _CFSocketStreamCreatePair"));
190
191 __CFBitSet(CFNetworkSupport.flags, kInitialized);
192 }
193
194 __CFSpinUnlock(&(CFNetworkSupport.lock));
195
196 CFNETWORK_CALL(_CFSocketStreamCreatePair, (alloc, host, port, sock, sig, readStream, writeStream));
197 }
198
199
200 extern void CFStreamCreatePairWithSocket(CFAllocatorRef alloc, CFSocketNativeHandle sock, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream) {
201 createPair(alloc, NULL, 0, sock, NULL, readStream, writeStream);
202 }
203
204 extern void CFStreamCreatePairWithSocketToHost(CFAllocatorRef alloc, CFStringRef host, UInt32 port, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream) {
205 createPair(alloc, host, port, 0, NULL, readStream, writeStream);
206 }
207
208 extern void CFStreamCreatePairWithPeerSocketSignature(CFAllocatorRef alloc, const CFSocketSignature* sig, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream) {
209 createPair(alloc, NULL, 0, 0, sig, readStream, writeStream);
210 }
211