Skip to content

Instantly share code, notes, and snippets.

@williamsjj
Created December 11, 2013 23:20
Show Gist options
  • Select an option

  • Save williamsjj/7920346 to your computer and use it in GitHub Desktop.

Select an option

Save williamsjj/7920346 to your computer and use it in GitHub Desktop.
Boolean CFHTTPMessageAddAuthentication(CFHTTPMessageRef request, CFHTTPMessageRef authenticationFailureResponse, CFStringRef username, CFStringRef password, CFStringRef scheme, Boolean forProxy) {
Boolean result = FALSE;
CFHTTPAuthenticationRef auth = NULL;
if (authenticationFailureResponse)
auth = CFHTTPAuthenticationCreateFromResponse(CFGetAllocator(authenticationFailureResponse), authenticationFailureResponse);
// Even though no one else could be using this auth, GetProperty needs us to be locked
if (auth)
_CFMutexLock(&auth->_lock);
if (!scheme && auth) {
scheme = (CFStringRef)_CFHTTPAuthenticationGetProperty(auth, kCFHTTPAuthenticationPropertyMethod);
/* Clients of this API are not prepared for NTLM until it can be done entirely under the covers. */
if (scheme == kCFHTTPAuthenticationSchemeNTLM) {
CFMutableDictionaryRef replacement = (CFMutableDictionaryRef)CFDictionaryGetValue(auth->_schemes, kCFHTTPAuthenticationSchemeDigest);
if (!replacement)
replacement = (CFMutableDictionaryRef)CFDictionaryGetValue(auth->_schemes, kCFHTTPAuthenticationSchemeBasic);
if (replacement)
auth->_preferred = replacement;
else
scheme = NULL;
}
}
// Careful, scheme may come from the client, do can't treat as an atom and do == compares
if (scheme) {
if (!CFStringCompare(scheme, kCFHTTPAuthenticationSchemeBasic, kCFCompareCaseInsensitive))
result = _CFHTTPMessageSetBasicAuthenticationOnRequest(request, username, password, forProxy, NULL);
else if (auth && !auth->_error.error
&& !CFStringCompare(scheme, kCFHTTPAuthenticationSchemeDigest, kCFCompareCaseInsensitive)
&& !CFStringCompare(scheme, _CFHTTPAuthenticationGetProperty(auth, kCFHTTPAuthenticationPropertyMethod), kCFCompareCaseInsensitive))
{
CFStringRef keys[] = {kCFHTTPAuthenticationUsername, kCFHTTPAuthenticationPassword};
CFStringRef values[] = {username, password};
CFDictionaryRef dict = CFDictionaryCreate(CFGetAllocator(request),
(const void**)(&keys[0]),
(const void**)(&values[0]),
sizeof(keys) / sizeof(keys[0]),
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
result = _CFApplyCredentials_Unsafe(request, auth, dict, NULL);
CFRelease(dict);
}
}
// This API is incapable of doing any multi-leg schemes, like NTLM. The auth object would need to
// persist across the multiple legs.
if (auth) {
_CFMutexUnlock(&auth->_lock);
CFRelease(auth);
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment