2 * Copyright (c) 2008 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 Copyright 2000-2002, Apple, Inc. All rights reserved.
25 Responsibility: Jeremy Wyld
27 // Original Author: Becky Willrich
28 #include <CoreFoundation/CFStream.h>
29 #include <CoreFoundation/CFNumber.h>
30 #include "CFInternal.h"
31 #include "CFStreamInternal.h"
32 #include "CFStreamPriv.h"
34 #if DEPLOYMENT_TARGET_MACOSX
35 // On Mach these live in CF for historical reasons, even though they are declared in CFNetwork
37 const int kCFStreamErrorDomainSSL
= 3;
38 const int kCFStreamErrorDomainSOCKS
= 5;
40 CONST_STRING_DECL(kCFStreamPropertyShouldCloseNativeSocket
, "kCFStreamPropertyShouldCloseNativeSocket")
41 CONST_STRING_DECL(kCFStreamPropertyAutoErrorOnSystemChange
, "kCFStreamPropertyAutoErrorOnSystemChange");
43 CONST_STRING_DECL(kCFStreamPropertySOCKSProxy
, "kCFStreamPropertySOCKSProxy")
44 CONST_STRING_DECL(kCFStreamPropertySOCKSProxyHost
, "SOCKSProxy")
45 CONST_STRING_DECL(kCFStreamPropertySOCKSProxyPort
, "SOCKSPort")
46 CONST_STRING_DECL(kCFStreamPropertySOCKSVersion
, "kCFStreamPropertySOCKSVersion")
47 CONST_STRING_DECL(kCFStreamSocketSOCKSVersion4
, "kCFStreamSocketSOCKSVersion4")
48 CONST_STRING_DECL(kCFStreamSocketSOCKSVersion5
, "kCFStreamSocketSOCKSVersion5")
49 CONST_STRING_DECL(kCFStreamPropertySOCKSUser
, "kCFStreamPropertySOCKSUser")
50 CONST_STRING_DECL(kCFStreamPropertySOCKSPassword
, "kCFStreamPropertySOCKSPassword")
52 CONST_STRING_DECL(kCFStreamPropertySocketSecurityLevel
, "kCFStreamPropertySocketSecurityLevel");
53 CONST_STRING_DECL(kCFStreamSocketSecurityLevelNone
, "kCFStreamSocketSecurityLevelNone");
54 CONST_STRING_DECL(kCFStreamSocketSecurityLevelSSLv2
, "kCFStreamSocketSecurityLevelSSLv2");
55 CONST_STRING_DECL(kCFStreamSocketSecurityLevelSSLv3
, "kCFStreamSocketSecurityLevelSSLv3");
56 CONST_STRING_DECL(kCFStreamSocketSecurityLevelTLSv1
, "kCFStreamSocketSecurityLevelTLSv1");
57 CONST_STRING_DECL(kCFStreamSocketSecurityLevelNegotiatedSSL
, "kCFStreamSocketSecurityLevelNegotiatedSSL");
61 // These are duplicated in CFNetwork, who actually externs them in its headers
62 CONST_STRING_DECL(kCFStreamPropertySocketSSLContext
, "kCFStreamPropertySocketSSLContext")
63 CONST_STRING_DECL(_kCFStreamPropertySocketSecurityAuthenticatesServerCertificate
, "_kCFStreamPropertySocketSecurityAuthenticatesServerCertificate");
67 void _CFSocketStreamSetAuthenticatesServerCertificateDefault(Boolean shouldAuthenticate
) {
68 CFLog(__kCFLogAssertion
, CFSTR("_CFSocketStreamSetAuthenticatesServerCertificateDefault(): This call has been deprecated. Use SetProperty(_kCFStreamPropertySocketSecurityAuthenticatesServerCertificate, kCFBooleanTrue/False)\n"));
72 /* CF_EXPORT */ Boolean
73 _CFSocketStreamGetAuthenticatesServerCertificateDefault(void) {
74 CFLog(__kCFLogAssertion
, CFSTR("_CFSocketStreamGetAuthenticatesServerCertificateDefault(): This call has been removed as a security risk. Use security properties on individual streams instead.\n"));
80 _CFSocketStreamPairSetAuthenticatesServerCertificate(CFReadStreamRef rStream
, CFWriteStreamRef wStream
, Boolean authenticates
) {
82 CFBooleanRef value
= (!authenticates
? kCFBooleanFalse
: kCFBooleanTrue
);
85 CFReadStreamSetProperty(rStream
, _kCFStreamPropertySocketSecurityAuthenticatesServerCertificate
, value
);
87 CFWriteStreamSetProperty(wStream
, _kCFStreamPropertySocketSecurityAuthenticatesServerCertificate
, value
);
91 // Flags for dyld loading of libraries.
100 void (*_CFSocketStreamCreatePair
)(CFAllocatorRef
, CFStringRef
, UInt32
, CFSocketNativeHandle
, const CFSocketSignature
*, CFReadStreamRef
*, CFWriteStreamRef
*);
101 CFErrorRef (*_CFErrorCreateWithStreamError
)(CFAllocatorRef
, CFStreamError
*);
102 CFStreamError (*_CFStreamErrorFromCFError
)(CFErrorRef
);
103 } CFNetworkSupport
= {
111 #define CFNETWORK_CALL(sym, args) ((CFNetworkSupport.sym)args)
113 #if DEPLOYMENT_TARGET_MACOSX
114 #define CFNETWORK_LOAD_SYM(sym) __CFLookupCFNetworkFunction(#sym)
117 static void initializeCFNetworkSupport(void) {
118 __CFBitSet(CFNetworkSupport
.flags
, kTriedToLoad
);
120 #if DEPLOYMENT_TARGET_MACOSX
121 CFNetworkSupport
._CFSocketStreamCreatePair
= CFNETWORK_LOAD_SYM(_CFSocketStreamCreatePair
);
122 CFNetworkSupport
._CFErrorCreateWithStreamError
= CFNETWORK_LOAD_SYM(_CFErrorCreateWithStreamError
);
123 CFNetworkSupport
._CFStreamErrorFromCFError
= CFNETWORK_LOAD_SYM(_CFStreamErrorFromCFError
);
126 if (!CFNetworkSupport
._CFSocketStreamCreatePair
) CFLog(__kCFLogAssertion
, CFSTR("CoreFoundation: failed to dynamically link symbol _CFSocketStreamCreatePair"));
127 if (!CFNetworkSupport
._CFErrorCreateWithStreamError
) CFLog(__kCFLogAssertion
, CFSTR("CoreFoundation: failed to dynamically link symbol _CFErrorCreateWithStreamError"));
128 if (!CFNetworkSupport
._CFStreamErrorFromCFError
) CFLog(__kCFLogAssertion
, CFSTR("CoreFoundation: failed to dynamically link symbol _CFStreamErrorFromCFError"));
130 __CFBitSet(CFNetworkSupport
.flags
, kInitialized
);
134 createPair(CFAllocatorRef alloc
, CFStringRef host
, UInt32 port
, CFSocketNativeHandle sock
, const CFSocketSignature
* sig
, CFReadStreamRef
*readStream
, CFWriteStreamRef
*writeStream
)
142 __CFSpinLock(&(CFNetworkSupport
.lock
));
143 if (!__CFBitIsSet(CFNetworkSupport
.flags
, kTriedToLoad
)) initializeCFNetworkSupport();
144 __CFSpinUnlock(&(CFNetworkSupport
.lock
));
146 CFNETWORK_CALL(_CFSocketStreamCreatePair
, (alloc
, host
, port
, sock
, sig
, readStream
, writeStream
));
150 extern void CFStreamCreatePairWithSocket(CFAllocatorRef alloc
, CFSocketNativeHandle sock
, CFReadStreamRef
*readStream
, CFWriteStreamRef
*writeStream
) {
151 createPair(alloc
, NULL
, 0, sock
, NULL
, readStream
, writeStream
);
154 extern void CFStreamCreatePairWithSocketToHost(CFAllocatorRef alloc
, CFStringRef host
, UInt32 port
, CFReadStreamRef
*readStream
, CFWriteStreamRef
*writeStream
) {
155 createPair(alloc
, host
, port
, 0, NULL
, readStream
, writeStream
);
158 extern void CFStreamCreatePairWithPeerSocketSignature(CFAllocatorRef alloc
, const CFSocketSignature
* sig
, CFReadStreamRef
*readStream
, CFWriteStreamRef
*writeStream
) {
159 createPair(alloc
, NULL
, 0, 0, sig
, readStream
, writeStream
);
162 __private_extern__ CFStreamError
_CFStreamErrorFromError(CFErrorRef error
) {
163 CFStreamError result
;
166 __CFSpinLock(&(CFNetworkSupport
.lock
));
167 if (!__CFBitIsSet(CFNetworkSupport
.flags
, kTriedToLoad
)) initializeCFNetworkSupport();
168 canUpCall
= (CFNetworkSupport
._CFStreamErrorFromCFError
!= NULL
);
169 __CFSpinUnlock(&(CFNetworkSupport
.lock
));
172 result
= CFNETWORK_CALL(_CFStreamErrorFromCFError
, (error
));
174 CFStringRef domain
= CFErrorGetDomain(error
);
175 if (CFEqual(domain
, kCFErrorDomainPOSIX
)) {
176 result
.domain
= kCFStreamErrorDomainPOSIX
;
177 } else if (CFEqual(domain
, kCFErrorDomainOSStatus
)) {
178 result
.domain
= kCFStreamErrorDomainMacOSStatus
;
179 } else if (CFEqual(domain
, kCFErrorDomainMach
)) {
180 result
.domain
= 11; // kCFStreamErrorDomainMach, but that symbol is in CFNetwork
182 result
.domain
= kCFStreamErrorDomainCustom
;
184 result
.error
= CFErrorGetCode(error
);
189 __private_extern__ CFErrorRef
_CFErrorFromStreamError(CFAllocatorRef alloc
, CFStreamError
*streamError
) {
193 __CFSpinLock(&(CFNetworkSupport
.lock
));
194 if (!__CFBitIsSet(CFNetworkSupport
.flags
, kTriedToLoad
)) initializeCFNetworkSupport();
195 canUpCall
= (CFNetworkSupport
._CFErrorCreateWithStreamError
!= NULL
);
196 __CFSpinUnlock(&(CFNetworkSupport
.lock
));
199 result
= CFNETWORK_CALL(_CFErrorCreateWithStreamError
, (alloc
, streamError
));
201 if (streamError
->domain
== kCFStreamErrorDomainPOSIX
) {
202 return CFErrorCreate(alloc
, kCFErrorDomainPOSIX
, streamError
->error
, NULL
);
203 } else if (streamError
->domain
== kCFStreamErrorDomainMacOSStatus
) {
204 return CFErrorCreate(alloc
, kCFErrorDomainOSStatus
, streamError
->error
, NULL
);
206 CFStringRef key
= CFSTR("CFStreamErrorDomainKey");
207 CFNumberRef value
= CFNumberCreate(alloc
, kCFNumberCFIndexType
, &streamError
->domain
);
208 CFDictionaryRef dict
= CFDictionaryCreate(alloc
, (const void **)(&key
), (const void **)(&value
), 1, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
209 result
= CFErrorCreate(alloc
, CFSTR("BogusCFStreamErrorCompatibilityDomain"), streamError
->error
, dict
);