]> git.saurik.com Git - apple/cf.git/blame - Stream.subproj/CFSocketStream.c
CF-368.28.tar.gz
[apple/cf.git] / Stream.subproj / CFSocketStream.c
CommitLineData
d8925383
A
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
42const int kCFStreamErrorDomainSSL = 3;
43const int kCFStreamErrorDomainSOCKS = 5;
44
45CONST_STRING_DECL(kCFStreamPropertyShouldCloseNativeSocket, "kCFStreamPropertyShouldCloseNativeSocket")
46CONST_STRING_DECL(kCFStreamPropertyAutoErrorOnSystemChange, "kCFStreamPropertyAutoErrorOnSystemChange");
47
48CONST_STRING_DECL(kCFStreamPropertySOCKSProxy, "kCFStreamPropertySOCKSProxy")
49CONST_STRING_DECL(kCFStreamPropertySOCKSProxyHost, "SOCKSProxy")
50CONST_STRING_DECL(kCFStreamPropertySOCKSProxyPort, "SOCKSPort")
51CONST_STRING_DECL(kCFStreamPropertySOCKSVersion, "kCFStreamPropertySOCKSVersion")
52CONST_STRING_DECL(kCFStreamSocketSOCKSVersion4, "kCFStreamSocketSOCKSVersion4")
53CONST_STRING_DECL(kCFStreamSocketSOCKSVersion5, "kCFStreamSocketSOCKSVersion5")
54CONST_STRING_DECL(kCFStreamPropertySOCKSUser, "kCFStreamPropertySOCKSUser")
55CONST_STRING_DECL(kCFStreamPropertySOCKSPassword, "kCFStreamPropertySOCKSPassword")
56
57CONST_STRING_DECL(kCFStreamPropertySocketSecurityLevel, "kCFStreamPropertySocketSecurityLevel");
58CONST_STRING_DECL(kCFStreamSocketSecurityLevelNone, "kCFStreamSocketSecurityLevelNone");
59CONST_STRING_DECL(kCFStreamSocketSecurityLevelSSLv2, "kCFStreamSocketSecurityLevelSSLv2");
60CONST_STRING_DECL(kCFStreamSocketSecurityLevelSSLv3, "kCFStreamSocketSecurityLevelSSLv3");
61CONST_STRING_DECL(kCFStreamSocketSecurityLevelTLSv1, "kCFStreamSocketSecurityLevelTLSv1");
62CONST_STRING_DECL(kCFStreamSocketSecurityLevelNegotiatedSSL, "kCFStreamSocketSecurityLevelNegotiatedSSL");
63#endif // !__MACH__
64
65// These are duplicated in CFNetwork, who actually externs them in its headers
66CONST_STRING_DECL(kCFStreamPropertySocketSSLContext, "kCFStreamPropertySocketSSLContext")
67CONST_STRING_DECL(_kCFStreamPropertySocketSecurityAuthenticatesServerCertificate, "_kCFStreamPropertySocketSecurityAuthenticatesServerCertificate");
68
69
70CF_EXPORT
71void _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.
96enum {
97 kTriedToLoad = 0,
98 kInitialized
99};
100
101static 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
129static void
130createPair(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
200extern void CFStreamCreatePairWithSocket(CFAllocatorRef alloc, CFSocketNativeHandle sock, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream) {
201 createPair(alloc, NULL, 0, sock, NULL, readStream, writeStream);
202}
203
204extern void CFStreamCreatePairWithSocketToHost(CFAllocatorRef alloc, CFStringRef host, UInt32 port, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream) {
205 createPair(alloc, host, port, 0, NULL, readStream, writeStream);
206}
207
208extern void CFStreamCreatePairWithPeerSocketSignature(CFAllocatorRef alloc, const CFSocketSignature* sig, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream) {
209 createPair(alloc, NULL, 0, 0, sig, readStream, writeStream);
210}
211