|
|
|
|
@@ -18,8 +18,11 @@
|
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#import <Foundation/NSProcessInfo.h>
|
|
|
|
|
|
|
|
|
|
#import <curl/curl.h>
|
|
|
|
|
|
|
|
|
|
#import <NGObjWeb/WOHTTPConnection.h>
|
|
|
|
|
#import <NGObjWeb/WORequest.h>
|
|
|
|
|
#import <NGObjWeb/WOResponse.h>
|
|
|
|
|
@@ -27,7 +30,6 @@
|
|
|
|
|
|
|
|
|
|
#import <SOGo/SOGoUser.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#import <GDLContentStore/GCSOpenIdFolder.h>
|
|
|
|
|
#import <GDLContentStore/GCSFolderManager.h>
|
|
|
|
|
|
|
|
|
|
@@ -40,6 +42,60 @@
|
|
|
|
|
|
|
|
|
|
static BOOL SOGoOpenIDDebugEnabled = YES;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
size_t curl_body_function(void *ptr, size_t size, size_t nmemb, void *buffer)
|
|
|
|
|
{
|
|
|
|
|
size_t total;
|
|
|
|
|
|
|
|
|
|
total = size * nmemb;
|
|
|
|
|
[(NSMutableData *)buffer appendBytes: ptr length: total];
|
|
|
|
|
|
|
|
|
|
return total;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@implementation SimpleOpenIdResponse
|
|
|
|
|
|
|
|
|
|
- (id)init {
|
|
|
|
|
if ((self = [super init])) {
|
|
|
|
|
}
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (id)initWithResponse: (NSString *)_data andStatus:(unsigned int )_status{
|
|
|
|
|
if ((self = [self init])) {
|
|
|
|
|
[self setStatus: _status];
|
|
|
|
|
[self setContent: _data];
|
|
|
|
|
}
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)setStatus:(unsigned int)_status
|
|
|
|
|
{
|
|
|
|
|
self->status = _status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (unsigned int)status
|
|
|
|
|
{
|
|
|
|
|
if(self->status)
|
|
|
|
|
return self->status;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)setContent:(NSString *)_data
|
|
|
|
|
{
|
|
|
|
|
self->content = _data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (NSString *)contentString
|
|
|
|
|
{
|
|
|
|
|
if(self->content)
|
|
|
|
|
return self->content;
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
@implementation SOGoOpenIdSession
|
|
|
|
|
|
|
|
|
|
/// Check if all required parameters to set up a OpenIdSession are in sogo.conf
|
|
|
|
|
@@ -72,6 +128,7 @@ static BOOL SOGoOpenIDDebugEnabled = YES;
|
|
|
|
|
openIdClient = [_config objectForKey: @"SOGoOpenIdClient"];
|
|
|
|
|
openIdClientSecret = [_config objectForKey: @"SOGoOpenIdClientSecret"];
|
|
|
|
|
openIdEmailParam = [_config objectForKey: @"SOGoOpenIdEmailParam"];
|
|
|
|
|
openIdHttpVersion = [_config objectForKey: @"SOGoOpenIdHttpVersion"];
|
|
|
|
|
|
|
|
|
|
openIdEnableRefreshToken = NO;
|
|
|
|
|
refreshTokenBool = [_config objectForKey: @"SOGoOpenIdEnableRefreshToken"];
|
|
|
|
|
@@ -130,6 +187,7 @@ static BOOL SOGoOpenIDDebugEnabled = YES;
|
|
|
|
|
openIdClient = [sd openIdClient];
|
|
|
|
|
openIdClientSecret = [sd openIdClientSecret];
|
|
|
|
|
openIdEmailParam = [sd openIdEmailParam];
|
|
|
|
|
openIdHttpVersion = [sd openIdHttpVersion];
|
|
|
|
|
openIdEnableRefreshToken = [sd openIdEnableRefreshToken];
|
|
|
|
|
userTokenInterval = [sd openIdTokenCheckInterval];
|
|
|
|
|
sendDomainInfo = [sd openIdSendDomainInfo];
|
|
|
|
|
@@ -150,65 +208,179 @@ static BOOL SOGoOpenIDDebugEnabled = YES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- (WOResponse *) _performOpenIdRequest: (NSString *) endpoint
|
|
|
|
|
// - (WOResponse *) _performOpenIdRequest: (NSString *) endpoint
|
|
|
|
|
// method: (NSString *) method
|
|
|
|
|
// headers: (NSDictionary *) headers
|
|
|
|
|
// body: (NSData *) body
|
|
|
|
|
// {
|
|
|
|
|
// NSURL *url;
|
|
|
|
|
// NSUInteger status;
|
|
|
|
|
// WORequest *request;
|
|
|
|
|
// WOResponse *response;
|
|
|
|
|
// WOHTTPConnection *httpConnection;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// url = [NSURL URLWithString: endpoint];
|
|
|
|
|
// if (url)
|
|
|
|
|
// {
|
|
|
|
|
// if(SOGoOpenIDDebugEnabled)
|
|
|
|
|
// {
|
|
|
|
|
// NSLog(@"OpenId perform request: %@ %@", method, endpoint);
|
|
|
|
|
// NSLog(@"OpenId perform request, headers %@", headers);
|
|
|
|
|
// // if(body)
|
|
|
|
|
// // NSLog(@"OpenId perform request: content %@", [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding]);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// httpConnection = [[WOHTTPConnection alloc] initWithURL: url];
|
|
|
|
|
// [httpConnection autorelease];
|
|
|
|
|
|
|
|
|
|
// request = [[WORequest alloc] initWithMethod: method
|
|
|
|
|
// uri: [endpoint hostlessURL]
|
|
|
|
|
// httpVersion: self->openIdHttpVersion
|
|
|
|
|
// headers: headers content: body
|
|
|
|
|
// userInfo: nil];
|
|
|
|
|
// [request autorelease];
|
|
|
|
|
// [httpConnection sendRequest: request];
|
|
|
|
|
// response = [httpConnection readResponse];
|
|
|
|
|
// status = [response status];
|
|
|
|
|
// if(status >= 200 && status <500 && status != 404)
|
|
|
|
|
// return response;
|
|
|
|
|
// else if (status == 404)
|
|
|
|
|
// {
|
|
|
|
|
// [self errorWithFormat: @"OpenID endpoint not found (404): %@", endpoint];
|
|
|
|
|
// return nil;
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// [self errorWithFormat: @"OpenID server internal error during %@: %@", endpoint, response];
|
|
|
|
|
// return nil;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// [self errorWithFormat: @"OpenID can't handle endpoint (not a url): '%@'", endpoint];
|
|
|
|
|
// return nil;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
- (SimpleOpenIdResponse *) _performOpenIdRequest: (NSString *) endpoint
|
|
|
|
|
method: (NSString *) method
|
|
|
|
|
headers: (NSDictionary *) headers
|
|
|
|
|
body: (NSData *) body
|
|
|
|
|
{
|
|
|
|
|
NSURL *url;
|
|
|
|
|
NSMutableData *buffer;
|
|
|
|
|
SimpleOpenIdResponse *response;
|
|
|
|
|
|
|
|
|
|
CURL *curl;
|
|
|
|
|
struct curl_slist *headerlist=NULL;
|
|
|
|
|
NSUInteger status;
|
|
|
|
|
WORequest *request;
|
|
|
|
|
WOResponse *response;
|
|
|
|
|
WOHTTPConnection *httpConnection;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
url = [NSURL URLWithString: endpoint];
|
|
|
|
|
if (url)
|
|
|
|
|
{
|
|
|
|
|
if(SOGoOpenIDDebugEnabled)
|
|
|
|
|
{
|
|
|
|
|
NSLog(@"OpenId perform request: %@ %@", method, endpoint);
|
|
|
|
|
NSLog(@"OpenId perform request, headers %@", headers);
|
|
|
|
|
// if(body)
|
|
|
|
|
// NSLog(@"OpenId perform request: content %@", [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
httpConnection = [[WOHTTPConnection alloc] initWithURL: url];
|
|
|
|
|
[httpConnection autorelease];
|
|
|
|
|
NSString *content;
|
|
|
|
|
CURLcode rc;
|
|
|
|
|
char error[CURL_ERROR_SIZE];
|
|
|
|
|
|
|
|
|
|
request = [[WORequest alloc] initWithMethod: method
|
|
|
|
|
uri: [endpoint hostlessURL]
|
|
|
|
|
httpVersion: @"HTTP/1.1"
|
|
|
|
|
headers: headers content: body
|
|
|
|
|
userInfo: nil];
|
|
|
|
|
[request autorelease];
|
|
|
|
|
[httpConnection sendRequest: request];
|
|
|
|
|
response = [httpConnection readResponse];
|
|
|
|
|
status = [response status];
|
|
|
|
|
if(status >= 200 && status <500 && status != 404)
|
|
|
|
|
return response;
|
|
|
|
|
else if (status == 404)
|
|
|
|
|
{
|
|
|
|
|
[self errorWithFormat: @"OpenID endpoint not found (404): %@", endpoint];
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
[self errorWithFormat: @"OpenID server internal error during %@: %@", endpoint, response];
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
url = [NSURL URLWithString: endpoint];
|
|
|
|
|
if(!url)
|
|
|
|
|
{
|
|
|
|
|
[self errorWithFormat: @"OpenID can't handle endpoint (not a url): '%@'", endpoint];
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(SOGoOpenIDDebugEnabled)
|
|
|
|
|
{
|
|
|
|
|
NSLog(@"OpenId perform request: %@ %@", method, endpoint);
|
|
|
|
|
NSLog(@"OpenId perform request, headers %@", headers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
curl_global_init(CURL_GLOBAL_SSL);
|
|
|
|
|
curl = curl_easy_init();
|
|
|
|
|
|
|
|
|
|
if (curl)
|
|
|
|
|
{
|
|
|
|
|
error[0] = 0;
|
|
|
|
|
curl_easy_setopt(curl, CURLOPT_URL, [endpoint UTF8String]);
|
|
|
|
|
|
|
|
|
|
//add form
|
|
|
|
|
if(body)
|
|
|
|
|
{
|
|
|
|
|
curl_easy_setopt(curl, CURLOPT_POST, 1);
|
|
|
|
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, [body bytes]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//add headers
|
|
|
|
|
if(headers)
|
|
|
|
|
{
|
|
|
|
|
NSEnumerator *enumerator = [headers keyEnumerator];
|
|
|
|
|
NSString *key, *header;
|
|
|
|
|
while((key = [enumerator nextObject]))
|
|
|
|
|
{
|
|
|
|
|
header = [NSString stringWithFormat: @"%@: %@", key, [headers objectForKey: key]];
|
|
|
|
|
headerlist = curl_slist_append(headerlist, [header UTF8String]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(headerlist != NULL)
|
|
|
|
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L);
|
|
|
|
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
|
|
|
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
|
|
|
|
|
|
|
|
|
buffer = [NSMutableData data];
|
|
|
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_body_function);
|
|
|
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
|
|
|
|
|
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error);
|
|
|
|
|
|
|
|
|
|
// Perform SOAP request
|
|
|
|
|
rc = curl_easy_perform(curl);
|
|
|
|
|
if (rc == CURLE_OK)
|
|
|
|
|
{
|
|
|
|
|
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
|
|
|
|
|
|
|
|
|
|
response = [SimpleOpenIdResponse alloc];
|
|
|
|
|
response = [response initWithResponse: nil andStatus: status];
|
|
|
|
|
|
|
|
|
|
if(status >= 200 && status <500 && status != 404)
|
|
|
|
|
{
|
|
|
|
|
content = [[NSString alloc] initWithData: buffer
|
|
|
|
|
encoding: NSUTF8StringEncoding];
|
|
|
|
|
if (!content)
|
|
|
|
|
content = [[NSString alloc] initWithData: buffer
|
|
|
|
|
encoding: NSISOLatin1StringEncoding];
|
|
|
|
|
[response setContent: content];
|
|
|
|
|
|
|
|
|
|
return [response autorelease];
|
|
|
|
|
}
|
|
|
|
|
else if (status == 404)
|
|
|
|
|
{
|
|
|
|
|
[self errorWithFormat: @"OpenID endpoint not found (404): %@", endpoint];
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
[self errorWithFormat: @"OpenID server internal error during %@: %@", endpoint, response];
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
[self errorWithFormat: @"CURL error while accessing %@ (%d): %@", endpoint, rc,
|
|
|
|
|
[NSString stringWithCString: strlen(error) ? error : curl_easy_strerror(rc)]];
|
|
|
|
|
}
|
|
|
|
|
curl_easy_cleanup (curl);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
[self errorWithFormat: @"OpenID error when setting curl request for: %@", endpoint];
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (NSMutableDictionary *) fecthConfiguration: (NSString*) _domain
|
|
|
|
|
{
|
|
|
|
|
NSString *content;
|
|
|
|
|
WOResponse * response;
|
|
|
|
|
SimpleOpenIdResponse *response;
|
|
|
|
|
// WOResponse * response;
|
|
|
|
|
NSUInteger status;
|
|
|
|
|
NSMutableDictionary *result;
|
|
|
|
|
NSDictionary *config, *headers;
|
|
|
|
|
@@ -498,7 +670,8 @@ static BOOL SOGoOpenIDDebugEnabled = YES;
|
|
|
|
|
- (NSMutableDictionary *) fetchToken: (NSString * ) code redirect: (NSString *) oldLocation
|
|
|
|
|
{
|
|
|
|
|
NSString *location, *form, *content;
|
|
|
|
|
WOResponse *response;
|
|
|
|
|
SimpleOpenIdResponse *response;
|
|
|
|
|
// WOResponse *response;
|
|
|
|
|
NSUInteger status;
|
|
|
|
|
NSMutableDictionary *result;
|
|
|
|
|
NSDictionary *headers;
|
|
|
|
|
@@ -566,7 +739,8 @@ static BOOL SOGoOpenIDDebugEnabled = YES;
|
|
|
|
|
- (NSMutableDictionary *) refreshToken: (NSString * ) userRefreshToken
|
|
|
|
|
{
|
|
|
|
|
NSString *location, *form, *content;
|
|
|
|
|
WOResponse *response;
|
|
|
|
|
SimpleOpenIdResponse *response;
|
|
|
|
|
// WOResponse *response;
|
|
|
|
|
NSUInteger status;
|
|
|
|
|
NSMutableDictionary *result;
|
|
|
|
|
NSDictionary *headers;
|
|
|
|
|
@@ -639,7 +813,8 @@ static BOOL SOGoOpenIDDebugEnabled = YES;
|
|
|
|
|
- (NSMutableDictionary *) fetchUserInfo
|
|
|
|
|
{
|
|
|
|
|
NSString *location, *auth, *content;
|
|
|
|
|
WOResponse *response;
|
|
|
|
|
SimpleOpenIdResponse *response;
|
|
|
|
|
// WOResponse *response;
|
|
|
|
|
NSUInteger status;
|
|
|
|
|
NSMutableDictionary *result;
|
|
|
|
|
NSDictionary *profile, *headers;
|
|
|
|
|
|