How to follow alias with libldap? - objective-c

I have an openvpn plugin which allows me to use ldap authentication. But my LDAP directory contains aliases and it seems that openvpn-auth-ldap doesn't follow them.
- (id) initWithURL: (LFString *) url timeout: (int) timeout {
...
ldap_initialize(&ldapConn, [url cString]);
if (!ldapConn) {
[TRLog error: "Unable to initialize LDAP server %s", [url cString]];
[self release];
return (NULL);
}
_timeout = timeout;
ldapTimeout.tv_sec = _timeout;
ldapTimeout.tv_usec = 0;
if (ldap_set_option(ldapConn, LDAP_OPT_NETWORK_TIMEOUT, &ldapTimeout) != LDAP_OPT_SUCCESS)
[TRLog warning: "Unable to set LDAP network timeout."];
Is there anyway I can fix it ?

By default, LDAP_OPT_DEREF is setted to LDAP_DEREF_NEVER. Maybe you should force alias deferencing of your ldap connection :
int deref = LDAP_DEREF_ALWAYS;
ldap_set_option(ldapConn, LDAP_OPT_DEREF, &deref)

Related

Creating local group on MacOS Catalina using Core Services and Objective-C

How do I create a local group using Core Services.? Documentation for Core Services says "The Core Services Identity Reference allows developers to support user and group creation.." but there are no examples on how to do it.
Update. This is the code I have so far but It doesn't work and ErrorCode return -2, error description is null. Really struggling to find any documentation that explains how to do it. 0 information on error codes as well.
CFStringRef realName = CFStringCreateWithCString(NULL, "newGroupTest",
kCFStringEncodingMacRoman);
CFStringRef posixName = CFStringCreateWithCString(NULL, "newgrptst1",
kCFStringEncodingMacRoman);
AuthorizationRef auth;
OSStatus status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
kAuthorizationFlagDefaults,
&auth);
CSIdentityAuthorityRef authority = CSGetDefaultIdentityAuthority();
CSIdentityRef identity = CSIdentityCreate(NULL, kCSIdentityClassGroup, realName,
posixName, kCSIdentityFlagNone, authority);
CFErrorRef error;
BOOL success = CSIdentityCommit(Identity, auth, &error);
if(!success)
{
CFIndex index = CFErrorGetCode(error);
CFStringRef desc = CFErrorCopyDescription(error);
const char* cDesc = CFStringGetCStringPtr(desc, CFStringGetSystemEncoding());
}
Found what was the problem. I wasn't using correct identity authority. To create a local group you need to use CSGetLocaldentityAuthority() that get a local identity authority that stores the identities local to the system, instead of
CSGetDefaultIdentityAuthority() that represents the network-bound authorities.

Getting certificate error in Uploading image with https Amazon AWS

I am facing an issue while uploading image in Amazon AWS. Here is my code:
import UIKit
protocol ContentUploaderDelegate {
func onContentLoadComplete(status:Bool,serverResponse:String)
}
class ContentUploader
{
let contentURL = "https:<MY URL>amazonaws.com/api/v1/contents"
var delegate:ContentUploaderDelegate?
func uploadImage(image:UIImage,xAuth:String,mimeType:String,imageName:String)
{
let url = NSURL(string: contentURL)
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
let boundary = generateBoundaryString()
//define the multipart request type
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.setValue(xAuth, forHTTPHeaderField: "x-auth-token")
request.setValue("application/json", forHTTPHeaderField: "accept")
let image_data = UIImageJPEGRepresentation(image, 1.0)
if(image_data == nil)
{
return
}
let body = NSMutableData()
//name to save in server
let fname = imageName
let mimetype = mimeType
//define the data post parameter
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition:form-data; name=\"test\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("hi\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition:form-data; name=\"files\"; filename=\"\(fname)\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Type: \(mimetype)\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(image_data!)
body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
//set the HTTPBody
request.HTTPBody = body
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) {
(
let data, let response, let error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print("error")
self.delegate?.onContentLoadComplete(false, serverResponse: (error?.description)!)
return
}
let dataString = NSString(data: data!, encoding: NSUTF8StringEncoding)
print("success \(dataString)")
self.delegate?.onContentLoadComplete(true, serverResponse:dataString! as String)
}
task.resume()
}
private func generateBoundaryString() -> String
{
return "Boundary-\(NSUUID().UUIDString)"
}
The following delegate method never gets called. What could be the reason?
func URLSession(session: NSURLSession,
task: NSURLSessionTask,
didReceiveChallenge challenge: NSURLAuthenticationChallenge,
completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?)
-> Void) {
let protectionSpace = challenge.protectionSpace
let theSender = challenge.sender
if protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
if (challenge.protectionSpace.host == "ec2-52-36-216-81.us-west-2.compute.amazonaws.com") {
if let theTrust = protectionSpace.serverTrust{
let theCredential = NSURLCredential(trust: theTrust)
theSender!.useCredential(theCredential, forAuthenticationChallenge: challenge)
return
}
}
}
theSender!.performDefaultHandlingForAuthenticationChallenge!(challenge)
return
}
}
And I am getting the following error. Any idea why getting this error?
Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this
server is invalid. You might be connecting to a server that is
pretending to be “.amazonaws.com” which could put your
confidential information at risk."
UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=, NSLocalizedRecoverySuggestion=Would you like to
connect to the server anyway?, _kCFStreamErrorDomainKey=3,
_kCFStreamErrorCodeKey=-9813, NSErrorPeerCertificateChainKey={type = immutable, count = 1, values = (
0 : .com i: www..com> )}, NSUnderlyingError=0x7f9d42aedc10 {Error
Domain=kCFErrorDomainCFNetwork Code=-1202 "(null)"
UserInfo={_kCFStreamPropertySSLClientCertificateState=0,
kCFStreamPropertySSLPeerTrust=,
_kCFNetworkCFStreamSSLErrorOriginalValue=-9813, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9813, kCFStreamPropertySSLPeerCertificates={type = immutable, count = 1, values = (
0 : .com i: www..com> )}}}, NSLocalizedDescription=The certificate for this server is
invalid. You might be connecting to a server that is pretending to be
“.amazonaws.com” which could put your confidential information
at risk., NSErrorFailingURLKey=https://amazonaws.com/api/v1/contents,
NSErrorFailingURLStringKey=https://.amazonaws.com/api/v1/contents,
NSErrorClientCertificateStateKey=0}
Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “.amazonaws.com”
I believe something is wrong with the common name “.amazonaws.com”
NSErrorFailingURLKey=https://amazonaws.com/api/v1/contents,
NSErrorFailingURLStringKey=https://.amazonaws.com/api/v1/contents
The URLs shown in the error message do not appear to be a well know endpoint. I would expect to see something like https://ec2-2-2-2-2.compute-1.amazonaws.com or another Fully Qualified Domain name there.
The error message also confirms this. You are connecting a host, but the name on the certificate does not match. This is the reason for the pretending to be “.amazonaws.com” error.
Confirm the correct endpoint, and how your code is forming the full URL.
The following delegate method never gets called. What could be the
reason?
The error occurs before the function is called. The session is never established because of the certificate error.

CloudFlare DNS / direct IP identifier

We started to use cloudflare at my work and I want to understand how the cloudflare knows that I put dns name at my browser and not direct IP.
I mean - how they knows if I put www.mysite.com and NOT 123.34.45.45 as URL on my browser.
Is there any flag at HTTP GET header or any other identifier ?
Many thanks.
That's how DNS works.
"The Domain Name System distributes the responsibility of assigning domain names and mapping those names to IP addresses by designating authoritative name servers for each domain"
There is a way of doing that.
Inside apache instead of doing a public root directory, use VHosts instead they will only respond to a vhost requested. While its better than nothing it still can be displayed through an numerous amount of ways.
CloudFlare has released a module mod_cloudflare for apache, the module will log and display the actual visitor IP Addresses rather than those accessed by cloudflare! https://www.cloudflare.com/resources-downloads#mod_cloudflare (Answer by: olimortimer)
I recommend you do it in PHP: Cloudflare's ips are stored in public so you can go view them here then check if the ip is from cloudflare (this will allow us to get the real ip from the http header HTTP_CF_CONNECTING_IP).
If you are using this to disable all non cf connections or vice versa, i recommend you to have a single php script file that gets called before every other script such as a common.php or pagestart.php etc.
function ip_in_range($ip, $range) {
if (strpos($range, '/') == false)
$range .= '/32';
// $range is in IP/CIDR format eg 127.0.0.1/24
list($range, $netmask) = explode('/', $range, 2);
$range_decimal = ip2long($range);
$ip_decimal = ip2long($ip);
$wildcard_decimal = pow(2, (32 - $netmask)) - 1;
$netmask_decimal = ~ $wildcard_decimal;
return (($ip_decimal & $netmask_decimal) == ($range_decimal & $netmask_decimal));
}
function _cloudflare_CheckIP($ip) {
$cf_ips = array(
'199.27.128.0/21',
'173.245.48.0/20',
'103.21.244.0/22',
'103.22.200.0/22',
'103.31.4.0/22',
'141.101.64.0/18',
'108.162.192.0/18',
'190.93.240.0/20',
'188.114.96.0/20',
'197.234.240.0/22',
'198.41.128.0/17',
'162.158.0.0/15',
'104.16.0.0/12',
);
$is_cf_ip = false;
foreach ($cf_ips as $cf_ip) {
if (ip_in_range($ip, $cf_ip)) {
$is_cf_ip = true;
break;
}
} return $is_cf_ip;
}
function _cloudflare_Requests_Check() {
$flag = true;
if(!isset($_SERVER['HTTP_CF_CONNECTING_IP'])) $flag = false;
if(!isset($_SERVER['HTTP_CF_IPCOUNTRY'])) $flag = false;
if(!isset($_SERVER['HTTP_CF_RAY'])) $flag = false;
if(!isset($_SERVER['HTTP_CF_VISITOR'])) $flag = false;
return $flag;
}
function isCloudflare() {
$ipCheck = _cloudflare_CheckIP($_SERVER['REMOTE_ADDR']);
$requestCheck = _cloudflare_Requests_Check();
return ($ipCheck && $requestCheck);
}
// Use when handling ip's
function getRequestIP() {
$check = isCloudflare();
if($check) {
return $_SERVER['HTTP_CF_CONNECTING_IP'];
} else {
return $_SERVER['REMOTE_ADDR'];
}
}
To use the script it's quite simple:
$ip = getRequestIP();
$cf = isCloudflare();
if($cf) echo "Cloudflare :D<br>";
else echo "Not cloudflare o_0";
echo "Your actual ip address is: ". $ip;
This script should help you out to check if the request is from CF and not directly though a ip address.

Not able to update firefox sqlite database when firefox is running-MacOS

I have the following code snippet to update firefox extension sqlite data base
NSString * profileFolderPath = [[ #"~" stringByExpandingTildeInPath] stringByAppendingPathComponent:#"/Library/Application Support/Firefox/Profiles"];
NSString *sqlitePath = [pathToProfileFolder stringByAppendingPathComponent:#"extensions.sqlite"];
int rc = sqlite3_open([sqlitePath UTF8String], &db);
if( rc )
{
NSLog(#"enable extension :%#\n",[NSString stringWithCString:sqlite3_errmsg(db)]);
sqlite3_close(db);
return NO;
}
else {
NSLog(#"opened entensions db successfully \n");
}
// check the values for active and userDisabled fields
rc = sqlite3_exec(db,"SELECT active,userDisabled FROM addon where id='myId.com'",sqliteCallback,0,&zErrMsg);
if (rc!=SQLITE_OK ) {
NSLog(#"error quering the entensions database :%#\n",[NSString stringWithCString:zErrMsg]);
if(zErrMsg)
sqlite3_free(zErrMsg);
sqlite3_close(db);
return NO;
// handle error
}
When firefox application is not in running state,I can read the values and also update the database,but when the firefox is running I am not able to read the values from the database as sqlite3_exec statement is returning the value 5 and I can see the error in console saying "error quering the extensions database :database is locked".
How can I resolve this issue.Please help.
You cannot b/c firefox keeps its own config file (and extensions db file IS a firefox own config file) open while it runs.

Cocoa: Handling 407 http response cfnetwork

I am creating downloader application.
I am facing a problem with proxy authentication.
I am getting 407 response code i.e proxy authentication required. I have valid proxy authentication details.
Following is Code Flow:
1. Create Http request using CFHTTPMessageCreateRequest
2. Set necessary header field values like Cache-Control, Accept-Ranges, Range & User-Agent using CFHTTPMessageSetHeaderFieldValue
3. Create read stream using CFReadStreamCreateForHTTPRequest
4. Set proxy server URL & port properties on read stream using CFReadStreamSetProperty
5. Set kCFStreamPropertyHTTPShouldAutoredirect to kCFBooleanTrue using CFReadStreamSetProperty
6. open read stream using CFReadStreamOpen
7. In a loop wait for stream to get opened
while (1)
{
if (kCFStreamStatusOpen == CFReadStreamGetStatus)
{
if (CFReadStreamHasBytesAvailable)
{
Get Http response header using CFReadStreamCopyProperty
Get response code using CFHTTPMessageGetResponseStatusCode
if (200 || 206 is response code)
SUCCESS
else check if response code is 407.
}
}
}
I tried using following code
if (407 == nsiStatusCode)
{
CFStreamError err;
cfAuthentication = CFHTTPAuthenticationCreateFromResponse(NULL, cfHttpResponse);
if ((cfAuthentication) && (CFHTTPAuthenticationIsValid(cfAuthentication, &err)))
{
if (CFHTTPAuthenticationRequiresUserNameAndPassword(cfAuthentication))
{
CFHTTPMessageApplyCredentials(cfHttpRequest, cfAuthentication, (CFStringRef)pnsUserName, (CFStringRef)pnsPassword, &err);
}
}
}
but unable to make it work.
How do I handle 407 status code so as to communicate with authenticating HTTP server?
Thanks in advance.
Vaibhav.
Build a CFHTTPMessageRef
-(CFHTTPMessageRef)buildMessage
{
NSURL *myURL = [NSURL URLWithString:#"http://myurl.com"];
NSData *dataToPost = [[NSString stringWithString:#"POST Data It Doesn't Matter What It Is"] dataUsingEncoding:NSUTF8StringEncoding];
//Create with the default allocator (NULL), a post request,
//the URL, and pick either
//kCFHTTPVersion1_0 or kCFHTTPVersion1_1
CFHTTPMessageRef request = CFHTTPMessageCreateRequest(NULL, CSTR("POST"), (CFURLRef)myURL, kCFHTTPVersion1_1);
CFHTTPMessageSetBody(request, (CFDataRef)dataToPost);
//Unfortunately, this isn't smart enough to set reasonable headers for you
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("HOST"), (CFStringRef)[myURL host]);
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Content-Length"), (CFStringRef)[NSString stringWithFormat:"%d", [dataToPost length]);
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Content-Type"), CFSTR("charset=utf-8"));
return [NSMakeCollectable(request) autorelease];
}
Send it to the server and read back the response
-(CFHTTPMessageRef)performHTTPRequest:(CFHTTPMessageRef)request
{
CFReadStreamRef requestStream = CFReadStreamCreateForHTTPRequest(NULL, request);
CFReadStreamOpen(requestStream);
NSMutableData *responseBytes = [NSMutableData data];
CFIndex numBytesRead = 0 ;
do
{
UInt8 buf[1024];
numBytesRead = CFReadStreamRead(requestStream, buf, sizeof(buf));
if(numBytesRead > 0)
[responseBytes appendBytes:buf length:numBytesRead];
} while(numBytesRead > 0);
CFHTTPMessageRef response = (CFHTTPMessageRef)CFReadStreamCopyProperty(requestStream, kCFStreamPropertyHTTPResponseHeader);
CFHTTPMessageSetBody(response, (CFDataRef)responseBytes);
CFReadStreamClose(requestStream);
CFRelease(requestStream);
return [NSMakeCollectable(response) autorelease];
}
Adding Authentication to an HTTP Request
-(void)addAuthenticationToRequest:(CFHTTPMessageRef)request withResponse:(CFHTTPMessageRef)response
{
CFHTTPAuthenticationRef authentication = CFHTTPAuthenticationCreateFromResponse(NULL, response);
[NSMakeCollectable(authentication) autorelease];
CFStreamError err;
Boolean success = CFHTTPMessageApplyCredentials(request, authentication, CFSTR("username"), CFSTR("password"), &err);
}
Putting It All Together
-(void)magicHappens
{
CFHTTPMessageRef request = [self buildMessage];
CFHTTPMessageRef response = [self performHTTPRequest: request];
UInt32 statusCode;
statusCode = CFHTTPMessageGetResponseStatusCode(response);
//An HTTP status code of 401 or 407 indicates that authentication is
//required I use an auth count to make sure we don't get stuck in an
//infinite loop if our credentials are bad. Sometimes, making the
//request more than once lets it go through.
//I admit I don't know why.
int authCount = 0;
while((statusCode == 401 || statusCode == 407) && authCount < 3)
{
request = [self buildMessage];
[self addAuthenticationToRequest:request withResponse:response];
response = [self performHTTPRequest: request];
statusCode = CFHTTPMessageGetResponseStatusCode;
authCount++;
}
NSData *responseBodyData = [(NSData*)CFHTTPMessageCopyBody(response) autorelease];
NSString *responseBody = [[[NSString alloc] initWithData:responseBodyData encoding:NSUTF8StringEncoding] autorelease];
NSLog(responseBody);
}
Refer this link.