From edd64a396ef7a7227d5c45cc1deb61ef3e2b6112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20H=C3=B6ft?= Date: Wed, 6 Jul 2022 14:49:48 +0200 Subject: [PATCH] fix(core): adjustments for IPv6 --- Documentation/SOGoInstallationGuide.asciidoc | 13 +-- SoObjects/Mailer/SOGoMailBaseObject.m | 7 +- Tests/Unit/GNUmakefile | 1 + Tests/Unit/TestNGInternetSocketAddress.m | 3 +- Tests/Unit/TestNGNetUtlilities.m | 90 ++++++++++++++++++++ Tests/Unit/TestNSURL+misc.m | 24 ++++++ 6 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 Tests/Unit/TestNGNetUtlilities.m diff --git a/Documentation/SOGoInstallationGuide.asciidoc b/Documentation/SOGoInstallationGuide.asciidoc index bf9a06a62..61008c051 100644 --- a/Documentation/SOGoInstallationGuide.asciidoc +++ b/Documentation/SOGoInstallationGuide.asciidoc @@ -351,7 +351,7 @@ The following table describes the general parameters that can be set: |S |WOWorkersCount |The amount of instances of SOGo that will be spawned to handle multiple requests simultaneously. When started from the init -script, that amount is overriden by the `PREFORK` value +script, that amount is overridden by the `PREFORK` value in `/etc/sysconfig/sogo` or `/etc/default/sogo`. A value of 3 is a reasonable default for low usage. The maximum value depends on the CPU and IO power provided by your machine: a value set too high will @@ -369,7 +369,8 @@ Defaults to 5 when unset. |S |WOPort |The TCP listening address and port used by the SOGo -daemon. The format is `ipaddress:port`. +daemon. The format is `ipaddress:port`. To bind to an IPv6 address, use +`[ipv6address]:port`, e.g. `[::1]:20000`. Defaults to `127.0.0.1:20000` when unset. @@ -937,7 +938,7 @@ even when using multiple domains. |The field that returns the complete name. |IDFieldName -|The field that starts a user DN if bindFields is not used. This field +|The field that starts a user DN if bindFields is not used. This field must be unique across the entire SOGo domain. |UIDFieldName @@ -1136,14 +1137,14 @@ ModulesConstraints = { attributes used by the schema of the LDAP source. Each entry must have an attribute name as key and an array of strings as value. This enables actual fields to be mapped one after another when fetching contact -informations. +information. See the LDAP Attribute Mapping section below for an example and a list of supported attributes. |objectClasses |When the _modifiers_ list (see below) is set, or when using LDAP-based -user addressbooks (see _abOU_ below), this list of object classes will +user address books (see _abOU_ below), this list of object classes will be applied to new records as they are created. |GroupObjectClasses @@ -1156,7 +1157,7 @@ and `posixgroup`. modifications to the address book defined by this LDAP source. |abOU -|This field enables LDAP-based user addressbooks by specifying the value +|This field enables LDAP-based user address books by specifying the value of the address book container beneath each user entry, for example: `ou=addressbooks,uid=username,dc=domain`. |======================================================================= diff --git a/SoObjects/Mailer/SOGoMailBaseObject.m b/SoObjects/Mailer/SOGoMailBaseObject.m index b59b94a86..45385b05c 100644 --- a/SoObjects/Mailer/SOGoMailBaseObject.m +++ b/SoObjects/Mailer/SOGoMailBaseObject.m @@ -28,6 +28,7 @@ #import #import #import +#import #import #import @@ -138,7 +139,7 @@ NGImap4ConnectionManager *manager; NGImap4Connection *newConnection; NSString *password; - NSHost *host; + NGInternetSocketAddress *host; SOGoSystemDefaults *sd; BOOL usesSSO; @@ -147,14 +148,14 @@ // We first check if we're trying to establish an IMAP connection to localhost // for an account number greater than 0 (default account). We prevent that // for security reasons if admins use an IMAP trust. - host = [NSHost hostWithName: [[self imap4URL] host]]; + host = [NGInternetSocketAddress addressWithPort:0 onHost:[[self imap4URL] host]]; sd = [SOGoSystemDefaults sharedSystemDefaults]; usesSSO = [[sd authenticationType] isEqualToString: @"cas"] || [[sd authenticationType] isEqualToString: @"saml2"]; if (![[[self mailAccountFolder] nameInContainer] isEqualToString: @"0"] && usesSSO && - [[host address] isEqualToString: @"127.0.0.1"]) + [host isLocalhost]) { [self errorWithFormat: @"Trying to use localhost for additional IMAP account - aborting."]; return nil; diff --git a/Tests/Unit/GNUmakefile b/Tests/Unit/GNUmakefile index b9f7a8611..2cdee513f 100644 --- a/Tests/Unit/GNUmakefile +++ b/Tests/Unit/GNUmakefile @@ -26,6 +26,7 @@ $(TEST_TOOL)_OBJC_FILES += \ TestNGMimeMessageGenerator.m \ TestNGMimeType.m \ \ + TestNGNetUtlilities.m \ TestNSData+Crypto.m \ TestNSString+Crypto.m \ TestNSString+URLEscaping.m \ diff --git a/Tests/Unit/TestNGInternetSocketAddress.m b/Tests/Unit/TestNGInternetSocketAddress.m index b092ae39c..d0d787be3 100644 --- a/Tests/Unit/TestNGInternetSocketAddress.m +++ b/Tests/Unit/TestNGInternetSocketAddress.m @@ -31,8 +31,7 @@ - (void) test_isLocalhost { - // @"localhost6", - NSString *addrStr[] = { @"127.0.0.1", @"127.1.2.3", @"localhost", @"something.localhost", @"localhost.", nil }; + NSString *addrStr[] = { @"127.0.0.1", @"127.1.2.3", @"localhost", @"something.localhost", @"localhost.", @"::1", nil }; NSString **curHost; BOOL is_localhost; NSString *error; diff --git a/Tests/Unit/TestNGNetUtlilities.m b/Tests/Unit/TestNGNetUtlilities.m new file mode 100644 index 000000000..6b364ea08 --- /dev/null +++ b/Tests/Unit/TestNGNetUtlilities.m @@ -0,0 +1,90 @@ +/* TestNGNetUtilities.m - this file is part of SOGo + * + * Copyright (C) 2022 Nicolas Höft + * Copyright (C) Inverse Inc. + * + * Author: Nicolas Höft + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import +#import + +#import "SOGoTest.h" + +@interface TestNGNetUtilities : SOGoTest +@end + +@implementation TestNGNetUtilities + +- (void) test_NGInternetSocketAddressFromString +{ + NSArray *cases = [NSArray arrayWithObjects: + // input, host, port, isWildcard, isIpV4 + [NSArray arrayWithObjects: @"127.0.0.1:1000", @"127.0.0.1", [NSNumber numberWithInt: 1000], [NSNumber numberWithBool:NO], [NSNumber numberWithBool:YES], nil], + [NSArray arrayWithObjects: @"*:1001", @"*", [NSNumber numberWithInt:1001], [NSNumber numberWithBool:YES], [NSNumber numberWithBool:YES], nil], + [NSArray arrayWithObjects: @"0.0.0.0:1001", @"0.0.0.0", [NSNumber numberWithInt:1001], [NSNumber numberWithBool:YES], [NSNumber numberWithBool:YES], nil], + [NSArray arrayWithObjects: @"localhost:1001", @"localhost", [NSNumber numberWithInt:1001], [NSNumber numberWithBool:NO], [NSNumber numberWithBool:YES], nil], + [NSArray arrayWithObjects: @"localhost:echo", @"localhost", [NSNumber numberWithInt:7], [NSNumber numberWithBool:NO], [NSNumber numberWithBool:YES], nil], + [NSArray arrayWithObjects: @"[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:1234", @"2001:0db8:85a3:0000:0000:8a2e:0370:7334", [NSNumber numberWithInt:1234], [NSNumber numberWithBool:NO], [NSNumber numberWithBool:NO], nil], + [NSArray arrayWithObjects: @"[::1]:echo", @"::1", [NSNumber numberWithInt:7], [NSNumber numberWithBool:NO], [NSNumber numberWithBool:NO], nil], + [NSArray arrayWithObjects: @"[::]:echo", @"::", [NSNumber numberWithInt:7], [NSNumber numberWithBool:YES], [NSNumber numberWithBool:NO], nil], + nil + ]; + int i; + for (i = 0; i < [cases count]; i++) + { + NSString *error; + + NSArray *currentCase = [cases objectAtIndex: i]; + NSString *input = [currentCase objectAtIndex: 0]; + NSString *expectedHost = [currentCase objectAtIndex: 1]; + int expectedPort = [[currentCase objectAtIndex: 2] intValue]; + bool expectedIsWildcard = [[currentCase objectAtIndex: 3] boolValue]; + bool expectedIsIpV4 = [[currentCase objectAtIndex: 4] boolValue]; + NGInternetSocketAddress *addr = (NGInternetSocketAddress *)NGSocketAddressFromString(input); + NSString *host = [addr hostName]; + if (host == nil) + host = @"*"; + + error = [NSString stringWithFormat: + @"Hostname mismatch. Expected: '%@', result: '%@'. Test url: '%@'", + expectedHost, host, input]; + testWithMessage([host isEqualToString: expectedHost], error); + + int port = [addr port]; + error = [NSString stringWithFormat: + @"Port mismatch. Expected: '%d', result: '%d'. Test url: '%@'", + expectedPort, port, input]; + testWithMessage(port == expectedPort, error); + + BOOL isWildcard = [addr isWildcardAddress]; + error = [NSString stringWithFormat: + @"isWildcard mismatch. Expected: '%d', result: '%d'. Test url: '%@'", + expectedIsWildcard, isWildcard, input]; + testWithMessage(isWildcard == expectedIsWildcard, error); + + + BOOL isIPv4 = [addr isIPv4]; + error = [NSString stringWithFormat: + @"isIpv4 mismatch. Expected: '%d', result: '%d'. Test url: '%@'", + expectedIsIpV4, isIPv4, input]; + testWithMessage(isIPv4 == expectedIsIpV4, error); + } +} + +@end diff --git a/Tests/Unit/TestNSURL+misc.m b/Tests/Unit/TestNSURL+misc.m index a830e0cf2..ba2912b64 100644 --- a/Tests/Unit/TestNSURL+misc.m +++ b/Tests/Unit/TestNSURL+misc.m @@ -59,6 +59,30 @@ test([[queryComp valueForKey: @"key1"] isEqualToString: @"value123"]); test([[queryComp valueForKey: @"key2"] isEqualToString: @"val2"]); + urlStr = @"http://domain/path"; + url = [NSURL URLWithString: urlStr]; + queryComp = [url queryComponents]; + error = [NSString stringWithFormat: + @"expected '%@' to have no entries, got %d", urlStr, [queryComp count]]; + testWithMessage([queryComp count] == 0, error); + } +- (void) test_IpV6Address +{ + NSURL *url; + NSString *error; + NSString *host = @"2001:0db8:85a3:0000:0000:8a2e:0370:7334"; + NSString *urlhost; + url = [NSURL URLWithString: @"mysql://user:pass@[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:1234/path"]; + testWithMessage([[url scheme] isEqualToString: @"mysql"], @"unexpected scheme"); + urlhost = [url host]; + error = [NSString + stringWithFormat: @"hostname is '%@' instead of '%@' ", + host, urlhost]; + testWithMessage([urlhost isEqualToString: host], error); + testWithMessage([[url port] intValue] == 1234, @"port does not match"); +} + + @end