Skip to content

Commit

Permalink
Add support for CAS LogoutRequests
Browse files Browse the repository at this point in the history
Fixes #2346
This changes the serviceURL sent by SOGo to the CAS server:
  /SOGo/so/ -> /SOGo/so/index
  • Loading branch information
Jean Raby committed Jun 20, 2013
1 parent d284825 commit 41ed498
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 4 deletions.
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Bug fixes
- fixed public access when SOGoTrustProxyAuthentication is used (#2237)
- fixed access right issues with import feature (#2294)
- fixed IMAP ACL issue when SOGoForceExternalLoginWithEmail is used (#2313)
- fixed handling of CAS logoutRequest (#2346)
- OpenChange stability fixes

2.0.5a (2013-04-17)
Expand Down
3 changes: 2 additions & 1 deletion SoObjects/SOGo/GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ SOGo_OBJC_FILES = \

SOGo_RESOURCE_FILES = \
SOGoDefaults.plist \
DAVReportMap.plist
DAVReportMap.plist \
CASLogoutRequestMap.plist

ifeq ($(saml2_config), yes)
SOGo_HEADER_FILES += SOGoSAML2Session.h SOGoSAML2Exceptions.h
Expand Down
11 changes: 11 additions & 0 deletions SoObjects/SOGo/SOGoCASSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
+ (SOGoCASSession *) CASSessionWithIdentifier: (NSString *) newIdentifier
fromProxy: (BOOL) fromProxy;

+ (void) handleLogoutRequest: (NSString *) logoutRequest;

- (NSString *) identifier;

- (NSString *) ticket;
Expand All @@ -65,4 +67,13 @@

@end

@interface CASLogoutRequest : NSObject
{
NSString *sessionIndex;
}

- (NSString *) sessionIndex;

@end

#endif /* SOGOCASSESSION_H */
75 changes: 74 additions & 1 deletion SoObjects/SOGo/SOGoCASSession.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* Boston, MA 02111-1307, USA.
*/

#import <Foundation/NSBundle.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSURL.h>

Expand All @@ -35,6 +36,11 @@
#import <NGObjWeb/WOResponse.h>
#import <NGExtensions/NSObject+Logs.h>

#import <SaxObjC/SaxObjC.h>
#import <SaxObjC/SaxMethodCallHandler.h>
#import <SaxObjC/SaxObjectDecoder.h>
#import <SaxObjC/SaxXMLReaderFactory.h>

#import "NSDictionary+Utilities.h"
#import "NSString+Utilities.h"
#import "SOGoCache.h"
Expand Down Expand Up @@ -106,6 +112,43 @@ + (SOGoCASSession *) CASSessionWithIdentifier: (NSString *) newIdentifier
return session;
}

+ (void) handleLogoutRequest: (NSString *) logoutRequest
{
CASLogoutRequest *rq;
SOGoCache *cache;
NSBundle *bundle;
NSDictionary *root;
NSString *mapFile, *sessionIndex;

bundle = [NSBundle bundleForClass: [self class]];
mapFile = [bundle pathForResource: @"CASLogoutRequestMap" ofType: @"plist"];
if (![mapFile length])
{
[self errorWithFormat: @"mapFile not found (CASLogoutRequest.plist)"];
return;
}

id<NSObject,SaxXMLReader> parser = nil;
SaxObjectDecoder *sax = nil;
parser = [[SaxXMLReaderFactory standardXMLReaderFactory]
createXMLReaderForMimeType:@"text/xml"];

sax = [[SaxObjectDecoder alloc] initWithMappingAtPath: mapFile];
[sax autorelease];
[parser setContentHandler:sax];
[parser setErrorHandler:sax];
[parser parseFromSource: logoutRequest];

rq = [sax rootObject];
sessionIndex = [rq sessionIndex];

This comment has been minimized.

Copy link
@extrafu

extrafu Jun 20, 2013

Contributor

Shouldn't you retain it?

This comment has been minimized.

Copy link
@jraby

jraby Jun 21, 2013

Contributor

As per offline discussion, sessionIndex has a retainCount of 1 and isn't in an autorelease pool, so the current code id correct. Retaining it would leave the object with a rc of 1 forever.


if ([sessionIndex length])
{
cache = [SOGoCache sharedCache];

This comment has been minimized.

Copy link
@extrafu

extrafu Jun 20, 2013

Contributor

Should do:

[[SOGoCache sharedCache] removeCASSessionWithTicket: sessionIndex];

as you don't reuse it elsewhere.

[cache removeCASSessionWithTicket: sessionIndex];
}
}

- (id) init
{
if ((self = [super init]))
Expand Down Expand Up @@ -381,7 +424,12 @@ - (void) _fetchTicketData
NSString *serviceURL;

soURL = [[WOApplication application] soURL];
serviceURL = [soURL absoluteString];

/* appending 'index' to /SOGo/so/ so that callbacks made by the CAS server
* are not greeted with a 302 generated by sope. The CAS server doesn't
* follow redirects, and we'd end up losing the LogoutRequests
*/
serviceURL = [NSString stringWithFormat: @"%@index", [soURL absoluteString]];

params = [NSDictionary dictionaryWithObjectsAndKeys:
ticket, @"ticket", serviceURL, @"service",
Expand Down Expand Up @@ -466,3 +514,28 @@ - (void) invalidateTicketForService: (NSString *) service
}

@end

@implementation CASLogoutRequest

- (id) init
{
if ((self = [super init]))
{
sessionIndex = nil;
}

return self;
}

- (void) dealloc
{
[sessionIndex release];
[super dealloc];
}

- (NSString *) sessionIndex
{
return sessionIndex;
}

@end
2 changes: 2 additions & 0 deletions SoObjects/SOGo/SOGoCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@
- (void) setCASPGTId: (NSString *) pgtId
forPGTIOU: (NSString *) pgtIou;

- (void) removeCASSessionWithTicket: (NSString *) ticket;

// SAML2 support
- (NSDictionary *) saml2LoginDumpsForIdentifier: (NSString *) identifier;
- (void) setSaml2LoginDumps: (NSDictionary *) dump
Expand Down
11 changes: 11 additions & 0 deletions SoObjects/SOGo/SOGoCache.m
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,17 @@ - (void) setCASPGTId: (NSString *) pgtId
forKey: [NSString stringWithFormat: @"cas-pgtiou:%@", pgtIou]];
}

- (void) removeCASSessionWithTicket: (NSString *) ticket
{
NSString *key, *session;
if ((session = [self CASSessionWithTicket: ticket]))
{
key = [NSString stringWithFormat: @"cas-ticket:%@", ticket];
[self removeValueForKey: key];
[self debugWithFormat: @"Removed session: %@", session];
}
}

// SAML2 support
- (NSDictionary *) saml2LoginDumpsForIdentifier: (NSString *) identifier
{
Expand Down
19 changes: 17 additions & 2 deletions UI/MainUI/SOGoRootPage.m
Original file line number Diff line number Diff line change
Expand Up @@ -272,10 +272,13 @@ - (NSDictionary *) _casRedirectKeys
{
NSDictionary *redirectKeys;
NSURL *soURL;
NSString *serviceURL;

soURL = [[WOApplication application] soURL];
// appending 'index' to /SOGo/so/. Matches serviceURL sent by _pgtUrlFromURL
serviceURL = [NSString stringWithFormat: @"%@index", [soURL absoluteString]];

redirectKeys = [NSDictionary dictionaryWithObject: [soURL absoluteString]
redirectKeys = [NSDictionary dictionaryWithObject: serviceURL
forKey: @"service"];

return redirectKeys;
Expand All @@ -302,7 +305,7 @@ - (NSDictionary *) _casRedirectKeys
- (id <WOActionResults>) _casDefaultAction
{
WOResponse *response;
NSString *login, *newLocation, *oldLocation, *ticket;
NSString *login, *logoutRequest, *newLocation, *oldLocation, *ticket;
SOGoCASSession *casSession;
SOGoWebAuthenticator *auth;
WOCookie *casCookie, *casLocationCookie;
Expand Down Expand Up @@ -340,6 +343,18 @@ - (NSDictionary *) _casRedirectKeys
withName: @"cas-location"];
}
}
else
{
/* anonymous and no ticket, possibly a logout request from CAS
* See: https://wiki.jasig.org/display/CASUM/Single+Sign+Out
*/
logoutRequest = [rq formValueForKey: @"logoutRequest"];
if ([logoutRequest length])
{
[SOGoCASSession handleLogoutRequest: logoutRequest];
return [self responseWithStatus: 200];
}
}
}
else
ticket = nil;
Expand Down

0 comments on commit 41ed498

Please sign in to comment.