diff --git a/SoObjects/Mailer/SOGoDraftObject.m b/SoObjects/Mailer/SOGoDraftObject.m index 82d843a49..d120120ea 100644 --- a/SoObjects/Mailer/SOGoDraftObject.m +++ b/SoObjects/Mailer/SOGoDraftObject.m @@ -2278,7 +2278,7 @@ static NSString *userAgent = nil; NSData *message, *messageForSent; SOGoMailFolder *sentFolder; SOGoDomainDefaults *dd; - NSURL *sourceIMAP4URL; + NSURL *sourceIMAP4URL, *smtpUrl; NSException *error; dd = [[context activeUser] domainDefaults]; @@ -2307,13 +2307,28 @@ static NSString *userAgent = nil; return [NSException exceptionWithHTTPStatus: 500 reason: @"could not generate message content"]; - error = [[SOGoMailer mailerWithDomainDefaults: dd] - sendMailData: message - toRecipients: [NSArray arrayWithObject: recipient] - sender: [self sender] - withAuthenticator: [self authenticatorInContext: context] - inContext: context - systemMessage: NO]; + smtpUrl = [self smtp4URL]; + + if (smtpUrl) + { + error = [[SOGoMailer mailerWithDomainDefaultsAndSmtpUrl: dd smtpUrl: smtpUrl] + sendMailData: message + toRecipients: [NSArray arrayWithObject: recipient] + sender: [self sender] + withAuthenticator: [self authenticatorInContext: context] + inContext: context + systemMessage: NO]; + } + else + { + error = [[SOGoMailer mailerWithDomainDefaults: dd] + sendMailData: message + toRecipients: [NSArray arrayWithObject: recipient] + sender: [self sender] + withAuthenticator: [self authenticatorInContext: context] + inContext: context + systemMessage: NO]; + } if (error) { [self cleanTmpFiles]; @@ -2335,7 +2350,9 @@ static NSString *userAgent = nil; return [NSException exceptionWithHTTPStatus: 500 reason: @"could not generate message content"]; - error = [[SOGoMailer mailerWithDomainDefaults: dd] + smtpUrl = [self smtp4URL]; + + error = [[SOGoMailer mailerWithDomainDefaultsAndSmtpUrl: dd smtpUrl: smtpUrl] sendMailData: message toRecipients: [self allBareRecipients] sender: [self sender] diff --git a/SoObjects/Mailer/SOGoMailAccount.h b/SoObjects/Mailer/SOGoMailAccount.h index dc90471ca..4c8e86d6e 100644 --- a/SoObjects/Mailer/SOGoMailAccount.h +++ b/SoObjects/Mailer/SOGoMailAccount.h @@ -95,7 +95,10 @@ typedef enum { - (NSDictionary *) identityForEmail: (NSString *) email; - (NSString *) signature; - (NSString *) encryption; +- (NSString *) smtpEncryption; - (NSString *) tlsVerifyMode; +- (NSString *) smtpTlsVerifyMode; +- (NSMutableString *) smtp4URLString; /* folder pathes */ - (NSArray *) toManyRelationshipKeysWithNamespaces: (BOOL) withNSs; diff --git a/SoObjects/Mailer/SOGoMailAccount.m b/SoObjects/Mailer/SOGoMailAccount.m index 28398808f..ffccf9b3d 100644 --- a/SoObjects/Mailer/SOGoMailAccount.m +++ b/SoObjects/Mailer/SOGoMailAccount.m @@ -800,6 +800,17 @@ static NSString *inboxFolderName = @"INBOX"; return encryption; } +- (NSString *) smtpEncryption +{ + NSString *encryption; + + encryption = [[self _mailAccount] objectForKey: @"smtpEncryption"]; + if (![encryption length]) + encryption = @"none"; + + return encryption; +} + - (NSString *) tlsVerifyMode { NSString *verifyMode; @@ -811,6 +822,17 @@ static NSString *inboxFolderName = @"INBOX"; return verifyMode; } +- (NSString *) smtpTlsVerifyMode +{ + NSString *verifyMode; + + verifyMode = [[self _mailAccount] objectForKey: @"smtpTlsVerifyMode"]; + if (!verifyMode || ![verifyMode length]) + verifyMode = @"default"; + + return verifyMode; +} + - (NSMutableString *) imap4URLString { NSMutableString *imap4URLString; @@ -849,6 +871,42 @@ static NSString *inboxFolderName = @"INBOX"; return imap4URLString; } +- (NSMutableString *) smtp4URLString +{ + NSMutableString *smtp4URLString; + NSDictionary *mailAccount; + NSString *encryption, *protocol, *smtpServerName; + int defaultPort, port; + + mailAccount = [self _mailAccount]; + smtpServerName = [mailAccount objectForKey: @"smtpServerName"]; + if(!smtpServerName) + return nil; //Auxiliary account can be only configured for imap and not smtp + encryption = [mailAccount objectForKey: @"smtpEncryption"]; + defaultPort = 25; + protocol = @"smtp"; + + if ([encryption isEqualToString: @"ssl"]) + { + protocol = @"smtps"; + defaultPort = 465; + } + else if ([encryption isEqualToString: @"tls"]) + { + protocol = @"smtps"; + defaultPort = 465; + } + + smtp4URLString = [NSMutableString stringWithFormat: @"%@://%@", protocol, smtpServerName]; + port = [[mailAccount objectForKey: @"smtpPort"] intValue]; + if (port && port != defaultPort) + [smtp4URLString appendFormat: @":%d", port]; + + [smtp4URLString appendString: @"/"]; + + return smtp4URLString; +} + - (NSMutableString *) traversalFromMailAccount { return [NSMutableString string]; diff --git a/SoObjects/Mailer/SOGoMailBaseObject.h b/SoObjects/Mailer/SOGoMailBaseObject.h index 43306d76a..6bbaa2fce 100644 --- a/SoObjects/Mailer/SOGoMailBaseObject.h +++ b/SoObjects/Mailer/SOGoMailBaseObject.h @@ -46,6 +46,7 @@ @interface SOGoMailBaseObject : SOGoObject { NSURL *imap4URL; + NSURL *smtp4URL; NGImap4Connection *imap4; BOOL imap4ExceptionsEnabled; } @@ -74,6 +75,7 @@ - (NSMutableString *) traversalFromMailAccount; - (NSURL *) imap4URL; +- (NSURL *) smtp4URL; - (NSString *) imap4PasswordRenewed: (BOOL) renew; - (void) flushMailCaches; diff --git a/SoObjects/Mailer/SOGoMailBaseObject.m b/SoObjects/Mailer/SOGoMailBaseObject.m index 45385b05c..8c9b4f215 100644 --- a/SoObjects/Mailer/SOGoMailBaseObject.m +++ b/SoObjects/Mailer/SOGoMailBaseObject.m @@ -71,6 +71,7 @@ - (void) dealloc { [imap4URL release]; + [smtp4URL release]; [imap4 release]; [super dealloc]; } @@ -317,6 +318,35 @@ return imap4URL; } +- (NSURL *) smtp4URL +{ + SOGoMailAccount *account; + NSString *urlString, *smtpUrl; + NSString *useTls = @"NO"; + + /* this could probably be handled better from NSURL but it's buggy in + GNUstep */ + if (!smtp4URL) + { + account = [self mailAccountFolder]; + smtpUrl = [account smtp4URLString]; + if(smtpUrl) + { + if ([[account smtpEncryption] isEqualToString: @"tls"]) + { + useTls = @"YES"; + } + urlString = [NSString stringWithFormat: @"%@?tls=%@&tlsVerifyMode=%@", + smtpUrl, useTls, [account smtpTlsVerifyMode]]; + smtp4URL = [[NSURL alloc] initWithString: urlString]; + } + else + smtp4URL = nil; + } + + return smtp4URL; +} + - (NSString *) imap4PasswordRenewed: (BOOL) renewed { return [[self mailAccountFolder] imap4PasswordRenewed: renewed]; diff --git a/SoObjects/SOGo/SOGoMailer.h b/SoObjects/SOGo/SOGoMailer.h index 5b33933a0..73934e8da 100644 --- a/SoObjects/SOGo/SOGoMailer.h +++ b/SoObjects/SOGo/SOGoMailer.h @@ -43,6 +43,8 @@ } + (SOGoMailer *) mailerWithDomainDefaults: (SOGoDomainDefaults *) dd; ++ (SOGoMailer *) mailerWithDomainDefaultsAndSmtpUrl: (SOGoDomainDefaults *) dd + smtpUrl: (NSURL *) smtpUrl; - (id) initWithDomainDefaults: (SOGoDomainDefaults *) dd; - (BOOL) requiresAuthentication; diff --git a/SoObjects/SOGo/SOGoMailer.m b/SoObjects/SOGo/SOGoMailer.m index 775005287..94c154758 100644 --- a/SoObjects/SOGo/SOGoMailer.m +++ b/SoObjects/SOGo/SOGoMailer.m @@ -148,6 +148,13 @@ return [[self alloc] initWithDomainDefaults: dd]; } ++ (SOGoMailer *) mailerWithDomainDefaultsAndSmtpUrl: (SOGoDomainDefaults *) dd + smtpUrl: (NSURL *) smtpUrl +{ + return [[self alloc] initWithDomainDefaultsAndSmtpUrl: dd + smtpUrl: smtpUrl]; +} + - (id) initWithDomainDefaults: (SOGoDomainDefaults *) dd { if ((self = [self init])) @@ -157,8 +164,23 @@ smtpMasterUserEnabled = [dd smtpMasterUserEnabled]; ASSIGN (smtpMasterUserUsername, [dd smtpMasterUserUsername]); ASSIGN (smtpMasterUserPassword, [dd smtpMasterUserPassword]); - ASSIGN (authenticationType, - [[dd smtpAuthenticationType] lowercaseString]); + ASSIGN (authenticationType, [[dd smtpAuthenticationType] lowercaseString]); + } + + return self; +} + +- (id) initWithDomainDefaultsAndSmtpUrl: (SOGoDomainDefaults *) dd + smtpUrl: (NSURL *) smtpUrl +{ + if ((self = [self init])) + { + ASSIGN (mailingMechanism, [dd mailingMechanism]); + ASSIGN (smtpServer, [smtpUrl absoluteString]); + smtpMasterUserEnabled = [dd smtpMasterUserEnabled]; + ASSIGN (smtpMasterUserUsername, [dd smtpMasterUserUsername]); + ASSIGN (smtpMasterUserPassword, [dd smtpMasterUserPassword]); + ASSIGN (authenticationType, [[dd smtpAuthenticationType] lowercaseString]); } return self; @@ -242,9 +264,12 @@ NGSmtpClient *client; NSException *result; NSURL * smtpUrl; + SOGoUser* user; result = nil; + //find the smtpurl for the account + smtpUrl = [[[NSURL alloc] initWithString: smtpServer] autorelease]; client = [NGSmtpClient clientWithURL: smtpUrl]; diff --git a/SoObjects/SOGo/SOGoUser.m b/SoObjects/SOGo/SOGoUser.m index 4dfc86e5e..5d22e3e5e 100644 --- a/SoObjects/SOGo/SOGoUser.m +++ b/SoObjects/SOGo/SOGoUser.m @@ -650,16 +650,17 @@ static const NSString *kEncryptedUserNamePrefix = @"uenc"; - (void) _appendSystemMailAccountWithDelegatedIdentities: (BOOL) appendDeletegatedIdentities { - NSString *fullName, *imapLogin, *imapServer, *cImapServer, - *encryption, *scheme, *action, *queryTls, *customEmail, *sieveServer, *tlsVerifyMode; + NSString *fullName, *imapLogin, *imapServer, *cImapServer, *smtpServer, + *imapEncryption, *smtpEncryption, *imapScheme, *smtpScheme, *action, *imapQueryTls, *smtpQueryTls, + *customEmail, *sieveServer, *imapTlsVerifyMode, *smtpTlsVerifyMode; NSMutableDictionary *mailAccount, *identity, *mailboxes, *receipts, *security, *mailSettings; - NSDictionary *queryComponents; - NSNumber *port; + NSDictionary *imapQueryComponents, *smtpQueryComponents; + NSNumber *imapPort, *smtpPort; NSMutableArray *identities, *mails; NSArray *delegators, *delegates; - NSURL *url, *cUrl; + NSURL *imapUrl, *cImapUrl, *smtpUrl; unsigned int count, max; //, default_identity; - NSInteger defaultPort; + NSInteger imapDefaultPort, smtpDefaultPort; NSUInteger index; BOOL hasDefaultIdentity; @@ -675,7 +676,7 @@ static const NSString *kEncryptedUserNamePrefix = @"uenc"; inDomain: [self domain]]; [mailAccount setObject: imapLogin forKey: @"userName"]; - // 2. server + // 2.1 IMAP server // imapServer might have the following format // localhost // localhost:143 @@ -687,57 +688,105 @@ static const NSString *kEncryptedUserNamePrefix = @"uenc"; cImapServer = [self _fetchFieldForUser: @"c_imaphostname"]; imapServer = [[self domainDefaults] imapServer]; - cUrl = [NSURL URLWithString: (cImapServer ? cImapServer : @"")]; - url = [NSURL URLWithString: imapServer]; - if([cUrl host]) - imapServer = [cUrl host]; + cImapUrl = [NSURL URLWithString: (cImapServer ? cImapServer : @"")]; + imapUrl = [NSURL URLWithString: imapServer]; + if([cImapUrl host]) + imapServer = [cImapUrl host]; else if(cImapServer) imapServer = cImapServer; else - if([url host]) - imapServer = [url host]; + if([imapUrl host]) + imapServer = [imapUrl host]; [mailAccount setObject: imapServer forKey: @"serverName"]; - // 3. port & encryption - scheme = [cUrl scheme] ? [cUrl scheme] : [url scheme]; - queryComponents = [cUrl query] ? [cUrl queryComponents] : [url queryComponents]; - queryTls = [queryComponents valueForKey: @"tls"]; - tlsVerifyMode = [queryComponents valueForKey: @"tlsVerifyMode"]; + // 2.2 IMAP port & encryption + imapScheme = [cImapUrl scheme] ? [cImapUrl scheme] : [imapUrl scheme]; + imapQueryComponents = [cImapUrl query] ? [cImapUrl queryComponents] : [imapUrl queryComponents]; + imapQueryTls = [imapQueryComponents valueForKey: @"tls"]; + imapTlsVerifyMode = [imapQueryComponents valueForKey: @"tlsVerifyMode"]; - if (!tlsVerifyMode) - tlsVerifyMode = @"default"; + if (!imapTlsVerifyMode) + imapTlsVerifyMode = @"default"; - if (scheme - && [scheme caseInsensitiveCompare: @"imaps"] == NSOrderedSame) + if (imapScheme && [imapScheme caseInsensitiveCompare: @"imaps"] == NSOrderedSame) { - if (queryTls && [queryTls caseInsensitiveCompare: @"YES"] == NSOrderedSame) + if (imapQueryTls && [imapQueryTls caseInsensitiveCompare: @"YES"] == NSOrderedSame) { - defaultPort = 143; - encryption = @"tls"; + imapDefaultPort = 143; + imapEncryption = @"tls"; } else { - encryption = @"ssl"; - defaultPort = 993; + imapEncryption = @"ssl"; + imapDefaultPort = 993; } } else { - if (queryTls && [queryTls caseInsensitiveCompare: @"YES"] == NSOrderedSame) - encryption = @"tls"; + if (imapQueryTls && [imapQueryTls caseInsensitiveCompare: @"YES"] == NSOrderedSame) + imapEncryption = @"tls"; else - encryption = @"none"; + imapEncryption = @"none"; - defaultPort = 143; + imapDefaultPort = 143; } - port = [cUrl port] ? [cUrl port] : [url port]; - if ([port intValue] == 0) /* port is nil or intValue == 0 */ - port = [NSNumber numberWithInt: defaultPort]; - [mailAccount setObject: port forKey: @"port"]; - [mailAccount setObject: encryption forKey: @"encryption"]; - [mailAccount setObject: tlsVerifyMode forKey: @"tlsVerifyMode"]; + imapPort = [cImapUrl port] ? [cImapUrl port] : [imapUrl port]; + if ([imapPort intValue] == 0) /* port is nil or intValue == 0 */ + imapPort = [NSNumber numberWithInt: imapDefaultPort]; + [mailAccount setObject: imapPort forKey: @"port"]; + [mailAccount setObject: imapEncryption forKey: @"encryption"]; + [mailAccount setObject: imapTlsVerifyMode forKey: @"tlsVerifyMode"]; + + //3.1 SMTP server + smtpServer = [[self domainDefaults] smtpServer]; + smtpUrl = [NSURL URLWithString: smtpServer]; + if([smtpUrl host]) + smtpServer = [smtpUrl host]; + [mailAccount setObject: smtpServer forKey: @"smtpServerName"]; + + // 3.2 SMTP port and encryption + smtpScheme = [smtpUrl scheme]; + smtpQueryComponents = [smtpUrl queryComponents]; + smtpQueryTls = [smtpQueryComponents valueForKey: @"tls"]; + smtpTlsVerifyMode = [smtpQueryComponents valueForKey: @"tlsVerifyMode"]; + + if (!smtpTlsVerifyMode) + smtpTlsVerifyMode = @"default"; + + if (smtpScheme && [smtpScheme caseInsensitiveCompare: @"smtps"] == NSOrderedSame) + { + if (smtpQueryTls && [smtpQueryTls caseInsensitiveCompare: @"YES"] == NSOrderedSame) + { + smtpDefaultPort = 465; //Shoud be 587 but sope sope-mime/NGMail/NGSmtpClient.m initWithUrl doesn't agree... + smtpEncryption = @"tls"; + } + else + { + smtpEncryption = @"ssl"; + smtpDefaultPort = 465; //Shoud be 587 but sope sope-mime/NGMail/NGSmtpClient.m initWithUrl doesn't agree... + } + } + else + { + if (smtpQueryTls && [smtpQueryTls caseInsensitiveCompare: @"YES"] == NSOrderedSame) + { + smtpEncryption = @"tls"; + smtpDefaultPort = 465; + } + else { + smtpEncryption = @"none"; + smtpDefaultPort = 25; + } + } + + smtpPort = [smtpUrl port]; + if ([smtpPort intValue] == 0) /* port is nil or intValue == 0 */ + smtpPort = [NSNumber numberWithInt: smtpDefaultPort]; + [mailAccount setObject: smtpPort forKey: @"smtpPort"]; + [mailAccount setObject: smtpEncryption forKey: @"smtpEncryption"]; + [mailAccount setObject: smtpTlsVerifyMode forKey: @"smtpTlsVerifyMode"]; // 4. Sieve server sieveServer = [self _fetchFieldForUser: @"c_sievehostname"]; diff --git a/UI/PreferencesUI/English.lproj/Localizable.strings b/UI/PreferencesUI/English.lproj/Localizable.strings index 0aea5dd48..7d3abe4ba 100644 --- a/UI/PreferencesUI/English.lproj/Localizable.strings +++ b/UI/PreferencesUI/English.lproj/Localizable.strings @@ -231,8 +231,10 @@ "Mail Account" = "Mail Account"; "New Mail Account" = "New Mail Account"; "Server Name" = "Server Name"; +"Outgoing Server Name (SMTP)" = "Outgoing Server Name (SMTP)"; "Port" = "Port"; "Encryption" = "Encryption"; +"Outgoing Encryption" = "Outgoing Encryption"; "None" = "None"; "User Name" = "User Name"; "Full Name" = "Full Name"; diff --git a/UI/PreferencesUI/French.lproj/Localizable.strings b/UI/PreferencesUI/French.lproj/Localizable.strings index e39bebfb4..14b4d5d45 100644 --- a/UI/PreferencesUI/French.lproj/Localizable.strings +++ b/UI/PreferencesUI/French.lproj/Localizable.strings @@ -231,8 +231,10 @@ "Mail Account" = "Compte courriel"; "New Mail Account" = "Nouveau compte"; "Server Name" = "Serveur"; +"Outgoing Server Name (SMTP)" = "Serveur sortant (SMTP)"; "Port" = "Port"; "Encryption" = "Chiffrement"; +"Outgoing Encryption" = "Chiffrement sortant"; "None" = "Aucun"; "User Name" = "Utilisateur"; "Full Name" = "Nom complet"; diff --git a/UI/PreferencesUI/UIxPreferences.m b/UI/PreferencesUI/UIxPreferences.m index 22ade23c7..2169f0c7e 100644 --- a/UI/PreferencesUI/UIxPreferences.m +++ b/UI/PreferencesUI/UIxPreferences.m @@ -1358,6 +1358,7 @@ static NSArray *reminderValues = nil; if (!knownKeys) { knownKeys = [NSArray arrayWithObjects: @"id", @"name", @"serverName", @"port", + @"smtpServerName", @"smtpPort", @"smtpEncryption", @"userName", @"password", @"encryption", @"replyTo", @"identities", @"mailboxes", @"forceDefaultIdentity", @"receipts", @"security", @"isNew", diff --git a/UI/Templates/PreferencesUI/UIxAccountEditor.wox b/UI/Templates/PreferencesUI/UIxAccountEditor.wox index d4dec3803..f35388784 100644 --- a/UI/Templates/PreferencesUI/UIxAccountEditor.wox +++ b/UI/Templates/PreferencesUI/UIxAccountEditor.wox @@ -77,6 +77,54 @@ +
+ + + +
+
+
+
+ + + + + +
+ + + + +
+
+ +
+
+ +
+
+ +
+
+
+
+
diff --git a/UI/WebServerResources/js/Preferences/AccountDialogController.js b/UI/WebServerResources/js/Preferences/AccountDialogController.js index 7042e2780..cab7d4bd6 100644 --- a/UI/WebServerResources/js/Preferences/AccountDialogController.js +++ b/UI/WebServerResources/js/Preferences/AccountDialogController.js @@ -12,6 +12,7 @@ var vm = this, usesSSO = $window.usesCASAuthentication || $window.usesSAML2Authentication; this.defaultPort = 143; + this.smtpDefaultPort = 25; this.defaults = defaults; this.account = account; this.maxSize = maxSize; @@ -30,6 +31,11 @@ else if (this.account.encryption == "ssl") this.defaultPort = 993; + if (!this.account.smtpEncryption) + this.account.smtpEncryption = "none"; + else + this.smtpDefaultPort = 465; + _loadCertificate(); this.uploader = new FileUploader({