diff --git a/Documentation/SOGo Installation Guide.odt b/Documentation/SOGo Installation Guide.odt index b63476e27..5d3c11b8f 100644 Binary files a/Documentation/SOGo Installation Guide.odt and b/Documentation/SOGo Installation Guide.odt differ diff --git a/SoObjects/Appointments/SOGoCalendarComponent.m b/SoObjects/Appointments/SOGoCalendarComponent.m index a33d5fb4c..e40bfd306 100644 --- a/SoObjects/Appointments/SOGoCalendarComponent.m +++ b/SoObjects/Appointments/SOGoCalendarComponent.m @@ -862,9 +862,12 @@ /* send the damn thing */ [[SOGoMailer mailerWithDomainDefaults: dd] - sendMimePart: msg - toRecipients: [NSArray arrayWithObject: email] - sender: shortSenderEmail]; + sendMimePart: msg + toRecipients: [NSArray arrayWithObject: email] + sender: shortSenderEmail + withAuthenticator: [self + authenticatorInContext: context] + inContext: context]; } } } @@ -946,9 +949,11 @@ /* send the damn thing */ email = [recipient rfc822Email]; [[SOGoMailer mailerWithDomainDefaults: dd] - sendMimePart: msg - toRecipients: [NSArray arrayWithObject: email] - sender: [attendee rfc822Email]]; + sendMimePart: msg + toRecipients: [NSArray arrayWithObject: email] + sender: [attendee rfc822Email] + withAuthenticator: [self authenticatorInContext: context] + inContext: context]; } } @@ -989,6 +994,7 @@ NGMimeMessage *msg; SOGoUser *currentUser; SOGoDomainDefaults *dd; + id authenticator; calendarName = [[self container] displayName]; @@ -1039,6 +1045,8 @@ /* text part */ mailText = [page getBody]; [msg setBody: [mailText dataUsingEncoding: NSUTF8StringEncoding]]; + + authenticator = [self authenticatorInContext: context]; if ([self->owner isEqualToString: [currentUser login]]) { @@ -1047,7 +1055,9 @@ [[SOGoMailer mailerWithDomainDefaults: dd] sendMimePart: msg toRecipients: [NSArray arrayWithObject: recipientEmail] - sender: senderEmail]; + sender: senderEmail + withAuthenticator: authenticator + inContext: context]; } if ([[self container] notifyUserOnPersonalModifications]) @@ -1061,7 +1071,9 @@ [[SOGoMailer mailerWithDomainDefaults: dd] sendMimePart: msg toRecipients: [NSArray arrayWithObject: recipientEmail] - sender: senderEmail]; + sender: senderEmail + withAuthenticator: authenticator + inContext: context]; [headerMap setObject: o forKey: @"to"]; } @@ -1074,7 +1086,9 @@ [[SOGoMailer mailerWithDomainDefaults: dd] sendMimePart: msg toRecipients: [NSArray arrayWithObject: recipientEmail] - sender: senderEmail]; + sender: senderEmail + withAuthenticator: authenticator + inContext: context]; } } diff --git a/SoObjects/Mailer/SOGoDraftObject.m b/SoObjects/Mailer/SOGoDraftObject.m index e1770d0dc..e335bf13e 100644 --- a/SoObjects/Mailer/SOGoDraftObject.m +++ b/SoObjects/Mailer/SOGoDraftObject.m @@ -1569,9 +1569,11 @@ static NSString *userAgent = nil; dd = [[context activeUser] domainDefaults]; error = [[SOGoMailer mailerWithDomainDefaults: dd] - sendMailData: cleaned_message - toRecipients: [self allBareRecipients] - sender: [self sender]]; + sendMailData: cleaned_message + toRecipients: [self allBareRecipients] + sender: [self sender] + withAuthenticator: [self authenticatorInContext: context] + inContext: context]; if (!error && copyToSent) { sentFolder = [[self mailAccountFolder] sentFolderInContext: context]; diff --git a/SoObjects/SOGo/SOGoDomainDefaults.h b/SoObjects/SOGo/SOGoDomainDefaults.h index 2e44b32a0..d7fce3bad 100644 --- a/SoObjects/SOGo/SOGoDomainDefaults.h +++ b/SoObjects/SOGo/SOGoDomainDefaults.h @@ -53,6 +53,7 @@ - (BOOL) vacationEnabled; - (NSString *) mailingMechanism; - (NSString *) smtpServer; +- (NSString *) smtpAuthenticationType; - (NSString *) mailSpoolPath; - (float) softQuotaRatio; - (BOOL) mailKeepDraftsAfterSend; diff --git a/SoObjects/SOGo/SOGoDomainDefaults.m b/SoObjects/SOGo/SOGoDomainDefaults.m index 4b1db7b0f..1b822b487 100644 --- a/SoObjects/SOGo/SOGoDomainDefaults.m +++ b/SoObjects/SOGo/SOGoDomainDefaults.m @@ -218,6 +218,11 @@ return [self stringForKey: @"SOGoSMTPServer"]; } +- (NSString *) smtpAuthenticationType +{ + return [self stringForKey: @"SOGoSMTPAuthenticationType"]; +} + - (NSString *) mailSpoolPath { return [self stringForKey: @"SOGoMailSpoolPath"]; diff --git a/SoObjects/SOGo/SOGoMailer.h b/SoObjects/SOGo/SOGoMailer.h index 52ca73cfa..6ebc0ef7d 100644 --- a/SoObjects/SOGo/SOGoMailer.h +++ b/SoObjects/SOGo/SOGoMailer.h @@ -29,14 +29,17 @@ @class NSException; @class NSString; +@class WOContext; @class SOGoDomainDefaults; @protocol NGMimePart; +@protocol SOGoAuthenticator; @interface SOGoMailer : NSObject { NSString *mailingMechanism; NSString *smtpServer; + NSString *authenticationType; } + (SOGoMailer *) mailerWithDomainDefaults: (SOGoDomainDefaults *) dd; @@ -45,13 +48,19 @@ - (NSException *) sendMailData: (NSData *) data toRecipients: (NSArray *) recipients - sender: (NSString *) sender; + sender: (NSString *) sender + withAuthenticator: (id ) authenticator + inContext: (WOContext *) woContext; - (NSException *) sendMailAtPath: (NSString *) filename toRecipients: (NSArray *) recipients - sender: (NSString *) sender; + sender: (NSString *) sender + withAuthenticator: (id ) authenticator + inContext: (WOContext *) woContext; - (NSException *) sendMimePart: (id ) part toRecipients: (NSArray *) recipients - sender: (NSString *) sender; + sender: (NSString *) sender + withAuthenticator: (id ) authenticator + inContext: (WOContext *) woContext; @end diff --git a/SoObjects/SOGo/SOGoMailer.m b/SoObjects/SOGo/SOGoMailer.m index 619d62f9a..f792669ac 100644 --- a/SoObjects/SOGo/SOGoMailer.m +++ b/SoObjects/SOGo/SOGoMailer.m @@ -33,8 +33,10 @@ #import #import "NSString+Utilities.h" +#import "SOGoAuthenticator.h" #import "SOGoDomainDefaults.h" #import "SOGoSystemDefaults.h" +#import "SOGoUser.h" #import "SOGoMailer.h" @@ -51,6 +53,8 @@ { ASSIGN (mailingMechanism, [dd mailingMechanism]); ASSIGN (smtpServer, [dd smtpServer]); + ASSIGN (authenticationType, + [[dd smtpAuthenticationType] lowercaseString]); } return self; @@ -62,6 +66,7 @@ { mailingMechanism = nil; smtpServer = nil; + authenticationType = nil; } return self; @@ -71,6 +76,7 @@ { [mailingMechanism release]; [smtpServer release]; + [authenticationType release]; [super dealloc]; } @@ -112,15 +118,16 @@ - (NSException *) _smtpSendData: (NSData *) mailData toRecipients: (NSArray *) recipients sender: (NSString *) sender + withAuthenticator: (id ) authenticator + inContext: (WOContext *) woContext { NGInternetSocketAddress *addr; - NSString *currentTo, *host; + NSString *currentTo, *host, *login, *password; NSMutableArray *toErrors; NSEnumerator *addresses; NGSmtpClient *client; - NSException *result; + NSException *result = nil; NSRange r; - unsigned int port; client = [NGSmtpClient smtpClient]; @@ -142,36 +149,57 @@ NS_DURING { [client connectToAddress: addr]; - if ([client mailFrom: sender]) - { - toErrors = [NSMutableArray array]; - addresses = [recipients objectEnumerator]; - currentTo = [addresses nextObject]; - while (currentTo) - { - if (![client recipientTo: [currentTo pureEMailAddress]]) - { - [self logWithFormat: @"error with recipient '%@'", currentTo]; - [toErrors addObject: [currentTo pureEMailAddress]]; - } - currentTo = [addresses nextObject]; - } - if ([toErrors count] == [recipients count]) - result = [NSException exceptionWithHTTPStatus: 500 - reason: @"cannot send message:" - @" (smtp) all recipients discarded"]; - else if ([toErrors count] > 0) - result = [NSException exceptionWithHTTPStatus: 500 - reason: [NSString stringWithFormat: - @"cannot send message (smtp) - recipients discarded:\n%@", - [toErrors componentsJoinedByString: @", "]]]; - else - result = [self _sendMailData: mailData withClient: client]; - } - else + if ([authenticationType isEqualToString: @"plain"]) + { + login = [[authenticator userInContext: woContext] login]; + password = [authenticator passwordInContext: woContext]; + if ([login length] == 0 + || [login isEqualToString: @"anonymous"] + || ![client plainAuthenticateUser: login + withPassword: password]) + result = [NSException + exceptionWithHTTPStatus: 500 + reason: @"cannot send message:" + @" (smtp) authentication failure"]; + } + else if (authenticationType) result = [NSException exceptionWithHTTPStatus: 500 - reason: @"cannot send message: (smtp) originator not accepted"]; + reason: @"cannot send message:" + @" unsupported authentication method"]; + if (!result) + { + if ([client mailFrom: sender]) + { + toErrors = [NSMutableArray array]; + addresses = [recipients objectEnumerator]; + currentTo = [addresses nextObject]; + while (currentTo) + { + if (![client recipientTo: [currentTo pureEMailAddress]]) + { + [self logWithFormat: @"error with recipient '%@'", currentTo]; + [toErrors addObject: [currentTo pureEMailAddress]]; + } + currentTo = [addresses nextObject]; + } + if ([toErrors count] == [recipients count]) + result = [NSException exceptionWithHTTPStatus: 500 + reason: @"cannot send message:" + @" (smtp) all recipients discarded"]; + else if ([toErrors count] > 0) + result = [NSException exceptionWithHTTPStatus: 500 + reason: [NSString stringWithFormat: + @"cannot send message (smtp) - recipients discarded:\n%@", + [toErrors componentsJoinedByString: @", "]]]; + else + result = [self _sendMailData: mailData withClient: client]; + } + else + result = [NSException + exceptionWithHTTPStatus: 500 + reason: @"cannot send message: (smtp) originator not accepted"]; + } [client quit]; [client disconnect]; } @@ -190,6 +218,8 @@ - (NSException *) sendMailData: (NSData *) data toRecipients: (NSArray *) recipients sender: (NSString *) sender + withAuthenticator: (id ) authenticator + inContext: (WOContext *) woContext { NSException *result; @@ -209,8 +239,10 @@ sender: [sender pureEMailAddress]]; else result = [self _smtpSendData: data - toRecipients: recipients - sender: [sender pureEMailAddress]]; + toRecipients: recipients + sender: [sender pureEMailAddress] + withAuthenticator: authenticator + inContext: woContext]; } } @@ -220,6 +252,8 @@ - (NSException *) sendMimePart: (id ) part toRecipients: (NSArray *) recipients sender: (NSString *) sender + withAuthenticator: (id ) authenticator + inContext: (WOContext *) woContext { NSData *mailData; @@ -228,12 +262,16 @@ return [self sendMailData: mailData toRecipients: recipients - sender: sender]; + sender: sender + withAuthenticator: authenticator + inContext: woContext]; } - (NSException *) sendMailAtPath: (NSString *) filename toRecipients: (NSArray *) recipients sender: (NSString *) sender + withAuthenticator: (id ) authenticator + inContext: (WOContext *) woContext { NSException *result; NSData *mailData; @@ -242,13 +280,15 @@ if ([mailData length] > 0) result = [self sendMailData: mailData toRecipients: recipients - sender: sender]; + sender: sender + withAuthenticator: authenticator + inContext: woContext]; else result = [NSException exceptionWithHTTPStatus: 500 reason: @"cannot send message: no data" @" (missing or empty file?)"]; - return nil; + return result; } @end diff --git a/SoObjects/SOGo/SOGoSession.m b/SoObjects/SOGo/SOGoSession.m index fce46aa5c..1c8f9abbd 100644 --- a/SoObjects/SOGo/SOGoSession.m +++ b/SoObjects/SOGo/SOGoSession.m @@ -27,6 +27,7 @@ #include "SOGoCache.h" #import +#import #import #import diff --git a/Tools/SOGoEAlarmsNotifier.m b/Tools/SOGoEAlarmsNotifier.m index bb5982b90..cec6e425c 100644 --- a/Tools/SOGoEAlarmsNotifier.m +++ b/Tools/SOGoEAlarmsNotifier.m @@ -122,9 +122,12 @@ message = [NGMimeMessage messageWithHeader: headers]; [message setBody: content]; to = [attendee rfc822Email]; + + /* TODO: SMTP authentication for services */ [mailer sendMimePart: message toRecipients: [NSArray arrayWithObject: to] - sender: from]; + sender: from + withAuthenticator: nil inContext: nil]; } - (void) _processAlarm: (iCalAlarm *) alarm diff --git a/UI/MailerUI/UIxMailView.m b/UI/MailerUI/UIxMailView.m index 48dac90ba..0c8e20fca 100644 --- a/UI/MailerUI/UIxMailView.m +++ b/UI/MailerUI/UIxMailView.m @@ -478,9 +478,11 @@ static NSString *mailETag = nil; [generator autorelease]; if (![[SOGoMailer mailerWithDomainDefaults: dd] - sendMailData: [generator generateMimeFromPart: message] - toRecipients: [NSArray arrayWithObject: email] - sender: [self _matchingIdentityEMail]]) + sendMailData: [generator generateMimeFromPart: message] + toRecipients: [NSArray arrayWithObject: email] + sender: [self _matchingIdentityEMail] + withAuthenticator: [self authenticatorInContext: context] + inContext: context]) [self _flagMessageWithMDNSent]; } diff --git a/UI/SOGoUI/SOGoACLAdvisory.m b/UI/SOGoUI/SOGoACLAdvisory.m index 3023d46d7..e5d1c0787 100644 --- a/UI/SOGoUI/SOGoACLAdvisory.m +++ b/UI/SOGoUI/SOGoACLAdvisory.m @@ -234,9 +234,12 @@ [body release]; mailer = [SOGoMailer mailerWithDomainDefaults: [activeUser domainDefaults]]; - [mailer sendMimePart: message + [mailer + sendMimePart: message toRecipients: [NSArray arrayWithObject: recipient] - sender: from]; + sender: from + withAuthenticator: [self authenticatorInContext: context] + inContext: context]; } @end diff --git a/UI/SOGoUI/SOGoFolderAdvisory.m b/UI/SOGoUI/SOGoFolderAdvisory.m index 83fe5f434..b0b14ad68 100644 --- a/UI/SOGoUI/SOGoFolderAdvisory.m +++ b/UI/SOGoUI/SOGoFolderAdvisory.m @@ -205,9 +205,11 @@ dd = [activeUser domainDefaults]; [[SOGoMailer mailerWithDomainDefaults: dd] - sendMimePart: message - toRecipients: [NSArray arrayWithObject: recipient] - sender: from]; + sendMimePart: message + toRecipients: [NSArray arrayWithObject: recipient] + sender: from + withAuthenticator: [self authenticatorInContext: context] + inContext: context]; } @end