Work in progress

This commit is contained in:
Lubos Dolezel 2017-03-01 17:39:52 +01:00
commit f0513a8f40
120 changed files with 62655 additions and 0 deletions

View File

@ -0,0 +1 @@
../../src/Headers/CFFTPStream.h

View File

@ -0,0 +1 @@
../../src/Headers/CFHTTPAuthentication.h

View File

@ -0,0 +1 @@
../../src/Headers/CFHTTPMessage.h

View File

@ -0,0 +1 @@
../../src/Headers/CFHTTPStream.h

1
include/CFNetwork/CFHost.h Symbolic link
View File

@ -0,0 +1 @@
../../src/Headers/CFHost.h

View File

@ -0,0 +1 @@
../../src/Headers/CFNetDiagnostics.h

View File

@ -0,0 +1 @@
../../src/Headers/CFNetServices.h

View File

@ -0,0 +1 @@
../../src/Headers/CFNetwork.h

View File

@ -0,0 +1 @@
../../src/Headers/CFNetworkDefs.h

View File

@ -0,0 +1,108 @@
#ifndef _CFNETWORKERRORS_H_
#define _CFNETWORKERRORS_H_
#include <CoreFoundation/CFString.h>
#ifdef __cplusplus
extern "C" {
#endif
extern const CFStringRef kCFErrorDomainCFNetwork;
extern const CFStringRef kCFErrorDomainWinSock;
typedef enum {
kCFHostErrorHostNotFound = 1,
kCFHostErrorUnknown = 2,
kCFSOCKSErrorUnknownClientVersion = 100,
kCFSOCKSErrorUnsupportedServerVersion = 101,
kCFSOCKS4ErrorRequestFailed = 110,
kCFSOCKS4ErrorIdentdFailed = 111,
kCFSOCKS4ErrorIdConflict = 112,
kCFSOCKS4ErrorUnknownStatusCode = 113,
kCFSOCKS5ErrorBadState = 120,
kCFSOCKS5ErrorBadResponseAddr = 121,
kCFSOCKS5ErrorBadCredentials = 122,
kCFSOCKS5ErrorUnsupportedNegotiationMethod = 123,
kCFSOCKS5ErrorNoAcceptableMethod = 124,
kCFFTPErrorUnexpectedStatusCode = 200,
kCFErrorHTTPAuthenticationTypeUnsupported = 300,
kCFErrorHTTPBadCredentials = 301,
kCFErrorHTTPConnectionLost = 302,
kCFErrorHTTPParseFailure = 303,
kCFErrorHTTPRedirectionLoopDetected = 304,
kCFErrorHTTPBadURL = 305,
kCFErrorHTTPProxyConnectionFailure = 306,
kCFErrorHTTPBadProxyCredentials = 307,
kCFErrorPACFileError = 308,
kCFErrorPACFileAuth = 309,
kCFErrorHTTPSProxyConnectionFailure = 310,
kCFURLErrorUnknown = -998,
kCFURLErrorCancelled = -999,
kCFURLErrorBadURL = -1000,
kCFURLErrorTimedOut = -1001,
kCFURLErrorUnsupportedURL = -1002,
kCFURLErrorCannotFindHost = -1003,
kCFURLErrorCannotConnectToHost = -1004,
kCFURLErrorNetworkConnectionLost = -1005,
kCFURLErrorDNSLookupFailed = -1006,
kCFURLErrorHTTPTooManyRedirects = -1007,
kCFURLErrorResourceUnavailable = -1008,
kCFURLErrorNotConnectedToInternet = -1009,
kCFURLErrorRedirectToNonExistentLocation = -1010,
kCFURLErrorBadServerResponse = -1011,
kCFURLErrorUserCancelledAuthentication = -1012,
kCFURLErrorUserAuthenticationRequired = -1013,
kCFURLErrorZeroByteResource = -1014,
kCFURLErrorCannotDecodeRawData = -1015,
kCFURLErrorCannotDecodeContentData = -1016,
kCFURLErrorCannotParseResponse = -1017,
kCFURLErrorInternationalRoamingOff = -1018,
kCFURLErrorCallIsActive = -1019,
kCFURLErrorDataNotAllowed = -1020,
kCFURLErrorRequestBodyStreamExhausted = -1021,
kCFURLErrorFileDoesNotExist = -1100,
kCFURLErrorFileIsDirectory = -1101,
kCFURLErrorNoPermissionsToReadFile = -1102,
kCFURLErrorDataLengthExceedsMaximum = -1103,
kCFURLErrorSecureConnectionFailed = -1200,
kCFURLErrorServerCertificateHasBadDate = -1201,
kCFURLErrorServerCertificateUntrusted = -1202,
kCFURLErrorServerCertificateHasUnknownRoot = -1203,
kCFURLErrorServerCertificateNotYetValid = -1204,
kCFURLErrorClientCertificateRejected = -1205,
kCFURLErrorClientCertificateRequired = -1206,
kCFURLErrorCannotLoadFromNetwork = -2000,
kCFURLErrorCannotCreateFile = -3000,
kCFURLErrorCannotOpenFile = -3001,
kCFURLErrorCannotCloseFile = -3002,
kCFURLErrorCannotWriteToFile = -3003,
kCFURLErrorCannotRemoveFile = -3004,
kCFURLErrorCannotMoveFile = -3005,
kCFURLErrorDownloadDecodingFailedMidStream = -3006,
kCFURLErrorDownloadDecodingFailedToComplete = -3007,
kCFHTTPCookieCannotParseCookieFile = -4000,
kCFNetServiceErrorUnknown = -72000L,
kCFNetServiceErrorCollision = -72001L,
kCFNetServiceErrorNotFound = -72002L,
kCFNetServiceErrorInProgress = -72003L,
kCFNetServiceErrorBadArgument = -72004L,
kCFNetServiceErrorCancel = -72005L,
kCFNetServiceErrorInvalid = -72006L,
kCFNetServiceErrorTimeout = -72007L,
kCFNetServiceErrorDNSServiceFailure = -73000L
} CFNetworkErrors;
extern const CFStringRef kCFURLErrorFailingURLErrorKey;
extern const CFStringRef kCFURLErrorFailingURLStringErrorKey;
extern const CFStringRef kCFGetAddrInfoFailureKey;
extern const CFStringRef kCFSOCKSStatusCodeKey;
extern const CFStringRef kCFSOCKSVersionKey;
extern const CFStringRef kCFSOCKSNegotiationMethodKey;
extern const CFStringRef kCFDNSServiceFailureKey;
extern const CFStringRef kCFFTPStatusCodeKey;
#ifdef __cplusplus
}
#endif
#endif /* _CFNETWORKERRORS_H_ */

View File

@ -0,0 +1,91 @@
#ifndef __CFPROXYSUPPORT__
#define __CFPROXYSUPPORT__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __CFARRAY__
#include <CoreFoundation/CFArray.h>
#endif
#ifndef __CFSTRING__
#include <CoreFoundation/CFString.h>
#endif
#ifndef __CFURL__
#include <CoreFoundation/CFURL.h>
#endif
#ifndef __CFERROR__
#include <CoreFoundation/CFError.h>
#endif
#ifndef __CFRUNLOOP__
#include <CoreFoundation/CFRunLoop.h>
#endif
#ifndef __CFSTREAM__
#include <CoreFoundation/CFStream.h>
#endif
#include <Availability.h>
#if PRAGMA_ONCE
#pragma once
#endif
__BEGIN_DECLS
typedef CALLBACK_API_C( void , CFProxyAutoConfigurationResultCallback )(void *client, CFArrayRef proxyList, CFErrorRef error);
CFN_EXPORT CFDictionaryRef CFNetworkCopySystemProxySettings(void);
CFN_EXPORT CFArrayRef CFNetworkCopyProxiesForURL(CFURLRef url, CFDictionaryRef proxySettings);
CFN_EXPORT CFArrayRef CFNetworkCopyProxiesForAutoConfigurationScript(CFStringRef proxyAutoConfigurationScript, CFURLRef targetURL, CFErrorRef *error);
CFN_EXPORT CFRunLoopSourceRef CFNetworkExecuteProxyAutoConfigurationScript(CFStringRef proxyAutoConfigurationScript, CFURLRef targetURL, CFProxyAutoConfigurationResultCallback cb, CFStreamClientContext *clientContext);
CFN_EXPORT CFRunLoopSourceRef CFNetworkExecuteProxyAutoConfigurationURL(CFURLRef proxyAutoConfigURL, CFURLRef targetURL, CFProxyAutoConfigurationResultCallback cb, CFStreamClientContext *clientContext);
CFN_EXPORT const CFStringRef kCFProxyTypeKey;
CFN_EXPORT const CFStringRef kCFProxyPortNumberKey;
CFN_EXPORT const CFStringRef kCFProxyAutoConfigurationURLKey;
CFN_EXPORT const CFStringRef kCFProxyAutoConfigurationJavaScriptKey;
CFN_EXPORT const CFStringRef kCFProxyUsernameKey;
CFN_EXPORT const CFStringRef kCFProxyPasswordKey;
CFN_EXPORT const CFStringRef kCFProxyHostNameKey;
CFN_EXPORT const CFStringRef kCFProxyTypeNone;
CFN_EXPORT const CFStringRef kCFProxyTypeHTTP;
CFN_EXPORT const CFStringRef kCFProxyTypeHTTPS;
CFN_EXPORT const CFStringRef kCFProxyTypeSOCKS;
CFN_EXPORT const CFStringRef kCFProxyTypeFTP;
CFN_EXPORT const CFStringRef kCFProxyTypeAutoConfigurationURL;
CFN_EXPORT const CFStringRef kCFProxyTypeAutoConfigurationJavaScript;
CFN_EXPORT const CFStringRef kCFProxyAutoConfigurationHTTPResponseKey;
CFN_EXPORT const CFStringRef kCFNetworkProxiesExceptionsList;
CFN_EXPORT const CFStringRef kCFNetworkProxiesExcludeSimpleHostnames;
CFN_EXPORT const CFStringRef kCFNetworkProxiesFTPEnable;
CFN_EXPORT const CFStringRef kCFNetworkProxiesFTPPassive;
CFN_EXPORT const CFStringRef kCFNetworkProxiesFTPPort;
CFN_EXPORT const CFStringRef kCFNetworkProxiesFTPProxy;
CFN_EXPORT const CFStringRef kCFNetworkProxiesGopherEnable;
CFN_EXPORT const CFStringRef kCFNetworkProxiesGopherPort;
CFN_EXPORT const CFStringRef kCFNetworkProxiesGopherProxy;
CFN_EXPORT const CFStringRef kCFNetworkProxiesHTTPEnable;
CFN_EXPORT const CFStringRef kCFNetworkProxiesHTTPPort;
CFN_EXPORT const CFStringRef kCFNetworkProxiesHTTPProxy;
CFN_EXPORT const CFStringRef kCFNetworkProxiesHTTPSEnable;
CFN_EXPORT const CFStringRef kCFNetworkProxiesHTTPSPort;
CFN_EXPORT const CFStringRef kCFNetworkProxiesHTTPSProxy;
CFN_EXPORT const CFStringRef kCFNetworkProxiesRTSPEnable;
CFN_EXPORT const CFStringRef kCFNetworkProxiesRTSPPort;
CFN_EXPORT const CFStringRef kCFNetworkProxiesRTSPProxy;
CFN_EXPORT const CFStringRef kCFNetworkProxiesSOCKSEnable;
CFN_EXPORT const CFStringRef kCFNetworkProxiesSOCKSPort;
CFN_EXPORT const CFStringRef kCFNetworkProxiesSOCKSProxy;
CFN_EXPORT const CFStringRef kCFNetworkProxiesProxyAutoConfigEnable;
CFN_EXPORT const CFStringRef kCFNetworkProxiesProxyAutoConfigURLString;
CFN_EXPORT const CFStringRef kCFNetworkProxiesProxyAutoConfigJavaScript;
CFN_EXPORT const CFStringRef kCFNetworkProxiesProxyAutoDiscoveryEnable;
__END_DECLS
#endif

View File

@ -0,0 +1 @@
../../src/Headers/CFSocketStream.h

View File

@ -0,0 +1,110 @@
#import <os/object.h>
#import <Foundation/NSURLSession.h>
#import <dispatch/dispatch.h>
@class NSOperationQueue, NSString, __NSCFSessionBridge;
__attribute__((visibility("hidden")))
@interface __NSCFURLSessionConfiguration : NSObject
@end
__attribute__((visibility("hidden")))
@interface __NSCFURLSession : NSObject {
__NSCFURLSessionConfiguration *_nsCFConfig;
BOOL _invalid;
NSOperationQueue *_delegateQueue;
id <NSURLSessionDelegate> _delegate;
NSString *_sessionDescription;
dispatch_queue_t _workQueue;
__NSCFSessionBridge *_connectionSession;
__NSCFURLSession *_extraRetain;
NSOperationQueue *_realDelegateQueue;
}
@property(retain) NSOperationQueue *realDelegateQueue; // @synthesize realDelegateQueue=_realDelegateQueue;
@property(retain) __NSCFURLSession *extraRetain; // @synthesize extraRetain=_extraRetain;
@property BOOL invalid; // @synthesize invalid=_invalid;
@property(retain) __NSCFSessionBridge *connectionSession; // @synthesize connectionSession=_connectionSession;
@property(retain) dispatch_queue_t workQueue; // @synthesize workQueue=_workQueue;
@property(copy) NSString *sessionDescription; // @synthesize sessionDescription=_sessionDescription;
@property(readonly) id <NSURLSessionDelegate> delegate; // @synthesize delegate=_delegate;
@property(readonly) NSOperationQueue *delegateQueue; // @synthesize delegateQueue=_delegateQueue;
@property(copy) __NSCFURLSessionConfiguration *configuration;
+ (id)sessionWithConfiguration:(id)configuration delegate:(id)delegate delegateQueue:(id)delegateQueue;
+ (id)sessionWithConfiguration:(id)configuration;
+ (id)sharedSession;
+ (void)_releaseProcessAssertionForSessionIdentifier:(NSString *)identifier;
+ (void)_sendPendingCallbacksForSessionIdentifier:(NSString *)identifier;
// + (const struct ClassicConnectionSession *)defaultClassicConnectionSession;
- (id)initWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(id <NSURLSessionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue;
- (void)delegate_didFinishEventsForBackgroundURLSession;
- (BOOL)can_delegate_didFinishEventsForBackgroundURLSession;
- (id)delegate_downloadTaskNeedsDownloadDirectory:(id)needsDownloadDirectory;
- (BOOL)can_delegate_downloadTaskNeedsDownloadDirectory;
- (void)delegate_downloadTask:(NSURLSessionDataTask *)task didReceiveResponse:(NSURLResponse *)response;
- (BOOL)can_delegate_downloadTask_didReceiveResponse;
- (void)delegate_downloadTask:(NSURLSessionDownloadTask *)task didResumeAtOffset:(int64_t)offset expectedTotalBytes:(int64_t)expectedTotalBytes;
- (BOOL)can_delegate_downloadTask_didResumeAtOffset;
- (void)delegate_downloadTask:(NSURLSessionDownloadTask *)task didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite;
- (BOOL)can_delegate_downloadTask_didWriteData;
- (void)delegate_downloadTask:(NSURLSessionDownloadTask *)task didFinishDownloadingToURL:(NSURL *)location;
- (BOOL)can_delegate_downloadTask_didFinishDownloadingToURL;
- (void)delegate_dataTask:(NSURLSessionTask *)task willCacheResponse:(NSCachedURLResponse *)proposedResponse completionHandler:(void (^)(NSCachedURLResponse *cachedResponse))completionHandler;
- (BOOL)can_delegate_dataTask_willCacheResponse;
- (void)delegate_dataTask:(NSURLSessionDataTask *)task didReceiveData:(NSData *)data;
- (BOOL)can_delegate_dataTask_didReceiveData;
- (void)delegate_dataTask:(NSURLSessionDataTask *)task didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask;
- (BOOL)can_delegate_dataTask_didBecomeDownloadTask;
- (void)delegate_dataTask:(NSURLSessionDataTask *)task didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler;
- (BOOL)can_delegate_dataTask_didReceiveResponse;
- (void)delegate_task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error;
- (BOOL)can_delegate_task_didCompleteWithError;
- (void)delegate_task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend;
- (BOOL)can_delegate_task_didSendBodyData;
- (void)delegate_task:(NSURLSessionTask *)task needNewBodyStream:(void (^)(NSInputStream *bodyStream))completionHandler;
- (BOOL)can_delegate_task_needNewBodyStream;
- (void)delegate_task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler;
- (BOOL)can_delegate_task_didReceiveChallenge;
- (void)delegate_task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest *))completionHandler;
- (BOOL)can_delegate_task_willPerformHTTPRedirection;
- (void)delegate_didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler;
- (BOOL)can_delegate_didReceiveChallenge;
- (void)addDelegateBlock:(void (^)(void))block;
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData;
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;
- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url;
- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request;
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData;
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request;
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request;
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;
- (NSURLSessionDataTask *)dataTaskWithHTTPGetRequest:(NSURL *)url;
- (NSURLSessionDataTask *)dataTaskWithHTTPGetRequest:(NSURL *)url completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;
- (void)getTasksWithCompletionHandler:(id)handler;
- (void)flushWithCompletionHandler:(id)handler;
- (void)resetWithCompletionHandler:(id)handler;
- (void)finishTasksAndInvalidate;
- (void)invalidateAndCancel;
- (void)_onqueue_completeInvalidation:(BOOL)completeInvalidation;
- (void)_onqueue_completeInvalidationFinal;
- (void)_onqueue_withTasks:(id)tasks;
- (BOOL)isBackgroundSession;
- (id)getConfiguration;
- (void)dealloc;
- (id)copyWithZone:(NSZone *)zone;
@end

View File

@ -0,0 +1,42 @@
#ifndef __CFCACHEDURLRESPONSE__
#define __CFCACHEDURLRESPONSE__
#include <CoreFoundation/CFString.h>
#include <CoreFoundation/CFDictionary.h>
#include "CFURLResponse.h"
CF_EXTERN_C_BEGIN
typedef CF_ENUM(CFIndex, CFCachedURLStoragePolicy) {
CFURLCacheStorageAllowed,
CFURLCacheStorageAllowedInMemoryOnly,
CFURLCacheStorageNotAllowed,
};
typedef struct _CFCachedURLResponse* CFCachedURLResponseRef;
CF_EXPORT CFCachedURLResponseRef CFCachedURLResponseCreate(CFAllocatorRef allocator,
CFURLResponseRef response,
CFTypeRef dataOrDataPath,
CFDictionaryRef userInfo,
CFCachedURLStoragePolicy storagePolicy);
CF_EXPORT CFURLResponseRef CFCachedURLResponseGetResponse(CFCachedURLResponseRef);
CF_EXPORT size_t CFCachedURLResponseGetDataSize(CFCachedURLResponseRef);
CF_EXPORT Boolean CFCachedURLResponseLoadData(CFCachedURLResponseRef, CFDataRef* data); // CFRelease() data
CF_EXPORT CFDictionaryRef CFCachedURLResponseGetUserInfo(CFCachedURLResponseRef);
CF_EXPORT CFCachedURLStoragePolicy CFCachedURLResponseGetStoragePolicy(CFCachedURLResponseRef);
// These functions return either 0 or CFCachedURLResponseGetDataSize().
CF_EXPORT size_t _CFCachedURLResponseGetMemorySize(CFCachedURLResponseRef);
CF_EXPORT size_t _CFCachedURLResponseGetDiskSize(CFCachedURLResponseRef);
CF_EXPORT Boolean _CFCachedURLResponseClaimOwnership(CFCachedURLResponseRef, const void* owner);
CF_EXPORT void _CFCachedURLResponseReleaseOwnership(CFCachedURLResponseRef, const void* owner);
CF_EXPORT Boolean _CFCachedURLResponseSetDataPath(CFCachedURLResponseRef, const void* owner, CFStringRef dataPath);
CF_EXPORT Boolean _CFCachedURLResponseEvictFromMemory(CFCachedURLResponseRef, const void* owner);
CF_EXPORT Boolean _CFCachedURLResponseCacheToMemory(CFCachedURLResponseRef, const void* owner);
CF_EXTERN_C_END
#endif // __CFCACHEDURLRESPONSE__

View File

@ -0,0 +1,38 @@
#ifndef CFNetwork_CFHTTPCookie_h
#define CFNetwork_CFHTTPCookie_h
#include <CoreFoundation/CFBase.h>
#include <CoreFoundation/CFDate.h>
#include <CoreFoundation/CFURL.h>
#include <CoreFoundation/CFNumber.h>
#include <CoreFoundation/CFArray.h>
#if PRAGMA_ONCE
#pragma once
#endif
__BEGIN_DECLS
typedef struct __CFHTTPCookie *CFHTTPCookieRef;
CFHTTPCookieRef CFHTTPCookieCreateWithProperties(CFDictionaryRef properties);
CFNumberRef CFHTTPCookieGetVersion(CFHTTPCookieRef cookie);
CFStringRef CFHTTPCookieGetValue(CFHTTPCookieRef cookie);
CFStringRef CFHTTPCookieGetName(CFHTTPCookieRef cookie);
CFStringRef CFHTTPCookieGetDomain(CFHTTPCookieRef cookie);
CFDateRef CFHTTPCookieGetExpirationDate(CFHTTPCookieRef cookie);
CFStringRef CFHTTPCookieGetPath(CFHTTPCookieRef cookie);
CFStringRef CFHTTPCookieGetComment(CFHTTPCookieRef cookie);
CFURLRef CFHTTPCookieGetCommentURL(CFHTTPCookieRef cookie);
CFStringRef CFHTTPCookieGetPath(CFHTTPCookieRef cookie);
CFArrayRef CFHTTPCookieGetPortArray(CFHTTPCookieRef cookie);
Boolean CFHTTPCookieIsHTTPOnly(CFHTTPCookieRef cookie);
Boolean CFHTTPCookieIsSecure(CFHTTPCookieRef cookie);
Boolean CFHTTPCookieIsSessionOnly(CFHTTPCookieRef cookie);
CFDictionaryRef CFHTTPCookieCopyProperties(CFHTTPCookieRef cookie);
CFDictionaryRef CFHTTPCookieCopyRequestHeaderFields(CFArrayRef cookies);
CFArrayRef CFHTTPCookieCreateWithResponseHeaderFields(CFDictionaryRef headerFields, CFURLRef url);
__END_DECLS
#endif

View File

@ -0,0 +1,27 @@
#ifndef CFNetwork_CFHTTPCookieStorage_h
#define CFNetwork_CFHTTPCookieStorage_h
#include <CoreFoundation/CFBase.h>
#include "CFHTTPCookie.h"
#if PRAGMA_ONCE
#pragma once
#endif
__BEGIN_DECLS
typedef struct __CFHTTPCookieStorage *CFHTTPCookieStorageRef;
CFHTTPCookieStorageRef CFHTTPCookieStorageGetDefault();
void CFHTTPCookieStorageDeleteCookie(CFHTTPCookieStorageRef storage, CFHTTPCookieRef cookie);
void CFHTTPCookieStorageSetCookie(CFHTTPCookieStorageRef storage, CFHTTPCookieRef cookie);
void CFHTTPCookieStorageSetCookies(CFHTTPCookieStorageRef storage, CFArrayRef cookies);
CFArrayRef CFHTTPCookieStorageCopyCookies(CFHTTPCookieStorageRef storage);
CFArrayRef CFHTTPCookieStorageCopyCookiesForURL(CFHTTPCookieStorageRef storage, CFURLRef url);
void CFHTTPCookieStorageSetCookiesWithResponseHeaderFields(CFHTTPCookieStorageRef storage, CFDictionaryRef headerFields, CFURLRef url);
CFDictionaryRef CFHTTPCookieStorageCopyRequestHeaderFieldsForURL(CFHTTPCookieStorageRef storage, CFURLRef url);
__END_DECLS
#endif

View File

@ -0,0 +1,26 @@
#ifndef __CFURLAUTHCHALLENGE__
#define __CFURLAUTHCHALLENGE__
#include "CFURLCredential.h"
#include "CFURLProtectionSpace.h"
#include "CFURLResponse.h"
#include <CFNetwork/CFHTTPAuthentication.h>
#if PRAGMA_ONCE
#pragma once
#endif
__BEGIN_DECLS
typedef const struct __CFURLAuthChallenge *CFURLAuthChallengeRef;
CFURLAuthChallengeRef CFURLAuthChallengeCreateWithCFHTTPAuthentication(CFAllocatorRef allocator, CFHTTPAuthenticationRef auth);
CFURLProtectionSpaceRef CFURLAuthChallengeGetProtectionSpace(CFURLAuthChallengeRef challenge);
CFURLCredentialRef CFURLAuthChallengeGetCredential(CFURLAuthChallengeRef challenge);
CFURLResponseRef CFURLAuthChallengeGetResponse(CFURLAuthChallengeRef challenge);
CFIndex CFURLAuthChallengeGetPreviousFailureCount(CFURLAuthChallengeRef challenge);
CFErrorRef CFURLAuthChallengeGetError(CFURLAuthChallengeRef challenge);
__END_DECLS
#endif

View File

@ -0,0 +1,97 @@
#ifndef __CFURLCACHE__
#define __CFURLCACHE__
#include "CFCachedURLResponse.h"
#include "CFURLRequest.h"
#include "CFURLResponse.h"
CF_EXTERN_C_BEGIN
typedef struct _CFURLCache* CFURLCacheRef;
CF_EXPORT
CFTypeID CFURLCacheGetTypeID(void);
CF_EXPORT
void CFURLCacheSetShared(CFURLCacheRef cache);
CF_EXPORT
Boolean CFURLCacheGetShared(CFURLCacheRef* cache); // CFRelease() cache
CF_EXPORT
CFURLCacheRef CFURLCacheCreate(CFAllocatorRef allocator,
size_t memoryCapacity, size_t diskCapacity,
CFStringRef path);
CF_EXPORT
size_t CFURLCacheMemoryCapacity(CFURLCacheRef cache);
CF_EXPORT
size_t _CFURLCacheMemoryCapacity(CFURLCacheRef cache);
CF_EXPORT
void CFURLCacheSetMemoryCapacity(CFURLCacheRef cache, size_t capacity);
CF_EXPORT
void _CFURLCacheSetMemoryCapacity(CFURLCacheRef cache, size_t capacity);
CF_EXPORT
size_t CFURLCacheCurrentMemoryUsage(CFURLCacheRef cache);
CF_EXPORT
size_t _CFURLCacheCurrentMemoryUsage(CFURLCacheRef cache);
CF_EXPORT
size_t CFURLCacheDiskCapacity(CFURLCacheRef cache);
CF_EXPORT
size_t _CFURLCacheDiskCapacity(CFURLCacheRef cache);
CF_EXPORT
void CFURLCacheSetDiskCapacity(CFURLCacheRef cache, size_t capacity);
CF_EXPORT
void _CFURLCacheSetDiskCapacity(CFURLCacheRef cache, size_t capacity);
CF_EXPORT
size_t CFURLCacheCurrentDiskUsage(CFURLCacheRef cache);
CF_EXPORT
size_t _CFURLCacheCurrentDiskUsage(CFURLCacheRef cache);
CF_EXPORT
CFCachedURLResponseRef CFURLCacheCopyResponseForRequest(CFURLCacheRef cache,
CFURLRequestRef request);
CF_EXPORT
CFCachedURLResponseRef _CFURLCacheCopyResponseForRequest(CFURLCacheRef cache,
CFURLRequestRef request);
CF_EXPORT
Boolean CFURLCacheAddCachedResponseForRequest(CFURLCacheRef cache,
CFCachedURLResponseRef cachedResponse,
CFURLRequestRef request);
CF_EXPORT
Boolean _CFURLCacheAddCachedResponseForRequest(CFURLCacheRef cache,
CFCachedURLResponseRef cachedResponse,
CFURLRequestRef request);
CF_EXPORT
void CFURLCacheRemoveCachedResponseForRequest(CFURLCacheRef cache,
CFURLRequestRef request);
CF_EXPORT
void _CFURLCacheRemoveCachedResponseForRequest(CFURLCacheRef cache,
CFURLRequestRef request);
CF_EXPORT
void CFURLCacheRemoveAllCachedResponses(CFURLCacheRef cache);
CF_EXPORT
void _CFURLCacheRemoveAllCachedResponses(CFURLCacheRef cache);
CF_EXPORT
void _CFURLCacheSetNSCache(CFURLCacheRef cache, void *nsCache);
CF_EXTERN_C_END
#endif // __CFURLCACHE__

View File

@ -0,0 +1,67 @@
#ifndef __CFURLCONNECTION__
#define __CFURLCONNECTION__
#include "CFURLAuthChallenge.h"
#include "CFURLProtectionSpace.h"
#include "CFURLRequest.h"
#include "CFURLResponse.h"
#include "CFCachedURLResponse.h"
#if PRAGMA_ONCE
#pragma once
#endif
__BEGIN_DECLS
typedef const struct _CFURLConnection *CFURLConnectionRef;
typedef struct {
CFIndex version;
const void *info;
const void *(*retain)(const void *info);
void (*release)(const void *info);
CFStringRef (*copyDescription)(const void *info);
Boolean (*equal)(const void *info1, const void *info2);
CFHashCode (*hash)(const void *info);
Boolean (*handledByProtocol)(const void *info);
Boolean (*canAuth)(const void *info, CFURLProtectionSpaceRef space);
void (*cancelledAuthChallenge)(const void *info, CFURLAuthChallengeRef challenge);
void (*failed)(const void *info, CFErrorRef error);
void (*receivedAuthChallenge)(const void *info, CFURLAuthChallengeRef challenge);
void (*sendRequestForAuthChallenge)(const void *info, CFURLAuthChallengeRef challenge);
Boolean (*useCredentialStorage)(const void *info);
} CFURLConnectionContext;
typedef struct {
CFIndex version;
const void *info;
const void *(*retain)(const void *info);
void (*release)(const void *info);
CFStringRef (*copyDescription)(const void *info);
Boolean (*equal)(const void *info1, const void *info2);
CFHashCode (*hash)(const void *info);
CFURLRequestRef (*redirect)(const void *info, CFURLRequestRef request, CFURLResponseRef response);
void (*response)(const void *info, CFURLResponseRef response);
void (*data)(const void *info, CFDataRef data);
CFReadStreamRef (*newBodyStream)(const void *info, CFURLRequestRef request);
void (*sent)(const void *info, CFIndex bytesWritten, CFIndex totalBytesWritten, CFIndex totalBytesExpectedToWrite);
void (*finished)(const void *info);
CFCachedURLResponseRef (*cache)(const void *info, CFCachedURLResponseRef cachedResponse);
} CFURLConnectionHandlerContext;
CFURLConnectionRef CFURLConnectionCreate(CFAllocatorRef allocator, CFURLRequestRef request, const CFURLConnectionContext *ctx);
Boolean CFURLConnectionGetResponse(CFURLConnectionRef connection, CFURLResponseRef *response, CFErrorRef *error);
void CFURLConnectionSetHandler(CFURLConnectionRef connection, const CFURLConnectionHandlerContext *handlerContext);
void CFURLConnectionScheduleWithRunLoop(CFURLConnectionRef connection, CFRunLoopRef runLoop, CFStringRef runLoopMode);
void CFURLConnectionUnscheduleFromRunLoop(CFURLConnectionRef connection, CFRunLoopRef runLoop, CFStringRef runLoopMode);
Boolean CFURLConnectionSendSynchronousRequest(CFURLRequestRef request, CFDataRef *data, CFURLResponseRef *response, CFErrorRef *error);
void CFURLConnectionSendAsynchronousRequest(CFURLRequestRef request, void (^)(CFURLResponseRef, CFDataRef, CFErrorRef));
void CFURLConnectionStart(CFURLConnectionRef connection);
void CFURLConnectionCancel(CFURLConnectionRef connection);
__END_DECLS
#endif

View File

@ -0,0 +1,16 @@
#ifndef __CFURLCREDENTIAL__
#define __CFURLCREDENTIAL__
#include <CoreFoundation/CFBase.h>
#if PRAGMA_ONCE
#pragma once
#endif
__BEGIN_DECLS
typedef struct _CFURLCredential *CFURLCredentialRef;
__END_DECLS
#endif

View File

@ -0,0 +1,50 @@
#ifndef __CFURLPROTECTIONSPACE__
#define __CFURLPROTECTIONSPACE__
#include <CoreFoundation/CFArray.h>
#include <CoreFoundation/CFString.h>
#include <Security/Security.h>
#if PRAGMA_ONCE
#pragma once
#endif
typedef CF_ENUM(UInt32, CFURLProtectionSpaceServerType) {
kCFURLProtectionSpaceServerHTTP,
kCFURLProtectionSpaceServerHTTPS,
kCFURLProtectionSpaceServerFTP,
kCFURLProtectionSpaceProxyHTTP,
kCFURLProtectionSpaceProxyHTTPS,
kCFURLProtectionSpaceProxyFTP,
kCFURLProtectionSpaceProxySOCKS,
};
typedef CF_ENUM(UInt32, CFURLProtectionSpaceAuthenticationSchemeType) {
kCFURLProtectionSpaceAuthenticationSchemeDefault,
kCFURLProtectionSpaceAuthenticationSchemeHTTPBasic,
kCFURLProtectionSpaceAuthenticationSchemeHTTPDigest,
kCFURLProtectionSpaceAuthenticationSchemeHTMLForm,
kCFURLProtectionSpaceAuthenticationSchemeNTLM,
kCFURLProtectionSpaceAuthenticationSchemeNegotiate,
kCFURLProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested,
kCFURLProtectionSpaceAuthenticationSchemeClientCertificateRequested,
};
__BEGIN_DECLS
typedef const struct _CFURLProtectionSpace *CFURLProtectionSpaceRef;
CFURLProtectionSpaceRef CFURLProtectionSpaceCreate(CFAllocatorRef allocator, CFStringRef host, CFIndex port, CFURLProtectionSpaceServerType serverType, CFStringRef realm, CFURLProtectionSpaceAuthenticationSchemeType scheme);
CFURLProtectionSpaceAuthenticationSchemeType CFURLProtectionSpaceGetAuthenticationScheme(CFURLProtectionSpaceRef space);
CFArrayRef CFURLProtectionSpaceGetDistinguishedNames(CFURLProtectionSpaceRef space);
CFStringRef CFURLProtectionSpaceGetHost(CFURLProtectionSpaceRef space);
CFIndex CFURLProtectionSpaceGetPort(CFURLProtectionSpaceRef space);
CFStringRef CFURLProtectionSpaceGetRealm(CFURLProtectionSpaceRef space);
SecTrustRef CFURLProtectionSpaceGetServerTrust(CFURLProtectionSpaceRef space);
CFURLProtectionSpaceServerType CFURLProtectionSpaceGetServerType(CFURLProtectionSpaceRef space);
Boolean CFURLProtectionSpaceIsProxy(CFURLProtectionSpaceRef space);
Boolean CFURLProtectionSpaceReceivesCredentialSecurely(CFURLProtectionSpaceRef space);
__END_DECLS
#endif

View File

@ -0,0 +1,91 @@
#ifndef __CFURLREQUEST__
#define __CFURLREQUEST__
#include <CoreFoundation/CFData.h>
#include <CoreFoundation/CFString.h>
#include <CoreFoundation/CFURL.h>
#include <CoreFoundation/CFStream.h>
#include <CoreFoundation/CFArray.h>
#include <CFNetwork/CFHTTPMessage.h>
#include <stdlib.h>
#if PRAGMA_ONCE
#pragma once
#endif
typedef CF_ENUM(UInt32, CFURLRequestCachePolicy) {
CFURLRequestUseProtocolCachePolicy = 0,
CFURLRequestReloadIgnoringLocalCacheData = 1,
CFURLRequestReloadIgnoringLocalAndRemoteCacheData = 4,
CFURLRequestReloadIgnoringCacheData = CFURLRequestReloadIgnoringLocalCacheData,
CFURLRequestReturnCacheDataElseLoad = 2,
CFURLRequestReturnCacheDataDontLoad = 3,
CFURLRequestReloadRevalidatingCacheData = 5,
};
typedef CF_ENUM(UInt32, CFURLRequestNetworkServiceType) {
CFURLNetworkServiceTypeDefault = 0,
CFURLNetworkServiceTypeVoIP = 1,
CFURLNetworkServiceTypeVideo = 2,
CFURLNetworkServiceTypeBackground = 3,
CFURLNetworkServiceTypeVoice = 4
};
__BEGIN_DECLS
typedef const struct _CFURLRequest *CFURLRequestRef;
typedef struct _CFURLRequest *CFMutableURLRequestRef;
CFStringRef CFURLRequestCopyDebugDescription(CFURLRequestRef req);
void __CFURLRequestLog(CFURLRequestRef req);
extern int __CFURLRequestLogging;
CFURLRequestRef CFURLRequestCreate(CFAllocatorRef allocator, CFURLRef url, CFURLRequestCachePolicy policy, CFTimeInterval timeout);
CFURLRequestRef CFURLRequestCreateCopy(CFAllocatorRef allocator, CFURLRequestRef request);
CFURLRef CFURLRequestGetURL(CFURLRequestRef request);
CFURLRequestCachePolicy CFURLRequestGetCachePolicy(CFURLRequestRef request);
CFTimeInterval CFURLRequestGetTimeout(CFURLRequestRef request);
CFURLRef CFURLRequestCopyMainDocumentURL(CFURLRequestRef request);
CFURLRequestNetworkServiceType CFURLRequestGetServiceType(CFURLRequestRef request);
Boolean CFURLRequestAllowsCellularAccess(CFURLRequestRef request);
CFStringRef CFURLRequestCopyHTTPMethod(CFURLRequestRef request);
CFStringRef CFURLRequestCopyHTTPVersion(CFURLRequestRef request);
CFStringRef CFURLRequestCopyValueForHTTPField(CFURLRequestRef request, CFStringRef field);
CFArrayRef CFURLRequestCopyHTTPFields(CFURLRequestRef request);
CFArrayRef CFURLRequestCopyHTTPValues(CFURLRequestRef request);
CFDictionaryRef CFURLRequestCopyAllHTTPFields(CFURLRequestRef request);
CFDataRef CFURLRequestGetHTTPBody(CFURLRequestRef request);
CFReadStreamRef CFURLRequestGetHTTPBodyStream(CFURLRequestRef request);
Boolean CFURLRequestShouldHandleCookes(CFURLRequestRef request);
Boolean CFURLRequestShouldUseHTTPPipelining(CFURLRequestRef request);
CFIndex CFURLRequestFirstFieldIndex(CFURLRequestRef request, CFStringRef key, CFIndex start);
CFStringRef CFURLRequestGetHeaderFieldValue(CFURLRequestRef request, CFStringRef key);
void _CFURLSetMutable(CFURLRequestRef request, Boolean canMutate);
CFMutableURLRequestRef CFURLRequestCreateMutableCopy(CFAllocatorRef allocator, CFURLRequestRef request);
Boolean CFURLRequestSetURL(CFMutableURLRequestRef request, CFURLRef url);
Boolean CFURLRequestSetCachePolicy(CFMutableURLRequestRef request, CFURLRequestCachePolicy policy);
Boolean CFURLRequestSetTimeout(CFMutableURLRequestRef request, CFTimeInterval timeout);
Boolean CFURLRequestSetMainDocumentURL(CFMutableURLRequestRef request, CFURLRef url);
Boolean CFURLRequestSetNetworkServiceType(CFMutableURLRequestRef request, CFURLRequestNetworkServiceType type);
Boolean CFURLRequestSetAllowsCellularAccess(CFMutableURLRequestRef request, Boolean allowed);
Boolean CFURLRequestSetHTTPMethod(CFMutableURLRequestRef request, CFStringRef method);
CFIndex CFURLRequestAddValueForHTTPField(CFMutableURLRequestRef request, CFStringRef field, CFStringRef value);
Boolean CFURLRequestSetHTTPFields(CFMutableURLRequestRef request, CFArrayRef keys, CFArrayRef values);
Boolean CFURLRequestRemoveHTTPField(CFMutableURLRequestRef request, CFIndex index);
Boolean CFURLRequestReplaceHTTPField(CFMutableURLRequestRef request, CFIndex index, CFStringRef value);
Boolean CFURLRequestSetHTTPBody(CFMutableURLRequestRef request, CFDataRef data);
Boolean CFURLRequestSetHTTPBodyStream(CFMutableURLRequestRef request, CFReadStreamRef stream);
Boolean CFURLRequestHandleCookies(CFMutableURLRequestRef request, Boolean enabled);
Boolean CFURLRequestUseHTTPPipelining(CFMutableURLRequestRef request, Boolean enabled);
CFHTTPMessageRef CFHTTPMessageCreateRequestFromURLRequest(CFAllocatorRef allocator, CFURLRequestRef request);
CFURLRequestRef _CFURLRequestCreateFromParcel(CFAllocatorRef allocator, CFPropertyListRef parcel);
CFPropertyListRef _CFURLRequestCreateParcel(CFURLRequestRef request);
__END_DECLS
#endif

View File

@ -0,0 +1,83 @@
#ifndef __CFURLRESPONSE__
#define __CFURLRESPONSE__
#include <CoreFoundation/CFData.h>
#include <CoreFoundation/CFString.h>
#include <CoreFoundation/CFURL.h>
#include <CoreFoundation/CFStream.h>
#include <CoreFoundation/CFArray.h>
#include <CFNetwork/CFHTTPMessage.h>
#include "CFURLRequest.h"
CF_EXTERN_C_BEGIN
typedef enum {
kCFURLResponseSourceNetwork,
kCFURLResponseSourceCache,
#ifdef TODO_CONDITIONAL_CACHE
kCFURLResponseSourceConditionalCache
#endif
} CFURLResponseSource;
typedef const struct _CFURLResponse* CFURLResponseRef;
CF_EXPORT
CFURLResponseRef CFURLResponseCreate(CFAllocatorRef allocator,
CFURLRef url,
CFStringRef mimeType,
int64_t length,
CFStringRef textEncoding);
CF_EXPORT
CFURLResponseRef CFURLResponseCreateWithCFHTTPMessage(CFAllocatorRef allocator,
CFURLRef request,
CFHTTPMessageRef responseMessage);
CF_EXPORT
CFURLResponseRef CFURLResponseCreateCopy(CFAllocatorRef allocator,
CFURLResponseRef response);
CF_EXPORT
CFAbsoluteTime CFURLResponseGetCreationTime(CFURLResponseRef response);
CF_EXPORT
CFURLRef CFURLResponseGetURL(CFURLResponseRef response);
CF_EXPORT
CFStringRef CFURLResponseGetMIMEType(CFURLResponseRef response);
CF_EXPORT
int64_t CFURLResponseGetExpectedContentLength(CFURLResponseRef response);
CF_EXPORT
CFStringRef CFURLResponseGetTextEncodingName(CFURLResponseRef response);
CF_EXPORT
CFStringRef CFURLResponseCopySuggestedFilename(CFURLResponseRef response);
CF_EXPORT
CFIndex CFURLResponseGetStatusCode(CFURLResponseRef response);
CF_EXPORT
CFDictionaryRef CFURLResponseGetHeaderFields(CFURLResponseRef response);
CF_EXPORT
Boolean CFURLResponseIsHTTPResponse(CFURLResponseRef response);
CF_EXPORT
CFURLResponseRef _CFURLResponseCreateFromParcel(CFAllocatorRef allocator, CFPropertyListRef parcel);
CF_EXPORT
CFPropertyListRef _CFURLResponseCreateParcel(CFURLResponseRef response);
CF_EXPORT
Boolean _CFURLResponseIsCacheableWithRequest(CFURLResponseRef response, CFURLRequestRef request);
CF_EXPORT
CFURLResponseSource _CFURLResponseChooseSourceWithRequest(CFURLResponseRef response,
CFURLRequestRef request,
CFAbsoluteTime now);
CF_EXTERN_C_END
#endif // __CFURLRESPONSE__

367
src/APPLE_LICENSE Executable file
View File

@ -0,0 +1,367 @@
APPLE PUBLIC SOURCE LICENSE
Version 2.0 - August 6, 2003
Please read this License carefully before downloading this software.
By downloading or using this software, you are agreeing to be bound by
the terms of this License. If you do not or cannot agree to the terms
of this License, please do not download or use the software.
1. General; Definitions. This License applies to any program or other
work which Apple Computer, Inc. ("Apple") makes publicly available and
which contains a notice placed by Apple identifying such program or
work as "Original Code" and stating that it is subject to the terms of
this Apple Public Source License version 2.0 ("License"). As used in
this License:
1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is
the grantor of rights, (i) claims of patents that are now or hereafter
acquired, owned by or assigned to Apple and (ii) that cover subject
matter contained in the Original Code, but only to the extent
necessary to use, reproduce and/or distribute the Original Code
without infringement; and (b) in the case where You are the grantor of
rights, (i) claims of patents that are now or hereafter acquired,
owned by or assigned to You and (ii) that cover subject matter in Your
Modifications, taken alone or in combination with Original Code.
1.2 "Contributor" means any person or entity that creates or
contributes to the creation of Modifications.
1.3 "Covered Code" means the Original Code, Modifications, the
combination of Original Code and any Modifications, and/or any
respective portions thereof.
1.4 "Externally Deploy" means: (a) to sublicense, distribute or
otherwise make Covered Code available, directly or indirectly, to
anyone other than You; and/or (b) to use Covered Code, alone or as
part of a Larger Work, in any way to provide a service, including but
not limited to delivery of content, through electronic communication
with a client other than You.
1.5 "Larger Work" means a work which combines Covered Code or portions
thereof with code not governed by the terms of this License.
1.6 "Modifications" mean any addition to, deletion from, and/or change
to, the substance and/or structure of the Original Code, any previous
Modifications, the combination of Original Code and any previous
Modifications, and/or any respective portions thereof. When code is
released as a series of files, a Modification is: (a) any addition to
or deletion from the contents of a file containing Covered Code;
and/or (b) any new file or other representation of computer program
statements that contains any part of Covered Code.
1.7 "Original Code" means (a) the Source Code of a program or other
work as originally made available by Apple under this License,
including the Source Code of any updates or upgrades to such programs
or works made available by Apple under this License, and that has been
expressly identified by Apple as such in the header file(s) of such
work; and (b) the object code compiled from such Source Code and
originally made available by Apple under this License.
1.8 "Source Code" means the human readable form of a program or other
work that is suitable for making modifications to it, including all
modules it contains, plus any associated interface definition files,
scripts used to control compilation and installation of an executable
(object code).
1.9 "You" or "Your" means an individual or a legal entity exercising
rights under this License. For legal entities, "You" or "Your"
includes any entity which controls, is controlled by, or is under
common control with, You, where "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of fifty percent
(50%) or more of the outstanding shares or beneficial ownership of
such entity.
2. Permitted Uses; Conditions & Restrictions. Subject to the terms
and conditions of this License, Apple hereby grants You, effective on
the date You accept this License and download the Original Code, a
world-wide, royalty-free, non-exclusive license, to the extent of
Apple's Applicable Patent Rights and copyrights covering the Original
Code, to do the following:
2.1 Unmodified Code. You may use, reproduce, display, perform,
internally distribute within Your organization, and Externally Deploy
verbatim, unmodified copies of the Original Code, for commercial or
non-commercial purposes, provided that in each instance:
(a) You must retain and reproduce in all copies of Original Code the
copyright and other proprietary notices and disclaimers of Apple as
they appear in the Original Code, and keep intact all notices in the
Original Code that refer to this License; and
(b) You must include a copy of this License with every copy of Source
Code of Covered Code and documentation You distribute or Externally
Deploy, and You may not offer or impose any terms on such Source Code
that alter or restrict this License or the recipients' rights
hereunder, except as permitted under Section 6.
2.2 Modified Code. You may modify Covered Code and use, reproduce,
display, perform, internally distribute within Your organization, and
Externally Deploy Your Modifications and Covered Code, for commercial
or non-commercial purposes, provided that in each instance You also
meet all of these conditions:
(a) You must satisfy all the conditions of Section 2.1 with respect to
the Source Code of the Covered Code;
(b) You must duplicate, to the extent it does not already exist, the
notice in Exhibit A in each file of the Source Code of all Your
Modifications, and cause the modified files to carry prominent notices
stating that You changed the files and the date of any change; and
(c) If You Externally Deploy Your Modifications, You must make
Source Code of all Your Externally Deployed Modifications either
available to those to whom You have Externally Deployed Your
Modifications, or publicly available. Source Code of Your Externally
Deployed Modifications must be released under the terms set forth in
this License, including the license grants set forth in Section 3
below, for as long as you Externally Deploy the Covered Code or twelve
(12) months from the date of initial External Deployment, whichever is
longer. You should preferably distribute the Source Code of Your
Externally Deployed Modifications electronically (e.g. download from a
web site).
2.3 Distribution of Executable Versions. In addition, if You
Externally Deploy Covered Code (Original Code and/or Modifications) in
object code, executable form only, You must include a prominent
notice, in the code itself as well as in related documentation,
stating that Source Code of the Covered Code is available under the
terms of this License with information on how and where to obtain such
Source Code.
2.4 Third Party Rights. You expressly acknowledge and agree that
although Apple and each Contributor grants the licenses to their
respective portions of the Covered Code set forth herein, no
assurances are provided by Apple or any Contributor that the Covered
Code does not infringe the patent or other intellectual property
rights of any other entity. Apple and each Contributor disclaim any
liability to You for claims brought by any other entity based on
infringement of intellectual property rights or otherwise. As a
condition to exercising the rights and licenses granted hereunder, You
hereby assume sole responsibility to secure any other intellectual
property rights needed, if any. For example, if a third party patent
license is required to allow You to distribute the Covered Code, it is
Your responsibility to acquire that license before distributing the
Covered Code.
3. Your Grants. In consideration of, and as a condition to, the
licenses granted to You under this License, You hereby grant to any
person or entity receiving or distributing Covered Code under this
License a non-exclusive, royalty-free, perpetual, irrevocable license,
under Your Applicable Patent Rights and other intellectual property
rights (other than patent) owned or controlled by You, to use,
reproduce, display, perform, modify, sublicense, distribute and
Externally Deploy Your Modifications of the same scope and extent as
Apple's licenses under Sections 2.1 and 2.2 above.
4. Larger Works. You may create a Larger Work by combining Covered
Code with other code not governed by the terms of this License and
distribute the Larger Work as a single product. In each such instance,
You must make sure the requirements of this License are fulfilled for
the Covered Code or any portion thereof.
5. Limitations on Patent License. Except as expressly stated in
Section 2, no other patent rights, express or implied, are granted by
Apple herein. Modifications and/or Larger Works may require additional
patent licenses from Apple which Apple may grant in its sole
discretion.
6. Additional Terms. You may choose to offer, and to charge a fee for,
warranty, support, indemnity or liability obligations and/or other
rights consistent with the scope of the license granted herein
("Additional Terms") to one or more recipients of Covered Code.
However, You may do so only on Your own behalf and as Your sole
responsibility, and not on behalf of Apple or any Contributor. You
must obtain the recipient's agreement that any such Additional Terms
are offered by You alone, and You hereby agree to indemnify, defend
and hold Apple and every Contributor harmless for any liability
incurred by or claims asserted against Apple or such Contributor by
reason of any such Additional Terms.
7. Versions of the License. Apple may publish revised and/or new
versions of this License from time to time. Each version will be given
a distinguishing version number. Once Original Code has been published
under a particular version of this License, You may continue to use it
under the terms of that version. You may also choose to use such
Original Code under the terms of any subsequent version of this
License published by Apple. No one other than Apple has the right to
modify the terms applicable to Covered Code created under this
License.
8. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in
part pre-release, untested, or not fully tested works. The Covered
Code may contain errors that could cause failures or loss of data, and
may be incomplete or contain inaccuracies. You expressly acknowledge
and agree that use of the Covered Code, or any portion thereof, is at
Your sole and entire risk. THE COVERED CODE IS PROVIDED "AS IS" AND
WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND AND APPLE AND
APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE
PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM
ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF
MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR
PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD
PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT WARRANT AGAINST
INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE
FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS,
THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR
ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO
ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE
AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY.
You acknowledge that the Covered Code is not intended for use in the
operation of nuclear facilities, aircraft navigation, communication
systems, or air traffic control machines in which case the failure of
the Covered Code could lead to death, personal injury, or severe
physical or environmental damage.
9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO
EVENT SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL,
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING
TO THIS LICENSE OR YOUR USE OR INABILITY TO USE THE COVERED CODE, OR
ANY PORTION THEREOF, WHETHER UNDER A THEORY OF CONTRACT, WARRANTY,
TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, EVEN IF
APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY
REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF
INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY
TO YOU. In no event shall Apple's total liability to You for all
damages (other than as may be required by applicable law) under this
License exceed the amount of fifty dollars ($50.00).
10. Trademarks. This License does not grant any rights to use the
trademarks or trade names "Apple", "Apple Computer", "Mac", "Mac OS",
"QuickTime", "QuickTime Streaming Server" or any other trademarks,
service marks, logos or trade names belonging to Apple (collectively
"Apple Marks") or to any trademark, service mark, logo or trade name
belonging to any Contributor. You agree not to use any Apple Marks in
or as part of the name of products derived from the Original Code or
to endorse or promote products derived from the Original Code other
than as expressly permitted by and in strict compliance at all times
with Apple's third party trademark usage guidelines which are posted
at http://www.apple.com/legal/guidelinesfor3rdparties.html.
11. Ownership. Subject to the licenses granted under this License,
each Contributor retains all rights, title and interest in and to any
Modifications made by such Contributor. Apple retains all rights,
title and interest in and to the Original Code and any Modifications
made by or on behalf of Apple ("Apple Modifications"), and such Apple
Modifications will not be automatically subject to this License. Apple
may, at its sole discretion, choose to license such Apple
Modifications under this License, or on different terms from those
contained in this License or may choose not to license them at all.
12. Termination.
12.1 Termination. This License and the rights granted hereunder will
terminate:
(a) automatically without notice from Apple if You fail to comply with
any term(s) of this License and fail to cure such breach within 30
days of becoming aware of such breach;
(b) immediately in the event of the circumstances described in Section
13.5(b); or
(c) automatically without notice from Apple if You, at any time during
the term of this License, commence an action for patent infringement
against Apple; provided that Apple did not first commence
an action for patent infringement against You in that instance.
12.2 Effect of Termination. Upon termination, You agree to immediately
stop any further use, reproduction, modification, sublicensing and
distribution of the Covered Code. All sublicenses to the Covered Code
which have been properly granted prior to termination shall survive
any termination of this License. Provisions which, by their nature,
should remain in effect beyond the termination of this License shall
survive, including but not limited to Sections 3, 5, 8, 9, 10, 11,
12.2 and 13. No party will be liable to any other for compensation,
indemnity or damages of any sort solely as a result of terminating
this License in accordance with its terms, and termination of this
License will be without prejudice to any other right or remedy of
any party.
13. Miscellaneous.
13.1 Government End Users. The Covered Code is a "commercial item" as
defined in FAR 2.101. Government software and technical data rights in
the Covered Code include only those rights customarily provided to the
public as defined in this License. This customary commercial license
in technical data and software is provided in accordance with FAR
12.211 (Technical Data) and 12.212 (Computer Software) and, for
Department of Defense purchases, DFAR 252.227-7015 (Technical Data --
Commercial Items) and 227.7202-3 (Rights in Commercial Computer
Software or Computer Software Documentation). Accordingly, all U.S.
Government End Users acquire Covered Code with only those rights set
forth herein.
13.2 Relationship of Parties. This License will not be construed as
creating an agency, partnership, joint venture or any other form of
legal association between or among You, Apple or any Contributor, and
You will not represent to the contrary, whether expressly, by
implication, appearance or otherwise.
13.3 Independent Development. Nothing in this License will impair
Apple's right to acquire, license, develop, have others develop for
it, market and/or distribute technology or products that perform the
same or similar functions as, or otherwise compete with,
Modifications, Larger Works, technology or products that You may
develop, produce, market or distribute.
13.4 Waiver; Construction. Failure by Apple or any Contributor to
enforce any provision of this License will not be deemed a waiver of
future enforcement of that or any other provision. Any law or
regulation which provides that the language of a contract shall be
construed against the drafter will not apply to this License.
13.5 Severability. (a) If for any reason a court of competent
jurisdiction finds any provision of this License, or portion thereof,
to be unenforceable, that provision of the License will be enforced to
the maximum extent permissible so as to effect the economic benefits
and intent of the parties, and the remainder of this License will
continue in full force and effect. (b) Notwithstanding the foregoing,
if applicable law prohibits or restricts You from fully and/or
specifically complying with Sections 2 and/or 3 or prevents the
enforceability of either of those Sections, this License will
immediately terminate and You must immediately discontinue any use of
the Covered Code and destroy all copies of it that are in your
possession or control.
13.6 Dispute Resolution. Any litigation or other dispute resolution
between You and Apple relating to this License shall take place in the
Northern District of California, and You and Apple hereby consent to
the personal jurisdiction of, and venue in, the state and federal
courts within that District with respect to this License. The
application of the United Nations Convention on Contracts for the
International Sale of Goods is expressly excluded.
13.7 Entire Agreement; Governing Law. This License constitutes the
entire agreement between the parties with respect to the subject
matter hereof. This License shall be governed by the laws of the
United States and the State of California, except that body of
California law concerning conflicts of law.
Where You are located in the province of Quebec, Canada, the following
clause applies: The parties hereby confirm that they have requested
that this License and all related documents be drafted in English. Les
parties ont exige que le present contrat et tous les documents
connexes soient rediges en anglais.
EXHIBIT A.
"Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
Reserved.
This file contains Original Code and/or Modifications of Original Code
as defined in and that are subject to the Apple Public Source License
Version 2.0 (the 'License'). You may not use this file except in
compliance with the License. Please obtain a copy of the License at
http://www.opensource.apple.com/apsl/ and read it before using this
file.
The Original Code and all software distributed under the License are
distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
Please see the License for the specific language governing rights and
limitations under the License."

413
src/CFNetServices.c Normal file
View File

@ -0,0 +1,413 @@
//
// CFNetServices.c
// CFNetwork
//
// Copyright (c) 2014 Apportable. All rights reserved.
//
#include "CFBase.h"
#include "CFRuntime.h"
#include "CFNetServices.h"
#include "dns_sd.h"
#include <libkern/OSAtomic.h>
/* extern */ const SInt32 kCFStreamErrorDomainNetServices = 10;
/* extern */ const SInt32 kCFStreamErrorDomainMach = 11;
struct __CFNetService {
CFRuntimeBase _base;
CFStringRef domain;
CFStringRef serviceType;
CFStringRef name;
UInt32 port;
CFDataRef txtData;
DNSServiceRef service;
DNSServiceRef resolver;
};
struct __CFNetServiceMonitor {
CFRuntimeBase _base;
};
struct __CFNetServiceBrowser {
CFRuntimeBase _base;
};
static void __CFNetServiceDeallocate(CFTypeRef cf) {
struct __CFNetService *service = (struct __CFNetService *)cf;
if (service->domain != NULL) {
CFRelease(service->domain);
}
if (service->serviceType != NULL) {
CFRelease(service->serviceType);
}
if (service->name != NULL) {
CFRelease(service->name);
}
}
static void __CFNetServiceMonitorDeallocate(CFTypeRef cf) {
struct __CFNetServiceMonitor *monitor = (struct __CFNetServiceMonitor *)cf;
}
static void __CFNetServiceBrowserDeallocate(CFTypeRef cf) {
struct __CFNetServiceBrowser *browser = (struct __CFNetServiceBrowser *)cf;
}
static CFTypeID __kCFNetServiceTypeID = _kCFRuntimeNotATypeID;
static CFTypeID __kCFNetServiceMonitorTypeID = _kCFRuntimeNotATypeID;
static CFTypeID __kCFNetServiceBrowserTypeID = _kCFRuntimeNotATypeID;
static const CFRuntimeClass __CFNetServiceClass = {
_kCFRuntimeScannedObject,
"CFNetService",
NULL,
NULL,
__CFNetServiceDeallocate,
NULL,
NULL,
NULL,
NULL
};
static const CFRuntimeClass __CFNetServiceMonitorClass = {
_kCFRuntimeScannedObject,
"CFNetServiceMonitor",
NULL,
NULL,
__CFNetServiceMonitorDeallocate,
NULL,
NULL,
NULL,
NULL
};
static const CFRuntimeClass __CFNetServiceBrowserClass = {
_kCFRuntimeScannedObject,
"CFNetServiceBrowser",
NULL,
NULL,
__CFNetServiceBrowserDeallocate,
NULL,
NULL,
NULL,
NULL
};
static void __CFNetServiceInitialize(void) {
__kCFNetServiceTypeID = _CFRuntimeRegisterClass(&__CFNetServiceClass);
}
static void __CFNetServiceMonitorInitialize(void) {
__kCFNetServiceMonitorTypeID = _CFRuntimeRegisterClass(&__CFNetServiceMonitorClass);
}
static void __CFNetServiceBrowserInitialize(void) {
__kCFNetServiceBrowserTypeID = _CFRuntimeRegisterClass(&__CFNetServiceBrowserClass);
}
CFTypeID CFNetServiceGetTypeID(void) {
if (__kCFNetServiceTypeID == _kCFRuntimeNotATypeID) {
__CFNetServiceInitialize();
}
return __kCFNetServiceTypeID;
}
CFTypeID CFNetServiceMonitorGetTypeID(void) {
if (__kCFNetServiceMonitorTypeID == _kCFRuntimeNotATypeID) {
__CFNetServiceMonitorInitialize();
}
return __kCFNetServiceMonitorTypeID;
}
CFTypeID CFNetServiceBrowserGetTypeID(void) {
if (__kCFNetServiceBrowserTypeID == _kCFRuntimeNotATypeID) {
__CFNetServiceBrowserInitialize();
}
return __kCFNetServiceBrowserTypeID;
}
static struct __CFNetService *_CFNetServiceCreate(CFAllocatorRef allocator) {
CFIndex size = sizeof(struct __CFNetService) - sizeof(CFRuntimeBase);
return (struct __CFNetService *)_CFRuntimeCreateInstance(allocator, CFNetServiceGetTypeID(), size, NULL);
}
static struct __CFNetServiceMonitor *_CFNetServiceMonitorCreate(CFAllocatorRef allocator) {
CFIndex size = sizeof(struct __CFNetServiceMonitor) - sizeof(CFRuntimeBase);
return (struct __CFNetServiceMonitor *)_CFRuntimeCreateInstance(allocator, CFNetServiceMonitorGetTypeID(), size, NULL);
}
static struct __CFNetServiceBrowser *_CFNetServiceBrowserCreate(CFAllocatorRef allocator) {
CFIndex size = sizeof(struct __CFNetServiceBrowser) - sizeof(CFRuntimeBase);
return (struct __CFNetServiceBrowser *)_CFRuntimeCreateInstance(allocator, CFNetServiceBrowserGetTypeID(), size, NULL);
}
static void (*multicastLock)() = NULL;
static void (*multicastUnlock)() = NULL;
static int32_t lockState = 0;
static void _CFNetServiceMulticastAquire() {
if (OSAtomicIncrement32(&lockState) == 1) {
if (multicastLock != NULL) {
multicastLock();
}
}
}
static void _CFNetServiceMulticastRelinquish() {
if (OSAtomicDecrement32(&lockState) == 0) {
if (multicastUnlock != NULL) {
multicastUnlock();
}
}
}
void _CFNetServiceRegisterMulticastLock(void (*lock)(), void (*unlock)()) {
multicastLock = lock;
multicastUnlock = unlock;
}
CFNetServiceRef CFNetServiceCreate(CFAllocatorRef alloc, CFStringRef domain, CFStringRef serviceType, CFStringRef name, UInt32 port) {
struct __CFNetService *service = _CFNetServiceCreate(alloc);
if (domain != NULL) {
service->domain = CFStringCreateCopy(alloc, domain);
}
if (serviceType != NULL) {
service->serviceType = CFStringCreateCopy(alloc, serviceType);
}
if (name != NULL) {
service->name = CFStringCreateCopy(alloc, name);
}
service->port = port;
return service;
}
CFNetServiceRef CFNetServiceCreateCopy(CFAllocatorRef alloc, CFNetServiceRef service) {
return CFNetServiceCreate(alloc, service->domain, service->serviceType, service->name, service->port);
}
CFStringRef CFNetServiceGetDomain(CFNetServiceRef theService) {
return theService->domain;
}
CFStringRef CFNetServiceGetType(CFNetServiceRef theService) {
return theService->serviceType;
}
CFStringRef CFNetServiceGetName(CFNetServiceRef theService) {
return theService->name;
}
static inline Boolean _CFUTF8String(const char **str, char *buffer, size_t sz, CFStringRef string) {
if (string == NULL) {
*str = NULL;
return true;
}
*str = CFStringGetCStringPtr(string, kCFStringEncodingUTF8);
if (*str == NULL) {
if (CFStringGetCString(string, buffer, sz, kCFStringEncodingUTF8)) {
*str = buffer;
}
if (*str == NULL) {
return false;
}
}
return true;
}
#define BUFSIZE 256
static void _CFNetServiceRegistered(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, void *context) {
CFNetServiceRef theService = (CFNetServiceRef)context;
CFRelease(theService); // balance registration
}
Boolean CFNetServiceRegisterWithOptions(CFNetServiceRef theService, CFOptionFlags options, CFStreamError *error) {
char nameBuffer[BUFSIZE];
char typeBuffer[BUFSIZE];
char domainBuffer[BUFSIZE];
const char *name = NULL;
const char *type = NULL;
const char *domain = NULL;
if (!_CFUTF8String(&name, (char *)nameBuffer, BUFSIZE, theService->name)) {
// TODO: populate error here
return false;
}
if (!_CFUTF8String(&type, (char *)typeBuffer, BUFSIZE, theService->serviceType)) {
// TODO: populate error here
return false;
}
if (!_CFUTF8String(&domain, (char *)domainBuffer, BUFSIZE, theService->domain)) {
// TODO: populate error here
return false;
}
uint16_t txtLen = 0;
const void *txtRecord = NULL;
if (theService->txtData != NULL) {
txtRecord = CFDataGetBytePtr(theService->txtData);
txtLen = CFDataGetLength(theService->txtData);
}
CFRetain(theService); // retain across registration
_CFNetServiceMulticastAquire();
DNSServiceErrorType err = DNSServiceRegister(&theService->service, 0, kDNSServiceInterfaceIndexAny, name, type, domain, NULL,
htons(theService->port), txtLen, txtRecord, &_CFNetServiceRegistered, theService);
return err == kDNSServiceErr_NoError;
}
static void _CFNetServiceResolved(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode,
const char *fullname, const char *hosttarget, uint16_t port, uint16_t txtLen,
const unsigned char *txtRecord, void *context) {
CFNetServiceRef theService = (CFNetServiceRef)context;
CFRelease(theService); // balance resolve
}
Boolean CFNetServiceResolveWithTimeout(CFNetServiceRef theService, CFTimeInterval timeout, CFStreamError *error) {
char nameBuffer[BUFSIZE];
char typeBuffer[BUFSIZE];
char domainBuffer[BUFSIZE];
const char *name = NULL;
const char *type = NULL;
const char *domain = NULL;
if (!_CFUTF8String(&name, (char *)nameBuffer, BUFSIZE, theService->name)) {
// TODO: populate error here
return false;
}
if (!_CFUTF8String(&type, (char *)typeBuffer, BUFSIZE, theService->serviceType)) {
// TODO: populate error here
return false;
}
if (!_CFUTF8String(&domain, (char *)domainBuffer, BUFSIZE, theService->domain)) {
// TODO: populate error here
return false;
}
CFRetain(theService); // retain across resolution
_CFNetServiceMulticastAquire();
DNSServiceErrorType err = DNSServiceResolve(&theService->resolver, 0, kDNSServiceInterfaceIndexAny,
name, type, domain, &_CFNetServiceResolved, theService);
return err == kDNSServiceErr_NoError;
}
void CFNetServiceCancel(CFNetServiceRef theService) {
_CFNetServiceMulticastRelinquish();
}
CFStringRef CFNetServiceGetTargetHost(CFNetServiceRef theService) {
return NULL;
}
SInt32 CFNetServiceGetPortNumber(CFNetServiceRef theService) {
return -1;
}
CFArrayRef CFNetServiceGetAddressing(CFNetServiceRef theService) {
return NULL;
}
CFDataRef CFNetServiceGetTXTData(CFNetServiceRef theService) {
return theService->txtData;
}
Boolean CFNetServiceSetTXTData(CFNetServiceRef theService, CFDataRef txtRecord) {
return false;
}
CFDictionaryRef CFNetServiceCreateDictionaryWithTXTData(CFAllocatorRef alloc, CFDataRef txtRecord) {
return NULL;
}
CFDataRef CFNetServiceCreateTXTDataWithDictionary(CFAllocatorRef alloc, CFDictionaryRef keyValuePairs) {
return NULL;
}
Boolean CFNetServiceSetClient(CFNetServiceRef theService, CFNetServiceClientCallBack clientCB, CFNetServiceClientContext *clientContext) {
return false;
}
void CFNetServiceScheduleWithRunLoop(CFNetServiceRef theService, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
_CFNetServiceMulticastAquire();
}
void CFNetServiceUnscheduleFromRunLoop(CFNetServiceRef theService, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
_CFNetServiceMulticastRelinquish();
}
CFNetServiceMonitorRef CFNetServiceMonitorCreate(CFAllocatorRef alloc, CFNetServiceRef theService, CFNetServiceMonitorClientCallBack clientCB, CFNetServiceClientContext *clientContext) {
return NULL;
}
void CFNetServiceMonitorInvalidate(CFNetServiceMonitorRef monitor) {
}
Boolean CFNetServiceMonitorStart(CFNetServiceMonitorRef monitor, CFNetServiceMonitorType recordType, CFStreamError *error) {
_CFNetServiceMulticastAquire();
return false;
}
void CFNetServiceMonitorStop(CFNetServiceMonitorRef monitor, CFStreamError *error) {
_CFNetServiceMulticastRelinquish();
}
void CFNetServiceMonitorScheduleWithRunLoop(CFNetServiceMonitorRef monitor, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
_CFNetServiceMulticastAquire();
}
void CFNetServiceMonitorUnscheduleFromRunLoop(CFNetServiceMonitorRef monitor, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
_CFNetServiceMulticastRelinquish();
}
CFNetServiceBrowserRef CFNetServiceBrowserCreate(CFAllocatorRef alloc, CFNetServiceBrowserClientCallBack clientCB, CFNetServiceClientContext *clientContext) {
return NULL;
}
void CFNetServiceBrowserInvalidate(CFNetServiceBrowserRef browser) {
}
Boolean CFNetServiceBrowserSearchForDomains(CFNetServiceBrowserRef browser, Boolean registrationDomains, CFStreamError *error) {
_CFNetServiceMulticastAquire();
return false;
}
Boolean CFNetServiceBrowserSearchForServices(CFNetServiceBrowserRef browser, CFStringRef domain, CFStringRef serviceType, CFStreamError *error) {
_CFNetServiceMulticastAquire();
return false;
}
void CFNetServiceBrowserStopSearch(CFNetServiceBrowserRef browser, CFStreamError *error) {
_CFNetServiceMulticastRelinquish();
}
void CFNetServiceBrowserScheduleWithRunLoop(CFNetServiceBrowserRef browser, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
_CFNetServiceMulticastAquire();
}
void CFNetServiceBrowserUnscheduleFromRunLoop(CFNetServiceBrowserRef browser, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
_CFNetServiceMulticastRelinquish();
}
Boolean CFNetServiceRegister(CFNetServiceRef theService, CFStreamError *error) {
return false;
}
Boolean CFNetServiceResolve(CFNetServiceRef theService, CFStreamError *error) {
return false;
}
CFStringRef CFNetServiceGetProtocolSpecificInformation(CFNetServiceRef theService) {
return NULL;
}
void CFNetServiceSetProtocolSpecificInformation(CFNetServiceRef theService, CFStringRef theInfo) {
}

1
src/CFNetwork Symbolic link
View File

@ -0,0 +1 @@
.

710
src/CFNetwork.c Normal file
View File

@ -0,0 +1,710 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/* Repository for initialization routine and any useful utilities that need to be added */
#include <CoreFoundation/CoreFoundation.h>
#include "CFPriv.h"
#include "CFStreamPriv.h"
#include "CFNetworkPriv.h"
#include "CFNetworkInternal.h"
#include "CFHTTPInternal.h"
#include <sys/stat.h>
#include <string.h> // For strcat
#include <stdlib.h> // for getenv
#if defined(__MACH__)
#include <mach-o/dyld.h>
#include <SystemConfiguration/SystemConfiguration.h>
#endif
#include <sys/types.h>
#if defined(__WIN32__)
#include <winsock2.h>
#include <ws2tcpip.h> // for ipv6
#include <wininet.h> // for InternetTimeToSystemTime
// WinHTTP has the same function, but it has more OS/SP constraints
#include <objbase.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#endif
const CFStringRef kCFErrorDomainCFNetwork = CFSTR("com.apple.cfnetwork");
const CFStringRef kCFErrorDomainWinSock = CFSTR("com.windows.sock");
#if defined(__MACH__)
/* extern*/ void*
__CFNetworkLoadFramework(const char* const framework_path) {
// OS 10.3 change to NSAddImage options here:
// a) Use NSADDIMAGE_OPTION_WITH_SEARCHING to support setting common DYLD_ environment variables
// including DYLD_IMAGE_SUFFIX and DYLD_LIBRARY_PATH.
// b) Use NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME to fix a nasty problem where two copies of
// a given framework are loaded into the same address space (See bug # 3060641).
return ((void*)NSAddImage(framework_path, NSADDIMAGE_OPTION_WITH_SEARCHING | NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME));
}
#endif
#if defined(__WIN32__)
typedef WSAAPI int (*getnameinfo_funcPtr)(const struct sockaddr*, socklen_t, char*, DWORD, char*, DWORD, int);
WINBOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID pReserved);
#else
typedef int (*getnameinfo_funcPtr)(const struct sockaddr *sa, socklen_t salen, char *node, socklen_t nodelen, char *service, socklen_t servicelen, int flags);
#endif
/* extern */ UInt8*
_CFStringGetOrCreateCString(CFAllocatorRef allocator, CFStringRef string, UInt8* buffer, CFIndex* bufferLength, CFStringEncoding encoding) {
CFIndex extra = 0;
if (!bufferLength)
bufferLength = &extra;
assert(string);
if (buffer && *bufferLength && CFStringGetCString(string, (char*)buffer, *bufferLength, encoding))
*bufferLength = strlen((const char*)buffer);
else {
UInt8* saved = buffer;
CFRange range = CFRangeMake(0, CFStringGetLength(string));
CFStringGetBytes(string, range, encoding, 0, FALSE, NULL, 0, bufferLength);
buffer = (UInt8*)CFAllocatorAllocate(allocator, *bufferLength + 1, 0);
if (buffer) {
*bufferLength = CFStringGetBytes(string, range, encoding, 0, FALSE, buffer, *bufferLength, NULL);
buffer[*bufferLength] = '\0';
*bufferLength = strlen((const char*)buffer);
}
else {
*bufferLength = 0;
buffer = saved;
if (buffer)
buffer[*bufferLength] = '\0';
}
}
return buffer;
}
/* extern */ CFStringRef
_CFNetworkCFStringCreateWithCFDataAddress(CFAllocatorRef alloc, CFDataRef addr) {
getnameinfo_funcPtr getnameinfo_func = NULL;
struct sockaddr* sa = (struct sockaddr*)CFDataGetBytePtr(addr);
CFIndex salen = CFDataGetLength(addr);
#if defined(__WIN32__)
// getnameinfo doesn't exist on Win2K, so we must look it up dynamically
static CFSpinLock_t lock = 0;
static Boolean beenHere = FALSE;
static getnameinfo_funcPtr getnameinfo_funcCache = NULL;
__CFSpinLock(&lock);
if (!beenHere) {
HMODULE module;
beenHere = TRUE;
module = GetModuleHandle("ws2_32");
if (module != NULL) {
getnameinfo_funcCache = (getnameinfo_funcPtr)GetProcAddress(module, "getnameinfo");
}
}
__CFSpinUnlock(&lock);
getnameinfo_func = getnameinfo_funcCache;
#else
getnameinfo_func = (getnameinfo_funcPtr)&getnameinfo;
#endif
CFStringRef name = NULL;
if (getnameinfo_func) {
char buffer[NI_MAXHOST];
if ((getnameinfo_func)(sa, salen, buffer, sizeof(buffer), NULL, 0, NI_NUMERICHOST) == 0) {
name = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingASCII);
}
} else {
if (sa->sa_family == AF_INET) {
char *cStr = inet_ntoa(((struct sockaddr_in*)sa)->sin_addr);
if (cStr)
name = CFStringCreateWithCString(NULL, cStr, kCFStringEncodingASCII);
}
}
return name;
}
#if 0
/*
-=-=- RFC-1123 -=-=-
5.2.14 RFC-822 Date and Time Specification: RFC-822 Section 5
The syntax for the date is hereby changed to:
date = 1*2DIGIT month 2*4DIGIT
All mail software SHOULD use 4-digit years in dates, to ease
the transition to the next century.
There is a strong trend towards the use of numeric timezone
indicators, and implementations SHOULD use numeric timezones
instead of timezone names. However, all implementations MUST
accept either notation. If timezone names are used, they MUST
be exactly as defined in RFC-822.
The military time zones are specified incorrectly in RFC-822:
they count the wrong way from UT (the signs are reversed). As
a result, military time zones in RFC-822 headers carry no
information.
Finally, note that there is a typo in the definition of "zone"
in the syntax summary of appendix D; the correct definition
occurs in Section 3 of RFC-822.
-=-=- RFC-822 -=-=-
5. DATE AND TIME SPECIFICATION
5.1. SYNTAX
date-time = [ day "," ] date time ; dd mm yy
; hh:mm:ss zzz
day = "Mon" / "Tue" / "Wed" / "Thu"
/ "Fri" / "Sat" / "Sun"
date = 1*2DIGIT month 2DIGIT ; day month year
; e.g. 20 Jun 82
month = "Jan" / "Feb" / "Mar" / "Apr"
/ "May" / "Jun" / "Jul" / "Aug"
/ "Sep" / "Oct" / "Nov" / "Dec"
time = hour zone ; ANSI and Military
hour = 2DIGIT ":" 2DIGIT [":" 2DIGIT]
; 00:00:00 - 23:59:59
zone = "UT" / "GMT" ; Universal Time
; North American : UT
/ "EST" / "EDT" ; Eastern: - 5/ - 4
/ "CST" / "CDT" ; Central: - 6/ - 5
/ "MST" / "MDT" ; Mountain: - 7/ - 6
/ "PST" / "PDT" ; Pacific: - 8/ - 7
/ 1ALPHA ; Military: Z = UT;
; A:-1; (J not used)
; M:-12; N:+1; Y:+12
/ ( ("+" / "-") 4DIGIT ) ; Local differential
; hours+min. (HHMM)
5.2. SEMANTICS
If included, day-of-week must be the day implied by the date
specification.
Time zone may be indicated in several ways. "UT" is Univer-
sal Time (formerly called "Greenwich Mean Time"); "GMT" is per-
mitted as a reference to Universal Time. The military standard
uses a single character for each zone. "Z" is Universal Time.
"A" indicates one hour earlier, and "M" indicates 12 hours ear-
lier; "N" is one hour later, and "Y" is 12 hours later. The
letter "J" is not used. The other remaining two forms are taken
from ANSI standard X3.51-1975. One allows explicit indication of
the amount of offset from UT; the other uses common 3-character
strings for indicating time zones in North America.
-=-=- RFC-2616 -=-=-
3.3.1 Full Date
HTTP applications have historically allowed three different formats
for the representation of date/time stamps:
Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
The first format is preferred as an Internet standard and represents
a fixed-length subset of that defined by RFC 1123 [8] (an update to
RFC 822 [9]). The second format is in common use, but is based on the
obsolete RFC 850 [12] date format and lacks a four-digit year.
HTTP/1.1 clients and servers that parse the date value MUST accept
all three formats (for compatibility with HTTP/1.0), though they MUST
only generate the RFC 1123 format for representing HTTP-date values
in header fields. See section 19.3 for further information.
Note: Recipients of date values are encouraged to be robust in
accepting date values that may have been sent by non-HTTP
applications, as is sometimes the case when retrieving or posting
messages via proxies/gateways to SMTP or NNTP.
All HTTP date/time stamps MUST be represented in Greenwich Mean Time
(GMT), without exception. For the purposes of HTTP, GMT is exactly
equal to UTC (Coordinated Universal Time). This is indicated in the
first two formats by the inclusion of "GMT" as the three-letter
abbreviation for time zone, and MUST be assumed when reading the
asctime format. HTTP-date is case sensitive and MUST NOT include
additional LWS beyond that specifically included as SP in the
grammar.
HTTP-date = rfc1123-date | rfc850-date | asctime-date
rfc1123-date = wkday "," SP date1 SP time SP "GMT"
rfc850-date = weekday "," SP date2 SP time SP "GMT"
asctime-date = wkday SP date3 SP time SP 4DIGIT
date1 = 2DIGIT SP month SP 4DIGIT
; day month year (e.g., 02 Jun 1982)
date2 = 2DIGIT "-" month "-" 2DIGIT
; day-month-year (e.g., 02-Jun-82)
date3 = month SP ( 2DIGIT | ( SP 1DIGIT ))
; month day (e.g., Jun 2)
time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
; 00:00:00 - 23:59:59
wkday = "Mon" | "Tue" | "Wed"
| "Thu" | "Fri" | "Sat" | "Sun"
weekday = "Monday" | "Tuesday" | "Wednesday"
| "Thursday" | "Friday" | "Saturday" | "Sunday"
month = "Jan" | "Feb" | "Mar" | "Apr"
| "May" | "Jun" | "Jul" | "Aug"
| "Sep" | "Oct" | "Nov" | "Dec"
Note: HTTP requirements for the date/time stamp format apply only
to their usage within the protocol stream. Clients and servers are
not required to use these formats for user presentation, request
logging, etc.
*/
#endif
/* Arrays of asctime-date day and month strs, rfc1123-date day and month strs, and rfc850-date day and month strs. */
static const char* kDayStrs[] = {
"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday",
"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
static const char* kMonthStrs[] = {
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December",
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
/* NOTE that these are ordered this way on purpose. */
static const char* kUSTimeZones[] = {"PST", "PDT", "MST", "MDT", "CST", "CDT", "EST", "EDT"};
/* extern */ const UInt8*
_CFGregorianDateCreateWithBytes(CFAllocatorRef alloc, const UInt8* bytes, CFIndex length, CFGregorianDate* date, CFTimeZoneRef* tz) {
UInt8 buffer[256]; /* Any dates longer than this are not understood. */
length = (length == 256) ? 255 : length;
memmove(buffer, bytes, length);
buffer[length] = '\0'; /* Guarantees every compare will fail if trying to index off the end. */
memset(date, 0, sizeof(date[0]));
if (tz) *tz = NULL;
do {
int i;
CFIndex scan = 0;
UInt8 c = buffer[scan];
/* Skip leading whitespace */
while (isspace(c))
c = buffer[++scan];
/* Check to see if there is a weekday up front. */
if (!isdigit(c)) {
for (i = 0; i < (sizeof(kDayStrs) / sizeof(kDayStrs[0])); i++) {
if (!memcmp(kDayStrs[i], &buffer[scan], strlen(kDayStrs[i])))
break;
}
if (i >=(sizeof(kDayStrs) / sizeof(kDayStrs[0])))
break;
scan += strlen(kDayStrs[i]);
c = buffer[scan];
while (isspace(c) || c == ',')
c = buffer[++scan];
}
/* check for asctime where month comes first */
if (!isdigit(c)) {
for (i = 0; i < (sizeof(kMonthStrs) / sizeof(kMonthStrs[0])); i++) {
if (!memcmp(kMonthStrs[i], &buffer[scan], strlen(kMonthStrs[i])))
break;
}
if (i >= (sizeof(kMonthStrs) / sizeof(kMonthStrs[0])))
break;
date->month = (i % 12) + 1;
scan += strlen(kMonthStrs[i]);
c = buffer[scan];
while (isspace(c))
c = buffer[++scan];
if (!isdigit(c))
break;
}
/* Read the day of month */
for (i = 0; isdigit(c) && (i < 2); i++) {
date->day *= 10;
date->day += c - '0';
c = buffer[++scan];
}
while (isspace(c) || c == '-')
c = buffer[++scan];
/* Not asctime so now comes the month. */
if (date->month == 0) {
if (isdigit(c)) {
for (i = 0; isdigit(c) && (i < 2); i++) {
date->month *= 10;
date->month += c - '0';
c = buffer[++scan];
}
}
else {
for (i = 0; i < (sizeof(kMonthStrs) / sizeof(kMonthStrs[0])); i++) {
if (!memcmp(kMonthStrs[i], &buffer[scan], strlen(kMonthStrs[i])))
break;
}
if (i >= (sizeof(kMonthStrs) / sizeof(kMonthStrs[0])))
break;
date->month = (i % 12) + 1;
scan += strlen(kMonthStrs[i]);
c = buffer[scan];
}
while (isspace(c) || c == '-')
c = buffer[++scan];
/* Read the year */
for (i = 0; isdigit(c) && (i < 4); i++) {
date->year *= 10;
date->year += c - '0';
c = buffer[++scan];
}
while (isspace(c))
c = buffer[++scan];
}
/* Read the hours */
for (i = 0; isdigit(c) && (i < 2); i++) {
date->hour *= 10;
date->hour += c - '0';
c = buffer[++scan];
}
if (c != ':')
break;
c = buffer[++scan];
/* Read the minutes */
for (i = 0; isdigit(c) && (i < 2); i++) {
date->minute *= 10;
date->minute += c - '0';
c = buffer[++scan];
}
if (c == ':') {
c = buffer[++scan];
/* Read the seconds */
for (i = 0; isdigit(c) && (i < 2); i++) {
date->second *= 10;
date->second += c - '0';
c = buffer[++scan];
}
c = buffer[++scan];
}
/* If haven't read the year yet, now is the time. */
if (date->year == 0) {
while (isspace(c))
c = buffer[++scan];
/* Read the year */
for (i = 0; isdigit(c) && (i < 4); i++) {
date->year *= 10;
date->year += c - '0';
c = buffer[++scan];
}
}
if (date->year && date->year < 100) {
if (date->year < 70)
date->year += 2000; /* My CC is still using 2-digit years! */
else
date->year += 1900; /* Bad 2 byte clients */
}
while (isspace(c))
c = buffer[++scan];
if (c && tz) {
/* If it has absolute offset, read the hours and minutes. */
if ((c == '+') || (c == '-')) {
char sign = c;
CFTimeInterval minutes = 0, offset = 0;
c = buffer[++scan];
/* Read the hours */
for (i = 0; isdigit(c) && (i < 2); i++) {
offset *= 10;
offset += c - '0';
c = buffer[++scan];
}
/* Read the minutes */
for (i = 0; isdigit(c) && (i < 2); i++) {
minutes *= 10;
minutes += c - '0';
c = buffer[++scan];
}
offset *= 60;
offset += minutes;
if (sign == '-') offset *= -60;
else offset *= 60;
*tz = CFTimeZoneCreateWithTimeIntervalFromGMT(alloc, offset);
}
/* If it's not GMT/UT time, need to parse the alpha offset. */
else if (!strncmp((const char*)(&buffer[scan]), "UT", 2)) {
*tz = CFTimeZoneCreateWithTimeIntervalFromGMT(alloc, 0);
scan += 2;
}
else if (!strncmp((const char*)(&buffer[scan]), "GMT", 3)) {
*tz = CFTimeZoneCreateWithTimeIntervalFromGMT(alloc, 0);
scan += 3;
}
else if (isalpha(c)) {
UInt8 next = buffer[scan + 1];
/* Check for military time. */
if ((c != 'J') && (!next || isspace(next) || (next == '*'))) {
if (c == 'Z')
*tz = CFTimeZoneCreateWithTimeIntervalFromGMT(alloc, 0);
else {
CFTimeInterval offset = (c < 'N') ? (c - 'A' + 1) : ('M' - c);
offset *= 60;
if (next == '*') {
scan++;
offset = (offset < 0) ? offset - 30 : offset + 30;
}
offset *= 60;
*tz = CFTimeZoneCreateWithTimeIntervalFromGMT(alloc, 0);
}
}
else {
for (i = 0; i < (sizeof(kUSTimeZones) / sizeof(kUSTimeZones[0])); i++) {
if (!memcmp(kUSTimeZones[i], &buffer[scan], strlen(kUSTimeZones[i]))) {
*tz = CFTimeZoneCreateWithTimeIntervalFromGMT(alloc, (-8 + (i >> 2) + (i & 0x1)) * 3600);
scan += strlen(kUSTimeZones[i]);
break;
}
}
}
}
}
if (!CFGregorianDateIsValid(*date, kCFGregorianAllUnits))
break;
return bytes + scan;
} while (1);
memset(date, 0, sizeof(date[0]));
if (tz) {
if (*tz) CFRelease(*tz);
*tz = NULL;
}
return bytes;
}
/* extern */ CFIndex
_CFGregorianDateCreateWithString(CFAllocatorRef alloc, CFStringRef str, CFGregorianDate* date, CFTimeZoneRef* tz) {
UInt8 buffer[256]; /* Any dates longer than this are not understood. */
CFIndex length = CFStringGetLength(str);
CFIndex result = 0;
CFStringGetBytes(str, CFRangeMake(0, length), kCFStringEncodingASCII, 0, FALSE, buffer, sizeof(buffer), &length);
if (length)
result = _CFGregorianDateCreateWithBytes(alloc, buffer, length, date, tz) - buffer;
else {
memset(date, 0, sizeof(date[0]));
if (tz) *tz = NULL;
}
return result;
}
/* extern */ CFStringRef
_CFStringCreateRFC1123DateStringWithGregorianDate(CFAllocatorRef alloc, CFGregorianDate* date, CFTimeZoneRef tz) {
CFStringRef result = NULL;
int hour = 0;
int minute = 0;
if (tz) {
CFTimeInterval offset = CFTimeZoneGetSecondsFromGMT(tz, 0.0);
hour = offset / 3600;
minute = abs(offset - (hour * 3600));
}
if (CFGregorianDateIsValid(*date, kCFGregorianAllUnits)) {
result = CFStringCreateWithFormat(alloc,
NULL,
CFSTR("%02d %s %04ld %02d:%02d:%02d %+03d%02d"),
date->day,
kMonthStrs[date->month + 11], /* Offset to the short names */
date->year,
date->hour,
date->minute,
(int)date->second,
hour,
minute);
}
return result;
}
/* extern */ CFStringRef
_CFStringCreateRFC2616DateStringWithGregorianDate(CFAllocatorRef alloc, CFGregorianDate* date, CFTimeZoneRef tz) {
CFStringRef result = NULL;
if (CFGregorianDateIsValid(*date, kCFGregorianAllUnits)) {
CFAbsoluteTime t = CFGregorianDateGetAbsoluteTime(*date, tz);
SInt32 day = CFAbsoluteTimeGetDayOfWeek(t, NULL);
result = CFStringCreateWithFormat(alloc,
NULL,
CFSTR("%s, %02d %s %04ld %02d:%02d:%02d GMT"),
kDayStrs[6 + day],
date->day,
kMonthStrs[date->month + 11], /* Offset to the short names */
date->year,
date->hour,
date->minute,
(int)date->second);
}
return result;
}
#if DNS_SD_SUPPORT
/* extern */ SInt32
_DNSServiceErrorToCFNetServiceError(DNSServiceErrorType dnsError) {
SInt32 cfError;
/* We may want to add more CFNetService errors in the future to cover some of the other
possible DNSService errors, like NAT Traversal and Not Authorized. <rdar://problem/4277898> */
switch (dnsError) {
case kDNSServiceErr_NameConflict:
cfError = kCFNetServicesErrorCollision;
break;
case kDNSServiceErr_BadParam:
cfError = kCFNetServicesErrorBadArgument;
break;
default:
cfError = kCFNetServicesErrorUnknown;
break;
}
return cfError;
}
#endif
#if defined(__WIN32__)
extern void _CFFTPCleanup(void); /* exported from FTPStream.c */
WINBOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID pReserved) {
if (dwReason == DLL_PROCESS_DETACH) {
_CFHTTPMessageCleanup();
_CFHTTPStreamCleanup();
_CFFTPCleanup();
}
return TRUE;
}
#endif // __WIN32__

166
src/CFNetworkInternal.h Normal file
View File

@ -0,0 +1,166 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CFNetworkInternal.h
* CFNetwork
*
* Created by rew on Tue Sep 26 2000.
* Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
*
*/
#ifndef __CFNETWORKINTERNAL__
#define __CFNETWORKINTERNAL__
#include "CFRuntime.h"
#include <CFNetwork/CFNetwork.h>
#if DNS_SD_SUPPORT
#include <dns_sd.h>
#endif
#include "CFNetworkThreadSupport.h" /* Include here since it used to live here and files rely on that. */
#include "ProxySupport.h" /* Include here since it used to live here and files rely on that. */
#if defined(__cplusplus)
extern "C" {
#endif
// An error domain which is either kCFStreamErrorDomainPOSIX or kCFStreamErrorDomainWinSock, depending on the platform.
#if defined(__WIN32__)
#define _kCFStreamErrorDomainNativeSockets kCFStreamErrorDomainWinSock
#else
#define _kCFStreamErrorDomainNativeSockets kCFStreamErrorDomainPOSIX
#endif
/* Use CF's logging routine. */
#define __kCFLogAssertion 15
CF_EXPORT void CFLog(int p, CFStringRef str, ...);
/* Bit manipulation macros */
/* Bits are numbered from 31 on left to 0 on right */
/* May or may not work if you use them on bitfields in types other than UInt32, bitfields the full width of a UInt32, or anything else for which they were not designed. */
#define __CFBitfieldMask(N1, N2) ((((UInt32)~0UL) << (31UL - (N1) + (N2))) >> (31UL - N1))
#define __CFBitfieldGetValue(V, N1, N2) (((V) & __CFBitfieldMask(N1, N2)) >> (N2))
#define __CFBitfieldSetValue(V, N1, N2, X) ((V) = ((V) & ~__CFBitfieldMask(N1, N2)) | (((X) << (N2)) & __CFBitfieldMask(N1, N2)))
#define __CFBitfieldMaxValue(N1, N2) __CFBitfieldGetValue(0xFFFFFFFFUL, (N1), (N2))
#define __CFBitIsSet(V, N) (((V) & (1UL << (N))) != 0)
#define __CFBitSet(V, N) ((V) |= (1UL << (N)))
#define __CFBitClear(V, N) ((V) &= ~(1UL << (N)))
#ifdef __CONSTANT_CFSTRINGS__
#define CONST_STRING_DECL(S, V) const CFStringRef S = (const CFStringRef)__builtin___CFStringMakeConstantString(V);
#else
/* Hack: we take a copy of this from CFInternal.h. */
struct CF_CONST_STRING {
CFRuntimeBase _base;
const char *_ptr;
uint32_t _length;
};
// On Windows, DLL's don't let us init the _base member to be &__CFConstantStringClassReference because
// it is not a constant. Since for now we don't have ObjC around, and we don't care about toll-free
// bridging, we can just init this field to NULL for now.
// CF_EXPORT int __CFConstantStringClassReference[];
#if defined(__ppc__)
#define CONST_STRING_DECL(S, V) \
static struct CF_CONST_STRING __ ## S ## __ = {{NULL/*&__CFConstantStringClassReference*/, 0x0000, 0x07c8}, V, sizeof(V) - 1}; \
const CFStringRef S = (CFStringRef) & __ ## S ## __;
#elif defined(__i386__)
#define CONST_STRING_DECL(S, V) \
static struct CF_CONST_STRING __ ## S ## __ = {{NULL/*&__CFConstantStringClassReference*/, 0x07c8, 0x0000}, V, sizeof(V) - 1}; \
const CFStringRef S = (CFStringRef) & __ ## S ## __;
#else
#error undefined architecture
#endif
#endif
/*!
@function __CFNetworkLoadFramework
@discussion Loads the framework image pointed to by framework_path.
This function will use the proper dyld suffix and search methods
for the given situation.
@param framework_path The path to the framework to be loaded.
@result Returns a pointer to the image on success. It returns NULL
on failure.
*/
extern void* __CFNetworkLoadFramework(const char* const framework_path);
/*!
@function _CFNetworkCFStringCreateWithCFDataAddress
@discussion Creates a dotted IP string for the address given.
@param alloc Allocator reference to use for the string allocation
@param addr CFDataRef containing the struct sockaddr with the address.
@result A CFStringRef containing the dotted IP string for the address.
Returns NULL if the address could not be converted to dotted IP.
Currently AF_INET and AF_INET6 are supported.
*/
extern CFStringRef _CFNetworkCFStringCreateWithCFDataAddress(CFAllocatorRef alloc, CFDataRef addr);
/*!
@function _CFStringGetOrCreateCString
@discussion Given a CFString, this function attempts to get the bytes of
the string and create a C-style (null terminated) string from them.
If the given buffer is too small, one of adequate length will be
allocated with the given allocator. It is the client's responsibility
to deallocate the buffer if the returned buffer is not the same
buffer which was passed.
@param allocator Allocator to be used for allocation should the given
buffer not be big enough.
@param string CFString from which the bytes should be retrieved. Must be
non-NULL.
@param buffer Buffer into which the bytes should be placed. If this buffer
is not big enough, one will be allocated. Use NULL to always allocate.
@param bufferLength Pointer to the size of the incoming buffer. Upon a
successful return, this will contain the number of bytes in the buffer,
not counting the null termination. Must be non-NULL if buffer is non-NULL.
@param encoding String encoding to be used for decoding the bytes.
@result Returns the buffer holding the bytes. If the passed in buffer pointer
is not the same as the result buffer pointer, the client must deallocate
the buffer.
*/
extern UInt8* _CFStringGetOrCreateCString(CFAllocatorRef allocator, CFStringRef string, UInt8* buffer, CFIndex* bufferLength, CFStringEncoding encoding);
#if DNS_SD_SUPPORT
/*!
@function _DNSServiceErrorToCFNetServiceError
@discussion Given a DNSService error, this returns the appropriate CFNetService error.
@param dnsError DNSServiceErrorType error.
@result A SInt32 containing the equivalent CFNetService error.
*/
extern SInt32 _DNSServiceErrorToCFNetServiceError(DNSServiceErrorType dnsError);
#endif
#if defined(__cplusplus)
}
#endif
#endif /* __CFNETWORKINTERNAL__ */

85
src/CFProxySupport.c Normal file
View File

@ -0,0 +1,85 @@
//
// CFProxySupport.c
// CFNetwork
//
// Copyright (c) 2014 Apportable. All rights reserved.
//
#include "CFProxySupport.h"
static CFDictionaryRef copyEmptySystemProxySettings(void) {
return CFDictionaryCreate(NULL, NULL, NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
}
static CFDictionaryRef (*copySystemProxySettingsCallback)(void) = &copyEmptySystemProxySettings;
void _CFNetworkSetCopySystemProxySettingsCallback(CFDictionaryRef (*callback)(void)) {
copySystemProxySettingsCallback = callback;
}
CFDictionaryRef CFNetworkCopySystemProxySettings(void) {
return copySystemProxySettingsCallback();
}
CFArrayRef CFNetworkCopyProxiesForURL(CFURLRef url, CFDictionaryRef proxySettings) {
CFDictionaryRef noSettings = CFDictionaryCreate(NULL,
(CFTypeRef*)&kCFProxyTypeKey, (CFTypeRef*)&kCFProxyTypeNone, 1,
&kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFArrayRef proxies = CFArrayCreate(NULL, (CFTypeRef*)&noSettings, 1, &kCFTypeArrayCallBacks);
CFRelease(noSettings);
return proxies;
}
CFArrayRef CFNetworkCopyProxiesForAutoConfigurationScript(CFStringRef proxyAutoConfigurationScript, CFURLRef targetURL, CFErrorRef *error) {
DEBUG_BREAK();
return NULL;
}
CFRunLoopSourceRef CFNetworkExecuteProxyAutoConfigurationScript(CFStringRef proxyAutoConfigurationScript, CFURLRef targetURL, CFProxyAutoConfigurationResultCallback cb, CFStreamClientContext *clientContext) {
DEBUG_BREAK();
return NULL;
}
CFRunLoopSourceRef CFNetworkExecuteProxyAutoConfigurationURL(CFURLRef proxyAutoConfigURL, CFURLRef targetURL, CFProxyAutoConfigurationResultCallback cb, CFStreamClientContext *clientContext) {
DEBUG_BREAK();
return NULL;
}
const CFStringRef kCFProxyTypeKey = CFSTR("kCFProxyTypeKey");
const CFStringRef kCFProxyPortNumberKey = CFSTR("kCFProxyPortNumberKey");
const CFStringRef kCFProxyAutoConfigurationURLKey = CFSTR("kCFProxyAutoConfigurationURLKey");
const CFStringRef kCFProxyAutoConfigurationJavaScriptKey = CFSTR("kCFProxyAutoConfigurationJavaScriptKey");
const CFStringRef kCFProxyUsernameKey = CFSTR("kCFProxyUsernameKey");
const CFStringRef kCFProxyPasswordKey = CFSTR("kCFProxyPasswordKey");
const CFStringRef kCFProxyHostNameKey = CFSTR("kCFProxyHostNameKey");
const CFStringRef kCFProxyTypeNone = CFSTR("kCFProxyTypeNone");
const CFStringRef kCFProxyTypeHTTP = CFSTR("kCFProxyTypeHTTP");
const CFStringRef kCFProxyTypeHTTPS = CFSTR("kCFProxyTypeHTTPS");
const CFStringRef kCFProxyTypeSOCKS = CFSTR("kCFProxyTypeSOCKS");
const CFStringRef kCFProxyTypeFTP = CFSTR("kCFProxyTypeFTP");
const CFStringRef kCFProxyTypeAutoConfigurationURL = CFSTR("kCFProxyTypeAutoConfigurationURL");
const CFStringRef kCFProxyTypeAutoConfigurationJavaScript = CFSTR("kCFProxyTypeAutoConfigurationJavaScript");
const CFStringRef kCFNetworkProxiesExceptionsList = CFSTR("ExceptionsList");
const CFStringRef kCFNetworkProxiesExcludeSimpleHostnames = CFSTR("ExcludeSimpleHostnames");
const CFStringRef kCFNetworkProxiesFTPEnable = CFSTR("FTPEnable");
const CFStringRef kCFNetworkProxiesFTPPassive = CFSTR("FTPPassive");
const CFStringRef kCFNetworkProxiesFTPPort = CFSTR("FTPPort");
const CFStringRef kCFNetworkProxiesFTPProxy = CFSTR("FTPProxy");
const CFStringRef kCFNetworkProxiesGopherEnable = CFSTR("GopherEnable");
const CFStringRef kCFNetworkProxiesGopherPort = CFSTR("GopherPort");
const CFStringRef kCFNetworkProxiesGopherProxy = CFSTR("GopherProxy");
const CFStringRef kCFNetworkProxiesHTTPEnable = CFSTR("HTTPEnable");
const CFStringRef kCFNetworkProxiesHTTPPort = CFSTR("HTTPPort");
const CFStringRef kCFNetworkProxiesHTTPProxy = CFSTR("HTTPProxy");
const CFStringRef kCFNetworkProxiesHTTPSEnable = CFSTR("HTTPSEnable");
const CFStringRef kCFNetworkProxiesHTTPSPort = CFSTR("HTTPSPort");
const CFStringRef kCFNetworkProxiesHTTPSProxy = CFSTR("HTTPSProxy");
const CFStringRef kCFNetworkProxiesRTSPEnable = CFSTR("RTSPEnable");
const CFStringRef kCFNetworkProxiesRTSPPort = CFSTR("RTSPPort");
const CFStringRef kCFNetworkProxiesRTSPProxy = CFSTR("RTSPProxy");
const CFStringRef kCFNetworkProxiesSOCKSEnable = CFSTR("SOCKSEnable");
const CFStringRef kCFNetworkProxiesSOCKSPort = CFSTR("SOCKSPort");
const CFStringRef kCFNetworkProxiesSOCKSProxy = CFSTR("SOCKSProxy");
const CFStringRef kCFNetworkProxiesProxyAutoConfigEnable = CFSTR("ProxyAutoConfigEnable");
const CFStringRef kCFNetworkProxiesProxyAutoConfigURLString = CFSTR("ProxyAutoConfigURLString");
const CFStringRef kCFNetworkProxiesProxyAutoDiscoveryEnable = CFSTR("ProxyAutoDiscoveryEnable");

101
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,101 @@
project(cfnetwork)
include(darling_framework)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc \
-include ${CMAKE_SOURCE_DIR}/src/external/corefoundation/macros.h")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc -nostdinc++ \
-include ${CMAKE_SOURCE_DIR}/src/external/corefoundation/macros.h")
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/SharedCode
${CMAKE_CURRENT_SOURCE_DIR}/Proxies
${CMAKE_CURRENT_SOURCE_DIR}/HTTP
${CMAKE_CURRENT_SOURCE_DIR}/HTTP/SPNEGO
${CMAKE_CURRENT_SOURCE_DIR}/Headers
${CMAKE_CURRENT_SOURCE_DIR}/Utils
${CMAKE_CURRENT_SOURCE_DIR}/../include
${CMAKE_CURRENT_SOURCE_DIR}/../include/CFNetwork
${CMAKE_CURRENT_SOURCE_DIR}/../private_include
${CMAKE_CURRENT_SOURCE_DIR}/../private_include/CFNetwork
${CMAKE_SOURCE_DIR}/src/launchd/liblaunch
${CMAKE_SOURCE_DIR}/src/CommonCrypto
${CMAKE_SOURCE_DIR}/src/libinfo/lookup.subproj
${CMAKE_SOURCE_DIR}/src/external/corefoundation
${CMAKE_SOURCE_DIR}/src/external/objc4/runtime
${CMAKE_SOURCE_DIR}/src/external/libclosure
${CMAKE_SOURCE_DIR}/src/external/zlib
${CMAKE_SOURCE_DIR}/src/external/icu/icuSources/i18n
${CMAKE_SOURCE_DIR}/src/external/icu/icuSources/common
${CMAKE_SOURCE_DIR}/src/external/coretls/lib
${CMAKE_SOURCE_DIR}/src/external/configd/SystemConfiguration.fproj
${CMAKE_SOURCE_DIR}/src/external/security/include
${CMAKE_SOURCE_DIR}/src/external/security/include/Security
)
set(cfnetwork_sources
resolv_stub.c
Stream/CFSocketStream.c
SharedCode/CFNetworkSchedule.c
SharedCode/CFNetworkThreadSupport.c
SharedCode/CFServer.c
SharedCode/CFNetConnection.c
SharedCode/CFError.c
# JavaScriptGlue.c
CFProxySupport.c
URL/CFURLConnection.c
URL/CFURLProtectionSpace.c
URL/CFCachedURLResponse.c
URL/CFURLCache.c
URL/CFURLResponse.c
URL/_CFURLAccess.c
URL/CFURLAuthChallenge.c
URL/CFURLRequest.c
HTTP/CFHTTPServer.c
HTTP/CFHTTPMessage.c
HTTP/CFHTTPStream.c
# HTTP/SPNEGO/spnegoKrb.cpp
# HTTP/SPNEGO/spnegoDER.cpp
# HTTP/SPNEGO/spnegoBlob.cpp
HTTP/CFHTTPFilter.c
#HTTP/NTLM/NtlmGenerator.cpp
#HTTP/NTLM/ntlmBlobPriv.cpp
HTTP/CFHTTPAuthentication.c
HTTP/CFHTTPConnection.c
CFNetServices.c # requires Bonjour
Host/CFHost.c
Proxies/ProxySupport.c
Cookies/CFHTTPCookie.c
Cookies/CFHTTPCookieStorage.c
Utils/CFHTTPUtils.c
Utils/CFFSUtils.c
Utils/CFRuntimeUtils.c
FTP/CFFTPStream.c
#NetDiagnostics/CFNetDiagnosticsProtocolUser.c
#NetDiagnostics/CFNetDiagnostics.c
#NetDiagnostics/CFNetDiagnosticPing.c
CFNetwork.c
#libresolv.c
#NetServices/DeprecatedDNSServiceDiscovery.c
#NetServices/CFNetServices.c
#NetServices/CFNetServiceMonitor.c
#NetServices/CFNetServiceBrowser.c
#security_cdsa_utils.c
)
add_framework(CFNetwork
FAT
CURRENT_VERSION
SOURCES
${cfnetwork_sources}
VERSION "A"
DEPENDENCIES
system
CoreFoundation
z
CommonCrypto
objc
icucore
)

330
src/Cookies/CFHTTPCookie.c Normal file
View File

@ -0,0 +1,330 @@
//
// CFHTTPCookie.c
// CFNetwork
//
// Copyright (c) 2014 Apportable. All rights reserved.
//
#include "CFBase.h"
#include "CFRuntime.h"
#include "CFHTTPCookie.h"
#include "CFNumber.h"
#include <unicode/uregex.h>
#include <assert.h>
static const CFStringRef kCFHTTPCookieName = CFSTR("Name");
static const CFStringRef kCFHTTPCookieValue = CFSTR("Value");
static const CFStringRef kCFHTTPCookieOriginURL = CFSTR("OriginURL");
static const CFStringRef kCFHTTPCookieVersion = CFSTR("Version");
static const CFStringRef kCFHTTPCookieDomain = CFSTR("Domain");
static const CFStringRef kCFHTTPCookiePath = CFSTR("Path");
static const CFStringRef kCFHTTPCookieSecure = CFSTR("Secure");
static const CFStringRef kCFHTTPCookieExpires = CFSTR("Expires");
static const CFStringRef kCFHTTPCookieComment = CFSTR("Comment");
static const CFStringRef kCFHTTPCookieCommentURL = CFSTR("CommentURL");
static const CFStringRef kCFHTTPCookieDiscard = CFSTR("Discard");
static const CFStringRef kCFHTTPCookieMaximumAge = CFSTR("Max-Age");
static const CFStringRef kCFHTTPCookiePort = CFSTR("Port");
static const CFStringRef kCFHTTPCookieHTTPOnly = CFSTR("HTTPOnly");
struct __CFHTTPCookie {
CFRuntimeBase _base;
CFDictionaryRef _properties;
CFStringRef _domain;
};
static void __CFHTTPCookieDeallocate(CFTypeRef cf) {
struct __CFHTTPCookie *item = (struct __CFHTTPCookie *)cf;
CFRelease(item->_properties);
}
static CFTypeID __kCFHTTPCookieTypeID = _kCFRuntimeNotATypeID;
static const CFRuntimeClass __CFHTTPCookieClass = {
_kCFRuntimeScannedObject,
"CFHTTPCookie",
NULL, // init
NULL, // copy
__CFHTTPCookieDeallocate,
NULL,
NULL,
NULL,
NULL
};
static void __CFHTTPCookieInitialize(void) {
__kCFHTTPCookieTypeID = _CFRuntimeRegisterClass(&__CFHTTPCookieClass);
}
CFTypeID CFHTTPCookieGetTypeID(void) {
if (__kCFHTTPCookieTypeID == _kCFRuntimeNotATypeID) {
__CFHTTPCookieInitialize();
}
return __kCFHTTPCookieTypeID;
}
CFHTTPCookieRef _CFHTTPCookieCreate(CFAllocatorRef allocator) {
CFIndex size = sizeof(struct __CFHTTPCookie) - sizeof(CFRuntimeBase);
return (CFHTTPCookieRef)_CFRuntimeCreateInstance(allocator, CFHTTPCookieGetTypeID(), size, NULL);
}
CFHTTPCookieRef CFHTTPCookieCreateWithProperties(CFDictionaryRef properties) {
CFHTTPCookieRef cookie = _CFHTTPCookieCreate(kCFAllocatorDefault);
cookie->_properties = CFRetain(CFDictionaryCreateCopy(kCFAllocatorDefault, properties));
if (CFHTTPCookieGetDomain(cookie)==NULL||CFHTTPCookieGetPath(cookie)==NULL) {
CFRelease(cookie);
cookie = NULL;
}
return cookie;
}
CFNumberRef CFHTTPCookieGetVersion(CFHTTPCookieRef cookie) {
return CFDictionaryGetValue(cookie->_properties, kCFHTTPCookieVersion);
}
CFStringRef CFHTTPCookieGetName(CFHTTPCookieRef cookie) {
return CFDictionaryGetValue(cookie->_properties, kCFHTTPCookieName);
}
CFStringRef CFHTTPCookieGetDomain(CFHTTPCookieRef cookie) {
if (cookie->_domain == NULL) {
cookie->_domain = CFStringCreateCopy(kCFAllocatorDefault, CFDictionaryGetValue(cookie->_properties, kCFHTTPCookieDomain));
if (cookie->_domain == NULL) {
CFTypeRef urlString = CFDictionaryGetValue(cookie->_properties, kCFHTTPCookieOriginURL);
if (urlString != NULL) {
CFURLRef url = NULL;
if (CFGetTypeID(urlString)==CFStringGetTypeID()) {
url = CFURLCreateWithString(kCFAllocatorDefault, urlString, NULL);
} else {
url = CFRetain(urlString);
}
cookie->_domain = CFURLCopyHostName(url);
CFRelease(url);
}
}
}
return cookie->_domain;
}
CFDateRef CFHTTPCookieGetExpirationDate(CFHTTPCookieRef cookie) {
return CFDictionaryGetValue(cookie->_properties, kCFHTTPCookieExpires);
}
CFStringRef CFHTTPCookieGetPath(CFHTTPCookieRef cookie) {
return CFDictionaryGetValue(cookie->_properties, kCFHTTPCookiePath);
}
CFStringRef CFHTTPCookieGetValue(CFHTTPCookieRef cookie) {
return CFDictionaryGetValue(cookie->_properties, kCFHTTPCookieValue);
}
CFStringRef CFHTTPCookieGetComment(CFHTTPCookieRef cookie) {
return CFDictionaryGetValue(cookie->_properties, kCFHTTPCookieComment);
}
CFURLRef CFHTTPCookieGetCommentURL(CFHTTPCookieRef cookie) {
return CFDictionaryGetValue(cookie->_properties, kCFHTTPCookieCommentURL);
}
CFArrayRef CFHTTPCookieGetPortArray(CFHTTPCookieRef cookie) {
return CFDictionaryGetValue(cookie->_properties, kCFHTTPCookiePort);
}
Boolean CFHTTPCookieIsSecure(CFHTTPCookieRef cookie) {
return CFBooleanGetValue(CFDictionaryGetValue(cookie->_properties, kCFHTTPCookieSecure));
}
Boolean CFHTTPCookieIsHTTPOnly(CFHTTPCookieRef cookie) {
return CFBooleanGetValue(CFDictionaryGetValue(cookie->_properties, kCFHTTPCookieHTTPOnly));
}
Boolean CFHTTPCookieIsSessionOnly(CFHTTPCookieRef cookie) {
return 0; //fixme
}
CFDictionaryRef CFHTTPCookieCopyProperties(CFHTTPCookieRef cookie) {
return CFDictionaryCreateCopy(kCFAllocatorDefault, cookie->_properties);
}
CFDictionaryRef CFHTTPCookieCopyRequestHeaderFields(CFArrayRef cookies) {
if (CFArrayGetCount(cookies)>0) {
CFMutableStringRef resultCookieString = CFStringCreateMutable(kCFAllocatorDefault, 4*1024*1024);
for (int i=0; i<CFArrayGetCount(cookies); i++) {
if (i>0) {
CFStringAppend(resultCookieString, CFSTR("; "));
}
CFHTTPCookieRef cookie = (CFHTTPCookieRef)CFArrayGetValueAtIndex(cookies, i);
CFStringRef name = CFHTTPCookieGetName(cookie);
CFStringRef value = CFHTTPCookieGetValue(cookie);
CFStringAppendFormat(resultCookieString, NULL, CFSTR("%@=%@"), name, value);
}
CFStringRef cookieString = CFStringCreateCopy(kCFAllocatorDefault, resultCookieString);
CFRelease(resultCookieString);
const void *keys[] = { CFSTR("Cookie")};
const void *values[] = { cookieString };
CFDictionaryRef result = CFDictionaryCreate(NULL, keys, values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFRelease(cookieString);
return result;
} else {
return NULL;
}
}
CFArrayRef CFHTTPCookieCreateWithResponseHeaderFields(CFDictionaryRef headerFields, CFURLRef url) {
CFStringRef cookieString = CFDictionaryGetValue(headerFields, CFSTR("Set-Cookie"));
if (cookieString!=NULL) {
UErrorCode status = U_ZERO_ERROR;
UParseError parse_err = { 0 };
//fixme. regex parsing is evil. adopt parsing algorithm from firefox or from somewhere
CFStringRef pattern = CFSTR("(.*?)(=(.*?))?($|;|,(?! [1-9][0-9])) *");
Boolean patNeedsFree = false;
const UChar *pat = CFStringGetCharactersPtr(pattern);
CFIndex patLen = CFStringGetLength(pattern);
if (pat == NULL)
{
pat = malloc(sizeof(UChar) * patLen);
CFStringGetCharacters(pattern, CFRangeMake(0, patLen), (UChar*)pat);
patNeedsFree = true;
}
URegularExpression *pExpr = uregex_open((const UChar *)pat, patLen, 0, &parse_err, &status);
assert(U_SUCCESS(status));
/* Configure the text that the regular expression operates on. */
const UChar *text = CFStringGetCharactersPtr(cookieString);
Boolean needsFree = false;
CFIndex len = CFStringGetLength(cookieString);
if (text == NULL)
{
text = malloc(sizeof(UChar) * len);
CFStringGetCharacters(cookieString, CFRangeMake(0, len), (UChar*)text);
needsFree = true;
}
uregex_setText(pExpr, text, len, &status);
assert(U_SUCCESS(status));
/* Attempt the match */
UBool res = uregex_findNext(pExpr, &status);
CFStringRef path = NULL;
CFMutableDictionaryRef cookiesNamesValues = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
while (res) {
int64_t nameStart = uregex_start64(pExpr, 1, &status);
int64_t nameEnd = uregex_end64(pExpr, 1, &status);
int64_t valueStart = uregex_start64(pExpr, 3, &status);
int64_t valueEnd = uregex_end64(pExpr, 3, &status);
CFStringRef name = CFStringCreateWithSubstring(kCFAllocatorDefault, cookieString, CFRangeMake(nameStart, nameEnd-nameStart));
CFStringRef value = CFStringCreateWithSubstring(kCFAllocatorDefault, cookieString, CFRangeMake(valueStart, valueEnd-valueStart));
//fixme: apply to last cookie only
if (CFStringCompare(name, CFSTR("path"), kCFCompareCaseInsensitive)==kCFCompareEqualTo) {
path = CFStringCreateCopy(kCFAllocatorDefault, value);
} else if (CFStringCompare(name, CFSTR("domain"), kCFCompareCaseInsensitive)==kCFCompareEqualTo) {
} else if (CFStringCompare(name, CFSTR("expires"), kCFCompareCaseInsensitive)==kCFCompareEqualTo) {
} else if (CFStringCompare(name, CFSTR("httponly"), kCFCompareCaseInsensitive)==kCFCompareEqualTo) {
} else if (CFStringCompare(name, CFSTR("secure"), kCFCompareCaseInsensitive)==kCFCompareEqualTo) {
} else if (value != NULL && CFStringGetLength(name)>0){
CFDictionarySetValue(cookiesNamesValues, name, value);
}
CFRelease(name);
CFRelease(value);
res = uregex_findNext(pExpr, &status);
}
if (path==NULL) {
path = CFSTR("/");
}
CFMutableArrayRef mutableResult = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
CFTypeRef names[CFDictionaryGetCount(cookiesNamesValues)];
CFTypeRef values[CFDictionaryGetCount(cookiesNamesValues)];
CFDictionaryGetKeysAndValues(cookiesNamesValues, names, values);
for (int i=0; i<CFDictionaryGetCount(cookiesNamesValues); i++) {
CFTypeRef propertyKeys[] = {kCFHTTPCookieName, kCFHTTPCookieValue, kCFHTTPCookieOriginURL, kCFHTTPCookiePath};
CFTypeRef propertyValues[] = {names[i], values[i], url, path};
CFDictionaryRef properties = CFDictionaryCreate(kCFAllocatorDefault, propertyKeys, propertyValues, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFHTTPCookieRef cookie = CFHTTPCookieCreateWithProperties(properties);
CFRelease(properties);
CFArrayAppendValue(mutableResult, cookie);
CFRelease(cookie);
}
CFRelease(path);
CFRelease(cookiesNamesValues);
assert(U_SUCCESS(status));
uregex_close(pExpr);
if (needsFree)
{
free((UChar *)text);
}
if (patNeedsFree)
{
free((UChar *)pat);
}
/*
NSMutableDictionary *cookiesKeyValue = [NSMutableDictionary dictionary];
__block NSString *path = @"/";
[regex enumerateMatchesInString:cookieString options:0 range:NSMakeRange(0, cookieString.length) usingBlock:^(NSTextCheckingResult *checkingResult, NSMatchingFlags flags, BOOL *stop) {
NSString *name = [cookieString substringWithRange:[checkingResult rangeAtIndex:1]];
NSString *value = [cookieString substringWithRange:[checkingResult rangeAtIndex:2]];
if ([name isEqual:@"Path"]) {
path = value;
} else {
[cookiesKeyValue setObject:value forKey:name];
}
}];
[cookiesKeyValue enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:@{NSHTTPCookieName: key, NSHTTPCookieValue:obj, NSHTTPCookieOriginURL:URL, NSHTTPCookiePath: path}];
[result addObject:cookie];
}];*/
CFArrayRef result = CFArrayCreateCopy(kCFAllocatorDefault, mutableResult);
CFRelease(mutableResult);
return result;
} else {
return NULL;
}
}

View File

@ -0,0 +1,128 @@
//
// CFHTTPCookieStorage.c
// CFNetwork
//
// Copyright (c) 2014 Apportable. All rights reserved.
//
#include "CFBase.h"
#include "CFRuntime.h"
#include "CFHTTPCookieStorage.h"
#include "CFHTTPCookie.h"
#include "CFArray.h"
#include <dispatch/dispatch.h>
struct __CFHTTPCookieStorage {
CFRuntimeBase _base;
CFMutableArrayRef _cookies;
};
static void __CFHTTPCookieStorageDeallocate(CFTypeRef cf) {
struct __CFHTTPCookieStorage *item = (struct __CFHTTPCookieStorage *)cf;
CFRelease(item->_cookies);
}
static CFTypeID __kCFHTTPCookieStorageTypeID = _kCFRuntimeNotATypeID;
static const CFRuntimeClass __CFHTTPCookieStorageClass = {
_kCFRuntimeScannedObject,
"CFHTTPCookieStorage",
NULL, // init
NULL, // copy
__CFHTTPCookieStorageDeallocate,
NULL,
NULL,
NULL,
NULL
};
static void __CFHTTPCookieStorageInitialize(void) {
__kCFHTTPCookieStorageTypeID = _CFRuntimeRegisterClass(&__CFHTTPCookieStorageClass);
}
CFTypeID CFHTTPCookieStorageGetTypeID(void) {
if (__kCFHTTPCookieStorageTypeID == _kCFRuntimeNotATypeID) {
__CFHTTPCookieStorageInitialize();
}
return __kCFHTTPCookieStorageTypeID;
}
static struct __CFHTTPCookieStorage *_CFHTTPCookieStorageCreate(CFAllocatorRef allocator) {
CFIndex size = sizeof(struct __CFHTTPCookieStorage) - sizeof(CFRuntimeBase);
struct __CFHTTPCookieStorage *cookieStorage = (struct __CFHTTPCookieStorage *)_CFRuntimeCreateInstance(allocator, CFHTTPCookieStorageGetTypeID(), size, NULL);
cookieStorage->_cookies = (CFMutableArrayRef)CFRetain(CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks));
return cookieStorage;
}
CFHTTPCookieStorageRef CFHTTPCookieStorageGetDefault() {
static struct __CFHTTPCookieStorage *sharedStorage = NULL;
static dispatch_once_t once = 0L;
dispatch_once(&once, ^{
sharedStorage = _CFHTTPCookieStorageCreate(kCFAllocatorDefault);
});
return (CFHTTPCookieStorageRef)sharedStorage;
}
void CFHTTPCookieStorageDeleteCookie(CFHTTPCookieStorageRef storage, CFHTTPCookieRef cookie) {
CFMutableArrayRef cookies = storage->_cookies;
CFIndex i = CFArrayGetFirstIndexOfValue(cookies,
CFRangeMake(0, CFArrayGetCount(cookies)),
cookie);
if (i != kCFNotFound)
CFArrayRemoveValueAtIndex(cookies, i);
}
void CFHTTPCookieStorageSetCookie(CFHTTPCookieStorageRef storage, CFHTTPCookieRef cookie) {
CFIndex existingCookieIndex = kCFNotFound;
for (int j=0; j<CFArrayGetCount(storage->_cookies); j++) {
CFHTTPCookieRef existingCookie = (CFHTTPCookieRef)CFArrayGetValueAtIndex(storage->_cookies, j);
if (CFStringCompare(CFHTTPCookieGetName(existingCookie), CFHTTPCookieGetName(cookie), kCFCompareCaseInsensitive)==kCFCompareEqualTo) {
existingCookieIndex = j;
break;
}
}
if (existingCookieIndex == kCFNotFound) {
CFArrayAppendValue(storage->_cookies, cookie);
} else {
CFArrayReplaceValues(storage->_cookies, CFRangeMake(existingCookieIndex, 1), (CFTypeRef*)&cookie, 1);
}
}
CFArrayRef CFHTTPCookieStorageCopyCookies(CFHTTPCookieStorageRef storage) {
return CFArrayCreateCopy(kCFAllocatorDefault, storage->_cookies);
}
CFArrayRef CFHTTPCookieStorageCopyCookiesForURL(CFHTTPCookieStorageRef storage, CFURLRef url) {
//fixme respect the url
return CFHTTPCookieStorageCopyCookies(storage);
}
void CFHTTPCookieStorageSetCookies(CFHTTPCookieStorageRef storage, CFArrayRef cookies) {
//fixme bad big O.
for (int i=0; i<CFArrayGetCount(cookies); i++) {
CFHTTPCookieRef cookie = (CFHTTPCookieRef)CFArrayGetValueAtIndex(cookies, i);
CFHTTPCookieStorageSetCookie(storage, cookie);
}
}
void CFHTTPCookieStorageSetCookiesWithResponseHeaderFields(CFHTTPCookieStorageRef storage, CFDictionaryRef headerFields, CFURLRef url) {
CFArrayRef cookies = CFHTTPCookieCreateWithResponseHeaderFields(headerFields, url);
if (cookies != NULL) {
CFHTTPCookieStorageSetCookies(storage, cookies);
CFRelease(cookies);
}
}
CFDictionaryRef CFHTTPCookieStorageCopyRequestHeaderFieldsForURL(CFHTTPCookieStorageRef storage, CFURLRef url) {
return CFHTTPCookieCopyRequestHeaderFields(storage->_cookies);
}

Binary file not shown.

Binary file not shown.

5227
src/FTP/CFFTPStream.c Normal file

File diff suppressed because it is too large Load Diff

2876
src/HTTP/CFHTTPAuthentication.c Executable file

File diff suppressed because it is too large Load Diff

1263
src/HTTP/CFHTTPConnection.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#include <CoreFoundation/CoreFoundation.h>
#include "CFHTTPConnectionPriv.h"
#include "CFNetConnection.h"
struct _CFHTTPConnectionInfo {
CFStringRef host;
SInt32 port;
UInt32 type;
CFDictionaryRef streamProperties;
CFMutableSetRef authentications;
};
typedef struct _CFHTTPConnectionInfo _CFHTTPConnectionInfo;
#define HAVE_SENT_REQUEST_HEADERS (0)
#define HAVE_SENT_REQUEST_PAYLOAD (1)
#define HAVE_CHECKED_RESPONSE_HEADERS (2)
// Used to force end-of-stream when we know from the request/response that no data should come (like for a HEAD request)
#define FORCE_EOF (3)
#define PAYLOAD_IS_DATA (4)
#define OPEN_SIGNALLED (5)
#define HAS_PAYLOAD (6)
#define IS_ZOMBIE (7)
#define MIN_STATE_BIT (8)
#define MAX_STATE_BIT (11)
#define IN_READ_CALLBACK (12)
/* A bit of a hack to cover the fact that we may become the current response well before the net connection signals
us with stateChanged to prepareReception. The problem is that once we become the current response, we get the
response stream callbacks, which may include the mark (actually intended for the prior response) - we don't want
that to cause us to send an endEncountered event. Now, if we receive such an event and we have not yet read the mark,
we simply do so and continue. */
#define HAVE_READ_MARK (13)
struct _CFHTTPStreamInfo {
CFOptionFlags flags;
CFHTTPMessageRef request;
CFHTTPMessageRef responseHeaders;
CFReadStreamRef requestPayload; // May be NULL
CFDataRef requestFragment; // Fragmentary data read from requestPayload but not yet written
long long requestBytesWritten;
CFArrayRef peerCertificates; // Certificates received from peer
CFArrayRef clientCertificates; // Client certificate chain sent to peer
CFNumberRef clientCertificateState; // Holds a SSLClientCertificateState value; see <Security/SecureTransport.h>
_CFNetConnectionRef conn;
CFReadStreamRef stream; // The stream we returned for this request
CFRunLoopSourceRef stateChangeSource; // This source is used when we need to wait on an outside state change - either for bytes to come in on the connection, or for some request upstream of us to progress.
};
typedef struct _CFHTTPStreamInfo _CFHTTPStreamInfo;
/* Callbacks for _CFNetConnection */
static const void *httpConnectionCreate(CFAllocatorRef alloc, const void *info);
static void httpConnectionFinalize(CFAllocatorRef alloc, const void *info);
static CFStreamError httpConnectionCreateStreams(CFAllocatorRef allocator, const void *info, CFWriteStreamRef *requestStream, CFReadStreamRef *responseStream);
static void httpConnectionStateChanged(void *request, int newState, CFStreamError *err, _CFNetConnectionRef connection, const void *info);
static void httpConnectionTransmitRequest(void *request, _CFNetConnectionRef connection, const void *info);
static void httpConnectionReceiveResponse(void *request, _CFNetConnectionRef connection, const void *info);
static void httpConnectionResponseStreamCB(void *request, CFReadStreamRef stream, CFStreamEventType eventType, _CFNetConnectionRef conn, const void *info);
static void httpConnectionRequestStreamCB(void *request, CFWriteStreamRef stream, CFStreamEventType eventType, _CFNetConnectionRef conn, const void *info);
static CFArrayRef httpConnectionRLArrayForRequest(void *request, _CFNetConnectionRef conn, const void *info);
/* Callbacks for the read streams we return */
static void *httpStreamCreate(CFReadStreamRef stream, void *info);
static void httpStreamFinalize(CFReadStreamRef stream, void *info);
static CFStringRef httpStreamCopyDescription(CFReadStreamRef stream, void *info);
static Boolean httpStreamOpen(CFReadStreamRef stream, CFStreamError *error, Boolean *openComplete, void *info);
static Boolean httpStreamOpenCompleted(CFReadStreamRef stream, CFStreamError *error, void *info);
static CFIndex httpStreamRead(CFReadStreamRef stream, UInt8 *buffer, CFIndex bufferLength, CFStreamError *error, Boolean *atEOF, void *info);
static Boolean httpStreamCanRead(CFReadStreamRef stream, void *info);
static void httpStreamClose(CFReadStreamRef stream, void *info);
static CFTypeRef httpStreamCopyProperty(CFReadStreamRef stream, CFStringRef propertyName, void *info);
static Boolean httpStreamSetProperty(CFReadStreamRef stream, CFStringRef propertyName, CFTypeRef propertyValue, void *info);
static void httpStreamSchedule(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode, void *info);
static void httpStreamUnschedule(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode, void *info);
/* Other function prototypes */
static void httpRequestPayloadCallBack(CFReadStreamRef stream, CFStreamEventType type, void *info);
static void dequeueFromConnection(_CFHTTPStreamInfo *streamInfo);
static void destroyStreamInfo(CFAllocatorRef alloc, _CFHTTPStreamInfo *streamInfo);
static _CFHTTPStreamInfo *createZombieDouble(CFAllocatorRef alloc, _CFHTTPStreamInfo *orig, _CFNetConnectionRef conn);

1963
src/HTTP/CFHTTPFilter.c Normal file

File diff suppressed because it is too large Load Diff

117
src/HTTP/CFHTTPInternal.h Normal file
View File

@ -0,0 +1,117 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CFHTTPInternal.h
* CFNetwork
* Copyright (c) 2003 Apple Computer. All rights reserved.
*/
#if !defined(__CFNETWORK_CFHTTPINTERNAL__)
#define __CFNETWORK_CFHTTPINTERNAL__ 1
#include "CFNetConnection.h"
#include "CFNetworkInternal.h"
#include "CFNetConnection.h"
#include "CFNetworkPriv.h"
#define kCFStreamEventMarkEncountered (32)
#if defined(__cplusplus)
extern "C" {
#endif
extern CFHTTPAuthenticationRef _CFHTTPMessageGetAuthentication(CFHTTPMessageRef message, Boolean proxy);
extern void _CFHTTPMessageSetAuthentication(CFHTTPMessageRef message, CFHTTPAuthenticationRef auth, Boolean proxy);
extern void _CFHTTPMessageSetResponseURL(CFHTTPMessageRef response, CFURLRef url);
extern void _CFHTTPMessageSetHeader(CFHTTPMessageRef msg, CFStringRef theHeader, CFStringRef value, CFIndex position);
extern void _CFHTTPMessageSetLaxParsing(CFHTTPMessageRef msg, Boolean allowLaxParsing);
extern CFDataRef _CFHTTPMessageCopySerializedMessage(CFHTTPMessageRef msg, Boolean forProxy);
extern void _CFHTTPMessageSetHeader(CFHTTPMessageRef msg, CFStringRef theHeader, CFStringRef value, CFIndex position);
extern Boolean _CFHTTPMessageConvertToDataOnlyResponse(CFHTTPMessageRef message);
extern Boolean _CFHTTPMessageIsEmpty(CFHTTPMessageRef message);
extern Boolean _CFHTTPMessageCanStandAlone(CFHTTPMessageRef message);
extern CFDataRef _CFHTTPMessageGetBody(CFHTTPMessageRef msg);
extern Boolean _CFHTTPMessageIsGetMethod(CFHTTPMessageRef msg);
extern const CFStringRef _kCFStreamPropertyHTTPZeroLengthResponseExpected;
extern const CFStringRef _kCFStreamPropertyHTTPLaxParsing;
extern const CFStringRef _kCFStreamPropertyHTTPSProxyHoldYourFire;
// Internal support for persistant connection stuff
extern const CFStringRef _kCFStreamPropertyHTTPPersistent;
extern const CFStringRef _kCFStreamPropertyHTTPNewHeader;
extern const SInt32 _kCFStreamErrorHTTPStreamAtMark;
// Private HTTP error codes
extern const SInt32 _kCFStreamErrorHTTPSProxyFailure;
/* Mark management */
extern Boolean _CFHTTPReadStreamIsAtMark(CFReadStreamRef filteredStream);
extern void _CFHTTPReadStreamReadMark(CFReadStreamRef filteredStream);
extern void _CFHTTPWriteStreamWriteMark(CFWriteStreamRef filteredStream);
/* Utilities in CFHTTPStream.c */
extern void cleanUpRequest(CFHTTPMessageRef req, int length, Boolean forPersistentConnection, Boolean forProxy);
extern Boolean canKeepAlive(CFHTTPMessageRef responseHeaders, CFHTTPMessageRef request);
extern void emptyPerform(void *info);
extern CFStringRef _CFNetworkUserAgentString(void);
extern CFStringRef _CFEncodeBase64(CFAllocatorRef allocator, CFDataRef inputData);
extern CFDataRef _CFDecodeBase64(CFAllocatorRef allocator, CFStringRef inputStr);
extern const CFStringRef kCFHTTPAuthenticationSchemeBasic;
extern const CFStringRef kCFHTTPAuthenticationSchemeDigest;
extern const CFStringRef kCFHTTPAuthenticationSchemeNegotiate;
extern const CFStringRef kCFHTTPAuthenticationSchemeNTLM;
extern CFStringRef _CFCapitalizeHeader(CFStringRef headerString);
extern UInt8 *_CFURLPortionForRequest(CFAllocatorRef alloc, CFURLRef url, Boolean useCompleteURL, UInt8 **buf, CFIndex bufLength, Boolean *deallocateBuffer);
#if defined(__WIN32__)
extern void _CFHTTPMessageCleanup(void);
extern void _CFHTTPStreamCleanup(void);
// support from CFHTTPAUth-Win32.c
typedef struct _CFSSPIState *_CFSSPIStateRef;
extern Boolean _CFMD5(const UInt8* d, UInt32 n, UInt8* md, UInt32 md_length);
extern Boolean _CFSSPIPackageIsEnabled(const char *packageName);
extern _CFSSPIStateRef _CFCreateSSPIState(CFAllocatorRef alloc, CFStringRef method);
extern Boolean _CFTrySSPIHandshakeForHTTP(_CFSSPIStateRef sspi, CFStringRef username, CFStringRef password, CFStringRef principal, CFStringRef inputString, CFStringRef *outputString, CFStreamError* error);
extern void _CFFreeSSPIState(_CFSSPIStateRef sspi);
extern Boolean _CFCanTryKerberos(void);
#endif
#if defined(__cplusplus)
}
#endif
#endif /* ! __CFNETWORK_CFHTTPINTERNAL__ */

1248
src/HTTP/CFHTTPMessage.c Normal file

File diff suppressed because it is too large Load Diff

1471
src/HTTP/CFHTTPServer.c Normal file

File diff suppressed because it is too large Load Diff

2678
src/HTTP/CFHTTPStream.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,758 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* NTLM client-side authentication engine.
*
* In the usual absence of documentation from Microsoft, the "inventors" of this
* protocol, this module was written using the superb revers engineering documented
* at
*
* http://davenport.sourceforge.net/ntlm.html#localAuthentication
*/
#include "NtlmGenerator.h"
#include "ntlmBlobPriv.h"
#include <CoreServices/CoreServices.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <strings.h>
#include <security_cdsa_utils/cuCdsaUtils.h>
/*
* For debugging using fixed server challenge and client nonce.
*/
#if DEBUG_FIXED_CHALLENGE
/* these are "test vectors", effectively, from sourceforge */
/* use pwd SecREt01, host/domain DOMAIN */
static const unsigned char fixServerChallenge[8] =
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
static const unsigned char fixClientNonce[8] =
{ 0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44 };
static const unsigned char fixTargetInfo[] = {
0x02, 0x00, 0x0c, 0x00, 0x44, 0x00, 0x4f, 0x00,
0x4d, 0x00, 0x41, 0x00, 0x49, 0x00, 0x4e, 0x00,
0x01, 0x00, 0x0c, 0x00, 0x53, 0x00, 0x45, 0x00,
0x52, 0x00, 0x56, 0x00, 0x45, 0x00, 0x52, 0x00,
0x04, 0x00, 0x14, 0x00, 0x64, 0x00, 0x6f, 0x00,
0x6d, 0x00, 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00,
0x2e, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00,
0x03, 0x00, 0x22, 0x00, 0x73, 0x00, 0x65, 0x00,
0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00,
0x2e, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x6d, 0x00,
0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x2e, 0x00,
0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x00, 0x00,
0x00, 0x00
};
#endif
/* app's NtlmGeneratorRef is a pointer to one of these */
struct NtlmGenerator {
NLTM_Which mWhich;
CSSM_CSP_HANDLE mCspHand;
NLTM_Which mNegotiatedVersion;
uint32_t mSentFlags; /* the flags we sent in first mst */
};
static OSStatus _NtlmGeneratePasswordHashes(
CFAllocatorRef alloc,
NtlmGeneratorRef ntlm,
CFStringRef password,
CFDataRef* ntlmHash,
CFDataRef* lmHash);
/*
* Validate type 2 message sent by the server; return interesting fields.
* NOTE we do not deal with the Context field here, which is only used
* for local authetication.
*/
static OSStatus ntlmParseServerChallenge(
CFDataRef serverBlob,
uint32_t *serverFlags, /* RETURNED */
unsigned char *challenge, /* 8 bytes, mallocd by caller, RETURNED */
unsigned char **targetName, /* mallocd and RETURNED */
unsigned *targetNameLen, /* RETURNED */
unsigned char **targetInfo, /* optionally mallocd and RETURNED */
unsigned *targetInfoLen) /* optionally RETURNED */
{
int minLength;
*targetName = NULL;
*targetNameLen = 0;
*targetInfo = NULL;
*targetInfoLen = 0;
if(serverBlob == NULL) {
return NTLM_ERR_PARSE_ERR;
}
minLength = NTLM_SIGNATURE_LEN +
sizeof(uint32_t) + /* msg type */
NTLM_SIZEOF_SEC_BUF + /* target name */
sizeof(uint32_t) + /* flags */
NTLM_CHALLENGE_LEN;
CFIndex bufLen = CFDataGetLength(serverBlob);
if(bufLen < minLength) {
dprintf("ntlmParseServerChallenge: bad length\n");
return NTLM_ERR_PARSE_ERR;
}
/* do not even think of touching serverBlob after this */
const unsigned char *cp = CFDataGetBytePtr(serverBlob);
/* byte 0: signature */
if(memcmp(cp, NTLM_SIGNATURE, NTLM_SIGNATURE_LEN)) {
dprintf("ntlmParseServerChallenge: signature mismatch\n");
return NTLM_ERR_PARSE_ERR;
}
const unsigned char *currCp = cp + NTLM_SIGNATURE_LEN;
/* byte 8: message type */
uint32_t msgType = deserializeUint32(currCp);
if(msgType != NTLM_MSG_MARKER_TYPE2) {
dprintf("ntlmParseServerChallenge: bad msg type\n");
return NTLM_ERR_PARSE_ERR;
}
currCp += sizeof(uint32_t);
/* byte 12: target name, security buffer */
const unsigned char *sbData;
uint16_t sbLen;
OSStatus ortn = ntlmParseSecBuffer(currCp, cp, bufLen, &sbData, &sbLen);
if(ortn) {
return ortn;
}
*targetName = (unsigned char *)malloc(sbLen);
*targetNameLen = sbLen;
memmove(*targetName, sbData, sbLen);
currCp += NTLM_SIZEOF_SEC_BUF;
/* byte 20: flags */
*serverFlags = deserializeUint32(currCp);
currCp += sizeof(uint32_t);
/* byte 24: challenge */
#if DEBUG_FIXED_CHALLENGE
memmove(challenge, fixServerChallenge, NTLM_CHALLENGE_LEN);
#else
memmove(challenge, currCp, NTLM_CHALLENGE_LEN);
#endif
currCp += NTLM_CHALLENGE_LEN;
/* remaining fields optional */
const unsigned char *endOfBuf = cp + bufLen;
assert(endOfBuf >= currCp);
if(endOfBuf == currCp) {
return noErr;
}
if(endOfBuf < (currCp + NTLM_SIZEOF_SEC_BUF)) {
/* not enough left for even one security buf; ignore */
return noErr;
}
/* byte 32: context: skip */
currCp += NTLM_SIZEOF_SEC_BUF;
if(endOfBuf < (currCp + NTLM_SIZEOF_SEC_BUF)) {
/* not enough left for target info security buf; ignore */
return noErr;
}
/* byte 40: target info */
ortn = ntlmParseSecBuffer(currCp, cp, bufLen, &sbData, &sbLen);
if(ortn) {
free(*targetName);
*targetName = NULL;
return ortn;
}
#if DEBUG_FIXED_CHALLENGE
sbData = fixTargetInfo;
sbLen = sizeof(fixTargetInfo);
#endif /* DEBUG_FIXED_CHALLENGE */
*targetInfo = (unsigned char *)malloc(sbLen);
*targetInfoLen = sbLen;
memmove(*targetInfo, sbData, sbLen);
return noErr;
}
/*
* Create NTLMv2 responses (both NTLM and LM).
*/
static OSStatus ntlmGenerateNtlmV2Response(
CSSM_CSP_HANDLE cspHand,
/* from app */
CFStringRef domain,
CFStringRef userName,
CFDataRef ntlmHash,
/* from server */
const unsigned char *serverChallenge,
const unsigned char *targetInfo,
unsigned targetInfoLen,
/* returned */
unsigned char *lmV2Response, // caller supplied, NTLM_LM_RESPONSE_LEN bytes
unsigned char **ntlmv2Response, // mallocd and RETURNED
unsigned *ntlmV2ResponseLen) // RETURNED
{
/* Random challenge used in both responses */
unsigned char challenge[NTLM_CLIENT_NONCE_LEN];
#if DEBUG_FIXED_CHALLENGE
memmove(challenge, fixClientNonce, NTLM_CLIENT_NONCE_LEN);
#else
ntlmRand(NTLM_CLIENT_NONCE_LEN, challenge);
#endif
/* NTLM password hash */
unsigned char ntlmPwdHash[NTLM_DIGEST_LENGTH];
// ntlmPasswordHash(password, ntlmPwdHash);
memmove(ntlmPwdHash, CFDataGetBytePtr(ntlmHash), sizeof(ntlmPwdHash));
/* uppercase(userName | domain) */
CFMutableStringRef userDomain = CFStringCreateMutableCopy(NULL, 0, userName);
if(domain != NULL) {
CFStringAppend(userDomain, domain);
}
CFStringUppercase(userDomain, NULL);
/* declare some locals prior to any gotos */
unsigned char *ucode = NULL;
unsigned ucodeLen;
unsigned char ntlmV2Hash[NTLM_DIGEST_LENGTH];
unsigned char macText2[NTLM_CHALLENGE_LEN + NTLM_CLIENT_NONCE_LEN];
unsigned char challengeMac[NTLM_DIGEST_LENGTH];
unsigned char blobMac[NTLM_DIGEST_LENGTH];
unsigned char *ntlmv2Resp = NULL;
CFMutableDataRef ntlmV2Blob = NULL;
CFMutableDataRef catBlob = NULL;
unsigned ntlmV2BlobLen;
unsigned char blobSig[4] = {0x01, 0x01, 0x00, 0x00};
/* HMAC(passwordHash, uppercase(userName | domain)) */
ntlmStringToLE(userDomain, &ucode, &ucodeLen);
OSStatus ortn = ntlmHmacMD5(cspHand, ntlmPwdHash, NTLM_DIGEST_LENGTH,
ucode, ucodeLen, ntlmV2Hash);
if(ortn) {
goto errOut;
}
/* HMAC(ntlmV2Hash, serverChallenge | clientChallenge) */
memmove(macText2, serverChallenge, NTLM_CHALLENGE_LEN);
memmove(macText2 + NTLM_CHALLENGE_LEN, challenge, NTLM_CLIENT_NONCE_LEN);
ortn = ntlmHmacMD5(cspHand, ntlmV2Hash, NTLM_DIGEST_LENGTH,
macText2, NTLM_CHALLENGE_LEN + NTLM_CLIENT_NONCE_LEN, challengeMac);
if(ortn) {
goto errOut;
}
/* LMv2 response := challengeMac | clientChallenge */
memmove(lmV2Response, challengeMac, NTLM_DIGEST_LENGTH);
memmove(lmV2Response + NTLM_DIGEST_LENGTH, challenge, NTLM_CLIENT_NONCE_LEN);
/* Prepare the NTLMv2 'blob' */
ntlmV2Blob = CFDataCreateMutable(NULL, 0);
/* 0: 0x01010000 */
CFDataAppendBytes(ntlmV2Blob, blobSig, 4);
/* 4: reserved, zeroes */
appendUint32(ntlmV2Blob, 0);
/* 8: Timestamp */
ntlmAppendTimestamp(ntlmV2Blob);
/* 16: client challenge */
CFDataAppendBytes(ntlmV2Blob, challenge, NTLM_CLIENT_NONCE_LEN);
/* 24: unknown, zeroes */
appendUint32(ntlmV2Blob, 0);
/* 28: target info from server */
CFDataAppendBytes(ntlmV2Blob, targetInfo, targetInfoLen);
/* *: unknown, zeroes */
appendUint32(ntlmV2Blob, 0);
/* keep that blob; it'll go directly into the response. Now cook up
* another one, the concatentation of the server challenge with the
* ntlmV2Blob */
ntlmV2BlobLen = CFDataGetLength(ntlmV2Blob);
catBlob = CFDataCreateMutable(NULL, 0);
CFDataAppendBytes(catBlob, serverChallenge, NTLM_CHALLENGE_LEN);
CFDataAppendBytes(catBlob, CFDataGetBytePtr(ntlmV2Blob), ntlmV2BlobLen);
/* HMAC(ntlmV2Hash, serverChallenge | blob) */
ortn = ntlmHmacMD5(cspHand, ntlmV2Hash, NTLM_DIGEST_LENGTH,
CFDataGetBytePtr(catBlob), CFDataGetLength(catBlob),
blobMac);
if(ortn) {
goto errOut;
}
/* Finally, NTLMv2 response := (blobMac | ntlmV2Blob) */
ntlmv2Resp = (unsigned char *)malloc(NTLM_DIGEST_LENGTH + ntlmV2BlobLen);
memmove(ntlmv2Resp, blobMac, NTLM_DIGEST_LENGTH);
memmove(ntlmv2Resp + NTLM_DIGEST_LENGTH, CFDataGetBytePtr(ntlmV2Blob), ntlmV2BlobLen);
*ntlmv2Response = ntlmv2Resp;
*ntlmV2ResponseLen = NTLM_DIGEST_LENGTH + ntlmV2BlobLen;
ortn = noErr;
errOut:
if(userDomain) {
CFRelease(userDomain);
}
if(ntlmV2Blob) {
CFRelease(ntlmV2Blob);
}
if(catBlob) {
CFRelease(catBlob);
}
CFREE(ucode);
return ortn;
}
/*
* Create/release NtlmGenerator objects.
*/
OSStatus NtlmGeneratorCreate(
NLTM_Which which,
NtlmGeneratorRef *ntlmGen) /* RETURNED */
{
struct NtlmGenerator *gen =
(struct NtlmGenerator *)malloc(sizeof(struct NtlmGenerator));
if(gen == NULL) {
return memFullErr;
}
gen->mWhich = which;
gen->mCspHand = cuCspStartup(CSSM_TRUE);
if(gen->mCspHand == 0) {
return internalComponentErr;
}
gen->mNegotiatedVersion = 0; /* i.e., unknown */
gen->mSentFlags = 0;
*ntlmGen = gen;
return noErr;
}
void NtlmGeneratorRelease(
NtlmGeneratorRef ntlmGen)
{
if(ntlmGen == NULL) {
return;
}
if(ntlmGen->mCspHand) {
cuCspDetachUnload(ntlmGen->mCspHand, CSSM_TRUE);
}
free(ntlmGen);
}
OSStatus NtlmCreateClientRequest(
NtlmGeneratorRef ntlmGen,
CFDataRef *clientRequest) /* RETURNED */
{
CFMutableDataRef req = CFDataCreateMutable(NULL, 0);
if(req == NULL) {
return memFullErr;
}
/* byte 0: signature, NULL terminated */
CFDataAppendBytes(req, (UInt8 *)NTLM_SIGNATURE, NTLM_SIGNATURE_LEN);
/* byte 8: message type */
appendUint32(req, NTLM_MSG_MARKER_TYPE1);
/* byte 12: the standard flags we send - we're wide open to all types */
/* FIXME isn't there a way to tell the server we support NTLMv2? */
ntlmGen->mSentFlags = NTLM_NegotiateUnicode |
NTLM_NegotiateOEM |
NTLM_RequestTarget |
NTLM_NegotiateNTLM |
NTLM_AlwaysSign;
if(ntlmGen->mWhich & NW_NTLM2) {
ntlmGen->mSentFlags |= NTLM_NegotiateNTLM2Key;
}
appendUint32(req, ntlmGen->mSentFlags);
/* byte 16: optional supplied domain: not needed */
CFIndex dex;
appendSecBuf(req, 0, &dex);
/* byte 24: optional supplied workstation: not needed */
appendSecBuf(req, 0, &dex);
*clientRequest = req;
return noErr;
}
/*
* The meat & potatoes: given a server type 2 message, cook up a type 3 response.
*/
OSStatus NtlmCreateClientResponse(
NtlmGeneratorRef ntlmGen,
CFDataRef serverBlob,
CFStringRef domain, /* optional */
CFStringRef userName,
CFStringRef password,
CFDataRef *clientResponse) /* RETURNED */
{
CFDataRef ntlmHash = NULL;
CFDataRef lmHash = NULL;
OSStatus result = _NtlmGeneratePasswordHashes(kCFAllocatorDefault, ntlmGen, password, &ntlmHash, &lmHash);
if (result == noErr) {
result = _NtlmCreateClientResponse(ntlmGen, serverBlob, domain, userName, ntlmHash, lmHash, clientResponse);
}
if (ntlmHash)
CFRelease(ntlmHash);
if (lmHash)
CFRelease(lmHash);
return result;
}
OSStatus _NtlmCreateClientResponse(
NtlmGeneratorRef ntlmGen,
CFDataRef serverBlob,
CFStringRef domain, /* optional */
CFStringRef userName,
CFDataRef ntlmHash,
CFDataRef lmHash,
CFDataRef *clientResponse) /* RETURNED */
{
OSStatus ortn;
uint32_t serverFlags;
unsigned char serverChallenge[NTLM_CHALLENGE_LEN];
unsigned char *targetName = NULL;
unsigned targetNameLen = 0;
unsigned char *targetInfo = NULL;
unsigned targetInfoLen = 0;
CFIndex lmRespOffset;
unsigned char lmResp[NTLM_LM_RESPONSE_LEN];
CFIndex ntlmRespOffset;
unsigned char ntlmResp[NTLM_LM_RESPONSE_LEN];
unsigned char *ntlmResponsePtr = NULL;
unsigned ntlmResponseLen = 0;
unsigned char *domainNameFlat = NULL;
unsigned domainNameFlatLen = 0;
CFIndex domainNameOffset;
unsigned char *userNameFlat = NULL;
unsigned userNameFlatLen = 0;
CFIndex userNameOffset;
unsigned char *workstationName = NULL;
unsigned workstationNameLen = 0;
CFIndex workstationNameOffset;
CFIndex nullDex;
unsigned char pwdHash[NTLM_DIGEST_LENGTH];
ortn = ntlmParseServerChallenge(serverBlob, &serverFlags, serverChallenge,
&targetName, &targetNameLen,
&targetInfo, &targetInfoLen);
if(ortn) {
return ortn;
}
/* subsequent errors to errOut: */
/* gather negotiated parameters */
bool lm2Key = (serverFlags & NTLM_NegotiateNTLM2Key) ? true : false;
bool unicode = (serverFlags & NTLM_NegotiateUnicode) ? true : false;
/* any others? */
CFMutableDataRef clientBuf = CFDataCreateMutable(NULL, 0);
if(clientBuf == NULL) {
ortn = memFullErr;
goto errOut;
}
if (domain) {
domain = CFStringCreateMutableCopy(NULL, 0, domain);
if (domain)
CFStringUppercase((CFMutableStringRef)domain, NULL);
else {
ortn = memFullErr;
goto errOut;
}
}
/* byte 0: signature, NULL terminated */
CFDataAppendBytes(clientBuf, (UInt8 *)NTLM_SIGNATURE, NTLM_SIGNATURE_LEN);
/* byte 8: message type */
appendUint32(clientBuf, NTLM_MSG_MARKER_TYPE3);
/* LM and NTLM responses */
if( (targetInfo != NULL) && // server is NTLMv2 capable
(targetInfoLen != 0) && // ditto
(serverFlags & NTLM_NegotiateTargetInfo) && // ditto
(ntlmGen->mWhich & NW_NTLMv2) ) { // ...and we are
/*
* NTLMv2
*/
ortn = ntlmGenerateNtlmV2Response(ntlmGen->mCspHand,
domain, userName, ntlmHash,
serverChallenge, targetInfo, targetInfoLen,
lmResp, &ntlmResponsePtr, &ntlmResponseLen);
if(ortn) {
goto errOut;
}
/*
* Write security buffers.
*
* byte 12: LM response
* byte 20: NTLM response
*/
appendSecBuf(clientBuf, NTLM_LM_RESPONSE_LEN, &lmRespOffset);
appendSecBuf(clientBuf, ntlmResponseLen, &ntlmRespOffset);
ntlmGen->mNegotiatedVersion = NW_NTLMv2;
}
else {
if(lm2Key && (ntlmGen->mWhich & NW_NTLM2)) {
/* LM response: 8 random bytes, rest zeroes */
#if DEBUG_FIXED_CHALLENGE
memmove(lmResp, fixClientNonce, NTLM_CLIENT_NONCE_LEN);
#else
ntlmRand(NTLM_CLIENT_NONCE_LEN, lmResp);
#endif
memset(lmResp + NTLM_CLIENT_NONCE_LEN, 0,
NTLM_LM_RESPONSE_LEN - NTLM_CLIENT_NONCE_LEN);
/* session nonce: server challenge | client nonce */
unsigned char sessionNonce[NTLM_CHALLENGE_LEN + NTLM_CLIENT_NONCE_LEN];
memmove(sessionNonce, serverChallenge, NTLM_CHALLENGE_LEN);
memmove(sessionNonce + NTLM_CHALLENGE_LEN, lmResp, NTLM_CLIENT_NONCE_LEN);
/* NTLM2 session hash: the first 8 bytes of MD5(sessionNonce) */
unsigned char sessionHash[NTLM_DIGEST_LENGTH];
md5Hash(sessionNonce, NTLM_CHALLENGE_LEN + NTLM_CLIENT_NONCE_LEN, sessionHash);
/* standard password hash */
// ntlmPasswordHash(password, pwdHash);
memmove(pwdHash, CFDataGetBytePtr(ntlmHash), sizeof(pwdHash));
/* NTLM response: DES with three different keys */
ortn = ntlmResponse(ntlmGen->mCspHand, pwdHash, sessionHash, ntlmResp);
if(ortn) {
dprintf("***Error on ntlmResponse (3)\n");
goto errOut;
}
ntlmGen->mNegotiatedVersion = NW_NTLM2;
}
else if(ntlmGen->mWhich & NW_NTLM1) {
/*
* LM response - the old style 2-DES "password hash" applied
* the the server's challenge
*/
// ortn = lmPasswordHash(ntlmGen->mCspHand, password, pwdHash);
// if(ortn) {
// dprintf("***Error on lmPasswordHash\n");
// goto errOut;
// }
memmove(pwdHash, CFDataGetBytePtr(lmHash), sizeof(pwdHash));
ortn = ntlmResponse(ntlmGen->mCspHand, pwdHash, serverChallenge, lmResp);
if(ortn) {
dprintf("***Error on ntlmResponse (1)\n");
goto errOut;
}
/*
* NTLM response: md4 password hash, DES with three different keys
*/
// ntlmPasswordHash(password, pwdHash);
memmove(pwdHash, CFDataGetBytePtr(ntlmHash), sizeof(pwdHash));
ortn = ntlmResponse(ntlmGen->mCspHand, pwdHash, serverChallenge, ntlmResp);
if(ortn) {
dprintf("***Error on ntlmResponse (2)\n");
goto errOut;
}
ntlmGen->mNegotiatedVersion = NW_NTLM1;
}
else {
dprintf("***NTLM protocol mismatch\n");
ortn = NTLM_ERR_PROTOCOL_MISMATCH;
goto errOut;
}
/*
* Write security buffers.
*
* byte 12: LM response
* byte 20: NTLM response
*/
appendSecBuf(clientBuf, NTLM_LM_RESPONSE_LEN, &lmRespOffset);
appendSecBuf(clientBuf, NTLM_LM_RESPONSE_LEN, &ntlmRespOffset);
ntlmResponsePtr = ntlmResp;
ntlmResponseLen = NTLM_LM_RESPONSE_LEN;
} /* not NTLMv2 */
/*
* convert domain and user as appropriate
* byte 28: domain (server) name
*/
if(domain != NULL) {
ortn = ntlmStringFlatten(domain, unicode, &domainNameFlat, &domainNameFlatLen);
if(ortn) {
dprintf("createClientResponse: error converting domain name\n");
ortn = NTLM_ERR_PARSE_ERR;
goto errOut;
}
}
appendSecBuf(clientBuf, domainNameFlatLen, &domainNameOffset);
/* byte 36: user name */
ortn = ntlmStringFlatten(userName, unicode, &userNameFlat, &userNameFlatLen);
if(ortn) {
dprintf("createClientResponse: error converting user name\n");
ortn = NTLM_ERR_PARSE_ERR;
goto errOut;
}
appendSecBuf(clientBuf, userNameFlatLen, &userNameOffset);
/* byte 44: hostname */
ortn = ntlmHostName(unicode, &workstationName, &workstationNameLen);
if(ortn) {
dprintf("createClientResponse: error getting host name\n");
goto errOut;
}
appendSecBuf(clientBuf, workstationNameLen, &workstationNameOffset);
/* byte 52: session key (whatever that is): optional, empty here */
appendSecBuf(clientBuf, 0, &nullDex);
/* byte 60: negotiated flags */
appendUint32(clientBuf, ntlmGen->mSentFlags & serverFlags);
/* finally, the data associated with the security buffers */
secBufOffset(clientBuf, lmRespOffset);
CFDataAppendBytes(clientBuf, lmResp, NTLM_LM_RESPONSE_LEN);
secBufOffset(clientBuf, ntlmRespOffset);
CFDataAppendBytes(clientBuf, ntlmResponsePtr, ntlmResponseLen);
if(domain != NULL) {
secBufOffset(clientBuf, domainNameOffset);
CFDataAppendBytes(clientBuf, domainNameFlat, domainNameFlatLen);
}
secBufOffset(clientBuf, userNameOffset);
CFDataAppendBytes(clientBuf, userNameFlat, userNameFlatLen);
secBufOffset(clientBuf, workstationNameOffset);
CFDataAppendBytes(clientBuf, workstationName, workstationNameLen);
errOut:
CFREE(targetName);
CFREE(targetInfo);
CFREE(domainNameFlat);
CFREE(userNameFlat);
CFREE(workstationName);
if (domain) CFRelease(domain);
if(ntlmResponsePtr != ntlmResp) {
/* i.e., it was mallocd by ntlmGenerateNtlmV2Response */
CFREE(ntlmResponsePtr);
}
if(ortn == noErr) {
*clientResponse = clientBuf;
}
else {
CFRelease(clientBuf);
}
return ortn;
}
/* replacement for NtlmNegotiatedNtlm2: returns NW_NTLM1Only, NW_NTLM2Only,
* or NW_NTLMv2Only */
NLTM_Which NtlmGetNegotiatedVersion(
NtlmGeneratorRef ntlmGen)
{
return ntlmGen->mNegotiatedVersion;
}
OSStatus _NtlmGeneratePasswordHashes(
CFAllocatorRef alloc,
NtlmGeneratorRef ntlm,
CFStringRef password,
CFDataRef* ntlmHash,
CFDataRef* lmHash)
{
OSStatus result = noErr;
unsigned char hash[NTLM_DIGEST_LENGTH];
ntlmPasswordHash(password, hash);
*ntlmHash = CFDataCreate(alloc, hash, sizeof(hash));
result = lmPasswordHash(ntlm->mCspHand, password, hash);
if (result == noErr)
*lmHash = CFDataCreate(alloc, hash, sizeof(hash));
return result;
}
OSStatus NtlmGeneratePasswordHashes(
CFAllocatorRef alloc,
CFStringRef password,
CFDataRef* ntlmHash,
CFDataRef* lmHash)
{
NtlmGeneratorRef ntlm = NULL;
OSStatus result = NtlmGeneratorCreate(NW_Any, &ntlm);
if (result == noErr) {
result = _NtlmGeneratePasswordHashes(alloc, ntlm, password, ntlmHash, lmHash);
}
if (ntlm)
NtlmGeneratorRelease(ntlm);
return result;
}

View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef _NTLM_GENERATOR_H_
#define _NTLM_GENERATOR_H_
#include <CoreFoundation/CFData.h>
#include <CoreFoundation/CFString.h>
#include <Security/cssmtype.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* This interface provides the capability to generate and parse the authentication
* blobs which pass back and forth between a client and a server during NTLM
* authentication. Only the client side is implemented.
*
* All three variants of NTLM authentication are performed: NTLM1, NTLM2, and
* NTLMv2.
*
* In general, to use this stuff for HTTP authentication:
*
* 1. Determine that NTLM authentication is possible. Drop the connection
* to the server if you have a persistent connection open; MS servers
* require a clean unused connection for this negotiation to occur.
*
* 2. Create a NtlmGeneratorRef object, specifying possible restrictions
* on negotiation version.
*
* 3. Create the client authentication blob using NtlmCreateClientRequest()
* and send it to the server, base64 encoded, in a "Authorization: NTLM"
* header line.
*
* 4. The server should send back another 401 status, with its own blob in
* a "WWW-Authenticate: NTLM" header.
*
* 5. Base64 decode that blob and feed it into NtlmCreateClientResponse(), the
* output of which is another blob which you send to the server again in
* a "WWW-Authenticate: NTLM" header.
*
* 6. If you're lucky the server will give a 200 status (or something else useful
* other than 401) and you're done.
*
* 7. Free the NtlmGeneratorRef object with NtlmGeneratorRelease().
*/
/*
* Opaque reference to an NTLM blob generator object.
*/
typedef struct NtlmGenerator *NtlmGeneratorRef;
/*
* Which versions of the protocol are acceptable?
*/
enum {
NW_NTLM1 = 0x00000001,
NW_NTLM2 = 0x00000002,
NW_NTLMv2 = 0x00000004,
// all variants enabled, preferring NTLMv2, then NTLM2, then NTLM1
NW_Any = NW_NTLM1 | NW_NTLM2 | NW_NTLMv2
};
typedef uint32_t NLTM_Which;
/* Create/release NtlmGenerator objects.*/
OSStatus NtlmGeneratorCreate(
NLTM_Which which,
NtlmGeneratorRef *ntlmGen); /* RETURNED */
void NtlmGeneratorRelease(
NtlmGeneratorRef ntlmGen);
/* create the initial client request */
OSStatus NtlmCreateClientRequest(
NtlmGeneratorRef ntlmGen,
CFDataRef *clientRequest); /* RETURNED */
/* parse server challenge and respond to it */
OSStatus NtlmCreateClientResponse(
NtlmGeneratorRef ntlmGen,
CFDataRef serverBlob, /* obtained from the server */
CFStringRef domain, /* server domain, appears to be optional */
CFStringRef userName,
CFStringRef password,
CFDataRef *clientResponse); /* RETURNED */
/* which version did we negotiate? Returns true for NTLM2, false for traditional NTLM */
bool NtlmNegotiatedNtlm2(
NtlmGeneratorRef ntlmGen);
/* which version did we negotiate? */
NLTM_Which NtlmGetNegotiatedVersion(
NtlmGeneratorRef ntlmGen);
OSStatus NtlmGeneratePasswordHashes(
CFAllocatorRef alloc,
CFStringRef password,
CFDataRef* ntlmHash,
CFDataRef* lmHash);
OSStatus _NtlmCreateClientResponse(
NtlmGeneratorRef ntlmGen,
CFDataRef serverBlob,
CFStringRef domain, /* optional */
CFStringRef userName,
CFDataRef ntlmHash,
CFDataRef lmHash,
CFDataRef *clientResponse); /* RETURNED */
#ifdef __cplusplus
}
#endif
#endif /* _NTLM_GENERATOR_H_ */

View File

@ -0,0 +1,622 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Private routines used by NtlmGenerator module.
*/
#include "ntlmBlobPriv.h"
#include <CoreServices/CoreServices.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <sys/param.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <fcntl.h>
#include <ctype.h>
#include <strings.h>
#include <CommonCrypto/CommonDigest.h>
#include <Security/cssmapi.h>
#include <Security/cssmapple.h>
#include <CoreFoundation/CFDate.h>
#if DEBUG_FIXED_CHALLENGE
/* Fixed 64-bit timestamp for sourceforge test vectors */
static unsigned char dbgStamp[] =
{
0x00, 0x90, 0xd3, 0x36, 0xb7, 0x34, 0xc3, 0x01
};
#endif /* DEBUG_FIXED_CHALLENGE */
#pragma mark --- encode/decode routines ---
/* uint32_t <--> unsigned char array */
void serializeUint32(
uint32_t num,
unsigned char *buf)
{
buf[0] = num & 0xff;
buf[1] = num >> 8;
buf[2] = num >> 16;
buf[3] = num >> 24;
}
uint32_t deserializeUint32(
const unsigned char *buf)
{
uint32_t rtn = *buf++;
rtn |= ((uint32_t)(*buf++)) << 8;
rtn |= ((uint32_t)(*buf++)) << 16;
rtn |= ((uint32_t)(*buf)) << 24;
return rtn;
}
uint16_t deserializeUint16(
const unsigned char *buf)
{
uint16_t rtn = *buf++;
rtn |= ((uint16_t)(*buf)) << 8;
return rtn;
}
/* write a 32-bit word, little endian */
void appendUint32(
CFMutableDataRef buf,
uint32_t word)
{
unsigned char cb[4];
serializeUint32(word, cb);
CFDataAppendBytes(buf, cb, 4);
}
/* write a 16-bit word, little endian */
void appendUint16(
CFMutableDataRef buf,
uint16_t word)
{
unsigned char cb[2];
cb[0] = word & 0xff;
cb[1] = word >> 8;
CFDataAppendBytes(buf, cb, 2);
}
/*
* Write a security buffer, providing the index into the CFData at which
* this security buffer's offset is located. Just before the actual data is written,
* go back and update the offset with the start of that data using secBufOffset().
*/
void appendSecBuf(
CFMutableDataRef buf,
uint16_t len,
CFIndex *offsetIndex)
{
appendUint16(buf, len); /* buffer length */
appendUint16(buf, len); /* buffer allocated size */
*offsetIndex = CFDataGetLength(buf); /* offset will go here */
appendUint32(buf, 0); /* but it's empty for now */
}
/*
* Update a security buffer's offset to be the current end of data in a CFData.
*/
void secBufOffset(
CFMutableDataRef buf,
CFIndex offsetIndex) /* obtained from appendSecBuf() */
{
CFIndex currPos = CFDataGetLength(buf);
unsigned char cb[4];
serializeUint32((uint32_t)currPos, cb);
CFRange range = {offsetIndex, 4};
CFDataReplaceBytes(buf, range, cb, 4);
}
/*
* Parse/validate a security buffer. Verifies that supplied offset/length don't go
* past end of avaialble data. Returns ptr to actual data and its length. Returns
* NTLM_ERR_PARSE_ERR on bogus values.
*/
OSStatus ntlmParseSecBuffer(
const unsigned char *cp, /* start of security buffer */
const unsigned char *bufStart, /* start of whole msg buffer */
unsigned bufLen, /* # of valid bytes starting at bufStart */
const unsigned char **data, /* RETURNED, start of actual data */
uint16_t *dataLen) /* RETURNED, length of actual data */
{
assert(cp >= bufStart);
uint16_t secBufLen = deserializeUint16(cp);
/* skip length we just parsed plus alloc size, which we don't use */
cp += 4;
uint32_t offset = deserializeUint32(cp);
if((offset + secBufLen) > bufLen) {
dprintf("ntlmParseSecBuffer: buf overflow\n");
return NTLM_ERR_PARSE_ERR;
}
*data = bufStart + offset;
*dataLen = secBufLen;
return noErr;
}
#pragma mark --- CFString converters ---
/*
* Convert CFString to little-endian unicode.
*/
void ntlmStringToLE(
CFStringRef pwd,
unsigned char **ucode, // mallocd and RETURNED
unsigned *ucodeLen) // RETURNED
{
CFIndex len = CFStringGetLength(pwd);
unsigned char *data = (unsigned char *)malloc(len * 2);
unsigned char *cp = data;
for(CFIndex dex=0; dex<len; dex++) {
UniChar uc = CFStringGetCharacterAtIndex(pwd, dex);
*cp++ = uc & 0xff;
*cp++ = uc >> 8;
}
*ucode = data;
*ucodeLen = len * 2;
}
/*
* Convert a CFStringRef into a mallocd array of chars suitable for the specified
* encoding. This might return an error if the string can't be converted
* appropriately.
*/
OSStatus ntlmStringFlatten(
CFStringRef str,
bool unicode,
unsigned char **flat, // mallocd and RETURNED
unsigned *flatLen) // RETURNED
{
if(unicode) {
/* convert to little-endian unicode */
ntlmStringToLE(str, flat, flatLen);
return noErr;
}
else {
/* convert to ASCII C string */
CFIndex strLen = CFStringGetLength(str);
char *cStr = (char *)malloc(strLen + 1);
if(cStr == NULL) {
return memFullErr;
}
if(CFStringGetCString(str, cStr, strLen + 1, kCFStringEncodingASCII)) {
*flat = (unsigned char *)cStr;
*flatLen = strLen;
return noErr;
}
/*
* Well that didn't work. Try UTF8 - I don't know how a MS would behave if
* this portion of auth (only used for the LM response) didn't work.
*/
dprintf("lmPasswordHash: ASCII password conversion failed; trying UTF8\n");
free(cStr);
cStr = (char *)malloc(strLen * 4);
if(cStr == NULL) {
return memFullErr;
}
if(CFStringCreateExternalRepresentation(NULL, str, kCFStringEncodingUTF8, 0)) {
*flat = (unsigned char *)cStr;
*flatLen = strLen;
return noErr;
}
dprintf("lmPasswordHash: UTF8 password conversion failed\n");
free(cStr);
return NTLM_ERR_PARSE_ERR;
}
}
#pragma mark --- machine dependent cruft ---
/* random number generator */
void ntlmRand(
unsigned len,
void *buf) /* allocated by caller, random data RETURNED */
{
int fd = open("/dev/random", O_RDONLY, 0);
if(fd < 0) {
dprintf("***ntlmRand failed to open /dev/random\n");
return;
}
read(fd, buf, len);
close(fd);
}
/* Obtain host name in appropriate encoding */
OSStatus ntlmHostName(
bool unicode,
unsigned char **flat, // mallocd and RETURNED
unsigned *flatLen) // RETURNED
{
char hostname[MAXHOSTNAMELEN];
if(gethostname(hostname, MAXHOSTNAMELEN)) {
#ifndef NDEBUG
perror("gethostname");
#endif
return internalComponentErr;
}
int len = strlen(hostname);
if(unicode) {
/* quickie "little endian unicode" conversion */
*flat = (unsigned char *)malloc(len * 2);
unsigned char *cp = *flat;
for(int dex=0; dex<len; dex++) {
*cp++ = hostname[dex];
*cp++ = 0;
}
*flatLen = len * 2;
return noErr;
}
else {
*flat = (unsigned char *)malloc(len);
*flatLen = len;
memmove(*flat, hostname, len);
return noErr;
}
}
/*
* Append 64-bit little-endiam timestamp to a CFData. Time is relative to
* January 1 1601, in tenths of a microsecond.
*/
static const CFGregorianDate ntlmTimeBasis =
{
1601, // year
1, // month
1, // day
0, // hour
0, // minute
0.0 // second
};
void ntlmAppendTimestamp(
CFMutableDataRef ntlmV2Blob)
{
#if DEBUG_FIXED_CHALLENGE
/* Fixed 64-bit timestamp for sourceforge test vectors */
CFDataAppendBytes(ntlmV2Blob, dbgStamp, 8);
#else
assert(CFGregorianDateIsValid(ntlmTimeBasis, kCFGregorianAllUnits));
/* NULL OK for CFTimeZoneRef? */
CFAbsoluteTime basisTime = CFGregorianDateGetAbsoluteTime(ntlmTimeBasis, NULL);
CFAbsoluteTime nowTime = CFAbsoluteTimeGetCurrent();
/* elapsed := time in seconds since basis */
CFTimeInterval elapsed = nowTime - basisTime;
/* now in tenths of microseconds */
elapsed *= 10000000.0;
uint32 lowWord = (uint32)elapsed;
elapsed /= 0x100000000ULL;
uint32 highWord = (uint32)elapsed;
/* append this in little endian format */
appendUint32(ntlmV2Blob, lowWord);
appendUint32(ntlmV2Blob, highWord);
#endif
}
#pragma mark --- crypto ---
/* MD4 and MD5 hash */
#define NTLM_DIGEST_LENGTH 16
void md4Hash(
const unsigned char *data,
unsigned dataLen,
unsigned char *digest) // caller-supplied, NTLM_DIGEST_LENGTH */
{
CC_MD4_CTX ctx;
CC_MD4_Init(&ctx);
CC_MD4_Update(&ctx, data, dataLen);
CC_MD4_Final(digest, &ctx);
}
void md5Hash(
const unsigned char *data,
unsigned dataLen,
unsigned char *digest) // caller-supplied, NTLM_DIGEST_LENGTH */
{
CC_MD5_CTX ctx;
CC_MD5_Init(&ctx);
CC_MD5_Update(&ctx, data, dataLen);
CC_MD5_Final(digest, &ctx);
}
/*
* Given 7 bytes, create 8-byte DES key. Our implementation ignores the
* parity bit (lsb), which simplifies this somewhat.
*/
void ntlmMakeDesKey(
const unsigned char *inKey, // 7 bytes
unsigned char *outKey) // 8 bytes
{
outKey[0] = inKey[0] & 0xfe;
outKey[1] = ((inKey[0] << 7) | (inKey[1] >> 1)) & 0xfe;
outKey[2] = ((inKey[1] << 6) | (inKey[2] >> 2)) & 0xfe;
outKey[3] = ((inKey[2] << 5) | (inKey[3] >> 3)) & 0xfe;
outKey[4] = ((inKey[3] << 4) | (inKey[4] >> 4)) & 0xfe;
outKey[5] = ((inKey[4] << 3) | (inKey[5] >> 5)) & 0xfe;
outKey[6] = ((inKey[5] << 2) | (inKey[6] >> 6)) & 0xfe;
outKey[7] = (inKey[6] << 1) & 0xfe;
}
static void ntlmSetupKey(
CSSM_ALGORITHMS alg,
const unsigned char *keyData,
unsigned keyDataLen, /* in bytes */
unsigned logicalKeySizeInBits,
CSSM_KEY_PTR ckey)
{
memset(ckey, 0, sizeof(*ckey));
CSSM_KEYHEADER &hdr = ckey->KeyHeader;
hdr.BlobType = CSSM_KEYBLOB_RAW;
hdr.Format = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
hdr.AlgorithmId = alg;
hdr.KeyClass = CSSM_KEYCLASS_SESSION_KEY;
hdr.LogicalKeySizeInBits = logicalKeySizeInBits;
hdr.KeyUsage = CSSM_KEYUSE_ANY;
ckey->KeyData.Data = (uint8 *)keyData;
ckey->KeyData.Length = keyDataLen;
}
/*
* single block DES encrypt.
* This would really benefit from a DES implementation in CommonCrypto.
*/
OSStatus ntlmDesCrypt(
CSSM_CSP_HANDLE cspHand,
const unsigned char *key, // 8 bytes
const unsigned char *inData, // 8 bytes
const unsigned char *outData) // 8 bytes
{
CSSM_CC_HANDLE ccHand;
CSSM_RETURN crtn;
CSSM_KEY ckey;
ntlmSetupKey(CSSM_ALGID_DES, key, DES_KEY_SIZE,
DES_RAW_KEY_SIZE * 8, &ckey);
crtn = CSSM_CSP_CreateSymmetricContext(cspHand,
CSSM_ALGID_DES,
CSSM_ALGMODE_ECB,
NULL, // access cred
&ckey,
NULL, // InitVector
CSSM_PADDING_NONE,
NULL, // Params
&ccHand);
if(crtn) {
#ifndef NDEBUG
cssmPerror("CSSM_CSP_CreateSymmetricContext", crtn);
#endif
return crtn;
}
CSSM_DATA ptext = {8, (uint8 *)inData};
CSSM_DATA ctext = {9, (uint8 *)outData};
uint32 bytesEncrypted;
crtn = CSSM_EncryptDataInit(ccHand);
if(crtn) {
#ifndef NDEBUG
cssmPerror("CSSM_EncryptDataInit", crtn);
#endif
goto errOut;
}
crtn = CSSM_EncryptDataUpdate(ccHand,
&ptext, 1,
&ctext, 1,
&bytesEncrypted);
if(crtn) {
#ifndef NDEBUG
cssmPerror("CSSM_EncryptDataUpdate", crtn);
#endif
}
errOut:
CSSM_DeleteContext(ccHand);
return crtn;
}
/*
* HMAC/MD5.
*/
OSStatus ntlmHmacMD5(
CSSM_CSP_HANDLE cspHand,
const unsigned char *key,
unsigned keyLen,
const unsigned char *inData,
unsigned inDataLen,
unsigned char *mac) // caller provided, NTLM_DIGEST_LENGTH
{
CSSM_CC_HANDLE ccHand;
CSSM_RETURN crtn;
CSSM_KEY ckey;
CSSM_DATA cdata = { inDataLen, (uint8 *)inData };
ntlmSetupKey(CSSM_ALGID_MD5HMAC, key, keyLen,
keyLen * 8, &ckey);
crtn = CSSM_CSP_CreateMacContext(cspHand,
CSSM_ALGID_MD5HMAC, &ckey, &ccHand);
if(crtn) {
#ifndef NDEBUG
cssmPerror("CSSM_CSP_CreateMacContext", crtn);
#endif
return crtn;
}
crtn = CSSM_GenerateMacInit(ccHand);
if(crtn) {
#ifndef NDEBUG
cssmPerror("CSSM_GenerateMacInit", crtn);
#endif
goto errOut;
}
crtn = CSSM_GenerateMacUpdate(ccHand, &cdata, 1);
if(crtn) {
#ifndef NDEBUG
cssmPerror("CSSM_GenerateMacUpdate", crtn);
#endif
goto errOut;
}
/* provide pre-allocated output buffer */
cdata.Data = (uint8 *)mac;
cdata.Length = NTLM_DIGEST_LENGTH;
crtn = CSSM_GenerateMacFinal(ccHand, &cdata);
if(crtn) {
#ifndef NDEBUG
cssmPerror("CSSM_GenerateMacFinal", crtn);
#endif
}
errOut:
CSSM_DeleteContext(ccHand);
return crtn;
}
#pragma mark --- LM and NTLM password and digest munging ---
/*
* Calculate LM-style password hash. This really only works if the password
* is convertible to ASCII (that is, it will indeed return an error if that
* is not true).
*
* This is the most gawdawful constant I've ever seen in security-related code.
*/
static const unsigned char lmHashPlaintext[] = {'K', 'G', 'S', '!', '@', '#', '$', '%'};
OSStatus lmPasswordHash(
CSSM_CSP_HANDLE cspHand,
CFStringRef pwd,
unsigned char *digest) // caller-supplied, NTLM_DIGEST_LENGTH
{
/* convert to ASCII */
unsigned strLen;
unsigned char *cStr;
OSStatus ortn;
ortn = ntlmStringFlatten(pwd, false, &cStr, &strLen);
if(ortn) {
dprintf("lmPasswordHash: ASCII password conversion failed\n");
return ortn;
}
/* truncate/pad to 14 bytes and convert to upper case */
unsigned char pwdFix[NTLM_LM_PASSWORD_LEN];
unsigned toMove = NTLM_LM_PASSWORD_LEN;
if(strLen < NTLM_LM_PASSWORD_LEN) {
toMove = strLen;
}
memmove(pwdFix, cStr, toMove);
free(cStr);
for(unsigned dex=0; dex<NTLM_LM_PASSWORD_LEN; dex++) {
pwdFix[dex] = toupper(pwdFix[dex]);
}
/* two DES keys - raw material 7 bytes, munge to 8 bytes */
unsigned char desKey1[DES_KEY_SIZE], desKey2[DES_KEY_SIZE];
ntlmMakeDesKey(pwdFix, desKey1);
ntlmMakeDesKey(pwdFix + DES_RAW_KEY_SIZE, desKey2);
/* use each of those keys to encrypt the magic string */
ortn = ntlmDesCrypt(cspHand, desKey1, lmHashPlaintext, digest);
if(ortn == noErr) {
ortn = ntlmDesCrypt(cspHand, desKey2, lmHashPlaintext, digest + DES_BLOCK_SIZE);
}
return ortn;
}
/*
* Calculate NTLM password hash (MD4 on a unicode password).
*/
void ntlmPasswordHash(
CFStringRef pwd,
unsigned char *digest) // caller-supplied, NTLM_DIGEST_LENGTH
{
unsigned char *data;
unsigned len;
/* convert to little-endian unicode */
ntlmStringToLE(pwd, &data, &len);
/* md4 hash of that */
md4Hash(data, len, digest);
free(data);
}
/*
* NTLM response: DES encrypt the challenge (or session hash) with three
* different keys derived from the password hash. Result is concatenation
* of three DES encrypts.
*/
#define ALL_KEYS_LENGTH (3 * DES_RAW_KEY_SIZE)
OSStatus ntlmResponse(
CSSM_CSP_HANDLE cspHand,
const unsigned char *digest, // NTLM_DIGEST_LENGTH bytes
const unsigned char *ptext, // challenge or session hash
unsigned char *ntlmResp) // caller-supplied NTLM_LM_RESPONSE_LEN
{
unsigned char allKeys[ALL_KEYS_LENGTH];
unsigned char key1[DES_KEY_SIZE], key2[DES_KEY_SIZE], key3[DES_KEY_SIZE];
OSStatus ortn;
memmove(allKeys, digest, NTLM_DIGEST_LENGTH);
memset(allKeys + NTLM_DIGEST_LENGTH, 0, ALL_KEYS_LENGTH - NTLM_DIGEST_LENGTH);
ntlmMakeDesKey(allKeys, key1);
ntlmMakeDesKey(allKeys + DES_RAW_KEY_SIZE, key2);
ntlmMakeDesKey(allKeys + (2 * DES_RAW_KEY_SIZE), key3);
ortn = ntlmDesCrypt(cspHand, key1, ptext, ntlmResp);
if(ortn == noErr) {
ortn = ntlmDesCrypt(cspHand, key2, ptext, ntlmResp + DES_BLOCK_SIZE);
}
if(ortn == noErr) {
ortn = ntlmDesCrypt(cspHand, key3, ptext, ntlmResp + (2 * DES_BLOCK_SIZE));
}
return ortn;
}

View File

@ -0,0 +1,317 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Private routines used by NtlmGenerator module.
*/
#ifndef _NTLM_BLOB_PRIV_H_
#define _NTLM_BLOB_PRIV_H_
#include <CoreFoundation/CFData.h>
#include <CoreFoundation/CFString.h>
#include <stdint.h>
#include <Security/cssmtype.h>
#include <Security/SecBase.h>
#include <CoreServices/CoreServices.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef NDEBUG
#include <stdio.h>
#define dprintf(args...) printf(args)
#else
#define dprintf(args...)
#endif
/*
* Common error returns.
*
* This one for "I don't understand the server blob".
*/
#define NTLM_ERR_PARSE_ERR paramErr
/*
* This one for protocol variant mismatch (e.g., app requires NTLMv2 but server
* doesn't accept that).
*/
#define NTLM_ERR_PROTOCOL_MISMATCH errSecAuthFailed
/*
* For debugging using fixed pamaters via sourceforge "test vectors".
*/
#define DEBUG_FIXED_CHALLENGE 0
/* handy portable NULL-tolerant free() */
#define CFREE(p) if(p != NULL) { free(p); }
#define NTLM_SIGNATURE "NTLMSSP"
#define NTLM_SIGNATURE_LEN 8 /* including NULL! */
#define NTLM_MSG_MARKER_TYPE1 1 /* first client msg */
#define NTLM_MSG_MARKER_TYPE2 2 /* server challenge */
#define NTLM_MSG_MARKER_TYPE3 3 /* client response */
/* Size of a security buffer */
#define NTLM_SIZEOF_SEC_BUF (sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t))
/* length of server challenge in bytes */
#define NTLM_CHALLENGE_LEN 8
/* length of client nonce in bytes */
#define NTLM_CLIENT_NONCE_LEN 8
/* length of LM and NTLM responses */
#define NTLM_LM_RESPONSE_LEN 24
/* foreced length of LM-style uppper case password */
#define NTLM_LM_PASSWORD_LEN 14
/*
* Flags - defined here in native endianness; sent over the wire little-endian
*/
#define NTLM_NegotiateUnicode 0x00000001
#define NTLM_NegotiateOEM 0x00000002
#define NTLM_RequestTarget 0x00000004
#define NTLM_Unknown1 0x00000008
#define NTLM_NegotiateSign 0x00000010
#define NTLM_NegotiateSeal 0x00000020
#define NTLM_NegotiateDatagram 0x00000040
#define NTLM_NegotiateLMKey 0x00000080
#define NTLM_NegotiateNetware 0x00000100
#define NTLM_NegotiateNTLM 0x00000200
#define NTLM_Unknown2 0x00000400
#define NTLM_Unknown3 0x00000800
#define NTLM_DomainSupplied 0x00001000
#define NTLM_WorkstationSupplies 0x00002000
#define NTLM_LocalCall 0x00004000
#define NTLM_AlwaysSign 0x00008000
#define NTLM_TargetTypeDomain 0x00010000
#define NTLM_TargetTypeServer 0x00020000
#define NTLM_TargetTypeShare 0x00040000
#define NTLM_NegotiateNTLM2Key 0x00080000
#define NTLM_RequestInitResp 0x00100000
#define NTLM_RequestAcceptResp 0x00200000
#define NTLM_RequestNonNTSessionKey 0x00400000
#define NTLM_NegotiateTargetInfo 0x00800000
#define NTLM_Unknown4 0x01000000
#define NTLM_Unknown5 0x02000000
#define NTLM_Unknown6 0x04000000
#define NTLM_Unknown7 0x08000000
#define NTLM_Unknown8 0x10000000
#define NTLM_Negotiate128Bit 0x20000000
#define NTLM_NegotiateKeyExchange 0x40000000
#define NTLM_Negotiate56Bit 0x80000000
/* uint32_t <--> unsigned char array */
void serializeUint32(
uint32_t num,
unsigned char *buf);
uint32_t deserializeUint32(
const unsigned char *buf);
uint16_t deserializeUint16(
const unsigned char *buf);
/* write a 32-bit word, little endian */
void appendUint32(
CFMutableDataRef buf,
uint32_t word);
/* write a 16-bit word, little endian */
void appendUint16(
CFMutableDataRef buf,
uint16_t word);
/*
* Write a security buffer, providing the index into the CFData at which
* this security buffer's offset is located. Just before the actual data is written,
* go back and update the offset with the start of that data using secBufOffset().
*/
void appendSecBuf(
CFMutableDataRef buf,
uint16_t len,
CFIndex *offsetIndex);
/*
* Update a security buffer's offset to be the current end of data in a CFData.
*/
void secBufOffset(
CFMutableDataRef buf,
CFIndex offsetIndex); /* obtained from appendSecBuf() */
/*
* Parse/validate a security buffer. Verifies that supplied offset/length don't go
* past end of avaialble data. Returns ptr to actual data and its length. Returns
* paramErr on bogus values.
*/
OSStatus ntlmParseSecBuffer(
const unsigned char *cp, /* start of security buffer */
const unsigned char *bufStart, /* start of whole msg buffer */
unsigned bufLen, /* # of valid bytes starting at bufStart */
const unsigned char **data, /* RETURNED, start of actual data */
uint16_t *dataLen); /* RETURNED, length of actual data */
/* random number generator */
void ntlmRand(
unsigned len,
void *buf); /* allocated by caller, random data RETURNED */
/* Obtain host name in appropriate encoding */
OSStatus ntlmHostName(
bool unicode,
unsigned char **flat, // mallocd and RETURNED
unsigned *flatLen); // RETURNED
void ntlmAppendTimestamp(
CFMutableDataRef ntlmV2Blob);
/*
* Convert CFString to little-endian unicode.
*/
void ntlmStringToLE(
CFStringRef pwd,
unsigned char **ucode, // mallocd and RETURNED
unsigned *ucodeLen); // RETURNED
/*
* Convert a CFStringRef into a mallocd array of chars suitable for the specified
* encoding. This might return an error if the string can't be converted
* appropriately.
*/
OSStatus ntlmStringFlatten(
CFStringRef str,
bool unicode,
unsigned char **flat, // mallocd and RETURNED
unsigned *flatLen); // RETURNED
/* MD4 and MD5 hash */
#define NTLM_DIGEST_LENGTH 16
void md4Hash(
const unsigned char *data,
unsigned dataLen,
unsigned char *digest); // caller-supplied, NTLM_DIGEST_LENGTH */
void md5Hash(
const unsigned char *data,
unsigned dataLen,
unsigned char *digest); // caller-supplied, NTLM_DIGEST_LENGTH */
/*
* Calculate LM-style password hash. This really only works if the password
* is convertible to ASCII.
*/
OSStatus lmPasswordHash(
CSSM_CSP_HANDLE cspHand,
CFStringRef pwd,
unsigned char *digest); // caller-supplied, NTLM_DIGEST_LENGTH
/*
* Calculate NTLM password hash (MD4 on a unicode password).
*/
void ntlmPasswordHash(
CFStringRef pwd,
unsigned char *digest); // caller-supplied, NTLM_DIGEST_LENGTH
/*
* NTLM response: DES with three different keys.
*/
OSStatus ntlmResponse(
CSSM_CSP_HANDLE cspHand,
const unsigned char *digest, // NTLM_DIGEST_LENGTH bytes
const unsigned char *challenge, // actually challenge or session hash
unsigned char *ntlmResp); // caller-supplied NTLM_LM_RESPONSE_LEN
/* DES-related consts */
#define DES_BLOCK_SIZE 8
#define DES_RAW_KEY_SIZE 7
#define DES_KEY_SIZE 8
/*
* Given 7 bytes, create 8-byte DES key. Our implementation ignores the
* parity bit (lsb), which simplifies this somewhat.
*/
void ntlmMakeDesKey(
const unsigned char *inKey, // DES_RAW_KEY_SIZE bytes
unsigned char *outKey); // DES_KEY_SIZE bytes
/*
* single block DES encrypt.
* This would really benefit from a DES implementation in CommonCrypto.
*/
OSStatus ntlmDesCrypt(
CSSM_CSP_HANDLE cspHand,
const unsigned char *key, // DES_KEY_SIZE bytes
const unsigned char *inData, // DES_BLOCK_SIZE bytes
const unsigned char *outData); // DES_BLOCK_SIZE bytes
/*
* HMAC/MD5.
*/
OSStatus ntlmHmacMD5(
CSSM_CSP_HANDLE cspHand,
const unsigned char *key,
unsigned keyLen,
const unsigned char *inData,
unsigned inDataLen,
unsigned char *mac); // caller provided, NTLM_DIGEST_LENGTH
#if NTLM_DUMP
void ntlmPrintFlags(
const char *whereFrom,
uint32_t flags);
#else
#define ntlmPrintFlags(w, f)
#endif
#ifdef __cplusplus
}
#endif
#endif /* _NTLM_BLOB_PRIV_H_ */

View File

@ -0,0 +1,152 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* spnegoBlob.cpp - GSS and "SPNEGO blob" formatting routines
* for SPNEGO tool
*
* Created July 7 2003 by dmitch
*/
#include "spnegoBlob.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "spnegoKrb.h"
#include <security_cdsa_utils/cuEnc64.h>
#include <Security/SecAsn1Coder.h>
#include "spnegoDER.h"
#define PA_CHUNK_SIZE 1024
/* malloc a NULL-ed array of pointers of size num+1 */
static void **nssNullArray(
SecAsn1CoderRef coder,
uint32 num)
{
unsigned len = (num + 1) * sizeof(void *);
void **p = (void **)SecAsn1Malloc(coder, len);
memset(p, 0, len);
return p;
}
/*
* Given a kerberos service tiocket in GSS form (i.e., an AP_REQ),
* cook up a DER-encoded SPNEGO blob. Result is malloc'd; caller
* must free.
*/
int spnegoCreateInit(
const unsigned char *gssBlob,
unsigned gssBlobLen,
unsigned char **spnegoBlob, // mallocd and RETURNED
unsigned *spnegoBlobLen) // RETURNED
{
SpnegoNegTokenInitGss negInit;
SecAsn1CoderRef coder;
if(SecAsn1CoderCreate(&coder)) {
/* memory failure */
return -1;
}
memset(&negInit, 0, sizeof(negInit));
negInit.oid = CSSMOID_SPNEGO;
negInit.token.mechTypeList = (CSSM_OID **)nssNullArray(coder, 2);
negInit.token.mechTypeList[0] = (CSSM_OID *)&CSSMOID_KERB_V5_LEGACY;
negInit.token.mechTypeList[1] = (CSSM_OID *)&CSSMOID_KERB_V5;
/* no contextFlags for now, though we might need 'em */
CSSM_DATA gssData;
if(gssBlob) {
gssData.Data = (uint8 *)gssBlob;
gssData.Length = gssBlobLen;
negInit.token.mechToken = &gssData;
}
CSSM_DATA res = {0, NULL};
OSStatus ortn = SecAsn1EncodeItem(coder, &negInit,
SpnegoNegTokenInitGssTemplate, &res);
if(ortn) {
SecAsn1CoderRelease(coder);
return -1;
}
*spnegoBlob = (unsigned char *)malloc(res.Length);
memmove(*spnegoBlob, res.Data, res.Length);
*spnegoBlobLen = res.Length;
/* this frees all memory allocated during SecAsn1EncodeItem() */
SecAsn1CoderRelease(coder);
return 0;
}
/*
* High-level "give me the SPNEGO blob for this principal" routine.
*
* The result is optionally base64 encoded data and the caller must free.
*
* Returns nonzero on any error.
*
* If principal is NULL, the actual kerberos ticket is not
* calculated and not included in the blob. This can be used to
* query a server for what MechTypes it supports.
*/
int spnegoTokenInitFromPrincipal(
const char *inHostname,
const char *inServiceType,
char **spnegoBlob, // mallocd and RETURNED
unsigned *spnegoBlobLen) // RETURNED
{
unsigned char *rawBlob = NULL;
unsigned rawBlobLen = 0;
unsigned char *tkt = NULL;
unsigned tktLen = 0;
int ourRtn = 0;
/*
* Get kerberos ticket for specified principal
*/
if(inHostname && inServiceType) {
krb5_error_code kerr = GetSvcTicketForHost(inHostname, inServiceType, &tktLen, &tkt);
if(kerr) {
return -1;
}
}
/* now an SPNEGO blob */
ourRtn = spnegoCreateInit(tkt, tktLen, &rawBlob, &rawBlobLen);
if(ourRtn) {
if (tkt) free(tkt);
return ourRtn;
}
/* caller wants binary DER encoded data */
*spnegoBlob = (char *)rawBlob;
*spnegoBlobLen = rawBlobLen;
if(tkt) {
free(tkt);
}
return ourRtn;
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 2003 Apple Computer, Inc. All Rights Reserved.
*
* The contents of this file constitute Original Code as defined in and are
* subject to the Apple Public Source License Version 1.2 (the 'License').
* You may not use this file except in compliance with the License. Please
* obtain a copy of the License at http://www.apple.com/publicsource and
* read it before using this file.
*
* This Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*/
/*
* spnegoBlob.h - GSS and "SPNEGO blob" formatting routines
* for SPNEGO tool
*
* Created July 7 2003 by dmitch
*/
#ifndef _SPNEGO_BLOB_H_
#define _SPNEGO_BLOB_H_
//#include "spnegoTool.h"
#include <Security/cssmtype.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Given a kerberos service tiocket in GSS form (i.e., an AP_REQ),
* cook up a DER-encoded SPNEGO blob. Result is malloc'd; caller
* must free.
*/
int spnegoCreateInit(
const unsigned char *gssBlob,
unsigned gssBlobLen,
unsigned char **spnegoBlob, // mallocd and RETURNED
unsigned *spnegoBlobLen); // RETURNED
/*
* High-level "give me the SPNEGO blob for this principal" routine.
*
* The result is optionally base64 encoded data and the caller must free.
*
* Returns nonzero on any error.
*
* If principal is NULL, the actual kerberos ticket is not
* calculated and not included in the blob. This can be used to
* query a server for what MechTypes it supports.
*/
int spnegoTokenInitFromPrincipal(
const char *inHostname,
const char *inServiceType,
char **spnegoBlob, // mallocd and RETURNED
unsigned *spnegoBlobLen); // RETURNED
#ifdef __cplusplus
}
#endif
#endif /* _SPNEGO_BLOB_H_ */

View File

@ -0,0 +1,172 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 2003 Apple Computer, Inc. All Rights Reserved.
*
* The contents of this file constitute Original Code as defined in and are
* subject to the Apple Public Source License Version 1.2 (the 'License').
* You may not use this file except in compliance with the License. Please
* obtain a copy of the License at http://www.apple.com/publicsource and
* read it before using this file.
*
* This Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*/
/*
* spnegoDER.cpp - DER encode/decode support for SPNEGO
*
* Created July 7 2003 by dmitch
*
* This file contains templates used in conjunction with
* libnssasn1.a to DER encode and decode data structs associated
* with the Microsoft implementation of SPNEGO. The DER produced
* and consumed by these templates is known to work with Microsoft
* IIS v. 5.0. This encoding and decoding does NOT match the ASN.1
* definitions provided by Microsoft and it does not match the
* ASN.1 definitions in RFC 2478, upon which SPNEGO is claimed to
* be based. The DER encoding and decoding performed here was
* developed the hard way, by observing traffic with IIS 5.0.
*/
#include "spnegoDER.h"
#include <Security/cssmtype.h>
#include <Security/asn1Templates.h>
#include <stddef.h>
#include "spnegoBlob.h"
/***
*** SPNEGO-specific OIDS
***/
/* 1.3.6.1.1.5.5.2 SPNEGO */
static const uint8 OID_SPNEGO[] =
{ 0x2b, 0x06, 0x01, 0x05, 0x05, 0x02 };
const CSSM_OID CSSMOID_SPNEGO =
{ sizeof(OID_SPNEGO), (uint8 *)OID_SPNEGO };
/* 1.2.840.48018.1.2.2 Kerberos V5 Legacy (same as Kerberos
* V5, but off by 1 bit required for legacy compatibility) */
static const uint8 OID_KERB_V5_LEGACY[] =
{ 0x2a, 0x86, 0x48, 0x82, 0xf7, 0x12, 0x01, 0x02, 0x02 };
const CSSM_OID CSSMOID_KERB_V5_LEGACY =
{ sizeof(OID_KERB_V5_LEGACY), (uint8 *)OID_KERB_V5_LEGACY };
/* 1.2.840.113554.1.2.2 Kerberos V5 */
static const uint8 OID_KERB_V5[] =
{ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02 };
const CSSM_OID CSSMOID_KERB_V5 =
{ sizeof(OID_KERB_V5), (uint8 *)OID_KERB_V5 };
/* SpnegoNegTokenInit */
const SecAsn1Template SpnegoNegTokenInitTemplate[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(SpnegoNegTokenInit) },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 0 |
SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED,
offsetof(SpnegoNegTokenInit,mechTypeList),
kSecAsn1SequenceOfObjectIDTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1 |
SEC_ASN1_EXPLICIT,
offsetof(SpnegoNegTokenInit,contextFlags),
kSecAsn1PointerToBitStringTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 2 |
SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED,
offsetof(SpnegoNegTokenInit,mechToken),
kSecAsn1PointerToOctetStringTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 3 |
SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED,
offsetof(SpnegoNegTokenInit,mechListMIC),
kSecAsn1PointerToOctetStringTemplate},
{ 0 }
};
/* SpnegoNegTokenInitGss */
const SecAsn1Template _SpnegoNegTokenInitGssTemplate[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(SpnegoNegTokenInitGss) },
{ SEC_ASN1_OBJECT_ID,
offsetof(SpnegoNegTokenInitGss,oid) },
{ SEC_ASN1_CONTEXT_SPECIFIC | 0 | SEC_ASN1_CONSTRUCTED |
SEC_ASN1_EXPLICIT,
offsetof(SpnegoNegTokenInitGss,token),
SpnegoNegTokenInitTemplate },
{ 0 }
};
/*
* This does the App-specific wrapper around the actual defined
* SpnegoNegTokenInitGss.
*/
const SecAsn1Template SpnegoNegTokenInitGssTemplate[] = {
{ SEC_ASN1_APPLICATION | 0 | SEC_ASN1_CONSTRUCTED,
0, _SpnegoNegTokenInitGssTemplate, sizeof(SpnegoNegTokenInitGss) },
{ 0 }
};
const SecAsn1Template _SpnegoNegTokenTargTemplate[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(SpnegoNegTokenTarg) },
/* Microsoft IIS passes all these back as constructed, I swear */
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 0 |
SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED,
offsetof(SpnegoNegTokenTarg,negResult),
kSecAsn1PointerToEnumeratedTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 1 |
SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED,
offsetof(SpnegoNegTokenTarg,mechType),
kSecAsn1PointerToObjectIDTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 2 |
SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED,
offsetof(SpnegoNegTokenTarg,responseToken),
kSecAsn1PointerToOctetStringTemplate },
{ SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 3 |
SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED,
offsetof(SpnegoNegTokenTarg,mechListMIC),
kSecAsn1PointerToOctetStringTemplate },
{ 0 }
};
/*
* This does the context-specific wrapper around the actual defined
* SpnegoNegTokenTarg.
*/
const SecAsn1Template SpnegoNegTokenTargTemplate[] = {
{ SEC_ASN1_CONTEXT_SPECIFIC | 1 | SEC_ASN1_CONSTRUCTED |
SEC_ASN1_EXPLICIT,
0, _SpnegoNegTokenTargTemplate, sizeof(SpnegoNegTokenTarg) },
{ 0 }
};

163
src/HTTP/SPNEGO/spnegoDER.h Normal file
View File

@ -0,0 +1,163 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 2003 Apple Computer, Inc. All Rights Reserved.
*
* The contents of this file constitute Original Code as defined in and are
* subject to the Apple Public Source License Version 1.2 (the 'License').
* You may not use this file except in compliance with the License. Please
* obtain a copy of the License at http://www.apple.com/publicsource and
* read it before using this file.
*
* This Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*/
/*
* spnegoDER.h - DER encode/decode support for SPNEGO
*
* Created July 7 2003 by dmitch
*/
#ifndef _SPNEGO_DER_H_
#define _SPNEGO_DER_H_
#include <Security/secasn1t.h>
#include <Security/cssmtype.h>
#ifdef __cplusplus
extern "C" {
#endif
/***
Ê*** ASN and OID definitions from Microsoft:
*** http://msdn.microsoft.com/library/
*** default.asp?url=/library/en-us/dnsecure/html/http-sso-2.asp
***/
/* SPNEGO-specific OIDS */
/* 1.3.6.1.1.5.5.2 SPNEGO */
extern const CSSM_OID CSSMOID_SPNEGO;
/* 1.2.840.48018.1.2.2 Kerberos V5 Legacy (same as Kerberos
* V5, but off by 1 bit required for legacy compatibility) */
extern const CSSM_OID CSSMOID_KERB_V5_LEGACY;
/* 1.2.840.113554.1.2.2 Kerberos V5 */
extern const CSSM_OID CSSMOID_KERB_V5;
/*
* RFC 2478 defines this stuff this way:
*
* NegotiationToken ::= CHOICE {
* negTokenInit [0] NegTokenInit,
* negTokenTarg [1] NegTokenTarg }
*
* MechTypeList ::= SEQUENCE OF MechType
*
* NegTokenInit ::= SEQUENCE {
* mechTypes [0] MechTypeList OPTIONAL,
* reqFlags [1] ContextFlags OPTIONAL,
* mechToken [2] OCTET STRING OPTIONAL,
* mechListMIC [3] OCTET STRING OPTIONAL
* }
*
* ContextFlags ::= BIT STRING {
* delegFlag (0),
* mutualFlag (1),
* replayFlag (2),
* sequenceFlag (3),
* anonFlag (4),
* confFlag (5),
* integFlag (6)
* }
*
* Note well: Miscrosoft encodes NegTokenInit as a context-specific
* explicit constructed sequence wrapped in a GSS header like so:
*
* NegTokenInitGss ::= APPLICATION SPECIFIC[0] {
* oid OID, // spnego
* token NegTokenInit EXPLICIT[0]
* }
*
* Also NOTE WELL: contrary to both RFC 2478 and Microsoft's own
* documentation, all of the fields in both NegTokenInit and
* NegTokenTarget are EXPLICITLY tagged. This was determined
* the hard way, via empirical observation of traffic to and
* from an IIS machine.
*/
typedef struct {
CSSM_OID **mechTypeList; // SEQUENCE OF, optional
CSSM_DATA *contextFlags; // BIT STRING, optional
CSSM_DATA *mechToken; // optional
CSSM_DATA *mechListMIC; // optional
} SpnegoNegTokenInit;
typedef struct {
CSSM_OID oid; // CSSMOID_SPNEGO
SpnegoNegTokenInit token;
} SpnegoNegTokenInitGss;
extern const SecAsn1Template SpnegoNegTokenInitTemplate[];
extern const SecAsn1Template SpnegoNegTokenInitGssTemplate[];
/*
* Here's what Microsoft has to say about NegTokenTarg.
*
* NegTokenTarg ::= SEQUENCE {
* negResult [0] ENUMERATED {
* accept_completed (0),
* accept_incomplete (1),
* rejected (2) } OPTIONAL,
* supportedMech [1] MechType OPTIONAL,
* responseToken [2] OCTET STRING OPTIONAL,
* mechListMIC [3] OCTET STRING OPTIONAL
* }
*
* However empirical observation indicates that this sequence
* is wrapped in an EXPLICIT CONTEXT_SPECIFIC[1] wrapper.
* Also each field in the NegTokenTarg is most definitely
* explicitly tagged.
*/
typedef struct {
CSSM_DATA *negResult; // SpegoNegResult, optional
CSSM_OID *mechType; // optional
CSSM_DATA *responseToken; // optional
CSSM_DATA *mechListMIC; // optional
} SpnegoNegTokenTarg;
extern const SecAsn1Template SpnegoNegTokenTargTemplate[];
#ifdef __cplusplus
}
#endif
#endif /* _SPNEGO_DER_H_ */

View File

@ -0,0 +1,254 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* spnegoKrb.cpp - Kerberos routines for SPNEGO tool
*
* Created July 7 2003 by dmitch
*/
#include "spnegoKrb.h"
#include <Kerberos/Kerberos.h>
#include <stdio.h>
//#include "unBER.h"
#include "CFNetworkInternal.h"
#include <mach-o/dyld.h>
#include "spnegoDER.h"
#ifndef DYNAMICALLY_LOAD_KERBEROS
#define DYNAMICALLY_LOAD_KERBEROS 1
#endif
#if DYNAMICALLY_LOAD_KERBEROS
static const void* KerberosLibrary = NULL;
static int returns_bad_int_return(void) { return 1; }
static void returns(void) { return; }
#define GET_DYNAMIC_SYMBOL(sym, rettype, arglist, alt) \
static rettype (* sym##_proc)arglist = NULL; \
if (sym##_proc == NULL) { \
if (KerberosLibrary || (KerberosLibrary = __CFNetworkLoadFramework("/System/Library/Frameworks/Kerberos.framework/Versions/A/Kerberos"))) \
sym##_proc = (rettype(*)arglist)NSAddressOfSymbol(NSLookupSymbolInImage((const mach_header*)KerberosLibrary, "_"#sym, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND)); \
if (! sym##_proc) sym##_proc = (rettype(*)arglist)alt; \
}
krb5_error_code KRB5_CALLCONV
krb5_init_context(krb5_context *ctxt) {
GET_DYNAMIC_SYMBOL(krb5_init_context, krb5_error_code, (krb5_context *ctxt), returns_bad_int_return);
return (*krb5_init_context_proc)(ctxt);
}
krb5_error_code KRB5_CALLCONV
krb5_cc_default(krb5_context ctxt, krb5_ccache *cache) {
GET_DYNAMIC_SYMBOL(krb5_cc_default, krb5_error_code, (krb5_context ctxt, krb5_ccache *cache), returns_bad_int_return);
return (*krb5_cc_default_proc)(ctxt, cache);
}
krb5_error_code KRB5_CALLCONV
krb5_cc_get_principal (krb5_context context, krb5_ccache cache, krb5_principal *principal) {
GET_DYNAMIC_SYMBOL(krb5_cc_get_principal, krb5_error_code, (krb5_context context, krb5_ccache cache, krb5_principal *principal), returns_bad_int_return);
return (*krb5_cc_get_principal_proc)(context, cache, principal);
}
krb5_error_code KRB5_CALLCONV
krb5_sname_to_principal(krb5_context context, const char *hostname, const char *sname, krb5_int32 type, krb5_principal *principal) {
GET_DYNAMIC_SYMBOL(krb5_sname_to_principal, krb5_error_code, (krb5_context context, const char *hostname, const char *sname, krb5_int32 type, krb5_principal *principal), returns_bad_int_return);
return (*krb5_sname_to_principal_proc)(context, hostname, sname, type, principal);
}
krb5_error_code KRB5_CALLCONV
krb5_cc_close(krb5_context context, krb5_ccache cache) {
GET_DYNAMIC_SYMBOL(krb5_cc_close, krb5_error_code, (krb5_context context, krb5_ccache cache), returns_bad_int_return);
return (*krb5_cc_close_proc)(context, cache);
}
void KRB5_CALLCONV
krb5_free_principal(krb5_context context, krb5_principal principal) {
GET_DYNAMIC_SYMBOL(krb5_free_principal, void, (krb5_context context, krb5_principal principal), returns);
(*krb5_free_principal_proc)(context, principal);
}
void KRB5_CALLCONV
krb5_free_context(krb5_context context) {
GET_DYNAMIC_SYMBOL(krb5_free_context, void, (krb5_context context), returns);
(*krb5_free_context_proc)(context);
}
OM_uint32 KRB5_CALLCONV
gss_init_sec_context(OM_uint32 *minor_status, gss_cred_id_t cred_handle, gss_ctx_id_t *context_handle, gss_name_t target_name, gss_OID mech_type, OM_uint32 req_flags, OM_uint32 time_req, gss_channel_bindings_t input_chan_bindings, gss_buffer_t input_token, gss_OID * actual_mech_type, gss_buffer_t output_token, OM_uint32 *ret_flags, OM_uint32 *time_rec ) {
GET_DYNAMIC_SYMBOL(gss_init_sec_context, OM_uint32, (OM_uint32 *minor_status, gss_cred_id_t cred_handle, gss_ctx_id_t *context_handle, gss_name_t target_name, gss_OID mech_type, OM_uint32 req_flags, OM_uint32 time_req, gss_channel_bindings_t input_chan_bindings, gss_buffer_t input_token, gss_OID * actual_mech_type, gss_buffer_t output_token, OM_uint32 *ret_flags, OM_uint32 *time_rec), returns_bad_int_return);
return (*gss_init_sec_context_proc)(minor_status, cred_handle, context_handle, target_name, mech_type, req_flags, time_req, input_chan_bindings, input_token, actual_mech_type, output_token, ret_flags, time_rec);
}
OM_uint32 KRB5_CALLCONV
gss_delete_sec_context(OM_uint32 *minor_status, gss_ctx_id_t *context_handle, gss_buffer_t output_token)
{
GET_DYNAMIC_SYMBOL(gss_delete_sec_context, OM_uint32, (OM_uint32 *minor_status, gss_ctx_id_t *context_handle, gss_buffer_t output_token), returns_bad_int_return);
return (*gss_delete_sec_context_proc)(minor_status, context_handle, output_token);
}
OM_uint32 KRB5_CALLCONV
gss_import_name(OM_uint32 *minor_status, gss_buffer_t input_name_buffer, gss_OID input_name_type, gss_name_t *output_name )
{
GET_DYNAMIC_SYMBOL(gss_import_name, OM_uint32, (OM_uint32 *minor_status, gss_buffer_t input_name_buffer, gss_OID input_name_type, gss_name_t *output_name), returns_bad_int_return);
return (*gss_import_name_proc)(minor_status, input_name_buffer, input_name_type, output_name);
}
OM_uint32 KRB5_CALLCONV
gss_release_name(OM_uint32 *minor_status, gss_name_t *input_name)
{
GET_DYNAMIC_SYMBOL(gss_release_name, OM_uint32, (OM_uint32 *minor_status, gss_name_t *input_name), returns_bad_int_return);
return (*gss_release_name_proc)(minor_status, input_name);
}
OM_uint32 KRB5_CALLCONV
gss_release_buffer(OM_uint32 *minor_status, gss_buffer_t buffer)
{
GET_DYNAMIC_SYMBOL(gss_release_buffer, OM_uint32, (OM_uint32 *minor_status, gss_buffer_t buffer), returns_bad_int_return);
return (*gss_release_buffer_proc)(minor_status, buffer);
}
#endif /* DYNAMICALLY_LOAD_KERBEROS */
krb5_error_code GetSvcTicketForHost(const char *inHostname,
const char *inServiceType, // http or ftp etc...
unsigned *outTicketLen,
unsigned char **outTicket)
{
krb5_error_code kerr;
krb5_context kctx = NULL;
krb5_principal kuserPrinc = NULL;
krb5_principal kservPrinc = NULL;
krb5_ccache kcc = NULL;
gss_buffer_desc outputToken = GSS_C_EMPTY_BUFFER;
gss_buffer_desc inputToken = GSS_C_EMPTY_BUFFER;
gss_OID_desc gss_nt_krb5_principal = {10, (void *)"\052\206\110\206\367\022\001\002\002\002"}; // from krb5.h
gss_name_t gssServicePrincipal = GSS_C_NO_NAME;
gss_ctx_id_t gssContext = GSS_C_NO_CONTEXT;
OM_uint32 minorStatus;
*outTicketLen = 0;
*outTicket = NULL;
if (!strcmp(inHostname, "localhost"))
inHostname = NULL;
if((kerr = krb5_init_context(&kctx)))
goto out;
// since there is no name available, there is no reason not to use the default cache
if ((kerr = krb5_cc_default(kctx, &kcc)))
goto out;
// if no error is returned, then there is a valid cache setup already, otherwise don't try SPNEGO
if ((kerr = krb5_cc_get_principal(kctx, kcc, &kuserPrinc)))
goto out;
// this prevents reverse lookup issues for AD environments, if name is unparsed it does a lookup
if ((kerr = krb5_sname_to_principal(kctx, inHostname, inServiceType, KRB5_NT_UNKNOWN, &kservPrinc)))
goto out;
gss_buffer_desc inputName; // do not release
inputName.value = &kservPrinc;
inputName.length = sizeof( krb5_principal );
kerr = gss_import_name( &minorStatus, &inputName, &gss_nt_krb5_principal, &gssServicePrincipal );
if( kerr != GSS_S_COMPLETE )
goto out;
kerr = gss_init_sec_context(
&minorStatus, /* minor_status */
GSS_C_NO_CREDENTIAL, /* claimant_cred_handle */
&gssContext, /* context_handle */
gssServicePrincipal, /* target_name */
GSS_C_NO_OID, /* mech_type (used to be const) */
0, /* no req_flags to be set */
GSS_C_INDEFINITE, /* time_req */
GSS_C_NO_CHANNEL_BINDINGS, /* input_chan_bindings */
&inputToken, /* empty input token */
NULL, /* actual_mech_type */
&outputToken, /* output_token */
NULL, /* ret_flags */
NULL /* time_rec */
);
if( kerr != GSS_S_COMPLETE )
goto out;
// if we got a token out.., we should have
if( outputToken.length ) {
if ((*outTicket = (unsigned char *)malloc(outputToken.length))) {
*outTicketLen = outputToken.length;
bcopy(outputToken.value, *outTicket, outputToken.length);
}
}
// release the outputToken now that it's been copied
gss_release_buffer(&minorStatus, &outputToken);
out:
if(gssContext != GSS_C_NO_CONTEXT)
gss_delete_sec_context(&minorStatus, &gssContext, GSS_C_NO_BUFFER);
if(gssServicePrincipal != GSS_C_NO_NAME)
gss_release_name(&minorStatus, &gssServicePrincipal);
if(kservPrinc)
krb5_free_principal(kctx, kservPrinc);
if(kuserPrinc)
krb5_free_principal(kctx, kuserPrinc);
if(kcc)
krb5_cc_close(kctx,kcc);
if(kctx)
krb5_free_context(kctx);
return kerr;
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* spnegoKrb.h - Kerberos routines for SPNEGO tool
*
* Created July 7 2003 by dmitch
*/
#ifndef _SPNEGO_KRB_H_
#define _SPNEGO_KRB_H_
//#include "spnegoTool.h"
#include <Kerberos/krb5.h> /* just for krb5_error_code */
#ifdef __cplusplus
extern "C" {
#endif
krb5_error_code GetSvcTicketForHost(const char *inHostname,
const char *inServiceType,
unsigned *outTicketLen,
unsigned char **outTicket);
/*
* Obtain service ticket for specified principal.
* Result is malloc'd; caller must free.
*/
krb5_error_code krbGetSvcTkt(
const char *principal,
unsigned char **tkt, // mallocd and RETURNED
unsigned *tktLen, // RETURNED
int *isLoggedIn); // RETURNED: nonzero means the user
// has a valid TGT
#ifdef __cplusplus
}
#endif
#endif /* _SPNEGO_KRB_H_ */

544
src/Headers/CFFTPStream.h Normal file
View File

@ -0,0 +1,544 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFFTPStream.h
Contains: CoreFoundation FTP stream header
Copyright: © 2001-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file may contain unreleased API's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFFTPStream.i
Revision: 1.9
Dated: 2004/06/01 17:53:05
Last change by: rew
Last comment: Updating all copyrights to include 2004
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFFTPSTREAM__
#define __CFFTPSTREAM__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __CFSTREAM__
#include <CoreFoundation/CFStream.h>
#endif
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* kCFStreamErrorDomainFTP
*
* Discussion:
* Result code returned by FTP server
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const SInt32 kCFStreamErrorDomainFTP AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
FTP Stream Property keys. These keys can be passed to the stream
property "set/get" functions, such as CFReadStreamSetProperty/
CFReadStreamCopyProperty, or to a CFDictionary creator or an item
accessor/mutator. The comment before each key declaration (treated
as definition) indicates the value type of the property.
*/
/*
* kCFStreamPropertyFTPUserName
*
* Discussion:
* Stream property key, for both set and copy operations. CFString
* type to hold login user name. Don't set this property if you
* want anonymous FTP.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyFTPUserName AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFStreamPropertyFTPPassword
*
* Discussion:
* Stream property key, for both set and copy operations. CFString
* type to hold login password. Don't set this property if you want
* anonymous FTP.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyFTPPassword AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFStreamPropertyFTPUsePassiveMode
*
* Discussion:
* Stream property key, for both set and copy operations. CFBoolean
* type. kCFBooleanTrue means use passive mode, kCFBooleanFalse
* otherwise
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyFTPUsePassiveMode AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFStreamPropertyFTPResourceSize
*
* Discussion:
* Stream property key, for read stream copy operations. CFNumber
* of kCFNumberLongLongType to hold resource size in bytes.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyFTPResourceSize AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFStreamPropertyFTPFetchResourceInfo
*
* Discussion:
* Stream property key, for both set and copy operations. CFBoolean
* type. TRUE means that resource info, such as size, must be
* provided before download starts at higher cost. Don't set if
* resource size/other info is unnecessary. Initially, only
* resource size is implemented.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyFTPFetchResourceInfo AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFStreamPropertyFTPFileTransferOffset
*
* Discussion:
* Stream property key, for both set and copy operations. CFNumber
* of kCFNumberLongLongType for the file offset to start transfer at.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyFTPFileTransferOffset AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFStreamPropertyFTPAttemptPersistentConnection
*
* Discussion:
* Stream property key, for both set and copy operations. CFBoolean
* type. TRUE by default, set to FALSE to avoid reusing existing
* server connections.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyFTPAttemptPersistentConnection AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFStreamPropertyFTPProxy
*
* Discussion:
* Stream property key, for both set and copy operations.
* CFDictionary type that holds key-value pairs of proxy dictionary.
* The dictionary returned by SystemConfiguration can also be
* passed directly as the value.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyFTPProxy AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFStreamPropertyFTPProxyHost
*
* Discussion:
* Stream property key or FTP Proxy dictionary key, for both set and
* copy operations. It matches kSCPropNetProxiesFTPProxy defined in
* SCSchemaDefinitions.h. CFString for proxy server host name.
* This property can be set and copied individually or via a
* CFDictionary.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyFTPProxyHost AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFStreamPropertyFTPProxyPort
*
* Discussion:
* Stream property key or FTP Proxy dictionary key, for both set and
* copy operations. It matches kSCPropNetProxiesFTPPort defined in
* SCSchemaDefinitions.h. CFNumber of kCFNumberIntType for proxy
* server port number. This property can be set and copied
* individually or via a CFDictionary.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyFTPProxyPort AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFStreamPropertyFTPProxyUser
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyFTPProxyUser AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFStreamPropertyFTPProxyPassword
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyFTPProxyPassword AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
CFDictionary keys for resource information. The information is
extracted from a line of the directory list by function
CFFTPCreateParsedResourceListing.
*/
/*
* kCFFTPResourceMode
*
* Discussion:
* CFDictionary key, for get value operation. CFNumber to hold the
* resource access permission defined in sys/types.h.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFFTPResourceMode AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFFTPResourceName
*
* Discussion:
* CFDictionary key, for get value operation. CFString that holds
* the resource name.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFFTPResourceName AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFFTPResourceOwner
*
* Discussion:
* CFDictionary key, for get value operation. CFString that holds
* the resource owner's name.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFFTPResourceOwner AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFFTPResourceGroup
*
* Discussion:
* CFDictionary key, for get value operation. CFString to hold the
* name of the group that shares the resource.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFFTPResourceGroup AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFFTPResourceLink
*
* Discussion:
* CFDictionary key, for get value operation. CFString to hold
* symbolic link information. If the item is a symbolic link the
* string will contain the path to the item the link references.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFFTPResourceLink AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFFTPResourceSize
*
* Discussion:
* CFDictionary key, for get value operation. CFNumber of
* kCFNumberLongLongType to hold the resource length in bytes.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFFTPResourceSize AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFFTPResourceType
*
* Discussion:
* CFDictionary key, for get value operation. CFNumber to hold the
* resource type as defined in sys/dirent.h.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFFTPResourceType AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFFTPResourceModDate
*
* Discussion:
* CFDictionary key, for get value operation. CFDate to hold the
* last modification date and time information.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFFTPResourceModDate AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFReadStreamCreateWithFTPURL()
*
* Discussion:
* Create an FTP read stream for downloading operation from an FTP
* URL. If the URL refers to a directory, the stream is a filtered
* line-at-a-time read stream corresponding to the listing results
* provided by the server. If it's a file, then the stream is a
* regular read stream providing the data for that file.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* alloc:
* A pointer to the CFAllocator which should be used to allocate
* memory for the CF read stream and its storage for values. If
* this reference is not a valid CFAllocator, the behavior is
* undefined.
*
* ftpURL:
* A pointer to a CFURL structure created by CFURLCreateWithString
* function. If this parameter is not a pointer to a valid CFURL
* structure, the behavior is undefined.
*
* Result:
* A pointer to the CF read stream created, or NULL if failed. It is
* caller's responsibilty to release the memory allocated for the
* read stream.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFReadStreamRef
CFReadStreamCreateWithFTPURL(
CFAllocatorRef alloc,
CFURLRef ftpURL) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFFTPCreateParsedResourceListing()
*
* Discussion:
* Parse a line of file or folder listing of Unix format, and store
* the extracted result in a CFDictionary.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* alloc:
* A pointer to the CFAllocator which should be used to allocate
* memory for the CFDictionary to hold resource info. If this
* reference is not a valid CFAllocator, the behavior is undefined.
*
* buffer:
* A pointer to a buffer that may hold lines of resource listing,
* but only the first line starting from buffer[0] will be parsed
* each call.
*
* bufferLength:
* The maximum buffer size in bytes started from the location
* pointed by "buffer."
*
* parsed:
* A pointer to a CFDictionary pointer. The dictionary holds the
* extracted resource information. When parsing fails, a NULL
* pointer will be returned. It is caller's responsibilty to
* release the memory allocated for the dictionary.
*
* Result:
* The number of bytes consumed from buffer, 0 if there are not
* enough bytes, or -1 if a parse failure occurs.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFIndex
CFFTPCreateParsedResourceListing(
CFAllocatorRef alloc,
const UInt8 * buffer,
CFIndex bufferLength,
CFDictionaryRef * parsed) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFWriteStreamCreateWithFTPURL()
*
* Discussion:
* Create an FTP write stream for uploading operation to a FTP URL.
* If the URL specifies a directory, the open will be followed by a
* close event/state and the directory will have been created.
* Intermediary directory structure is not created.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* alloc:
* A pointer to the CFAllocator which should be used to allocate
* memory for the CF read stream and its storage for values. If
* this reference is not a valid CFAllocator, the behavior is
* undefined.
*
* ftpURL:
* A pointer to a CFURL structure created by CFURLCreateWithString
* function. If this parameter is not a pointer to a valid CFURL
* structure, the behavior is undefined.
*
* Result:
* A pointer to the CF write stream created, or NULL if failed. It
* is caller's responsibilty to release the memory allocated for the
* write stream.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFWriteStreamRef
CFWriteStreamCreateWithFTPURL(
CFAllocatorRef alloc,
CFURLRef ftpURL) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
#ifdef __cplusplus
}
#endif
#endif /* __CFFTPSTREAM__ */

View File

@ -0,0 +1,109 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFFTPStreamPriv.h
Contains: CoreFoundation Network FTP streams header (private)
Copyright: © 2003-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file contains unreleased SPI's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFFTPStreamPriv.i
Revision: 1.4
Dated: 2004/06/01 17:53:05
Last change by: rew
Last comment: Updating all copyrights to include 2004
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFFTPSTREAMPRIV__
#define __CFFTPSTREAMPRIV__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __CFSTREAM__
#include <CoreFoundation/CFStream.h>
#endif
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint on
#endif
/*
* _kCFStreamPropertyFTPLogInOnly
*
* Discussion:
* Stream property key, for both set and copy operations. CFBoolean
* type to indicate that the stream should only log into the server
* and then stop at the idle state.
*
*/
extern const CFStringRef _kCFStreamPropertyFTPLogInOnly AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _kCFStreamPropertyFTPRemoveResource
*
* Discussion:
* Stream property key, for both set and copy operations. CFBoolean
* type to indicate that the write stream should remove the
* referenced resource instead of creating it.
*
*/
extern const CFStringRef _kCFStreamPropertyFTPRemoveResource AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _kCFStreamPropertyFTPNewResourceName
*
* Discussion:
* Stream property key, for both set and copy operations. CFURL
* type indicating the new path name. This will cause the request
* url to be renamed to the given url.
*
*/
extern const CFStringRef _kCFStreamPropertyFTPNewResourceName AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint reset
#endif
#endif /* __CFFTPSTREAMPRIV__ */

View File

@ -0,0 +1,619 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFHTTPAuthentication.h
Contains: CoreFoundation Network HTTP authentication header
Copyright: © 2001-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file may contain unreleased API's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFHTTPAuthentication.i
Revision: 1.3
Dated: 2004/06/08 21:27:18
Last change by: jwyld
Last comment: Comment changes/cleanup
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFHTTPAUTHENTICATION__
#define __CFHTTPAUTHENTICATION__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __COREFOUNDATION__
#include <CoreFoundation/CoreFoundation.h>
#endif
#ifndef __CFHTTPMESSAGE__
#include <CFNetwork/CFHTTPMessage.h>
#endif
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint on
#endif
/*
* CFHTTPAuthenticationRef
*
* Discussion:
* This is the type of a reference to HTTP authentication
* information.
*/
typedef struct _CFHTTPAuthentication* CFHTTPAuthenticationRef;
/*
* CFStreamErrorHTTPAuthentication
*
* Discussion:
* Authentication errors which may be returned as a result of trying
* to apply authentication to a request. These errors are in the
* kCFStreamErrorDomainHTTP domain.
*/
enum CFStreamErrorHTTPAuthentication {
/*
* The type of authentication to be applied to a request is not
* supported.
*/
kCFStreamErrorHTTPAuthenticationTypeUnsupported = -1000,
/*
* The username was in a format not suitable for applying to the
* request.
*/
kCFStreamErrorHTTPAuthenticationBadUserName = -1001,
/*
* The password was in a format not suitable for applying to the
* request.
*/
kCFStreamErrorHTTPAuthenticationBadPassword = -1002
};
typedef enum CFStreamErrorHTTPAuthentication CFStreamErrorHTTPAuthentication;
/*
* kCFHTTPAuthenticationUsername
*
* Discussion:
* CFDictionary key, for CFHTTPMessageApplyCredentialDictionary. The
* username for authentication as a CFString. Needs to be added if
* CFHTTPAuthenticationRequiresUserNameAndPassword returns TRUE.
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFHTTPAuthenticationUsername AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFHTTPAuthenticationPassword
*
* Discussion:
* CFDictionary key, for CFHTTPMessageApplyCredentialDictionary. The
* password for authentication as a CFString. Needs to be added if
* CFHTTPAuthenticationRequiresUserNameAndPassword returns TRUE.
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFHTTPAuthenticationPassword AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFHTTPAuthenticationAccountDomain
*
* Discussion:
* CFDictionary key, for CFHTTPMessageApplyCredentialDictionary. The
* domain for authentication as a CFString. Needs to be added if
* CFHTTPAuthenticationRequiresAccountDomain returns TRUE.
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFHTTPAuthenticationAccountDomain AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFHTTPAuthenticationGetTypeID()
*
* Discussion:
* Returns the type identifier of all CFHTTPAuthentication instances.
*
* Mac OS X threading:
* Thread safe
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFTypeID
CFHTTPAuthenticationGetTypeID(void) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* CFHTTPAuthenticationCreateFromResponse()
*
* Discussion:
* Based on a response of 401 or 407, this function will create a
* new authentication object which can be used for adding
* credentials to future requests.
*
* Mac OS X threading:
* Thread safe
* The API's to CFHTTPAuthenticationRef are thread-safe so long as
* multiple threads are not altering the same
* CFHTTPAuthenticationRef at the same time.
*
* Parameters:
*
* alloc:
* Allocator to use for creating authentication object
*
* response:
* Failed response.
*
* Result:
* A freshly created authentication object useful for applying
* authentication credentials to new requests.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFHTTPAuthenticationRef
CFHTTPAuthenticationCreateFromResponse(
CFAllocatorRef alloc,
CFHTTPMessageRef response) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* CFHTTPAuthenticationIsValid()
*
* Discussion:
* Returns TRUE if the given authentication information was
* instantiated correctly and contains enough information in order
* to be applied to a request. If FALSE is returned, the object may
* still contain information which is useful to the user, e.g.
* unsupported method name. An invalid object may be queried for
* information but may not be applied to a request.
*
* Mac OS X threading:
* Thread safe
* The API's to CFHTTPAuthenticationRef are thread-safe so long as
* multiple threads are not altering the same
* CFHTTPAuthenticationRef at the same time.
*
* Parameters:
*
* auth:
* The authentication information being queried.
*
* error:
* Reference to a CFStreamError which will be populated in the
* case of an error in creation. Pass NULL if not interested in
* the failure reason. The error domain will be
* kCFStreamErrorDomainHTTP, and the error code will be one of
* those defined in CFHTTPStream.h or one of those listed as
* CFStreamErrorHTTPAuthentication.
*
* Result:
* TRUE or FALSE depending on whether the authentication object is
* good for applying credentials to further requests.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern Boolean
CFHTTPAuthenticationIsValid(
CFHTTPAuthenticationRef auth,
CFStreamError * error) /* can be NULL */ AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* CFHTTPAuthenticationAppliesToRequest()
*
* Discussion:
* Returns TRUE if the given request requires credentials based upon
* the given authentication information.
*
* Mac OS X threading:
* Thread safe
* The API's to CFHTTPAuthenticationRef are thread-safe so long as
* multiple threads are not altering the same
* CFHTTPAuthenticationRef at the same time.
*
* Parameters:
*
* auth:
* The authentication information being queried.
*
* request:
* The request which is believed to need the given authentication.
*
* Result:
* TRUE if the given authentication information should be applied to
* the request, otherwise FALSE is returned.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern Boolean
CFHTTPAuthenticationAppliesToRequest(
CFHTTPAuthenticationRef auth,
CFHTTPMessageRef request) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* CFHTTPAuthenticationRequiresOrderedRequests()
*
* Discussion:
* Some authentication methods require that future requests must be
* performed in an ordered manner, so that information from a
* response can be added to a following request.
*
* Mac OS X threading:
* Thread safe
* The API's to CFHTTPAuthenticationRef are thread-safe so long as
* multiple threads are not altering the same
* CFHTTPAuthenticationRef at the same time.
*
* Parameters:
*
* auth:
* The authentication information being queried.
*
* Result:
* Returns TRUE if the given authentication method requires ordered
* requests.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern Boolean
CFHTTPAuthenticationRequiresOrderedRequests(CFHTTPAuthenticationRef auth) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* CFHTTPMessageApplyCredentials()
*
* Discussion:
* Perform the authentication method required on the request using
* the given username and password.
*
* Mac OS X threading:
* Thread safe
* The API's to CFHTTPAuthenticationRef are thread-safe so long as
* multiple threads are not altering the same
* CFHTTPAuthenticationRef at the same time.
*
* Parameters:
*
* request:
* The request which is to receive the credentials.
*
* auth:
* The authentication information for the given request.
*
* username:
* The username to use for performing the authentication.
*
* password:
* The password to use for performing the authentication.
*
* error:
* Reference to a CFStreamError which will be populated with the
* error information should one occurr during the application of
* the credentials. Pass NULL if not interested in the failure
* reason. The error domain will be kCFStreamErrorDomainHTTP, and
* the error code will be one of those define in CFHTTPStream.h or
* one of those listed as CFStreamErrorHTTPAuthentication.
*
* Result:
* TRUE will be returned if the application of the credentials to
* the request was successful, otherwise FALSE is returned.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern Boolean
CFHTTPMessageApplyCredentials(
CFHTTPMessageRef request,
CFHTTPAuthenticationRef auth,
CFStringRef username,
CFStringRef password,
CFStreamError * error) /* can be NULL */ AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* CFHTTPMessageApplyCredentialDictionary()
*
* Discussion:
* Perform the authentication method required on the request using
* the given credential information.
*
* Mac OS X threading:
* Thread safe
* The API's to CFHTTPAuthenticationRef are thread-safe so long as
* multiple threads are not altering the same
* CFHTTPAuthenticationRef at the same time.
*
* Parameters:
*
* request:
* The request which is to receive the credentials.
*
* auth:
* The authentication information for the given request.
*
* dict:
* A dictionary containing credentials to be applied to the
* request. Valid keys are declared above.
*
* error:
* Reference to a CFStreamError which will be populated with the
* error information should one occurr during the application of
* the credentials. Pass NULL if not interested in the failure
* reason. The error domain will be kCFStreamErrorDomainHTTP, and
* the error code will be one of those define in CFHTTPStream.h or
* one of those listed as CFStreamErrorHTTPAuthentication.
*
* Result:
* TRUE will be returned if the application of the credentials to
* the request was successful, otherwise FALSE is returned.
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern Boolean
CFHTTPMessageApplyCredentialDictionary(
CFHTTPMessageRef request,
CFHTTPAuthenticationRef auth,
CFDictionaryRef dict,
CFStreamError * error) /* can be NULL */ AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFHTTPAuthenticationCopyRealm()
*
* Discussion:
* Some authentication techniques provide for namespaces on top of
* domains. This call will return the authentication information's
* namespace if there is one, otherwise it will return NULL. This
* namespace is usually used for prompting the application user for
* a name and password.
*
* Mac OS X threading:
* Thread safe
* The API's to CFHTTPAuthenticationRef are thread-safe so long as
* multiple threads are not altering the same
* CFHTTPAuthenticationRef at the same time.
*
* Parameters:
*
* auth:
* The authentication information being queried.
*
* Result:
* This call will return the authentication information's namespace
* if there is one, otherwise it will return NULL.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFStringRef
CFHTTPAuthenticationCopyRealm(CFHTTPAuthenticationRef auth) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* CFHTTPAuthenticationCopyDomains()
*
* Discussion:
* Returns a list of domain URL's on which the given authentication
* should be applied. This function is provided mostly for
* informational purposes. CFHTTPAuthenticationAppliesToRequest
* should be used in order to check whether a request requires the
* authentication.
*
* Mac OS X threading:
* Thread safe
* The API's to CFHTTPAuthenticationRef are thread-safe so long as
* multiple threads are not altering the same
* CFHTTPAuthenticationRef at the same time.
*
* Parameters:
*
* auth:
* The authentication information being queried.
*
* Result:
* Returns a list of domain URL's on which the given authentication
* should be applied.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFArrayRef
CFHTTPAuthenticationCopyDomains(CFHTTPAuthenticationRef auth) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* CFHTTPAuthenticationCopyMethod()
*
* Discussion:
* Returns the method of authentication which will be performed when
* applying credentials. The strongest method of authentication
* will be chosen in the case of multiple choices.
*
* Mac OS X threading:
* Thread safe
* The API's to CFHTTPAuthenticationRef are thread-safe so long as
* multiple threads are not altering the same
* CFHTTPAuthenticationRef at the same time.
*
* Parameters:
*
* auth:
* The authentication information being queried.
*
* Result:
* Returns the method of authentication which will be performed when
* applying credentials.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFStringRef
CFHTTPAuthenticationCopyMethod(CFHTTPAuthenticationRef auth) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* CFHTTPAuthenticationRequiresUserNameAndPassword()
*
* Discussion:
* Returns TRUE if the chosen authentication scheme requires a
* username and password.
*
* Mac OS X threading:
* Thread safe
* The API's to CFHTTPAuthenticationRef are thread-safe so long as
* multiple threads are not altering the same
* CFHTTPAuthenticationRef at the same time.
*
* Parameters:
*
* auth:
* The authentication information being queried.
*
* Result:
* Returns TRUE if the chosen authentication scheme requires a
* username and password.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern Boolean
CFHTTPAuthenticationRequiresUserNameAndPassword(CFHTTPAuthenticationRef auth) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFHTTPAuthenticationRequiresAccountDomain()
*
* Discussion:
* Returns TRUE if the chosen authentication scheme requires a
* domain for authentication. Currently, this will return TRUE for
* "NTLM" and FALSE for the other methods.
*
* Mac OS X threading:
* Thread safe
* The API's to CFHTTPAuthenticationRef are thread-safe so long as
* multiple threads are not altering the same
* CFHTTPAuthenticationRef at the same time.
*
* Parameters:
*
* auth:
* The authentication information being queried.
*
* Result:
* Returns TRUE if the chosen authentication scheme requires a
* domain for authentication.
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern Boolean
CFHTTPAuthenticationRequiresAccountDomain(CFHTTPAuthenticationRef auth) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint reset
#endif
#ifdef __cplusplus
}
#endif
#endif /* __CFHTTPAUTHENTICATION__ */

View File

@ -0,0 +1,527 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFHTTPConnectionPriv.h
Contains: CoreFoundation Network HTTP connection SPI
Copyright: © 2004-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file contains unreleased SPI's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFHTTPConnectionPriv.i
Revision: 1.6
Dated: 2004/06/08 00:02:25
Last change by: rew
Last comment: Add symbol to allow CFHTTPConnection to handle streamed uploads
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFHTTPCONNECTIONPRIV__
#define __CFHTTPCONNECTIONPRIV__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __COREFOUNDATION__
#include <CoreFoundation/CoreFoundation.h>
#endif
#ifndef __CFNETWORK__
#include <CFNetwork/CFNetwork.h>
#endif
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint on
#endif
/*
* _CFHTTPConnectionType
*
* Discussion:
* The different kinds of connections that can be passed in to
* CFHTTPConnectionCreate()
*/
enum _CFHTTPConnectionType {
/*
* A direct HTTP connection to the server
*/
kHTTP = 0,
/*
* A direct HTTPS connection to the server
*/
kHTTPS = 1,
/*
* A connection to an HTTP proxy
*/
kHTTPProxy = 2,
/*
* A connection to an HTTPS proxy
*/
kHTTPSProxy = 3,
kSOCKSProxy = 4
};
typedef enum _CFHTTPConnectionType _CFHTTPConnectionType;
/*
* CFHTTPConnectionRef
*
* Discussion:
* A connection to a particular host over which HTTP requests may be
* enqueued
*/
typedef CFTypeRef CFHTTPConnectionRef;
/*
* kCFStreamErrorHTTPConnectionLost
*
* Discussion:
* The error in the domain kCFStreamErrorDomainHTTP returned when an
* upstream request has detected that the connection is dying (often
* because of a request limit from the server). If you receive this
* error, you may assume that there is nothing wrong with your
* request itself, just that the connection did not survive long
* enough to process your request.
*
*/
extern const SInt32 kCFStreamErrorHTTPConnectionLost AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* _kCFStreamPropertyHTTPConnection
*
* Discussion:
* Retrievable property on streams returned by
* CFHTTPConnectionEnqueue, below. Returns the CFHTTPConnectionRef
* on which the stream is scheduled.
*
*/
extern const CFStringRef _kCFStreamPropertyHTTPConnection AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFHTTPConnectionCreate()
*
* Discussion:
* Creates a new HTTP connection.
*
* Parameters:
*
* alloc:
* The CFAllocator to be used to create the new connection
*
* host:
* The target host for the new connection
*
* port:
* The target port for the new connection
*
* connectionType:
* The type of connection desired; taken from
* _CFHTTPConnectionType above.
*
* streamProperties:
* Any additional properties to be set on the underlying socket
* stream(s) before the connection is first used
*
* Result:
* Returns the newly created CFHTTPConnection, or NULL if
* unsuccessful
*
*/
extern CFHTTPConnectionRef
CFHTTPConnectionCreate(
CFAllocatorRef alloc,
CFStringRef host,
SInt32 port,
UInt32 connectionType,
CFDictionaryRef streamProperties) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFHTTPConnectionEnqueue()
*
* Discussion:
* Enqueues the given HTTP request on the given connection.
*
* Parameters:
*
* connection:
* The connection you wish to send the request over
*
* request:
* The request you wish to send
*
* Result:
* A CFReadStream with which you can monitor the request's progress
* through the connection. Note that the request will not actually
* be scheduled on the connection until the returned stream is
* opened.
*
*/
extern CFReadStreamRef
CFHTTPConnectionEnqueue(
CFHTTPConnectionRef connection,
CFHTTPMessageRef request) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFHTTPConnectionEnqueueWithBodyStream()
*
* Discussion:
* Enqueues the given HTTP request on the given connection.
*
* Parameters:
*
* connection:
* The connection you wish to send the request over
*
* request:
* The request you wish to send
*
* bodyStream:
* An unopened read stream which will return the body bytes to be
* transmitted with request
*
* Result:
* A CFReadStream with which you can monitor the request's progress
* through the connection. Note that the request will not actually
* be scheduled on the connection until the returned stream is
* opened.
*
*/
extern CFReadStreamRef
CFHTTPConnectionEnqueueWithBodyStream(
CFHTTPConnectionRef connection,
CFHTTPMessageRef request,
CFReadStreamRef bodyStream) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFHTTPConnectionSetShouldPipeline()
*
* Discussion:
* Sets whether the given connection will pipeline outgoing
* requests, transmitting the requests in sequence without waiting
* for the full responses to earlier requests.
*
* Parameters:
*
* connection:
* The connection to be configured
*
* shouldPipeline:
* TRUE if you wish the connection to pipeline outgoing requests;
* FALSE if you wish the connection to wait for one request's
* response before sending the next request
*
*/
extern void
CFHTTPConnectionSetShouldPipeline(
CFHTTPConnectionRef connection,
Boolean shouldPipeline) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFHTTPConnectionLost()
*
* Discussion:
* Informs the connection that after the current response, no
* further request can be processed. Causes the connection to error
* out all further requests on the connection, returning an error
* code of {kCFStreamErrorDomainHTTP,
* kCFStreamErrorHTTPConnectionLost}
*
* Parameters:
*
* conn:
* The connection that has been lost
*
*/
extern void
CFHTTPConnectionLost(CFHTTPConnectionRef conn) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFHTTPConnectionInvalidate()
*
* Discussion:
* Invalidates the given connection, stopping all traffic on that
* connection and causing all requests in progress to return the
* error given. This also closes the underlying system resources to
* be release, and the connection to the remote host to be severed.
*
* Parameters:
*
* connection:
* The connection to be shut down
*
* error:
* The error to be returned by all active requests on the
* connection being shut down
*
*/
extern void
CFHTTPConnectionInvalidate(
CFHTTPConnectionRef connection,
CFStreamError * error) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFHTTPConnectionAcceptsRequests()
*
* Discussion:
* Returns whether the given connection would current accept new
* requests. It would not accept new requests if the connection has
* been invalidated, or if the connection has detected an underlying
* networking error, rendering its network connection to the remote
* host unusable.
*
* Parameters:
*
* connection:
* The connection to query about its status
*
* Result:
* TRUE if the connection currently believes it can process further
* requests; FALSE otherwise. Note that a TRUE return value does not
* guarantee that future requests will be accepted - the connection
* could become invalid between this call and accepting the new
* request, or between accepting the new request and the resulting
* stream being opened - but a FALSE return can be used as an early
* indicator of a bad connection.
*
*/
extern Boolean
CFHTTPConnectionAcceptsRequests(CFHTTPConnectionRef connection) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFHTTPConnectionGetLastAccessTime()
*
* Discussion:
* Returns the last time the connection had an active request in it
*
* Parameters:
*
* connection:
* The connection to query about its last access tiem
*
* Result:
* The last time the connection had an active request
*
*/
extern CFAbsoluteTime
CFHTTPConnectionGetLastAccessTime(CFHTTPConnectionRef connection) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFHTTPConnectionGetQueueDepth()
*
* Discussion:
* Returns the current depth of the request queue, counting from the
* request currently receiving its response
*
* Parameters:
*
* conn:
* The connection to query about its queue
*
* Result:
* The current depth of the queue
*
*/
extern int
CFHTTPConnectionGetQueueDepth(CFHTTPConnectionRef conn) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* _CFHTTPGetConnectionInfoForProxyURL()
*
*/
extern void
_CFHTTPGetConnectionInfoForProxyURL(
CFURLRef proxyURL,
CFHTTPMessageRef request,
CFStringRef * host,
SInt32 * port,
UInt32 * theType,
CFDictionaryRef * streamProperties) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* _CFProxyStreamCallBack
*
* Discussion:
* Callback function which is called once an asynchronous proxy
* lookup completes
*
* Parameters:
*
* proxyStream:
* The proxy stream returned when the asynchronous lookup began
*
* clientInfo:
* The opaque client context passed in to
* _CFNetworkFindProxyForURLAsync, below
*/
typedef CALLBACK_API_C( void , _CFProxyStreamCallBack )(CFReadStreamRef proxyStream, void *clientInfo);
/*
* _CFNetworkFindProxyForURLAsync()
*
* Discussion:
* Given a url, host name, and proxy dictionary (as returned by SC)
* produce the proxy list of attempts for establishing connnections.
*
* Parameters:
*
* scheme:
* The target or intended scheme which the callee thinks applies
* to the given url. This value if set trumps the scheme on the
* url.
*
* url:
* A CFURLRef representing the object to be obtained. If NULL,
* host must be specified.
*
* host:
* A CFStringRef representing the far server which will receive
* the connection. If NULL, url must be specified in which case
* the host field from the URL will be used.
*
* proxies:
* A CFDictionaryRef contatining all proxy information to be
* considered. All proxy information will be consulted and the
* best fit for the given url and host will be returned.
*
* cb:
* A callback function to be called once an answer to "which
* proxy?" is available. If NULL, this function will block until
* an answer is available.
*
* clientInfo:
* A pointer of the caller's choosing that will be passed back
* when cb is invoked. It is the caller's responsibility to
* ensure that the clientInfo pointer remains good until either cb
* is invoked or proxyStream is closed.
*
* proxyStream:
* The stream returned when async operation is required. Must not
* be NULL if cb is non-NULL. The caller should schedule the
* returned stream on whichever run loop it wishes to receive cb.
* The caller must not set the client of proxyStream.
*
* Result:
* A CFMutableArrayRef containing the list of proxies to be
* attempted in respective order. Individual proxy items are
* CFURLRef's where the scheme indicates the proxy type (i.e. http,
* https, socks4, etc.), the host indicates the proxy host name, the
* port indicates the proxy port, the username is the user's
* username on the proxy (if needed), and the password is the user's
* password for accessing the proxy (if needed). The username and
* password would primarily be needed for SOCKS. A kCFNull in the
* list indicates that a direct connection is to be used and proxies
* should be bypassed for that attempt. If all entries in the list
* are attempted, the connection has failed. If NULL is returned,
* asynchronous operation has begun, and the caller should wait for
* their callback to be invoked, or poll via
* _CFNetworkCopyProxyFromProxyStream, below.
*
*/
extern CFMutableArrayRef
_CFNetworkFindProxyForURLAsync(
CFStringRef scheme,
CFURLRef url,
CFStringRef host,
CFDictionaryRef proxies,
_CFProxyStreamCallBack cb,
void * clientInfo,
CFReadStreamRef * proxyStream) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* _CFNetworkCopyProxyFromProxyStream()
*
* Discussion:
* Once an asynchronous search for the correct proxy has begun (via
* _CFNetworkFindProxyForURLAsync, above), call this function to
* discover whether the correct proxy has been found, and if so,
* what that proxy is.
*
* Parameters:
*
* proxyStream:
* The proxy stream returned by _CFNetworkFindProxyForURLAsync,
* above
*
* isComplete:
* This out parameter is set to true if the asynchronous search is
* now complete, or false otherwise.
*
* Result:
* A CFMutableArrayRef giving the discovered proxies, in the same
* format as returned by _CFNetworkFindProxyForURLAsync, above.
*
*/
extern CFMutableArrayRef
_CFNetworkCopyProxyFromProxyStream(
CFReadStreamRef proxyStream,
Boolean * isComplete) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint reset
#endif
#ifdef __cplusplus
}
#endif
#endif /* __CFHTTPCONNECTIONPRIV__ */

816
src/Headers/CFHTTPMessage.h Normal file
View File

@ -0,0 +1,816 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFHTTPMessage.h
Contains: CoreFoundation Network socket streams header
Copyright: © 2001-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file may contain unreleased API's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFHTTPMessage.i
Revision: 1.4
Dated: 2004/08/03 22:57:05
Last change by: jiarocci
Last comment: Update Interface files to include headerdoc and remove warnings.
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFHTTPMESSAGE__
#define __CFHTTPMESSAGE__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __CFSTRING__
#include <CoreFoundation/CFString.h>
#endif
#ifndef __CFURL__
#include <CoreFoundation/CFURL.h>
#endif
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* kCFHTTPVersion1_0
*
* Discussion:
* Version string for HTTP 1.0.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFHTTPVersion1_0 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* kCFHTTPVersion1_1
*
* Discussion:
* Version string for HTTP 1.1.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFHTTPVersion1_1 AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* kCFHTTPAuthenticationSchemeBasic
*
* Discussion:
* Basic HTTP authentication scheme.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFHTTPAuthenticationSchemeBasic AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* kCFHTTPAuthenticationSchemeDigest
*
* Discussion:
* Digest HTTP authentication scheme.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFHTTPAuthenticationSchemeDigest AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
extern const CFStringRef kCFHTTPAuthenticationSchemeNTLM;
/*
* CFHTTPMessageRef
*
* Discussion:
* This is the type of a reference to an HTTP message. An HTTP
* message can be a request or a response.
*/
typedef struct __CFHTTPMessage* CFHTTPMessageRef;
/*
* CFHTTPMessageGetTypeID()
*
* Discussion:
* Return the unique type for this class.
*
* Mac OS X threading:
* Thread safe
*
* Result:
* A unique CFType for CFHTTPMessage.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFTypeID
CFHTTPMessageGetTypeID(void) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageCreateRequest()
*
* Discussion:
* Create an HTTPMessage from an HTTP method, url and version.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* alloc:
* A pointer to the CFAllocator which should be used to allocate
* memory for the CF read stream and its storage for values. If
* this reference is not a valid CFAllocator, the behavior is
* undefined.
*
* requestMethod:
* A pointer to a CFString indicating the method of request. For a
* "GET" request, for example, the value would be CFSTR("GET").
*
* url:
* A pointer to a CFURL structure created any of the several
* CFURLCreate... functions. If this parameter is not a pointer
* to a valid CFURL structure, the behavior is undefined.
*
* httpVersion:
* A pointer to a CFString indicating the version of request.
*
* Result:
* A pointer to the CFHTTPMessage created, or NULL if failed. It is
* caller's responsibilty to release the memory allocated for the
* message.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFHTTPMessageRef
CFHTTPMessageCreateRequest(
CFAllocatorRef alloc,
CFStringRef requestMethod,
CFURLRef url,
CFStringRef httpVersion) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageCreateResponse()
*
* Discussion:
* Create an HTTPMessage from an HTTP status code, description and
* version.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* alloc:
* A pointer to the CFAllocator which should be used to allocate
* memory for the CF read stream and its storage for values. If
* this reference is not a valid CFAllocator, the behavior is
* undefined.
*
* statusCode:
* An integer status code for the response.
*
* statusDescription:
* A pointer to a CFString for the status. Pass NULL to use the
* standard description for the given status code, as found in RFC
* 2616.
*
* httpVersion:
* A pointer to a CFString for the HTTP version.
*
* Result:
* A pointer to the CFHTTPMessage created, or NULL if failed. It is
* caller's responsibilty to release the memory allocated for the
* message.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFHTTPMessageRef
CFHTTPMessageCreateResponse(
CFAllocatorRef alloc,
int statusCode,
CFStringRef statusDescription,
CFStringRef httpVersion) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageCreateEmpty()
*
* Discussion:
* Creates an empty request or response, which you can then append
* bytes to via CFHTTPMessageAppendBytes().
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* alloc:
* A pointer to the CFAllocator which should be used to allocate
* memory for the CF read stream and its storage for values. If
* this reference is not a valid CFAllocator, the behavior is
* undefined.
*
* isRequest:
* A boolean. Pass kCFBooleanTrue if the message should be a
* request.
*
* Result:
* A pointer to the CFHTTPMessage created, or NULL if failed. It is
* caller's responsibilty to release the memory allocated for the
* message.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFHTTPMessageRef
CFHTTPMessageCreateEmpty(
CFAllocatorRef alloc,
Boolean isRequest) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageCreateCopy()
*
* Discussion:
* Creates a copy of a CFHTTPMessage.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* alloc:
* A pointer to the CFAllocator which should be used to allocate
* memory for the CF read stream and its storage for values. If
* this reference is not a valid CFAllocator, the behavior is
* undefined.
*
* message:
* A pointer to the CFHTTPMessage to be copied. If the message is
* NULL, the behavior is undefined.
*
* Result:
* A pointer to the CFHTTPMessage created, or NULL if failed. It is
* caller's responsibilty to release the memory allocated for the
* message.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFHTTPMessageRef
CFHTTPMessageCreateCopy(
CFAllocatorRef alloc,
CFHTTPMessageRef message) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageIsRequest()
*
* Discussion:
* Returns whether the CFHTTPMessage is a request or a response.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* message:
* A pointer to the CFHTTPMessage to be copied. If the message is
* NULL, the behavior is undefined.
*
* Result:
* A Boolean. A value of kCFBooleanTrue indicates the message is a
* request. A value of kCFBooleanFalse indicates the message is a
* response.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern Boolean
CFHTTPMessageIsRequest(CFHTTPMessageRef message) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageCopyVersion()
*
* Discussion:
* Returns the HTTP version.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* message:
* A pointer to the CFHTTPMessage to be copied. If the message is
* NULL, the behavior is undefined.
*
* Result:
* A pointer to a CFString, or NULL if failed. It is caller's
* responsibilty to release the memory allocated for the string.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFStringRef
CFHTTPMessageCopyVersion(CFHTTPMessageRef message) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageCopyBody()
*
* Discussion:
* Returns the body of the message.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* message:
* A pointer to the CFHTTPMessage to be copied. If the message is
* NULL, the behavior is undefined.
*
* Result:
* A pointer to a CFData, or NULL if failed. It is caller's
* responsibilty to release the memory allocated for the data.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFDataRef
CFHTTPMessageCopyBody(CFHTTPMessageRef message) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageSetBody()
*
* Discussion:
* Sets the body of the message from a CFData.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* message:
* A pointer to the CFHTTPMessage to be copied. If the message is
* NULL, the behavior is undefined.
*
* bodyData:
* A pointer to a CFData containing the body to be set. If the
* bodyData is NULL, the behavior is undefined.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern void
CFHTTPMessageSetBody(
CFHTTPMessageRef message,
CFDataRef bodyData) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageCopyHeaderFieldValue()
*
* Discussion:
* Returns the specified header field.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* message:
* A pointer to the CFHTTPMessage to be copied. If the message is
* NULL, the behavior is undefined.
*
* headerField:
* A pointer to the CFString. If the headerField is NULL, the
* behavior is undefined.
*
* Result:
* A pointer to a CFString, or NULL if failed. It is caller's
* responsibilty to release the memory allocated for the string.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFStringRef
CFHTTPMessageCopyHeaderFieldValue(
CFHTTPMessageRef message,
CFStringRef headerField) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageCopyAllHeaderFields()
*
* Discussion:
* Returns a CFDictionary containing all of the header fields.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* message:
* A pointer to the CFHTTPMessage to be copied. If the message is
* NULL, the behavior is undefined.
*
* Result:
* A pointer to a CFDictionary, or NULL if failed. It is caller's
* responsibilty to release the memory allocated for the dictionary.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFDictionaryRef
CFHTTPMessageCopyAllHeaderFields(CFHTTPMessageRef message) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageSetHeaderFieldValue()
*
* Discussion:
* Sets the value of the specified header field.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* message:
* A pointer to the CFHTTPMessage to be copied. If the message is
* NULL, the behavior is undefined.
*
* headerField:
* A pointer to the CFString. If headerField is NULL, the behavior
* is undefined.
*
* value:
* A pointer to the CFString containing the value to set. Set the
* value to NULL to remove the header field.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern void
CFHTTPMessageSetHeaderFieldValue(
CFHTTPMessageRef message,
CFStringRef headerField,
CFStringRef value) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageAppendBytes()
*
* Discussion:
* Appends the given bytes to the message given (parsing out any
* control information if appropriate). Returns kCFBooleanFalse if
* a parsing error occurs while processing the new data.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* message:
* A pointer to the CFHTTPMessage to be copied. If the message is
* NULL, the behavior is undefined.
*
* newBytes:
* A pointer to the bytes. If newBytes is NULL, the behavior is
* undefined.
*
* numBytes:
* A CFIndex of the number of bytes to append.
*
* Result:
* A Boolean indicating success or failure.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern Boolean
CFHTTPMessageAppendBytes(
CFHTTPMessageRef message,
const UInt8 * newBytes,
CFIndex numBytes) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageIsHeaderComplete()
*
* Discussion:
* Returns whether further header data is expected by the message.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* message:
* A pointer to the CFHTTPMessage to be copied. If the message is
* NULL, the behavior is undefined.
*
* Result:
* A Boolean. A value of kCFBooleanTrue indicates the header is
* complete and no further data is expected.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern Boolean
CFHTTPMessageIsHeaderComplete(CFHTTPMessageRef message) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageCopySerializedMessage()
*
* Discussion:
* Creates a self-contained copy of a CFHTTPMessage. This would be
* suitable for persistant storage or for transmitting over the
* network independently.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* request:
* A pointer to the CFHTTPMessage to be seralized.
*
* Result:
* A pointer to a CFData, or NULL if failed. It is caller's
* responsibilty to release the memory allocated for the data.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFDataRef
CFHTTPMessageCopySerializedMessage(CFHTTPMessageRef request) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*********************/
/* Request functions */
/*********************/
/*
* CFHTTPMessageCopyRequestURL()
*
* Discussion:
* Creates a copy of the request URL.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* request:
* A pointer to the CFHTTPMessage.
*
* Result:
* A pointer to a CFURL, or NULL if failed. It is caller's
* responsibilty to release the memory allocated for the url.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFURLRef
CFHTTPMessageCopyRequestURL(CFHTTPMessageRef request) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageCopyRequestMethod()
*
* Discussion:
* Creates a copy of the request method.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* request:
* A pointer to the CFHTTPMessage.
*
* Result:
* A pointer to a CFString, or NULL if failed. It is caller's
* responsibilty to release the memory allocated for the string.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFStringRef
CFHTTPMessageCopyRequestMethod(CFHTTPMessageRef request) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageAddAuthentication()
*
* Discussion:
* Adds authentication to the request. Tries to modify request to
* contain the authentication information requested by the failed
* response (which presumably is a 401 or 407 response).
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* request:
* A pointer to a CFHTTPMessage request.
*
* authenticationFailureResponse:
* A pointer to a CFHTTPMessage of the failed response.
*
* username:
* A pointer to a CFString containing the user name to
* authenticate.
*
* password:
* A pointer to a CFString containing the password of the user.
*
* authenticationScheme:
* A pointer to a CFString containing the authentication scheme to
* use to authenticate. If authenticationScheme is NULL, strongest
* supported scheme listed authenticationFailureResponse will be
* used.
*
* forProxy:
* A boolean indicating whether the authentication applies to a
* proxy or not.
*
* Result:
* A pointer to a CFString, or NULL if failed. It is caller's
* responsibilty to release the memory allocated for the string.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern Boolean
CFHTTPMessageAddAuthentication(
CFHTTPMessageRef request,
CFHTTPMessageRef authenticationFailureResponse,
CFStringRef username,
CFStringRef password,
CFStringRef authenticationScheme,
Boolean forProxy) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/**********************/
/* Response functions */
/**********************/
/*
* CFHTTPMessageGetResponseStatusCode()
*
* Discussion:
* Returns the status code for the response.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* response:
* A pointer to the CFHTTPMessage to be copied. If the message is
* NULL, the behavior is undefined.
*
* Result:
* A UInt32 indicating the status code.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern UInt32
CFHTTPMessageGetResponseStatusCode(CFHTTPMessageRef response) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFHTTPMessageCopyResponseStatusLine()
*
* Discussion:
* Returns the status line for the response.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* response:
* A pointer to the CFHTTPMessage to be copied. If the message is
* NULL, the behavior is undefined.
*
* Result:
* A CFString indicating the status code, or NULL if failed. It is
* caller's responsibilty to release the memory allocated for the
* string.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFStringRef
CFHTTPMessageCopyResponseStatusLine(CFHTTPMessageRef response) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
#ifdef __cplusplus
}
#endif
#endif /* __CFHTTPMESSAGE__ */

View File

@ -0,0 +1,526 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFHTTPMessagePriv.h
Contains: CoreFoundation Network HTTP message private header
Copyright: © 2001-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file contains unreleased SPI's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFHTTPMessagePriv.i
Revision: 1.12
Dated: 2005/01/18 22:12:43
Last change by: jwyld
Last comment: 3663096 Make NTLM work for Safari, WebDAV, AB, and hopefully all others.
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFHTTPMESSAGEPRIV__
#define __CFHTTPMESSAGEPRIV__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __COREFOUNDATION__
#include <CoreFoundation/CoreFoundation.h>
#endif
#ifndef __CFHTTPMESSAGE__
#include <CFNetwork/CFHTTPMessage.h>
#endif
#ifndef __CFHTTPAUTHENTICATION__
#include <CFNetwork/CFHTTPAuthentication.h>
#endif
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint on
#endif
/*
* _CFHTTPMessageSetResponseURL()
*
* Discussion:
* Adds the given url to the response. Responses don't have URL's
* associated with them. This function allows the association to be
* made. This is required for Digest authentication. This function
* is provided primarily for hand-rolled responses.
*
* Mac OS X threading:
* Thread safe
* The API's to CFHTTPMessageRef are thread-safe so long as multiple
* threads are not altering the same CFHTTPMessageRef at the same
* time.
*
* Parameters:
*
* response:
* HTTP message which is to get the url
*
* url:
* URL to be associated with the response.
*
*/
extern void
_CFHTTPMessageSetResponseURL(
CFHTTPMessageRef response,
CFURLRef url) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFHTTPAuthenticationUpdateFromResponse()
*
* Discussion:
* Updates an authentication object with carry-over information from
* a HTTP response. Some authentication types use information from
* the previous response in order to formulate new request
* authorization.
*
* Mac OS X threading:
* Thread safe
* Thread safe
*
* Parameters:
*
* auth:
* Authentication object to have updated
*
* response:
* HTTP message with the carry-over information
*
* conn:
* Connection identifier to which this response is associated.
*
*/
extern void
_CFHTTPAuthenticationUpdateFromResponse(
CFHTTPAuthenticationRef auth,
CFHTTPMessageRef response,
const void * conn) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFHTTPAuthenticationAllowsSingleSignOn()
*
* Discussion:
* Returns TRUE if the chosen authentication scheme requires a
* username and password. Currently, this will return FALSE for
* "Negotiate" and TRUE for the other methods.
*
* Mac OS X threading:
* Thread safe
* The API's to CFHTTPAuthenticationRef are thread-safe so long as
* multiple threads are not altering the same
* CFHTTPAuthenticationRef at the same time.
*
* Parameters:
*
* auth:
* The authentication information being queried.
*
* Result:
* Returns TRUE if the chosen authentication scheme requires a
* username and password.
*
*/
extern Boolean
CFHTTPAuthenticationAllowsSingleSignOn(CFHTTPAuthenticationRef auth) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFHTTPAuthenticationPasswordInClear()
*
* Discussion:
* Returns TRUE if the password is sent in an unencrypted manner.
* Currently, this will return TRUE for Basic authentication and
* FALSE for Digest Authentication.
*
* Mac OS X threading:
* Thread safe
* The API's to CFHTTPAuthenticationRef are thread-safe so long as
* multiple threads are not altering the same
* CFHTTPAuthenticationRef at the same time.
*
* Parameters:
*
* auth:
* The authentication information being queried.
*
* Result:
* Returns TRUE if the password is sent in an unencrypted manner.
*
*/
extern Boolean
_CFHTTPAuthenticationPasswordInClear(CFHTTPAuthenticationRef auth) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* _CFHTTPAuthenticationCopyServerSupportedSchemes()
*
* Discussion:
* Returns a CFArray containing the names of the methods of
* authentication that the server supports.
*
* Mac OS X threading:
* Thread safe
* Thread safe
*
* Parameters:
*
* auth:
* The authentication information being queried.
*
* Result:
* Returns a CFArray of CFStringRef's which are the names of the
* supported schemes. NULL will be returned if the authentication
* object is not valid.
*
*/
extern CFArrayRef
_CFHTTPAuthenticationCopyServerSupportedSchemes(CFHTTPAuthenticationRef auth) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* _CFHTTPAuthenticationSetPreferredScheme()
*
* Discussion:
* Forces this authentication object to use the given scheme instead
* of its chosen scheme. This call must be made prior to first use,
* so preferrably right after the authentication object is created.
* Keep in mind some authentication objects are carried over from
* one response to another.
*
* Mac OS X threading:
* Thread safe
* Thread safe
*
* Parameters:
*
* auth:
* The authentication information to be adjusted.
*
* scheme:
* The name of the new preferred scheme.
*
* Result:
* Returns TRUE on success and FALSE on failure.
*
*/
extern Boolean
_CFHTTPAuthenticationSetPreferredScheme(
CFHTTPAuthenticationRef auth,
CFStringRef scheme) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* _CFHTTPAuthenticationApplyHeaderToRequest()
*
* Discussion:
* Sets the required authorization or proxy authorization header on
* the request which is to be sent out on the given request. This
* is needed for connection-based authentication schemes since the
* connection association for a request is not known until late.
*
* Mac OS X threading:
* Thread safe
* Thread safe
*
* Parameters:
*
* auth:
* The authentication information to be used.
*
* request:
* The request to gain the authorization headers.
*
* connection:
* The connection to which the request is associated. This
* represents the pipe on which the request will be sent.
*
* Result:
* Returns a CFStreamError. The error field will be zero if there
* is no error.
*
*/
extern CFStreamError
_CFHTTPAuthenticationApplyHeaderToRequest(
CFHTTPAuthenticationRef auth,
CFHTTPMessageRef request,
const void * connection) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* _CFHTTPAuthenticationDisassociateConnection()
*
* Discussion:
* Breaks the association between an authentication object and a
* connection reference. This association is first made with a call
* to _CFHTTPAuthenticationApplyHeaderToRequest.
*
* Mac OS X threading:
* Thread safe
* Thread safe.
*
* Parameters:
*
* auth:
* The authentication information to be used.
*
* connection:
* The connection to which the authentication object is referenced.
*
*/
extern void
_CFHTTPAuthenticationDisassociateConnection(
CFHTTPAuthenticationRef auth,
const void * connection) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* _CFHTTPMessageCanRetry()
*
* Discussion:
* Upon a failure of a request which had credentials applied, this
* function will return TRUE if it believes that another attempt
* might succeed if the credentials are applied to a new request.
* The caller should differentiate between 407 and 401 errors before
* calling this, since it is possible to get a 407 followed by a 401
* in a legal progress of fetching.
*
* Mac OS X threading:
* Thread safe
* The API's to CFHTTPAuthenticationRef are thread-safe so long as
* multiple threads are not altering the same
* CFHTTPAuthenticationRef at the same time.
*
* Parameters:
*
* response:
* The failed response being queried.
*
* Result:
* Returns TRUE if it is believed that re-applying credentials might
* allow the request to succeed, otherwise FALSE is returned.
*
*/
extern Boolean
_CFHTTPMessageCanRetry(CFHTTPMessageRef response) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* _CFGregorianDateCreateWithBytes()
*
* Discussion:
* Parses RFC 850, RFC 1123, and asctime formatted date/time strings.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* alloc:
* The allocator to be used for new allocations.
*
* bytes:
* Pointer to a byte buffer to be parsed.
*
* length:
* Number of bytes located at the bytes pointer location.
*
* date:
* Reference to a CFGregorianDate structure to be filled with the
* parse results.
*
* tz:
* Reference to a CFTimeZoneRef if the time zone information is to
* be parsed. Pass NULL if the time zone is not to be parsed.
* This will be allocated with the passed in allocator argument.
*
* Result:
* Returns the location in the buffer where parsing finished. If
* nothing was parsed as a result of failure, the result will be
* bytes. If the time zone could not parse, tz will be set to NULL
* but a result not equal to bytes will be returned.
*
*/
extern const UInt8 *
_CFGregorianDateCreateWithBytes(
CFAllocatorRef alloc,
const UInt8 * bytes,
CFIndex length,
CFGregorianDate * date,
CFTimeZoneRef * tz) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* _CFGregorianDateCreateWithString()
*
* Discussion:
* Parses RFC 850, RFC 1123, and asctime formatted date/time strings.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* alloc:
* The allocator to be used for new allocations.
*
* str:
* CFStringRef to be parsed.
*
* date:
* Reference to a CFGregorianDate structure to be filled with the
* parse results.
*
* tz:
* Reference to a CFTimeZoneRef if the time zone information is to
* be parsed. Pass NULL if the time zone is not to be parsed.
* This will be allocated with the passed in allocator argument.
*
* Result:
* Same as _CFGregorianDateCreateWithBytes but returns the count of
* characters parsed.
*
*/
extern CFIndex
_CFGregorianDateCreateWithString(
CFAllocatorRef alloc,
CFStringRef str,
CFGregorianDate * date,
CFTimeZoneRef * tz) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* _CFStringCreateRFC1123DateStringWithGregorianDate()
*
* Discussion:
* Creates a RFC 1123 formatted date and time string.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* alloc:
* The allocator to be used for the new allocation.
*
* date:
* Reference to a CFGregorianDate structure to be used.
*
* tz:
* Time zone reference if offset is different than GMT. If NULL
* is passed, the offset is assumed to be +0000.
*
* Result:
* A string representing the passed in date and time in the RFC 1123
* format.
*
*/
extern CFStringRef
_CFStringCreateRFC1123DateStringWithGregorianDate(
CFAllocatorRef alloc,
CFGregorianDate * date,
CFTimeZoneRef tz) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* _CFStringCreateRFC2616DateStringWithGregorianDate()
*
* Discussion:
* Creates a RFC 2616 formatted date and time string.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* alloc:
* The allocator to be used for the new allocation.
*
* date:
* Reference to a CFGregorianDate structure to be used.
*
* tz:
* Time zone reference if offset is different than GMT. If NULL
* is passed, the time zone is assumed to be GMT.
*
* Result:
* A string representing the passed in date and time in the RFC 2616
* format.
*
*/
extern CFStringRef
_CFStringCreateRFC2616DateStringWithGregorianDate(
CFAllocatorRef alloc,
CFGregorianDate * date,
CFTimeZoneRef tz) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint reset
#endif
#ifdef __cplusplus
}
#endif
#endif /* __CFHTTPMESSAGEPRIV__ */

View File

@ -0,0 +1,592 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFHTTPServerPriv.h
Contains: CoreFoundation Network HTTP server SPI
Copyright: © 2003-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file contains unreleased SPI's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFHTTPServerPriv.i
Revision: 1.7
Dated: 2004/06/01 17:53:05
Last change by: rew
Last comment: Updating all copyrights to include 2004
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFHTTPSERVERPRIV__
#define __CFHTTPSERVERPRIV__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __COREFOUNDATION__
#include <CoreFoundation/CoreFoundation.h>
#endif
#ifndef __CFNETWORK__
#include <CFNetwork/CFNetwork.h>
#endif
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint on
#endif
/*
* _CFHTTPServerError
*
* Discussion:
* HTTP server's error domain and its errors.
*/
enum _CFHTTPServerError {
/*
* CFStreamError domain for HTTP server errors.
*/
kCFStreamErrorDomainCFHTTPServer = 20,
/*
* Critical failure and server should be shutdown and destroyed.
*/
kCFStreamErrorCFHTTPServerInternal = 1,
/*
* A timeout occurred on the given request (and response).
*/
kCFStreamErrorCFHTTPServerTimeout = 2
};
typedef enum _CFHTTPServerError _CFHTTPServerError;
/*
* _CFHTTPServerRef
*
* Discussion:
* This is the type of a reference to a HTTP server. Although
* individual functions are thread-safe, _CFHTTPServerRef itself is
* not thread-safe.
*/
typedef struct __CFHTTPServer* _CFHTTPServerRef;
/*
* _CFHTTPServerContext
*
* Discussion:
* Structure containing the user-defined data and callbacks for
* _CFHTTPServerRef objects.
*/
struct _CFHTTPServerContext {
/*
* The version number of the structure type being passed in as a
* parameter to the CFHTTPServer creation function. Valid version
* number is currently 0.
*/
CFIndex version;
/*
* An arbitrary pointer to client-defined data, which can be
* associated with the host and is passed to the callbacks.
*/
void * info;
/*
* The callback used to add a retain for the host on the info pointer
* for the life of the host, and may be used for temporary references
* the host needs to take. This callback returns the actual info
* pointer to store in the host, almost always just the pointer
* passed as the parameter.
*/
CFAllocatorRetainCallBack retain;
/*
* The callback used to remove a retain previously added for the host
* on the info pointer.
*/
CFAllocatorReleaseCallBack release;
/*
* The callback used to create a descriptive string representation of
* the info pointer (or the data pointed to by the info pointer) for
* debugging purposes. This is used by the CFCopyDescription()
* function.
*/
CFAllocatorCopyDescriptionCallBack copyDescription;
};
typedef struct _CFHTTPServerContext _CFHTTPServerContext;
/*
* _CFHTTPServerAcceptNewConnectionCallBack
*
* Discussion:
* Callback which is invoked as a new connection is accepted.
*
* Parameters:
*
* server:
* The instance of the server which is receiving the connection.
*
* peer:
* A CFDataRef which contains a struct sockaddr holding the peer's
* network address.
*
* info:
* The reference from the server context which was given when the
* server was created.
*
* Result:
* A boolean value of TRUE if the server should accept the
* connection. FALSE should be returned if the server should deny
* the connection.
*/
typedef CALLBACK_API_C( Boolean , _CFHTTPServerAcceptNewConnectionCallBack )(_CFHTTPServerRef server, CFDataRef peer, void *info);
/*
* _CFHTTPServerAcceptNewRequestCallBack
*
* Discussion:
* Callback which is invoked as a request begins to arrive. This
* callback will be called after the headers have arrived but before
* the body.
*
* Parameters:
*
* server:
* The instance of the server which is receiving the request.
*
* headers:
* The headers which have been received.
*
* peer:
* A CFDataRef which contains a struct sockaddr holding the peer's
* network address.
*
* info:
* The reference from the server context which was given when the
* server was created.
*
* Result:
* A boolean value of TRUE if the server should accept the request.
* FALSE should be returned if the server should deny the request.
* All requests on the outstanding connection will be cancelled too.
*/
typedef CALLBACK_API_C( Boolean , _CFHTTPServerAcceptNewRequestCallBack )(_CFHTTPServerRef server, CFHTTPMessageRef headers, CFDataRef peer, void *info);
/*
* _CFHTTPServerDidReceiveRequestCallBack
*
* Discussion:
* Callback which is invoked when a request has been successfully
* received.
*
* Parameters:
*
* server:
* The instance of the server which received the given request.
*
* request:
* The request which was received. Use this request in order to
* add a response.
*
* info:
* The reference from the server context which was given when the
* server was created.
*/
typedef CALLBACK_API_C( void , _CFHTTPServerDidReceiveRequestCallBack )(_CFHTTPServerRef server, CFHTTPMessageRef request, void *info);
/*
* _CFHTTPServerDidSendResponseCallBack
*
* Discussion:
* Callback which is invoked when an individual response has been
* successfully sent.
*
* Parameters:
*
* server:
* The instance of the server with which the request and response
* were associated.
*
* request:
* The original request with which the response was associated.
*
* response:
* The massaged response which was sent over the wire. This is a
* copy of the original response and has no body. It is just the
* headers.
*
* info:
* The reference from the server context which was given when the
* server was created.
*/
typedef CALLBACK_API_C( void , _CFHTTPServerDidSendResponseCallBack )(_CFHTTPServerRef server, CFHTTPMessageRef request, CFHTTPMessageRef response, void *info);
/*
* _CFHTTPServerErrorCallBack
*
* Discussion:
* Callback which is invoked when errors occur in the server. All
* requests and responses on a single persistent connection will
* receive the error at the same time if it was the connection
* itself which had the error.
*
* Parameters:
*
* server:
* The instance of the server which received the error.
*
* error:
* Reference to the CFStreamError which contains the error
* information.
*
* request:
* If non-NULL, the request which was being actively managed when
* the error was received.
*
* response:
* If non-NULL, the response which was being actively managed when
* the error was received.
*
* info:
* The reference from the server context which was given when the
* server was created.
*/
typedef CALLBACK_API_C( void , _CFHTTPServerErrorCallBack )(_CFHTTPServerRef server, const CFStreamError *error, CFHTTPMessageRef request, CFHTTPMessageRef response, void *info);
/*
* _CFHTTPServerCallBacks
*
* Discussion:
* The set of callbacks which will be invoked as different events
* occur inside of the server.
*/
struct _CFHTTPServerCallBacks {
/*
* The version number of the structure type being passed in as a
* parameter to the CFHTTPServer creation function. Valid version
* number is currently 0.
*/
CFIndex version;
/*
* Callback invoked when a new incoming connection is accepted.
*/
_CFHTTPServerAcceptNewConnectionCallBack acceptNewConnectionCallBack;
/*
* Callback invoked when a new incoming request has started but after
* the headers have arrived.
*/
_CFHTTPServerAcceptNewRequestCallBack acceptNewRequestCallBack;
/*
* Callback invoked when a full request has been received.
*/
_CFHTTPServerDidReceiveRequestCallBack didReceiveRequestCallBack;
/*
* Callback invoked when an individual response has been completely
* sent.
*/
_CFHTTPServerDidSendResponseCallBack didSendResponseCallBack;
/*
* Callback invoked if there is an error on the server.
*/
_CFHTTPServerErrorCallBack errorCallBack;
};
typedef struct _CFHTTPServerCallBacks _CFHTTPServerCallBacks;
/*
* _CFHTTPServerGetTypeID()
*
* Discussion:
* Returns the type identifier of all _CFHTTPServer instances.
*
* Mac OS X threading:
* Not thread safe
*
*/
extern CFTypeID
_CFHTTPServerGetTypeID(void) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFHTTPServerCreate()
*
* Discussion:
* Creates a new HTTP server.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* alloc:
* The CFAllocator which should be used to allocate memory for the
* server. If this reference is not a valid CFAllocator, the
* behavior is undefined.
*
* callbacks:
* The callbacks which should be called as requests and responses
* are handled or if errors occur.
*
* context:
* A _CFHTTPServerContext which is used to set the contextual
* information associated with the server object. The info pointer
* from the struct will be passed to the callback function.
*
* Result:
* Returns NULL if unsuccessful, otherwise a _CFHTTPServerRef will
* be returned.
*
*/
extern _CFHTTPServerRef
_CFHTTPServerCreate(
CFAllocatorRef alloc,
const _CFHTTPServerCallBacks * callbacks,
_CFHTTPServerContext * context) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFHTTPServerStart()
*
* Discussion:
* Starts the server listening and handling incoming connections on
* the given port. It also Rendezvous advertises itself on the
* local domain with the given name and type if provided.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* server:
* The server being started. Must be non-NULL. If this reference
* is not a valid _CFHTTPServerRef, the behavior is undefined.
*
* name:
* The name to use for Rendezvous advertising. The empty string
* or NULL indicate to use the machine's name.
*
* serviceType:
* The type of service being advertised on Rendezvous. If the
* service type and name are both NULL, the server will not
* Rendezvous advertise itself.
*
* port:
* The port on which the server should be listening for new
* connections. Use zero to indicate that the server can assign
* one for the service (use this is a well-known port has not been
* assigned).
*
* Result:
* Returns TRUE is the server was started. It returns FALSE if
* there was a failure to start the server.
*
*/
extern Boolean
_CFHTTPServerStart(
_CFHTTPServerRef server,
CFStringRef name,
CFStringRef serviceType,
UInt32 port) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFHTTPServerInvalidate()
*
* Discussion:
* Invalidates the server, so that it no longer accepts connections
* and the client will no longer receive callbacks. All outstanding
* requests/responses are terminated.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* server:
* The server being invalidated. Must be non-NULL. If this
* reference is not a valid _CFHTTPServerRef, the behavior is
* undefined.
*
*/
extern void
_CFHTTPServerInvalidate(_CFHTTPServerRef server) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFHTTPServerGetPort()
*
* Discussion:
* Returns the port on which the server is listening. If not
* currently listening, it will return zero.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* server:
* The server being queried. Must be non-NULL. If this reference
* is not a valid _CFHTTPServerRef, the behavior is undefined.
*
*/
extern UInt32
_CFHTTPServerGetPort(_CFHTTPServerRef server) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFHTTPServerCopyPeerAddressForRequest()
*
* Discussion:
* Given an incoming request, this function will retrieve the peer's
* address.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* server:
* The server which received the request.
*
* request:
* The incoming request whose peer wishes to be known.
*
* Result:
* Returns a CFDataRef which contains a struct sockaddr holding the
* address of the peer. NULL is returned if not known.
*
*/
extern CFDataRef
_CFHTTPServerCopyPeerAddressForRequest(
_CFHTTPServerRef server,
CFHTTPMessageRef request) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFHTTPServerAddResponse()
*
* Discussion:
* Adds the given response for the request to the server. Only one
* response should be added per individual request.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* server:
* The server on which the request was received. Must be
* non-NULL. If this reference is not a valid _CFHTTPServerRef,
* the behavior is undefined.
*
* request:
* The request which was received and for which the response being
* added corresponds.
*
* response:
* The response being added for the given request.
*
*/
extern void
_CFHTTPServerAddResponse(
_CFHTTPServerRef server,
CFHTTPMessageRef request,
CFHTTPMessageRef response) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFHTTPServerAddStreamedResponse()
*
* Discussion:
* Adds the given response headers and body for the request to the
* server. Only one response should be added per individual request.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* server:
* The server on which the request was received. Must be
* non-NULL. If this reference is not a valid _CFHTTPServerRef,
* the behavior is undefined.
*
* request:
* The request which was received and for which the response being
* added corresponds.
*
* responseHeaders:
* The headers for the response being added.
*
* body:
* An unopened CFReadStreamRef which will be used for stream- ing
* the body's data to the requesting client.
*
*/
extern void
_CFHTTPServerAddStreamedResponse(
_CFHTTPServerRef server,
CFHTTPMessageRef request,
CFHTTPMessageRef responseHeaders,
CFReadStreamRef body) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint reset
#endif
#ifdef __cplusplus
}
#endif
#endif /* __CFHTTPSERVERPRIV__ */

447
src/Headers/CFHTTPStream.h Normal file
View File

@ -0,0 +1,447 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFHTTPStream.h
Contains: CoreFoundation Network HTTP streams header
Copyright: © 2001-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file may contain unreleased API's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFHTTPStream.i
Revision: 1.6
Dated: 2004/08/03 22:57:05
Last change by: jiarocci
Last comment: Update Interface files to include headerdoc and remove warnings.
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFHTTPSTREAM__
#define __CFHTTPSTREAM__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __CFSTREAM__
#include <CoreFoundation/CFStream.h>
#endif
#ifndef __CFHTTPMESSAGE__
#include <CFNetwork/CFHTTPMessage.h>
#endif
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint on
#endif
/*
* kCFStreamErrorDomainHTTP
*
* Discussion:
* Result code returned by HTTP server
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const SInt32 kCFStreamErrorDomainHTTP AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFStreamErrorHTTP
*
* Discussion:
* Errors from the kCFStreamErrorDomainHTTP domain.
*/
enum CFStreamErrorHTTP {
/*
* Could not parse the request/response.
*/
kCFStreamErrorHTTPParseFailure = -1,
/*
* A loop was detected during redirection.
*/
kCFStreamErrorHTTPRedirectionLoop = -2,
/*
* Could not retreive url for request/response.
*/
kCFStreamErrorHTTPBadURL = -3
};
typedef enum CFStreamErrorHTTP CFStreamErrorHTTP;
/*
* kCFStreamPropertyHTTPResponseHeader
*
* Discussion:
* Stream property key, for copy operations. Value is a
* CFHTTPMessage with 0 bytes data.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyHTTPResponseHeader AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* kCFStreamPropertyHTTPFinalURL
*
* Discussion:
* Stream property key, for copy operations. The response header
* value is the CFURL from the final request; will only differ from
* the URL in the original request if an autoredirection has
* occurred.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyHTTPFinalURL AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* kCFStreamPropertyHTTPProxy
*
* Discussion:
* Stream property key, for both set and copy operations. The value
* is a CFDictionary. HTTP proxy information is set the same way as
* SOCKS proxies (see CFSocketStream.h). Call
* CFReadStreamSetProperty() passing an HTTP stream and the property
* kCFStreamPropertyHTTPProxy. The value should include at least one
* Host/Port pair from the keys below. Use the dictionary returned
* by SystemConfiguration.framework to set the default values for
* the system. HTTP proxies are not applied automatically.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyHTTPProxy AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* kCFStreamPropertyHTTPProxyHost
*
* Discussion:
* Proxy dictionary key. The hostname of an HTTP proxy. The value is
* a CFString. The key name matches kSCPropNetProxiesHTTPProxy.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyHTTPProxyHost AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* kCFStreamPropertyHTTPProxyPort
*
* Discussion:
* Proxy dictionary key. Value is a CFNumber.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyHTTPProxyPort AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/* matches kSCPropNetProxiesHTTPPort */
/*
* kCFStreamPropertyHTTPSProxyHost
*
* Discussion:
* Proxy dictionary key. Value is a CFString.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyHTTPSProxyHost AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/* matches kSCPropNetProxiesHTTPSProxy */
/*
* kCFStreamPropertyHTTPSProxyPort
*
* Discussion:
* Proxy dictionary key. Value is a CFNumber.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyHTTPSProxyPort AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/* matches kSCPropNetProxiesHTTPSPort */
/*
* kCFStreamPropertyHTTPShouldAutoredirect
*
* Discussion:
* Proxy dictionary key. Value is a CFBoolean. Redirection is not
* performed by default.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyHTTPShouldAutoredirect AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* kCFStreamPropertyHTTPAttemptPersistentConnection
*
* Discussion:
* Proxy dictionary key. Value is a CFBoolean. If this property is
* set to kCFBooleanTrue, an HTTP stream will look for an
* appropriate extant persistent connection to use, and if it finds
* none, will try to create one. Persistent connections are not used
* by default.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyHTTPAttemptPersistentConnection AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* kCFStreamPropertyHTTPRequestBytesWrittenCount
*
* Discussion:
* Proxy dictionary key. Value is a CFNumber. This property can only
* be retrieved, not set. The number returned is the number of bytes
* from the body of the request that have been written to the
* underlying socket
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyHTTPRequestBytesWrittenCount AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*********************/
/* Creation routines */
/*********************/
/*
* CFReadStreamCreateForHTTPRequest()
*
* Discussion:
* Create an HTTP read stream for the response to the given request.
* When the stream is opened, it will begin transmitting the
* request. The bytes returned are the pure body bytes; the response
* header has been parsed off. To retrieve the response header, ask
* for kCFStreamPropertyHTTPResponseHeader, above, any time after
* the first bytes arrive on the stream (or when stream end is
* reported, if there are no data bytes). When an HTTP/1.1 server
* returns a chunked a response, the chunks will be formed into one
* continuous stream.
*
* Parameters:
*
* alloc:
* A pointer to the CFAllocator which should be used to allocate
* memory for the CF read stream and its storage for values. If
* this reference is not a valid CFAllocator, the behavior is
* undefined.
*
* request:
* A pointer to a CFHTTPMessage created by the
* CFHTTPMessageCreateRequest function.
*
* Result:
* A pointer to the CF read stream created, or NULL if failed. It is
* caller's responsibilty to release the memory allocated for the
* read stream.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFReadStreamRef
CFReadStreamCreateForHTTPRequest(
CFAllocatorRef alloc,
CFHTTPMessageRef request) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER;
/*
* CFReadStreamCreateForStreamedHTTPRequest()
*
* Discussion:
* Creates a read stream for the response to the given
* requestHeaders plus requestBody. Use in preference to
* CFReadStreamCreateForHTTPRequest() when the body of the request
* is larger than you wish to be resident in memory. Note that
* because streams cannot be reset, read streams created this way
* cannot have autoredirection enabled. If the Content-Length
* header is set in requestHeaders, it is assumed that the caller
* got the length right and that requestBody will report
* end-of-stream after precisely Content-Length bytes have been read
* from it. If the Content-Length header is not set, the chunked
* transfer-encoding will be added to requestHeaders, and bytes read
* from requestBody will be transmitted chunked. The body of
* requestHeaders is ignored.
*
* Parameters:
*
* alloc:
* A pointer to the CFAllocator which should be used to allocate
* memory for the CF read stream and its storage for values. If
* this reference is not a valid CFAllocator, the behavior is
* undefined.
*
* requestHeaders:
* A pointer to a CFHTTPMessage created by the
* CFHTTPMessageCreateRequest function. The body of requestHeaders
* is ignored.
*
* requestBody:
* A pointer to a CFReadStream.
*
* Result:
* A pointer to the CF read stream created, or NULL if failed. It is
* caller's responsibilty to release the memory allocated for the
* read stream.
*
* Availability:
* Mac OS X: in version 10.2 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFReadStreamRef
CFReadStreamCreateForStreamedHTTPRequest(
CFAllocatorRef alloc,
CFHTTPMessageRef requestHeaders,
CFReadStreamRef requestBody) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*
* CFHTTPReadStreamSetRedirectsAutomatically() *** DEPRECATED ***
*
* Deprecated:
* Use the kCFStreamPropertyHTTPShouldAutoredirect property above
* instead.
*
* Discussion:
* Sets the redirection property on the http stream.
*
* Parameters:
*
* httpStream:
* A pointer to the CFHTTPStream to be set.
*
* shouldAutoRedirect:
* A boolean indicating whether to redirect or not.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework but deprecated in 10.3
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern void
CFHTTPReadStreamSetRedirectsAutomatically(
CFReadStreamRef httpStream,
Boolean shouldAutoRedirect) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_3;
/*
* CFHTTPReadStreamSetProxy() *** DEPRECATED ***
*
* Deprecated:
* Use the kCFStreamPropertyHTTPProxy above instead.
*
* Discussion:
* Sets the redirection property on the http stream.
*
* Parameters:
*
* httpStream:
* A pointer to the CFHTTPStream to be set.
*
* proxyHost:
* The proxy hostname. A CFString value.
*
* proxyPort:
* The port number. A CFNumber value.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework but deprecated in 10.3
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern void
CFHTTPReadStreamSetProxy(
CFReadStreamRef httpStream,
CFStringRef proxyHost,
CFIndex proxyPort) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_3;
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint reset
#endif
#ifdef __cplusplus
}
#endif
#endif /* __CFHTTPSTREAM__ */

View File

@ -0,0 +1,126 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFHTTPStreamPriv.h
Contains: CoreFoundation Network HTTP streams header (private)
Copyright: © 2003-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file contains unreleased SPI's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFHTTPStreamPriv.i
Revision: 1.5
Dated: 2004/06/01 17:53:05
Last change by: rew
Last comment: Updating all copyrights to include 2004
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFHTTPSTREAMPRIV__
#define __CFHTTPSTREAMPRIV__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __CFHTTPSTREAM__
#include <CFNetwork/CFHTTPStream.h>
#endif
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint on
#endif
extern const CFStringRef kCFStreamPropertyHTTPRequest AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/* Value is the CFHTTPMessage that represents the request*/
extern const CFStringRef kCFHTTPRedirectionResponse AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
/*The first redirection*/
/*
The following routines filter the read or write stream as if they were coming from
or going to an HTTP server. The read stream variant, for instance, strips off the
first bytes and interprets them as an HTTP header. The write stream formats the
given request and transmits it before transmitting the write stream bytes.
*/
extern CFReadStreamRef
CFReadStreamCreateHTTPStream(
CFAllocatorRef alloc,
CFReadStreamRef readStream,
Boolean forResponse) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
extern CFWriteStreamRef
CFWriteStreamCreateHTTPStream(
CFAllocatorRef alloc,
CFHTTPMessageRef header,
Boolean useFullURL,
CFWriteStreamRef socketStream) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
extern CFDataRef
_CFHTTPMessageCopySerializedMessage(
CFHTTPMessageRef msg,
Boolean forProxy) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
extern void
_CFHTTPMessageSetHeader(
CFHTTPMessageRef msg,
CFStringRef theHeader,
CFStringRef value,
CFIndex position) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
extern const CFStringRef _kCFStreamPropertyHTTPConnectionStreams AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
extern const CFStringRef _kCFStreamPropertyHTTPZeroLengthResponseExpected AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER;
extern const CFStringRef _kCFStreamPropertyHTTPProxyProxyAutoConfigURLString AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
extern const CFStringRef _kCFStreamPropertyHTTPProxyProxyAutoConfigEnable AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint reset
#endif
#ifdef __cplusplus
}
#endif
#endif /* __CFHTTPSTREAMPRIV__ */

667
src/Headers/CFHost.h Normal file
View File

@ -0,0 +1,667 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFHost.h
Contains: CoreFoundation CFHost header
Copyright: © 2001-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file may contain unreleased API's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFHost.i
Revision: 1.8
Dated: 2004/06/01 17:53:05
Last change by: rew
Last comment: Updating all copyrights to include 2004
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFHOST__
#define __CFHOST__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __COREFOUNDATION__
#include <CoreFoundation/CoreFoundation.h>
#endif
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint on
#endif
/*
* CFHostRef
*
* Discussion:
* This is the type of a reference to a host name or address lookup.
*/
typedef struct __CFHost* CFHostRef;
/*
* kCFStreamErrorDomainNetDB
*
* Discussion:
* Errors listed in netdb.h
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const SInt32 kCFStreamErrorDomainNetDB AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFStreamErrorDomainSystemConfiguration
*
* Discussion:
* Errors listed in SystemConfiguration/SystemConfiguration.h
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const SInt32 kCFStreamErrorDomainSystemConfiguration AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFHostInfoType
*
* Discussion:
* Host information types to be resolved.
*/
enum CFHostInfoType {
/*
* Results value is a CFArray of CFData's (each being a struct
* sockaddr)
*/
kCFHostAddresses = 0,
/*
* Results value is a CFArray of CFString's
*/
kCFHostNames = 1,
/*
* Results value is a CFData wrapping SCNetworkConnectionFlags
* (defined in SystemConfiguration/SCNetwork.h)
*/
kCFHostReachability = 2
};
typedef enum CFHostInfoType CFHostInfoType;
/*
* CFHostClientContext
*
* Discussion:
* Structure containing the user-defined data and callbacks for
* CFHost objects.
*/
struct CFHostClientContext {
/*
* The version number of the structure type being passed in as a
* parameter to the CFHost client function. Valid version number is
* currently 0.
*/
CFIndex version;
/*
* An arbitrary pointer to client-defined data, which can be
* associated with the host and is passed to the callbacks.
*/
void * info;
/*
* The callback used to add a retain for the host on the info pointer
* for the life of the host, and may be used for temporary references
* the host needs to take. This callback returns the actual info
* pointer to store in the host, almost always just the pointer
* passed as the parameter.
*/
CFAllocatorRetainCallBack retain;
/*
* The callback used to remove a retain previously added for the host
* on the info pointer.
*/
CFAllocatorReleaseCallBack release;
/*
* The callback used to create a descriptive string representation of
* the info pointer (or the data pointed to by the info pointer) for
* debugging purposes. This is used by the CFCopyDescription()
* function.
*/
CFAllocatorCopyDescriptionCallBack copyDescription;
};
typedef struct CFHostClientContext CFHostClientContext;
/*
* CFHostClientCallBack
*
* Discussion:
* Callback function which is called upon error or completion of an
* asynchronous resolve.
*
* Parameters:
*
* theHost:
* Host whose resolution is complete.
*
* typeInfo:
* Enum representing which info resolution is complete.
*
* error:
* Reference to an error structure if the resolution failed.
*
* info:
* Client's info reference which was passed into the client
* context.
*/
typedef CALLBACK_API_C( void , CFHostClientCallBack )(CFHostRef theHost, CFHostInfoType typeInfo, const CFStreamError *error, void *info);
/*
* CFHostGetTypeID()
*
* Discussion:
* Returns the type identifier of all CFHost instances.
*
* Mac OS X threading:
* Thread safe
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFTypeID
CFHostGetTypeID(void) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFHostCreateWithName()
*
* Discussion:
* Creates a new host object with the given name.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* allocator:
* The CFAllocator which should be used to allocate memory for the
* host. If this reference is not a valid CFAllocator, the
* behavior is undefined.
*
* hostname:
* A CFStringRef representing the name of the host. Must be
* non-NULL. If this If this reference is not a valid
* CFStringRef, the behavior is undefined.
*
* Result:
* A valid CFHostRef which may now be resolved, or NULL if
* unsuccessful.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFHostRef
CFHostCreateWithName(
CFAllocatorRef allocator,
CFStringRef hostname) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFHostCreateWithAddress()
*
* Discussion:
* Creates a new host object with the given address.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* allocator:
* The CFAllocator which should be used to allocate memory for the
* host. If this reference is not a valid CFAllocator, the
* behavior is undefined.
*
* addr:
* A CFDataRef containing a struct sockaddr which is the address
* of the host. Must be non-NULL. If this If this reference is
* not a valid CFDataRef, the behavior is undefined.
*
* Result:
* A valid CFHostRef which may now be resolved, or NULL if
* unsuccessful.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFHostRef
CFHostCreateWithAddress(
CFAllocatorRef allocator,
CFDataRef addr) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFHostCreateCopy()
*
* Discussion:
* Creates a new host object as a copy of host argument.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* alloc:
* The CFAllocator which should be used to allocate memory for the
* new host. If this reference is not a valid CFAllocator, the
* behavior is undefined.
*
* host:
* A CFHostRef representing the original host. Must be non-NULL.
* If this If this reference is not a valid CFHostRef, the
* behavior is undefined.
*
* Result:
* A valid CFHostRef which contains a copy of all previously
* resolved data from the original. NULL is returned in the case of
* failure.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFHostRef
CFHostCreateCopy(
CFAllocatorRef alloc,
CFHostRef host) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFHostStartInfoResolution()
*
* Discussion:
* Performs a lookup for the given host. It will search for the
* requested information if there is no other active request.
* Previously cached information of the given type will be released.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* theHost:
* The CFHostRef which should be resolved. Must be non-NULL. If
* this reference is not a valid CFHostRef, the behavior is
* undefined.
*
* info:
* The enum representing the type of information to be retrieved.
* If the value is not a valid type, the behavior is undefined.
*
* error:
* A reference to a CFStreamError structure which will be filled
* with any error information should an error occur. May be set
* to NULL if error information is not wanted.
*
* Result:
* Returns TRUE on success and FALSE on failure. In asynchronous
* mode, this function will return immediately. In synchronous
* mode, it will block until the resolve has completed or until the
* resolve is cancelled.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern Boolean
CFHostStartInfoResolution(
CFHostRef theHost,
CFHostInfoType info,
CFStreamError * error) /* can be NULL */ AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFHostGetAddressing()
*
* Discussion:
* Tries to retrieve the known addresses from the given host.
* Returns a CFArrayRef of addresses if known and there were some.
* NULL is returned otherwise. Each address is a CFDataRef wrapping
* a struct sockaddr.
*
* Mac OS X threading:
* Thread safe
* The function gets the data in a thread-safe manner, but the
* resulting data is not safe. Since it is returned as a matter of
* a get opposed to a copy, the data is not safe if the host is
* being altered from another thread.
*
* Parameters:
*
* theHost:
* The CFHostRef which contains the relevant information. Must be
* non-NULL. If this reference is not a valid CFHostRef, the
* behavior is undefined.
*
* hasBeenResolved:
* A reference to a Boolean which returns FALSE if the information
* was not available (e.g. CFHostStartInfoResolution has not been
* called), otherwise TRUE will be returned.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFArrayRef
CFHostGetAddressing(
CFHostRef theHost,
Boolean * hasBeenResolved) /* can be NULL */ AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFHostGetNames()
*
* Discussion:
* Tries to retrieve the names/aliases from the given host. Returns
* a CFArrayRef of names for the given host. NULL is returned
* otherwise.
*
* Mac OS X threading:
* Thread safe
* The function gets the data in a thread-safe manner, but the
* resulting data is not safe. Since it is returned as a matter of
* a get opposed to a copy, the data is not safe if the host is
* being altered from another thread.
*
* Parameters:
*
* theHost:
* The CFHostRef which contains the relevant information. Must be
* non-NULL. If this reference is not a valid CFHostRef, the
* behavior is undefined.
*
* hasBeenResolved:
* A reference to a Boolean which returns FALSE if the information
* was not available (e.g. CFHostStartInfoResolution has not been
* called), otherwise TRUE will be returned.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFArrayRef
CFHostGetNames(
CFHostRef theHost,
Boolean * hasBeenResolved) /* can be NULL */ AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFHostGetReachability()
*
* Discussion:
* Tries to retrieve the reachability of the given host. Returns a
* CFDataRef which wraps the reachability flags. NULL will be
* returned if the value has not been resolved. The possible values
* of these flags is declared in SystemConfiguration/SCNetwork.h.
* Returns FALSE if the information was not available, otherwise
* TRUE will be returned with the results containing the requested
* information.
*
* Mac OS X threading:
* Thread safe
* The function gets the data in a thread-safe manner, but the
* resulting data is not safe. Since it is returned as a matter of
* a get opposed to a copy, the data is not safe if the host is
* being altered from another thread.
*
* Parameters:
*
* theHost:
* The CFHostRef which contains the relevant information. Must be
* non-NULL. If this reference is not a valid CFHostRef, the
* behavior is undefined.
*
* hasBeenResolved:
* A reference to a Boolean which returns FALSE if the information
* was not available (e.g. CFHostStartInfoResolution has not been
* called), otherwise TRUE will be returned.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFDataRef
CFHostGetReachability(
CFHostRef theHost,
Boolean * hasBeenResolved) /* can be NULL */ AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFHostCancelInfoResolution()
*
* Discussion:
* Cancels an outstanding asynchronous or synchronous resolve.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* theHost:
* The CFHostRef which is currently resolving. Must be non-NULL.
* If this reference is not a valid CFHostRef, the behavior is
* undefined.
*
* info:
* The enum representing which resolution to be canceled. If the
* value is not a valid type, the behavior is undefined.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern void
CFHostCancelInfoResolution(
CFHostRef theHost,
CFHostInfoType info) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFHostSetClient()
*
* Discussion:
* Associates a client context and callback function with a
* CFHostRef. This is required for asynchronous usage. If not set,
* resolve will take place synchronously.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* theHost:
* The CFHostRef which is getting a client. Must be non-NULL. If
* this reference is not a valid CFHostRef, the behavior is
* undefined.
*
* clientCB:
* A CFHostClientCallBack which will be called when the resolve
* completes or is cancelled. Use NULL to remove the client
* association with a host object.
*
* clientContext:
* A CFHostClientContext which is used to set the contextual
* information associated with the host object. The info pointer
* from the struct will be passed to the callback function. If
* setting a client, this value must be non-NULL.
*
* Result:
* Returns TRUE if the procedure was a success, otherwise it returns
* FALSE.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern Boolean
CFHostSetClient(
CFHostRef theHost,
CFHostClientCallBack clientCB, /* can be NULL */
CFHostClientContext * clientContext) /* can be NULL */ AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFHostScheduleWithRunLoop()
*
* Discussion:
* Schedules the given host on a run loop and mode so the client
* will receive its callbacks on that loop and mode.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* theHost:
* The CFHostRef which is being scheduled. Must be non-NULL. If
* this reference is not a valid CFHostRef, the behavior is
* undefined.
*
* runLoop:
* A CFRunLoopRef on which the host should be scheduled. Must be
* non-NULL. If this reference is not a valid CFRunLoopRef, the
* behavior is undefined.
*
* runLoopMode:
* A CFStringRef which is the mode in which the run loop will be
* running when notification occurs. Must be non-NULL. If this
* reference is not a valid CFStringRef, the behavior is undefined.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern void
CFHostScheduleWithRunLoop(
CFHostRef theHost,
CFRunLoopRef runLoop,
CFStringRef runLoopMode) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFHostUnscheduleFromRunLoop()
*
* Discussion:
* Unschedules the given host from a run loop and mode so the client
* will not receive its callbacks on that loop and mode.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* theHost:
* The CFHostRef which is being unscheduled. Must be non-NULL. If
* this reference is not a valid CFHostRef, the behavior is
* undefined.
*
* runLoop:
* A CFRunLoopRef on which the host is scheduled and should now be
* unscheduled. Must be non-NULL. If this reference is not a
* valid CFRunLoopRef, the behavior is undefined.
*
* runLoopMode:
* A CFStringRef which is the mode in which the host is scheduled
* and should be unscheduled. Must be non-NULL. If this reference
* is not a valid CFStringRef, the behavior is undefined.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern void
CFHostUnscheduleFromRunLoop(
CFHostRef theHost,
CFRunLoopRef runLoop,
CFStringRef runLoopMode) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint reset
#endif
#ifdef __cplusplus
}
#endif
#endif /* __CFHOST__ */

123
src/Headers/CFHostPriv.h Normal file
View File

@ -0,0 +1,123 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFHostPriv.h
Contains: CoreFoundation Network CFHost header (private)
Copyright: © 2004-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file contains unreleased SPI's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFHostPriv.i
Revision: 1.4
Dated: 2004/06/01 17:53:05
Last change by: rew
Last comment: Updating all copyrights to include 2004
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFHOSTPRIV__
#define __CFHOSTPRIV__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __CFNETWORK__
#include <CFNetwork/CFNetwork.h>
#endif
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint on
#endif
/*
* CFHostGetInfo()
*
* Discussion:
* Tries to retrieve the information of the given type from the
* given host. Returns a CFTypeRef containing the information. The
* actual type of object returned is dictated by the type of
* information being requested. NULL is returned otherwise.
*
* Mac OS X threading:
* Not thread safe
* The function gets the data in a thread-safe manner, but the
* resulting data is not safe. Since it is returned as a matter of
* a get opposed to a copy, the data is not safe if the host is
* being altered from another thread.
*
* Parameters:
*
* theHost:
* The CFHostRef which contains the relevant information. Must be
* non-NULL. If this reference is not a valid CFHostRef, the
* behavior is undefined.
*
* info:
* The CFHostInfoType information type to retrieve.
*
* hasBeenResolved:
* A reference to a Boolean which returns FALSE if the information
* was not available (e.g. CFHostStartInfoResolution has not been
* called), otherwise TRUE will be returned.
*
*/
extern CFTypeRef
CFHostGetInfo(
CFHostRef theHost,
CFHostInfoType info,
Boolean * hasBeenResolved) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint reset
#endif
#ifdef __cplusplus
}
#endif
#endif /* __CFHOSTPRIV__ */

View File

@ -0,0 +1,290 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFNetDiagnostics.h
Contains: CFNetDiagnostics interface
Version: 1.0
Copyright: © 2004-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file may contain unreleased API's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFNetDiagnostics.i
Revision: 1.3
Dated: 2004/08/03 22:57:05
Last change by: jiarocci
Last comment: Update Interface files to include headerdoc and remove warnings.
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFNETDIAGNOSTICS__
#define __CFNETDIAGNOSTICS__
#ifndef __COREFOUNDATION__
#include <CoreFoundation/CoreFoundation.h>
#endif
#include <stdint.h>
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint on
#endif
/*
* CFNetDiagnosticStatus
*
* Discussion:
* Returned by the various status and diagnostic calls
*/
typedef int32_t CFNetDiagnosticStatus;
/*
* CFNetDiagnosticRef
*
* Discussion:
* This is the type used to describe the types of connection that
* clients may be querying about
*/
typedef struct __CFNetDiagnostic* CFNetDiagnosticRef;
/*
* CFNetDiagnosticStatusValues
*
* Discussion:
* Values for CFNetDiagnosticStatus
*/
enum CFNetDiagnosticStatusValues {
/*
* There is no status, but no error has occured
*/
kCFNetDiagnosticNoErr = 0,
/*
* An error occured that prevented the call from completing
*/
kCFNetDiagnosticErr = -66560L,
/*
* The connection appears to be working
*/
kCFNetDiagnosticConnectionUp = -66559L,
kCFNetDiagnosticConnectionIndeterminate = -66558L,
/*
* The connection does not appear to be working
*/
kCFNetDiagnosticConnectionDown = -66557L
};
typedef enum CFNetDiagnosticStatusValues CFNetDiagnosticStatusValues;
/*
* CFNetDiagnosticCreateWithStreams()
*
* Discussion:
* Creates a CFNetDiagnosticRef from a pair of CFStreams. Either
* stream may be NULL. This is the preferred interface for creating
* a CFNetDiagnosticRef.
*
* Parameters:
*
* alloc:
* The CF allocator to use.
*
* readStream:
* CFReadStreamRef referring to the failed connection. May be NULL.
*
* writeStream:
* CFWriteStreamRef referring to the failed connection. May be
* NULL.
*
* Result:
* A CFNetDiagnosticRef referring to the current networking issue.
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFNetDiagnosticRef
CFNetDiagnosticCreateWithStreams(
CFAllocatorRef alloc,
CFReadStreamRef readStream,
CFWriteStreamRef writeStream) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFNetDiagnosticCreateWithURL()
*
* Discussion:
* Creates a CFNetDiagnosticRef based on a CFURLRef passed in by the
* application.
*
* Parameters:
*
* alloc:
* The CF allocator to use.
*
* url:
* CFURLRef referring to the failed connection.
*
* Result:
* A CFNetDiagnosticRef referring to the current networking issue.
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFNetDiagnosticRef
CFNetDiagnosticCreateWithURL(
CFAllocatorRef alloc,
CFURLRef url) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFNetDiagnosticSetName()
*
* Discussion:
* If the framework requires an application name to be displayed to
* the user it will derive it from the bundle identifier of the
* currently running application, in that application's current
* localization. If you want to override that you may use
* CFNetDiagnosticAddName to specify a CFStringRef to be used.
*
* Parameters:
*
* details:
* CFNetDiagnosticRef referring to the current problem.
*
* name:
* The localized name that should appear to the user when
* referring to the application.
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern void
CFNetDiagnosticSetName(
CFNetDiagnosticRef details,
CFStringRef name) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFNetDiagnosticDiagnoseProblemInteractively()
*
* Discussion:
* Opens the Network Diagnostics window and returns immediately once
* it is open. The client passes in a CFNetDiagnosticRef built with
* one of the creator functions.
*
* Parameters:
*
* details:
* CFNetDiagnosticRef referring to the current problem.
*
* Result:
* A CFNetDiagnosticStatus. Will either be CFNetDiagnosticNoErr, or
* CFNetDiagnosticErr if there was an error attempting to run the
* diagnosis.
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFNetDiagnosticStatus
CFNetDiagnosticDiagnoseProblemInteractively(CFNetDiagnosticRef details) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFNetDiagnosticCopyNetworkStatusPassively()
*
* Discussion:
* Returns a status value that can be used to display basic
* information about the connection. If the caller wishes they may
* pass in a pointer to a CFStringRef that will be used to pass back
* a localized description of the problem. It is the caller's
* responsibility to release the CFStringRef. If the caller does not
* want a description they may pass in NULL.
* CFNetDiagnosticCopyNetworkStatusPassively() is guaranteed not to
* cause network activity.
*
* Parameters:
*
* details:
* CFNetDiagnosticRef referring to the current problem
*
* description:
* A pointer to a CFStringRef that, upon return, will point to a
* localized string containing a description of the current
* network status. May be NULL. If it is not NULL, the client must
* call CFRelease on the returned object.
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern CFNetDiagnosticStatus
CFNetDiagnosticCopyNetworkStatusPassively(
CFNetDiagnosticRef details,
CFStringRef * description) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint reset
#endif
#ifdef __cplusplus
}
#endif
#endif /* __CFNETDIAGNOSTICS__ */

View File

@ -0,0 +1,144 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFNetDiagnosticsPriv.h
Contains: CFNetDiagnostics private interfaces
Version: 1.0
Copyright: © 2004-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file contains unreleased SPI's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFNetDiagnosticsPriv.i
Revision: 1.4
Dated: 2004/10/01 16:45:11
Last change by: jwyld
Last comment: 3817528 Drop in a bunch of DATA segment changes
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFNETDIAGNOSTICSPRIV__
#define __CFNETDIAGNOSTICSPRIV__
#ifndef __COREFOUNDATION__
#include <CoreFoundation/CoreFoundation.h>
#endif
#ifndef __CFNETDIAGNOSTICS__
#include <CFNetwork/CFNetDiagnostics.h>
#endif
/*FIXME I need to be converted to headerdoc*/
/*
CFNetDiagnosticNotifyKey
This key is for use with the APIs in notify.h, such as notify_register_check().
This key's value will be increased every time a diagnosis is completed, no matter
whether it succeeded or failed.
*/
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint on
#endif
extern const char *CFNetDiagnosticNotifyKey AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
standardized protocol key values
We may have to add more.
*/
extern const CFStringRef CFNetDiagnosticProtocolHTTP AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
extern const CFStringRef CFNetDiagnosticProtocolFTP AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
extern const CFStringRef CFNetDiagnosticProtocolSMTP AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
extern const CFStringRef CFNetDiagnosticProtocolIMAP AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
extern const CFStringRef CFNetDiagnosticProtocolOSCAR AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
extern const CFStringRef CFNetDiagnosticProtocolUnknown AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
CFNetDiagnosticCreateBasic() builds an NDDescriptorRef based on parameters
passed in by the application. Any parameter may be NULL. If a parameter is NULL that
entry in the details dictionary will be omitted.
*/
extern CFNetDiagnosticRef
CFNetDiagnosticCreateBasic(
CFAllocatorRef allocator,
CFStringRef remoteHost,
CFStringRef protocol,
CFNumberRef port) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
extern void
CFNetDiagnosticSetProtocol(
CFNetDiagnosticRef details,
CFStringRef name) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
extern void
CFNetDiagnosticSetServiceID(
CFNetDiagnosticRef details,
CFStringRef name) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
CFNetDiagnosticCreateStatusActive() returns a status value that can be used to display basic information
about the connection. If the caller wishes they may pass in a pointer to a CFStringRef
that will be used to passive back a localized description of the problem. It is the
callers responsibility to release the CFStringRef. If the callers does not want a
description they may pass in NULL.
*/
extern CFNetDiagnosticStatus
CFNetDiagnosticCopyNetworkStatusActively(
CFNetDiagnosticRef details,
CFNumberRef timeout,
CFStringRef * description) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint reset
#endif
#ifdef __cplusplus
}
#endif
#endif /* __CFNETDIAGNOSTICSPRIV__ */

1764
src/Headers/CFNetServices.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,159 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFNetServicesPriv.h
Contains: CoreFoundation Network CFNetServices header (private)
Copyright: © 2004-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file contains unreleased SPI's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFNetServicesPriv.i
Revision: 1.2
Dated: 2004/06/01 17:53:05
Last change by: rew
Last comment: Updating all copyrights to include 2004
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFNETSERVICESPRIV__
#define __CFNETSERVICESPRIV__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __CFNETWORK__
#include <CFNetwork/CFNetwork.h>
#endif
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint on
#endif
/*
* CFNetServiceGetInfo()
*
* Discussion:
* Tries to retrieve the information of the given type from the
* given service. Returns a CFTypeRef containing the information.
* The actual type of object returned is dictated by the type of
* information being requested. NULL is returned otherwise.
*
* Mac OS X threading:
* Not thread safe
* The function gets the data in a thread-safe manner, but the
* resulting data is not safe. Since it is returned as a matter of
* a get opposed to a copy, the data is not safe if the service is
* being altered from another thread.
*
* Parameters:
*
* theService:
* The CFNetServiceRef which contains the relevant information.
* Must be non-NULL. If this reference is not a valid
* CFNetServiceRef, the behavior is undefined.
*
* property:
* The descriptor of the information to retrieve.
*
* Result:
* Returns a CFTypeRef containing the information. The actual type
* of object returned is dictated by the type of information being
* requested. NULL is returned otherwise.
*
*/
extern CFTypeRef
CFNetServiceGetInfo(
CFNetServiceRef theService,
UInt32 property) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* CFNetServiceSetInfo()
*
* Discussion:
* Sets the given value for the specified property on a service. It
* will publish the data to the wire if there is an active
* registration.
*
* Mac OS X threading:
* Not thread safe
* The function sets the data in a thread-safe manner.
*
* Parameters:
*
* theService:
* The CFNetServiceRef which will receive the information. Must be
* non-NULL. If this reference is not a valid CFNetServiceRef, the
* behavior is undefined.
*
* property:
* The descriptor of the information to set.
*
* value:
* The data to be set. For records, this must be a CFDataRef.
*
* Result:
* Returns TRUE if the value was set.
*
*/
extern Boolean
CFNetServiceSetInfo(
CFNetServiceRef theService,
UInt32 property,
CFTypeRef value) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint reset
#endif
#ifdef __cplusplus
}
#endif
#endif /* __CFNETSERVICESPRIV__ */

99
src/Headers/CFNetwork.h Normal file
View File

@ -0,0 +1,99 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFNetwork.h
Contains: CoreFoundation Network header
Copyright: © 2001-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file may contain unreleased API's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFNetwork.i
Revision: 1.5
Dated: 2004/06/01 17:53:05
Last change by: rew
Last comment: Updating all copyrights to include 2004
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFNETWORK__
#define __CFNETWORK__
#ifndef __COREFOUNDATION__
#include <CoreFoundation/CoreFoundation.h>
#endif
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __CFNETWORKERRORS__
#include <CFNetwork/CFNetworkErrors.h>
#endif
#ifndef __CFSOCKETSTREAM__
#include <CFNetwork/CFSocketStream.h>
#endif
#ifndef __CFFTPSTREAM__
#include <CFNetwork/CFFTPStream.h>
#endif
#ifndef __CFHOST__
#include <CFNetwork/CFHost.h>
#endif
#ifndef __CFHTTPMESSAGE__
#include <CFNetwork/CFHTTPMessage.h>
#endif
#ifndef __CFHTTPSTREAM__
#include <CFNetwork/CFHTTPStream.h>
#endif
#ifndef __CFHTTPAUTHENTICATION__
#include <CFNetwork/CFHTTPAuthentication.h>
#endif
#ifndef __CFNETDIAGNOSTICS__
#include <CFNetwork/CFNetDiagnostics.h>
#endif
#ifndef __CFNETSERVICES__
#include <CFNetwork/CFNetServices.h>
#endif
#ifndef __CFPROXYSUPPORT__
#include <CFNetwork/CFProxySupport.h>
#endif
#endif /* __CFNETWORK__ */

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFNetworkDefs.h
Contains: CoreFoundation Network header
Copyright: © 2001-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file may contain unreleased API's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFNetworkDefs.i
Revision: 1.5
Dated: 2004/06/01 17:53:05
Last change by: rew
Last comment: Updating all copyrights to include 2004
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFNETWORK_DEFS_H_
#define __CFNETWORK_DEFS_H_
#include <ConditionalMacros.h>
#define CFNetwork_EXPORT extern
#define CFN_EXPORT extern
#if __cplusplus
#define CFN_CPP_BEGIN extern "C" {
#define CFN_CPP_END };
#else
#define CFN_CPP_BEGIN
#define CFN_CPP_END
#endif
#endif

View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFNetworkPriv.h
Contains: CoreFoundation Network private framework header
Copyright: © 2001-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file contains unreleased SPI's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFNetworkPriv.i
Revision: 1.13
Dated: 2004/06/01 17:53:05
Last change by: rew
Last comment: Updating all copyrights to include 2004
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFNETWORKPRIV__
#define __CFNETWORKPRIV__
#ifndef __CFNETWORK__
#include <CFNetwork/CFNetwork.h>
#endif
#ifndef __CFHTTPMESSAGEPRIV__
#include "CFHTTPMessagePriv.h"
#endif
#ifndef __CFSOCKETSTREAMPRIV__
#include "CFSocketStreamPriv.h"
#endif
#ifndef __CFSERVERPRIV__
#include "CFServerPriv.h"
#endif
#ifndef __CFHTTPSERVERPRIV__
#include "CFHTTPServerPriv.h"
#endif
#ifndef __CFHTTPSTREAMPRIV__
#include "CFHTTPStreamPriv.h"
#endif
#ifndef __CFFTPSTREAMPRIV__
#include "CFFTPStreamPriv.h"
#endif
#ifndef __CFHTTPCONNECTIONPRIV__
#include "CFHTTPConnectionPriv.h"
#endif
#ifndef __CFHOSTPRIV__
#include "CFHostPriv.h"
#endif
#ifndef __CFNETDIAGNOSTICSPRIV__
#include "CFNetDiagnosticsPriv.h"
#endif
#ifndef __CFNETSERVICESPRIV__
#include "CFNetServicesPriv.h"
#endif
#endif /* __CFNETWORKPRIV__ */

289
src/Headers/CFServerPriv.h Normal file
View File

@ -0,0 +1,289 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFServerPriv.h
Contains: CoreFoundation Network server SPI
Copyright: © 2003-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file contains unreleased SPI's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFServerPriv.i
Revision: 1.3
Dated: 2004/06/01 17:53:06
Last change by: rew
Last comment: Updating all copyrights to include 2004
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFSERVERPRIV__
#define __CFSERVERPRIV__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __CFNETWORK__
#include <CFNetwork/CFNetwork.h>
#endif
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* _CFServerRef
*
* Discussion:
* This is the type of a reference to a TCP server. Although
* individual functions are thread-safe, _CFServerRef itself is not
* thread-safe.
*/
typedef struct __CFServer* _CFServerRef;
/*
* _CFServerContext
*
* Discussion:
* Structure containing the user-defined data and callbacks for
* _CFServerRef objects.
*/
struct _CFServerContext {
/*
* The version number of the structure type being passed in as a
* parameter to the CFServer creation function. Valid version number
* is currently 0.
*/
CFIndex version;
/*
* An arbitrary pointer to client-defined data, which can be
* associated with the host and is passed to the callbacks.
*/
void * info;
/*
* The callback used to add a retain for the host on the info pointer
* for the life of the host, and may be used for temporary references
* the host needs to take. This callback returns the actual info
* pointer to store in the host, almost always just the pointer
* passed as the parameter.
*/
CFAllocatorRetainCallBack retain;
/*
* The callback used to remove a retain previously added for the host
* on the info pointer.
*/
CFAllocatorReleaseCallBack release;
/*
* The callback used to create a descriptive string representation of
* the info pointer (or the data pointed to by the info pointer) for
* debugging purposes. This is used by the CFCopyDescription()
* function.
*/
CFAllocatorCopyDescriptionCallBack copyDescription;
};
typedef struct _CFServerContext _CFServerContext;
/*
* _CFServerCallBack
*
* Discussion:
* Callback which is invoked as a new connection is accepted.
*
* Parameters:
*
* server:
* The instance of the server which is receiving the connection.
*
* sock:
* The native socket which has been accepted or -1 if there was an
* error.
*
* error:
* A reference to a CFStreamError which contains any error which
* may have occurred in the server.
*
* info:
* The reference from the server context which was given when the
* server was created.
*/
typedef CALLBACK_API_C( void , _CFServerCallBack )(_CFServerRef server, CFSocketNativeHandle sock, const CFStreamError *error, void *info);
/*
* _CFServerGetTypeID()
*
* Discussion:
* Returns the type identifier of all _CFServer instances.
*
* Mac OS X threading:
* Not thread safe
*
*/
extern CFTypeID
_CFServerGetTypeID(void) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFServerCreate()
*
* Discussion:
* Create a new instance of a server object. This will allocate
* only the underlying structures and set aside the resources. Use
* _CFServerStart to actually start the server listening.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* alloc:
* Allocator to use for allocating. NULL indicates the default
* allocator.
*
* callback:
* Function to call as incoming connections are accepted
*
* context:
* Reference to a context block which will be copied into the
* server context for the callbacks.
*
*/
extern _CFServerRef
_CFServerCreate(
CFAllocatorRef alloc,
_CFServerCallBack callback,
_CFServerContext * context) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFServerGetPort()
*
* Discussion:
* Returns the port on which the server is listening. If not
* currently listening, it will return zero.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* server:
* The server being queried. Must be non-NULL. If this reference
* is not a valid _CFServerRef, the behavior is undefined.
*
*/
extern UInt32
_CFServerGetPort(_CFServerRef server) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFServerStart()
*
* Discussion:
* Starts the socket listening on the given port. Registers the
* service by name and type on the local network. The socket and
* service will be registered on the current run loop in the common
* modes.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* server:
* Reference to the server. Must be non-NULL.
*
* name:
* Unique name to register on the network. NULL indicates to use
* the computer's name. The name must be unique in the local
* domain and for the given service type.
*
* serviceType:
* Service type being registered. Service types can be retrieved
* from IANA (www.iana.org). Examples include _http._tcp. and
* _echo._tcp.
*
* port:
* TCP port on which to listen. If a well-known port is not
* required, set to zero and one will be assigned.
*
*/
extern Boolean
_CFServerStart(
_CFServerRef server,
CFStringRef name,
CFStringRef serviceType,
UInt32 port) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFServerInvalidate()
*
* Discussion:
* Removes the client and its associated data from the server
* reference. This ensures that the client will no longer get
* callbacks associated with this instance of the object.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* server:
* Reference to the server. Must be non-NULL.
*
*/
extern void
_CFServerInvalidate(_CFServerRef server) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
#ifdef __cplusplus
}
#endif
#endif /* __CFSERVERPRIV__ */

View File

@ -0,0 +1,799 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFSocketStream.h
Contains: CoreFoundation Network socket streams header
Copyright: © 2001-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file may contain unreleased API's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFSocketStream.i
Revision: 1.14
Dated: 2004/08/31 20:33:12
Last change by: jwyld
Last comment: 3781282 Make sure SimpleHost bypass key matches SC and look at the value
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFSOCKETSTREAM__
#define __CFSOCKETSTREAM__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __CFSTREAM__
#include <CoreFoundation/CFStream.h>
#endif
#ifndef __CFHOST__
#include <CFNetwork/CFHost.h>
#endif
#ifndef __CFNETSERVICES__
#include <CFNetwork/CFNetServices.h>
#endif
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint on
#endif
/*
* kCFStreamPropertySSLPeerCertificates
*
* Discussion:
* Stream property key for copy operations. CFArrayRef containing
* SecCertificateRefs. See SSLGetPeerCertificates in
* Security/SecureTransport.h for more information.
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertySSLPeerCertificates AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamPropertySSLSettings
*
* Discussion:
* Stream property key for set operations. CFDictionaryRef filled
* with different security settings. By default, there are no
* security settings.
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertySSLSettings AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamSSLLevel
*
* Discussion:
* Security property key for kCFStreamPropertySSLSettings.
* CFStringRef being one of the security levels. The value is
* kCFStreamSocketSecurityLevelNegotiatedSSL by default (not set).
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamSSLLevel AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamSSLAllowsExpiredCertificates
*
* Discussion:
* Security property key for kCFStreamPropertySSLSettings.
* CFBooleanRef indicating whether expired certificates should be
* allowed or not. The value is kCFBooleanFalse by default (not
* set).
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamSSLAllowsExpiredCertificates AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamSSLAllowsExpiredRoots
*
* Discussion:
* Security property key for kCFStreamPropertySSLSettings.
* CFBooleanRef indicating whether expired root certificates should
* be allowed or not. The value is kCFBooleanFalse by default (not
* set).
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamSSLAllowsExpiredRoots AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamSSLAllowsAnyRoot
*
* Discussion:
* Security property key for kCFStreamPropertySSLSettings.
* CFBooleanRef indicating whether any root certificates should be
* allowed or not. The value is kCFBooleanFalse by default (not
* set).
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamSSLAllowsAnyRoot AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamSSLValidatesCertificateChain
*
* Discussion:
* Security property key for kCFStreamPropertySSLSettings.
* CFBooleanRef indicating whether the certificate chain should be
* validated or not. The value is kCFBooleanTrue by default (not
* set).
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamSSLValidatesCertificateChain AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamSSLPeerName
*
* Discussion:
* Security property key for kCFStreamPropertySSLSettings.
* CFStringRef overriding the name used for certificate
* verification. Set to kCFNull to prevent name verification.
* Default is the host name with which the streams were created. If
* no host name was used, no peer name will be used.
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamSSLPeerName AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamSSLCertificates
*
* Discussion:
* Security property key for kCFStreamPropertySSLSettings.
* CFArrayRef of SecCertificateRefs, except for index [0], which is
* a SecIdentityRef. See SSLSetCertificate in
* Security/SecureTransport.h for more information.
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamSSLCertificates AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamSSLIsServer
*
* Discussion:
* Security property key for kCFStreamPropertySSLSettings.
* CFBooleanRef indicating whether the connection is to act as a
* server in the SSL process or not. The value is kCFBooleanFalse
* by default (not set). If set to kCFBooleanTrue, there must be a
* valid value for the kCFStreamSSLCertificates key too.
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamSSLIsServer AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamErrorDomainSOCKS
*
* Discussion:
* SOCKS proxy error domain. Errors formulated using inlines below.
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const int kCFStreamErrorDomainSOCKS;
extern const CFStringRef kCFStreamNetworkServiceType ;
extern const CFStringRef kCFStreamNetworkServiceTypeVoIP;
extern const CFStringRef kCFStreamNetworkServiceTypeVideo;
extern const CFStringRef kCFStreamNetworkServiceTypeBackground;
extern const CFStringRef kCFStreamNetworkServiceTypeVoice;
CF_INLINE
SInt32 CFSocketStreamSOCKSGetErrorSubdomain(CFStreamError* error) {
return ((error->error >> 16) & 0x0000FFFF);
}
CF_INLINE
SInt32 CFSocketStreamSOCKSGetError(CFStreamError* error) {
return (error->error & 0x0000FFFF);
}
enum {
kCFStreamErrorSOCKSSubDomainNone = 0, /* Error code is a general SOCKS error*/
kCFStreamErrorSOCKSSubDomainVersionCode = 1, /* Error code is the version of SOCKS which the server wishes to use*/
kCFStreamErrorSOCKS4SubDomainResponse = 2, /* Error code is the status code returned by the server*/
kCFStreamErrorSOCKS5SubDomainUserPass = 3, /* Error code is the status code that the server returned*/
kCFStreamErrorSOCKS5SubDomainMethod = 4, /* Error code is the server's desired negotiation method*/
kCFStreamErrorSOCKS5SubDomainResponse = 5 /* Error code is the response code that the server returned in reply to the connection request*/
};
/* kCFStreamErrorSOCKSSubDomainNone*/
enum {
kCFStreamErrorSOCKS5BadResponseAddr = 1,
kCFStreamErrorSOCKS5BadState = 2,
kCFStreamErrorSOCKSUnknownClientVersion = 3
};
/* kCFStreamErrorSOCKS4SubDomainResponse*/
enum {
kCFStreamErrorSOCKS4RequestFailed = 91, /* request rejected or failed */
kCFStreamErrorSOCKS4IdentdFailed = 92, /* request rejected because SOCKS server cannot connect to identd on the client */
kCFStreamErrorSOCKS4IdConflict = 93 /* request rejected because the client program and identd report different user-ids */
};
/* kCFStreamErrorSOCKS5SubDomainMethod*/
enum {
kSOCKS5NoAcceptableMethod = 0xFF /* other values indicate the server's desired method */
};
/*
* kCFStreamPropertySOCKSProxy
*
* Discussion:
* Stream property key, for both set and copy operations. To set a
* stream to use a SOCKS proxy, call CFReadStreamSetProperty or
* CFWriteStreamSetProperty with the property name set to
* kCFStreamPropertySOCKSProxy and the value being a dictionary with
* at least the following two keys: kCFStreamPropertySOCKSProxyHost
* and kCFStreamPropertySOCKSProxyPort. The dictionary returned by
* SystemConfiguration for SOCKS proxies will work without
* alteration.
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertySOCKSProxy;
/*
* kCFStreamPropertySOCKSProxyHost
*
* Discussion:
* CFDictionary key for SOCKS proxy information. The key
* kCFStreamPropertySOCKSProxyHost should contain a CFStringRef
* value representing the SOCKS proxy host. Defined to match
* kSCPropNetProxiesSOCKSProxy
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertySOCKSProxyHost;
/*
* kCFStreamPropertySOCKSProxyPort
*
* Discussion:
* CFDictionary key for SOCKS proxy information. The key
* kCFStreamPropertySOCKSProxyPort should contain a CFNumberRef
* which itself is of type kCFNumberSInt32Type. This value should
* represent the port on which the proxy is listening. Defined to
* match kSCPropNetProxiesSOCKSPort
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertySOCKSProxyPort;
/*
* kCFStreamPropertySOCKSVersion
*
* Discussion:
* CFDictionary key for SOCKS proxy information. By default, SOCKS5
* will be used unless there is a kCFStreamPropertySOCKSVersion key
* in the dictionary. Its value must be
* kCFStreamSocketSOCKSVersion4 or kCFStreamSocketSOCKSVersion5 to
* set SOCKS4 or SOCKS5, respectively.
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertySOCKSVersion;
/*
* kCFStreamSocketSOCKSVersion4
*
* Discussion:
* CFDictionary value for SOCKS proxy information. Indcates that
* SOCKS will or is using version 4 of the SOCKS protocol.
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamSocketSOCKSVersion4;
/*
* kCFStreamSocketSOCKSVersion5
*
* Discussion:
* CFDictionary value for SOCKS proxy information. Indcates that
* SOCKS will or is using version 5 of the SOCKS protocol.
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamSocketSOCKSVersion5;
/*
* kCFStreamPropertySOCKSUser
*
* Discussion:
* CFDictionary key for SOCKS proxy information. To set a user name
* and/or password, if required, the dictionary must contain the
* key(s) kCFStreamPropertySOCKSUser and/or
* kCFStreamPropertySOCKSPassword with the value being the user's
* name as a CFStringRef and/or the user's password as a
* CFStringRef, respectively.
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertySOCKSUser;
/*
* kCFStreamPropertySOCKSPassword
*
* Discussion:
* CFDictionary key for SOCKS proxy information. To set a user name
* and/or password, if required, the dictionary must contain the
* key(s) kCFStreamPropertySOCKSUser and/or
* kCFStreamPropertySOCKSPassword with the value being the user's
* name as a CFStringRef and/or the user's password as a
* CFStringRef, respectively.
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertySOCKSPassword;
/*
* kCFStreamErrorDomainSSL
*
* Discussion:
* Errors located in Security/SecureTransport.h
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const int kCFStreamErrorDomainSSL;
/*
* kCFStreamPropertySocketSecurityLevel
*
* Discussion:
* Stream property key, for both set and copy operations. To set a
* stream to be secure, call CFReadStreamSetProperty or
* CFWriteStreamSetPropertywith the property name set to
* kCFStreamPropertySocketSecurityLevel and the value being one of
* the following values. Streams may set a security level after
* open in order to allow on-the-fly securing of a stream.
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertySocketSecurityLevel;
/*
* kCFStreamSocketSecurityLevelNone
*
* Discussion:
* Stream property value, for both set and copy operations.
* Indicates to use no security (default setting).
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamSocketSecurityLevelNone;
/*
* kCFStreamSocketSecurityLevelSSLv2
*
* Discussion:
* Stream property value, for both set and copy operations.
* Indicates to use SSLv2 security.
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamSocketSecurityLevelSSLv2;
/*
* kCFStreamSocketSecurityLevelSSLv3
*
* Discussion:
* Stream property value, for both set and copy operations.
* Indicates to use SSLv3 security.
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamSocketSecurityLevelSSLv3;
/*
* kCFStreamSocketSecurityLevelTLSv1
*
* Discussion:
* Stream property value, for both set and copy operations.
* Indicates to use TLSv1 security.
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamSocketSecurityLevelTLSv1;
/*
* kCFStreamSocketSecurityLevelNegotiatedSSL
*
* Discussion:
* Stream property value, for both set and copy operations.
* Indicates to use TLS or SSL with fallback to lower versions. This
* is what HTTPS does, for instance.
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamSocketSecurityLevelNegotiatedSSL;
/*
* kCFStreamPropertyShouldCloseNativeSocket
*
* Discussion:
* Set the value to kCFBooleanTrue if the stream should close and
* release the underlying native socket when the stream is released.
* Set the value to kCFBooleanFalse to keep the native socket from
* closing and releasing when the stream is released. If the stream
* was created with a native socket, the default property setting on
* the stream is kCFBooleanFalse. The
* kCFStreamPropertyShouldCloseNativeSocket can be set through
* CFReadStreamSetProperty or CFWriteStreamSetProperty. The
* property can be copied through CFReadStreamCopyProperty or
* CFWriteStreamCopyProperty.
*
* Availability:
* Mac OS X: in version 10.2 and later
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyShouldCloseNativeSocket;
/*
* kCFStreamPropertySocketRemoteHost
*
* Discussion:
* Stream property key for copy operations. Returns a CFHostRef if
* known, otherwise NULL.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertySocketRemoteHost AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFStreamPropertySocketRemoteNetService
*
* Discussion:
* Stream property key for copy operations. Returns a
* CFNetServiceRef if known, otherwise NULL.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertySocketRemoteNetService AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFStreamCreatePairWithSocketToCFHost()
*
* Discussion:
* Given a CFHostRef, this function will create a pair of streams
* suitable for connecting to the host. If there is a failure
* during creation, the stream references will be set to NULL.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* alloc:
* The CFAllocator which should be used to allocate memory for the
* streams. If this reference is not a valid CFAllocator, the
* behavior is undefined.
*
* host:
* A reference to a CFHost to which the streams are desired. If
* unresolved, the host will be resolved prior to connecting.
*
* port:
* The port to which the connection should be established.
*
* readStream:
* A pointer to a CFReadStreamRef which will be set to the new
* read stream instance. Can be set to NULL if not desired.
*
* writeStream:
* A pointer to a CFWriteStreamRef which will be set to the new
* write stream instance. Can be set to NULL if not desired.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern void
CFStreamCreatePairWithSocketToCFHost(
CFAllocatorRef alloc,
CFHostRef host,
UInt32 port,
CFReadStreamRef * readStream, /* can be NULL */
CFWriteStreamRef * writeStream) /* can be NULL */ AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFStreamCreatePairWithSocketToNetService()
*
* Discussion:
* Given a CFNetService, this function will create a pair of streams
* suitable for connecting to the service. If there is a failure
* during creation, the stream references will be set to NULL.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* alloc:
* The CFAllocator which should be used to allocate memory for the
* streams. If this reference is not a valid CFAllocator, the
* behavior is undefined.
*
* service:
* A reference to a CFNetService to which the streams are desired.
* If unresolved, the service will be resolved prior to
* connecting.
*
* readStream:
* A pointer to a CFReadStreamRef which will be set to the new
* read stream instance. Can be set to NULL if not desired.
*
* writeStream:
* A pointer to a CFWriteStreamRef which will be set to the new
* write stream instance. Can be set to NULL if not desired.
*
* Availability:
* Mac OS X: in version 10.3 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern void
CFStreamCreatePairWithSocketToNetService(
CFAllocatorRef alloc,
CFNetServiceRef service,
CFReadStreamRef * readStream, /* can be NULL */
CFWriteStreamRef * writeStream) /* can be NULL */ AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* CFStreamSocketSecurityProtocol
*
* Discussion:
* These enum values and CFSocketStreamPairSetSecurityProtocol have
* been deprecated in favor of CFReadStreamSetProperty and
* CFWriteStreamSetProperty with the previously mentioned property
* and values.
*/
enum CFStreamSocketSecurityProtocol {
/*
* DEPRECATED, use kCFStreamSocketSecurityLevelNone
*/
kCFStreamSocketSecurityNone = 0,
/*
* DEPRECATED, use kCFStreamSocketSecurityLevelSSLv2
*/
kCFStreamSocketSecuritySSLv2 = 1,
/*
* DEPRECATED, use kCFStreamSocketSecurityLevelSSLv3
*/
kCFStreamSocketSecuritySSLv3 = 2,
/*
* DEPRECATED, use kCFStreamSocketSecurityLevelNegotiatedSSL
*/
kCFStreamSocketSecuritySSLv23 = 3,
/*
* DEPRECATED, use kCFStreamSocketSecurityLevelTLSv1
*/
kCFStreamSocketSecurityTLSv1 = 4
};
typedef enum CFStreamSocketSecurityProtocol CFStreamSocketSecurityProtocol;
/*
* CFSocketStreamPairSetSecurityProtocol() *** DEPRECATED ***
*
* Discussion:
* CFSocketStreamPairSetSecurityProtocol has been deprecated in
* favor of CFReadStreamSetProperty and CFWriteStreamSetProperty
* with the previously mentioned property and values. Sets the
* security level on a pair of streams.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* socketReadStream:
* Read stream reference which is to have its security level
* changed.
*
* socketWriteStream:
* Write stream reference which is to have its security level
* changed.
*
* securityProtocol:
* CFStreamSocketSecurityProtocol enum indicating the security
* level to be set.
*
* Result:
* Returns TRUE if the settings were placed on the stream, FALSE
* otherwise.
*
* Availability:
* Mac OS X: in version 10.1 and later in CoreServices.framework but deprecated in 10.2
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern Boolean
CFSocketStreamPairSetSecurityProtocol(
CFReadStreamRef socketReadStream,
CFWriteStreamRef socketWriteStream,
CFStreamSocketSecurityProtocol securityProtocol) AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_2;
/*
* kCFStreamPropertyProxyLocalBypass
*
* Discussion:
* CFDictionary key for proxy information. It matches
* kSCPropNetProxiesExcludeSimpleHostnames defined in
* SCSchemaDefinitions.h. CFNumber (0 or 1) indicating to bypass
* the proxies for simple hostnames (names without dots).
*
* Availability:
* Mac OS X: in version 10.4 and later in CoreServices.framework
* CarbonLib: not available
* Non-Carbon CFM: not available
*/
extern const CFStringRef kCFStreamPropertyProxyLocalBypass AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
#if PRAGMA_ENUM_ALWAYSINT
#pragma enumsalwaysint reset
#endif
#ifdef __cplusplus
}
#endif
#endif /* __CFSOCKETSTREAM__ */

View File

@ -0,0 +1,299 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
File: CFNetwork/CFSocketStreamPriv.h
Contains: CoreFoundation Socket Stream SPI
Copyright: © 2002-2005 by Apple Computer, Inc., all rights reserved
Warning: *** APPLE INTERNAL USE ONLY ***
This file contains unreleased SPI's
BuildInfo: Built by: anonymous
On: Wed Apr 27 10:45:36 2005
With Interfacer: 3.0d46 (Mac OS X for PowerPC)
From: CFSocketStreamPriv.i
Revision: 1.19
Dated: 2005/03/17 20:54:24
Last change by: jwyld
Last comment: 4042459 ntlm authenticating proxies were not getting connect tunneling authorization for https
Bugs: Report bugs to Radar component "System Interfaces", "Latest"
List the version information (from above) in the Problem Description.
*/
#ifndef __CFSOCKETSTREAMPRIV__
#define __CFSOCKETSTREAMPRIV__
#ifndef __CFNETWORKDEFS__
#include <CFNetwork/CFNetworkDefs.h>
#endif
#ifndef __CFSTREAM__
#include <CoreFoundation/CFStream.h>
#endif
#include <AvailabilityMacros.h>
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* kCFStreamSocketSecurityLevelTLSv1SSLv3
*
* Discussion:
* Stream property value, for both set and copy operations.
* Indicates to attempt TLSv1 with fallback to SSLv3. SSLv2 is not
* attempted.
*
*/
extern const CFStringRef kCFStreamSocketSecurityLevelTLSv1SSLv3 AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamPropertyUseAddressCache
*
* Discussion:
* Stream property key, for both set and copy operations.
* CFBooleanRef to allow hostname lookup to use CFSocketStream's
* built-in address cache. The value is kCFBooleanTrue by default.
*
*/
extern const CFStringRef kCFStreamPropertyUseAddressCache AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* kCFStreamPropertyCONNECTProxy
*
* Discussion:
* Stream property key, for set operations. To set a stream to use
* a CONNECT proxy, call CFReadStreamSetProperty or
* CFWriteStreamSetProperty with the property name set to
* kCFStreamPropertyCONNECTProxy and the value being a dictionary
* with at least the following two keys:
* kCFStreamPropertyCONNECTProxyHost. The dictionary returned by
* SystemConfiguration for proxies will work without alteration.
*
*/
extern const CFStringRef kCFStreamPropertyCONNECTProxy AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamPropertyCONNECTProxyHost
*
* Discussion:
* CFDictionary key for CONNECT proxy information. The key
* kCFStreamPropertyCONNECTProxyHost should contain a CFStringRef
* value representing the CONNECT proxy host. Defined to match
* kSCPropNetProxiesHTTPSProxy
*
*/
extern const CFStringRef kCFStreamPropertyCONNECTProxyHost AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamPropertyCONNECTProxyPort
*
* Discussion:
* CFDictionary key for CONNECT proxy information. The key
* kCFStreamPropertyCONNECTProxyPort should contain a CFNumberRef
* which itself is of type kCFNumberSInt32Type. This value should
* represent the port on which the proxy is listening. Defined to
* match kSCPropNetProxiesHTTPSPort
*
*/
extern const CFStringRef kCFStreamPropertyCONNECTProxyPort AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamPropertyCONNECTVersion
*
* Discussion:
* CFDictionary key for CONNECT proxy information. By default,
* kCFHTTPVersion1_0 will be used unless there is a
* kCFStreamPropertyCONNECTVersion key in the dictionary. Its value
* should be a CFStringRef representing the HTTP version to use for
* the CONNECT request.
*
*/
extern const CFStringRef kCFStreamPropertyCONNECTVersion AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamPropertyCONNECTAdditionalHeaders
*
* Discussion:
* CFDictionary key for CONNECT proxy information. Its value should
* be a CFDictionary of header fields and their respective values.
* This dictionary will be iterated and added to the CONNECT request.
*
*/
extern const CFStringRef kCFStreamPropertyCONNECTAdditionalHeaders AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamPropertyCONNECTResponse
*
* Discussion:
* Stream property key, for copy operations. CFHTTPMessage holding
* the proxy server's response.
*
*/
extern const CFStringRef kCFStreamPropertyCONNECTResponse AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* kCFStreamPropertyPreviousCONNECTResponse
*
* Discussion:
* Stream property key, for copy operations. CFHTTPMessage holding
* the proxy server's last response until the current one is fully
* valid again. This is used for a CONNECT resume after a 407, for
* example.
*
*/
extern const CFStringRef kCFStreamPropertyPreviousCONNECTResponse AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
#if defined(__MACH__) || defined(APPORTABLE)
/*
* kCFStreamPropertySocketSSLContext
*
* Discussion:
* Stream property key, for both set and copy operations. CFDataRef
* containing a reference to the SecureTransport SecureContext
* structure.
*
*/
extern const CFStringRef kCFStreamPropertySocketSSLContext;
/*
* _kCFStreamPropertySocketSecurityAuthenticatesServerCertificate
*
* Discussion:
* Stream property key, for both set and copy operations.
* CFBooleanRef to set whether SSL authenticates the server's
* certificate or not. The value is kCFBooleanTrue by default.
*
*/
extern const CFStringRef _kCFStreamPropertySocketSecurityAuthenticatesServerCertificate;
/*
* _kCFStreamPropertySSLClientCertificates
*
* Discussion:
* Stream property key for copy operations. CFArrayRef containing
* SecCertificateRefs (except for element 0 of the array, which is a
* SecIdentityRef.) See SSLGetCertificate in
* Security/SecureTransportPriv.h for more information.
*
*/
extern const CFStringRef _kCFStreamPropertySSLClientCertificates AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/*
* _kCFStreamPropertySSLClientCertificateState
*
* Discussion:
* Stream property key for copy operations. CFNumberRef wrapping a
* SSLClientCertificateState value. See SSLGetClientCertificateState
* in Security/SecureTransport.h for more information.
*
*/
extern const CFStringRef _kCFStreamPropertySSLClientCertificateState AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
#endif /* defined(__MACH__) */
/*
* kCFStreamPropertyProxyExceptionsList
*
* Discussion:
* CFDictionary key for proxy information, for both set and copy
* operations. The value is a CFArray of hostname expressions for
* which we should bypass the proxy server. This key is used within
* the dictionary that serves as the value of the properties
* kCFStreamPropertySOCKSProxy, kCFStreamPropertyHTTPProxy or
* kCFStreamPropertyFTPProxy.
*
*/
extern const CFStringRef kCFStreamPropertyProxyExceptionsList;
/* matches kSCPropNetProxiesExceptionsList */
/*
* _kCFStreamPropertySocketPeerName
*
* Discussion:
* Stream property key, for both set and copy operations. The value
* is a CFStringRef indicating the peer's host name. This is to be
* set when doing SSL through a proxy, since the SocketStream's
* hostname will be the proxy instead of the peer.
*
*/
extern const CFStringRef _kCFStreamPropertySocketPeerName;
/*
* CFStreamCreatePairWithNetServicePieces()
*
* Discussion:
* Creates a pair of streams to a net service using the individual
* pieces of the net service instead of the net service itself.
*
* Mac OS X threading:
* Thread safe
*
* Parameters:
*
* alloc:
* The allocator to use for creation.
*
* domain:
* The network domain in which the service is registered.
*
* serviceType:
* The type of service being resolved on the network.
*
* name:
* The name of the machine or application advertising the service.
*
* readStream:
* Reference to a CFReadStreamRef which will be filled with the
* created read stream. Pass in NULL if the read stream is not
* required.
*
* writeStream:
* Reference to a CFWriteStreamRef which will be filled with the
* created write stream. Pass in NULL if the write stream is not
* required.
*
*/
extern void
CFStreamCreatePairWithNetServicePieces(
CFAllocatorRef alloc,
CFStringRef domain,
CFStringRef serviceType,
CFStringRef name,
CFReadStreamRef * readStream, /* can be NULL */
CFWriteStreamRef * writeStream) /* can be NULL */ AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
#ifdef __cplusplus
}
#endif
#endif /* __CFSOCKETSTREAMPRIV__ */

2479
src/Host/CFHost.c Normal file

File diff suppressed because it is too large Load Diff

213
src/JavaScriptGlue.c Executable file
View File

@ -0,0 +1,213 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* JavaScriptGlue.c
* CFNetwork
*
* Created by Jeremy Wyld on Thu Oct 16 2003.
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
*
*/
#include <stdio.h>
#include <JavaScriptGlue/JavaScriptGlue.h>
#include "CFNetworkInternal.h"
#include <mach-o/dyld.h>
void JSLockInterpreter(void);
void JSUnlockInterpreter(void);
#ifndef DYNAMICALLY_LOAD_JAVASCRIPT
#define DYNAMICALLY_LOAD_JAVASCRIPT 1
#endif
#if DYNAMICALLY_LOAD_JAVASCRIPT
struct _JavaScriptCallBacks {
void (*JSRelease_proc)(JSTypeRef);
void (*JSLockInterpreter_proc)(void);
void (*JSUnlockInterpreter_proc)(void);
JSObjectRef (*JSObjectCallFunction_proc)(JSObjectRef, JSObjectRef, CFArrayRef);
CFMutableArrayRef (*JSCreateJSArrayFromCFArray_proc)(CFArrayRef);
JSRunRef (*JSRunCreate_proc)(CFStringRef, JSFlags);
JSObjectRef (*JSRunCopyGlobalObject_proc)(JSRunRef);
JSObjectRef (*JSRunEvaluate_proc)(JSRunRef);
bool (*JSRunCheckSyntax_proc)(JSRunRef);
JSObjectRef (*JSObjectCreate_proc)(void*, JSObjectCallBacksPtr);
void (*JSObjectSetProperty_proc)(JSObjectRef, CFStringRef, JSObjectRef);
JSObjectRef (*JSObjectCreateWithCFType_proc)(CFTypeRef);
CFTypeRef (*JSObjectCopyCFValue_proc)(JSObjectRef);
JSObjectRef (*JSObjectCopyProperty_proc)(JSObjectRef, CFStringRef);
};
static const char kJavaScriptLibraryPath[] = "/System/Library/PrivateFrameworks/JavaScriptGlue.framework/Versions/A/JavaScriptGlue";
static const void* JavaScriptLibrary = NULL;
static CFSpinLock_t JavaScriptLibraryLock = 0;
static struct _JavaScriptCallBacks* JavaScriptCallBacks = NULL;
static const void* returns_ref(void) { return NULL; }
static bool returns_bool(void) { return 0; }
static void returns(void) { return; }
#define GET_DYNAMIC_SYMBOL(sym, rettype, arglist, alt) \
if (!JavaScriptLibrary) { \
__CFSpinLock(&JavaScriptLibraryLock); \
JavaScriptLibrary = __CFNetworkLoadFramework(kJavaScriptLibraryPath); \
if (!JavaScriptCallBacks) { \
JavaScriptCallBacks = (struct _JavaScriptCallBacks*)calloc(1, sizeof(JavaScriptCallBacks[0])); \
} \
__CFSpinUnlock(&JavaScriptLibraryLock); \
} \
if (!JavaScriptCallBacks->sym##_proc) { \
JavaScriptCallBacks->sym##_proc = (rettype(*)arglist)NSAddressOfSymbol(NSLookupSymbolInImage(JavaScriptLibrary, "_"#sym, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND)); \
if (!JavaScriptCallBacks->sym##_proc) JavaScriptCallBacks->sym##_proc = (rettype(*)arglist)alt; \
} \
void
JSRelease(JSTypeRef ref) {
GET_DYNAMIC_SYMBOL(JSRelease, void, (JSTypeRef), returns);
return JavaScriptCallBacks->JSRelease_proc(ref);
}
void
JSLockInterpreter(void) {
GET_DYNAMIC_SYMBOL(JSLockInterpreter, void, (void), returns);
JavaScriptCallBacks->JSLockInterpreter_proc();
}
void
JSUnlockInterpreter(void) {
GET_DYNAMIC_SYMBOL(JSUnlockInterpreter, void, (void), returns);
JavaScriptCallBacks->JSUnlockInterpreter_proc();
}
JSObjectRef
JSObjectCallFunction(JSObjectRef ref, JSObjectRef thisObj, CFArrayRef args) {
GET_DYNAMIC_SYMBOL(JSObjectCallFunction, JSObjectRef, (JSObjectRef, JSObjectRef, CFArrayRef), returns_ref);
return JavaScriptCallBacks->JSObjectCallFunction_proc(ref, thisObj, args);
}
CFMutableArrayRef
JSCreateJSArrayFromCFArray(CFArrayRef array) {
GET_DYNAMIC_SYMBOL(JSCreateJSArrayFromCFArray, CFMutableArrayRef, (CFArrayRef), returns_ref);
return JavaScriptCallBacks->JSCreateJSArrayFromCFArray_proc(array);
}
JSRunRef
JSRunCreate(CFStringRef jsSource, JSFlags inFlags) {
GET_DYNAMIC_SYMBOL(JSRunCreate, JSRunRef, (CFStringRef, JSFlags), returns_ref);
return JavaScriptCallBacks->JSRunCreate_proc(jsSource, inFlags);
}
JSObjectRef
JSRunCopyGlobalObject(JSRunRef ref) {
GET_DYNAMIC_SYMBOL(JSRunCopyGlobalObject, JSObjectRef, (JSRunRef), returns_ref);
return JavaScriptCallBacks->JSRunCopyGlobalObject_proc(ref);
}
JSObjectRef
JSRunEvaluate(JSRunRef ref) {
GET_DYNAMIC_SYMBOL(JSRunEvaluate, JSObjectRef, (JSRunRef), returns_ref);
return JavaScriptCallBacks->JSRunEvaluate_proc(ref);
}
bool
JSRunCheckSyntax(JSRunRef ref) {
GET_DYNAMIC_SYMBOL(JSRunCheckSyntax, bool, (JSRunRef), returns_bool);
return JavaScriptCallBacks->JSRunCheckSyntax_proc(ref);
}
JSObjectRef
JSObjectCreate(void* data, JSObjectCallBacksPtr callBacks) {
GET_DYNAMIC_SYMBOL(JSObjectCreate, JSObjectRef, (void*, JSObjectCallBacksPtr), returns_ref);
return JavaScriptCallBacks->JSObjectCreate_proc(data, callBacks);
}
void
JSObjectSetProperty(JSObjectRef ref, CFStringRef propertyName, JSObjectRef value) {
GET_DYNAMIC_SYMBOL(JSObjectSetProperty, void, (JSObjectRef, CFStringRef, JSObjectRef), returns);
return JavaScriptCallBacks->JSObjectSetProperty_proc(ref, propertyName, value);
}
JSObjectRef
JSObjectCreateWithCFType(CFTypeRef inRef) {
GET_DYNAMIC_SYMBOL(JSObjectCreateWithCFType, JSObjectRef, (CFTypeRef), returns_ref);
return JavaScriptCallBacks->JSObjectCreateWithCFType_proc(inRef);
}
CFTypeRef
JSObjectCopyCFValue(JSObjectRef ref) {
GET_DYNAMIC_SYMBOL(JSObjectCopyCFValue, CFTypeRef, (JSObjectRef), returns_ref);
return JavaScriptCallBacks->JSObjectCopyCFValue_proc(ref);
}
JSObjectRef
JSObjectCopyProperty(JSObjectRef ref, CFStringRef propertyName) {
GET_DYNAMIC_SYMBOL(JSObjectCopyProperty, JSObjectRef, (JSObjectRef, CFStringRef), returns_ref);
return JavaScriptCallBacks->JSObjectCopyProperty_proc(ref, propertyName);
}
#undef GET_DYNAMIC_SYMBOL
#endif /* DYNAMICALLY_LOAD_JAVASCRIPT */

91
src/Makefile Executable file
View File

@ -0,0 +1,91 @@
# Simple makefile for building the CNetwork.
#
# Define sets of files to build, other info specific to this project.
#
NAME = CFNetwork
PUBLIC_HEADERS = CFFTPStream.h CFHost.h CFHTTPAuthentication.h CFHTTPMessage.h CFHTTPStream.h CFNetDiagnostics.h CFNetServices.h CFNetwork.h CFNetworkDefs.h CFSocketStream.h
PRIVATE_HEADERS = CFFTPStreamPriv.h CFHostPriv.h CFHTTPConnectionPriv.h CFHTTPMessagePriv.h CFHTTPServerPriv.h CFHTTPStreamPriv.h CFNetDiagnosticsPriv.h CFNetServicesPriv.h CFNetworkPriv.h CFServerPriv.h CFSocketStreamPriv.h
# These are the actual vars that are used by framework.make
PUBLIC_HFILES = $(foreach S, $(PUBLIC_HEADERS), $(SRCROOT)/Headers/$(S))
PRIVATE_HFILES = $(foreach S, $(PRIVATE_HEADERS), $(SRCROOT)/Headers/$(S))
PROJECT_HFILES = CFNetworkInternal.h HTTP/CFHTTPConnectionInternal.h HTTP/CFHTTPInternal.h NetDiagnostics/CFNetDiagnosticsInternal.h NetDiagnostics/CFNetDiagnosticsProtocol.h NetServices/DeprecatedDNSServiceDiscovery.h Proxies/ProxySupport.h SharedCode/CFNetConnection.h SharedCode/CFNetworkSchedule.h SharedCode/CFNetworkThreadSupport.h Stream/CFSocketStreamImpl.h HTTP/SPNEGO/spnegoBlob.h HTTP/SPNEGO/spnegoDER.h HTTP/SPNEGO/spnegoKrb.h HTTP/NTLM/ntlmBlobPriv.h HTTP/NTLM/NtlmGenerator.h
CFILES = CFNetwork.c SharedCode/CFServer.c SharedCode/CFNetConnection.c SharedCode/CFNetworkSchedule.c SharedCode/CFNetworkThreadSupport.c \
FTP/CFFTPStream.c Host/CFHost.c \
HTTP/CFHTTPAuthentication.c HTTP/CFHTTPConnection.c HTTP/CFHTTPFilter.c HTTP/CFHTTPMessage.c HTTP/CFHTTPServer.c HTTP/CFHTTPStream.c\
NetDiagnostics/CFNetDiagnosticPing.c NetDiagnostics/CFNetDiagnostics.c NetDiagnostics/CFNetDiagnosticsProtocolUser.c \
NetServices/CFNetServices.c NetServices/CFNetServiceBrowser.c NetServices/CFNetServiceMonitor.c NetServices/DeprecatedDNSServiceDiscovery.c \
Proxies/ProxySupport.c Stream/CFSocketStream.c URL/_CFURLAccess.c JavaScriptGlue.c libresolv.c
CPP_FILES = HTTP/SPNEGO/spnegoBlob.cpp HTTP/SPNEGO/spnegoDER.cpp HTTP/SPNEGO/spnegoKrb.cpp HTTP/NTLM/ntlmBlobPriv.cpp HTTP/NTLM/NtlmGenerator.cpp
OTHER_CFLAGS += -F/System/Library/PrivateFrameworks -F/usr/local/SecurityPieces/Frameworks
OTHER_CPPFLAGS += -F/usr/local/SecurityPieces/Frameworks
OTHER_LFLAGS += -framework CoreFoundation -framework Security -framework SystemConfiguration -F/usr/local/SecurityPieces/Frameworks -framework security_cdsa_utils
# Careful: This must be included after files are set, since they are used in dependencies which
# evaluate variables on the first parsing pass. Other variables used in rule bodiess are evaluated
# when the rules run, so they come after to have an additive effect on any defaults.
include framework.make
#
# Misc additional options
#
CURRENT_PROJECT_VERSION = 7
# -DAVAILABLE_MAC_OS_X_VERSION_XMerlot_AND_LATER is a hack - not sure why we need this, perhaps
# we need a newer version of Interfacer to build Merlot-based CFNetwork
#
# base addr is set to come after CoreFoundation - use the rebase MS command to see the sizes
# more info at http://msdn.microsoft.com/library/en-us/tools/tools/rebase.asp
ifeq "$(PLATFORM)" "CYGWIN"
CFLAGS += -DCFNETWORK_BUILDING_DLL -DAVAILABLE_MAC_OS_X_VERSION_XMerlot_AND_LATER=
CPPFLAGS += -DCFNETWORK_BUILDING_DLL
LIBS += -lCoreFoundation$(LIBRARY_SUFFIX) -lole32 -loleaut32 -lws2_32 -lwininet -luuid
LFLAGS += -Wl,--image-base=0x660b0000
endif
ifeq "$(PLATFORM)" "Darwin"
CFLAGS += -F/System/Library/Frameworks/CoreServices.framework/Frameworks
CPPFLAGS += -F/System/Library/Frameworks/CoreServices.framework/Frameworks
LFLAGS += -compatibility_version 1 -current_version $(CURRENT_PROJECT_VERSION)
endif
ifeq "$(PLATFORM)" "FreeBSD"
LFLAGS += -shared
endif
ifeq "$(PLATFORM)" "Linux"
LIBS += -lpthread
endif
# needs to be after including framework.make, to get our options after the -Wall
C_WARNING_FLAGS += -Wmissing-prototypes -Wpointer-arith -Wcast-align -Wno-unknown-pragmas -Wmissing-declarations -Wbad-function-cast
CPP_WARNING_FLAGS += -Wmissing-prototypes -Wpointer-arith -Wcast-align -Wno-unknown-pragmas
#
# Install the PAC support JS routines (build time is done, install time not done)
#
ifeq "$(LIBRARY_STYLE)" "Library"
prebuild_after::
$(SILENT) $(COPY_RECUR) PACSupport.js $(RESOURCE_DIR)
clean_after::
$(REMOVE_RECUR) -f $(RESOURCE_DIR)/PACSupport.js
endif
# mimics the Tests target in PB
#Tests:
# (cd HTTP/HTTPEcho; make)
# (cd HTTP/HTTPSConnect; make)
# (cd HTTP/ListLoad; make)
# (cd Stream/gethostbyname; make)
# (cd Stream/SocketStreamPerf; make)

View File

@ -0,0 +1,730 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CFNetDiagnosticPing.c
* CFNetwork
*
* Created by Louis Gerbarg on 8/30/04.
* Copyright 2004 __MyCompanyName__. All rights reserved.
*
*/
//Copied from Network Diagnostic, from sample code. Should be migrated to CFHost based, and made API
#include <CoreFoundation/CoreFoundation.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#if !defined(APPORTABLE)
#include <netinet/ip_var.h>
#endif
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <errno.h>
struct PingICMPPacket
{
struct icmp icmpHeader; //required icmp header
struct timeval packetTimeStamp; //our optional data will be the packet send time.
};
static int in_cksum(u_short *addr, int len);
static int WaitAndPrintICMPs(int socketConnectionToHost, int TimeoutInSeconds, int ReturnImmediatlyAfterReply, int* GotResponse);
static int CreateAndSendICMPPacket(struct sockaddr_in HostAddress, int SequenceNumber, int SocketConnectionToHost);
static int CreateSocketForCommunicationWithHost(const struct sockaddr_in HostAddress, int* SocketToReturn);
static int LookupHostAddress(const char* HostToPing, struct sockaddr_in* HostAddress);
/*****************************************************
* SimplePing
*****************************************************
* Purpose: This function uses the above functions to ping a given remote host with
* a given number of packets and with a given timeout to wait for responses on each packet.
* Note this function does not require root permissions since on MacOSX 10.2.x pings are
* possible using non-privaldged datagram sockets.
*
* Parameters:
* HostToPing A C-String describing the remote host. On calling
* SimplePing this variable will hold a description of the host as a C-String. The string
* can either be a hostname (e.g. www.google.com) or an IP address (e.g. 17.203.23.111)
*
* NumberOfPacketsToSend An integer. On calling SimplePing this variable holds
* the number of ping packets to send to the host before stopping.
*
* PingTimeoutInSeconds An integer. On calling Simple Ping this variable holds
* the amount of time SimplePing will wait for reponses from the ping before going onto the next packet.
*
* ReturnImmediatlyAfterReply An integer. On calling Simple Ping if this variable is zero then
* we will wait for the timeout to occur even if we get the appropriate ping reply (waiting for any other packets).
* If this variable is non-zero then simple ping will return immediatly after getting the appropriate ping reply to
* the request.
*
* *Function Result* A UNIX error integer return value as described in:
* /usr/include/sys/errno.h on a BSD system.
* Note: This value will be zero on success.
*****************************************************/
int _CFNetDiagnosticPing(CFStringRef HostToPing, const int NumberOfPacketsToSend, const int PingTimeoutInSeconds);
int _CFNetDiagnosticPing(CFStringRef HostToPing, const int NumberOfPacketsToSend, const int PingTimeoutInSeconds)
{
struct sockaddr_in hostAddress;
int packetSequenceNumber;
int socketConnectionToHost;
int gotResponse = 0;
int numberPacketsSent = 0;
int numberPacketsReceived = 0;
char HostToPingStr[256];
if ((HostToPing == NULL) || (NumberOfPacketsToSend < 1) || (PingTimeoutInSeconds < 1))
{
//printf("Invalid arguments to SimplePing\n");
return(EINVAL); //invalid arguments error
}
if(!CFStringGetCString((CFStringRef)HostToPing, HostToPingStr, sizeof(HostToPingStr), kCFStringEncodingASCII)) {
return(EINVAL);
}
int error = LookupHostAddress(HostToPingStr, &hostAddress);
if (error != 0)
{
//printf("Unable to lookup host address. UNIX Error: %d", error);
return(error);
}
//printf("PING %s (%s)\n", HostToPing, inet_ntoa(hostAddress.sin_addr));
//fflush(stdout);
error = CreateSocketForCommunicationWithHost(hostAddress, &socketConnectionToHost);
if (error != 0)
{
//printf("Unable to create socket. UNIX Error: %d", error);
return(error);
}
packetSequenceNumber = 0;
while ((packetSequenceNumber < NumberOfPacketsToSend) && (error == 0))
{
//printf("*Pinging host %s: icmp_seq=%u\n",
// inet_ntoa(hostAddress.sin_addr), packetSequenceNumber);
//fflush(stdout);
error = CreateAndSendICMPPacket(hostAddress,
packetSequenceNumber, socketConnectionToHost);
if (error == 0) //successfully sent packet
{
numberPacketsSent = numberPacketsSent + 1;
//Here we wait for the return on the packet until we get it or until the timeout fires.
error = WaitAndPrintICMPs(socketConnectionToHost, PingTimeoutInSeconds, 1, &gotResponse);
if (error == 0) //was able to wait for reply successfully (whether we got a reply or not)
{
if (gotResponse == 1)
{numberPacketsReceived = numberPacketsReceived + 1;}
}
}
packetSequenceNumber = packetSequenceNumber + 1;
}
close(socketConnectionToHost); //closing the socket connection since we are finished with it.
//printf("\n--- %s ping statistics ---\n", HostToPing);
//printf("%d packets transmitted, %d packets received, %.0f%% packet loss",
// numberPacketsSent, numberPacketsReceived,
// 100*((double)numberPacketsSent -
// (double)numberPacketsReceived)/(double)numberPacketsSent);
//fflush(stdout);
return(error);
}
/*****************************************************
* LookupHostAddress
*****************************************************
* Purpose: This function provides a mechanism to get a host address
* as a internet address structure given only a string describing the
* remote host. The string passed will be either a host name
* (e.g. www.apple.com) or an IP address (e.g. 17.203.23.111)
*
* Parameters:
* HostToPing A constant C-string. On calling
* LookupHostAddress this variable holds a CString describing the
* remote host. The string can either be a host name (e.g. www.google.com)
* or an IP address (e.g. 17.203.23.112)
*
* HostAddress A pointer to a pre-allocated array of sockaddr_in structure.
* On calling LookupHostAddress this variable must be a pointer to a
* pre-allocated sockaddr_in structure. On successful return from LookupHostAddress
* this variable will hold the host address expressed as an sockaddr_in structure.
* On failed return the value of this variable is undefined
*
* *Function Result* A UNIX error integer return value as described in:
* /usr/include/sys/errno.h on a BSD system.
* Note: This value will be zero on success.
*****************************************************/
static int LookupHostAddress(const char* HostToPing, struct sockaddr_in* HostAddress)
{
struct hostent * hostInformation;
//Checking input argument for validity
if ((HostToPing == NULL) || (HostAddress == NULL))
{
return(EINVAL); //invalid argument error return
}
//Initalizing host address
memset(HostAddress, 0, sizeof(struct sockaddr_in));
/* Calling inet_addr to try to interpret the input address as a
* IP string "xx.xx.xx.xx.xx. If this doesn't work then we will
* try gethostbyname which will resolve any domain names (i.e. www.google.com)
* First Argument: The IP address expressed as a character string. Assuming
* the string passed to us is an IP string we try to interpret the string.
* if this doesn't work then we will try gethostbyname.
* Return Value: If properly formed input then what is returned is an internet
* address structure. We will use this to set the internet address structure
* in our socket address. If the request is malformed then the constant
* INADDR_NONE will be returned for the internet address.
*/
HostAddress->sin_addr.s_addr = inet_addr(HostToPing);
//Checking to see if IP address was got correctly from character string.
if (HostAddress->sin_addr.s_addr != INADDR_NONE) //Success no error returned!
{
//Setting socket family to internet (TCP/IP) since know it was IP address interpreted
HostAddress->sin_family = AF_INET;
}
else //failure! now try with gethostbyname
{
/* The inet_addr call failed because the string isn't an IP address. Instead
* we will try to interpret it as a host name (e.g. www.google.com).
* First Argument: The character string we are trying to interpret of as a
* host name.
* Return Value: A host information structure on success which will contain the
* information we need for connecting to the host. On failure a NULL pointer
* will be returned
*/
hostInformation = gethostbyname(HostToPing);
if (hostInformation == NULL) //Failure!
{
//Failure unable to interpret character string as host name.
//We give up here by returning can't find host (unreachable host host).
return(EHOSTUNREACH);
}
//Setting the socket family for connecting to the host. We get this information from
//the hostInformation structure directly
HostAddress->sin_family = hostInformation->h_addrtype;
//Now getting the internet address structure from our host information structure.
//We copy the structure into ours using a memmove
memmove(&HostAddress->sin_addr, hostInformation->h_addr, hostInformation->h_length);
}
/* Now for the host we have the address and connection family for the host we can return this
* information
*/
return(0); //return zero indicating success.
}
/*****************************************************
* CreateSocketForCommunicationWithHost
*****************************************************
* Purpose: This function sets up a socket for communicating
* with the given remote host and also sets the parameters of
* that socket to our required specifications (timeout of 1 second
* and larger receive buffer).
*
* Parameters:
* HostAddress A sockaddr_in structure. On calling
* CreateSocketForCommunicationWithHost this variable has an address
* of the host the socket will be established with expressed in sockaddr_in format.
*
* SocketToReturn A pointer to a pre-allocated integer. On successful
* return from CreateSocketForCommunicationWithHost this variable will hold
* a socket descriptor used to communicate with the socket in future calls. On
* failed result this variable will be undefined. Note on successful result its
* the caller's responsibility to close the socket.
*
* *Function Result* A UNIX error integer return value as described in:
* /usr/include/sys/errno.h on a BSD system.
* Note: This value will be zero on success.
*****************************************************/
static int CreateSocketForCommunicationWithHost(const struct sockaddr_in HostAddress, int* SocketToReturn)
{
struct protoent* protocalInformation;
const int kRecieveSocketBufferSize = 50 * 1024; //here we want 50K for size of receive buffer
struct timeval pingTimeout;
int error = 0;
/* Getting the protocal information we need to create the socket. This socket will use the
* icmp protocal (protocal used for pings). We first need to get the procal information with
* a getprotobyname call
* First Argument: The name of the protocal we will be using
* Return Value: A pointer to a protocal structure which provides us with the protocal
* information used to create the socket. On failure the pointer will be NULL.
*/
protocalInformation = getprotobyname("icmp");
//Check to see if got protocal information successfully.
if (protocalInformation == NULL)
{
//here the protocal we want isn't supported or isn't found. Need to fail here
return(EPFNOSUPPORT); //return protocal not supported UNIX error
}
/* Now creating the socket which will be used for pinging the remote host. Note
* here we need to create a socket to send the ping. Note previous to MacOSX 10.2
* this required a raw socket which required root permissions. However, now in 10.2.x
* you can simply create a datagram socket and can use that to ping remote hosts.
* First Argument: The communication domain to use. In this case the ARPA internet
* protocal which is used to do pings.
* Second Argument: The type of socket to create. In this case we need a raw socket
* to ping the remote host.
* Third Argument: The partucular protocal to use over the socket. Here we use the
* icmp protocal so pass the protocal number from the protocal information found earlier.
* Return Value: On success the created socket will be returned. On failure a value
* less then zero will be returned.
*/
*SocketToReturn = socket(AF_INET, SOCK_DGRAM, protocalInformation->p_proto);
if (*SocketToReturn < 0)
{
//error creating socket give up here. Return operation not permitted error indicating
//we can't create socket.
return(EPERM);
}
/* Now that we have the socket created there is one extra step we would like to do.
* That is increase the receive buffer size. The reason we do this is when we send
* an echo request there can be many replies. This means that a regular sized buffer
* might get overwelmed. Thus we increase the receive buffer size to 50K which
* should be large enough to hold the ICMP replies.
* First Argument: The socket we are editing the receive buffer size on. In this case
* the socket we just created.
* Second Argument: UNIX constant SOL_SOCKET indicating we are editing a socket level
* attribute (see man page for setsockopt for more details).
* Third Argument: UNIX constant SO_RCVBUF indicating we are editing a receive buffer on
* the socket (see man page for setsockopt for more details).
* Forth Argument: The new size of the buffer we desire. In this case the arbitrarily
* chosen 50K buffer.
* Fifth Argument: The size of the forth argument (i.e. sizeof())
* Return Value: There is actually a return value of zero on success and -1 on failure.
* However, whether we get an error or not we will continue. We would *like* to increase
* the buffer size but its not required.
*/
(void) setsockopt(*SocketToReturn, SOL_SOCKET, SO_RCVBUF,
&kRecieveSocketBufferSize, sizeof(kRecieveSocketBufferSize));
/* Now that we have the socket created we want to set the timeout on the socket. This is
* the time a ping request will wait before assuming failure. Here we use the value which
* is passed to us as the timeout value. We set the timeout by setting the timeout for
* recieve requests on the socket using setsockopt.
* First Argument: The socket we are editing the receive timeout. In this case
* the socket we just created. This timeout will end up being the time ping waits for a response.
* Second Argument: UNIX constant SOL_SOCKET indicating we are editing a socket level
* attribute (see man page for setsockopt for more details).
* Third Argument: UNIX constant SO_RCVTIMEO indicating we are editing the receive timeout on
* the socket (see man page for setsockopt for more details).
* Forth Argument: The value that the timeout should be as a timeval structure. In this case
* we use the timeout passed to us as the timeout for the requests.
* Fifth Argument: The size of the forth argument (i.e. sizeof())
* Return Value: There is actually a return value of zero on success and -1 on failure.
*/
//Setting the ping timeout to one second. This way a recieve call will timeout after 1
//second later on. This saves us from having to use UNIX signal alarms for timeouts
pingTimeout.tv_sec = 1;
pingTimeout.tv_usec = 0;
error = setsockopt(*SocketToReturn, SOL_SOCKET, SO_RCVTIMEO,
&pingTimeout, sizeof(pingTimeout));
if (error != 0)
{
close(*SocketToReturn); //before returning error close the socket.
//were unable to set timeout on the socket. Here we will return an error.
return(errno);
}
return(0); //if got this far were successful. Return zero for success.
}
/*****************************************************
* CreateAndSendICMPPacket
*****************************************************
* Purpose: This function creates an ICMP packet with the neccessary information
* inside of it to make it a ping packet. This function also sends that ping packet to
* the remote host.
*
* Parameters:
* HostAddress A sockaddr_in structure. On calling
* CreateAndSendICMPPacket this variable has an address
* of the host where the ping will be sent.
*
* SequenceNumber A integer. when calling CreateAndSendICMPPacket this variable
* will hold the sequence number of the ping packet being sent. This information is
* then put in the ping packet sent to the host so when they reply we know which
* send the reply is accociated with.
*
* SocketConnectionToHost A socket descriptor expressed as an integer. On calling
* CreateAndSendICMPPacket this variable will be a valid socket which is already setup
* for communicating with the remote host.
*
* *Function Result* A UNIX error integer return value as described in:
* /usr/include/sys/errno.h on a BSD system.
* Note: This value will be zero on success.
*****************************************************/
static int CreateAndSendICMPPacket(struct sockaddr_in HostAddress, int SequenceNumber, int SocketConnectionToHost)
{
struct PingICMPPacket PacketToSend;
int error;
ssize_t sizeOfDataSent;
// --- Setting up the packet we are going to send. --- //
//ICMP type is an echo packet which is the packet type for a ping.
PacketToSend.icmpHeader.icmp_type = ICMP_ECHO;
//Zero code for ping packet.
PacketToSend.icmpHeader.icmp_code = 0;
//Sequence number of the packet is whatever is passed to us
PacketToSend.icmpHeader.icmp_seq = SequenceNumber;
//add our PID as the identifyer so we know later the ping originated from us.
PacketToSend.icmpHeader.icmp_id = getpid();
/* Now we will get time of day so we can add it to the "extra" data on the ICMP packet.
* The time of day will allow us to calculate the round trip time on the ping opon
* recieveing the echo packet
*/
error = gettimeofday(&PacketToSend.packetTimeStamp, NULL);
if (error != 0) //if not equal to zero then couldn't get time of day
{
if (errno != 0)
{
return(errno); //errno was set by gettimeofday. Return that value as error.
}
return(EPERM); //could not perform operation return UNIX error code operation not permitted.
}
/* Now that we have the filled out packet we will calculate the checksum for the packet.
* We actually will calculate checksum but only after we have everything filled out and
* set the checksum value to zero (for calculation)
*/
PacketToSend.icmpHeader.icmp_cksum = 0;
//The in_cksum function will calcluate the checksum for us given the packet and its length.
PacketToSend.icmpHeader.icmp_cksum = in_cksum((u_short *)&PacketToSend, sizeof(PacketToSend));
/* Now that the packet is finished we will go ahead and send the packet to the host
* We use the sendto API to send the packet to the host.
* First Argument: The Socket used for sending the packet to the host. In this case the
* ICMP socket we already created.
* Second Argument: The actual packet itself we already created
* Third Argument: The size of the packet we are sending in this case the size of the packet
* structure
* Forth Argument: This is for additional flags which we won't use. Pass zero to ignore.
* Fifth Argument: The host address to send the packet to.
* Sixth Argument: The size of the host address passed in.
* Return Value: This call returns the size of the data sent (hopefully it will be the
* same as PacketToSend). On failure this function returns -1.
*/
sizeOfDataSent = sendto(SocketConnectionToHost, &PacketToSend,
sizeof(PacketToSend), 0,
(struct sockaddr*) &HostAddress, sizeof(HostAddress));
//if size of data sent is -1 (indicating error) or not size we wanted then we have a problem
if ((sizeOfDataSent < 0) || (sizeOfDataSent != sizeof(PacketToSend)))
{
if (errno != 0)
{
//packet wasn't sent properly return error.
return(errno); //return UNIX created by sendto
}
return(EPERM); //return more generic code since error code since errno wasn't set.
}
return(0); //If got this far were successful. Return zero indicating success.
}
/*****************************************************
* WaitAndPrintICMPs
*****************************************************
* Purpose: This function creates an ICMP packet with the neccessary information
* inside of it to make it a ping packet. This function also sends that ping packet to
* the remote host.
*
* Parameters:
* SocketConnectionToHost A socket descriptor expressed as an integer. On calling
* WaitAndPrintICMPs this variable will be a valid socket which is already setup
* for communicating with the remote host. This will be used in getting the reply
* packets from the host.
*
* TimeoutInSeconds A timeout expressed as an integer. On calling
* WaitAndPrintICMPs this variable will have the number of seconds to wait for
* ICMP replies. Note even if a valid ICMP reply comes that matches what we expect
* we will still wait for additional ICMP packets until the timeout has occurred.
*
* ReturnImmediatlyAfterReply An integer. On calling WaitAndPrintICMPs if this variable is zero then
* we will wait for the timeout to occur even if we get the appropriate ping reply (waiting for any other packets).
* If this variable is non-zero then simple ping will return immediatly after getting the appropriate ping reply to
* the request.
*
* GotResponse A pre-allocated integer. when calling WaitAndPrintICMPs
* this variable will be a pre-allocated integer. On successful return from WaitAndPrintICMPs this
* variable will hold a value of 1 if a ICMP packet response to our ping was recieved.
* And a zero otherwise. On failed return the value of this variable will be undefined.
*
* *Function Result* A UNIX error integer return value as described in:
* /usr/include/sys/errno.h on a BSD system.
* Note: This value will be zero on success.
*****************************************************/
static int WaitAndPrintICMPs(int socketConnectionToHost, int TimeoutInSeconds, int ReturnImmediatlyAfterReply, int* GotResponse)
{
const int kBufferSize = 2048; //size we allocate for the reply buffer.
char pingReplyBuffer[kBufferSize];
struct sockaddr_in remoteHost;
socklen_t sizeOfRemoteHost = (int) sizeof(remoteHost);
ssize_t numberOfBytesReceived;
struct ip* packetInterpetedAsIPPacket;
int ipHeaderLength;
struct PingICMPPacket* icmpPacket;
unsigned int icmpPacketSize;
int error = 0;
int gotStartTime = 0;
struct timeval currentTime, timeSinceStartedWaiting;
struct timeval startTime, roundTripTimeOnPacket;
double roundTripTimeInMS;
//Checking input argument for validity
if ((GotResponse == NULL) || (TimeoutInSeconds < 1))
{
return(EINVAL); //invalid argument error return
}
*GotResponse = 0;
do
{
/* Now that he have sent the ping to the host we need to wait for a reply. We do this
* by calling recvfrom which will wait for a response for the timeout specified earlier
* when creating the socket
* First Argument: The socket we are waiting for data upon
* Second Argument: The buffer to use for storing the reply from the remote host.
* Third Argument: The size of the buffer in argument two
* Forth Argument: Additional flags which can be used for special options. We ignore this
* by passing zero
* Fifth Argument: A internet address structure used to hold the address information from where the
* data came from
* Sixth Argument: Size of the buffer/structure in argument five.
* Return Value: The size of the data returned. On error this value will be less than zero.
*/
numberOfBytesReceived = recvfrom(socketConnectionToHost, pingReplyBuffer,
sizeof(pingReplyBuffer), 0,
(struct sockaddr *) &remoteHost, &sizeOfRemoteHost);
if (numberOfBytesReceived < 0) //error reciving data, return error
{
error = errno; //return the UNIX errno variable which would be set by recvfrom.
}
if (gotStartTime == 0)
{
//Getting the start time for this function if we dont already have it.
if (gettimeofday(&startTime, NULL) != 0)
{
if (errno != 0)
{
//if got error getting time of day return UNIX error and give up.
return(errno);
}
return(EPERM); //return more generic error since wasn't set by gettimeofday
}
gotStartTime = 1;
}
if (error == 0)
{
/* Now that we have a reply we will test it to see if its the reply we expect.
* First step is to discard the IP header from the raw packet we got back. We can do this
* by determining the size of the IP header and then moving our pointer beyond that.
*/
//Interpret packet as IP packet to remove header
packetInterpetedAsIPPacket = (struct ip*)pingReplyBuffer;
//The ip_hl item within the IP packet has the length of the IP header expressed as bytes
//(shifted right twice, thus need to shift left to compensate.
ipHeaderLength = packetInterpetedAsIPPacket->ip_hl << 2;
//Now we know the IP header length we can get a pointer to the ICMP section of the packet
icmpPacket = (struct PingICMPPacket*)(pingReplyBuffer + ipHeaderLength);
icmpPacketSize = numberOfBytesReceived - ipHeaderLength;
//The echo request must be at least as large as the one we sent to have all echo information.
if (icmpPacketSize >= sizeof(struct PingICMPPacket))
{
//This packet also has to be an ICMP echo reply packet to the one.
if (icmpPacket->icmpHeader.icmp_type == ICMP_ECHOREPLY)
{
//To be our packet the id on the packet has to match our PID.
//This is because in the echo
//the id wouldn't change and we sent pid as the id.
if (icmpPacket->icmpHeader.icmp_id == getpid())
{
//If we got this far then this is a reply to our ping request!
*GotResponse = 1;
//--- Print out ICMP packet information ---//
//Get the current time for determining round trip time
if (gettimeofday(&currentTime, NULL) != 0)
{
if (errno != 0)
{
//if error getting time of day return UNIX error.
return(errno);
}
return(EPERM); //return more generic EPERM since gettimeofday
//didn't set error
}
//Subtracting the timeval structures to get roundTripTimeOnPacket
timersub(&currentTime, &(icmpPacket->packetTimeStamp), &roundTripTimeOnPacket);
//getting round trip time in milliseconds
roundTripTimeInMS = (double) (roundTripTimeOnPacket.tv_sec*1000 +
(((double) roundTripTimeOnPacket.tv_usec) / 1000));
//printf("Response from %s: icmp_seq=%u ttl=%d time=%.3f ms\n",
// inet_ntoa(remoteHost.sin_addr),
// icmpPacket->icmpHeader.icmp_seq,
// packetInterpetedAsIPPacket->ip_ttl,
// roundTripTimeInMS);
//fflush(stdout);
}//endif
}//endif
}//endif
}//endif no error on getting packet
else if (error == EAGAIN)
{
//we ignore EAGAIN errors since they are fired by the 1 second timeout on the socket
//On these occasions we just want to see if our timeout for the function has passed.
error = 0;
}
//no errors up to this point then calculate the time for timeout
if (error == 0)
{
//Get the current time for looking for determining timeout for function
if (gettimeofday(&currentTime, NULL) != 0)
{
if (errno != 0)
{
//if error getting time of day return UNIX error.
error = errno;
}
else
{error = EPERM;} //get more generic error since gettimeofday didn't set value
}
//Subtract two timeval structures to get the time since we started this function
timersub(&currentTime, &startTime, &timeSinceStartedWaiting);
}
}//end do while
while ((error == 0) && (timeSinceStartedWaiting.tv_sec < TimeoutInSeconds) && ((ReturnImmediatlyAfterReply == 0) || (GotResponse == 0)));
if (*GotResponse == 0)
{
//printf("No Response From Host\n"); fflush(stdout);
}
return(0);
}
//Here stealing the in_cksum function which computes checksum for our packets from original ping.
static int in_cksum(u_short *addr, int len)
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1) {
*(u_char *)(&answer) = *(u_char *)w ;
sum += answer;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return(answer);
}

View File

@ -0,0 +1,708 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* NetworkDiagnostics.c
* NetworkDiagnostics
*
* Created by Louis Gerbarg on Fri Mar 26 2004.
* Copyright 2004 Apple Computer, Inc. All rights reserved.
*
*/
#include <CoreFoundation/CoreFoundation.h>
#include <SystemConfiguration/SystemConfiguration.h>
#include "CFNetworkInternal.h"
#include <CFNetwork/CFNetDiagnostics.h>
#include "CFNetDiagnosticsPriv.h"
//For mig and mach stuff
#include <mach/mach.h>
#if !defined(APPORTABLE)
#include <servers/bootstrap.h>
#include <servers/bootstrap_defs.h>
#endif
#include "CFNetDiagnosticsProtocol.h"
#include "CFNetDiagnosticsInternal.h"
//For IN_LINKLOCAL() and inet_addr()
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
//For mach_absolute_time()
#include <mach/mach_time.h>
//For printf
#include <stdio.h>
extern
int _CFNetDiagnosticPing(CFStringRef HostToPing, const int NumberOfPacketsToSend, const int PingTimeoutInSeconds);
const char * CFNetDiagnosticNotifyKey = "com.apple.NetworkDiagnostics.notification";
/*
**INTERNAL SCHEMA INFO**
details schema
_NDNameKey = <CFString for app that called us> (example: "Safari")
_NDBundleKey = <CFString for the app that called us>
_NDRemoteHostKey = <CFString for remote network host> (example: "www.apple.com")
_NDProtocolKey = <CFString for network protocol> (example: "HTTP")
_NDPortKey = <CFNumber for network port> (example: 80)
Usage:
The details dictionary passed into NDDiagnoseProblem() must contain either a name
or a BundleIdentifier. Everything else is optional. If the dictionary contains a
Bundle identifier it will be used to determine the localized name of the caller,
and potentially to get the icon. If the application wants to override that
behaviour it may pass a name instead. In that cas the app is responsible for
localizing the string before it passes it to us.
The rest of the dictionary values can be used to help Network Diagnostics attempt
to analyze the problem.
*/
const CFStringRef CFNetDiagnosticProtocolHTTP = CFSTR("http");
const CFStringRef CFNetDiagnosticProtocolFTP = CFSTR("ftp");
const CFStringRef CFNetDiagnosticProtocolSMTP = CFSTR("smtp");
const CFStringRef CFNetDiagnosticProtocolIMAP = CFSTR("imap");
const CFStringRef CFNetDiagnosticProtocolOSCAR = CFSTR("oscar");
const CFStringRef CFNetDiagnosticProtocolUnknown = CFSTR("unknown");
#if 0
/* This is used for debugging. I should also conditionalize it on an environment variable in case any
calls are accidentally left in the code.
*/
static
void _CFNetDiagnosticsPrintObject(CFTypeRef object) {
char buffer[32768];
Boolean converted;
CFStringRef desc;
desc = CFCopyDescription(object);
if(desc) {
converted = CFStringGetCString(desc, buffer, 32768, kCFStringEncodingASCII);
if(converted) {
printf("%s\n", buffer);
}
CFRelease(desc);
}
}
#endif
/*
I am a big believer in static functions. Anything you repeated 3 times
in a row should be refactored into them.
*/
static
void _CFNetDiagnosticSetDictionaryKeyIfNotNull( CFStringRef key,
CFTypeRef value,
CFMutableDictionaryRef dict) {
if(key != NULL && value != NULL) {
CFDictionaryAddValue(dict, key, value);
}
}
static
void _CFNetDiagnosticSetDictionaryKeyAndReleaseIfNotNull( CFStringRef key,
CFTypeRef value,
CFMutableDictionaryRef dict) {
if(key != NULL) {
if(value != NULL) {
CFDictionaryAddValue(dict, key, value);
CFRelease(value);
}
}
}
static
CFTypeRef _CFNetDiagnosticGetValueFromDictionaryAndRetain(CFDictionaryRef dict, CFStringRef key) {
CFTypeRef s;
s = (CFTypeRef)CFDictionaryGetValue(dict, key);
if(s != NULL) {
CFRetain(s);
}
return s;
}
/* Okay, _CFNetDiagnosticsGetDataFromSCDSAndThowAwayGarbage is tricky. I use it to avoid doing this:
pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(allocator, arg1, arg2, arg3);
if(pattern) {
dict = SCDynamicStoreCopyValue( store, pattern );
CFRelease(pattern);
}
in a bunch of places in the code. Afterall, if I am going to generate an SCDS pattern from one of the
provided functions the only thing I am possibly going to do with it is call SCDynamicStoreCopyValue.
*/
static
CFDictionaryRef _CFNetDiagnosticsGetDataFromSCDSAndThowAwayGarbage(CFAllocatorRef allocator, SCDynamicStoreRef store,
CFStringRef(*SCFunc)(CFAllocatorRef, CFStringRef, CFStringRef, CFStringRef), CFStringRef arg1, CFStringRef arg2, CFStringRef arg3) {
CFStringRef pattern = NULL;
CFDictionaryRef dict = NULL;
pattern = SCFunc(allocator, arg1, arg2, arg3);
if(pattern) {
dict = SCDynamicStoreCopyValue( store, pattern );
CFRelease(pattern);
}
return dict;
}
CFNetDiagnosticRef CFNetDiagnosticCreateBasic( CFAllocatorRef allocator,
CFStringRef remoteHost,
CFStringRef protocol,
CFNumberRef port) {
CFMutableDictionaryRef retval = NULL;
retval = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if(retval != NULL) {
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticNameKey, CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleNameKey), retval);
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticBundleKey, CFBundleGetIdentifier( CFBundleGetMainBundle() ), retval);
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticRemoteHostKey, remoteHost, retval);
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticProtocolKey, protocol, retval);
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticPortKey, port, retval);
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticMethodKey, CFSTR("CFNetDiagnosticCreateBasic"), retval);
}
return (CFNetDiagnosticRef)retval;
}
CFNetDiagnosticRef CFNetDiagnosticCreateWithURL(CFAllocatorRef allocator, CFURLRef url) {
CFMutableDictionaryRef retval;
SInt32 port = 0;
retval = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if(retval != NULL && CFURLCanBeDecomposed(url)) {
port = CFURLGetPortNumber(url);
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticNameKey, CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleNameKey), retval);
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticBundleKey, CFBundleGetIdentifier( CFBundleGetMainBundle() ), retval);
_CFNetDiagnosticSetDictionaryKeyAndReleaseIfNotNull(_CFNetDiagnosticRemoteHostKey, CFURLCopyHostName(url), retval);
_CFNetDiagnosticSetDictionaryKeyAndReleaseIfNotNull(_CFNetDiagnosticProtocolKey, CFURLCopyScheme(url), retval);
_CFNetDiagnosticSetDictionaryKeyAndReleaseIfNotNull(_CFNetDiagnosticPortKey, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &port), retval);
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticMethodKey, CFSTR("CFNetDiagnosticCreateWithURL"), retval);
}
return (CFNetDiagnosticRef)retval;
}
CFNetDiagnosticRef CFNetDiagnosticCreateWithStreams(CFAllocatorRef allocator, CFReadStreamRef readStream, CFWriteStreamRef writeStream) {
//FIXME deal with read and write streams
CFMutableDictionaryRef retval;
#if 0
CFArrayRef hostnames;
CFHostRef host;
#endif
retval = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if(retval != NULL) {
#if 0
host = (CFHostRef)CFReadStreamCopyProperty(readStream, kCFStreamPropertySocketRemoteHost);
if(host) {
hostnames = CFHostGetAddressing(host, NULL);
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticRemoteHostKey, CFArrayGetValueAtIndex(hostnames, 0), retval);
CFRelease(host);
}
#endif
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticNameKey, CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleNameKey), retval);
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticBundleKey, CFBundleGetIdentifier( CFBundleGetMainBundle() ), retval);
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticMethodKey, CFSTR("CFNetDiagnosticCreateWithStreams"), retval);
}
return (CFNetDiagnosticRef)retval;
}
void CFNetDiagnosticSetName(CFNetDiagnosticRef details, CFStringRef name) {
CFMutableDictionaryRef detailsDict = (CFMutableDictionaryRef)details;
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticNameKey, name, detailsDict);
}
void CFNetDiagnosticSetProtocol(CFNetDiagnosticRef details, CFStringRef service) {
CFMutableDictionaryRef detailsDict = (CFMutableDictionaryRef)details;
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticProtocolKey, service, detailsDict);
}
void CFNetDiagnosticSetServiceID(CFNetDiagnosticRef details, CFStringRef service) {
CFMutableDictionaryRef detailsDict = (CFMutableDictionaryRef)details;
_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticServiceIDKey, service, detailsDict);
}
CFNetDiagnosticStatus CFNetDiagnosticDiagnoseProblemInteractively(CFNetDiagnosticRef details) {
SInt32 retval = 0;
mach_port_t port = MACH_PORT_NULL;
CFDataRef msgData = NULL;
kern_return_t err;
//build message
CFWriteStreamRef stream = CFWriteStreamCreateWithAllocatedBuffers(kCFAllocatorDefault, kCFAllocatorDefault);
CFWriteStreamOpen(stream);
CFIndex len = CFPropertyListWriteToStream(details, stream, kCFPropertyListBinaryFormat_v1_0, NULL);
CFWriteStreamClose(stream);
if(len > 0) {
msgData = CFWriteStreamCopyProperty(stream, kCFStreamPropertyDataWritten);
}
CFRelease(stream);
if(msgData) {
err = bootstrap_look_up(bootstrap_port, *((name_t*)(&_CFNetDiagnosticMachPortName)), &port);
if (err == KERN_SUCCESS) {
err = _CFNetDiagnosticClient_passDescriptor( port,
_CFNetDiagnosticMachProtocolVersion,
(vm_address_t)CFDataGetBytePtr(msgData),
CFDataGetLength(msgData));
if (err == KERN_SUCCESS) {
//FIXME Yay!!!
}
}
CFRelease(msgData);
}
return (CFNetDiagnosticStatus)retval;
}
static
CFStringRef copyCurrentRouter(void) {
SCDynamicStoreRef store;
CFPropertyListRef propList;
CFStringRef retval = NULL;
store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("Network Diagnostics"), NULL, NULL);
if(store) {
propList = SCDynamicStoreCopyValue(store, CFSTR("State:/Network/Global/IPv4"));
if(propList) {
retval = CFDictionaryGetValue(propList, CFSTR("Router"));
if (retval) {
CFRetain(retval);
}
CFRelease(propList);
}
CFRelease(store);
}
return retval;
}
static
CFStringRef copyCurrentPrimaryService(void) {
SCDynamicStoreRef store;
CFPropertyListRef propList;
CFStringRef retval = NULL;
store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("Network Diagnostics"), NULL, NULL);
if(store) {
propList = SCDynamicStoreCopyValue(store, CFSTR("State:/Network/Global/IPv4"));
if(propList) {
retval = CFDictionaryGetValue(propList, CFSTR("PrimaryService"));
if (retval) {
CFRetain(retval);
}
CFRelease(propList);
}
CFRelease(store);
}
return retval;
}
static
CFArrayRef copyCurrentDNSServers(void) {
SCDynamicStoreRef store;
CFPropertyListRef propList;
CFStringRef scdsRegexp;
CFArrayRef retval = NULL;
CFStringRef serviceID;
serviceID = copyCurrentPrimaryService();
if(serviceID) {
scdsRegexp = SCDynamicStoreKeyCreateNetworkServiceEntity (
kCFAllocatorDefault,
kSCDynamicStoreDomainState,
serviceID,
kSCEntNetDNS);
if(scdsRegexp) {
store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("Network Diagnostics"), NULL, NULL);
if(store) {
propList = SCDynamicStoreCopyValue(store, scdsRegexp);
if(propList) {
retval = CFDictionaryGetValue(propList, CFSTR("ServerAddresses"));
if (retval) {
CFRetain(retval);
}
CFRelease(propList);
}
CFRelease(store);
}
CFRelease(scdsRegexp);
}
CFRelease(serviceID);
}
return retval;
}
CFNetDiagnosticStatus CFNetDiagnosticCopyNetworkStatusActively(CFNetDiagnosticRef details, CFNumberRef timeout, CFStringRef *description) {
uint64_t timestamp;
uint32_t timeout_value;
uint32_t running_timeout;
struct mach_timebase_info timebase;
CFNetDiagnosticStatus retval = kCFNetDiagnosticConnectionDown;
kern_return_t err;
double conversion_factor;
CFStringRef pingTarget;
CFArrayRef nameServers;
CFIndex nameServerCount;
CFIndex i;
bool nameServerResponded;
//Get a timestamp
timestamp = mach_absolute_time();
err = mach_timebase_info(&timebase);
if(err == KERN_SUCCESS) {
conversion_factor = 1e-9 * (double)(timebase.numer) / (double)(timebase.denom);
retval = CFNetDiagnosticCopyNetworkStatusPassively(details, description);
if (retval != kCFNetDiagnosticConnectionUp) {
if (CFNumberGetValue(timeout, kCFNumberIntType, &timeout_value)) {
//Get current time remaining
running_timeout = timeout_value - conversion_factor * (mach_absolute_time() - timestamp);
pingTarget = copyCurrentRouter();
if (pingTarget) {
if(_CFNetDiagnosticPing(pingTarget, 1, running_timeout)) {
CFRelease(pingTarget);
retval = kCFNetDiagnosticConnectionDown;
if (description) {
*description = CFCopyLocalizedStringFromTableInBundle( CFSTR("ROUTER_DOWN"),
NULL,
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.CFNetwork")),
"This computer's router is not responding.");
}
} else {
CFRelease(pingTarget);
nameServers = copyCurrentDNSServers();
if (nameServers) {
nameServerCount = CFArrayGetCount(nameServers);
//Get current time remaining
running_timeout = ((timeout_value - conversion_factor * (mach_absolute_time() - timestamp)) / nameServerCount);
//ping a nameserver
nameServerResponded = false;
for (i=0; i < nameServerCount; i++) {
pingTarget = CFArrayGetValueAtIndex(nameServers, i);
if (!nameServerResponded) {
if(!_CFNetDiagnosticPing(pingTarget, 1, running_timeout)) {
nameServerResponded = true;
}
}
}
CFRelease(nameServers);
if (!nameServerResponded) {
retval = kCFNetDiagnosticConnectionDown;
if (description) {
*description = CFCopyLocalizedStringFromTableInBundle( CFSTR("NAMESERVER_DOWN"),
NULL,
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.CFNetwork")),
"This computer's DNS server is not responding.");
}
} else {
//Get current time remaining
running_timeout = timeout_value - conversion_factor * (mach_absolute_time() - timestamp);
//Server router
pingTarget = CFDictionaryGetValue((CFDictionaryRef)details, _CFNetDiagnosticRemoteHostKey);
if(pingTarget) {
if (_CFNetDiagnosticPing(pingTarget, 1, running_timeout)) {
retval = kCFNetDiagnosticConnectionDown;
if (description) {
*description = CFCopyLocalizedStringFromTableInBundle( CFSTR("SERVER_DOWN"),
NULL,
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.CFNetwork")),
"The server this computer is attempting to connect to is not responding.");
}
} else {
retval = kCFNetDiagnosticConnectionUp;
if (description) {
*description = CFCopyLocalizedStringFromTableInBundle( CFSTR("SERVER_UP"),
NULL,
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.CFNetwork")),
"This computer's Internet connection appears ot be online.");
}
}
}
}
}
}
}
}
}
}
//FIXME
return retval;
}
static
Boolean _CFNetDiagnosticIsLinkLocal (CFStringRef s)
{
char buffer[16];
Boolean converted;
Boolean retval = 0;
uint32_t addr;
converted = CFStringGetCString(s, buffer, 16, kCFStringEncodingASCII);
if(converted) {
addr = inet_addr(buffer);
if(addr == INADDR_NONE) {
retval = 0;
} else {
retval = IN_LINKLOCAL(ntohl(addr));
}
}
return retval;
}
//_CFNetDiagnosticCopyNetworkStatusPassivelyInterfaceSpecific is where the meat of CFNetDiagnosticCopyNetworkStatusPassively is implemented
static
CFNetDiagnosticStatus _CFNetDiagnosticCopyNetworkStatusPassivelyInterfaceSpecific(SCDynamicStoreRef store, CFStringRef serviceID, CFStringRef *description) {
CFDictionaryRef dict = NULL;
CFNetDiagnosticStatus retval;
// CFStringRef name;
CFStringRef device = NULL;
// CFStringRef hardware;
// Boolean isDialup = 0;
CFArrayRef addresses = NULL;
CFTypeRef address = NULL;
Boolean isLinkActive = 0;
Boolean isConnected = 0;
Boolean isLinkLocal = 0;
//First we get basic Information about the device
dict = _CFNetDiagnosticsGetDataFromSCDSAndThowAwayGarbage(NULL, store, SCDynamicStoreKeyCreateNetworkServiceEntity,
kSCDynamicStoreDomainSetup, serviceID, kSCEntNetInterface);
if(dict) {
// name = _CFNetDiagnosticGetValueFromDictionaryAndRetain(dict, kSCPropUserDefinedName);
device = (CFStringRef)_CFNetDiagnosticGetValueFromDictionaryAndRetain(dict, kSCPropNetInterfaceDeviceName);
// hardware = _CFNetDiagnosticGetValueFromDictionaryAndRetain(dict, kSCPropNetInterfaceHardware);
// isDialup = CFEqual(kSCValNetInterfaceTypePPP, CFDictionaryGetValue(dict, kSCPropNetInterfaceType));
CFRelease(dict);
}
//Now we find out if the link is active
if(device) {
dict = _CFNetDiagnosticsGetDataFromSCDSAndThowAwayGarbage(NULL, store, SCDynamicStoreKeyCreateNetworkInterfaceEntity,
kSCDynamicStoreDomainState, device, kSCEntNetLink);
if(dict) {
CFBooleanRef linkActive = CFDictionaryGetValue(dict, kSCPropNetLinkActive);
CFBooleanRef linkDetaching = CFDictionaryGetValue(dict, kSCPropNetLinkDetaching);
if (linkActive) {
isLinkActive = CFBooleanGetValue(linkActive);
} else if (linkDetaching) {
isLinkActive = !CFBooleanGetValue(linkDetaching);
} else {
isLinkActive = true;
}
CFRelease( (CFDictionaryRef) dict );
}
CFRelease(device);
}
//Now we find out if the link is connected
dict = _CFNetDiagnosticsGetDataFromSCDSAndThowAwayGarbage(NULL, store, SCDynamicStoreKeyCreateNetworkServiceEntity,
kSCDynamicStoreDomainState, serviceID, kSCEntNetIPv4);
if(dict) {
isConnected = 1;
addresses = CFDictionaryGetValue(dict, kSCPropNetIPv4Addresses);
if(CFArrayGetCount(addresses) > 0) {
address = CFArrayGetValueAtIndex(addresses, 0);
}
if(address) {
isLinkLocal = _CFNetDiagnosticIsLinkLocal(address);
}
CFRelease( (CFDictionaryRef) dict );
}
if(isLinkActive && isConnected) {
if(isLinkLocal) {
retval = kCFNetDiagnosticConnectionIndeterminate;
} else {
retval = kCFNetDiagnosticConnectionUp;
}
} else {
retval = kCFNetDiagnosticConnectionDown;
}
return retval;
}
CFNetDiagnosticStatus CFNetDiagnosticCopyNetworkStatusPassively(CFNetDiagnosticRef details, CFStringRef *description) {
CFMutableDictionaryRef detailsDict = (CFMutableDictionaryRef)details;
CFNetDiagnosticStatus retval = kCFNetDiagnosticConnectionIndeterminate;
CFStringRef serviceID;
SCDynamicStoreRef store;
store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("CFNetDiagnostics"), NULL, NULL);
if(store) {
serviceID = CFDictionaryGetValue(detailsDict, _CFNetDiagnosticServiceIDKey);
if(serviceID) {
//If there is a specific ServiceID we only scan on it. We can only get in this position through SPIs
retval = _CFNetDiagnosticCopyNetworkStatusPassivelyInterfaceSpecific(store, serviceID, description);
} else {
//Iterate through all serviceIDs. If any are good, then we return it
CFStringRef pattern = NULL;
CFDictionaryRef dict = NULL;
CFArrayRef serviceOrder = NULL;
CFIndex i, count;
CFNetDiagnosticStatus serviceState = kCFNetDiagnosticConnectionDown;
pattern = SCDynamicStoreKeyCreateNetworkGlobalEntity( NULL,
(CFStringRef) kSCDynamicStoreDomainSetup,
(CFStringRef) kSCEntNetIPv4 );
if(pattern) {
dict = SCDynamicStoreCopyValue( store, pattern );
CFRelease( pattern );
}
if(dict) {
serviceOrder = CFDictionaryGetValue(dict, CFSTR("ServiceOrder"));
CFRetain(serviceOrder);
CFRelease(dict);
}
if(serviceOrder) {
count = CFArrayGetCount(serviceOrder);
retval = kCFNetDiagnosticConnectionDown;
for ( i = 0; i < count; i++ ) {
serviceID = CFArrayGetValueAtIndex(serviceOrder, i);
serviceState = _CFNetDiagnosticCopyNetworkStatusPassivelyInterfaceSpecific(store, serviceID, description);
if(serviceState == kCFNetDiagnosticConnectionDown) {
retval = kCFNetDiagnosticConnectionDown;
if (description) {
*description = CFCopyLocalizedStringFromTableInBundle( CFSTR("CONNECTION_DOWN"),
NULL,
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.CFNetwork")),
"This computer's Internet connect appears to be offline.");
}
} else if (serviceState == kCFNetDiagnosticConnectionIndeterminate) {
retval = kCFNetDiagnosticConnectionIndeterminate;
if (description) {
*description = CFCopyLocalizedStringFromTableInBundle( CFSTR("CONNECTION_INDETERMINATE"),
NULL,
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.CFNetwork")),
"This computer's Internet may be offline.");
}
} else if (serviceState == kCFNetDiagnosticConnectionUp) {
retval = kCFNetDiagnosticConnectionUp;
if (description) {
*description = CFCopyLocalizedStringFromTableInBundle( CFSTR("CONNECTION_UP"),
NULL,
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.CFNetwork")),
"This computer's Internet may be online.");
}
break;
} else {
//FIXME
//NOT REACHED log an error
}
}
CFRelease(serviceOrder);
}
}
CFRelease(store);
}
return retval;
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* NetworkDiagnosticsInternal.h
* NetworkDiagnostics
*
* Created by Louis Gerbarg on Fri Apr 09 2004.
* Copyright 2004 __MyCompanyName__. All rights reserved.
*
*/
const name_t _CFNetDiagnosticMachPortName = "com.apple.NetworkDiagnostic.agent";
#define _CFNetDiagnosticMachProtocolVersion 1L
const CFStringRef _CFNetDiagnosticNameKey = CFSTR("NDNameKey");
const CFStringRef _CFNetDiagnosticBundleKey = CFSTR("NDBundleKey");
const CFStringRef _CFNetDiagnosticRemoteHostKey = CFSTR("NDRemoteHostKey");
const CFStringRef _CFNetDiagnosticProtocolKey = CFSTR("NDProtocolKey");
const CFStringRef _CFNetDiagnosticPortKey = CFSTR("NDPortKey");
const CFStringRef _CFNetDiagnosticServiceIDKey = CFSTR("NDServiceIDKey");
const CFStringRef _CFNetDiagnosticMethodKey = CFSTR("NDMethodKey");

View File

@ -0,0 +1,161 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef _CFNetDiagnosticsProtocol_user_
#define _CFNetDiagnosticsProtocol_user_
/* Module CFNetDiagnosticsProtocol */
#include <string.h>
#include <mach/ndr.h>
#include <mach/boolean.h>
#include <mach/kern_return.h>
#include <mach/notify.h>
#include <mach/mach_types.h>
#include <mach/message.h>
#include <mach/mig_errors.h>
#include <mach/port.h>
#ifdef AUTOTEST
#ifndef FUNCTION_PTR_T
#define FUNCTION_PTR_T
typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t);
typedef struct {
char *name;
function_ptr_t function;
} function_table_entry;
typedef function_table_entry *function_table_t;
#endif /* FUNCTION_PTR_T */
#endif /* AUTOTEST */
#ifndef CFNetDiagnosticsProtocol_MSG_COUNT
#define CFNetDiagnosticsProtocol_MSG_COUNT 1
#endif /* CFNetDiagnosticsProtocol_MSG_COUNT */
#include <mach/std_types.h>
#include <mach/mig.h>
#include <mach/mig.h>
#include <mach/mach_types.h>
#ifdef __BeforeMigUserHeader
__BeforeMigUserHeader
#endif /* __BeforeMigUserHeader */
#include <sys/cdefs.h>
__BEGIN_DECLS
/* SimpleRoutine passDescriptor */
#ifdef mig_external
mig_external
#else
extern
#endif /* mig_external */
kern_return_t _CFNetDiagnosticClient_passDescriptor
(
mach_port_t server_port,
int32_t protocol_version,
vm_address_t descriptor,
mach_msg_type_number_t descriptorCnt
);
__END_DECLS
/********************** Caution **************************/
/* The following data types should be used to calculate */
/* maximum message sizes only. The actual message may be */
/* smaller, and the position of the arguments within the */
/* message layout may vary from what is presented here. */
/* For example, if any of the arguments are variable- */
/* sized, and less than the maximum is sent, the data */
/* will be packed tight in the actual message to reduce */
/* the presence of holes. */
/********************** Caution **************************/
/* typedefs for all requests */
#ifndef __Request__CFNetDiagnosticsProtocol_subsystem__defined
#define __Request__CFNetDiagnosticsProtocol_subsystem__defined
#ifdef __MigPackStructs
#pragma pack(4)
#endif
typedef struct {
mach_msg_header_t Head;
/* start of the kernel processed data */
mach_msg_body_t msgh_body;
mach_msg_ool_descriptor_t descriptor;
/* end of the kernel processed data */
NDR_record_t NDR;
int32_t protocol_version;
mach_msg_type_number_t descriptorCnt;
} __Request__passDescriptor_t;
#ifdef __MigPackStructs
#pragma pack()
#endif
#endif /* !__Request__CFNetDiagnosticsProtocol_subsystem__defined */
/* union of all requests */
#ifndef __RequestUnion___CFNetDiagnosticClient_CFNetDiagnosticsProtocol_subsystem__defined
#define __RequestUnion___CFNetDiagnosticClient_CFNetDiagnosticsProtocol_subsystem__defined
union __RequestUnion___CFNetDiagnosticClient_CFNetDiagnosticsProtocol_subsystem {
__Request__passDescriptor_t Request__CFNetDiagnosticClient_passDescriptor;
};
#endif /* !__RequestUnion___CFNetDiagnosticClient_CFNetDiagnosticsProtocol_subsystem__defined */
/* typedefs for all replies */
#ifndef __Reply__CFNetDiagnosticsProtocol_subsystem__defined
#define __Reply__CFNetDiagnosticsProtocol_subsystem__defined
#ifdef __MigPackStructs
#pragma pack(4)
#endif
typedef struct {
mach_msg_header_t Head;
NDR_record_t NDR;
kern_return_t RetCode;
} __Reply__passDescriptor_t;
#ifdef __MigPackStructs
#pragma pack()
#endif
#endif /* !__Reply__CFNetDiagnosticsProtocol_subsystem__defined */
/* union of all replies */
#ifndef __ReplyUnion___CFNetDiagnosticClient_CFNetDiagnosticsProtocol_subsystem__defined
#define __ReplyUnion___CFNetDiagnosticClient_CFNetDiagnosticsProtocol_subsystem__defined
union __ReplyUnion___CFNetDiagnosticClient_CFNetDiagnosticsProtocol_subsystem {
__Reply__passDescriptor_t Reply__CFNetDiagnosticClient_passDescriptor;
};
#endif /* !__RequestUnion___CFNetDiagnosticClient_CFNetDiagnosticsProtocol_subsystem__defined */
#ifndef subsystem_to_name_map_CFNetDiagnosticsProtocol
#define subsystem_to_name_map_CFNetDiagnosticsProtocol \
{ "passDescriptor", 10000 }
#endif
#ifdef __AfterMigUserHeader
__AfterMigUserHeader
#endif /* __AfterMigUserHeader */
#endif /* _CFNetDiagnosticsProtocol_user_ */

View File

@ -0,0 +1,224 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* IDENTIFICATION:
* stub generated Wed Apr 27 10:45:38 2005
* with a MiG generated Sun Mar 20 14:22:13 PST 2005 by root@b05.apple.com
* OPTIONS:
*/
#define __MIG_check__Reply__CFNetDiagnosticsProtocol_subsystem__ 1
#define __NDR_convert__Reply__CFNetDiagnosticsProtocol_subsystem__ 1
#define __NDR_convert__mig_reply_error_subsystem__ 1
#include "CFNetDiagnosticsProtocol.h"
#ifndef mig_internal
#define mig_internal static __inline__
#endif /* mig_internal */
#ifndef mig_external
#define mig_external
#endif /* mig_external */
#if !defined(__MigTypeCheck) && defined(TypeCheck)
#define __MigTypeCheck TypeCheck /* Legacy setting */
#endif /* !defined(__MigTypeCheck) */
#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_)
#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */
#endif /* !defined(__MigKernelSpecificCode) */
#ifndef LimitCheck
#define LimitCheck 0
#endif /* LimitCheck */
#ifndef min
#define min(a,b) ( ((a) < (b))? (a): (b) )
#endif /* min */
#if !defined(_WALIGN_)
#define _WALIGN_(x) (((x) + 3) & ~3)
#endif /* !defined(_WALIGN_) */
#if !defined(_WALIGNSZ_)
#define _WALIGNSZ_(x) _WALIGN_(sizeof(x))
#endif /* !defined(_WALIGNSZ_) */
#ifndef UseStaticTemplates
#define UseStaticTemplates 0
#endif /* UseStaticTemplates */
#ifndef __MachMsgErrorWithTimeout
#define __MachMsgErrorWithTimeout(_R_) { \
switch (_R_) { \
case MACH_SEND_INVALID_REPLY: \
case MACH_RCV_INVALID_NAME: \
case MACH_RCV_PORT_DIED: \
case MACH_RCV_PORT_CHANGED: \
case MACH_RCV_TIMED_OUT: \
mig_dealloc_reply_port(InP->Head.msgh_reply_port); \
break; \
default: \
mig_put_reply_port(InP->Head.msgh_reply_port); \
} \
}
#endif /* __MachMsgErrorWithTimeout */
#ifndef __MachMsgErrorWithoutTimeout
#define __MachMsgErrorWithoutTimeout(_R_) { \
switch (_R_) { \
case MACH_SEND_INVALID_REPLY: \
case MACH_RCV_INVALID_NAME: \
case MACH_RCV_PORT_DIED: \
case MACH_RCV_PORT_CHANGED: \
mig_dealloc_reply_port(InP->Head.msgh_reply_port); \
break; \
default: \
mig_put_reply_port(InP->Head.msgh_reply_port); \
} \
}
#endif /* __MachMsgErrorWithoutTimeout */
#ifndef __DeclareSendRpc
#define __DeclareSendRpc(_NUM_, _NAME_)
#endif /* __DeclareSendRpc */
#ifndef __BeforeSendRpc
#define __BeforeSendRpc(_NUM_, _NAME_)
#endif /* __BeforeSendRpc */
#ifndef __AfterSendRpc
#define __AfterSendRpc(_NUM_, _NAME_)
#endif /* __AfterSendRpc */
#ifndef __DeclareSendSimple
#define __DeclareSendSimple(_NUM_, _NAME_)
#endif /* __DeclareSendSimple */
#ifndef __BeforeSendSimple
#define __BeforeSendSimple(_NUM_, _NAME_)
#endif /* __BeforeSendSimple */
#ifndef __AfterSendSimple
#define __AfterSendSimple(_NUM_, _NAME_)
#endif /* __AfterSendSimple */
#define msgh_request_port msgh_remote_port
#define msgh_reply_port msgh_local_port
/* SimpleRoutine passDescriptor */
mig_external kern_return_t _CFNetDiagnosticClient_passDescriptor
(
mach_port_t server_port,
int32_t protocol_version,
vm_address_t descriptor,
mach_msg_type_number_t descriptorCnt
)
{
{
#ifdef __MigPackStructs
#pragma pack(4)
#endif
typedef struct {
mach_msg_header_t Head;
/* start of the kernel processed data */
mach_msg_body_t msgh_body;
mach_msg_ool_descriptor_t descriptor;
/* end of the kernel processed data */
NDR_record_t NDR;
int32_t protocol_version;
mach_msg_type_number_t descriptorCnt;
} Request;
#ifdef __MigPackStructs
#pragma pack()
#endif
/*
* typedef struct {
* mach_msg_header_t Head;
* NDR_record_t NDR;
* kern_return_t RetCode;
* } mig_reply_error_t;
*/
union {
Request In;
} Mess;
Request *InP = &Mess.In;
mach_msg_return_t msg_result;
#ifdef __MIG_check__Reply__passDescriptor_t__defined
kern_return_t check_result;
#endif /* __MIG_check__Reply__passDescriptor_t__defined */
__DeclareSendSimple(10000, "passDescriptor")
#if UseStaticTemplates
const static mach_msg_ool_descriptor_t descriptorTemplate = {
/* addr = */ (void *)0,
/* size = */ 0,
/* deal = */ FALSE,
/* copy = */ MACH_MSG_VIRTUAL_COPY,
/* pad2 = */ 0,
/* type = */ MACH_MSG_OOL_DESCRIPTOR,
};
#endif /* UseStaticTemplates */
InP->msgh_body.msgh_descriptor_count = 1;
#if UseStaticTemplates
InP->descriptor = descriptorTemplate;
InP->descriptor.address = (void *)(descriptor);
InP->descriptor.size = descriptorCnt;
#else /* UseStaticTemplates */
InP->descriptor.address = (void *)(descriptor);
InP->descriptor.size = descriptorCnt;
InP->descriptor.deallocate = FALSE;
InP->descriptor.copy = MACH_MSG_VIRTUAL_COPY;
InP->descriptor.type = MACH_MSG_OOL_DESCRIPTOR;
#endif /* UseStaticTemplates */
InP->NDR = NDR_record;
InP->protocol_version = protocol_version;
InP->descriptorCnt = descriptorCnt;
InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX|
MACH_MSGH_BITS(19, 0);
/* msgh_size passed as argument */
InP->Head.msgh_request_port = server_port;
InP->Head.msgh_reply_port = MACH_PORT_NULL;
InP->Head.msgh_id = 10000;
__BeforeSendSimple(10000, "passDescriptor")
msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
__AfterSendSimple(10000, "passDescriptor")
return msg_result;
return KERN_SUCCESS;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,815 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CFNetServiceMonitor.c
* CFNetwork
*
* Created by Jeremy Wyld on Sun May 09 2004.
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
*
*/
#if 0
#pragma mark Includes
#endif
#include <CFNetwork/CFNetwork.h>
#include "CFNetworkInternal.h" // for __CFSpinLock and __CFSpinUnlock
#include "CFNetworkSchedule.h"
#include <dns_sd.h>
#include <nameser.h>
#if 0
#pragma mark -
#pragma mark Extern Function Declarations
#endif
extern Boolean _CFNetServiceSetInfoNoPublish(CFNetServiceRef theService, UInt32 property, CFTypeRef value);
#if 0
#pragma mark -
#pragma mark Constant Strings
#endif
#ifdef __CONSTANT_CFSTRINGS__
#define _kCFNetServiceMonitorBlockingMode CFSTR("_kCFNetServiceMonitorBlockingMode")
#else
static CONST_STRING_DECL(_kCFNetServiceMonitorBlockingMode, "_kCFNetServiceMonitorBlockingMode")
#endif /* __CONSTANT_CFSTRINGS__ */
static const char _kCFNetServiceMonitorClassName[] = "CFNetServiceMonitor";
#if 0
#pragma mark -
#pragma mark CFNetServiceMonitor struct
#endif
typedef struct {
CFRuntimeBase _base;
CFSpinLock_t _lock;
CFStreamError _error;
CFNetServiceRef _service;
CFTypeRef _trigger;
DNSServiceRef _monitor;
CFNetServiceMonitorType _type;
CFMutableArrayRef _schedules; // List of loops and modes
CFNetServiceMonitorClientCallBack _callback;
CFNetServiceClientContext _client;
} __CFNetServiceMonitor;
#if 0
#pragma mark -
#pragma mark Static Function Declarations
#endif
static void _CFNetServiceMonitorRegisterClass(void);
static void _MonitorDestroy(__CFNetServiceMonitor* monitor);
static void _MonitorCancel(__CFNetServiceMonitor* monitor);
static Boolean _MonitorBlockUntilComplete(__CFNetServiceMonitor* monitor);
static void _QueryRecordReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
DNSServiceErrorType errorCode, const char* fullname, uint16_t rrtype,
uint16_t rrclass, uint16_t rdlen, const void* rdata, uint32_t ttl, void* context);
static void _SocketCallBack(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info);
#if 0
#pragma mark -
#pragma mark Globals
#endif
static _CFOnceLock _kCFNetServiceMonitorRegisterClass = _CFOnceInitializer;
static CFTypeID _kCFNetServiceMonitorTypeID = _kCFRuntimeNotATypeID;
static CFRuntimeClass* _kCFNetServiceMonitorClass = NULL;
#if 0
#pragma mark -
#pragma mark Static Function Definitions
#endif
/* static */ void
_CFNetServiceMonitorRegisterClass(void) {
_kCFNetServiceMonitorClass = (CFRuntimeClass*)calloc(1, sizeof(_kCFNetServiceMonitorClass[0]));
if (_kCFNetServiceMonitorClass) {
_kCFNetServiceMonitorClass->version = 0;
_kCFNetServiceMonitorClass->className = _kCFNetServiceMonitorClassName;
_kCFNetServiceMonitorClass->finalize = (void(*)(CFTypeRef))_MonitorDestroy;
_kCFNetServiceMonitorTypeID = _CFRuntimeRegisterClass(_kCFNetServiceMonitorClass);
}
}
/* static */ void
_MonitorDestroy(__CFNetServiceMonitor* monitor) {
// Prevent anything else from taking hold
__CFSpinLock(&(monitor->_lock));
// Release the user's context info if there is some and a release method
if (monitor->_client.info && monitor->_client.release)
monitor->_client.release(monitor->_client.info);
// Cancel the outstanding trigger
if (monitor->_trigger) {
// Remove the trigger from run loops and modes
if (monitor->_schedules)
_CFTypeUnscheduleFromMultipleRunLoops(monitor->_trigger, monitor->_schedules);
// Go ahead and invalidate the trigger
_CFTypeInvalidate(monitor->_trigger);
// Release the monitor now.
CFRelease(monitor->_trigger);
}
// Need to clean up the service discovery stuff if there is
if (monitor->_monitor) {
// Release the underlying service discovery reference
DNSServiceRefDeallocate(monitor->_monitor);
}
/* Release the service if there is one */
if (monitor->_service) {
CFRelease(monitor->_service);
monitor->_service = NULL;
}
// Release the list of loops and modes
if (monitor->_schedules)
CFRelease(monitor->_schedules);
}
/* static */ void
_MonitorCancel(__CFNetServiceMonitor* monitor) {
CFNetServiceMonitorClientCallBack cb = NULL;
CFStreamError error;
void* info = NULL;
// Retain here to guarantee safety really after the monitor release,
// but definitely before the callback.
CFRetain(monitor);
// Lock the monitor
__CFSpinLock(&monitor->_lock);
// If the monitor canceled, don't need to do any of this.
if (monitor->_trigger) {
// Save the callback if there is one at this time.
cb = monitor->_callback;
// Save the error and client information for the callback
memmove(&error, &(monitor->_error), sizeof(error));
info = monitor->_client.info;
// Remove the trigger from run loops and modes
_CFTypeUnscheduleFromMultipleRunLoops(monitor->_trigger, monitor->_schedules);
// Invalidate the run loop source that got here
CFRunLoopSourceInvalidate((CFRunLoopSourceRef)(monitor->_trigger));
// Release the trigger now.
CFRelease(monitor->_trigger);
monitor->_trigger = NULL;
}
// Unlock the monitor so the callback can be made safely.
__CFSpinUnlock(&monitor->_lock);
// If there is a callback, inform the client of the finish.
if (cb)
cb((CFNetServiceMonitorRef)monitor, NULL, 0, NULL, &error, info);
// Go ahead and release now that the callback is done.
CFRelease(monitor);
}
/* static */ Boolean
_MonitorBlockUntilComplete(__CFNetServiceMonitor* monitor) {
// Assume success by default
Boolean result = TRUE;
CFRunLoopRef rl = CFRunLoopGetCurrent();
// Schedule in the blocking mode.
CFNetServiceMonitorScheduleWithRunLoop((CFNetServiceMonitorRef)monitor, rl, _kCFNetServiceMonitorBlockingMode);
// Lock in order to check for trigger
__CFSpinLock(&(monitor->_lock));
// Check that monitor exists.
while (monitor->_trigger) {
// Unlock again so the monitor can continue to be processed.
__CFSpinUnlock(&(monitor->_lock));
// Run the loop in a private mode with it returning whenever a source
// has been handled.
CFRunLoopRunInMode(_kCFNetServiceMonitorBlockingMode, DBL_MAX, TRUE);
// Lock again in preparation for trigger check
__CFSpinLock(&(monitor->_lock));
}
// Fail if there was an error.
if (monitor->_error.error)
result = FALSE;
// Unlock the monitor again.
__CFSpinUnlock(&(monitor->_lock));
// Unschedule from the blocking mode
CFNetServiceMonitorUnscheduleFromRunLoop((CFNetServiceMonitorRef)monitor, rl, _kCFNetServiceMonitorBlockingMode);
return result;
}
/* static */ void
_QueryRecordReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex,
DNSServiceErrorType errorCode, const char* fullname, uint16_t rrtype,
uint16_t rrclass, uint16_t rdlen, const void* rdata, uint32_t ttl, void* context)
{
__CFNetServiceMonitor* monitor = context;
CFNetServiceMonitorClientCallBack cb = NULL;
CFStreamError error;
void* info = NULL;
CFDataRef data = NULL;
CFNetServiceRef service = NULL;
CFNetServiceMonitorType type = 0;
// Retain here to guarantee safety really after the trigger release,
// but definitely before the callback.
CFRetain(monitor);
// Lock the monitor
__CFSpinLock(&monitor->_lock);
// If the monitor canceled, don't need to do any of this.
if (monitor->_monitor) {
service = (CFNetServiceRef)CFRetain(monitor->_service);
type = monitor->_type;
// If there is an error, fold the monitor.
if (errorCode) {
// Save the error
monitor->_error.error = _DNSServiceErrorToCFNetServiceError(errorCode);
monitor->_error.domain = kCFStreamErrorDomainNetServices;
// Remove the monitor from run loops and modes
_CFTypeUnscheduleFromMultipleRunLoops(monitor->_trigger, monitor->_schedules);
// Go ahead and invalidate the socket
CFSocketInvalidate((CFSocketRef)(monitor->_trigger));
// Release the monitor now.
CFRelease(monitor->_trigger);
monitor->_trigger = NULL;
// Clean up the underlying service discovery stuff
DNSServiceRefDeallocate(monitor->_monitor);
monitor->_monitor = NULL;
}
else if (rdata && (flags & kDNSServiceFlagsAdd)) {
data = CFDataCreate(CFGetAllocator(monitor), rdata, rdlen);
/* Update the service with the info */
_CFNetServiceSetInfoNoPublish(service, type, data);
}
cb = monitor->_callback;
// Save the error and client information for the callback
memmove(&error, &(monitor->_error), sizeof(error));
info = monitor->_client.info;
}
// Unlock the monitor so the callback can be made safely.
__CFSpinUnlock(&monitor->_lock);
// If there is a callback, inform the client of the finish.
if (cb && (flags & kDNSServiceFlagsAdd)) {
// Inform the client.
cb((CFNetServiceMonitorRef)monitor, service, type, data, &error, info);
}
// No longer need this after the callback
if (service)
CFRelease(service);
/* Release the data if it was created */
if (data)
CFRelease(data);
// Go ahead and release now that the callback is done.
CFRelease(monitor);
}
/* static */ void
_SocketCallBack(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void* data, void* info) {
DNSServiceErrorType err;
__CFNetServiceMonitor* monitor = info;
(void)s; // unused
(void)type; // unused
(void)address; // unused
(void)data; // unused
CFRetain(monitor);
// Dispatch to process the result
err = DNSServiceProcessResult(monitor->_monitor);
// If there was an error, need to infor the client.
if (err)
_QueryRecordReply(monitor->_monitor, 0, 0, err, NULL, 0, 0, 0, NULL, 0, info);
CFRelease(monitor);
}
#if 0
#pragma mark -
#pragma mark Extern Function Definitions (API)
#endif
/* CF_EXPORT */ CFTypeID
CFNetServiceMonitorGetTypeID(void) {
_CFDoOnce(&_kCFNetServiceMonitorRegisterClass, _CFNetServiceMonitorRegisterClass);
return _kCFNetServiceMonitorTypeID;
}
/* CF_EXPORT */ CFNetServiceMonitorRef
CFNetServiceMonitorCreate(CFAllocatorRef alloc, CFNetServiceRef theService, CFNetServiceMonitorClientCallBack clientCB, CFNetServiceClientContext* context) {
__CFNetServiceMonitor* result = NULL;
if (clientCB && context) {
CFTypeID class_type = CFNetServiceMonitorGetTypeID();
if (class_type != _kCFRuntimeNotATypeID) {
result = (__CFNetServiceMonitor*)_CFRuntimeCreateInstance(alloc,
class_type,
sizeof(result[0]) - sizeof(CFRuntimeBase),
NULL);
}
if (result) {
// Save a copy of the base so it's easier to zero the struct
CFRuntimeBase copy = result->_base;
// Clear everything.
memset(result, 0, sizeof(result[0]));
// Put back the base
memmove(&(result->_base), &copy, sizeof(result->_base));
// Save the client's callback
result->_callback = clientCB;
// Copy the client's context
memmove(&(result->_client), context, sizeof(result->_client));
// If there is user data and a retain method, call it.
if (result->_client.info && result->_client.retain)
result->_client.info = (void*)(result->_client.retain(result->_client.info));
// Create the list of loops and modes
result->_schedules = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks);
/* Need to save the service if successful */
if (result->_schedules)
result->_service = (CFNetServiceRef)CFRetain(theService);
// If any failed, need to release and return null
else {
CFRelease((CFTypeRef)result);
result = NULL;
}
}
}
return (CFNetServiceMonitorRef)result;
}
/* CF_EXPORT */ void
CFNetServiceMonitorInvalidate(CFNetServiceMonitorRef theMonitor) {
__CFNetServiceMonitor* monitor = (__CFNetServiceMonitor*)theMonitor;
// Lock the monitor
__CFSpinLock(&(monitor->_lock));
// Release the user's context info if there is some and a release method
if (monitor->_client.info && monitor->_client.release)
monitor->_client.release(monitor->_client.info);
// Cancel the outstanding trigger
if (monitor->_trigger) {
// Remove the trigger from run loops and modes
_CFTypeUnscheduleFromMultipleRunLoops(monitor->_trigger, monitor->_schedules);
// Go ahead and invalidate the trigger
_CFTypeInvalidate(monitor->_trigger);
// Release the monitor now.
CFRelease(monitor->_trigger);
monitor->_trigger = NULL;
}
// Need to clean up the service discovery stuff if there is
if (monitor->_monitor) {
// Release the underlying service discovery reference
DNSServiceRefDeallocate(monitor->_monitor);
monitor->_monitor = NULL;
}
/* No longer need the service, so release it. */
if (monitor->_service) {
CFRelease(monitor->_service);
monitor->_service = NULL;
}
// Zero out the callback and client context.
monitor->_callback = NULL;
memset(&(monitor->_client), 0, sizeof(monitor->_client));
// Unlock the monitor.
__CFSpinUnlock(&(monitor->_lock));
}
/* CF_EXPORT */ Boolean
CFNetServiceMonitorStart(CFNetServiceMonitorRef theMonitor, CFNetServiceMonitorType recordType, CFStreamError* error) {
__CFNetServiceMonitor* monitor = (__CFNetServiceMonitor*)theMonitor;
CFStreamError extra;
Boolean result = FALSE;
if (!error)
error = &extra;
memset(error, 0, sizeof(error[0]));
// Retain so it doesn't go away underneath in the case of a callout. This is really
// no worry for async, but makes the memmove for the error more difficult to place
// for synchronous without it being here.
CFRetain(monitor);
// Lock down the monitor to start monitor
__CFSpinLock(&(monitor->_lock));
do {
UInt16 rrtype = (recordType & 0x0000FFFF);
UInt16 rrclass = ((recordType & 0xFFFF0000) >> 16);
int i;
char properties[4][1024];
CFStringRef values[] = {
CFNetServiceGetDomain(monitor->_service),
CFNetServiceGetType(monitor->_service),
CFNetServiceGetName(monitor->_service)
};
CFSocketContext ctxt = {0, monitor, CFRetain, CFRelease, NULL};
if (!monitor->_callback) {
monitor->_error.error = kCFNetServicesErrorInvalid;
monitor->_error.domain = kCFStreamErrorDomainNetServices;
break;
}
// Check to see if there is an ongoing monitor already
if (monitor->_trigger) {
// If it's a mdns monitor, don't allow another.
if (CFGetTypeID(monitor->_trigger) == CFSocketGetTypeID()) {
monitor->_error.error = kCFNetServicesErrorInProgress;
monitor->_error.domain = kCFStreamErrorDomainNetServices;
break;
}
// It's just the cancel that hasn't fired yet, so cancel it.
else {
// Remove the trigger from run loops and modes
_CFTypeUnscheduleFromMultipleRunLoops(monitor->_trigger, monitor->_schedules);
// Invalidate the run loop source
CFRunLoopSourceInvalidate((CFRunLoopSourceRef)(monitor->_trigger));
// Release the trigger now.
CFRelease(monitor->_trigger);
monitor->_trigger = NULL;
}
}
/* If it's the TXT monitor type, set up rrtype and rrclass correctly. */
if (recordType == kCFNetServiceMonitorTXT) {
rrtype = ns_t_txt;
rrclass = ns_c_in;
}
/* Get the raw data for the properties to send down to mdns */
for (i = 0; i < 3; i++) {
CFIndex used;
CFStringGetBytes(values[i],
CFRangeMake(0, CFStringGetLength(values[i])),
kCFStringEncodingUTF8,
0,
FALSE,
(UInt8*)properties[i],
sizeof(properties[i]) - 1,
&used);
properties[i][used] = '\0';
}
DNSServiceConstructFullName(properties[3], properties[2], properties[1], properties[0]);
monitor->_type = recordType;
// Create the domain monitor at the service discovery level
monitor->_error.error = DNSServiceQueryRecord(&monitor->_monitor,
kDNSServiceFlagsLongLivedQuery,
0,
properties[3],
rrtype,
rrclass,
_QueryRecordReply,
monitor);
// Fail if it did.
if (monitor->_error.error) {
monitor->_error.error = _DNSServiceErrorToCFNetServiceError(monitor->_error.error);
monitor->_error.domain = kCFStreamErrorDomainNetServices;
break;
}
// Create the trigger for the monitor
monitor->_trigger = CFSocketCreateWithNative(CFGetAllocator(monitor),
DNSServiceRefSockFD(monitor->_monitor),
kCFSocketReadCallBack,
_SocketCallBack,
&ctxt);
// Make sure the CFSocket wrapper succeeded
if (!monitor->_trigger) {
// Try to use errno for the error
monitor->_error.error = errno;
// If it has no error in it, assume no memory
if (!monitor->_error.error)
monitor->_error.error = ENOMEM;
// Correct domain and bail.
monitor->_error.domain = kCFStreamErrorDomainPOSIX;
DNSServiceRefDeallocate(monitor->_monitor);
monitor->_monitor = NULL;
break;
}
// Tell CFSocket not to close the native socket on invalidation.
CFSocketSetSocketFlags((CFSocketRef)monitor->_trigger,
CFSocketGetSocketFlags((CFSocketRef)monitor->_trigger) & ~kCFSocketCloseOnInvalidate);
// Async mode is complete at this point
if (CFArrayGetCount(monitor->_schedules)) {
// Schedule the trigger on the run loops and modes.
_CFTypeScheduleOnMultipleRunLoops(monitor->_trigger, monitor->_schedules);
// It's now succeeded.
result = TRUE;
}
// If there is no callback, go into synchronous mode.
else {
// Unlock the monitor
__CFSpinUnlock(&(monitor->_lock));
// Wait for synchronous return
result = _MonitorBlockUntilComplete(monitor);
// Lock down the monitor
__CFSpinLock(&(monitor->_lock));
}
} while (0);
// Copy the error.
memmove(error, &monitor->_error, sizeof(error[0]));
// Unlock the monitor
__CFSpinUnlock(&(monitor->_lock));
// Release the earlier retain.
CFRelease(monitor);
return result;
}
/* CF_EXPORT */ void
CFNetServiceMonitorStop(CFNetServiceMonitorRef theMonitor, CFStreamError* error) {
__CFNetServiceMonitor* monitor = (__CFNetServiceMonitor*)theMonitor;
// By default, the error is marked as a cancel
CFStreamError extra = {kCFStreamErrorDomainNetServices , kCFNetServicesErrorCancel};
// Make sure error has a value.
if (!error)
error = &extra;
// Lock down the monitor
__CFSpinLock(&(monitor->_lock));
// Make sure there is something to cancel.
if (monitor->_trigger) {
CFRunLoopSourceContext ctxt = {
0, // version
monitor, // info
NULL, // retain
NULL, // release
NULL, // copyDescription
NULL, // equal
NULL, // hash
NULL, // schedule
NULL, // cancel
(void(*)(void*))(&_MonitorCancel) // perform
};
// Remove the trigger from run loops and modes
_CFTypeUnscheduleFromMultipleRunLoops(monitor->_trigger, monitor->_schedules);
// Go ahead and invalidate the trigger
_CFTypeInvalidate(monitor->_trigger);
// Release the trigger now.
CFRelease(monitor->_trigger);
// Need to clean up the service discovery stuff if there is
if (monitor->_monitor) {
// Release the underlying service discovery reference
DNSServiceRefDeallocate(monitor->_monitor);
monitor->_monitor = NULL;
}
// Copy the error into place
memmove(&(monitor->_error), error, sizeof(error[0]));
// Create the cancel source
monitor->_trigger = CFRunLoopSourceCreate(CFGetAllocator(monitor), 0, &ctxt);
// If the cancel was created, need to schedule and signal it.
if (monitor->_trigger) {
CFArrayRef schedules = monitor->_schedules;
CFIndex i, count = CFArrayGetCount(schedules);
// Schedule the new trigger
_CFTypeScheduleOnMultipleRunLoops(monitor->_trigger, schedules);
// Signal the cancel for immediate attention.
CFRunLoopSourceSignal((CFRunLoopSourceRef)(monitor->_trigger));
// Make sure the signal can make it through
for (i = 0; i < count; i += 2) {
// Grab the run loop for checking
CFRunLoopRef runloop = (CFRunLoopRef)CFArrayGetValueAtIndex(schedules, i);
// If it's sleeping, need to further check it.
if (CFRunLoopIsWaiting(runloop)) {
// Grab the mode for further check
CFStringRef mode = CFRunLoopCopyCurrentMode(runloop);
if (mode) {
// If the trigger is in the right mode, need to wake up the run loop.
if (CFRunLoopContainsSource(runloop, (CFRunLoopSourceRef)(monitor->_trigger), mode)) {
CFRunLoopWakeUp(runloop);
}
// Don't need this anymore.
CFRelease(mode);
}
}
}
}
}
// Unlock the monitor
__CFSpinUnlock(&(monitor->_lock));
}
/* CF_EXPORT */ void
CFNetServiceMonitorScheduleWithRunLoop(CFNetServiceMonitorRef theMonitor, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
__CFNetServiceMonitor* monitor = (__CFNetServiceMonitor*)theMonitor;
// Lock down the monitor before work
__CFSpinLock(&(monitor->_lock));
if (_SchedulesAddRunLoopAndMode(monitor->_schedules, runLoop, runLoopMode)) {
// If there is a current monitor, need to schedule it.
if (monitor->_trigger) {
_CFTypeScheduleOnRunLoop(monitor->_trigger, runLoop, runLoopMode);
}
}
// Unlock the monitor
__CFSpinUnlock(&(monitor->_lock));
}
/* CF_EXPORT */ void
CFNetServiceMonitorUnscheduleFromRunLoop(CFNetServiceMonitorRef theMonitor, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
__CFNetServiceMonitor* monitor = (__CFNetServiceMonitor*)theMonitor;
// Lock down the monitor before work
__CFSpinLock(&(monitor->_lock));
if (_SchedulesRemoveRunLoopAndMode(monitor->_schedules, runLoop, runLoopMode)) {
// If there is a current monitor, need to unschedule it.
if (monitor->_trigger) {
_CFTypeUnscheduleFromRunLoop(monitor->_trigger, runLoop, runLoopMode);
}
}
// Unlock the monitor
__CFSpinUnlock(&(monitor->_lock));
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* DeprecatedDNSServiceDiscovery.c
* CFNetwork
*
* Created by Jeremy Wyld on 12/15/04.
* Copyright 2004 Apple Computer, Inc. All rights reserved.
*
*/
#include "DeprecatedDNSServiceDiscovery.h"
dns_service_discovery_ref DNSServiceRegistrationCreate_Deprecated
(
const char *name,
const char *regtype,
const char *domain,
uint16_t port,
const char *txtRecord,
DNSServiceRegistrationReply callBack,
void *context
)
{
return DNSServiceRegistrationCreate(name, regtype, domain, port, txtRecord, callBack, context);
}
dns_service_discovery_ref DNSServiceResolverResolve_Deprecated
(
const char *name,
const char *regtype,
const char *domain,
DNSServiceResolverReply callBack,
void *context
)
{
return DNSServiceResolverResolve(name, regtype, domain, callBack, context);
}
mach_port_t DNSServiceDiscoveryMachPort_Deprecated(dns_service_discovery_ref dnsServiceDiscovery)
{
return DNSServiceDiscoveryMachPort(dnsServiceDiscovery);
}
void DNSServiceDiscoveryDeallocate_Deprecated(dns_service_discovery_ref dnsServiceDiscovery)
{
DNSServiceDiscoveryDeallocate( dnsServiceDiscovery);
}
DNSServiceRegistrationReplyErrorType DNSServiceRegistrationUpdateRecord_Deprecated(dns_service_discovery_ref ref, DNSRecordReference reference, uint16_t rdlen, const char *rdata, uint32_t ttl)
{
return DNSServiceRegistrationUpdateRecord(ref, reference, rdlen, rdata, ttl);
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* DeprecatedDNSServiceDiscovery.h
* CFNetwork
*
* Created by Jeremy Wyld on 12/15/04.
* Copyright 2004 Apple Computer, Inc. All rights reserved.
*
*/
#include "DNSServiceDiscovery.h"
dns_service_discovery_ref DNSServiceRegistrationCreate_Deprecated
(
const char *name,
const char *regtype,
const char *domain,
uint16_t port,
const char *txtRecord,
DNSServiceRegistrationReply callBack,
void *context
);
dns_service_discovery_ref DNSServiceResolverResolve_Deprecated
(
const char *name,
const char *regtype,
const char *domain,
DNSServiceResolverReply callBack,
void *context
);
mach_port_t DNSServiceDiscoveryMachPort_Deprecated(dns_service_discovery_ref dnsServiceDiscovery);
void DNSServiceDiscoveryDeallocate_Deprecated(dns_service_discovery_ref dnsServiceDiscovery);
DNSServiceRegistrationReplyErrorType DNSServiceRegistrationUpdateRecord_Deprecated(dns_service_discovery_ref ref, DNSRecordReference reference, uint16_t rdlen, const char *rdata, uint32_t ttl);

463
src/PACSupport.js Executable file
View File

@ -0,0 +1,463 @@
/*
File: PACSuppport.js
Contains: PAC Support functions
Copyright: © 2003-2004 by Apple Computer, Inc., all rights reserved
Bugs?: For bug reports, consult the following page on
the World Wide Web:
http://developer.apple.com/bugreporter/
*/
var __Apple_dsn_cache = new Array;
function isPlainHostName(host) {
return (host.indexOf('.') == -1 ? true : false);
}
function dnsDomainIs(host, domain) {
var h = host.toLowerCase();
var d = domain.toLowerCase();
var sub = h.substring(h.length - d.length, h.length);
if (sub == d)
return true;
return false;
}
function localHostOrDomainIs(host, hostdom) {
var h1 = host.toLowerCase();
var h2 = hostdom.toLowerCase();
return ((h1 == h2) || (isPlainHostName(h1) & !isPlainHostName(h2))) ? true : false;
}
function isResolvable(host) {
var ip = dnsResolve(host);
return ((typeof ip == "string") && ip.length) ? true : false;
}
function isInNet(host, pattern, mask) {
var ip = dnsResolve(host);
if (ip) {
var p = pattern.split('.');
var m = mask.split('.');
var a = ip.split('.');
if ((p.length == m.length) && (m.length == a.length)) {
for (i = 0; i < p.length; i++) {
if ((p[i]& m[i]) != (m[i]& a[i]))
return false;
}
return true;
}
}
return false;
}
function dnsResolve(host) {
var ips, i;
for (i = 0; i < __Apple_dsn_cache.length; i += 2) {
if (__Apple_dsn_cache[i] == host) {
ips = __Apple_dsn_cache[i + 1];
break;
}
}
if (i >= __Apple_dsn_cache.length) {
ips = __dnsResolve(host);
if (__Apple_dsn_cache.length == 20) {
__Apple_dsn_cache.pop();
__Apple_dsn_cache.pop();
}
__Apple_dsn_cache[__Apple_dsn_cache.length] = host;
__Apple_dsn_cache[__Apple_dsn_cache.length] = ips;
}
if (ips && ips.length) {
for (var i = 0; i < ips.length; i++) {
var bytes = ips[i].split('.');
if (bytes.length == 4)
return ips[i];
}
}
return null;
}
function myIpAddress() {
var primary = __primaryIPv4Addresses();
var ips = null;
if (primary && primary.length) {
ips = primary.Addresses;
}
if (ips && ips.length) {
for (var i = 0; i < ips.length; i++) {
var bytes = ips[i].split('.');
if (bytes.length == 4)
return ips[i];
}
}
return null;
}
function dnsDomainLevels(host) {
var parts = host.split('.');
return parts.length - 1;
}
function shExpMatch(str, shexp) {
if (typeof str != "string" || typeof shexp != "string")
return false;
if (shexp == "*")
return true;
if (str == "" && shexp == "")
return true;
str = str.toLowerCase();
shexp = shexp.toLowerCase();
var len = str.length;
var pieces = shexp.split('*');
var start = 0;
for (i = 0; i < pieces.length; i++) {
if (pieces[i] == "")
continue;
if (start > len)
return false;
start = str.indexOf(pieces[i]);
if (start == -1)
return false;
start += pieces[i].length;
str = str.substring(start, len);
len = str.length;
}
i--;
if ((pieces[i] == "") || (str == ""))
return true;
return false;
}
function weekdayRange(wd1, wd2, gmt) {
var today = new Date();
var days = "SUNMONTUEWEDTHUFRISAT";
wd1 = wd1.toUpperCase();
if (wd2 == undefined)
wd2 = wd1;
else
wd2 = wd2.toUpperCase();
var d1 = days.indexOf(wd1);
var d2 = days.indexOf(wd2);
if ((d2 == -1) && (wd2 == "GMT")) {
gmt = wd2;
d2 = d1;
}
if ((d1 == -1) || (d2 == -1))
return false;
d1 = d1 / 3;
d2 = d2 / 3;
if (gmt == "GMT")
today = today.getUTCDay();
else
today = today.getDay();
if ((d1 <= d2) && (today >= d1) && (today <= d2))
return true;
if ((d2 < d1) && ((today <= d2) || (today >= d1)))
return true;
return false;
}
function dateRange() {
var today = new Date();
var num = arguments.length;
var gmt = arguments[num - 1];
if (typeof gmt != "string")
gmt = false;
else {
gmt = gmt.toUpperCase();
if (gmt != "GMT")
gmt = false;
else {
gmt = true;
num--;
}
}
if (!num || (num > 6))
return false;
var d1 = 0;
var d2 = 0;
var m1 = 0;
var m2 = 0;
var y1 = 0;
var y2 = 0;
for (i = 0; i < num; i++) {
var arg = arguments[i];
if (typeof arg == "number") {
if (arg > 31) {
if (!y1)
y1 = arg;
else if (!y2)
y2 = arg;
else
return false;
}
else if (!arg)
return false;
else if (!d1)
d1 = arg;
else if (!d2)
d2 = arg;
else
return false;
}
else if (typeof arg == "string") {
var months = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
arg = arg.toUpperCase();
arg = months.indexOf(arg);
if (arg == -1)
return false;
arg /= 3;
arg += 1;
if (!m1)
m1 = arg;
else if (!m2)
m2 = arg;
else
return false;
}
else
return false;
}
if (!y1) y1 = gmt ? today.getUTCFullYear() : today.getFullYear();
if (!y2) y2 = y1;
if (!m1) m1 = (gmt ? today.getUTCMonth() : today.getMonth()) + 1;
if (!m2) m2 = m1;
if (!d1) d1 = gmt ? today.getUTCDate() : today.getDate();
if (!d2) d2 = d1;
var date1;
var date2;
if (gmt) {
date1 = Date.UTC(y1, m1 - 1, d1, 0, 0, 0, 0);
date2 = Date.UTC(y2, m2 - 1, d2, 23, 59, 59, 999);
}
else {
date1 = (Date(y1, m1 - 1, d1, 0, 0, 0, 0)).valueOf();
date2 = (Date(y2, m2 - 1, d2, 23, 59, 59, 999)).valueOf();
}
today = today.valueOf();
return ((date1 <= today) && (today <= date2));
}
function timeRange() {
var date1 = new Date();
var today = new Date();
var date2 = new Date();
var num = arguments.length;
var gmt = arguments[num - 1];
if (typeof gmt != "string")
gmt = false;
else {
gmt = gmt.toUpperCase();
if (gmt != "GMT")
gmt = false;
else {
gmt = true;
num--;
}
}
if (!num || (num > 6) || ((num % 2) && (num != 1)))
return false;
date1.setMinutes(0);
date1.setSeconds(0);
date1.setMilliseconds(0);
date2.setMinutes(59);
date2.setSeconds(59);
date2.setMilliseconds(999);
for (i = 0; i < (num / 2); i++) {
var arg = arguments[i];
if (gmt) {
switch (i) {
case 0:
date1.setUTCHours(arg);
date2.setUTCHours(arg);
break;
case 1:
date1.setUTCMinutes(arg);
date2.setUTCMinutes(arg);
break;
case 2:
date1.setUTCSeconds(arg);
date2.setUTCSeconds(arg);
break;
}
}
else {
switch (i) {
case 0:
date1.setHours(arg);
date2.setHours(arg);
break;
case 1:
date1.setMinutes(arg);
date2.setMinutes(arg);
break;
case 2:
date1.setSeconds(arg);
date2.setSeconds(arg);
break;
}
}
}
if (num != 1) {
date2.setMinutes(0);
date2.setSeconds(0);
date2.setMilliseconds(0);
for (i = 0; i < (num / 2); i++) {
var arg = arguments[(num / 2) + i];
if (gmt) {
switch (i) {
case 0:
date2.setUTCHours(arg);
break;
case 1:
date2.setUTCMinutes(arg);
break;
case 2:
date2.setUTCSeconds(arg);
break;
}
}
else {
switch (i) {
case 0:
date2.setHours(arg);
break;
case 1:
date2.setMinutes(arg);
break;
case 2:
date2.setSeconds(arg);
break;
}
}
}
}
today = today.valueOf();
date1 = date1.valueOf();
date2 = date2.valueOf();
if (date2 < date1)
date2 += 86400000;
return ((date1 <= today) && (today <= date2));
}
function __Apple_FindProxyForURL(host, url) {
__Apple_dsn_cache = new Array;
var result = FindProxyForURL(host, url);
__Apple_dsn_cache = new Array;
return result;
}

2260
src/Proxies/ProxySupport.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* ProxySupport.h
* CFNetwork
*
* Created by Jeremy Wyld on 11/4/04.
* Copyright 2004 Apple Computer, Inc. All rights reserved.
*
*/
#ifndef __PROXYSUPPORT__
#define __PROXYSUPPORT__
#include <CFNetwork/CFNetwork.h>
#if defined(__cplusplus)
extern "C" {
#endif
/*!
@function _CFNetworkCFHostDoesNeedProxy
@discussion Given a host with a name or an address check to see
if it matches anything in the bypass list. This performs
wildcard matches along with straight comparisons. Address
resolutions and reverse lookups are not performed. In addition if localBypass
is true, names without periods are treated as not needing the proxy.
@param host A CFHostRef representing the host which is to be checked.
Must be non-NULL. If this If this reference is not a valid
CFHostRef, the behavior is undefined.
@param bypasses A CFArrayRef of CFStringRef's indicating host
names which should be bypassed (not use the proxy). The
exception list in the SystemConfiguration proxy dictionary
can be used directly.
@param localBypass A CFBooleanRefindicating "local" hosts do not need the proxy.
@result If a match for the host is not found, TRUE is returned.
If a match is not found, FALSE is returned.
*/
// Currently not used, so hand dead-stripping for now.
//extern Boolean _CFNetworkCFHostDoesNeedProxy(CFHostRef host, CFArrayRef bypasses, CFBooleanRef localBypass);
/*!
@function _CFNetworkDoesNeedProxy
@discussion Given a host name check to see if it matches anything
in the bypass list. This performs wildcard matches along with
straight comparisons. Address resolutions and reverse lookups
are not performed. In addition if localBypass
is true, names without periods are treated as not needing the proxy.
@param host A CFHostRef representing the host which is to be checked.
Must be non-NULL. If this If this reference is not a valid
CFHostRef, the behavior is undefined.
@param bypasses A CFArrayRef of CFStringRef's indicating host
names which should be bypassed (not use the proxy). The
exception list in the SystemConfiguration proxy dictionary
can be used directly.
@param localBypass A CFBooleanRefindicating "local" hosts do not need the proxy.
@result If a match for the host is not found, TRUE is returned.
If a match is not found, FALSE is returned.
*/
extern Boolean _CFNetworkDoesNeedProxy(CFStringRef hostname, CFArrayRef bypasses, CFBooleanRef localBypass);
#if defined(__cplusplus)
}
#endif
#endif /* __PROXYSUPPORT__ */

91
src/SharedCode/CFError.c Normal file
View File

@ -0,0 +1,91 @@
//
// CFError.c
// CFNetwork
//
// Copyright (c) 2014 Apportable. All rights reserved.
//
#include <CoreFoundation/CFError.h>
#include "CFHost.h"
#include "CFHTTPStream.h"
#include "CFFTPStream.h"
#include "CFHTTPAuthentication.h"
#include "CFNetServices.h"
#include "CFSocketStream.h"
#include "CFNetworkInternal.h"
static const CFStringRef CFStreamErrorDomainPOSIX = CFSTR("POSIX");
static const CFStringRef CFStreamErrorDomainFTP = CFSTR("FTP");
static const CFStringRef CFStreamErrorDomainNetDB = CFSTR("NetDB");
static const CFStringRef CFStreamErrorDomainSystemConfiguration = CFSTR("SystemConfiguration");
static const CFStringRef CFStreamErrorDomainHTTP = CFSTR("HTTP");
static const CFStringRef CFStreamErrorDomainMach = CFSTR("Mach");
static const CFStringRef CFStreamErrorDomainNetServices = CFSTR("NetServices");
static const CFStringRef CFStreamErrorDomainSOCKS = CFSTR("SOCKS");
static const CFStringRef CFStreamErrorDomainSSL = CFSTR("SSL");
static const CFStringRef CFStreamErrorDomainMacOSStatus = CFSTR("MacOSStatus");
static const CFStringRef CFStreamErrorDomainCustom = CFSTR("Custom");
extern CFErrorRef _CFErrorCreateWithStreamError(CFAllocatorRef allocator, CFStreamError *err);
CFErrorRef _CFErrorCreateWithStreamError(CFAllocatorRef allocator, CFStreamError *err) {
CFStringRef domain = NULL;
if (err->domain == kCFStreamErrorDomainPOSIX) {
domain = CFStreamErrorDomainPOSIX;
} else if (err->domain == kCFStreamErrorDomainFTP) {
domain = CFStreamErrorDomainFTP;
} else if (err->domain == kCFStreamErrorDomainNetDB) {
domain = CFStreamErrorDomainNetDB;
} else if (err->domain == kCFStreamErrorDomainSystemConfiguration) {
domain = CFStreamErrorDomainSystemConfiguration;
} else if (err->domain == kCFStreamErrorDomainHTTP) {
domain = CFStreamErrorDomainHTTP;
} else if (err->domain == kCFStreamErrorDomainMach) {
domain = CFStreamErrorDomainMach;
} else if (err->domain == kCFStreamErrorDomainNetServices) {
domain = CFStreamErrorDomainNetServices;
} else if (err->domain == kCFStreamErrorDomainSOCKS) {
domain = CFStreamErrorDomainSOCKS;
} else if (err->domain == kCFStreamErrorDomainSSL) {
domain = CFStreamErrorDomainSSL;
} else if (err->domain == kCFStreamErrorDomainMacOSStatus) {
domain = CFStreamErrorDomainMacOSStatus;
} else if (err->domain == kCFStreamErrorDomainCustom) {
domain = CFStreamErrorDomainCustom;
} else {
domain = CFSTR("Unknown");
}
return CFErrorCreate(allocator, domain, err->error, NULL);
}
extern CFStreamError _CFStreamErrorFromCFError(CFErrorRef err);
CFStreamError _CFStreamErrorFromCFError(CFErrorRef err) {
CFStreamError error = { 0, 0 };
error.error = CFErrorGetCode(err);
CFStringRef domain = CFErrorGetDomain(err);
if (CFStringCompare(domain, CFStreamErrorDomainPOSIX, 0)) {
error.domain = kCFStreamErrorDomainPOSIX;
} else if (CFStringCompare(domain, CFStreamErrorDomainFTP, 0)) {
error.domain = kCFStreamErrorDomainFTP;
} else if (CFStringCompare(domain, CFStreamErrorDomainNetDB, 0)) {
error.domain = kCFStreamErrorDomainNetDB;
} else if (CFStringCompare(domain, CFStreamErrorDomainSystemConfiguration, 0)) {
error.domain = kCFStreamErrorDomainSystemConfiguration;
} else if (CFStringCompare(domain, CFStreamErrorDomainHTTP, 0)) {
error.domain = kCFStreamErrorDomainHTTP;
} else if (CFStringCompare(domain, CFStreamErrorDomainMach, 0)) {
error.domain = kCFStreamErrorDomainMach;
} else if (CFStringCompare(domain, CFStreamErrorDomainNetServices, 0)) {
error.domain = kCFStreamErrorDomainNetServices;
} else if (CFStringCompare(domain, CFStreamErrorDomainSOCKS, 0)) {
error.domain = kCFStreamErrorDomainSOCKS;
} else if (CFStringCompare(domain, CFStreamErrorDomainSSL, 0)) {
error.domain = kCFStreamErrorDomainSSL;
} else if (CFStringCompare(domain, CFStreamErrorDomainMacOSStatus, 0)) {
error.domain = kCFStreamErrorDomainMacOSStatus;
} else if (CFStringCompare(domain, CFStreamErrorDomainCustom, 0)) {
error.domain = kCFStreamErrorDomainCustom;
}
return error;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,400 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#if !defined(__CFNETWORK_CFCONNECTION__)
#define __CFNETWORK_CFCONNECTION__ 1
#include <CFNetwork/CFNetwork.h>
#include "CFNetworkInternal.h"
#include "CFStreamAbstract.h"
#include <CFNetwork/CFSocketStream.h>
#include "CFRuntime.h"
#include <sys/types.h>
#include <AvailabilityMacros.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* _CFNetConnectionRef
*
* Discussion:
* This is the type of a reference to a net connection. A
* CFNetConnection maintains a pair of streams on which a queue of
* requests are serviced. A given net connection request represents
* a request and response pair.
*/
typedef struct __CFNetConnection* _CFNetConnectionRef;
/*
* _CFNetConnectionState
*
* Discussion:
* Indicators of state for individual requests and responses on a
* CFNetConnection.
*/
enum _CFNetConnectionState {
/*
* Request or response is not in the queue
*/
kNotQueued = 0,
/*
* Request or response is in the queue
*/
kQueued = 1,
/*
* Request is in the process of sending
*/
kTransmittingRequest = 2,
/*
* Request has been sent but the response hasn't started to arrive
*/
kWaitingForResponse = 3,
/*
* Response is in the process of being received
*/
kReceivingResponse = 4,
/*
* Request has been transmitted and the response has been received.
* The request is now complete.
*/
kFinished = 5,
/*
* Request has been cancelled and removed from the queue.
*/
kCancelled = 6,
/*
* Something has happened with the connection such that the given
* queued request has now been dropped from the queue. The user
* should now requeue the request on a new net connection.
*/
kOrphaned = 7
};
typedef enum _CFNetConnectionState _CFNetConnectionState;
typedef CALLBACK_API_C( const void *, _CFNetConnectionCreateCallBack )(CFAllocatorRef alloc, const void *info);
typedef CALLBACK_API_C( void , _CFNetConnectionFinalizeCallBack )(CFAllocatorRef alloc, const void *info);
typedef CALLBACK_API_C( CFStreamError , _CFNetConnectionCreateStreamsCallBack )(CFAllocatorRef allocator, const void *info, CFWriteStreamRef *requestStream, CFReadStreamRef *responseStream);
typedef CALLBACK_API_C( void , _CFNetConnectionStateChangedCallBack )(void *request, int newState, CFStreamError *err, _CFNetConnectionRef connection, const void *info);
typedef CALLBACK_API_C( void , _CFNetConnectionTransmitRequest )(void *request, _CFNetConnectionRef connection, const void *info);
typedef CALLBACK_API_C( void , _CFNetConnectionReceiveResponse )(void *request, _CFNetConnectionRef connection, const void *info);
typedef CALLBACK_API_C( void , _CFNetConnectionResponseStreamCallBack )(void *request, CFReadStreamRef stream, CFStreamEventType eventType, _CFNetConnectionRef conn, const void *info);
typedef CALLBACK_API_C( void , _CFNetConnectionRequestStreamCallBack )(void *request, CFWriteStreamRef stream, CFStreamEventType eventType, _CFNetConnectionRef conn, const void *info);
typedef CALLBACK_API_C( CFArrayRef , _CFNetConnectionRunLoopArrayCallBack )(void *request, _CFNetConnectionRef conn, const void *info);
struct _CFNetConnectionCallBacks {
CFIndex version;
_CFNetConnectionCreateCallBack create;
_CFNetConnectionFinalizeCallBack finalize;
_CFNetConnectionCreateStreamsCallBack createConnectionStreams;
_CFNetConnectionStateChangedCallBack requestStateChanged;
_CFNetConnectionTransmitRequest transmitRequest;
_CFNetConnectionReceiveResponse receiveResponse;
_CFNetConnectionResponseStreamCallBack responseStreamCallBack;
_CFNetConnectionRequestStreamCallBack requestStreamCallBack;
_CFNetConnectionRunLoopArrayCallBack runLoopAndModesArrayForRequest;
};
typedef struct _CFNetConnectionCallBacks _CFNetConnectionCallBacks;
/* Net connection*/
/*
* _CFNetConnectionGetTypeID()
*
*/
extern CFTypeID
_CFNetConnectionGetTypeID(void) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFNetConnectionGetInfoPointer()
*
*/
extern const void *
_CFNetConnectionGetInfoPointer(_CFNetConnectionRef conn) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/* Create and return a new connection object*/
/*
* _CFNetConnectionCreate()
* Note - in 10.3, this function did not take the isThreadSafe argument; that was added for 10.4
*
*/
extern _CFNetConnectionRef
_CFNetConnectionCreate(
CFAllocatorRef alloc,
const void * info,
const _CFNetConnectionCallBacks * callBacks,
Boolean isThreadSafe) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
/* Enqueues req on conn's transmission queue. If this is the first such request, this will cause the connection to open streams to the server*/
/*
* _CFNetConnectionEnqueue()
*
*/
extern Boolean
_CFNetConnectionEnqueue(
_CFNetConnectionRef conn,
void * req) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/* Cancel an enqueued request; this will cause the connection to in all ways "forget" the request. Returns FALSE if the request is currently mid-transmission, in which case the connection cannot safely remove the request.*/
/*
* _CFNetConnectionDequeue()
*
*/
extern Boolean
_CFNetConnectionDequeue(
_CFNetConnectionRef conn,
void * req) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFNetConnectionGetCurrentRequest()
*
* Discussion:
* Returns the head queued request or NULL if there is nothing
* queued.
*
* Mac OS X threading:
* Not thread safe
*
* Parameters:
*
* conn:
* The connection to query for the head request.
*
* Result:
* Returns a pointer to the head request if there is one, otherwise
* it returns NULL.
*
*/
extern void *
_CFNetConnectionGetCurrentRequest(_CFNetConnectionRef conn) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/* Replaces oldReq with newReq in the connection's queue.*/
/*
* _CFNetConnectionReplaceRequest()
*
*/
extern void
_CFNetConnectionReplaceRequest(
_CFNetConnectionRef conn,
void * oldReq,
void * newReq) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/* Returns the response streams*/
/*
* _CFNetConnectionGetResponseStream()
*
*/
extern CFReadStreamRef
_CFNetConnectionGetResponseStream(_CFNetConnectionRef conn) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/* Returns the request streams*/
/*
* _CFNetConnectionGetRequestStream()
*
*/
extern CFWriteStreamRef
_CFNetConnectionGetRequestStream(_CFNetConnectionRef conn) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/* Informs the connection that the given request considers its response complete, and the connection should break its connection to the request and advance to the next response*/
/*
* _CFNetConnectionResponseIsComplete()
*
*/
extern void
_CFNetConnectionResponseIsComplete(
_CFNetConnectionRef conn,
void * req) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/* Informs the connection that the given request considers its request complete (i.e. fully transmitted), and the connection should advance to the next request to be transmitted*/
/*
* _CFNetConnectionRequestIsComplete()
*
*/
extern void
_CFNetConnectionRequestIsComplete(
_CFNetConnectionRef conn,
void * req) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/* Error out the connection with the given error. All queued requests will be orphaned.*/
/*
* _CFNetConnectionErrorOccurred()
*
*/
extern void
_CFNetConnectionErrorOccurred(
_CFNetConnectionRef conn,
CFStreamError * err) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/* Announces that the persistent connection has been lost; all responses after the current one must be orphaned*/
/*
* _CFNetConnectionLost()
*
*/
extern void
_CFNetConnectionLost(_CFNetConnectionRef conn) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/* Set whether requests will be transmitted without waiting for previous responses*/
/*
* _CFNetConnectionSetShouldPipeline()
*
*/
extern void
_CFNetConnectionSetShouldPipeline(
_CFNetConnectionRef conn,
Boolean shouldPipeline) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
extern CFAbsoluteTime
_CFNetConnectionGetLastAccessTime(_CFNetConnectionRef arg);
extern int
_CFNetConnectionGetQueueDepth(_CFNetConnectionRef conn);
/*
* _CFNetConnectionSetAllowsNewRequests()
*
*/
extern void
_CFNetConnectionSetAllowsNewRequests(
_CFNetConnectionRef conn,
Boolean allowRequests) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/*
* _CFNetConnectionWillEnqueueRequests()
*
*/
extern Boolean
_CFNetConnectionWillEnqueueRequests(_CFNetConnectionRef conn) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/* Gets the connection's current opinion about the request's state. If advanceConnection is TRUE, calling this will cause the connection to attempt to further the state of its queue, and may cause calls back in to the request. If the connection knows nothing about the request, it will return kOrphaned, and the calling request should forget any tie to this connection*/
/*
* _CFNetConnectionGetState()
*
*/
extern int
_CFNetConnectionGetState(
_CFNetConnectionRef conn,
Boolean advanceConnection,
void * req) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/* Informs the connection that the given request has been scheduled and asks the connection to take any appropriate action*/
/*
* _CFNetConnectionSchedule()
*
*/
extern void
_CFNetConnectionSchedule(
_CFNetConnectionRef conn,
void * req,
CFRunLoopRef rl,
CFStringRef mode) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/* Informs the connection that the given request has been unscheduled, and asks the connection to take any appropriate action*/
/*
* _CFNetConnectionUnschedule()
*
*/
extern void
_CFNetConnectionUnschedule(
_CFNetConnectionRef conn,
void * req,
CFRunLoopRef rl,
CFStringRef mode) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
/* Informs the connection that the given request has been unscheduled, and asks the connection to take any appropriate action*/
/*
* _CFNetConnectionIsEmpty()
*
*/
extern Boolean
_CFNetConnectionIsEmpty(_CFNetConnectionRef conn) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
// Currently not used, so hand dead-stripping for now.
//extern Boolean
//_CFNetConnectionIsPipelining(_CFNetConnectionRef arg);
typedef struct __CFNetConnectionCache * CFNetConnectionCacheRef;
typedef struct __CFNetConnectionCacheKey* _CFNetConnectionCacheKey;
//
// Net connection cache
//
CFNetConnectionCacheRef createConnectionCache();
#if defined(__WIN32__)
void releaseConnectionCache(CFNetConnectionCacheRef cache);
#endif /* defined(__WIN32__) */
void lockConnectionCache(CFNetConnectionCacheRef cache);
void unlockConnectionCache(CFNetConnectionCacheRef cache);
extern
_CFNetConnectionRef findOrCreateNetConnection(CFNetConnectionCacheRef connectionCache, CFAllocatorRef allocator, const _CFNetConnectionCallBacks *callbacks, const void *info, _CFNetConnectionCacheKey key, Boolean persistent, CFDictionaryRef connectionProperties); // This routine ties the two objects (connection cache & connection)
extern
void removeFromConnectionCache(CFNetConnectionCacheRef cache, _CFNetConnectionRef conn, _CFNetConnectionCacheKey key);
// These two callbacks are shared across protocols
const void *connCacheKeyRetain(CFAllocatorRef allocator, const void *value);
void connCacheKeyRelease(CFAllocatorRef allocator, const void *value);
//
// Net connection cache key
//
_CFNetConnectionCacheKey createConnectionCacheKey(CFStringRef host, SInt32 port, UInt32 connType, CFDictionaryRef properties);
void releaseConnectionCacheKey(_CFNetConnectionCacheKey theKey);
void getValuesFromKey(const _CFNetConnectionCacheKey theKey, CFStringRef *host, SInt32 *port, UInt32 *connType, CFDictionaryRef *properties);
#ifdef DEBUG
void printKey(_CFNetConnectionCacheKey key);
#endif /* DEBUG */
#if defined(__cplusplus)
}
#endif
#endif /* ! __CFNETWORK_CFNETCONNECTION__ */

View File

@ -0,0 +1,528 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CFNetworkSchedule.c
* CFNetwork
*
* Created by Jeremy Wyld on Sat May 01 2004.
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
*
*/
#include "CFNetworkSchedule.h"
#include <CFNetwork/CFNetwork.h>
#include <SystemConfiguration/SystemConfiguration.h>
#include <CoreFoundation/CFMachPort.h>
/* extern */ void
_CFTypeScheduleOnRunLoop(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
CFTypeID t = CFGetTypeID(obj);
CFTypeRef src = NULL;
void(*fn)(CFTypeRef, CFRunLoopRef, CFStringRef);
void(*fn2)(CFRunLoopRef, CFTypeRef, CFStringRef);
fn = NULL;
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopAddSource;
/* Get the correct source or function used for adding the object to the run loop. */
if (t == CFRunLoopSourceGetTypeID()) {
src = CFRetain(obj);
}
else if (t == CFMachPortGetTypeID()) {
src = CFMachPortCreateRunLoopSource(CFGetAllocator(obj), (CFMachPortRef)obj, 0);
}
else if (t == CFSocketGetTypeID()) {
src = CFSocketCreateRunLoopSource(CFGetAllocator(obj), (CFSocketRef)obj, 0);
}
else if (t == CFReadStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFReadStreamScheduleWithRunLoop;
}
else if (t == CFWriteStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFWriteStreamScheduleWithRunLoop;
}
else if (t == CFHostGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFHostScheduleWithRunLoop;
}
else if (t == SCNetworkReachabilityGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkReachabilityScheduleWithRunLoop;
}
else if (t == CFRunLoopTimerGetTypeID()) {
src = CFRetain(obj);
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopAddTimer;
}
#if NETSERVICE_SUPPORT
else if (t == CFNetServiceGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceScheduleWithRunLoop;
}
else if (t == CFNetServiceBrowserGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceBrowserScheduleWithRunLoop;
}
else if (t == CFNetServiceMonitorGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceMonitorScheduleWithRunLoop;
}
#endif
else if (t == SCNetworkConnectionGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkConnectionScheduleWithRunLoop;
}
/* If a source was retrieved, need to add the source */
if (src) {
fn2(runLoop, src, runLoopMode);
CFRelease(src);
}
/* If a schedule function was retrieved, call it. */
else if (fn) {
fn(obj, runLoop, runLoopMode);
}
}
/* extern */ void
_CFTypeUnscheduleFromRunLoop(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
CFTypeID t = CFGetTypeID(obj);
CFTypeRef src = NULL;
void(*fn)(CFTypeRef, CFRunLoopRef, CFStringRef);
void(*fn2)(CFRunLoopRef, CFTypeRef, CFStringRef);
fn = NULL;
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveSource;
/* Get the proper source or function for removing the object from the run loop. */
if (t == CFRunLoopSourceGetTypeID()) {
src = CFRetain(obj);
}
else if (t == CFMachPortGetTypeID()) {
src = CFMachPortCreateRunLoopSource(CFGetAllocator(obj), (CFMachPortRef)obj, 0);
}
else if (t == CFSocketGetTypeID()) {
src = CFSocketCreateRunLoopSource(CFGetAllocator(obj), (CFSocketRef)obj, 0);
}
else if (t == CFReadStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFReadStreamUnscheduleFromRunLoop;
}
else if (t == CFWriteStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFWriteStreamUnscheduleFromRunLoop;
}
else if (t == CFHostGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFHostUnscheduleFromRunLoop;
}
else if (t == SCNetworkReachabilityGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkReachabilityUnscheduleFromRunLoop;
}
else if (t == CFRunLoopTimerGetTypeID()) {
src = CFRetain(obj);
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveTimer;
}
#if NETSERVICE_SUPPORT
else if (t == CFNetServiceGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceUnscheduleFromRunLoop;
}
else if (t == CFNetServiceBrowserGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceBrowserUnscheduleFromRunLoop;
}
else if (t == CFNetServiceMonitorGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceMonitorUnscheduleFromRunLoop;
}
#endif
else if (t == SCNetworkConnectionGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkConnectionUnscheduleFromRunLoop;
}
/* If a source was retrieved, need to remove it */
if (src) {
fn2(runLoop, src, runLoopMode);
CFRelease(src);
}
/* If an unschedule function was retrieved, need to call it. */
else if (fn) {
fn(obj, runLoop, runLoopMode);
}
}
/* extern */ void
_CFTypeScheduleOnMultipleRunLoops(CFTypeRef obj, CFArrayRef schedules) {
CFTypeID t = CFGetTypeID(obj);
CFTypeRef src = NULL;
void(*fn)(CFTypeRef, CFRunLoopRef, CFStringRef);
void(*fn2)(CFRunLoopRef, CFTypeRef, CFStringRef);
fn = NULL;
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopAddSource;
/* Get the correct source or function used for adding the object to the run loop. */
if (t == CFRunLoopSourceGetTypeID()) {
src = CFRetain(obj);
}
else if (t == CFRunLoopTimerGetTypeID()) {
src = CFRetain(obj);
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopAddTimer;
}
else if (t == CFMachPortGetTypeID()) {
src = CFMachPortCreateRunLoopSource(CFGetAllocator(obj), (CFMachPortRef)obj, 0);
}
else if (t == CFSocketGetTypeID()) {
src = CFSocketCreateRunLoopSource(CFGetAllocator(obj), (CFSocketRef)obj, 0);
}
else if (t == CFReadStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFReadStreamScheduleWithRunLoop;
}
else if (t == CFWriteStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFWriteStreamScheduleWithRunLoop;
}
else if (t == CFHostGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFHostScheduleWithRunLoop;
}
#if NETSERVICE_SUPPORT
else if (t == CFNetServiceGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceScheduleWithRunLoop;
}
else if (t == CFNetServiceBrowserGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceBrowserScheduleWithRunLoop;
}
else if (t == CFNetServiceMonitorGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceMonitorScheduleWithRunLoop;
}
#endif
else if (t == SCNetworkReachabilityGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkReachabilityScheduleWithRunLoop;
}
else if (t == SCNetworkConnectionGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkConnectionScheduleWithRunLoop;
}
/* If a source was retrieved, need to add the source to the list of run loops */
if (src) {
CFIndex i, length = CFArrayGetCount(schedules);
for (i = 0; i < length; i += 2) {
fn2((CFRunLoopRef)CFArrayGetValueAtIndex(schedules, i),
src,
(CFStringRef)CFArrayGetValueAtIndex(schedules, i + 1));
}
CFRelease(src);
}
/* If a schedule function was retrieved, call it for each schedule in the list. */
else if (fn) {
CFIndex i, length = CFArrayGetCount(schedules);
for (i = 0; i < length; i += 2) {
fn(obj,
(CFRunLoopRef)CFArrayGetValueAtIndex(schedules, i),
(CFStringRef)CFArrayGetValueAtIndex(schedules, i + 1));
}
}
}
/* extern */ void
_CFTypeUnscheduleFromMultipleRunLoops(CFTypeRef obj, CFArrayRef schedules) {
CFTypeID t = CFGetTypeID(obj);
CFTypeRef src = NULL;
void(*fn)(CFTypeRef, CFRunLoopRef, CFStringRef);
void(*fn2)(CFRunLoopRef, CFTypeRef, CFStringRef);
fn = NULL;
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveSource;
/* Get the proper source or function for removing the object from the run loop. */
if (t == CFRunLoopSourceGetTypeID()) {
src = CFRetain(obj);
}
else if (t == CFMachPortGetTypeID()) {
src = CFMachPortCreateRunLoopSource(CFGetAllocator(obj), (CFMachPortRef)obj, 0);
}
else if (t == CFSocketGetTypeID()) {
src = CFSocketCreateRunLoopSource(CFGetAllocator(obj), (CFSocketRef)obj, 0);
}
else if (t == CFReadStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFReadStreamUnscheduleFromRunLoop;
}
else if (t == CFWriteStreamGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFWriteStreamUnscheduleFromRunLoop;
}
else if (t == CFHostGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFHostUnscheduleFromRunLoop;
}
else if (t == SCNetworkReachabilityGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkReachabilityUnscheduleFromRunLoop;
}
else if (t == CFRunLoopTimerGetTypeID()) {
src = CFRetain(obj);
fn2 = (void(*)(CFRunLoopRef, CFTypeRef, CFStringRef))CFRunLoopRemoveTimer;
}
#if NETSERVICE_SUPPORT
else if (t == CFNetServiceGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceUnscheduleFromRunLoop;
}
else if (t == CFNetServiceBrowserGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceBrowserUnscheduleFromRunLoop;
}
else if (t == CFNetServiceMonitorGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))CFNetServiceMonitorUnscheduleFromRunLoop;
}
#endif
else if (t == SCNetworkConnectionGetTypeID()) {
fn = (void(*)(CFTypeRef, CFRunLoopRef, CFStringRef))SCNetworkConnectionUnscheduleFromRunLoop;
}
/* If a source was retrieved, need to remove it from the list of run loops*/
if (src) {
CFIndex i, length = CFArrayGetCount(schedules);
for (i = 0; i < length; i += 2) {
fn2((CFRunLoopRef)CFArrayGetValueAtIndex(schedules, i),
src,
(CFStringRef)CFArrayGetValueAtIndex(schedules, i + 1));
}
CFRelease(src);
}
/* If an unschedule function was retrieved, need to call it for each schedule in the list. */
else if (fn) {
CFIndex i, length = CFArrayGetCount(schedules);
for (i = 0; i < length; i += 2) {
fn(obj,
(CFRunLoopRef)CFArrayGetValueAtIndex(schedules, i),
(CFStringRef)CFArrayGetValueAtIndex(schedules, i + 1));
}
}
}
/* extern */ void
_CFTypeInvalidate(CFTypeRef obj) {
CFTypeID t = CFGetTypeID(obj);
/* Invalidate according to type of object. */
if (t == CFRunLoopSourceGetTypeID()) {
CFRunLoopSourceInvalidate((CFRunLoopSourceRef)obj);
}
else if (t == CFMachPortGetTypeID()) {
CFMachPortInvalidate((CFMachPortRef)obj);
}
else if (t == CFSocketGetTypeID()) {
CFSocketInvalidate((CFSocketRef)obj);
}
/* For scheduled types of objects, it is invalidated by setting the client to NULL. */
else if (t == CFReadStreamGetTypeID()) {
CFReadStreamSetClient((CFReadStreamRef)obj, kCFStreamEventNone, NULL, NULL);
}
else if (t == CFWriteStreamGetTypeID()) {
CFWriteStreamSetClient((CFWriteStreamRef)obj, kCFStreamEventNone, NULL, NULL);
}
else if (t == CFHostGetTypeID()) {
CFHostSetClient((CFHostRef)obj, NULL, NULL);
}
else if (t == SCNetworkReachabilityGetTypeID()) {
SCNetworkReachabilitySetCallback((SCNetworkReachabilityRef)obj, NULL, NULL);
}
else if (t == CFRunLoopTimerGetTypeID()) {
CFRunLoopTimerInvalidate((CFRunLoopTimerRef)obj);
}
#if NETSERVICE_SUPPORT
else if (t == CFNetServiceGetTypeID()) {
CFNetServiceSetClient((CFNetServiceRef)obj, NULL, NULL);
}
else if (t == CFNetServiceBrowserGetTypeID()) {
CFNetServiceBrowserInvalidate((CFNetServiceBrowserRef)obj);
}
else if (t == CFNetServiceMonitorGetTypeID()) {
CFNetServiceMonitorInvalidate((CFNetServiceMonitorRef)obj);
}
#endif
else if (t == SCNetworkReachabilityGetTypeID()) {
SCNetworkConnectionStop((SCNetworkConnectionRef)obj, FALSE);
}
}
/* extern */ Boolean
_SchedulesAddRunLoopAndMode(CFMutableArrayRef schedules, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
/* Get the number of items in schedules and create a range for searching */
CFIndex count = CFArrayGetCount(schedules);
CFRange range = CFRangeMake(0, count);
/* Go through the list looking for this schedule */
while (range.length) {
/* Find the run loop in the list */
CFIndex i = CFArrayGetFirstIndexOfValue(schedules, range, runLoop);
/* If the loop wasn't found, then this has never been scheduled on this loop and mode */
if (i == kCFNotFound)
break;
/* If the mode is the same, this is already scheduled here so bail */
if (CFEqual(CFArrayGetValueAtIndex(schedules, i + 1), runLoopMode)) {
/* Did not add the pair to the list */
return FALSE;
}
/* Continue looking from here */
range.location = i + 2;
range.length = count - range.location;
}
/* Schedule wasn't found, so add it to the list. */
CFArrayAppendValue(schedules, runLoop);
CFArrayAppendValue(schedules, runLoopMode);
/* Did add the pair to the list */
return TRUE;
}
/* extern */ Boolean
_SchedulesRemoveRunLoopAndMode(CFMutableArrayRef schedules, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
/* Get the number of items in schedules and create a range for searching */
CFIndex count = CFArrayGetCount(schedules);
CFRange range = CFRangeMake(0, count);
/* Go through the list looking for this schedule */
while (range.length) {
/* Find the run loop in the list */
CFIndex i = CFArrayGetFirstIndexOfValue(schedules, range, runLoop);
/* If the loop wasn't found, then this pair was never added. */
if (i == kCFNotFound)
break;
/* If the mode is the same, this is already scheduled here so bail */
if (CFEqual(CFArrayGetValueAtIndex(schedules, i + 1), runLoopMode)) {
/* Remove the schedule from the list */
range.location = i;
range.length = 2;
CFArrayReplaceValues(schedules, range, NULL, 0);
/* Did remove the schedule from the list */
return TRUE;
}
/* Continue looking from here */
range.location = i + 2;
range.length = count - range.location;
}
/* Did not remove the schedule from the list */
return FALSE;
}
/* extern */ CFIndex
_SchedulesFind(CFArrayRef schedules, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
/* Get the number of items in schedules and create a range for searching */
CFIndex count = CFArrayGetCount(schedules);
CFRange range = CFRangeMake(0, count);
/* Go through the list looking for this schedule */
while (range.length) {
/* Find the run loop in the list */
CFIndex i = CFArrayGetFirstIndexOfValue(schedules, range, runLoop);
/* If the loop wasn't found, then this pair was never added. */
if (i == kCFNotFound)
break;
/* If the mode is the same, found it */
if (CFEqual(CFArrayGetValueAtIndex(schedules, i + 1), runLoopMode))
return i;
/* Continue looking from here */
range.location = i + 2;
range.length = count - range.location;
}
/* Did not find the schedule in the list */
return kCFNotFound;
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CFNetworkSchedule.h
* CFNetwork
*
* Created by Jeremy Wyld on Sat May 01 2004.
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
*
*/
#ifndef __CFNETWORKSCHEDULE__
#define __CFNETWORKSCHEDULE__
#ifndef __COREFOUNDATION__
#include <CoreFoundation/CoreFoundation.h>
#endif
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* Currently does not handle CFRunLoopObserverRef or _CFNetConnectionRef.
*/
void _CFTypeScheduleOnRunLoop(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode);
void _CFTypeUnscheduleFromRunLoop(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode);
void _CFTypeScheduleOnMultipleRunLoops(CFTypeRef obj, CFArrayRef schedules);
void _CFTypeUnscheduleFromMultipleRunLoops(CFTypeRef obj, CFArrayRef schedules);
void _CFTypeInvalidate(CFTypeRef obj);
/*
* Return if the run loop and mode were added to the list or removed from the list, respectively.
*/
Boolean _SchedulesAddRunLoopAndMode(CFMutableArrayRef schedules, CFRunLoopRef runLoop, CFStringRef runLoopMode);
Boolean _SchedulesRemoveRunLoopAndMode(CFMutableArrayRef schedules, CFRunLoopRef runLoop, CFStringRef runLoopMode);
/*
* Find the given run loop and mode in the list of schedules. kCFNotFound returned if not found.
*/
CFIndex _SchedulesFind(CFArrayRef schedules, CFRunLoopRef runLoop, CFStringRef runLoopMode);
#ifdef __cplusplus
}
#endif
#endif /* __CFNETWORKSCHEDULE__ */

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CFNetworkThreadSupport.c
* CFNetwork
*
* Created by Jeremy Wyld on 11/4/04.
* Copyright 2004 __MyCompanyName__. All rights reserved.
*
*/
#include "CFNetworkThreadSupport.h"
#ifdef __WIN32__
#include <process.h>
#endif /* __WIN32__ */
#if !defined(__WIN32__)
extern void _CFMutexInit(_CFMutex *lock, Boolean recursive) {
if (recursive) {
pthread_mutexattr_t attrs;
pthread_mutexattr_init(&attrs);
pthread_mutexattr_settype(&attrs, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(lock, &attrs);
} else
pthread_mutex_init(lock, NULL);
}
#else
// Cribbed from CFUtilities.c
struct _args {
void *func;
void *arg;
HANDLE handle;
};
static __stdcall unsigned __CFWinThreadFunc(void *arg) {
struct _args *args = arg;
((void (*)(void *))args->func)(args->arg);
CloseHandle(args->handle);
CFAllocatorDeallocate(kCFAllocatorSystemDefault, arg);
_endthreadex(0);
return 0;
}
extern int _CFThreadSpawn(_CFThread *thread, void *(*func)(void *), void *arg) {
unsigned tid;
struct _args *args = CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(struct _args), 0);
args->func = func;
args->arg = arg;
/* The thread is created suspended, because otherwise there would be a race between the assignment below of the handle field, and it's possible use in the thread func above. */
unsigned long fauxHandle = _beginthreadex(NULL, 0, __CFWinThreadFunc, args, CREATE_SUSPENDED, &tid);
args->handle = (HANDLE)fauxHandle;
*thread = args->handle;
ResumeThread(*thread);
return *thread != 0;
}
#endif

View File

@ -0,0 +1,184 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CFNetworkThreadSupport.h
* CFNetwork
*
* Created by Jeremy Wyld on 11/4/04.
* Copyright 2004 Apple Computer, Inc. All rights reserved.
*
*/
#ifndef __CFNETWORKTHREADSUPPORT__
#define __CFNETWORKTHREADSUPPORT__
#include <CoreFoundation/CoreFoundation.h> /* for CF_INLINE */
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(__MACH__) || defined(APPORTABLE)
#include <libkern/OSAtomic.h>
#include <pthread.h> // For spin_lock stuff below
#include <unistd.h>
typedef OSSpinLock CFSpinLock_t;
extern int _spin_lock_try(CFSpinLock_t *lockp);
extern void _spin_unlock(CFSpinLock_t *lockp);
extern int nanosleep(const struct timespec *, struct timespec *);
CF_INLINE Boolean __CFSpinTryLock(CFSpinLock_t *lockp) {
return(OSSpinLockTry(lockp));
}
CF_INLINE void __CFSpinLock(CFSpinLock_t *lockp) {
OSSpinLockLock(lockp);
}
CF_INLINE void __CFSpinUnlock(CFSpinLock_t *lockp) {
OSSpinLockUnlock(lockp);
}
#elif defined(__WIN32__)
typedef LONG CFSpinLock_t;
CF_INLINE Boolean __CFSpinTryLock(CFSpinLock_t *slock) {
return InterlockedExchange(slock, 1) == 0;
}
CF_INLINE void __CFSpinLock(CFSpinLock_t *slock) {
while (InterlockedExchange(slock, 1) != 0) {
Sleep(1); // 1ms
}
}
CF_INLINE void __CFSpinUnlock(CFSpinLock_t *lock) {
*lock = 0;
}
#else
#warning CF spin locks not defined for this platform -- CF is not thread-safe
#define __CFSpinLock(A) do {} while (0)
#define __CFSpinUnlock(A) do {} while (0)
#endif
/*
* Insulation layer over mutex locks and simple threads
*/
#if !defined(__WIN32__)
typedef pthread_mutex_t _CFMutex;
CF_INLINE void _CFMutexLock(_CFMutex *lock) {
pthread_mutex_lock(lock);
}
CF_INLINE Boolean _CFMutexTryLock(_CFMutex *lock) {
return pthread_mutex_trylock(lock) == 0;
}
CF_INLINE void _CFMutexUnlock(_CFMutex *lock) {
pthread_mutex_unlock(lock);
}
extern void _CFMutexInit(_CFMutex *lock, Boolean recursive);
CF_INLINE void _CFMutexDestroy(_CFMutex *lock) {
pthread_mutex_destroy(lock);
}
typedef pthread_once_t _CFOnceLock;
#define _CFOnceInitializer PTHREAD_ONCE_INIT
CF_INLINE void _CFDoOnce(_CFOnceLock *lock, void (*func)(void)) {
pthread_once(lock, func);
}
typedef pthread_t _CFThread;
CF_INLINE int _CFThreadSpawn(_CFThread *thread, void *(*func)(void *), void *arg) {
return pthread_create(thread, NULL, func, arg);
}
#else // __WIN32__
typedef CRITICAL_SECTION _CFMutex;
CF_INLINE void _CFMutexLock(_CFMutex *lock) {
EnterCriticalSection(lock);
}
CF_INLINE Boolean _CFMutexTryLock(_CFMutex *lock) {
return TryEnterCriticalSection(lock) != 0;
}
CF_INLINE void _CFMutexUnlock(_CFMutex *lock) {
LeaveCriticalSection(lock);
}
CF_INLINE void _CFMutexInit(_CFMutex *lock, Boolean recursive) {
// critical sections are always recursive on Win32
InitializeCriticalSection(lock);
}
CF_INLINE void _CFMutexDestroy(_CFMutex *lock) {
DeleteCriticalSection(lock);
}
typedef struct {
CFSpinLock_t lock;
UInt32 state;
} _CFOnceLock;
#define _CFOnceInitializer { 0, 0 }
CF_INLINE void _CFDoOnce(_CFOnceLock *once, void (*func)(void)) {
__CFSpinLock(&once->lock);
if (once->state == 0) {
(*func)();
once->state = 1;
}
__CFSpinUnlock(&once->lock);
}
typedef HANDLE _CFThread;
extern int _CFThreadSpawn(_CFThread *thread, void *(*func)(void *), void *arg);
#endif // __WIN32__
#if defined(__cplusplus)
}
#endif
#endif /* __CFNETWORKTHREADSUPPORT__ */

618
src/SharedCode/CFServer.c Normal file
View File

@ -0,0 +1,618 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* CFServer.c
* CFNetwork
*
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
*
*/
#pragma mark Includes
#include "CFServerPriv.h"
#include "CFRuntime.h"
#include <CFNetwork/CFNetwork.h>
#include <assert.h>
#if defined(__WIN32__)
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif
#if 0
#pragma mark -
#pragma mark Constant Strings
#endif
#ifdef __CONSTANT_CFSTRINGS__
#define _kCFServerNULL CFSTR("0x0")
#define _kCFServerPtrFormat CFSTR("<0x%x>")
#define _kCFServerDescribeFormat CFSTR("<Server 0x%x>{sockets=[%@, %@], service=%@, info=%@}")
#define _kCFServerEmptyString CFSTR("")
#else
static CONST_STRING_DECL(_kCFServerNULL, "0x0")
static CONST_STRING_DECL(_kCFServerPtrFormat, "<0x%x>")
static CONST_STRING_DECL(_kCFServerDescribeFormat, "<Server 0x%x>{sockets=[%@, %@], service=%@, info=%@}")
static CONST_STRING_DECL(_kCFServerEmptyString, "")
#endif /* __CONSTANT_CFSTRINGS__ */
#pragma mark -
#pragma mark Type Declarations
typedef struct {
CFRuntimeBase _base; // CFRuntimeBase for CF types
CFSocketRef _sockets[2]; // Server sockets listening for connections
CFStringRef _name; // Name that is being registered
CFStringRef _type; // Service type that is being registered
UInt32 _port; // Port being serviced
CFNetServiceRef _service; // Registered service on the network
_CFServerCallBack _callback; // User's callback function
_CFServerContext _ctxt; // User's context info
} Server;
#pragma mark -
#pragma mark Constant Definitions
#pragma mark -
#pragma mark Static Function Declarations
static void _ServerRelease(_CFServerRef server);
CFStringRef _ServerCopyDescription(_CFServerRef server);
static void _ServerReleaseSocket(Server* server);
static void _ServerHandleAccept(Server* server, CFSocketNativeHandle nativeSocket);
static void _SocketCallBack(CFSocketRef sock, CFSocketCallBackType type, CFDataRef address, const void *data, Server* server);
#if defined(__MACH__)
static void _ServerReleaseNetService(Server* server);
static Boolean _ServerCreateAndRegisterNetService(Server* server);
static void _ServerHandleNetServiceError(Server* server, CFStreamError* error);
static void _NetServiceCallBack(CFNetServiceRef service, CFStreamError* error, Server* server);
#endif
#pragma mark -
#pragma mark Static Variable Definitions
static CFTypeID _ServerTypeId = _kCFRuntimeNotATypeID;
#pragma mark -
#pragma mark Extern Function Definitions (API)
/* CF_EXPORT */ CFTypeID
_CFServerGetTypeID(void) {
if (_ServerTypeId == _kCFRuntimeNotATypeID) {
static const CFRuntimeClass ServerClass = {
0, // version
"_CFServer", // class name
NULL, // init
NULL, // copy
(void(*)(CFTypeRef))_ServerRelease, // finalize
NULL, // equal
NULL, // hash
NULL, // copy formatting description
(CFStringRef(*)(CFTypeRef))_ServerCopyDescription // copy debug description
};
_ServerTypeId = _CFRuntimeRegisterClass(&ServerClass);
}
return _ServerTypeId;
}
/* extern */ _CFServerRef
_CFServerCreate(CFAllocatorRef alloc, _CFServerCallBack callback, _CFServerContext* context) {
Server* server = NULL;
do {
int yes = 1;
CFSocketContext socketCtxt = {0,
NULL,
(const void*(*)(const void*))&CFRetain,
(void(*)(const void*))&CFRelease,
(CFStringRef(*)(const void *))&CFCopyDescription};
CFTypeID id = _CFServerGetTypeID();
// Ask CF to allocate the instance and then return it.
if (id != _kCFRuntimeNotATypeID) {
server = (Server*)_CFRuntimeCreateInstance(alloc,
id,
sizeof(Server) - sizeof(CFRuntimeBase),
NULL);
}
// Fail if unable to create the server
if (server == NULL)
break;
server->_name = NULL;
server->_type = NULL;
server->_port = 0;
server->_service = NULL;
memset(&server->_callback, 0, sizeof(server->_callback));
memset(&server->_ctxt, 0, sizeof(server->_ctxt));
// Make sure the server is saved for the callback.
socketCtxt.info = server;
// Create the IPv4 server socket.
server->_sockets[0] = CFSocketCreate(alloc,
PF_INET,
SOCK_STREAM,
IPPROTO_TCP,
kCFSocketAcceptCallBack,
(CFSocketCallBack)&_SocketCallBack,
&socketCtxt);
// If the socket couldn't create, bail.
if (server->_sockets[0] == NULL)
break;
// Create the IPv6 server socket.
server->_sockets[1] = CFSocketCreate(alloc,
PF_INET6,
SOCK_STREAM,
IPPROTO_TCP,
kCFSocketAcceptCallBack,
(CFSocketCallBack)&_SocketCallBack,
&socketCtxt);
// If the socket couldn't create, bail.
if (server->_sockets[1] == NULL)
break;
// In order to accomadate stopping and starting the process without closing the socket,
// set the addr for resuse on the native socket. This is not required if the port is
// being supplied by the OS opposed to being specified by the user.
setsockopt(CFSocketGetNative(server->_sockets[0]), SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(yes));
setsockopt(CFSocketGetNative(server->_sockets[1]), SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(yes));
// Save the user's callback in context.
server->_callback = callback;
memcpy(&(server->_ctxt), context, sizeof(server->_ctxt));
// If there is info and a retain function, retain the info.
if (server->_ctxt.info && server->_ctxt.retain)
server->_ctxt.info = (void*)server->_ctxt.retain(server->_ctxt.info);
return (_CFServerRef)server;
} while (0);
// Something failed, so clean up.
if (server) {
_CFServerInvalidate((_CFServerRef)server);
CFRelease((_CFServerRef)server);
}
return NULL;
}
/* extern */ UInt32
_CFServerGetPort(_CFServerRef server) {
return ((Server*)server)->_port & 0x0000FFFF;
}
/* static */ void
_ServerRelease(_CFServerRef server) {
// Invalidate the server which will release the socket and service.
_CFServerInvalidate(server);
}
/* static */ CFStringRef
_ServerCopyDescription(_CFServerRef server) {
Server* s = (Server*)server;
CFAllocatorRef alloc = CFGetAllocator(server);
CFTypeRef socket4, socket6, service;
CFStringRef info, result;
// Start with everything being "NULL"
socket4 = socket6 = service = _kCFServerNULL;
// Set socket to it's value
if (s->_sockets[0] != NULL)
socket4 = (CFTypeRef)(s->_sockets[0]);
// Set socket to it's value
if (s->_sockets[1] != NULL)
socket6 = (CFTypeRef)(s->_sockets[1]);
// Set service to it's value
if (s->_service != NULL)
service = (CFTypeRef)(s->_service);
// Set the user's context based upon supplied "copyDescription"
if (s->_ctxt.copyDescription)
info = s->_ctxt.copyDescription(s->_ctxt.info);
else
info = CFStringCreateWithFormat(alloc, NULL, _kCFServerPtrFormat, (UInt32)(s->_ctxt.info));
// Create the debug string
result = CFStringCreateWithFormat(alloc,
NULL,
_kCFServerDescribeFormat,
(UInt32)server,
socket4,
socket6,
service,
info);
// Release the user's string
CFRelease(info);
return result;
}
/* extern */ Boolean
_CFServerStart(_CFServerRef server, CFStringRef name, CFStringRef type, UInt32 port) {
Server* s = (Server*)server;
CFDataRef address = NULL;
do {
unsigned i;
CFRunLoopRef rl = CFRunLoopGetCurrent();
CFAllocatorRef alloc = CFGetAllocator(server);
struct sockaddr_in addr4;
struct sockaddr_in6 addr6;
// Make sure the port is valid (0 - 65535).
if ((port & 0xFFFF0000U) != 0)
break;
// NULL means to use the machine name.
if (name == NULL)
name = _kCFServerEmptyString;
for (i = 0; i < (sizeof(s->_sockets) / sizeof(s->_sockets[0])); i++) {
// Create the run loop source for putting on the run loop.
CFRunLoopSourceRef src = CFSocketCreateRunLoopSource(alloc, s->_sockets[i], 0);
if (src == NULL)
break;
// Add the run loop source to the current run loop and default mode.
CFRunLoopAddSource(rl, src, kCFRunLoopCommonModes);
CFRelease(src);
}
memset(&addr4, 0, sizeof(addr4));
// Put the local port and address into the native address.
#if !defined(__WIN32__)
addr4.sin_len = sizeof(addr4);
#endif
addr4.sin_family = AF_INET;
addr4.sin_port = htons((UInt16)port);
addr4.sin_addr.s_addr = htonl(INADDR_ANY);
// Wrap the native address structure for CFSocketCreate.
address = CFDataCreateWithBytesNoCopy(alloc, (const UInt8*)&addr4, sizeof(addr4), kCFAllocatorNull);
// If it failed to create the address data, bail.
if (address == NULL)
break;
// Set the local binding which causes the socket to start listening.
if (CFSocketSetAddress(s->_sockets[0], address) != kCFSocketSuccess)
break;
CFRelease(address);
address = CFSocketCopyAddress(s->_sockets[0]);
memcpy(&addr4, CFDataGetBytePtr(address), CFDataGetLength(address));
port = ntohs(addr4.sin_port);
CFRelease(address);
memset(&addr6, 0, sizeof(addr6));
// Put the local port and address into the native address.
addr6.sin6_family = AF_INET6;
#ifndef __WIN32__
addr6.sin6_port = htons((UInt16)port);
#ifndef ANDROID
addr6.sin6_len = sizeof(addr6);
#endif
memcpy(&(addr6.sin6_addr), &in6addr_any, sizeof(addr6.sin6_addr));
#else
#ifndef __MINGW32__
// real MS headers have this
IN6ADDR_SETANY(addr6);
addr6.sin6_port = htons((UInt16)port);
#else
addr6.sin6_port = htons((UInt16)port);
// mingw's w32 headers have this INIT macro instead, for some odd reason
struct sockaddr_in6 in6addr_any = IN6ADDR_ANY_INIT;
memcpy(&(addr6.sin6_addr), &in6addr_any, sizeof(addr6.sin6_addr));
#endif
#endif
// Wrap the native address structure for CFSocketCreate.
address = CFDataCreateWithBytesNoCopy(alloc, (const UInt8*)&addr6, sizeof(addr6), kCFAllocatorNull);
// Set the local binding which causes the socket to start listening.
if (CFSocketSetAddress(s->_sockets[1], address) != kCFSocketSuccess)
break;
// Save the name, service type and port.
s->_name = CFRetain(name);
s->_type = type ? CFRetain(type) : NULL;
s->_port = port;
#if defined(__MACH__)
// Attempt to register the service on the network.
if (type && !_ServerCreateAndRegisterNetService(s))
break;
#endif
// Release this since it's not needed any longer.
CFRelease(address);
return TRUE;
} while (0);
// Handle the error cleanup.
// Release the address data if it was created.
if (address)
CFRelease(address);
// Kill the socket if it was created.
_ServerReleaseSocket(s);
return FALSE;
}
/* extern */ void
_CFServerInvalidate(_CFServerRef server) {
Server* s = (Server*)server;
// Release the user's context info pointer.
if (s->_ctxt.info && s->_ctxt.release)
s->_ctxt.release(s->_ctxt.info);
// Clear out the context, so nothing can be called.
memset(&(s->_ctxt), 0, sizeof(s->_ctxt));
// Guarantee that there will be no user callback.
s->_callback = NULL;
#if defined(__MACH__)
// Release the net service.
_ServerReleaseNetService(s);
#endif
if (s->_name) {
CFRelease(s->_name);
s->_name = NULL;
}
if (s->_type) {
CFRelease(s->_type);
s->_type = NULL;
}
// Release the socket.
_ServerReleaseSocket(s);
}
#pragma mark -
#pragma mark Static Function Definitions
#if defined(__MACH__)
/* static */ void
_ServerReleaseNetService(Server* server) {
// Unschedule, cancel, and release the net service if there is one.
if (server->_service != NULL) {
CFNetServiceUnscheduleFromRunLoop(server->_service, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
CFNetServiceSetClient(server->_service, NULL, NULL);
CFNetServiceCancel(server->_service);
CFRelease(server->_service);
server->_service = NULL;
}
}
#endif
/* static */ void
_ServerReleaseSocket(Server* server) {
unsigned i;
for (i = 0; i < (sizeof(server->_sockets) / sizeof(server->_sockets[0])); i++) {
// Invalidate and release the socket if there is one.
if (server->_sockets[i] != NULL) {
CFSocketInvalidate(server->_sockets[i]);
CFRelease(server->_sockets[i]);
server->_sockets[i] = NULL;
}
}
}
#if defined(__MACH__)
/* static */ Boolean
_ServerCreateAndRegisterNetService(Server* server) {
do {
UInt32 port = server->_port;
Boolean didSet, didRegister;
CFNetServiceClientContext netSvcCtxt = {0,
server,
(CFAllocatorRetainCallBack)&CFRetain,
(CFAllocatorReleaseCallBack)&CFRelease,
(CFAllocatorCopyDescriptionCallBack)&CFCopyDescription};
// If the port was unspecified, get the port from the socket.
if (port == 0) {
// Get the local address
CFDataRef addr = CFSocketCopyAddress(server->_sockets[0]);
struct sockaddr_in* nativeAddr = (struct sockaddr_in*)CFDataGetBytePtr(addr);
CFRelease(addr);
port = ntohs(nativeAddr->sin_port);
}
// Create the service for registration.
server->_service = CFNetServiceCreate(CFGetAllocator((_CFServerRef)server),
_kCFServerEmptyString,
server->_type,
server->_name,
port);
// Require the service for the socket.
if (server->_service == NULL)
break;
// Try setting the client on the service.
didSet = CFNetServiceSetClient(server->_service,
(CFNetServiceClientCallBack)&_NetServiceCallBack,
&netSvcCtxt);
// Check to make sure it set before registering.
if (!didSet)
break;
// Schedule the service on the run loop.
CFNetServiceScheduleWithRunLoop(server->_service, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
// Start the registration.
didRegister = CFNetServiceRegisterWithOptions(server->_service, 0, NULL);
// If registration failed, die.
if (!didRegister)
break;
return TRUE;
} while (0);
// Failed to set up the service, so clean up anything that succeeded.
_ServerReleaseNetService(server);
return FALSE;
}
#endif
/* static */ void
_ServerHandleAccept(Server* server, CFSocketNativeHandle nativeSocket) {
// Inform the user of an incoming connection.
if (server->_callback != NULL) {
CFStreamError error = {0, 0};
server->_callback((_CFServerRef)server, nativeSocket, &error, server->_ctxt.info);
}
}
#if defined(__MACH__)
/* static */ void
_ServerHandleNetServiceError(Server* server, CFStreamError* error) {
// No matter what happened, tear down the service.
_ServerReleaseNetService(server);
// Handle the error.
if (error->error != 0) {
// Kill the underlying socket to prevent callbacks.
_ServerReleaseSocket(server);
// Inform the user of the error.
if (server->_callback != NULL)
server->_callback((_CFServerRef)server, (CFSocketNativeHandle)(-1), error, server->_ctxt.info);
}
}
#endif
/* static */ void
_SocketCallBack(CFSocketRef sock, CFSocketCallBackType type, CFDataRef address, const void *data, Server* server) {
assert((sock == server->_sockets[0]) || (sock == server->_sockets[1]));
// Only care about accept callbacks.
if (type == kCFSocketAcceptCallBack) {
assert((data != NULL) && (*((CFSocketNativeHandle*)data) != -1));
// Dispatch the accept event.
_ServerHandleAccept(server, *((CFSocketNativeHandle*)data));
}
}
#if defined(__MACH__)
/* static */ void
_NetServiceCallBack(CFNetServiceRef service, CFStreamError* error, Server* server) {
assert(service == server->_service);
// Dispatch the registration error.
if (error->error)
_ServerHandleNetServiceError(server, error);
}
#endif

6990
src/Stream/CFSocketStream.c Normal file

File diff suppressed because it is too large Load Diff

246
src/Stream/CFSocketStreamImpl.h Executable file
View File

@ -0,0 +1,246 @@
/*
* Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
CFSocketStreamImpl.h
Copyright 1998-2003, Apple, Inc. All rights reserved.
Responsibility: Jeremy Wyld
Private header only for the set of files that implement CFSocketStream.
*/
#ifndef __CFSOCKETSTREAMIMPL__
#define __CFSOCKETSTREAMIMPL__
#include <CFNetwork/CFSocketStream.h>
#include "CFNetworkInternal.h"
#include <CFNetwork/CFHTTPStream.h>
#if defined(__MACH__)
#include <Security/SecureTransport.h>
#include <SystemConfiguration/SCNetworkReachability.h>
#endif
#if defined(__WIN32__)
#include <winsock2.h>
#include <ws2tcpip.h> // for ipv6
// an alias for Win32 routines
#define ioctl(a, b, c) ioctlsocket(a, b, c)
// Sockets and fds are not interchangeable on Win32, and have different error codes.
// These redefines assumes that in this file we only apply this error constant to socket ops.
#undef EAGAIN
#define EAGAIN WSAEWOULDBLOCK
#undef ECONNABORTED
#define ECONNABORTED WSAECONNABORTED
#undef ENOTCONN
#define ENOTCONN WSAENOTCONN
#undef ECONNREFUSED
#define ECONNREFUSED WSAECONNREFUSED
#undef EBADF
#define EBADF WSAENOTSOCK
#undef ETIMEDOUT
#define ETIMEDOUT WSAETIMEDOUT
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(__WIN32__)
typedef struct _SchannelState *SchannelState;
// Win32 doesn't have an equivalent, but we reuse this for porting ease
typedef enum {
kSSLIdle = 1,
kSSLHandshake,
kSSLConnected,
kSSLClosed,
kSSLAborted
} SSLSessionState;
#endif
// The bits for a socket context's flags. Note that these are the bit indices, not the bit masks themselves.
enum {
SHARED = 0,
CREATED_WITH_SOCKET,
OPEN_START,
OPEN_COMPLETE,
SHOULD_CLOSE,
KILL_SOCKET_ON_CLOSE,
SECURITY_CHECK_CERTIFICATE,
VERIFIED_READ_EVENT,
VERIFIED_WRITE_EVENT,
WRITE_STREAM_OPENED,
READ_STREAM_OPENED,
USE_ADDR_CACHE,
RECVD_READ,
RECVD_WRITE,
SELECT_READ,
SELECT_WRITE,
NO_REACHABILITY,
ICHAT_SUBNET_SETTING = 31
};
typedef struct {
CFMutableArrayRef runloops;
struct _CFStream *stream; // NOT retained; if it's retained, we introduce a retain loop!
} _CFSocketStreamRLSource;
typedef struct {
UInt32 socks_flags; // Flags used for performing SOCKS handshake.
CFHostRef host; // SOCKS server
UInt32 port; // Port of the SOCKS server
CFStringRef user; // user id for the SOCKS server
CFStringRef pass; // password for the SOCKS server
CFIndex bytesInBuffer; // Number of bytes in the buffer.
UInt8* buffer; // Bytes read or waiting to be written.
} _SOCKSInfo;
typedef struct {
CFHostRef host;
UInt32 port;
CFDictionaryRef settings;
CFDataRef request;
CFIndex left;
CFHTTPMessageRef response;
} _CONNECTInfo;
struct _CFSocketStreamContext;
typedef void (*handshakeFn)(struct _CFSocketStreamContext*);
typedef struct {
CFSpinLock_t lock; // Used to lock access if two separate streams exist for the same socket.
CFOptionFlags flags;
CFAllocatorRef alloc;
CFStreamError error; // Store the error code for the operation that failed
CFTypeRef lookup; // async lookup; either a CFHost or a CFNetService
CFIndex attempt; // current address index being attempted
CFSocketRef sock; // underlying CFSocket
CFArrayRef cb;
#if defined(__MACH__)
SCNetworkReachabilityRef reachability;
#endif
union {
UInt32 port; // Port number if created with host/port
int sock; // socket if created with a native socket
} u;
CFSocketSignature sig; // Signature for a stream pair created with one
CFMutableArrayRef runloops; // loop/mode pairs that are scheduled for
// both read and write
_CFSocketStreamRLSource *readSource, *writeSource;
handshakeFn handshakes[4]; // Holds the functions to be performed as part of open.
CFStringRef peerName; // if set, overrides peer name from the host we looked up
#if defined(__MACH__) || defined(APPORTABLE)
SSLContextRef security;
UInt8* sslBuffer;
CFIndex sslBufferCount;
#elif defined(__WIN32__)
SchannelState ssl;
#endif
_SOCKSInfo* socks_info;
_CONNECTInfo* connect_info;
} _CFSocketStreamContext;
// General routines used by the implementation files, implemented in CFSocketStream.c
extern CFIndex __fdRecv(int fd, UInt8* buffer, CFIndex bufferLength, CFStreamError* errorCode, Boolean *atEOF);
extern CFIndex __fdSend(int fd, const UInt8* buffer, CFIndex bufferLength, CFStreamError* errorCode);
extern char* __getServerName(_CFSocketStreamContext* ctxt, char *buffer, UInt32 *bufSize, CFAllocatorRef *allocator);
extern Boolean __AddHandshake_Unsafe(_CFSocketStreamContext* ctxt, handshakeFn fn);
extern void __RemoveHandshake_Unsafe(_CFSocketStreamContext* ctxt, handshakeFn fn);
extern void __WaitForHandshakeToComplete_Unsafe(_CFSocketStreamContext* ctxt);
#define __socketGetFD(ctxt) ((int)((__CFBitIsSet(ctxt->flags, CREATED_WITH_SOCKET)) ? ctxt->u.sock : (ctxt->sock ? CFSocketGetNative(ctxt->sock) : -1)))
// SSL routines used by CFSocketStream.c, implemented on both Mach and Win32
extern CFIndex sslRecv(_CFSocketStreamContext* ctxt, UInt8* buffer, CFIndex bufferLength, CFStreamError* errorCode, Boolean *atEOF);
extern CFIndex sslSend(_CFSocketStreamContext* ctxt, const UInt8* buffer, CFIndex bufferLength, CFStreamError* errorCode);
extern void sslClose(_CFSocketStreamContext* ctxt);
extern CFIndex sslBytesAvailableForRead(_CFSocketStreamContext* ctxt);
extern void performSSLHandshake(_CFSocketStreamContext* ctxt);
extern void performSSLSendHandshake(_CFSocketStreamContext* ctxt);
extern Boolean __SetSecuritySettings_Unsafe(_CFSocketStreamContext* ctxt, CFDictionaryRef settings);
extern CFStringRef __GetSSLProtocol(_CFSocketStreamContext* ctxt);
extern SSLSessionState __GetSSLSessionState(_CFSocketStreamContext* ctxt);
#if 0
#define SSL_LOG printf
#else
#define SSL_LOG while(0) printf
#endif
#if defined(__MACH__)
#define IS_SECURE(x) ((x)->security != NULL)
#define SSL_WOULD_BLOCK(error) ((error->domain == kCFStreamErrorDomainSSL) && (errSSLWouldBlock == error->error) )
#elif defined(__WIN32__)
#define IS_SECURE(ctxt) ((ctxt)->ssl != NULL)
// On Windows there is no SSL-specific way to represent this, it uses the normal EAGAIN
#define SSL_WOULD_BLOCK(error) (FALSE)
#endif /* __WIN32__ */
#if defined(__cplusplus)
}
#endif
#endif /* __CFSOCKETSTREAMIMPL__ */

Some files were not shown because too many files have changed in this diff Show More