From 56598d1e3777265ebb09fa19e7a719f673aaee40 Mon Sep 17 00:00:00 2001 From: Hivert Quentin Date: Tue, 1 Oct 2024 17:53:46 +0200 Subject: [PATCH] feat(login): add parameters to prevent uneccesary connection request when the domain is unknown --- Documentation/SOGoInstallationGuide.asciidoc | 12 ++++++ SoObjects/SOGo/SOGoSystemDefaults.h | 2 + SoObjects/SOGo/SOGoSystemDefaults.m | 13 ++++++- SoObjects/SOGo/SOGoUserManager.m | 40 +++++++++++++++++++- 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/Documentation/SOGoInstallationGuide.asciidoc b/Documentation/SOGoInstallationGuide.asciidoc index 7ba7fcd30..1524ecd60 100644 --- a/Documentation/SOGoInstallationGuide.asciidoc +++ b/Documentation/SOGoInstallationGuide.asciidoc @@ -806,6 +806,16 @@ Default value is `YES`, or enabled. authentication and global address books. Multiple sources can be specified as an array of dictionaries. +|S |SOGoForbidUnknownDomainsAuth +|Boolean. If set to `YES`, prevent user that try to connect with an unknown domain. +The known domains are set in parameter `SOGoDomainAllowed` and/or the domains listed in a <>. Default value is `NO`. + +Obiously, if your users can connect without specifying a domain, let this parameter to `NO`. + +|S |SOGoDomainAllowed +|Parameter used to define which domains SOGo should allowed during a connection request. This parameter is an array of strings. + + |S |SOGoPasswordRecoveryEnabled |Boolean enable password recovery with secret question or secondary e-mail. Default value is `NO`. @@ -2824,6 +2834,8 @@ like this: } ---- +[[multi-domains-configuration]] + Multi-domains Configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/SoObjects/SOGo/SOGoSystemDefaults.h b/SoObjects/SOGo/SOGoSystemDefaults.h index a0f617d11..9df14a873 100644 --- a/SoObjects/SOGo/SOGoSystemDefaults.h +++ b/SoObjects/SOGo/SOGoSystemDefaults.h @@ -36,6 +36,8 @@ static const NSString *kDisableSharingCalendar = @"Calendar"; + (SOGoSystemDefaults *) sharedSystemDefaults; - (NSArray *) domainIds; +- (BOOL) forbidUnknownDomainsAuth; +- (NSArray *) domainsAllowed; - (BOOL) enableDomainBasedUID; - (NSArray *) loginDomains; - (NSArray *) visibleDomainsForDomain: (NSString *) domain; diff --git a/SoObjects/SOGo/SOGoSystemDefaults.m b/SoObjects/SOGo/SOGoSystemDefaults.m index 40e590eca..03149bab9 100644 --- a/SoObjects/SOGo/SOGoSystemDefaults.m +++ b/SoObjects/SOGo/SOGoSystemDefaults.m @@ -258,7 +258,8 @@ _injectConfigurationFromFile (NSMutableDictionary *defaultsDict, - (NSArray *) domainIds { - return [[self dictionaryForKey: @"domains"] allKeys]; + NSDictionary *domains = [self dictionaryForKey: @"domains"]; + return [domains allKeys]; } - (BOOL) enableDomainBasedUID @@ -266,6 +267,16 @@ _injectConfigurationFromFile (NSMutableDictionary *defaultsDict, return [self boolForKey: @"SOGoEnableDomainBasedUID"]; } +- (BOOL) forbidUnknownDomainsAuth +{ + return [self boolForKey: @"SOGoForbidUnknownDomainsAuth"]; +} + +- (NSArray *) domainsAllowed +{ + return [NSMutableArray arrayWithArray: [self stringArrayForKey: @"SOGoDomainAllowed"]]; +} + - (NSArray *) loginDomains { NSMutableArray *filteredLoginDomains; diff --git a/SoObjects/SOGo/SOGoUserManager.m b/SoObjects/SOGo/SOGoUserManager.m index 1a8ed6b93..d0f93d43b 100644 --- a/SoObjects/SOGo/SOGoUserManager.m +++ b/SoObjects/SOGo/SOGoUserManager.m @@ -607,10 +607,48 @@ static const NSString *kObfuscatedSecondaryEmailKey = @"obfuscatedSecondaryEmail { *_domain = [username substringFromIndex: r.location+1]; - if (![[[SOGoSystemDefaults sharedSystemDefaults] domainIds] containsObject: *_domain]) + if (![[sd domainIds] containsObject: *_domain]) *_domain = nil; } } + + // If the domains is unknwon we reject the auth + if([sd forbidUnknownDomainsAuth]) + { + NSArray *domainsAllowed, *domainsKnown; + NSString *userDomain; + NSRange r; + BOOL allowed = NO; + if(!*_domain) + { + r = [username rangeOfString: @"@"]; + if(r.location != NSNotFound) + userDomain = [username substringFromIndex: r.location+1]; + else + userDomain = nil; + } + else + userDomain = *_domain; + + if(!userDomain) + { + [self errorWithFormat: @"User attempt to login without domain"]; + return allowed; + } + + + if((domainsAllowed = [sd domainsAllowed]) && [domainsAllowed containsObject: userDomain]) + allowed = YES; + if((domainsKnown = [sd domainIds]) && [domainsKnown containsObject: userDomain]) + allowed = YES; + + if([domainsKnown length] == 0 && [domainsAllowed length] == 0) + [self errorWithFormat: @"SOGoForbidUnknownDomainsAuth is set but sogo don't know any domains"]; + else if(!allowed) + [self errorWithFormat: @"User domain is unknown or not allowed: %@", userDomain]; + + return allowed; + } // We check the fail count per user in memcache (per server). If the // fail count reaches X in Y minutes, we deny immediately the