Added support for SMTP PLAIN authentication

pull/5/head
Wolfgang Sourdeau 2012-10-16 16:56:48 -04:00
parent ef5119f765
commit 5a76790418
12 changed files with 142 additions and 60 deletions

View File

@ -862,9 +862,12 @@
/* send the damn thing */ /* send the damn thing */
[[SOGoMailer mailerWithDomainDefaults: dd] [[SOGoMailer mailerWithDomainDefaults: dd]
sendMimePart: msg sendMimePart: msg
toRecipients: [NSArray arrayWithObject: email] toRecipients: [NSArray arrayWithObject: email]
sender: shortSenderEmail]; sender: shortSenderEmail
withAuthenticator: [self
authenticatorInContext: context]
inContext: context];
} }
} }
} }
@ -946,9 +949,11 @@
/* send the damn thing */ /* send the damn thing */
email = [recipient rfc822Email]; email = [recipient rfc822Email];
[[SOGoMailer mailerWithDomainDefaults: dd] [[SOGoMailer mailerWithDomainDefaults: dd]
sendMimePart: msg sendMimePart: msg
toRecipients: [NSArray arrayWithObject: email] toRecipients: [NSArray arrayWithObject: email]
sender: [attendee rfc822Email]]; sender: [attendee rfc822Email]
withAuthenticator: [self authenticatorInContext: context]
inContext: context];
} }
} }
@ -989,6 +994,7 @@
NGMimeMessage *msg; NGMimeMessage *msg;
SOGoUser *currentUser; SOGoUser *currentUser;
SOGoDomainDefaults *dd; SOGoDomainDefaults *dd;
id <SOGoAuthenticator> authenticator;
calendarName = [[self container] displayName]; calendarName = [[self container] displayName];
@ -1039,6 +1045,8 @@
/* text part */ /* text part */
mailText = [page getBody]; mailText = [page getBody];
[msg setBody: [mailText dataUsingEncoding: NSUTF8StringEncoding]]; [msg setBody: [mailText dataUsingEncoding: NSUTF8StringEncoding]];
authenticator = [self authenticatorInContext: context];
if ([self->owner isEqualToString: [currentUser login]]) if ([self->owner isEqualToString: [currentUser login]])
{ {
@ -1047,7 +1055,9 @@
[[SOGoMailer mailerWithDomainDefaults: dd] [[SOGoMailer mailerWithDomainDefaults: dd]
sendMimePart: msg sendMimePart: msg
toRecipients: [NSArray arrayWithObject: recipientEmail] toRecipients: [NSArray arrayWithObject: recipientEmail]
sender: senderEmail]; sender: senderEmail
withAuthenticator: authenticator
inContext: context];
} }
if ([[self container] notifyUserOnPersonalModifications]) if ([[self container] notifyUserOnPersonalModifications])
@ -1061,7 +1071,9 @@
[[SOGoMailer mailerWithDomainDefaults: dd] [[SOGoMailer mailerWithDomainDefaults: dd]
sendMimePart: msg sendMimePart: msg
toRecipients: [NSArray arrayWithObject: recipientEmail] toRecipients: [NSArray arrayWithObject: recipientEmail]
sender: senderEmail]; sender: senderEmail
withAuthenticator: authenticator
inContext: context];
[headerMap setObject: o forKey: @"to"]; [headerMap setObject: o forKey: @"to"];
} }
@ -1074,7 +1086,9 @@
[[SOGoMailer mailerWithDomainDefaults: dd] [[SOGoMailer mailerWithDomainDefaults: dd]
sendMimePart: msg sendMimePart: msg
toRecipients: [NSArray arrayWithObject: recipientEmail] toRecipients: [NSArray arrayWithObject: recipientEmail]
sender: senderEmail]; sender: senderEmail
withAuthenticator: authenticator
inContext: context];
} }
} }

View File

@ -1569,9 +1569,11 @@ static NSString *userAgent = nil;
dd = [[context activeUser] domainDefaults]; dd = [[context activeUser] domainDefaults];
error = [[SOGoMailer mailerWithDomainDefaults: dd] error = [[SOGoMailer mailerWithDomainDefaults: dd]
sendMailData: cleaned_message sendMailData: cleaned_message
toRecipients: [self allBareRecipients] toRecipients: [self allBareRecipients]
sender: [self sender]]; sender: [self sender]
withAuthenticator: [self authenticatorInContext: context]
inContext: context];
if (!error && copyToSent) if (!error && copyToSent)
{ {
sentFolder = [[self mailAccountFolder] sentFolderInContext: context]; sentFolder = [[self mailAccountFolder] sentFolderInContext: context];

View File

@ -53,6 +53,7 @@
- (BOOL) vacationEnabled; - (BOOL) vacationEnabled;
- (NSString *) mailingMechanism; - (NSString *) mailingMechanism;
- (NSString *) smtpServer; - (NSString *) smtpServer;
- (NSString *) smtpAuthenticationType;
- (NSString *) mailSpoolPath; - (NSString *) mailSpoolPath;
- (float) softQuotaRatio; - (float) softQuotaRatio;
- (BOOL) mailKeepDraftsAfterSend; - (BOOL) mailKeepDraftsAfterSend;

View File

@ -218,6 +218,11 @@
return [self stringForKey: @"SOGoSMTPServer"]; return [self stringForKey: @"SOGoSMTPServer"];
} }
- (NSString *) smtpAuthenticationType
{
return [self stringForKey: @"SOGoSMTPAuthenticationType"];
}
- (NSString *) mailSpoolPath - (NSString *) mailSpoolPath
{ {
return [self stringForKey: @"SOGoMailSpoolPath"]; return [self stringForKey: @"SOGoMailSpoolPath"];

View File

@ -29,14 +29,17 @@
@class NSException; @class NSException;
@class NSString; @class NSString;
@class WOContext;
@class SOGoDomainDefaults; @class SOGoDomainDefaults;
@protocol NGMimePart; @protocol NGMimePart;
@protocol SOGoAuthenticator;
@interface SOGoMailer : NSObject @interface SOGoMailer : NSObject
{ {
NSString *mailingMechanism; NSString *mailingMechanism;
NSString *smtpServer; NSString *smtpServer;
NSString *authenticationType;
} }
+ (SOGoMailer *) mailerWithDomainDefaults: (SOGoDomainDefaults *) dd; + (SOGoMailer *) mailerWithDomainDefaults: (SOGoDomainDefaults *) dd;
@ -45,13 +48,19 @@
- (NSException *) sendMailData: (NSData *) data - (NSException *) sendMailData: (NSData *) data
toRecipients: (NSArray *) recipients toRecipients: (NSArray *) recipients
sender: (NSString *) sender; sender: (NSString *) sender
withAuthenticator: (id <SOGoAuthenticator>) authenticator
inContext: (WOContext *) woContext;
- (NSException *) sendMailAtPath: (NSString *) filename - (NSException *) sendMailAtPath: (NSString *) filename
toRecipients: (NSArray *) recipients toRecipients: (NSArray *) recipients
sender: (NSString *) sender; sender: (NSString *) sender
withAuthenticator: (id <SOGoAuthenticator>) authenticator
inContext: (WOContext *) woContext;
- (NSException *) sendMimePart: (id <NGMimePart>) part - (NSException *) sendMimePart: (id <NGMimePart>) part
toRecipients: (NSArray *) recipients toRecipients: (NSArray *) recipients
sender: (NSString *) sender; sender: (NSString *) sender
withAuthenticator: (id <SOGoAuthenticator>) authenticator
inContext: (WOContext *) woContext;
@end @end

View File

@ -33,8 +33,10 @@
#import <NGStreams/NGInternetSocketAddress.h> #import <NGStreams/NGInternetSocketAddress.h>
#import "NSString+Utilities.h" #import "NSString+Utilities.h"
#import "SOGoAuthenticator.h"
#import "SOGoDomainDefaults.h" #import "SOGoDomainDefaults.h"
#import "SOGoSystemDefaults.h" #import "SOGoSystemDefaults.h"
#import "SOGoUser.h"
#import "SOGoMailer.h" #import "SOGoMailer.h"
@ -51,6 +53,8 @@
{ {
ASSIGN (mailingMechanism, [dd mailingMechanism]); ASSIGN (mailingMechanism, [dd mailingMechanism]);
ASSIGN (smtpServer, [dd smtpServer]); ASSIGN (smtpServer, [dd smtpServer]);
ASSIGN (authenticationType,
[[dd smtpAuthenticationType] lowercaseString]);
} }
return self; return self;
@ -62,6 +66,7 @@
{ {
mailingMechanism = nil; mailingMechanism = nil;
smtpServer = nil; smtpServer = nil;
authenticationType = nil;
} }
return self; return self;
@ -71,6 +76,7 @@
{ {
[mailingMechanism release]; [mailingMechanism release];
[smtpServer release]; [smtpServer release];
[authenticationType release];
[super dealloc]; [super dealloc];
} }
@ -112,15 +118,16 @@
- (NSException *) _smtpSendData: (NSData *) mailData - (NSException *) _smtpSendData: (NSData *) mailData
toRecipients: (NSArray *) recipients toRecipients: (NSArray *) recipients
sender: (NSString *) sender sender: (NSString *) sender
withAuthenticator: (id <SOGoAuthenticator>) authenticator
inContext: (WOContext *) woContext
{ {
NGInternetSocketAddress *addr; NGInternetSocketAddress *addr;
NSString *currentTo, *host; NSString *currentTo, *host, *login, *password;
NSMutableArray *toErrors; NSMutableArray *toErrors;
NSEnumerator *addresses; NSEnumerator *addresses;
NGSmtpClient *client; NGSmtpClient *client;
NSException *result; NSException *result = nil;
NSRange r; NSRange r;
unsigned int port; unsigned int port;
client = [NGSmtpClient smtpClient]; client = [NGSmtpClient smtpClient];
@ -142,36 +149,57 @@
NS_DURING NS_DURING
{ {
[client connectToAddress: addr]; [client connectToAddress: addr];
if ([client mailFrom: sender]) if ([authenticationType isEqualToString: @"plain"])
{ {
toErrors = [NSMutableArray array]; login = [[authenticator userInContext: woContext] login];
addresses = [recipients objectEnumerator]; password = [authenticator passwordInContext: woContext];
currentTo = [addresses nextObject]; if ([login length] == 0
while (currentTo) || [login isEqualToString: @"anonymous"]
{ || ![client plainAuthenticateUser: login
if (![client recipientTo: [currentTo pureEMailAddress]]) withPassword: password])
{ result = [NSException
[self logWithFormat: @"error with recipient '%@'", currentTo]; exceptionWithHTTPStatus: 500
[toErrors addObject: [currentTo pureEMailAddress]]; reason: @"cannot send message:"
} @" (smtp) authentication failure"];
currentTo = [addresses nextObject]; }
} else if (authenticationType)
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 result = [NSException
exceptionWithHTTPStatus: 500 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 quit];
[client disconnect]; [client disconnect];
} }
@ -190,6 +218,8 @@
- (NSException *) sendMailData: (NSData *) data - (NSException *) sendMailData: (NSData *) data
toRecipients: (NSArray *) recipients toRecipients: (NSArray *) recipients
sender: (NSString *) sender sender: (NSString *) sender
withAuthenticator: (id <SOGoAuthenticator>) authenticator
inContext: (WOContext *) woContext
{ {
NSException *result; NSException *result;
@ -209,8 +239,10 @@
sender: [sender pureEMailAddress]]; sender: [sender pureEMailAddress]];
else else
result = [self _smtpSendData: data result = [self _smtpSendData: data
toRecipients: recipients toRecipients: recipients
sender: [sender pureEMailAddress]]; sender: [sender pureEMailAddress]
withAuthenticator: authenticator
inContext: woContext];
} }
} }
@ -220,6 +252,8 @@
- (NSException *) sendMimePart: (id <NGMimePart>) part - (NSException *) sendMimePart: (id <NGMimePart>) part
toRecipients: (NSArray *) recipients toRecipients: (NSArray *) recipients
sender: (NSString *) sender sender: (NSString *) sender
withAuthenticator: (id <SOGoAuthenticator>) authenticator
inContext: (WOContext *) woContext
{ {
NSData *mailData; NSData *mailData;
@ -228,12 +262,16 @@
return [self sendMailData: mailData return [self sendMailData: mailData
toRecipients: recipients toRecipients: recipients
sender: sender]; sender: sender
withAuthenticator: authenticator
inContext: woContext];
} }
- (NSException *) sendMailAtPath: (NSString *) filename - (NSException *) sendMailAtPath: (NSString *) filename
toRecipients: (NSArray *) recipients toRecipients: (NSArray *) recipients
sender: (NSString *) sender sender: (NSString *) sender
withAuthenticator: (id <SOGoAuthenticator>) authenticator
inContext: (WOContext *) woContext
{ {
NSException *result; NSException *result;
NSData *mailData; NSData *mailData;
@ -242,13 +280,15 @@
if ([mailData length] > 0) if ([mailData length] > 0)
result = [self sendMailData: mailData result = [self sendMailData: mailData
toRecipients: recipients toRecipients: recipients
sender: sender]; sender: sender
withAuthenticator: authenticator
inContext: woContext];
else else
result = [NSException exceptionWithHTTPStatus: 500 result = [NSException exceptionWithHTTPStatus: 500
reason: @"cannot send message: no data" reason: @"cannot send message: no data"
@" (missing or empty file?)"]; @" (missing or empty file?)"];
return nil; return result;
} }
@end @end

View File

@ -27,6 +27,7 @@
#include "SOGoCache.h" #include "SOGoCache.h"
#import <Foundation/NSArray.h> #import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSData.h> #import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h> #import <Foundation/NSDictionary.h>

View File

@ -122,9 +122,12 @@
message = [NGMimeMessage messageWithHeader: headers]; message = [NGMimeMessage messageWithHeader: headers];
[message setBody: content]; [message setBody: content];
to = [attendee rfc822Email]; to = [attendee rfc822Email];
/* TODO: SMTP authentication for services */
[mailer sendMimePart: message [mailer sendMimePart: message
toRecipients: [NSArray arrayWithObject: to] toRecipients: [NSArray arrayWithObject: to]
sender: from]; sender: from
withAuthenticator: nil inContext: nil];
} }
- (void) _processAlarm: (iCalAlarm *) alarm - (void) _processAlarm: (iCalAlarm *) alarm

View File

@ -478,9 +478,11 @@ static NSString *mailETag = nil;
[generator autorelease]; [generator autorelease];
if (![[SOGoMailer mailerWithDomainDefaults: dd] if (![[SOGoMailer mailerWithDomainDefaults: dd]
sendMailData: [generator generateMimeFromPart: message] sendMailData: [generator generateMimeFromPart: message]
toRecipients: [NSArray arrayWithObject: email] toRecipients: [NSArray arrayWithObject: email]
sender: [self _matchingIdentityEMail]]) sender: [self _matchingIdentityEMail]
withAuthenticator: [self authenticatorInContext: context]
inContext: context])
[self _flagMessageWithMDNSent]; [self _flagMessageWithMDNSent];
} }

View File

@ -234,9 +234,12 @@
[body release]; [body release];
mailer = [SOGoMailer mailerWithDomainDefaults: [activeUser domainDefaults]]; mailer = [SOGoMailer mailerWithDomainDefaults: [activeUser domainDefaults]];
[mailer sendMimePart: message [mailer
sendMimePart: message
toRecipients: [NSArray arrayWithObject: recipient] toRecipients: [NSArray arrayWithObject: recipient]
sender: from]; sender: from
withAuthenticator: [self authenticatorInContext: context]
inContext: context];
} }
@end @end

View File

@ -205,9 +205,11 @@
dd = [activeUser domainDefaults]; dd = [activeUser domainDefaults];
[[SOGoMailer mailerWithDomainDefaults: dd] [[SOGoMailer mailerWithDomainDefaults: dd]
sendMimePart: message sendMimePart: message
toRecipients: [NSArray arrayWithObject: recipient] toRecipients: [NSArray arrayWithObject: recipient]
sender: from]; sender: from
withAuthenticator: [self authenticatorInContext: context]
inContext: context];
} }
@end @end