feat(core): Support smtps and STARTTLS for SMTP

Support uri schemes for SMTP, enabling STARTTLS and SMTPS for SMTP
connections.
The new format for configuration value SMTPServer supports passing a
URI scheme (either smtp:// or smtps://). To support old configurations,
if no scheme is given, smtp:// is assumed.

Fixes #31
pull/278/head
Nicolas Höft 2020-05-16 04:58:40 +02:00
parent 9198fc9bf6
commit cd3095e43b
5 changed files with 30 additions and 28 deletions

View File

@ -1642,10 +1642,16 @@ are:
|D |SOGoSMTPServer |D |SOGoSMTPServer
|The DNS name or IP address of the SMTP server used when |The DNS name or IP address of the SMTP server used when
_SOGoMailingMechanism_ is set to `smtp`. _SOGoMailingMechanism_ is set to `smtp`.
Supported formats are: `smtp://domain:port`, `smtps://domain`,
`domain:port`, `smtp://domain:port/?tls=YES`. Using the option
`tls=YES` will enforce using STARTTLS smtp connections. Thus,
`smtp://localhost:587/?tls=YES` would use the default MUA port
on localhost with STARTTLS enforced.
|D |SOGoSMTPAuthenticationType |D |SOGoSMTPAuthenticationType
|Activate SMTP authentication and specifies which type is in use. |Activate SMTP authentication and specifies which type is in use.
Current, only `PLAIN` is supported and other values will be ignored. Current, only `PLAIN` is supported and other values will cause
the authentication to fail.
|S |WOSendMail |S |WOSendMail
|The path of the sendmail binary. |The path of the sendmail binary.
@ -2214,7 +2220,7 @@ like this:
SOGoTrashFolderName = Trash; SOGoTrashFolderName = Trash;
SOGoJunkFolderName = Junk; SOGoJunkFolderName = Junk;
SOGoMailingMechanism = smtp; SOGoMailingMechanism = smtp;
SOGoSMTPServer = 127.0.0.1; SOGoSMTPServer = "smtp://127.0.0.1";
SOGoUserSources = ( SOGoUserSources = (
{ {
type = ldap; type = ldap;

View File

@ -26,7 +26,7 @@
//SOGoTrashFolderName = Trash; //SOGoTrashFolderName = Trash;
//SOGoIMAPServer = localhost; //SOGoIMAPServer = localhost;
//SOGoSieveServer = sieve://127.0.0.1:4190; //SOGoSieveServer = sieve://127.0.0.1:4190;
//SOGoSMTPServer = 127.0.0.1; //SOGoSMTPServer = "smtp://127.0.0.1";
//SOGoMailDomain = acme.com; //SOGoMailDomain = acme.com;
//SOGoMailingMechanism = smtp; //SOGoMailingMechanism = smtp;
//SOGoForceExternalLoginWithEmail = NO; //SOGoForceExternalLoginWithEmail = NO;

View File

@ -29,7 +29,7 @@
SOGoLDAPContactInfoAttribute = "description"; SOGoLDAPContactInfoAttribute = "description";
SOGoMailingMechanism = "sendmail"; SOGoMailingMechanism = "sendmail";
SOGoSMTPServer = "localhost"; SOGoSMTPServer = "smtp://localhost";
SOGoMailSpoolPath = "/var/spool/sogo"; SOGoMailSpoolPath = "/var/spool/sogo";
SOGoWebAccessEnabled = YES; SOGoWebAccessEnabled = YES;

View File

@ -242,7 +242,15 @@
- (NSString *) smtpServer - (NSString *) smtpServer
{ {
return [self stringForKey: @"SOGoSMTPServer"]; NSString *server;
server = [self stringForKey: @"SOGoSMTPServer"];
// backwards compatibility
if (![server hasPrefix: @"smtp://"] &&
![server hasPrefix: @"smtps://"])
{
return [NSString stringWithFormat: @"smtp://%@", server];
}
return server;
} }
- (NSString *) smtpAuthenticationType - (NSString *) smtpAuthenticationType

View File

@ -25,6 +25,7 @@
#import <NGObjWeb/NSException+HTTP.h> #import <NGObjWeb/NSException+HTTP.h>
#import <NGExtensions/NSObject+Logs.h> #import <NGExtensions/NSObject+Logs.h>
#import <NGExtensions/NSURL+misc.h>
#import <NGMail/NGSendMail.h> #import <NGMail/NGSendMail.h>
#import <NGMail/NGSmtpClient.h> #import <NGMail/NGSmtpClient.h>
#import <NGMime/NGMimePartGenerator.h> #import <NGMime/NGMimePartGenerator.h>
@ -221,40 +222,27 @@
} }
- (NSException *) _smtpSendData: (NSData *) mailData - (NSException *) _smtpSendData: (NSData *) mailData
toRecipients: (NSArray *) recipients toRecipients: (NSArray *) recipients
sender: (NSString *) sender sender: (NSString *) sender
withAuthenticator: (id <SOGoAuthenticator>) authenticator withAuthenticator: (id <SOGoAuthenticator>) authenticator
inContext: (WOContext *) woContext inContext: (WOContext *) woContext
{ {
NSString *currentTo, *host, *login, *password; NSString *currentTo, *login, *password;
NGInternetSocketAddress *addr;
NSMutableArray *toErrors; NSMutableArray *toErrors;
NSEnumerator *addresses; NSEnumerator *addresses;
NGSmtpClient *client; NGSmtpClient *client;
NSException *result; NSException *result;
NSRange r; NSURL * smtpUrl;
unsigned int port;
client = [NGSmtpClient smtpClient];
host = smtpServer;
result = nil; result = nil;
port = 25;
// We check if there is a port specified in the smtpServer ivar value smtpUrl = [[[NSURL alloc] initWithString: smtpServer] autorelease];
r = [smtpServer rangeOfString: @":"];
if (r.length)
{
port = [[smtpServer substringFromIndex: r.location+1] intValue];
host = [smtpServer substringToIndex: r.location];
}
addr = [NGInternetSocketAddress addressWithPort: port client = [NGSmtpClient clientWithURL: smtpUrl];
onHost: host];
NS_DURING NS_DURING
{ {
[client connectToAddress: addr]; [client connect];
if ([authenticationType isEqualToString: @"plain"]) if ([authenticationType isEqualToString: @"plain"])
{ {
/* XXX Allow static credentials by peeking at the classname */ /* XXX Allow static credentials by peeking at the classname */
@ -302,7 +290,7 @@
@" (smtp) all recipients discarded"]; @" (smtp) all recipients discarded"];
else if ([toErrors count] > 0) else if ([toErrors count] > 0)
result = [NSException exceptionWithHTTPStatus: 500 result = [NSException exceptionWithHTTPStatus: 500
reason: [NSString stringWithFormat: reason: [NSString stringWithFormat:
@"cannot send message (smtp) - recipients discarded:\n%@", @"cannot send message (smtp) - recipients discarded:\n%@",
[toErrors componentsJoinedByString: @", "]]]; [toErrors componentsJoinedByString: @", "]]];
else else
@ -318,7 +306,7 @@
} }
NS_HANDLER NS_HANDLER
{ {
[self errorWithFormat: @"Could not connect to the SMTP server %@ on port %d", host, port]; [self errorWithFormat: @"Could not connect to the SMTP server %@", smtpServer];
result = [NSException exceptionWithHTTPStatus: 500 result = [NSException exceptionWithHTTPStatus: 500
reason: @"cannot send message:" reason: @"cannot send message:"
@" (smtp) error when connecting"]; @" (smtp) error when connecting"];